prpm 2.1.8 → 2.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -204,6 +204,15 @@ function removeCollectionFromLockfile(lockfile, collectionKey) {
204
204
  delete lockfile.collections[collectionKey];
205
205
  lockfile.generated = (/* @__PURE__ */ new Date()).toISOString();
206
206
  }
207
+ function listCollectionsFromLockfile(lockfile) {
208
+ if (!lockfile || !lockfile.collections) {
209
+ return [];
210
+ }
211
+ return Object.entries(lockfile.collections).map(([key, collection]) => ({
212
+ key,
213
+ ...collection
214
+ }));
215
+ }
207
216
  var import_fs, import_path, import_crypto, LOCKFILE_NAME, LOCKFILE_VERSION;
208
217
  var init_lockfile = __esm({
209
218
  "src/core/lockfile.ts"() {
@@ -17589,7 +17598,9 @@ async function installFromLockfile(options) {
17589
17598
  // Force reinstall when installing from lockfile
17590
17599
  location: locationOverride,
17591
17600
  manifestFile,
17592
- hookMapping: options.hookMapping
17601
+ hookMapping: options.hookMapping,
17602
+ fromCollection: lockEntry.fromCollection
17603
+ // Preserve collection metadata
17593
17604
  });
17594
17605
  successCount++;
17595
17606
  } catch (error) {
@@ -21302,6 +21313,9 @@ function getManifestSchema() {
21302
21313
  }
21303
21314
 
21304
21315
  // src/utils/manifest-loader.ts
21316
+ function toOrganizationSlug(value) {
21317
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").replace(/-+/g, "-");
21318
+ }
21305
21319
  async function findAndLoadManifests() {
21306
21320
  const prpmJsonPath = (0, import_path17.join)(process.cwd(), "prpm.json");
21307
21321
  let prpmJsonExists = false;
@@ -21502,8 +21516,8 @@ function normalizeFilePaths2(files) {
21502
21516
  function predictScopedPackageName(manifestName, username, organization) {
21503
21517
  const usernameLowercase = username.toLowerCase();
21504
21518
  if (organization) {
21505
- const orgNameLowercase = organization.toLowerCase();
21506
- const expectedPrefix = `@${orgNameLowercase}/`;
21519
+ const orgSlug = toOrganizationSlug(organization);
21520
+ const expectedPrefix = `@${orgSlug}/`;
21507
21521
  if (!manifestName.startsWith(expectedPrefix)) {
21508
21522
  return `${expectedPrefix}${manifestName}`;
21509
21523
  }
@@ -21598,6 +21612,7 @@ function formatTarballSize(sizeInBytes) {
21598
21612
 
21599
21613
  // src/commands/publish.ts
21600
21614
  init_init();
21615
+ var toOrgSlug = (value) => value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").replace(/-+/g, "-");
21601
21616
  async function listPackages2() {
21602
21617
  const { manifests, collections, source } = await findAndLoadManifests();
21603
21618
  console.log(`
@@ -21827,6 +21842,7 @@ ${"=".repeat(60)}`);
21827
21842
  let lastError = null;
21828
21843
  let retryCount = 0;
21829
21844
  let publishSuccess = false;
21845
+ let sawGatewayLikeError = false;
21830
21846
  while (retryCount <= MAX_RETRIES && !publishSuccess) {
21831
21847
  try {
21832
21848
  if (retryCount > 0 && RETRY_DELAY_MS > 0) {
@@ -21865,9 +21881,11 @@ ${"=".repeat(60)}`);
21865
21881
  }
21866
21882
  let selectedOrgId;
21867
21883
  let selectedOrgName;
21884
+ let selectedOrgSlug;
21868
21885
  if (manifest.organization && userInfo) {
21886
+ const manifestOrgSlug = toOrgSlug(manifest.organization);
21869
21887
  const orgFromManifest = (_a = userInfo.organizations) == null ? void 0 : _a.find(
21870
- (org) => org.name === manifest.organization || org.id === manifest.organization
21888
+ (org) => org.id === manifest.organization || org.name === manifest.organization || org.slug && typeof org.slug === "string" && org.slug.toLowerCase() === manifestOrgSlug || org.name && toOrgSlug(typeof org.name === "string" ? org.name : "") === manifestOrgSlug
21871
21889
  );
21872
21890
  if (!orgFromManifest) {
21873
21891
  throw new Error(
@@ -21881,6 +21899,7 @@ ${"=".repeat(60)}`);
21881
21899
  }
21882
21900
  selectedOrgId = orgFromManifest.id;
21883
21901
  selectedOrgName = orgFromManifest.name;
21902
+ selectedOrgSlug = (typeof orgFromManifest.slug === "string" ? orgFromManifest.slug : void 0) || (orgFromManifest.name ? toOrgSlug(String(orgFromManifest.name)) : void 0);
21884
21903
  }
21885
21904
  let publishAsAuthor;
21886
21905
  if ((userInfo == null ? void 0 : userInfo.is_admin) && manifest.author) {
@@ -21889,7 +21908,7 @@ ${"=".repeat(60)}`);
21889
21908
  const scopedPackageName = predictScopedPackageName(
21890
21909
  manifest.name,
21891
21910
  (userInfo == null ? void 0 : userInfo.username) || config.username || "unknown",
21892
- selectedOrgName || manifest.organization
21911
+ selectedOrgSlug || manifest.organization
21893
21912
  );
21894
21913
  console.log(` Source: ${source}`);
21895
21914
  console.log(` Package: ${scopedPackageName}@${manifest.version}`);
@@ -22020,7 +22039,40 @@ ${"=".repeat(60)}`);
22020
22039
  userInfo,
22021
22040
  packageName
22022
22041
  );
22042
+ if (sawGatewayLikeError && pkgError.toLowerCase().includes("version already exists")) {
22043
+ const assumedName = predictScopedPackageName(
22044
+ manifest.name,
22045
+ (userInfo == null ? void 0 : userInfo.username) || config.username || "unknown",
22046
+ manifest.organization
22047
+ );
22048
+ let webappUrl;
22049
+ const registryUrl = config.registryUrl || "https://registry.prpm.dev";
22050
+ if (registryUrl.includes("localhost") || registryUrl.includes("127.0.0.1")) {
22051
+ webappUrl = "http://localhost:5173";
22052
+ } else if (registryUrl.includes("registry.prpm.dev")) {
22053
+ webappUrl = "https://prpm.dev";
22054
+ } else {
22055
+ webappUrl = registryUrl;
22056
+ }
22057
+ const packageSlug = assumedName.startsWith("@") ? assumedName.slice(1) : assumedName;
22058
+ const packagePath = packageSlug.split("/").map((segment) => encodeURIComponent(segment)).join("/");
22059
+ const packageUrl = `${webappUrl}/packages/${packagePath}`;
22060
+ console.log(
22061
+ `
22062
+ \u2705 ${displayName}@${manifest.version} now exists on the registry after a transient gateway error; assuming publish succeeded.`
22063
+ );
22064
+ publishedPackages.push({
22065
+ name: assumedName,
22066
+ version: manifest.version,
22067
+ url: packageUrl
22068
+ });
22069
+ publishSuccess = true;
22070
+ break;
22071
+ }
22023
22072
  if (isRetriableError(pkgError) && retryCount < MAX_RETRIES) {
22073
+ if (pkgError.includes("Bad Gateway") || pkgError.includes("Service Unavailable") || pkgError.includes("502") || pkgError.includes("503") || pkgError.includes("504")) {
22074
+ sawGatewayLikeError = true;
22075
+ }
22024
22076
  console.error(
22025
22077
  `
22026
22078
  \u26A0\uFE0F Temporary error publishing ${displayName}: ${pkgError}`
@@ -22744,6 +22796,7 @@ init_install();
22744
22796
  init_telemetry();
22745
22797
  init_errors();
22746
22798
  async function handleUpgrade(packageName, options = {}) {
22799
+ var _a;
22747
22800
  const startTime = Date.now();
22748
22801
  let success = false;
22749
22802
  let error;
@@ -22805,6 +22858,82 @@ ${emoji} Upgrading ${packageId}: ${currentVersion} \u2192 ${latestVersion} (${up
22805
22858
  );
22806
22859
  }
22807
22860
  }
22861
+ if (!packageName) {
22862
+ const lockfile = await readLockfile();
22863
+ if (lockfile) {
22864
+ const installedCollections = listCollectionsFromLockfile(lockfile);
22865
+ for (const collection of installedCollections) {
22866
+ try {
22867
+ const latestCollection = await client.getCollection(
22868
+ collection.name_slug
22869
+ );
22870
+ if (!latestCollection) continue;
22871
+ const currentVersion = collection.version;
22872
+ const latestVersion = latestCollection.version || "1.0.0";
22873
+ if (currentVersion !== latestVersion) {
22874
+ console.log(
22875
+ `
22876
+ \u{1F4E6} Collection ${collection.name_slug}: ${currentVersion} \u2192 ${latestVersion}`
22877
+ );
22878
+ const installedPackageIds = new Set(collection.packages);
22879
+ const newPackages = latestCollection.packages.filter(
22880
+ (pkg) => {
22881
+ var _a2;
22882
+ return !installedPackageIds.has(((_a2 = pkg.package) == null ? void 0 : _a2.name) || "");
22883
+ }
22884
+ );
22885
+ if (newPackages.length > 0) {
22886
+ console.log(
22887
+ ` \u{1F4E5} ${newPackages.length} new package(s) added to collection`
22888
+ );
22889
+ const existingCollectionPkg = installedPackages.find(
22890
+ (p) => {
22891
+ var _a2;
22892
+ return ((_a2 = p.fromCollection) == null ? void 0 : _a2.name_slug) === collection.name_slug;
22893
+ }
22894
+ );
22895
+ const collectionFormat = existingCollectionPkg == null ? void 0 : existingCollectionPkg.format;
22896
+ for (const pkg of newPackages) {
22897
+ const pkgName = (_a = pkg.package) == null ? void 0 : _a.name;
22898
+ if (!pkgName) continue;
22899
+ try {
22900
+ console.log(` \u{1F4E5} Installing new package: ${pkgName}`);
22901
+ await handleInstall(`${pkgName}@${pkg.version || "latest"}`, {
22902
+ as: collectionFormat,
22903
+ fromCollection: {
22904
+ name_slug: collection.name_slug,
22905
+ version: latestVersion
22906
+ }
22907
+ });
22908
+ upgradedCount++;
22909
+ } catch (err) {
22910
+ console.error(
22911
+ ` \u274C Failed to install ${pkgName}: ${err instanceof Error ? err.message : String(err)}`
22912
+ );
22913
+ }
22914
+ }
22915
+ }
22916
+ addCollectionToLockfile(lockfile, collection.name_slug, {
22917
+ name_slug: collection.name_slug,
22918
+ version: latestVersion,
22919
+ packages: [
22920
+ ...collection.packages,
22921
+ ...newPackages.map((p) => {
22922
+ var _a2;
22923
+ return (_a2 = p.package) == null ? void 0 : _a2.name;
22924
+ }).filter((n) => !!n)
22925
+ ]
22926
+ });
22927
+ await writeLockfile(lockfile);
22928
+ }
22929
+ } catch (err) {
22930
+ console.error(
22931
+ ` \u26A0\uFE0F Could not check collection ${collection.name_slug}: ${err instanceof Error ? err.message : String(err)}`
22932
+ );
22933
+ }
22934
+ }
22935
+ }
22936
+ }
22808
22937
  if (upgradedCount === 0) {
22809
22938
  console.log("\n\u2705 All packages are at the latest version!\n");
22810
22939
  } else {
@@ -147,10 +147,11 @@
147
147
  },
148
148
  "organization": {
149
149
  "type": "string",
150
- "description": "Organization name or ID to publish this package under. If not specified, publishes to personal account.",
150
+ "description": "Organization slug or ID to publish this package under (used for package scope). If not specified, publishes to personal account. Slugs should be lowercase, alphanumeric with hyphens (spaces removed).",
151
151
  "examples": [
152
152
  "my-team",
153
- "my-company"
153
+ "my-company",
154
+ "my-senior-dev"
154
155
  ]
155
156
  },
156
157
  "private": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prpm",
3
- "version": "2.1.8",
3
+ "version": "2.1.10",
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.9",
49
- "@pr-pm/registry-client": "^2.3.8",
50
- "@pr-pm/types": "^2.1.9",
48
+ "@pr-pm/converters": "^2.1.11",
49
+ "@pr-pm/registry-client": "^2.3.10",
50
+ "@pr-pm/types": "^2.1.11",
51
51
  "ajv": "^8.17.1",
52
52
  "ajv-formats": "^3.0.1",
53
53
  "commander": "^11.1.0",
@@ -147,10 +147,11 @@
147
147
  },
148
148
  "organization": {
149
149
  "type": "string",
150
- "description": "Organization name or ID to publish this package under. If not specified, publishes to personal account.",
150
+ "description": "Organization slug or ID to publish this package under (used for package scope). If not specified, publishes to personal account. Slugs should be lowercase, alphanumeric with hyphens (spaces removed).",
151
151
  "examples": [
152
152
  "my-team",
153
- "my-company"
153
+ "my-company",
154
+ "my-senior-dev"
154
155
  ]
155
156
  },
156
157
  "private": {