prpm 2.1.37 → 2.1.39
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/README.md +1 -1
- package/dist/index.js +128 -36
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ prpm install collections/nextjs-pro # Entire Next.js setup in one command
|
|
|
14
14
|
```
|
|
15
15
|
Installs 20 packages: backend-architect, cloud-architect, database-architect, and more
|
|
16
16
|
|
|
17
|
-
7,
|
|
17
|
+
7,500+ cross platform packages
|
|
18
18
|
|
|
19
19
|
[Docs](https://docs.prpm.dev) | [Search Packages](https://prpm.dev/search) | [Search Collections](https://prpm.dev/search?tab=collections)
|
|
20
20
|
|
package/dist/index.js
CHANGED
|
@@ -102,7 +102,8 @@ function parseLockfileKey(key) {
|
|
|
102
102
|
function addToLockfile(lockfile, packageId, packageInfo) {
|
|
103
103
|
var _a;
|
|
104
104
|
const snippetLocation = packageInfo.subtype === "snippet" ? (_a = packageInfo.snippetMetadata) == null ? void 0 : _a.targetPath : void 0;
|
|
105
|
-
const
|
|
105
|
+
const locationKey = packageInfo.global ? "global" : snippetLocation;
|
|
106
|
+
const lockfileKey = getLockfileKey(packageId, packageInfo.format, locationKey);
|
|
106
107
|
lockfile.packages[lockfileKey] = {
|
|
107
108
|
version: packageInfo.version,
|
|
108
109
|
resolved: packageInfo.tarballUrl,
|
|
@@ -111,6 +112,7 @@ function addToLockfile(lockfile, packageId, packageInfo) {
|
|
|
111
112
|
dependencies: packageInfo.dependencies,
|
|
112
113
|
format: packageInfo.format,
|
|
113
114
|
subtype: packageInfo.subtype,
|
|
115
|
+
global: packageInfo.global,
|
|
114
116
|
sourceFormat: packageInfo.sourceFormat,
|
|
115
117
|
sourceSubtype: packageInfo.sourceSubtype,
|
|
116
118
|
installedPath: packageInfo.installedPath,
|
|
@@ -140,13 +142,13 @@ function verifyPackageIntegrity(lockfile, packageId, tarballBuffer, format, loca
|
|
|
140
142
|
const expectedHash = pkg.integrity.replace("sha256-", "");
|
|
141
143
|
return hash === expectedHash;
|
|
142
144
|
}
|
|
143
|
-
function getLockedVersion(lockfile, packageId, format) {
|
|
145
|
+
function getLockedVersion(lockfile, packageId, format, location) {
|
|
144
146
|
var _a;
|
|
145
147
|
if (!lockfile) {
|
|
146
148
|
return null;
|
|
147
149
|
}
|
|
148
150
|
if (format) {
|
|
149
|
-
const lockfileKey = getLockfileKey(packageId, format);
|
|
151
|
+
const lockfileKey = getLockfileKey(packageId, format, location);
|
|
150
152
|
return ((_a = lockfile.packages[lockfileKey]) == null ? void 0 : _a.version) || null;
|
|
151
153
|
}
|
|
152
154
|
if (lockfile.packages[packageId]) {
|
|
@@ -17641,6 +17643,36 @@ ${lines.join("\n")}
|
|
|
17641
17643
|
---
|
|
17642
17644
|
${body}`;
|
|
17643
17645
|
}
|
|
17646
|
+
function replaceLeadingDirectory(filePath, from, to) {
|
|
17647
|
+
const normalizedPath = filePath.startsWith("./") ? filePath.slice(2) : filePath;
|
|
17648
|
+
if (normalizedPath === from) {
|
|
17649
|
+
return to;
|
|
17650
|
+
}
|
|
17651
|
+
if (normalizedPath.startsWith(`${from}/`)) {
|
|
17652
|
+
return import_path15.default.join(to, normalizedPath.slice(from.length + 1));
|
|
17653
|
+
}
|
|
17654
|
+
return filePath;
|
|
17655
|
+
}
|
|
17656
|
+
function getGlobalDestinationDir(format, destDir) {
|
|
17657
|
+
const homeDir = import_os5.default.homedir();
|
|
17658
|
+
if (format === "claude") {
|
|
17659
|
+
return replaceLeadingDirectory(destDir, ".claude", import_path15.default.join(homeDir, ".claude"));
|
|
17660
|
+
}
|
|
17661
|
+
if (format === "codex") {
|
|
17662
|
+
if (destDir === "." || destDir === "./") {
|
|
17663
|
+
return import_path15.default.join(homeDir, ".codex");
|
|
17664
|
+
}
|
|
17665
|
+
const codexPath = replaceLeadingDirectory(destDir, ".codex", import_path15.default.join(homeDir, ".codex"));
|
|
17666
|
+
if (codexPath !== destDir) {
|
|
17667
|
+
return codexPath;
|
|
17668
|
+
}
|
|
17669
|
+
return replaceLeadingDirectory(destDir, ".agents", import_path15.default.join(homeDir, ".agents"));
|
|
17670
|
+
}
|
|
17671
|
+
return destDir;
|
|
17672
|
+
}
|
|
17673
|
+
function getLockfileLocationKey(options) {
|
|
17674
|
+
return options.global ? "global" : void 0;
|
|
17675
|
+
}
|
|
17644
17676
|
function getPackageLabel2(format, subtype) {
|
|
17645
17677
|
const formatLabels = {
|
|
17646
17678
|
"claude": "Claude",
|
|
@@ -17783,7 +17815,8 @@ async function handleInstall(packageSpec, options) {
|
|
|
17783
17815
|
if (!targetFormat) {
|
|
17784
17816
|
targetFormat = config.defaultFormat || await autoDetectFormat() || void 0;
|
|
17785
17817
|
}
|
|
17786
|
-
const
|
|
17818
|
+
const lockfileLocationKey = getLockfileLocationKey(options);
|
|
17819
|
+
const lockedVersion = getLockedVersion(lockfile, packageId, targetFormat, lockfileLocationKey);
|
|
17787
17820
|
let version;
|
|
17788
17821
|
if (options.frozenLockfile) {
|
|
17789
17822
|
if (!lockedVersion) {
|
|
@@ -17804,7 +17837,7 @@ async function handleInstall(packageSpec, options) {
|
|
|
17804
17837
|
matchedKey = snippetKey;
|
|
17805
17838
|
}
|
|
17806
17839
|
if (!installedPkg) {
|
|
17807
|
-
const standardKey = getLockfileKey(packageId, targetFormat);
|
|
17840
|
+
const standardKey = getLockfileKey(packageId, targetFormat, lockfileLocationKey);
|
|
17808
17841
|
if (lockfile.packages[standardKey]) {
|
|
17809
17842
|
installedPkg = lockfile.packages[standardKey];
|
|
17810
17843
|
matchedKey = standardKey;
|
|
@@ -17954,11 +17987,11 @@ async function handleInstall(packageSpec, options) {
|
|
|
17954
17987
|
}
|
|
17955
17988
|
console.log(` \u2B07\uFE0F Downloading...`);
|
|
17956
17989
|
const tarball = await client.downloadPackage(tarballUrl);
|
|
17957
|
-
const lockfileKeyForVerification = getLockfileKey(packageId, targetFormat);
|
|
17990
|
+
const lockfileKeyForVerification = getLockfileKey(packageId, targetFormat, lockfileLocationKey);
|
|
17958
17991
|
const existingEntry = lockfile == null ? void 0 : lockfile.packages[lockfileKeyForVerification];
|
|
17959
17992
|
if ((existingEntry == null ? void 0 : existingEntry.integrity) && existingEntry.version === actualVersion) {
|
|
17960
17993
|
console.log(` \u{1F512} Verifying integrity...`);
|
|
17961
|
-
const isValid = verifyPackageIntegrity(lockfile, packageId, tarball, targetFormat);
|
|
17994
|
+
const isValid = verifyPackageIntegrity(lockfile, packageId, tarball, targetFormat, lockfileLocationKey);
|
|
17962
17995
|
if (!isValid) {
|
|
17963
17996
|
throw new CLIError(
|
|
17964
17997
|
`\u274C Integrity verification failed for ${packageId}
|
|
@@ -17982,6 +18015,7 @@ This could indicate:
|
|
|
17982
18015
|
if (options.as && format && format !== pkg.format && effectiveSubtype !== "snippet" && !isMCPToEditor) {
|
|
17983
18016
|
console.log(` \u{1F504} Converting from ${pkg.format} to ${format}...`);
|
|
17984
18017
|
let sourceContent;
|
|
18018
|
+
let mainFileIndex = 0;
|
|
17985
18019
|
if (extractedFiles.length === 1) {
|
|
17986
18020
|
sourceContent = extractedFiles[0].content;
|
|
17987
18021
|
} else {
|
|
@@ -17991,6 +18025,7 @@ This could indicate:
|
|
|
17991
18025
|
`Could not identify main file for multi-file ${pkg.format} ${pkg.subtype} package. Expected files like SKILL.md, agent.md, or similar main entry points.`
|
|
17992
18026
|
);
|
|
17993
18027
|
}
|
|
18028
|
+
mainFileIndex = extractedFiles.indexOf(mainFile);
|
|
17994
18029
|
console.log(` \u{1F4C4} Using main file: ${mainFile.name}`);
|
|
17995
18030
|
sourceContent = mainFile.content;
|
|
17996
18031
|
}
|
|
@@ -18142,10 +18177,16 @@ This could indicate:
|
|
|
18142
18177
|
if (!convertedContent) {
|
|
18143
18178
|
throw new CLIError("Conversion failed: No content generated");
|
|
18144
18179
|
}
|
|
18145
|
-
extractedFiles
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18180
|
+
if (extractedFiles.length === 1) {
|
|
18181
|
+
extractedFiles = [{
|
|
18182
|
+
name: extractedFiles[0].name,
|
|
18183
|
+
content: convertedContent
|
|
18184
|
+
}];
|
|
18185
|
+
} else {
|
|
18186
|
+
extractedFiles = extractedFiles.map(
|
|
18187
|
+
(file, index) => index === mainFileIndex ? { ...file, content: convertedContent } : file
|
|
18188
|
+
);
|
|
18189
|
+
}
|
|
18149
18190
|
console.log(` \u2713 Converted from ${pkg.format} to ${format}`);
|
|
18150
18191
|
}
|
|
18151
18192
|
const locationSupportedFormats = ["agents.md", "cursor"];
|
|
@@ -18164,6 +18205,7 @@ This could indicate:
|
|
|
18164
18205
|
const isClaudePlugin = pkg.format === "claude" && pkg.subtype === "plugin";
|
|
18165
18206
|
if (isClaudePlugin) {
|
|
18166
18207
|
console.log(` \u{1F50C} Installing Claude Plugin...`);
|
|
18208
|
+
const claudeRoot = options.global ? import_path15.default.join(import_os5.default.homedir(), ".claude") : ".claude";
|
|
18167
18209
|
const pluginJsonFile = extractedFiles.find(
|
|
18168
18210
|
(f) => f.name === "plugin.json" || f.name === ".claude-plugin/plugin.json" || f.name.endsWith("/plugin.json")
|
|
18169
18211
|
);
|
|
@@ -18180,14 +18222,15 @@ This could indicate:
|
|
|
18180
18222
|
(f) => f.name.startsWith("agents/") && f.name.endsWith(".md")
|
|
18181
18223
|
);
|
|
18182
18224
|
if (agentFiles.length > 0) {
|
|
18183
|
-
|
|
18225
|
+
const agentDir = import_path15.default.join(claudeRoot, "agents");
|
|
18226
|
+
await import_promises4.default.mkdir(agentDir, { recursive: true });
|
|
18184
18227
|
for (const file of agentFiles) {
|
|
18185
18228
|
const filename = import_path15.default.basename(file.name);
|
|
18186
|
-
const destFile =
|
|
18229
|
+
const destFile = import_path15.default.join(agentDir, filename);
|
|
18187
18230
|
await saveFile(destFile, file.content);
|
|
18188
18231
|
installedFiles.push(destFile);
|
|
18189
18232
|
}
|
|
18190
|
-
console.log(` \u2713 Installed ${agentFiles.length} agents to
|
|
18233
|
+
console.log(` \u2713 Installed ${agentFiles.length} agents to ${agentDir}/`);
|
|
18191
18234
|
}
|
|
18192
18235
|
const skillFiles = extractedFiles.filter(
|
|
18193
18236
|
(f) => f.name.startsWith("skills/") && (f.name.endsWith(".md") || f.name.includes("SKILL.md"))
|
|
@@ -18195,26 +18238,27 @@ This could indicate:
|
|
|
18195
18238
|
if (skillFiles.length > 0) {
|
|
18196
18239
|
for (const file of skillFiles) {
|
|
18197
18240
|
const relativePath = file.name.replace(/^skills\//, "");
|
|
18198
|
-
const destFile =
|
|
18241
|
+
const destFile = import_path15.default.join(claudeRoot, "skills", relativePath);
|
|
18199
18242
|
const destFileDir = import_path15.default.dirname(destFile);
|
|
18200
18243
|
await import_promises4.default.mkdir(destFileDir, { recursive: true });
|
|
18201
18244
|
await saveFile(destFile, file.content);
|
|
18202
18245
|
installedFiles.push(destFile);
|
|
18203
18246
|
}
|
|
18204
|
-
console.log(` \u2713 Installed ${skillFiles.length} skill files to .
|
|
18247
|
+
console.log(` \u2713 Installed ${skillFiles.length} skill files to ${import_path15.default.join(claudeRoot, "skills")}/`);
|
|
18205
18248
|
}
|
|
18206
18249
|
const commandFiles = extractedFiles.filter(
|
|
18207
18250
|
(f) => f.name.startsWith("commands/") && f.name.endsWith(".md")
|
|
18208
18251
|
);
|
|
18209
18252
|
if (commandFiles.length > 0) {
|
|
18210
|
-
|
|
18253
|
+
const commandDir = import_path15.default.join(claudeRoot, "commands");
|
|
18254
|
+
await import_promises4.default.mkdir(commandDir, { recursive: true });
|
|
18211
18255
|
for (const file of commandFiles) {
|
|
18212
18256
|
const filename = import_path15.default.basename(file.name);
|
|
18213
|
-
const destFile =
|
|
18257
|
+
const destFile = import_path15.default.join(commandDir, filename);
|
|
18214
18258
|
await saveFile(destFile, file.content);
|
|
18215
18259
|
installedFiles.push(destFile);
|
|
18216
18260
|
}
|
|
18217
|
-
console.log(` \u2713 Installed ${commandFiles.length} commands to
|
|
18261
|
+
console.log(` \u2713 Installed ${commandFiles.length} commands to ${commandDir}/`);
|
|
18218
18262
|
}
|
|
18219
18263
|
if (pluginConfig.mcpServers && Object.keys(pluginConfig.mcpServers).length > 0) {
|
|
18220
18264
|
const editor = options.editor || "claude";
|
|
@@ -18251,7 +18295,7 @@ This could indicate:
|
|
|
18251
18295
|
files: installedFiles
|
|
18252
18296
|
};
|
|
18253
18297
|
}
|
|
18254
|
-
destPath =
|
|
18298
|
+
destPath = `${claudeRoot}/`;
|
|
18255
18299
|
fileCount = installedFiles.length;
|
|
18256
18300
|
} else if (effectiveFormat === "mcp" && (effectiveSubtype === "server" || effectiveSubtype === "tool") || isMCPServerPackage && (pkg.subtype === "server" || pkg.subtype === "tool") && isMCPToEditor) {
|
|
18257
18301
|
console.log(` \u{1F527} Installing MCP Server...`);
|
|
@@ -18341,11 +18385,18 @@ This could indicate:
|
|
|
18341
18385
|
throw new Error("CLAUDE.md format only supports single-file packages");
|
|
18342
18386
|
}
|
|
18343
18387
|
let mainFile = extractedFiles[0].content;
|
|
18344
|
-
destPath = "CLAUDE.md";
|
|
18388
|
+
destPath = options.global ? import_path15.default.join(import_os5.default.homedir(), ".claude", "CLAUDE.md") : "CLAUDE.md";
|
|
18345
18389
|
await saveFile(destPath, mainFile);
|
|
18346
18390
|
fileCount = 1;
|
|
18347
18391
|
} else if (extractedFiles.length === 1) {
|
|
18348
18392
|
destDir = getDestinationDir2(effectiveFormat, effectiveSubtype, pkg.name);
|
|
18393
|
+
if (options.global) {
|
|
18394
|
+
const globalDestDir = getGlobalDestinationDir(effectiveFormat, destDir);
|
|
18395
|
+
if (globalDestDir !== destDir) {
|
|
18396
|
+
destDir = globalDestDir;
|
|
18397
|
+
console.log(` \u{1F310} Installing globally to ${destDir}`);
|
|
18398
|
+
}
|
|
18399
|
+
}
|
|
18349
18400
|
if (locationOverride && effectiveFormat === "cursor") {
|
|
18350
18401
|
const relativeDestDir = destDir.startsWith("./") ? destDir.slice(2) : destDir;
|
|
18351
18402
|
destDir = import_path15.default.join(locationOverride, relativeDestDir);
|
|
@@ -18369,7 +18420,11 @@ This could indicate:
|
|
|
18369
18420
|
} else if (effectiveFormat === "agents.md" || effectiveFormat === "gemini.md" || effectiveFormat === "claude.md" || effectiveFormat === "codex") {
|
|
18370
18421
|
if (effectiveSubtype === "skill") {
|
|
18371
18422
|
destPath = `${destDir}/SKILL.md`;
|
|
18372
|
-
|
|
18423
|
+
if (effectiveFormat === "codex") {
|
|
18424
|
+
console.log(` \u{1F4E6} Installing Codex skill to ${destDir}/`);
|
|
18425
|
+
} else {
|
|
18426
|
+
console.log(` \u{1F4E6} Installing skill to ${destDir}/ for progressive disclosure`);
|
|
18427
|
+
}
|
|
18373
18428
|
} else if (effectiveSubtype === "agent") {
|
|
18374
18429
|
if (effectiveFormat === "codex") {
|
|
18375
18430
|
destPath = `${destDir}/${packageName}.toml`;
|
|
@@ -18541,12 +18596,19 @@ This could indicate:
|
|
|
18541
18596
|
} else {
|
|
18542
18597
|
destDir = getDestinationDir2(effectiveFormat, effectiveSubtype, pkg.name);
|
|
18543
18598
|
}
|
|
18599
|
+
if (options.global) {
|
|
18600
|
+
const globalDestDir = getGlobalDestinationDir(effectiveFormat, destDir);
|
|
18601
|
+
if (globalDestDir !== destDir) {
|
|
18602
|
+
destDir = globalDestDir;
|
|
18603
|
+
console.log(` \u{1F310} Installing globally to ${destDir}`);
|
|
18604
|
+
}
|
|
18605
|
+
}
|
|
18544
18606
|
if (locationOverride && effectiveFormat === "cursor") {
|
|
18545
18607
|
const relativeDestDir = destDir.startsWith("./") ? destDir.slice(2) : destDir;
|
|
18546
18608
|
destDir = import_path15.default.join(locationOverride, relativeDestDir);
|
|
18547
18609
|
console.log(` \u{1F4C1} Installing Cursor package to custom location: ${destDir}`);
|
|
18548
18610
|
}
|
|
18549
|
-
const isCursorConversion = effectiveFormat === "cursor" && pkg.format === "claude" && pkg.subtype === "skill";
|
|
18611
|
+
const isCursorConversion = effectiveFormat === "cursor" && pkg.format === "claude" && pkg.subtype === "skill" && !needsProgressiveDisclosureMulti;
|
|
18550
18612
|
const nativeSubtypeConfig = getSubtypeConfig(effectiveFormat, effectiveSubtype);
|
|
18551
18613
|
const usesNativePackageSubdirectory = !needsProgressiveDisclosureMulti && Boolean(nativeSubtypeConfig == null ? void 0 : nativeSubtypeConfig.usesPackageSubdirectory);
|
|
18552
18614
|
const packageDir = effectiveFormat === "claude" && effectiveSubtype === "skill" ? destDir : isCursorConversion ? destDir : needsProgressiveDisclosureMulti ? destDir : usesNativePackageSubdirectory ? destDir : `${destDir}/${packageName}`;
|
|
@@ -18704,11 +18766,13 @@ ${afterFrontmatter}`;
|
|
|
18704
18766
|
progressiveDisclosure: progressiveDisclosureMetadata,
|
|
18705
18767
|
pluginMetadata,
|
|
18706
18768
|
// Track plugin installation metadata for uninstall
|
|
18707
|
-
snippetMetadata
|
|
18769
|
+
snippetMetadata,
|
|
18708
18770
|
// Track snippet installation metadata for uninstall
|
|
18771
|
+
global: options.global
|
|
18709
18772
|
});
|
|
18710
18773
|
const snippetTargetPath = effectiveSubtype === "snippet" ? snippetMetadata == null ? void 0 : snippetMetadata.targetPath : void 0;
|
|
18711
|
-
|
|
18774
|
+
const integrityLocationKey = lockfileLocationKey || snippetTargetPath;
|
|
18775
|
+
setPackageIntegrity(updatedLockfile, packageId, tarball, effectiveFormat, integrityLocationKey);
|
|
18712
18776
|
await writeLockfile(updatedLockfile);
|
|
18713
18777
|
await client.trackDownload(packageId, {
|
|
18714
18778
|
version: actualVersion || version,
|
|
@@ -18889,7 +18953,7 @@ async function collectExtractedFiles(rootDir, excludedNames, fs16) {
|
|
|
18889
18953
|
return files;
|
|
18890
18954
|
}
|
|
18891
18955
|
async function installFromLockfile(options) {
|
|
18892
|
-
var _a, _b;
|
|
18956
|
+
var _a, _b, _c, _d;
|
|
18893
18957
|
try {
|
|
18894
18958
|
const lockfile = await readLockfile();
|
|
18895
18959
|
if (!lockfile) {
|
|
@@ -18906,7 +18970,7 @@ async function installFromLockfile(options) {
|
|
|
18906
18970
|
let failCount = 0;
|
|
18907
18971
|
for (const lockfileKey of packageIds) {
|
|
18908
18972
|
const lockEntry = lockfile.packages[lockfileKey];
|
|
18909
|
-
const { packageId, format } = parseLockfileKey(lockfileKey);
|
|
18973
|
+
const { packageId, format, location } = parseLockfileKey(lockfileKey);
|
|
18910
18974
|
const displayName = format ? `${packageId} (${format})` : packageId;
|
|
18911
18975
|
try {
|
|
18912
18976
|
const packageSpec = packageId.includes("@") && !packageId.startsWith("@") ? packageId.substring(0, packageId.lastIndexOf("@")) : packageId;
|
|
@@ -18921,6 +18985,8 @@ async function installFromLockfile(options) {
|
|
|
18921
18985
|
}
|
|
18922
18986
|
}
|
|
18923
18987
|
const manifestFile = (_a = lockEntry.progressiveDisclosure) == null ? void 0 : _a.manifestPath;
|
|
18988
|
+
const preservedGlobal = options.global ?? lockEntry.global ?? ((_b = lockEntry.pluginMetadata) == null ? void 0 : _b.mcpGlobal) ?? (location === "global" ? true : void 0);
|
|
18989
|
+
const preservedEditor = options.editor ?? ((_c = lockEntry.pluginMetadata) == null ? void 0 : _c.mcpEditor);
|
|
18924
18990
|
await handleInstall(packageSpec, {
|
|
18925
18991
|
version: lockEntry.version,
|
|
18926
18992
|
as: options.as || lockEntry.format,
|
|
@@ -18931,8 +18997,10 @@ async function installFromLockfile(options) {
|
|
|
18931
18997
|
location: locationOverride,
|
|
18932
18998
|
manifestFile,
|
|
18933
18999
|
hookMapping: options.hookMapping,
|
|
18934
|
-
fromCollection: lockEntry.fromCollection
|
|
19000
|
+
fromCollection: lockEntry.fromCollection,
|
|
18935
19001
|
// Preserve collection metadata
|
|
19002
|
+
global: preservedGlobal,
|
|
19003
|
+
editor: preservedEditor
|
|
18936
19004
|
});
|
|
18937
19005
|
successCount++;
|
|
18938
19006
|
} catch (error) {
|
|
@@ -18941,7 +19009,7 @@ async function installFromLockfile(options) {
|
|
|
18941
19009
|
} else {
|
|
18942
19010
|
failCount++;
|
|
18943
19011
|
console.error(` \u274C Failed to install ${displayName}:`);
|
|
18944
|
-
console.error(` Type: ${(
|
|
19012
|
+
console.error(` Type: ${(_d = error == null ? void 0 : error.constructor) == null ? void 0 : _d.name}`);
|
|
18945
19013
|
console.error(` Message: ${error instanceof Error ? error.message : String(error)}`);
|
|
18946
19014
|
if (error instanceof CLIError) {
|
|
18947
19015
|
console.error(` ExitCode: ${error.exitCode}`);
|
|
@@ -18963,7 +19031,7 @@ async function installFromLockfile(options) {
|
|
|
18963
19031
|
}
|
|
18964
19032
|
function createInstallCommand() {
|
|
18965
19033
|
const command = new import_commander12.Command("install");
|
|
18966
|
-
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. Accepts a comma-separated list to install to multiple formats in one command (${import_types.FORMATS.join(", ")})`).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("--hook-mapping <strategy>", "Hook mapping strategy: auto (default), strict, skip", "auto").option("--frozen-lockfile", "Fail if lock file needs to be updated (for CI)").option("-y, --yes", "Auto-confirm prompts (overwrite files without asking)").option("--no-append", "Skip adding skill to manifest file (skill files only)").option("--manifest-file <filename>", "Custom manifest filename for progressive disclosure").option("--eager", "Force skill/agent to always activate (not on-demand)").option("--lazy", "Use default on-demand activation (overrides package eager setting)").option("--tools <tools>", "Override Claude/Codex tool list for this install (comma- or space-separated)").option("--global", "Install
|
|
19034
|
+
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. Accepts a comma-separated list to install to multiple formats in one command (${import_types.FORMATS.join(", ")})`).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("--hook-mapping <strategy>", "Hook mapping strategy: auto (default), strict, skip", "auto").option("--frozen-lockfile", "Fail if lock file needs to be updated (for CI)").option("-y, --yes", "Auto-confirm prompts (overwrite files without asking)").option("--no-append", "Skip adding skill to manifest file (skill files only)").option("--manifest-file <filename>", "Custom manifest filename for progressive disclosure").option("--eager", "Force skill/agent to always activate (not on-demand)").option("--lazy", "Use default on-demand activation (overrides package eager setting)").option("--tools <tools>", "Override Claude/Codex tool list for this install (comma- or space-separated)").option("--global", "Install to user-level/global locations where supported (e.g., ~/.claude/skills, ~/.agents/skills, ~/.codex/agents, or global MCP config)").option("--editor <editor>", "[Deprecated: use --as] Target editor for MCP server installation").action(async (packageSpec, options) => {
|
|
18967
19035
|
const rawAs = options.format || options.as;
|
|
18968
19036
|
const validFormats = import_types.FORMATS;
|
|
18969
19037
|
const asTokens = rawAs ? Array.from(new Set(rawAs.split(",").map((s) => s.trim()).filter(Boolean))) : [];
|
|
@@ -19040,7 +19108,9 @@ The lockfile already records the target format for each package. Run prpm instal
|
|
|
19040
19108
|
subtype: options.subtype,
|
|
19041
19109
|
frozenLockfile: options.frozenLockfile,
|
|
19042
19110
|
location: options.location,
|
|
19043
|
-
hookMapping: options.hookMapping
|
|
19111
|
+
hookMapping: options.hookMapping,
|
|
19112
|
+
global: options.global,
|
|
19113
|
+
editor: options.editor ?? (isMCPEditorOnly ? singleAs : void 0)
|
|
19044
19114
|
});
|
|
19045
19115
|
return;
|
|
19046
19116
|
}
|
|
@@ -21074,7 +21144,14 @@ async function handleUninstall(name, options = {}) {
|
|
|
21074
21144
|
if (requestedFormat) {
|
|
21075
21145
|
const requestedKey = getLockfileKey(name, requestedFormat);
|
|
21076
21146
|
if (!lockfile.packages[requestedKey]) {
|
|
21077
|
-
|
|
21147
|
+
const matchingFormatKeys = matchingKeys.filter((key) => {
|
|
21148
|
+
const parsed = parseLockfileKey(key);
|
|
21149
|
+
const pkg = lockfile.packages[key];
|
|
21150
|
+
return parsed.format === requestedFormat || pkg.format === requestedFormat;
|
|
21151
|
+
});
|
|
21152
|
+
if (matchingFormatKeys.length > 0) {
|
|
21153
|
+
keysToUninstall = matchingFormatKeys;
|
|
21154
|
+
} else if (lockfile.packages[name] && lockfile.packages[name].format === requestedFormat) {
|
|
21078
21155
|
keysToUninstall = [name];
|
|
21079
21156
|
} else {
|
|
21080
21157
|
throw new CLIError(`\u274C Package "${name}" with format "${requestedFormat}" not found`, 1);
|
|
@@ -24760,6 +24837,14 @@ init_lockfile();
|
|
|
24760
24837
|
init_install();
|
|
24761
24838
|
init_telemetry();
|
|
24762
24839
|
init_errors();
|
|
24840
|
+
function getPreservedGlobal(pkg, location) {
|
|
24841
|
+
var _a;
|
|
24842
|
+
return pkg.global ?? ((_a = pkg.pluginMetadata) == null ? void 0 : _a.mcpGlobal) ?? (location === "global" ? true : void 0);
|
|
24843
|
+
}
|
|
24844
|
+
function getPreservedEditor(pkg) {
|
|
24845
|
+
var _a;
|
|
24846
|
+
return (_a = pkg.pluginMetadata) == null ? void 0 : _a.mcpEditor;
|
|
24847
|
+
}
|
|
24763
24848
|
async function handleUpdate(packageName, options = {}) {
|
|
24764
24849
|
const startTime = Date.now();
|
|
24765
24850
|
let success = false;
|
|
@@ -24786,7 +24871,7 @@ async function handleUpdate(packageName, options = {}) {
|
|
|
24786
24871
|
}
|
|
24787
24872
|
console.log("\u{1F504} Checking for updates...\n");
|
|
24788
24873
|
for (const pkg of packagesToUpdate) {
|
|
24789
|
-
const { packageId, format: installedFormat } = parseLockfileKey(pkg.id);
|
|
24874
|
+
const { packageId, format: installedFormat, location } = parseLockfileKey(pkg.id);
|
|
24790
24875
|
try {
|
|
24791
24876
|
const registryPkg = await client.getPackage(packageId);
|
|
24792
24877
|
if (!registryPkg.latest_version || !pkg.version) {
|
|
@@ -24812,9 +24897,16 @@ async function handleUpdate(packageName, options = {}) {
|
|
|
24812
24897
|
\u{1F4E6} Updating ${packageId}: ${currentVersion} \u2192 ${latestVersion}`
|
|
24813
24898
|
);
|
|
24814
24899
|
const targetFormat = pkg.format || installedFormat;
|
|
24815
|
-
|
|
24816
|
-
|
|
24817
|
-
|
|
24900
|
+
const installOptions = { as: targetFormat };
|
|
24901
|
+
const preservedGlobal = getPreservedGlobal(pkg, location);
|
|
24902
|
+
const preservedEditor = getPreservedEditor(pkg);
|
|
24903
|
+
if (preservedGlobal !== void 0) {
|
|
24904
|
+
installOptions.global = preservedGlobal;
|
|
24905
|
+
}
|
|
24906
|
+
if (preservedEditor) {
|
|
24907
|
+
installOptions.editor = preservedEditor;
|
|
24908
|
+
}
|
|
24909
|
+
await handleInstall(`${packageId}@${latestVersion}`, installOptions);
|
|
24818
24910
|
updatedCount++;
|
|
24819
24911
|
} catch (err) {
|
|
24820
24912
|
console.error(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prpm",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.39",
|
|
4
4
|
"description": "Prompt Package Manager CLI - Install and manage prompt-based files",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"license": "MIT",
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@octokit/rest": "^22.0.0",
|
|
48
|
-
"@pr-pm/converters": "^2.1.
|
|
49
|
-
"@pr-pm/registry-client": "^2.3.
|
|
50
|
-
"@pr-pm/types": "^2.1.
|
|
48
|
+
"@pr-pm/converters": "^2.1.40",
|
|
49
|
+
"@pr-pm/registry-client": "^2.3.39",
|
|
50
|
+
"@pr-pm/types": "^2.1.40",
|
|
51
51
|
"ajv": "^8.17.1",
|
|
52
52
|
"ajv-formats": "^3.0.1",
|
|
53
53
|
"chalk": "^5.6.2",
|