prpm 1.1.19 → 1.1.20

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.
Files changed (2) hide show
  1. package/dist/index.js +849 -588
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -10849,7 +10849,7 @@ var init_to_replit = __esm({
10849
10849
  });
10850
10850
 
10851
10851
  // ../converters/dist/schema-files.js
10852
- var import_module, import_path6, schemaRequire, convertersPackagePath, convertersDir, loadSchema2, agentsMdSchema, canonicalSchema, claudeSchema, continueSchema, copilotSchema, cursorSchema, droidSchema, geminiMdSchema, geminiSchema, kiroSteeringSchema, opencodeSchema, rulerSchema, windsurfSchema, traeSchema, aiderSchema, zencoderSchema, replitSchema, claudeAgentSchema, claudeHookSchema, claudeSkillSchema, claudeSlashCommandSchema, cursorCommandSchema, droidHookSchema, droidSkillSchema, droidSlashCommandSchema, kiroAgentSchema, kiroHookSchema, opencodeSlashCommandSchema;
10852
+ var import_module, import_path6, schemaRequire, convertersPackagePath, convertersDir, loadSchema2, formatRegistrySchema, agentsMdSchema, canonicalSchema, claudeSchema, continueSchema, copilotSchema, cursorSchema, droidSchema, geminiMdSchema, geminiSchema, kiroSteeringSchema, opencodeSchema, rulerSchema, windsurfSchema, traeSchema, aiderSchema, zencoderSchema, replitSchema, claudeAgentSchema, claudeHookSchema, claudeSkillSchema, claudeSlashCommandSchema, cursorCommandSchema, droidHookSchema, droidSkillSchema, droidSlashCommandSchema, kiroAgentSchema, kiroHookSchema, opencodeSlashCommandSchema;
10853
10853
  var init_schema_files = __esm({
10854
10854
  "../converters/dist/schema-files.js"() {
10855
10855
  "use strict";
@@ -10860,6 +10860,7 @@ var init_schema_files = __esm({
10860
10860
  convertersPackagePath = schemaRequire.resolve("@pr-pm/converters/package.json");
10861
10861
  convertersDir = (0, import_path6.dirname)(convertersPackagePath);
10862
10862
  loadSchema2 = (filename) => schemaRequire((0, import_path6.join)(convertersDir, "schemas", filename));
10863
+ formatRegistrySchema = loadSchema2("format-registry.schema.json");
10863
10864
  agentsMdSchema = loadSchema2("agents-md.schema.json");
10864
10865
  canonicalSchema = loadSchema2("canonical.schema.json");
10865
10866
  claudeSchema = loadSchema2("claude.schema.json");
@@ -10896,7 +10897,7 @@ var format_registry_default;
10896
10897
  var init_format_registry = __esm({
10897
10898
  "../converters/dist/format-registry.json"() {
10898
10899
  format_registry_default = {
10899
- $schema: "../schemas/format-registry.schema.json",
10900
+ $schema: "https://registry.prpm.dev/api/v1/schemas/format-registry.json",
10900
10901
  version: "1.0.0",
10901
10902
  formats: {
10902
10903
  cursor: {
@@ -10907,7 +10908,7 @@ var init_format_registry = __esm({
10907
10908
  subtypes: {
10908
10909
  rule: {
10909
10910
  directory: ".cursor/rules",
10910
- filePatterns: ["*.mdc", "*.md"],
10911
+ filePatterns: ["*.mdc"],
10911
10912
  fileExtension: ".mdc"
10912
10913
  },
10913
10914
  agent: {
@@ -11067,8 +11068,9 @@ var init_format_registry = __esm({
11067
11068
  subtypes: {
11068
11069
  skill: {
11069
11070
  directory: ".factory/skills",
11070
- filePatterns: ["*.md"],
11071
+ filePatterns: ["SKILL.md", "skill.mdx"],
11071
11072
  nested: true,
11073
+ nestedIndicator: "SKILL.md",
11072
11074
  usesPackageSubdirectory: true,
11073
11075
  fileExtension: ".md"
11074
11076
  },
@@ -11353,6 +11355,7 @@ __export(dist_exports, {
11353
11355
  droidSlashCommandSchema: () => droidSlashCommandSchema,
11354
11356
  findFormatByRootFile: () => findFormatByRootFile,
11355
11357
  formatRegistry: () => formatRegistry,
11358
+ formatRegistrySchema: () => formatRegistrySchema,
11356
11359
  formatValidationErrors: () => formatValidationErrors,
11357
11360
  fromAgentsMd: () => fromAgentsMd,
11358
11361
  fromAider: () => fromAider,
@@ -14187,6 +14190,62 @@ function getPackageLabel2(format, subtype) {
14187
14190
  }
14188
14191
  return `${formatLabel} ${subtypeLabel}`;
14189
14192
  }
14193
+ function findMainFile(files, format, subtype) {
14194
+ const nestedIndicator = getNestedIndicator(format, subtype);
14195
+ if (nestedIndicator) {
14196
+ const match = files.find((f) => {
14197
+ const filename = import_path10.default.basename(f.name);
14198
+ return filename.toLowerCase() === nestedIndicator.toLowerCase();
14199
+ });
14200
+ if (match) return match;
14201
+ }
14202
+ const filePatterns = getFilePatterns(format, subtype);
14203
+ if (filePatterns) {
14204
+ for (const pattern of filePatterns) {
14205
+ for (const file of files) {
14206
+ const filename = import_path10.default.basename(file.name);
14207
+ if (pattern.startsWith("*")) {
14208
+ const extension = pattern.slice(1);
14209
+ if (filename.endsWith(extension)) {
14210
+ return file;
14211
+ }
14212
+ } else {
14213
+ if (filename.toLowerCase() === pattern.toLowerCase()) {
14214
+ return file;
14215
+ }
14216
+ }
14217
+ }
14218
+ }
14219
+ }
14220
+ const fallbackPatterns = [
14221
+ "SKILL.md",
14222
+ "skill.md",
14223
+ "agent.md",
14224
+ "AGENT.md",
14225
+ "command.md",
14226
+ "COMMAND.md",
14227
+ "rule.md",
14228
+ "RULE.md",
14229
+ "index.md",
14230
+ "INDEX.md",
14231
+ "main.md",
14232
+ "MAIN.md",
14233
+ "README.md"
14234
+ ];
14235
+ for (const pattern of fallbackPatterns) {
14236
+ for (const file of files) {
14237
+ const filename = import_path10.default.basename(file.name);
14238
+ if (filename.toLowerCase() === pattern.toLowerCase()) {
14239
+ return file;
14240
+ }
14241
+ }
14242
+ }
14243
+ const mdFile = files.find((f) => f.name.endsWith(".md"));
14244
+ if (mdFile) {
14245
+ return mdFile;
14246
+ }
14247
+ return null;
14248
+ }
14190
14249
  async function handleInstall(packageSpec, options) {
14191
14250
  var _a;
14192
14251
  const startTime = Date.now();
@@ -14379,10 +14438,19 @@ This could indicate:
14379
14438
  let extractedFiles = await extractTarball(tarball, packageId);
14380
14439
  if (options.as && format && format !== pkg.format) {
14381
14440
  console.log(` \u{1F504} Converting from ${pkg.format} to ${format}...`);
14382
- if (extractedFiles.length !== 1) {
14383
- throw new CLIError("Format conversion is only supported for single-file packages");
14441
+ let sourceContent;
14442
+ if (extractedFiles.length === 1) {
14443
+ sourceContent = extractedFiles[0].content;
14444
+ } else {
14445
+ const mainFile = findMainFile(extractedFiles, pkg.format, pkg.subtype);
14446
+ if (!mainFile) {
14447
+ throw new CLIError(
14448
+ `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.`
14449
+ );
14450
+ }
14451
+ console.log(` \u{1F4C4} Using main file: ${mainFile.name}`);
14452
+ sourceContent = mainFile.content;
14384
14453
  }
14385
- const sourceContent = extractedFiles[0].content;
14386
14454
  const scopeMatch = packageId.match(/^@([^/]+)\//);
14387
14455
  const author = scopeMatch ? scopeMatch[1] : "unknown";
14388
14456
  const metadata = {
@@ -15186,7 +15254,7 @@ async function fileExists2(filePath) {
15186
15254
  }
15187
15255
  async function scanDirectory2(config, cwd) {
15188
15256
  const packages = [];
15189
- const fullDir = import_path14.default.join(cwd, config.directory);
15257
+ const fullDir = import_path16.default.join(cwd, config.directory);
15190
15258
  if (!await directoryExists2(fullDir)) {
15191
15259
  return packages;
15192
15260
  }
@@ -15194,13 +15262,13 @@ async function scanDirectory2(config, cwd) {
15194
15262
  if (config.nested) {
15195
15263
  for (const entry of entries) {
15196
15264
  if (!entry.isDirectory()) continue;
15197
- const packageDir = import_path14.default.join(fullDir, entry.name);
15265
+ const packageDir = import_path16.default.join(fullDir, entry.name);
15198
15266
  if (config.nestedIndicator) {
15199
- const indicatorPath = import_path14.default.join(packageDir, config.nestedIndicator);
15267
+ const indicatorPath = import_path16.default.join(packageDir, config.nestedIndicator);
15200
15268
  if (!await fileExists2(indicatorPath)) continue;
15201
15269
  const packageFiles = await collectPackageFiles(packageDir, config.directory, entry.name);
15202
15270
  const metadata = await extractMetadata2(indicatorPath);
15203
- const relativePath = import_path14.default.join(config.directory, entry.name, config.nestedIndicator);
15271
+ const relativePath = import_path16.default.join(config.directory, entry.name, config.nestedIndicator);
15204
15272
  packages.push({
15205
15273
  name: metadata.name || filenameToPackageName(entry.name),
15206
15274
  format: config.format,
@@ -15215,8 +15283,8 @@ async function scanDirectory2(config, cwd) {
15215
15283
  for (const subEntry of subEntries) {
15216
15284
  if (!subEntry.isFile()) continue;
15217
15285
  if (!matchesPattern(subEntry.name, config.patterns)) continue;
15218
- const filePath = import_path14.default.join(packageDir, subEntry.name);
15219
- const relativePath = import_path14.default.join(config.directory, entry.name, subEntry.name);
15286
+ const filePath = import_path16.default.join(packageDir, subEntry.name);
15287
+ const relativePath = import_path16.default.join(config.directory, entry.name, subEntry.name);
15220
15288
  const metadata = await extractMetadata2(filePath);
15221
15289
  packages.push({
15222
15290
  name: metadata.name || filenameToPackageName(entry.name),
@@ -15234,8 +15302,8 @@ async function scanDirectory2(config, cwd) {
15234
15302
  for (const entry of entries) {
15235
15303
  if (!entry.isFile()) continue;
15236
15304
  if (!matchesPattern(entry.name, config.patterns)) continue;
15237
- const filePath = import_path14.default.join(fullDir, entry.name);
15238
- const relativePath = import_path14.default.join(config.directory, entry.name);
15305
+ const filePath = import_path16.default.join(fullDir, entry.name);
15306
+ const relativePath = import_path16.default.join(config.directory, entry.name);
15239
15307
  const metadata = await extractMetadata2(filePath);
15240
15308
  packages.push({
15241
15309
  name: metadata.name || filenameToPackageName(entry.name),
@@ -15255,22 +15323,22 @@ async function collectPackageFiles(packageDir, baseDir, packageName) {
15255
15323
  async function walkDir(dir, relativeBase) {
15256
15324
  const entries = await import_fs12.promises.readdir(dir, { withFileTypes: true });
15257
15325
  for (const entry of entries) {
15258
- const fullPath = import_path14.default.join(dir, entry.name);
15259
- const relativePath = import_path14.default.join(relativeBase, entry.name);
15326
+ const fullPath = import_path16.default.join(dir, entry.name);
15327
+ const relativePath = import_path16.default.join(relativeBase, entry.name);
15260
15328
  if (entry.isDirectory()) {
15261
15329
  if (["node_modules", "dist", ".git", "coverage"].includes(entry.name)) {
15262
15330
  continue;
15263
15331
  }
15264
15332
  await walkDir(fullPath, relativePath);
15265
15333
  } else if (entry.isFile()) {
15266
- const ext = import_path14.default.extname(entry.name).toLowerCase();
15334
+ const ext = import_path16.default.extname(entry.name).toLowerCase();
15267
15335
  if ([".md", ".json", ".js", ".ts", ".toml"].includes(ext)) {
15268
15336
  files.push(relativePath);
15269
15337
  }
15270
15338
  }
15271
15339
  }
15272
15340
  }
15273
- await walkDir(packageDir, import_path14.default.join(baseDir, packageName));
15341
+ await walkDir(packageDir, import_path16.default.join(baseDir, packageName));
15274
15342
  return files;
15275
15343
  }
15276
15344
  function buildRootManifestFiles() {
@@ -15292,7 +15360,7 @@ async function scanForPackages(cwd = process.cwd()) {
15292
15360
  allPackages.push(...packages);
15293
15361
  }
15294
15362
  for (const { file, format } of ROOT_MANIFEST_FILES) {
15295
- const filePath = import_path14.default.join(cwd, file);
15363
+ const filePath = import_path16.default.join(cwd, file);
15296
15364
  if (await fileExists2(filePath)) {
15297
15365
  const metadata = await extractMetadata2(filePath);
15298
15366
  allPackages.push({
@@ -15306,7 +15374,7 @@ async function scanForPackages(cwd = process.cwd()) {
15306
15374
  });
15307
15375
  }
15308
15376
  }
15309
- const copilotInstructionsPath = import_path14.default.join(cwd, ".github/copilot-instructions.md");
15377
+ const copilotInstructionsPath = import_path16.default.join(cwd, ".github/copilot-instructions.md");
15310
15378
  if (await fileExists2(copilotInstructionsPath)) {
15311
15379
  const metadata = await extractMetadata2(copilotInstructionsPath);
15312
15380
  allPackages.push({
@@ -15321,13 +15389,13 @@ async function scanForPackages(cwd = process.cwd()) {
15321
15389
  }
15322
15390
  return allPackages;
15323
15391
  }
15324
- var import_fs12, import_path14, SCAN_CONFIGS, ROOT_MANIFEST_FILES;
15392
+ var import_fs12, import_path16, SCAN_CONFIGS, ROOT_MANIFEST_FILES;
15325
15393
  var init_package_scanner = __esm({
15326
15394
  "src/core/package-scanner.ts"() {
15327
15395
  "use strict";
15328
15396
  init_cjs_shims();
15329
15397
  import_fs12 = require("fs");
15330
- import_path14 = __toESM(require("path"));
15398
+ import_path16 = __toESM(require("path"));
15331
15399
  init_dist();
15332
15400
  SCAN_CONFIGS = buildScanConfigs();
15333
15401
  ROOT_MANIFEST_FILES = buildRootManifestFiles();
@@ -15337,7 +15405,7 @@ var init_package_scanner = __esm({
15337
15405
  // src/core/package-reconciler.ts
15338
15406
  async function readManifest(cwd = process.cwd()) {
15339
15407
  try {
15340
- const manifestPath = import_path15.default.join(cwd, "prpm.json");
15408
+ const manifestPath = import_path17.default.join(cwd, "prpm.json");
15341
15409
  const content = await import_fs13.promises.readFile(manifestPath, "utf-8");
15342
15410
  const raw = JSON.parse(content);
15343
15411
  if ("packages" in raw && Array.isArray(raw.packages)) {
@@ -15420,7 +15488,7 @@ async function reconcilePackages(detected, manifest, cwd = process.cwd()) {
15420
15488
  const manifestPkg = manifest[mi];
15421
15489
  let anyFileExists = false;
15422
15490
  for (const file of manifestPkg.files) {
15423
- const fullPath = import_path15.default.join(cwd, file);
15491
+ const fullPath = import_path17.default.join(cwd, file);
15424
15492
  if (await fileExists3(fullPath)) {
15425
15493
  anyFileExists = true;
15426
15494
  break;
@@ -15489,7 +15557,7 @@ function createManifestFromDetected(packages, defaults) {
15489
15557
  files: pkg.files
15490
15558
  };
15491
15559
  }
15492
- const projectName = import_path15.default.basename(process.cwd()).toLowerCase().replace(/[^a-z0-9-]/g, "-");
15560
+ const projectName = import_path17.default.basename(process.cwd()).toLowerCase().replace(/[^a-z0-9-]/g, "-");
15493
15561
  return {
15494
15562
  name: `${projectName}-packages`,
15495
15563
  version: "1.0.0",
@@ -15500,13 +15568,13 @@ function createManifestFromDetected(packages, defaults) {
15500
15568
  packages: packages.map(detectedToManifest)
15501
15569
  };
15502
15570
  }
15503
- var import_fs13, import_path15;
15571
+ var import_fs13, import_path17;
15504
15572
  var init_package_reconciler = __esm({
15505
15573
  "src/core/package-reconciler.ts"() {
15506
15574
  "use strict";
15507
15575
  init_cjs_shims();
15508
15576
  import_fs13 = require("fs");
15509
- import_path15 = __toESM(require("path"));
15577
+ import_path17 = __toESM(require("path"));
15510
15578
  }
15511
15579
  });
15512
15580
 
@@ -15557,7 +15625,7 @@ ${question}`);
15557
15625
  }
15558
15626
  async function extractMetadataFromFile(filePath) {
15559
15627
  try {
15560
- const content = await (0, import_promises6.readFile)(filePath, "utf-8");
15628
+ const content = await (0, import_promises8.readFile)(filePath, "utf-8");
15561
15629
  const metadata = {};
15562
15630
  const frontmatterMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
15563
15631
  if (frontmatterMatch) {
@@ -15621,10 +15689,10 @@ function getDefaultAuthor() {
15621
15689
  async function createExampleFiles(format, files, packageName) {
15622
15690
  const templates = EXAMPLE_TEMPLATES[format] || {};
15623
15691
  for (const file of files) {
15624
- const filePath = (0, import_path16.join)(process.cwd(), file);
15625
- const dirPath = (0, import_path16.join)(filePath, "..");
15692
+ const filePath = (0, import_path18.join)(process.cwd(), file);
15693
+ const dirPath = (0, import_path18.join)(filePath, "..");
15626
15694
  if (!(0, import_fs14.existsSync)(dirPath)) {
15627
- await (0, import_promises6.mkdir)(dirPath, { recursive: true });
15695
+ await (0, import_promises8.mkdir)(dirPath, { recursive: true });
15628
15696
  }
15629
15697
  if ((0, import_fs14.existsSync)(filePath)) {
15630
15698
  console.log(` Skipping ${file} (already exists)`);
@@ -15635,12 +15703,12 @@ async function createExampleFiles(format, files, packageName) {
15635
15703
  Add your content here.
15636
15704
  `;
15637
15705
  content = content.replace(/example-skill/g, packageName);
15638
- await (0, import_promises6.writeFile)(filePath, content, "utf-8");
15706
+ await (0, import_promises8.writeFile)(filePath, content, "utf-8");
15639
15707
  console.log(` Created ${file}`);
15640
15708
  }
15641
15709
  }
15642
15710
  async function createReadme(config) {
15643
- const readmePath = (0, import_path16.join)(process.cwd(), "README.md");
15711
+ const readmePath = (0, import_path18.join)(process.cwd(), "README.md");
15644
15712
  if ((0, import_fs14.existsSync)(readmePath)) {
15645
15713
  console.log(" Skipping README.md (already exists)");
15646
15714
  return;
@@ -15671,7 +15739,7 @@ ${config.author}
15671
15739
 
15672
15740
  ${config.license}
15673
15741
  `;
15674
- await (0, import_promises6.writeFile)(readmePath, content, "utf-8");
15742
+ await (0, import_promises8.writeFile)(readmePath, content, "utf-8");
15675
15743
  console.log(" Created README.md");
15676
15744
  }
15677
15745
  function displayPackagesTable(packages) {
@@ -15750,7 +15818,7 @@ async function reviewMissingPackage(rl, pkg, index, total) {
15750
15818
  return await confirm(rl, "\n Remove from prpm.json?", true);
15751
15819
  }
15752
15820
  async function smartInit(options) {
15753
- const manifestPath = (0, import_path16.join)(process.cwd(), "prpm.json");
15821
+ const manifestPath = (0, import_path18.join)(process.cwd(), "prpm.json");
15754
15822
  const hasManifest = (0, import_fs14.existsSync)(manifestPath);
15755
15823
  console.log("\nScanning for packages...\n");
15756
15824
  const detected = await scanForPackages();
@@ -15824,7 +15892,7 @@ ${summaryParts.join(" and ")} package${changes === 1 ? "" : "s"}?`,
15824
15892
  packagesToRemove,
15825
15893
  existingManifest.isMultiPackage
15826
15894
  );
15827
- await (0, import_promises6.writeFile)(
15895
+ await (0, import_promises8.writeFile)(
15828
15896
  manifestPath,
15829
15897
  JSON.stringify(updatedManifest, null, 2) + "\n",
15830
15898
  "utf-8"
@@ -15883,7 +15951,7 @@ Create multi-package prpm.json with these ${detected.length} packages?` : "\nCre
15883
15951
  author: defaultAuthor || void 0,
15884
15952
  license: "MIT"
15885
15953
  });
15886
- await (0, import_promises6.writeFile)(
15954
+ await (0, import_promises8.writeFile)(
15887
15955
  manifestPath,
15888
15956
  JSON.stringify(manifest, null, 2) + "\n",
15889
15957
  "utf-8"
@@ -15901,7 +15969,7 @@ Create multi-package prpm.json with these ${detected.length} packages?` : "\nCre
15901
15969
  }
15902
15970
  }
15903
15971
  async function classicInit(options) {
15904
- const manifestPath = (0, import_path16.join)(process.cwd(), "prpm.json");
15972
+ const manifestPath = (0, import_path18.join)(process.cwd(), "prpm.json");
15905
15973
  if ((0, import_fs14.existsSync)(manifestPath) && !options.force) {
15906
15974
  throw new Error(
15907
15975
  "prpm.json already exists. Use --force to overwrite, or run this command in a different directory."
@@ -16073,7 +16141,7 @@ Current files (${config.files.length}):`);
16073
16141
  manifest.tags = config.tags;
16074
16142
  }
16075
16143
  manifest.files = config.files;
16076
- await (0, import_promises6.writeFile)(
16144
+ await (0, import_promises8.writeFile)(
16077
16145
  manifestPath,
16078
16146
  JSON.stringify(manifest, null, 2) + "\n",
16079
16147
  "utf-8"
@@ -16160,11 +16228,11 @@ async function scanMode(directories, options) {
16160
16228
  console.log("\u{1F50D} Dry run - no changes made\n");
16161
16229
  return;
16162
16230
  }
16163
- const prpmJsonPath = options.output || (0, import_path16.join)(process.cwd(), "prpm.json");
16231
+ const prpmJsonPath = options.output || (0, import_path18.join)(process.cwd(), "prpm.json");
16164
16232
  let manifest;
16165
16233
  if (options.append) {
16166
16234
  try {
16167
- const existingContent = await (0, import_promises6.readFile)(prpmJsonPath, "utf-8");
16235
+ const existingContent = await (0, import_promises8.readFile)(prpmJsonPath, "utf-8");
16168
16236
  const existing = JSON.parse(existingContent);
16169
16237
  if ("packages" in existing && Array.isArray(existing.packages)) {
16170
16238
  manifest = existing;
@@ -16210,7 +16278,7 @@ async function scanMode(directories, options) {
16210
16278
  manifest.packages.push(packageManifest);
16211
16279
  addedCount++;
16212
16280
  }
16213
- await (0, import_promises6.writeFile)(
16281
+ await (0, import_promises8.writeFile)(
16214
16282
  prpmJsonPath,
16215
16283
  JSON.stringify(manifest, null, 2) + "\n",
16216
16284
  "utf-8"
@@ -16262,14 +16330,14 @@ function createInitCommand() {
16262
16330
  });
16263
16331
  return command;
16264
16332
  }
16265
- var import_commander12, import_promises6, import_path16, import_fs14, readline4, import_process, FORMAT_EXAMPLES, EXAMPLE_TEMPLATES;
16333
+ var import_commander12, import_promises8, import_path18, import_fs14, readline4, import_process, FORMAT_EXAMPLES, EXAMPLE_TEMPLATES;
16266
16334
  var init_init = __esm({
16267
16335
  "src/commands/init.ts"() {
16268
16336
  "use strict";
16269
16337
  init_cjs_shims();
16270
16338
  import_commander12 = require("commander");
16271
- import_promises6 = require("fs/promises");
16272
- import_path16 = require("path");
16339
+ import_promises8 = require("fs/promises");
16340
+ import_path18 = require("path");
16273
16341
  import_fs14 = require("fs");
16274
16342
  readline4 = __toESM(require("readline/promises"));
16275
16343
  import_process = require("process");
@@ -16564,7 +16632,7 @@ Include examples if helpful.
16564
16632
  init_cjs_shims();
16565
16633
  var import_commander29 = require("commander");
16566
16634
  var import_fs18 = require("fs");
16567
- var import_path20 = require("path");
16635
+ var import_path22 = require("path");
16568
16636
 
16569
16637
  // src/commands/list.ts
16570
16638
  init_cjs_shims();
@@ -17816,369 +17884,138 @@ init_install();
17816
17884
  // src/commands/publish.ts
17817
17885
  init_cjs_shims();
17818
17886
  var import_commander13 = require("commander");
17819
- var import_promises7 = require("fs/promises");
17820
- var import_path17 = require("path");
17887
+ var import_promises9 = require("fs/promises");
17888
+ var import_path19 = require("path");
17821
17889
  var import_fs15 = require("fs");
17822
- var tar2 = __toESM(require("tar"));
17823
- var import_os4 = require("os");
17824
- var import_crypto2 = require("crypto");
17825
17890
  var import_registry_client6 = require("@pr-pm/registry-client");
17826
17891
  init_user_config();
17827
17892
  init_telemetry();
17828
17893
  init_errors();
17829
17894
 
17830
- // src/core/marketplace-converter.ts
17895
+ // src/utils/license-extractor.ts
17831
17896
  init_cjs_shims();
17832
- function marketplaceToManifest(marketplace, pluginIndex = 0) {
17833
- var _a, _b;
17834
- if (!marketplace.plugins || marketplace.plugins.length === 0) {
17835
- throw new Error("marketplace.json must contain at least one plugin");
17836
- }
17837
- if (pluginIndex >= marketplace.plugins.length) {
17838
- throw new Error(`Plugin index ${pluginIndex} out of range. Found ${marketplace.plugins.length} plugins.`);
17839
- }
17840
- const plugin = marketplace.plugins[pluginIndex];
17841
- let format = "claude";
17842
- let subtype = "rule";
17843
- if (plugin.agents && plugin.agents.length > 0) {
17844
- format = "claude";
17845
- subtype = "agent";
17846
- } else if (plugin.skills && plugin.skills.length > 0) {
17847
- format = "claude";
17848
- subtype = "skill";
17849
- } else if (plugin.commands && plugin.commands.length > 0) {
17850
- format = "claude";
17851
- subtype = "slash-command";
17852
- }
17853
- const ownerName = typeof marketplace.owner === "string" ? marketplace.owner : marketplace.owner.name;
17854
- const packageName = generatePackageName(ownerName, plugin.name);
17855
- const files = collectFiles(plugin);
17856
- const main = determineMainFile(plugin);
17857
- const keywords = [
17858
- ...marketplace.keywords || [],
17859
- ...plugin.keywords || []
17860
- ].slice(0, 20);
17861
- const tags = keywords.slice(0, 10);
17862
- const description = plugin.description || ((_a = marketplace.metadata) == null ? void 0 : _a.description) || marketplace.description || "";
17863
- const version = plugin.version || ((_b = marketplace.metadata) == null ? void 0 : _b.version) || marketplace.version || "1.0.0";
17864
- const author = plugin.author || ownerName;
17865
- const manifest = {
17866
- name: packageName,
17867
- version,
17868
- description,
17869
- format,
17870
- subtype,
17871
- author,
17872
- files,
17873
- tags,
17874
- keywords
17875
- };
17876
- if (marketplace.githubUrl) {
17877
- manifest.repository = marketplace.githubUrl;
17878
- }
17879
- if (marketplace.websiteUrl) {
17880
- manifest.homepage = marketplace.websiteUrl;
17881
- }
17882
- if (plugin.category) {
17883
- manifest.category = plugin.category;
17884
- }
17885
- if (main) {
17886
- manifest.main = main;
17897
+ var import_promises3 = require("fs/promises");
17898
+ var import_path11 = require("path");
17899
+ var import_fs10 = require("fs");
17900
+ var LICENSE_FILE_PATTERNS = [
17901
+ "LICENSE",
17902
+ "LICENSE.md",
17903
+ "LICENSE.txt",
17904
+ "LICENCE",
17905
+ "LICENCE.md",
17906
+ "LICENCE.txt",
17907
+ "LICENSE-MIT",
17908
+ "LICENSE-APACHE",
17909
+ "COPYING",
17910
+ "COPYING.txt"
17911
+ ];
17912
+ var LICENSE_PATTERNS = [
17913
+ { pattern: /MIT License/i, type: "MIT" },
17914
+ { pattern: /Apache License[\s\S]*Version 2\.0/i, type: "Apache-2.0" },
17915
+ { pattern: /GNU GENERAL PUBLIC LICENSE[\s\S]*Version 3/i, type: "GPL-3.0" },
17916
+ { pattern: /GNU GENERAL PUBLIC LICENSE[\s\S]*Version 2/i, type: "GPL-2.0" },
17917
+ { pattern: /GNU LESSER GENERAL PUBLIC LICENSE[\s\S]*Version 3/i, type: "LGPL-3.0" },
17918
+ { pattern: /GNU LESSER GENERAL PUBLIC LICENSE[\s\S]*Version 2/i, type: "LGPL-2.1" },
17919
+ { pattern: /BSD 3-Clause License/i, type: "BSD-3-Clause" },
17920
+ { pattern: /BSD 2-Clause License/i, type: "BSD-2-Clause" },
17921
+ { pattern: /Mozilla Public License[\s\S]*Version 2\.0/i, type: "MPL-2.0" },
17922
+ { pattern: /ISC License/i, type: "ISC" },
17923
+ { pattern: /The Unlicense/i, type: "Unlicense" },
17924
+ { pattern: /Creative Commons Zero[\s\S]*1\.0/i, type: "CC0-1.0" }
17925
+ ];
17926
+ function detectLicenseType(text) {
17927
+ for (const { pattern, type: type2 } of LICENSE_PATTERNS) {
17928
+ if (pattern.test(text)) {
17929
+ return type2;
17930
+ }
17887
17931
  }
17888
- return manifest;
17889
- }
17890
- function generatePackageName(owner, pluginName) {
17891
- const sanitizedOwner = owner.toLowerCase().replace(/[^a-z0-9-]/g, "-");
17892
- const sanitizedName = pluginName.toLowerCase().replace(/[^a-z0-9-]/g, "-");
17893
- const cleanOwner = sanitizedOwner.replace(/^-+|-+$/g, "");
17894
- const cleanName = sanitizedName.replace(/^-+|-+$/g, "");
17895
- return `@${cleanOwner}/${cleanName}`;
17932
+ return null;
17896
17933
  }
17897
- function collectFiles(plugin) {
17898
- const files = /* @__PURE__ */ new Set();
17899
- if (plugin.source && !plugin.source.startsWith("http")) {
17900
- files.add(plugin.source);
17901
- }
17902
- if (plugin.agents) {
17903
- for (const agent of plugin.agents) {
17904
- if (agent.source && !agent.source.startsWith("http")) {
17905
- files.add(agent.source);
17906
- }
17907
- }
17934
+ function generateLicenseUrl(repositoryUrl, fileName) {
17935
+ if (!repositoryUrl) {
17936
+ return null;
17908
17937
  }
17909
- if (plugin.skills) {
17910
- for (const skill of plugin.skills) {
17911
- if (skill.source && !skill.source.startsWith("http")) {
17912
- files.add(skill.source);
17913
- }
17914
- }
17938
+ const githubMatch = repositoryUrl.match(/github\.com[/:]([\w-]+)\/([\w-]+)/);
17939
+ if (!githubMatch) {
17940
+ return null;
17915
17941
  }
17916
- if (plugin.commands) {
17917
- for (const command of plugin.commands) {
17918
- if (command.source && !command.source.startsWith("http")) {
17919
- files.add(command.source);
17920
- }
17942
+ const [, owner, repo] = githubMatch;
17943
+ return `https://raw.githubusercontent.com/${owner}/${repo}/main/${fileName}`;
17944
+ }
17945
+ async function extractLicenseInfo(repositoryUrl) {
17946
+ const cwd = process.cwd();
17947
+ for (const fileName of LICENSE_FILE_PATTERNS) {
17948
+ const filePath = (0, import_path11.join)(cwd, fileName);
17949
+ try {
17950
+ await (0, import_promises3.access)(filePath, import_fs10.constants.R_OK);
17951
+ const text = await (0, import_promises3.readFile)(filePath, "utf-8");
17952
+ const type2 = detectLicenseType(text);
17953
+ const url = generateLicenseUrl(repositoryUrl, fileName);
17954
+ return {
17955
+ type: type2,
17956
+ text,
17957
+ url,
17958
+ fileName
17959
+ };
17960
+ } catch {
17961
+ continue;
17921
17962
  }
17922
17963
  }
17923
- const standardFiles = ["README.md", "LICENSE", ".claude/marketplace.json", ".claude-plugin/marketplace.json"];
17924
- for (const file of standardFiles) {
17925
- files.add(file);
17926
- }
17927
- return Array.from(files);
17964
+ return {
17965
+ type: null,
17966
+ text: null,
17967
+ url: null,
17968
+ fileName: null
17969
+ };
17928
17970
  }
17929
- function determineMainFile(plugin) {
17930
- var _a, _b, _c;
17931
- const agentCount = ((_a = plugin.agents) == null ? void 0 : _a.length) || 0;
17932
- const skillCount = ((_b = plugin.skills) == null ? void 0 : _b.length) || 0;
17933
- const commandCount = ((_c = plugin.commands) == null ? void 0 : _c.length) || 0;
17934
- const totalCount = agentCount + skillCount + commandCount;
17935
- if (totalCount !== 1) {
17936
- return void 0;
17971
+ function validateLicenseInfo(licenseInfo, packageName) {
17972
+ if (licenseInfo.text && licenseInfo.type) {
17973
+ console.log(` License: ${licenseInfo.type} (${licenseInfo.fileName})`);
17974
+ } else if (licenseInfo.text && !licenseInfo.type) {
17975
+ console.log(` License: Found (${licenseInfo.fileName})`);
17976
+ } else {
17977
+ console.log(` License: Not found (package will be published without license)`);
17937
17978
  }
17938
- if (agentCount === 1) {
17939
- const source = plugin.agents[0].source;
17940
- if (source && !source.startsWith("http")) {
17941
- return source;
17979
+ }
17980
+
17981
+ // src/utils/snippet-extractor.ts
17982
+ init_cjs_shims();
17983
+ var import_promises4 = require("fs/promises");
17984
+ var import_path12 = require("path");
17985
+ var MAX_SNIPPET_LENGTH = 2e3;
17986
+ async function extractSnippet(manifest) {
17987
+ const cwd = process.cwd();
17988
+ try {
17989
+ if (!manifest.files || manifest.files.length === 0) {
17990
+ console.warn("\u26A0\uFE0F Cannot extract snippet: no files specified in manifest");
17991
+ return null;
17942
17992
  }
17943
- }
17944
- if (skillCount === 1) {
17945
- const source = plugin.skills[0].source;
17946
- if (source && !source.startsWith("http")) {
17947
- return source;
17993
+ let fileName;
17994
+ if (manifest.main) {
17995
+ fileName = manifest.main;
17996
+ } else {
17997
+ const firstFile = manifest.files[0];
17998
+ fileName = typeof firstFile === "string" ? firstFile : firstFile.path;
17948
17999
  }
17949
- }
17950
- if (commandCount === 1) {
17951
- const source = plugin.commands[0].source;
17952
- if (source && !source.startsWith("http")) {
17953
- return source;
18000
+ const fullPath = (0, import_path12.join)(cwd, fileName);
18001
+ const stats = await (0, import_promises4.stat)(fullPath);
18002
+ if (stats.isDirectory()) {
18003
+ console.warn(`\u26A0\uFE0F Skipping snippet extraction: "${fullPath}" is a directory`);
18004
+ return null;
17954
18005
  }
17955
- }
17956
- if (plugin.source && !plugin.source.startsWith("http")) {
17957
- return plugin.source;
17958
- }
17959
- return void 0;
17960
- }
17961
- function validateMarketplaceJson(data) {
17962
- var _a;
17963
- if (!data || typeof data !== "object") {
17964
- return false;
17965
- }
17966
- const marketplace = data;
17967
- if (!marketplace.name || typeof marketplace.name !== "string") {
17968
- return false;
17969
- }
17970
- if (!marketplace.owner) {
17971
- return false;
17972
- }
17973
- if (typeof marketplace.owner !== "string" && (typeof marketplace.owner !== "object" || !marketplace.owner.name)) {
17974
- return false;
17975
- }
17976
- const hasDescription = marketplace.description && typeof marketplace.description === "string" || ((_a = marketplace.metadata) == null ? void 0 : _a.description) && typeof marketplace.metadata.description === "string";
17977
- if (!hasDescription) {
17978
- return false;
17979
- }
17980
- if (!Array.isArray(marketplace.plugins) || marketplace.plugins.length === 0) {
17981
- return false;
17982
- }
17983
- const plugin = marketplace.plugins[0];
17984
- if (!plugin.name || !plugin.description || !plugin.version) {
17985
- return false;
17986
- }
17987
- return true;
17988
- }
17989
-
17990
- // src/core/schema-validator.ts
17991
- init_cjs_shims();
17992
- var import_ajv2 = __toESM(require("ajv"));
17993
- var import_ajv_formats2 = __toESM(require("ajv-formats"));
17994
- var import_fs10 = require("fs");
17995
- var import_path11 = require("path");
17996
- var schema2;
17997
- var schemaCandidates = [
17998
- // Source file layout (src/core → ../../schemas)
17999
- (0, import_path11.join)(__dirname, "../../schemas/prpm-manifest.schema.json"),
18000
- // Bundled layout (dist/index.js → ../schemas)
18001
- (0, import_path11.join)(__dirname, "../schemas/prpm-manifest.schema.json")
18002
- ];
18003
- for (const candidate of schemaCandidates) {
18004
- try {
18005
- if ((0, import_fs10.existsSync)(candidate)) {
18006
- schema2 = JSON.parse((0, import_fs10.readFileSync)(candidate, "utf-8"));
18007
- break;
18008
- }
18009
- } catch {
18010
- }
18011
- }
18012
- if (!schema2) {
18013
- console.warn("\u26A0\uFE0F Could not load manifest schema, skipping schema validation");
18014
- }
18015
- function validateManifestSchema(manifest) {
18016
- if (!schema2) {
18017
- return { valid: true };
18018
- }
18019
- const ajv2 = new import_ajv2.default({
18020
- allErrors: true,
18021
- verbose: true
18022
- });
18023
- (0, import_ajv_formats2.default)(ajv2);
18024
- const validate = ajv2.compile(schema2);
18025
- const valid = validate(manifest);
18026
- if (!valid && validate.errors) {
18027
- const errors = validate.errors.map((err) => {
18028
- const path10 = err.instancePath || "manifest";
18029
- const message = err.message || "validation failed";
18030
- if (err.keyword === "required") {
18031
- const missingProp = err.params.missingProperty;
18032
- return `Missing required field: ${missingProp}`;
18033
- }
18034
- if (err.keyword === "pattern") {
18035
- return `${path10}: ${message}. Value does not match required pattern.`;
18036
- }
18037
- if (err.keyword === "enum") {
18038
- const allowedValues = err.params.allowedValues;
18039
- return `${path10}: ${message}. Allowed values: ${allowedValues.join(", ")}`;
18040
- }
18041
- if (err.keyword === "minLength" || err.keyword === "maxLength") {
18042
- const limit = err.params.limit;
18043
- return `${path10}: ${message} (${err.keyword}: ${limit})`;
18044
- }
18045
- if (err.keyword === "oneOf") {
18046
- return `${path10}: must match exactly one schema (check if files array uses either all strings or all objects, not mixed)`;
18047
- }
18048
- return `${path10}: ${message}`;
18049
- });
18050
- return { valid: false, errors };
18051
- }
18052
- return { valid: true };
18053
- }
18054
- function getManifestSchema() {
18055
- return schema2;
18056
- }
18057
-
18058
- // src/utils/license-extractor.ts
18059
- init_cjs_shims();
18060
- var import_promises3 = require("fs/promises");
18061
- var import_path12 = require("path");
18062
- var import_fs11 = require("fs");
18063
- var LICENSE_FILE_PATTERNS = [
18064
- "LICENSE",
18065
- "LICENSE.md",
18066
- "LICENSE.txt",
18067
- "LICENCE",
18068
- "LICENCE.md",
18069
- "LICENCE.txt",
18070
- "LICENSE-MIT",
18071
- "LICENSE-APACHE",
18072
- "COPYING",
18073
- "COPYING.txt"
18074
- ];
18075
- var LICENSE_PATTERNS = [
18076
- { pattern: /MIT License/i, type: "MIT" },
18077
- { pattern: /Apache License[\s\S]*Version 2\.0/i, type: "Apache-2.0" },
18078
- { pattern: /GNU GENERAL PUBLIC LICENSE[\s\S]*Version 3/i, type: "GPL-3.0" },
18079
- { pattern: /GNU GENERAL PUBLIC LICENSE[\s\S]*Version 2/i, type: "GPL-2.0" },
18080
- { pattern: /GNU LESSER GENERAL PUBLIC LICENSE[\s\S]*Version 3/i, type: "LGPL-3.0" },
18081
- { pattern: /GNU LESSER GENERAL PUBLIC LICENSE[\s\S]*Version 2/i, type: "LGPL-2.1" },
18082
- { pattern: /BSD 3-Clause License/i, type: "BSD-3-Clause" },
18083
- { pattern: /BSD 2-Clause License/i, type: "BSD-2-Clause" },
18084
- { pattern: /Mozilla Public License[\s\S]*Version 2\.0/i, type: "MPL-2.0" },
18085
- { pattern: /ISC License/i, type: "ISC" },
18086
- { pattern: /The Unlicense/i, type: "Unlicense" },
18087
- { pattern: /Creative Commons Zero[\s\S]*1\.0/i, type: "CC0-1.0" }
18088
- ];
18089
- function detectLicenseType(text) {
18090
- for (const { pattern, type: type2 } of LICENSE_PATTERNS) {
18091
- if (pattern.test(text)) {
18092
- return type2;
18093
- }
18094
- }
18095
- return null;
18096
- }
18097
- function generateLicenseUrl(repositoryUrl, fileName) {
18098
- if (!repositoryUrl) {
18099
- return null;
18100
- }
18101
- const githubMatch = repositoryUrl.match(/github\.com[/:]([\w-]+)\/([\w-]+)/);
18102
- if (!githubMatch) {
18103
- return null;
18104
- }
18105
- const [, owner, repo] = githubMatch;
18106
- return `https://raw.githubusercontent.com/${owner}/${repo}/main/${fileName}`;
18107
- }
18108
- async function extractLicenseInfo(repositoryUrl) {
18109
- const cwd = process.cwd();
18110
- for (const fileName of LICENSE_FILE_PATTERNS) {
18111
- const filePath = (0, import_path12.join)(cwd, fileName);
18112
- try {
18113
- await (0, import_promises3.access)(filePath, import_fs11.constants.R_OK);
18114
- const text = await (0, import_promises3.readFile)(filePath, "utf-8");
18115
- const type2 = detectLicenseType(text);
18116
- const url = generateLicenseUrl(repositoryUrl, fileName);
18117
- return {
18118
- type: type2,
18119
- text,
18120
- url,
18121
- fileName
18122
- };
18123
- } catch {
18124
- continue;
18125
- }
18126
- }
18127
- return {
18128
- type: null,
18129
- text: null,
18130
- url: null,
18131
- fileName: null
18132
- };
18133
- }
18134
- function validateLicenseInfo(licenseInfo, packageName) {
18135
- if (licenseInfo.text && licenseInfo.type) {
18136
- console.log(` License: ${licenseInfo.type} (${licenseInfo.fileName})`);
18137
- } else if (licenseInfo.text && !licenseInfo.type) {
18138
- console.log(` License: Found (${licenseInfo.fileName})`);
18139
- } else {
18140
- console.log(` License: Not found (package will be published without license)`);
18141
- }
18142
- }
18143
-
18144
- // src/utils/snippet-extractor.ts
18145
- init_cjs_shims();
18146
- var import_promises4 = require("fs/promises");
18147
- var import_path13 = require("path");
18148
- var MAX_SNIPPET_LENGTH = 2e3;
18149
- async function extractSnippet(manifest) {
18150
- const cwd = process.cwd();
18151
- try {
18152
- if (!manifest.files || manifest.files.length === 0) {
18153
- console.warn("\u26A0\uFE0F Cannot extract snippet: no files specified in manifest");
18154
- return null;
18155
- }
18156
- let fileName;
18157
- if (manifest.main) {
18158
- fileName = manifest.main;
18159
- } else {
18160
- const firstFile = manifest.files[0];
18161
- fileName = typeof firstFile === "string" ? firstFile : firstFile.path;
18162
- }
18163
- const fullPath = (0, import_path13.join)(cwd, fileName);
18164
- const stats = await (0, import_promises4.stat)(fullPath);
18165
- if (stats.isDirectory()) {
18166
- console.warn(`\u26A0\uFE0F Skipping snippet extraction: "${fullPath}" is a directory`);
18167
- return null;
18168
- }
18169
- const content = await (0, import_promises4.readFile)(fullPath, "utf-8");
18170
- if (content.length <= MAX_SNIPPET_LENGTH) {
18171
- return content.trim();
18172
- }
18173
- let snippet2 = content.substring(0, MAX_SNIPPET_LENGTH);
18174
- const lastNewline = snippet2.lastIndexOf("\n");
18175
- if (lastNewline > MAX_SNIPPET_LENGTH * 0.8) {
18176
- snippet2 = snippet2.substring(0, lastNewline);
18177
- }
18178
- return snippet2.trim() + "\n\n[... content truncated ...]";
18179
- } catch (error) {
18180
- console.warn("\u26A0\uFE0F Could not extract snippet:", error instanceof Error ? error.message : "Unknown error");
18181
- return null;
18006
+ const content = await (0, import_promises4.readFile)(fullPath, "utf-8");
18007
+ if (content.length <= MAX_SNIPPET_LENGTH) {
18008
+ return content.trim();
18009
+ }
18010
+ let snippet2 = content.substring(0, MAX_SNIPPET_LENGTH);
18011
+ const lastNewline = snippet2.lastIndexOf("\n");
18012
+ if (lastNewline > MAX_SNIPPET_LENGTH * 0.8) {
18013
+ snippet2 = snippet2.substring(0, lastNewline);
18014
+ }
18015
+ return snippet2.trim() + "\n\n[... content truncated ...]";
18016
+ } catch (error) {
18017
+ console.warn("\u26A0\uFE0F Could not extract snippet:", error instanceof Error ? error.message : "Unknown error");
18018
+ return null;
18182
18019
  }
18183
18020
  }
18184
18021
  function validateSnippet(snippet2, packageName) {
@@ -18321,111 +18158,342 @@ Stack: ${error.stack}` : String(error);
18321
18158
  };
18322
18159
  }
18323
18160
  }
18324
- async function validatePackageFiles(manifest) {
18325
- const errors = [];
18326
- const warnings = [];
18327
- const formatType = getFormatType(manifest.format);
18328
- if (!formatType) {
18329
- warnings.push(`Format '${manifest.format}' is not recognized for validation`);
18330
- return { errors, warnings };
18331
- }
18332
- if (formatType === "canonical") {
18333
- return { errors, warnings };
18161
+ async function validatePackageFiles(manifest) {
18162
+ const errors = [];
18163
+ const warnings = [];
18164
+ const formatType = getFormatType(manifest.format);
18165
+ if (!formatType) {
18166
+ warnings.push(`Format '${manifest.format}' is not recognized for validation`);
18167
+ return { errors, warnings };
18168
+ }
18169
+ if (formatType === "canonical") {
18170
+ return { errors, warnings };
18171
+ }
18172
+ const filePaths = normalizeFilePaths(manifest.files);
18173
+ const shouldValidateFile = (filePath) => {
18174
+ const skipFiles = ["prpm.json", "README.md", "LICENSE", ".gitignore", ".npmignore"];
18175
+ if (skipFiles.includes(filePath)) {
18176
+ return false;
18177
+ }
18178
+ const skipDirs = ["examples/", "example/", "tests/", "__tests__/", "docs/", "doc/"];
18179
+ if (skipDirs.some((dir) => filePath.includes(dir))) {
18180
+ return false;
18181
+ }
18182
+ if (formatType === "cursor") {
18183
+ return filePath.includes(".cursorrules") || filePath.endsWith(".mdc");
18184
+ } else if (formatType === "claude") {
18185
+ if (manifest.subtype === "skill") {
18186
+ return filePath.endsWith("SKILL.md");
18187
+ }
18188
+ if (manifest.subtype === "hook") {
18189
+ return false;
18190
+ }
18191
+ if (filePath.endsWith(".json")) {
18192
+ return false;
18193
+ }
18194
+ if (manifest.subtype === "agent") {
18195
+ return filePath.includes(".claude/agents/") && filePath.endsWith(".md");
18196
+ } else if (manifest.subtype === "slash-command") {
18197
+ return filePath.includes(".claude/commands/") && filePath.endsWith(".md");
18198
+ }
18199
+ return filePath.endsWith(".md") && !filePath.endsWith(".json");
18200
+ } else if (formatType === "continue") {
18201
+ return filePath.includes(".continue/") && filePath.endsWith(".json");
18202
+ } else if (formatType === "windsurf") {
18203
+ return filePath.includes(".windsurf/rules");
18204
+ } else if (formatType === "agents-md") {
18205
+ return filePath === "agents.md";
18206
+ } else if (formatType === "kiro") {
18207
+ return filePath.endsWith(".md") || filePath.endsWith(".json");
18208
+ }
18209
+ return filePath.endsWith(".md") || filePath.endsWith(".json") || filePath.endsWith(".yaml");
18210
+ };
18211
+ for (const filePath of filePaths) {
18212
+ if (!shouldValidateFile(filePath)) {
18213
+ continue;
18214
+ }
18215
+ try {
18216
+ if (formatType === "windsurf") {
18217
+ const result = await validateMarkdownFile(filePath, formatType);
18218
+ errors.push(...result.errors);
18219
+ warnings.push(...result.warnings);
18220
+ } else if (formatType === "agents-md") {
18221
+ const result = await validateMarkdownFile(filePath, formatType);
18222
+ errors.push(...result.errors);
18223
+ warnings.push(...result.warnings);
18224
+ } else if (formatType === "kiro") {
18225
+ if (filePath.endsWith(".json")) {
18226
+ const result = await validateStructuredFile(filePath, formatType, "hook");
18227
+ errors.push(...result.errors);
18228
+ warnings.push(...result.warnings);
18229
+ } else {
18230
+ const result = await validateMarkdownFile(filePath, formatType);
18231
+ errors.push(...result.errors);
18232
+ warnings.push(...result.warnings);
18233
+ }
18234
+ } else {
18235
+ const result = await validateMarkdownFile(filePath, formatType, manifest.subtype);
18236
+ errors.push(...result.errors);
18237
+ warnings.push(...result.warnings);
18238
+ }
18239
+ } catch (error) {
18240
+ errors.push(`${filePath}: Cannot read file - ${error instanceof Error ? error.message : "Unknown error"}`);
18241
+ }
18242
+ }
18243
+ if (manifest.format === "claude" && manifest.subtype === "skill") {
18244
+ const hasSkillMd = filePaths.some((path10) => path10.endsWith("/SKILL.md") || path10 === "SKILL.md");
18245
+ if (!hasSkillMd) {
18246
+ errors.push("Claude skills must contain a SKILL.md file");
18247
+ }
18248
+ }
18249
+ if (manifest.format === "windsurf") {
18250
+ const hasWindsurfRules = filePaths.some((path10) => path10.includes(".windsurf/rules"));
18251
+ if (!hasWindsurfRules) {
18252
+ warnings.push("Windsurf packages typically use .windsurf/rules filename");
18253
+ }
18254
+ }
18255
+ return { errors, warnings };
18256
+ }
18257
+
18258
+ // src/utils/manifest-loader.ts
18259
+ init_cjs_shims();
18260
+ var import_promises6 = require("fs/promises");
18261
+ var import_path14 = require("path");
18262
+
18263
+ // src/core/marketplace-converter.ts
18264
+ init_cjs_shims();
18265
+ function marketplaceToManifest(marketplace, pluginIndex = 0) {
18266
+ var _a, _b;
18267
+ if (!marketplace.plugins || marketplace.plugins.length === 0) {
18268
+ throw new Error("marketplace.json must contain at least one plugin");
18269
+ }
18270
+ if (pluginIndex >= marketplace.plugins.length) {
18271
+ throw new Error(`Plugin index ${pluginIndex} out of range. Found ${marketplace.plugins.length} plugins.`);
18272
+ }
18273
+ const plugin = marketplace.plugins[pluginIndex];
18274
+ let format = "claude";
18275
+ let subtype = "rule";
18276
+ if (plugin.agents && plugin.agents.length > 0) {
18277
+ format = "claude";
18278
+ subtype = "agent";
18279
+ } else if (plugin.skills && plugin.skills.length > 0) {
18280
+ format = "claude";
18281
+ subtype = "skill";
18282
+ } else if (plugin.commands && plugin.commands.length > 0) {
18283
+ format = "claude";
18284
+ subtype = "slash-command";
18285
+ }
18286
+ const ownerName = typeof marketplace.owner === "string" ? marketplace.owner : marketplace.owner.name;
18287
+ const packageName = generatePackageName(ownerName, plugin.name);
18288
+ const files = collectFiles(plugin);
18289
+ const main = determineMainFile(plugin);
18290
+ const keywords = [
18291
+ ...marketplace.keywords || [],
18292
+ ...plugin.keywords || []
18293
+ ].slice(0, 20);
18294
+ const tags = keywords.slice(0, 10);
18295
+ const description = plugin.description || ((_a = marketplace.metadata) == null ? void 0 : _a.description) || marketplace.description || "";
18296
+ const version = plugin.version || ((_b = marketplace.metadata) == null ? void 0 : _b.version) || marketplace.version || "1.0.0";
18297
+ const author = plugin.author || ownerName;
18298
+ const manifest = {
18299
+ name: packageName,
18300
+ version,
18301
+ description,
18302
+ format,
18303
+ subtype,
18304
+ author,
18305
+ files,
18306
+ tags,
18307
+ keywords
18308
+ };
18309
+ if (marketplace.githubUrl) {
18310
+ manifest.repository = marketplace.githubUrl;
18311
+ }
18312
+ if (marketplace.websiteUrl) {
18313
+ manifest.homepage = marketplace.websiteUrl;
18314
+ }
18315
+ if (plugin.category) {
18316
+ manifest.category = plugin.category;
18317
+ }
18318
+ if (main) {
18319
+ manifest.main = main;
18320
+ }
18321
+ return manifest;
18322
+ }
18323
+ function generatePackageName(owner, pluginName) {
18324
+ const sanitizedOwner = owner.toLowerCase().replace(/[^a-z0-9-]/g, "-");
18325
+ const sanitizedName = pluginName.toLowerCase().replace(/[^a-z0-9-]/g, "-");
18326
+ const cleanOwner = sanitizedOwner.replace(/^-+|-+$/g, "");
18327
+ const cleanName = sanitizedName.replace(/^-+|-+$/g, "");
18328
+ return `@${cleanOwner}/${cleanName}`;
18329
+ }
18330
+ function collectFiles(plugin) {
18331
+ const files = /* @__PURE__ */ new Set();
18332
+ if (plugin.source && !plugin.source.startsWith("http")) {
18333
+ files.add(plugin.source);
18334
+ }
18335
+ if (plugin.agents) {
18336
+ for (const agent of plugin.agents) {
18337
+ if (agent.source && !agent.source.startsWith("http")) {
18338
+ files.add(agent.source);
18339
+ }
18340
+ }
18341
+ }
18342
+ if (plugin.skills) {
18343
+ for (const skill of plugin.skills) {
18344
+ if (skill.source && !skill.source.startsWith("http")) {
18345
+ files.add(skill.source);
18346
+ }
18347
+ }
18348
+ }
18349
+ if (plugin.commands) {
18350
+ for (const command of plugin.commands) {
18351
+ if (command.source && !command.source.startsWith("http")) {
18352
+ files.add(command.source);
18353
+ }
18354
+ }
18355
+ }
18356
+ const standardFiles = ["README.md", "LICENSE", ".claude/marketplace.json", ".claude-plugin/marketplace.json"];
18357
+ for (const file of standardFiles) {
18358
+ files.add(file);
18359
+ }
18360
+ return Array.from(files);
18361
+ }
18362
+ function determineMainFile(plugin) {
18363
+ var _a, _b, _c;
18364
+ const agentCount = ((_a = plugin.agents) == null ? void 0 : _a.length) || 0;
18365
+ const skillCount = ((_b = plugin.skills) == null ? void 0 : _b.length) || 0;
18366
+ const commandCount = ((_c = plugin.commands) == null ? void 0 : _c.length) || 0;
18367
+ const totalCount = agentCount + skillCount + commandCount;
18368
+ if (totalCount !== 1) {
18369
+ return void 0;
18370
+ }
18371
+ if (agentCount === 1) {
18372
+ const source = plugin.agents[0].source;
18373
+ if (source && !source.startsWith("http")) {
18374
+ return source;
18375
+ }
18376
+ }
18377
+ if (skillCount === 1) {
18378
+ const source = plugin.skills[0].source;
18379
+ if (source && !source.startsWith("http")) {
18380
+ return source;
18381
+ }
18382
+ }
18383
+ if (commandCount === 1) {
18384
+ const source = plugin.commands[0].source;
18385
+ if (source && !source.startsWith("http")) {
18386
+ return source;
18387
+ }
18388
+ }
18389
+ if (plugin.source && !plugin.source.startsWith("http")) {
18390
+ return plugin.source;
18391
+ }
18392
+ return void 0;
18393
+ }
18394
+ function validateMarketplaceJson(data) {
18395
+ var _a;
18396
+ if (!data || typeof data !== "object") {
18397
+ return false;
18398
+ }
18399
+ const marketplace = data;
18400
+ if (!marketplace.name || typeof marketplace.name !== "string") {
18401
+ return false;
18402
+ }
18403
+ if (!marketplace.owner) {
18404
+ return false;
18405
+ }
18406
+ if (typeof marketplace.owner !== "string" && (typeof marketplace.owner !== "object" || !marketplace.owner.name)) {
18407
+ return false;
18408
+ }
18409
+ const hasDescription = marketplace.description && typeof marketplace.description === "string" || ((_a = marketplace.metadata) == null ? void 0 : _a.description) && typeof marketplace.metadata.description === "string";
18410
+ if (!hasDescription) {
18411
+ return false;
18412
+ }
18413
+ if (!Array.isArray(marketplace.plugins) || marketplace.plugins.length === 0) {
18414
+ return false;
18415
+ }
18416
+ const plugin = marketplace.plugins[0];
18417
+ if (!plugin.name || !plugin.description || !plugin.version) {
18418
+ return false;
18419
+ }
18420
+ return true;
18421
+ }
18422
+
18423
+ // src/core/schema-validator.ts
18424
+ init_cjs_shims();
18425
+ var import_ajv2 = __toESM(require("ajv"));
18426
+ var import_ajv_formats2 = __toESM(require("ajv-formats"));
18427
+ var import_fs11 = require("fs");
18428
+ var import_path13 = require("path");
18429
+ var schema2;
18430
+ var schemaCandidates = [
18431
+ // Source file layout (src/core → ../../schemas)
18432
+ (0, import_path13.join)(__dirname, "../../schemas/prpm-manifest.schema.json"),
18433
+ // Bundled layout (dist/index.js → ../schemas)
18434
+ (0, import_path13.join)(__dirname, "../schemas/prpm-manifest.schema.json")
18435
+ ];
18436
+ for (const candidate of schemaCandidates) {
18437
+ try {
18438
+ if ((0, import_fs11.existsSync)(candidate)) {
18439
+ schema2 = JSON.parse((0, import_fs11.readFileSync)(candidate, "utf-8"));
18440
+ break;
18441
+ }
18442
+ } catch {
18443
+ }
18444
+ }
18445
+ if (!schema2) {
18446
+ console.warn("\u26A0\uFE0F Could not load manifest schema, skipping schema validation");
18447
+ }
18448
+ function validateManifestSchema(manifest) {
18449
+ if (!schema2) {
18450
+ return { valid: true };
18334
18451
  }
18335
- const filePaths = normalizeFilePaths(manifest.files);
18336
- const shouldValidateFile = (filePath) => {
18337
- const skipFiles = ["prpm.json", "README.md", "LICENSE", ".gitignore", ".npmignore"];
18338
- if (skipFiles.includes(filePath)) {
18339
- return false;
18340
- }
18341
- const skipDirs = ["examples/", "example/", "tests/", "__tests__/", "docs/", "doc/"];
18342
- if (skipDirs.some((dir) => filePath.includes(dir))) {
18343
- return false;
18344
- }
18345
- if (formatType === "cursor") {
18346
- return filePath.includes(".cursorrules") || filePath.endsWith(".mdc");
18347
- } else if (formatType === "claude") {
18348
- if (manifest.subtype === "skill") {
18349
- return filePath.endsWith("SKILL.md");
18452
+ const ajv2 = new import_ajv2.default({
18453
+ allErrors: true,
18454
+ verbose: true
18455
+ });
18456
+ (0, import_ajv_formats2.default)(ajv2);
18457
+ const validate = ajv2.compile(schema2);
18458
+ const valid = validate(manifest);
18459
+ if (!valid && validate.errors) {
18460
+ const errors = validate.errors.map((err) => {
18461
+ const path10 = err.instancePath || "manifest";
18462
+ const message = err.message || "validation failed";
18463
+ if (err.keyword === "required") {
18464
+ const missingProp = err.params.missingProperty;
18465
+ return `Missing required field: ${missingProp}`;
18350
18466
  }
18351
- if (manifest.subtype === "hook") {
18352
- return false;
18467
+ if (err.keyword === "pattern") {
18468
+ return `${path10}: ${message}. Value does not match required pattern.`;
18353
18469
  }
18354
- if (filePath.endsWith(".json")) {
18355
- return false;
18470
+ if (err.keyword === "enum") {
18471
+ const allowedValues = err.params.allowedValues;
18472
+ return `${path10}: ${message}. Allowed values: ${allowedValues.join(", ")}`;
18356
18473
  }
18357
- if (manifest.subtype === "agent") {
18358
- return filePath.includes(".claude/agents/") && filePath.endsWith(".md");
18359
- } else if (manifest.subtype === "slash-command") {
18360
- return filePath.includes(".claude/commands/") && filePath.endsWith(".md");
18474
+ if (err.keyword === "minLength" || err.keyword === "maxLength") {
18475
+ const limit = err.params.limit;
18476
+ return `${path10}: ${message} (${err.keyword}: ${limit})`;
18361
18477
  }
18362
- return filePath.endsWith(".md") && !filePath.endsWith(".json");
18363
- } else if (formatType === "continue") {
18364
- return filePath.includes(".continue/") && filePath.endsWith(".json");
18365
- } else if (formatType === "windsurf") {
18366
- return filePath.includes(".windsurf/rules");
18367
- } else if (formatType === "agents-md") {
18368
- return filePath === "agents.md";
18369
- } else if (formatType === "kiro") {
18370
- return filePath.endsWith(".md") || filePath.endsWith(".json");
18371
- }
18372
- return filePath.endsWith(".md") || filePath.endsWith(".json") || filePath.endsWith(".yaml");
18373
- };
18374
- for (const filePath of filePaths) {
18375
- if (!shouldValidateFile(filePath)) {
18376
- continue;
18377
- }
18378
- try {
18379
- if (formatType === "windsurf") {
18380
- const result = await validateMarkdownFile(filePath, formatType);
18381
- errors.push(...result.errors);
18382
- warnings.push(...result.warnings);
18383
- } else if (formatType === "agents-md") {
18384
- const result = await validateMarkdownFile(filePath, formatType);
18385
- errors.push(...result.errors);
18386
- warnings.push(...result.warnings);
18387
- } else if (formatType === "kiro") {
18388
- if (filePath.endsWith(".json")) {
18389
- const result = await validateStructuredFile(filePath, formatType, "hook");
18390
- errors.push(...result.errors);
18391
- warnings.push(...result.warnings);
18392
- } else {
18393
- const result = await validateMarkdownFile(filePath, formatType);
18394
- errors.push(...result.errors);
18395
- warnings.push(...result.warnings);
18396
- }
18397
- } else {
18398
- const result = await validateMarkdownFile(filePath, formatType, manifest.subtype);
18399
- errors.push(...result.errors);
18400
- warnings.push(...result.warnings);
18478
+ if (err.keyword === "oneOf") {
18479
+ return `${path10}: must match exactly one schema (check if files array uses either all strings or all objects, not mixed)`;
18401
18480
  }
18402
- } catch (error) {
18403
- errors.push(`${filePath}: Cannot read file - ${error instanceof Error ? error.message : "Unknown error"}`);
18404
- }
18405
- }
18406
- if (manifest.format === "claude" && manifest.subtype === "skill") {
18407
- const hasSkillMd = filePaths.some((path10) => path10.endsWith("/SKILL.md") || path10 === "SKILL.md");
18408
- if (!hasSkillMd) {
18409
- errors.push("Claude skills must contain a SKILL.md file");
18410
- }
18411
- }
18412
- if (manifest.format === "windsurf") {
18413
- const hasWindsurfRules = filePaths.some((path10) => path10.includes(".windsurf/rules"));
18414
- if (!hasWindsurfRules) {
18415
- warnings.push("Windsurf packages typically use .windsurf/rules filename");
18416
- }
18481
+ return `${path10}: ${message}`;
18482
+ });
18483
+ return { valid: false, errors };
18417
18484
  }
18418
- return { errors, warnings };
18485
+ return { valid: true };
18486
+ }
18487
+ function getManifestSchema() {
18488
+ return schema2;
18419
18489
  }
18420
18490
 
18421
- // src/commands/publish.ts
18422
- init_init();
18491
+ // src/utils/manifest-loader.ts
18423
18492
  async function findAndLoadManifests() {
18424
- const prpmJsonPath = (0, import_path17.join)(process.cwd(), "prpm.json");
18493
+ const prpmJsonPath = (0, import_path14.join)(process.cwd(), "prpm.json");
18425
18494
  let prpmJsonExists = false;
18426
- let prpmJsonError = null;
18427
18495
  try {
18428
- const content = await (0, import_promises7.readFile)(prpmJsonPath, "utf-8");
18496
+ const content = await (0, import_promises6.readFile)(prpmJsonPath, "utf-8");
18429
18497
  prpmJsonExists = true;
18430
18498
  const manifest = JSON.parse(content);
18431
18499
  const collections = [];
@@ -18460,22 +18528,36 @@ async function findAndLoadManifests() {
18460
18528
  const label = pkg.name || `package #${idx + 1}`;
18461
18529
  return validateManifest(packageWithDefaults, label);
18462
18530
  });
18463
- return { manifests: validatedManifests, collections, source: "prpm.json (multi-package)" };
18531
+ return {
18532
+ manifests: validatedManifests,
18533
+ collections,
18534
+ source: "prpm.json (multi-package)"
18535
+ };
18464
18536
  }
18465
18537
  if (collections.length > 0) {
18466
- return { manifests: [], collections, source: "prpm.json (collections-only)" };
18538
+ return {
18539
+ manifests: [],
18540
+ collections,
18541
+ source: "prpm.json (collections-only)"
18542
+ };
18467
18543
  }
18468
- const validated = validateManifest(manifest, manifest.name);
18544
+ const validated = validateManifest(
18545
+ manifest,
18546
+ manifest.name
18547
+ );
18469
18548
  return { manifests: [validated], collections, source: "prpm.json" };
18470
18549
  } catch (error) {
18471
- prpmJsonError = error;
18472
18550
  if (prpmJsonExists && error instanceof Error && (error.message.includes("Invalid JSON") || error.message.includes("Manifest validation failed") || error.message.includes("Claude skill") || error.message.includes("SKILL.md"))) {
18473
18551
  throw error;
18474
18552
  }
18475
18553
  }
18476
- const marketplaceJsonPath = (0, import_path17.join)(process.cwd(), ".claude", "marketplace.json");
18554
+ const marketplaceJsonPath = (0, import_path14.join)(
18555
+ process.cwd(),
18556
+ ".claude",
18557
+ "marketplace.json"
18558
+ );
18477
18559
  try {
18478
- const content = await (0, import_promises7.readFile)(marketplaceJsonPath, "utf-8");
18560
+ const content = await (0, import_promises6.readFile)(marketplaceJsonPath, "utf-8");
18479
18561
  const marketplaceData = JSON.parse(content);
18480
18562
  if (!validateMarketplaceJson(marketplaceData)) {
18481
18563
  throw new Error("Invalid marketplace.json format");
@@ -18489,9 +18571,13 @@ async function findAndLoadManifests() {
18489
18571
  return { manifests, collections: [], source: ".claude/marketplace.json" };
18490
18572
  } catch (error) {
18491
18573
  }
18492
- const marketplaceJsonPluginPath = (0, import_path17.join)(process.cwd(), ".claude-plugin", "marketplace.json");
18574
+ const marketplaceJsonPluginPath = (0, import_path14.join)(
18575
+ process.cwd(),
18576
+ ".claude-plugin",
18577
+ "marketplace.json"
18578
+ );
18493
18579
  try {
18494
- const content = await (0, import_promises7.readFile)(marketplaceJsonPluginPath, "utf-8");
18580
+ const content = await (0, import_promises6.readFile)(marketplaceJsonPluginPath, "utf-8");
18495
18581
  const marketplaceData = JSON.parse(content);
18496
18582
  if (!validateMarketplaceJson(marketplaceData)) {
18497
18583
  throw new Error("Invalid marketplace.json format");
@@ -18502,7 +18588,11 @@ async function findAndLoadManifests() {
18502
18588
  const validated = validateManifest(manifest, manifest.name);
18503
18589
  manifests.push(validated);
18504
18590
  }
18505
- return { manifests, collections: [], source: ".claude-plugin/marketplace.json" };
18591
+ return {
18592
+ manifests,
18593
+ collections: [],
18594
+ source: ".claude-plugin/marketplace.json"
18595
+ };
18506
18596
  } catch (error) {
18507
18597
  }
18508
18598
  throw new Error(
@@ -18519,8 +18609,10 @@ function validateManifest(manifest, contextLabel) {
18519
18609
  const schemaValidation = validateManifestSchema(manifest);
18520
18610
  if (!schemaValidation.valid) {
18521
18611
  const errorMessages = ((_a = schemaValidation.errors) == null ? void 0 : _a.join("\n - ")) || "Unknown validation error";
18522
- throw new Error(`${prefix}Manifest validation failed:
18523
- - ${errorMessages}`);
18612
+ throw new Error(
18613
+ `${prefix}Manifest validation failed:
18614
+ - ${errorMessages}`
18615
+ );
18524
18616
  }
18525
18617
  const hasEnhancedFormat = manifest.files.some((f) => typeof f === "object");
18526
18618
  if (hasEnhancedFormat) {
@@ -18528,12 +18620,16 @@ function validateManifest(manifest, contextLabel) {
18528
18620
  manifest.files.filter((f) => typeof f === "object").map((f) => f.format)
18529
18621
  );
18530
18622
  if (fileFormats.size > 1 && manifest.subtype !== "collection") {
18531
- console.warn(`${prefix}\u26A0\uFE0F Package contains multiple file formats. Consider setting subtype to "collection" for clarity.`);
18623
+ console.warn(
18624
+ `${prefix}\u26A0\uFE0F Package contains multiple file formats. Consider setting subtype to "collection" for clarity.`
18625
+ );
18532
18626
  }
18533
18627
  }
18534
18628
  if (manifest.format === "claude" && manifest.subtype === "skill") {
18535
18629
  const filePaths = normalizeFilePaths2(manifest.files);
18536
- const hasSkillMd = filePaths.some((path10) => path10.endsWith("/SKILL.md") || path10 === "SKILL.md");
18630
+ const hasSkillMd = filePaths.some(
18631
+ (path10) => path10.endsWith("/SKILL.md") || path10 === "SKILL.md"
18632
+ );
18537
18633
  if (!hasSkillMd) {
18538
18634
  throw new Error(
18539
18635
  `${prefix}Claude skills must contain a SKILL.md file.
@@ -18621,9 +18717,17 @@ function getSafePackageName(manifest, userInfo, fallbackName) {
18621
18717
  }
18622
18718
  return manifest.name;
18623
18719
  }
18720
+
18721
+ // src/utils/tarball-creator.ts
18722
+ init_cjs_shims();
18723
+ var import_promises7 = require("fs/promises");
18724
+ var import_path15 = require("path");
18725
+ var tar2 = __toESM(require("tar"));
18726
+ var import_os4 = require("os");
18727
+ var import_crypto2 = require("crypto");
18624
18728
  async function createTarball(manifest) {
18625
- const tmpDir = (0, import_path17.join)((0, import_os4.tmpdir)(), `prpm-${(0, import_crypto2.randomBytes)(8).toString("hex")}`);
18626
- const tarballPath = (0, import_path17.join)(tmpDir, "package.tar.gz");
18729
+ const tmpDir = (0, import_path15.join)((0, import_os4.tmpdir)(), `prpm-${(0, import_crypto2.randomBytes)(8).toString("hex")}`);
18730
+ const tarballPath = (0, import_path15.join)(tmpDir, "package.tar.gz");
18627
18731
  try {
18628
18732
  await (0, import_promises7.mkdir)(tmpDir, { recursive: true });
18629
18733
  const filePaths = normalizeFilePaths2(manifest.files);
@@ -18655,7 +18759,9 @@ async function createTarball(manifest) {
18655
18759
  const tarballBuffer = await (0, import_promises7.readFile)(tarballPath);
18656
18760
  const sizeMB = tarballBuffer.length / (1024 * 1024);
18657
18761
  if (sizeMB > 10) {
18658
- throw new Error(`Package size (${sizeMB.toFixed(2)}MB) exceeds 10MB limit`);
18762
+ throw new Error(
18763
+ `Package size (${sizeMB.toFixed(2)}MB) exceeds 10MB limit`
18764
+ );
18659
18765
  }
18660
18766
  return tarballBuffer;
18661
18767
  } catch (error) {
@@ -18667,8 +18773,78 @@ async function createTarball(manifest) {
18667
18773
  }
18668
18774
  }
18669
18775
  }
18776
+ function formatTarballSize(sizeInBytes) {
18777
+ const sizeInKB = sizeInBytes / 1024;
18778
+ const sizeInMB = sizeInBytes / (1024 * 1024);
18779
+ if (sizeInMB >= 1) {
18780
+ return `${sizeInMB.toFixed(2)}MB`;
18781
+ } else {
18782
+ return `${sizeInKB.toFixed(2)}KB`;
18783
+ }
18784
+ }
18785
+
18786
+ // src/commands/publish.ts
18787
+ init_init();
18788
+ async function listPackages2() {
18789
+ const { manifests, collections, source } = await findAndLoadManifests();
18790
+ console.log(`
18791
+ \u{1F4E6} Packages in ${source}
18792
+ `);
18793
+ if (manifests.length === 0 && collections.length === 0) {
18794
+ console.log(" No packages or collections found.\n");
18795
+ return;
18796
+ }
18797
+ if (manifests.length > 0) {
18798
+ const nameWidth = Math.max(20, ...manifests.map((m) => m.name.length));
18799
+ const versionWidth = Math.max(8, ...manifests.map((m) => m.version.length));
18800
+ const formatWidth = Math.max(8, ...manifests.map((m) => m.format.length));
18801
+ const subtypeWidth = Math.max(
18802
+ 8,
18803
+ ...manifests.map((m) => (m.subtype || "rule").length)
18804
+ );
18805
+ console.log(
18806
+ ` ${"Name".padEnd(nameWidth)} ${"Version".padEnd(versionWidth)} ${"Format".padEnd(formatWidth)} ${"Subtype".padEnd(subtypeWidth)} Files`
18807
+ );
18808
+ console.log(
18809
+ " " + "\u2500".repeat(nameWidth + versionWidth + formatWidth + subtypeWidth + 20)
18810
+ );
18811
+ for (const manifest of manifests) {
18812
+ const fileCount = manifest.files.length;
18813
+ const filesDisplay = fileCount === 1 ? "1 file" : `${fileCount} files`;
18814
+ console.log(
18815
+ ` ${manifest.name.padEnd(nameWidth)} ${manifest.version.padEnd(versionWidth)} ${manifest.format.padEnd(formatWidth)} ${(manifest.subtype || "rule").padEnd(subtypeWidth)} ${filesDisplay}`
18816
+ );
18817
+ }
18818
+ console.log(`
18819
+ Total: ${manifests.length} package(s)
18820
+ `);
18821
+ }
18822
+ if (collections.length > 0) {
18823
+ console.log("\u{1F4DA} Collections:\n");
18824
+ const idWidth = Math.max(15, ...collections.map((c) => c.id.length));
18825
+ const nameWidth = Math.max(20, ...collections.map((c) => c.name.length));
18826
+ console.log(
18827
+ ` ${"ID".padEnd(idWidth)} ${"Name".padEnd(nameWidth)} Packages`
18828
+ );
18829
+ console.log(" " + "\u2500".repeat(idWidth + nameWidth + 15));
18830
+ for (const collection of collections) {
18831
+ const pkgCount = collection.packages.length;
18832
+ const pkgsDisplay = pkgCount === 1 ? "1 package" : `${pkgCount} packages`;
18833
+ console.log(
18834
+ ` ${collection.id.padEnd(idWidth)} ${collection.name.padEnd(nameWidth)} ${pkgsDisplay}`
18835
+ );
18836
+ }
18837
+ console.log(`
18838
+ Total: ${collections.length} collection(s)
18839
+ `);
18840
+ }
18841
+ }
18670
18842
  async function handlePublish(options) {
18671
18843
  var _a, _b, _c;
18844
+ if (options.list) {
18845
+ await listPackages2();
18846
+ return;
18847
+ }
18672
18848
  const startTime = Date.now();
18673
18849
  let success = false;
18674
18850
  let error;
@@ -18680,15 +18856,26 @@ async function handlePublish(options) {
18680
18856
  throw new CLIError('\u274C Not logged in. Run "prpm login" first.', 1);
18681
18857
  }
18682
18858
  console.log("\u{1F4E6} Publishing package...\n");
18683
- const prpmJsonPath = (0, import_path17.join)(process.cwd(), "prpm.json");
18684
- const marketplaceJsonPath = (0, import_path17.join)(process.cwd(), ".claude", "marketplace.json");
18685
- const marketplaceJsonPluginPath = (0, import_path17.join)(process.cwd(), ".claude-plugin", "marketplace.json");
18859
+ const prpmJsonPath = (0, import_path19.join)(process.cwd(), "prpm.json");
18860
+ const marketplaceJsonPath = (0, import_path19.join)(
18861
+ process.cwd(),
18862
+ ".claude",
18863
+ "marketplace.json"
18864
+ );
18865
+ const marketplaceJsonPluginPath = (0, import_path19.join)(
18866
+ process.cwd(),
18867
+ ".claude-plugin",
18868
+ "marketplace.json"
18869
+ );
18686
18870
  const hasManifest = (0, import_fs15.existsSync)(prpmJsonPath) || (0, import_fs15.existsSync)(marketplaceJsonPath) || (0, import_fs15.existsSync)(marketplaceJsonPluginPath);
18687
18871
  if (!hasManifest) {
18688
18872
  console.log("No prpm.json found. Let's create one first.\n");
18689
18873
  await smartInit({});
18690
18874
  if (!(0, import_fs15.existsSync)(prpmJsonPath)) {
18691
- throw new CLIError("No prpm.json was created. Cannot publish without a manifest.", 1);
18875
+ throw new CLIError(
18876
+ "No prpm.json was created. Cannot publish without a manifest.",
18877
+ 1
18878
+ );
18692
18879
  }
18693
18880
  console.log("\n\u{1F4E6} Continuing with publish...\n");
18694
18881
  }
@@ -18696,8 +18883,8 @@ async function handlePublish(options) {
18696
18883
  const { manifests, collections, source } = await findAndLoadManifests();
18697
18884
  if (source === "prpm.json (multi-package)" || source === "prpm.json") {
18698
18885
  try {
18699
- const prpmJsonPath2 = (0, import_path17.join)(process.cwd(), "prpm.json");
18700
- const prpmContent = await (0, import_promises7.readFile)(prpmJsonPath2, "utf-8");
18886
+ const prpmJsonPath2 = (0, import_path19.join)(process.cwd(), "prpm.json");
18887
+ const prpmContent = await (0, import_promises9.readFile)(prpmJsonPath2, "utf-8");
18701
18888
  const prpmManifest = JSON.parse(prpmContent);
18702
18889
  if (prpmManifest.scripts) {
18703
18890
  await executePrepublishOnly(prpmManifest.scripts);
@@ -18716,7 +18903,9 @@ async function handlePublish(options) {
18716
18903
  }
18717
18904
  }
18718
18905
  if (collections.length > 0) {
18719
- console.log(` Found ${collections.length} collection(s) in ${source}`);
18906
+ console.log(
18907
+ ` Found ${collections.length} collection(s) in ${source}`
18908
+ );
18720
18909
  if (options.collection) {
18721
18910
  console.log(` Filtering to collection: ${options.collection}`);
18722
18911
  }
@@ -18731,7 +18920,9 @@ async function handlePublish(options) {
18731
18920
  } else if (options.package) {
18732
18921
  filteredManifests = manifests.filter((m) => m.name === options.package);
18733
18922
  if (filteredManifests.length === 0) {
18734
- throw new Error(`Package "${options.package}" not found in manifest. Available packages: ${manifests.map((m) => m.name).join(", ")}`);
18923
+ throw new Error(
18924
+ `Package "${options.package}" not found in manifest. Available packages: ${manifests.map((m) => m.name).join(", ")}`
18925
+ );
18735
18926
  }
18736
18927
  console.log(` \u2713 Found package "${options.package}"
18737
18928
  `);
@@ -18742,7 +18933,9 @@ async function handlePublish(options) {
18742
18933
  try {
18743
18934
  userInfo = await client.whoami();
18744
18935
  } catch (err) {
18745
- console.log(" Could not fetch user organizations, publishing as personal packages");
18936
+ console.log(
18937
+ " Could not fetch user organizations, publishing as personal packages"
18938
+ );
18746
18939
  }
18747
18940
  console.log("");
18748
18941
  if (filteredManifests.length > 1) {
@@ -18751,7 +18944,9 @@ async function handlePublish(options) {
18751
18944
  filteredManifests.forEach((manifest, index) => {
18752
18945
  const existingIndex = nameMap.get(manifest.name);
18753
18946
  if (existingIndex !== void 0) {
18754
- duplicates.push(` - "${manifest.name}" appears in positions ${existingIndex + 1} and ${index + 1}`);
18947
+ duplicates.push(
18948
+ ` - "${manifest.name}" appears in positions ${existingIndex + 1} and ${index + 1}`
18949
+ );
18755
18950
  } else {
18756
18951
  nameMap.set(manifest.name, index);
18757
18952
  }
@@ -18760,9 +18955,15 @@ async function handlePublish(options) {
18760
18955
  console.error("\u274C Duplicate package names detected:\n");
18761
18956
  duplicates.forEach((dup) => console.error(dup));
18762
18957
  console.error("\n\u26A0\uFE0F Each package must have a unique name.");
18763
- console.error(" Package names are globally unique per author/organization.");
18764
- console.error(" If you want to publish the same package for different formats,");
18765
- console.error(' use different names (e.g., "react-rules-cursor" vs "react-rules-claude").\n');
18958
+ console.error(
18959
+ " Package names are globally unique per author/organization."
18960
+ );
18961
+ console.error(
18962
+ " If you want to publish the same package for different formats,"
18963
+ );
18964
+ console.error(
18965
+ ' use different names (e.g., "react-rules-cursor" vs "react-rules-claude").\n'
18966
+ );
18766
18967
  throw new Error("Cannot publish packages with duplicate names");
18767
18968
  }
18768
18969
  }
@@ -18779,8 +18980,12 @@ async function handlePublish(options) {
18779
18980
  return error2.includes("Service Unavailable") || error2.includes("Bad Gateway") || error2.includes("at capacity") || error2.includes("502") || error2.includes("503") || error2.includes("ECONNRESET") || error2.includes("ETIMEDOUT");
18780
18981
  };
18781
18982
  if (filteredManifests.length > 1 && BATCH_DELAY_MS > 0) {
18782
- console.log(`\u{1F4E6} Publishing ${filteredManifests.length} packages in batches of ${BATCH_SIZE}`);
18783
- console.log(`\u23F1\uFE0F ${BATCH_DELAY_MS}ms delay between batches, ${RETRY_DELAY_MS}ms retry delay`);
18983
+ console.log(
18984
+ `\u{1F4E6} Publishing ${filteredManifests.length} packages in batches of ${BATCH_SIZE}`
18985
+ );
18986
+ console.log(
18987
+ `\u23F1\uFE0F ${BATCH_DELAY_MS}ms delay between batches, ${RETRY_DELAY_MS}ms retry delay`
18988
+ );
18784
18989
  console.log("");
18785
18990
  }
18786
18991
  for (let i = 0; i < filteredManifests.length; i++) {
@@ -18788,13 +18993,17 @@ async function handlePublish(options) {
18788
18993
  packageName = manifest.name;
18789
18994
  version = manifest.version;
18790
18995
  if (i > 0 && i % BATCH_SIZE === 0 && BATCH_DELAY_MS > 0) {
18791
- console.log(`\u23F8\uFE0F Batch delay (${BATCH_DELAY_MS}ms) before next ${Math.min(BATCH_SIZE, filteredManifests.length - i)} packages...`);
18996
+ console.log(
18997
+ `\u23F8\uFE0F Batch delay (${BATCH_DELAY_MS}ms) before next ${Math.min(BATCH_SIZE, filteredManifests.length - i)} packages...`
18998
+ );
18792
18999
  await delay(BATCH_DELAY_MS);
18793
19000
  }
18794
19001
  if (filteredManifests.length > 1) {
18795
19002
  console.log(`
18796
19003
  ${"=".repeat(60)}`);
18797
- console.log(`\u{1F4E6} Publishing package ${i + 1} of ${filteredManifests.length}`);
19004
+ console.log(
19005
+ `\u{1F4E6} Publishing package ${i + 1} of ${filteredManifests.length}`
19006
+ );
18798
19007
  console.log(`${"=".repeat(60)}
18799
19008
  `);
18800
19009
  }
@@ -18804,7 +19013,9 @@ ${"=".repeat(60)}`);
18804
19013
  while (retryCount <= MAX_RETRIES && !publishSuccess) {
18805
19014
  try {
18806
19015
  if (retryCount > 0 && RETRY_DELAY_MS > 0) {
18807
- console.log(` \u{1F504} Retry ${retryCount}/${MAX_RETRIES} after ${RETRY_DELAY_MS}ms...`);
19016
+ console.log(
19017
+ ` \u{1F504} Retry ${retryCount}/${MAX_RETRIES} after ${RETRY_DELAY_MS}ms...`
19018
+ );
18808
19019
  await delay(RETRY_DELAY_MS);
18809
19020
  } else if (retryCount > 0) {
18810
19021
  console.log(` \u{1F504} Retry ${retryCount}/${MAX_RETRIES}...`);
@@ -18842,7 +19053,9 @@ ${"=".repeat(60)}`);
18842
19053
  (org) => org.name === manifest.organization || org.id === manifest.organization
18843
19054
  );
18844
19055
  if (!orgFromManifest) {
18845
- throw new Error(`Organization "${manifest.organization}" not found or you are not a member`);
19056
+ throw new Error(
19057
+ `Organization "${manifest.organization}" not found or you are not a member`
19058
+ );
18846
19059
  }
18847
19060
  if (!["owner", "admin", "maintainer"].includes(orgFromManifest.role)) {
18848
19061
  throw new Error(
@@ -18863,15 +19076,21 @@ ${"=".repeat(60)}`);
18863
19076
  );
18864
19077
  console.log(` Source: ${source}`);
18865
19078
  console.log(` Package: ${scopedPackageName}@${manifest.version}`);
18866
- console.log(` Format: ${manifest.format} | Subtype: ${manifest.subtype}`);
19079
+ console.log(
19080
+ ` Format: ${manifest.format} | Subtype: ${manifest.subtype}`
19081
+ );
18867
19082
  console.log(` Description: ${manifest.description}`);
18868
19083
  console.log(` Access: ${manifest.private ? "private" : "public"}`);
18869
19084
  if (publishAsAuthor) {
18870
19085
  console.log(` \u{1F510} Author Override: ${publishAsAuthor} (admin)`);
18871
19086
  }
18872
19087
  if (selectedOrgId && userInfo) {
18873
- const selectedOrg = userInfo.organizations.find((org) => org.id === selectedOrgId);
18874
- console.log(` Publishing to: ${(selectedOrg == null ? void 0 : selectedOrg.name) || "organization"}`);
19088
+ const selectedOrg = userInfo.organizations.find(
19089
+ (org) => org.id === selectedOrgId
19090
+ );
19091
+ console.log(
19092
+ ` Publishing to: ${(selectedOrg == null ? void 0 : selectedOrg.name) || "organization"}`
19093
+ );
18875
19094
  }
18876
19095
  console.log("");
18877
19096
  console.log("\u{1F50D} Validating package files...");
@@ -18882,7 +19101,9 @@ ${"=".repeat(60)}`);
18882
19101
  console.log(` - ${err}`);
18883
19102
  });
18884
19103
  console.log("");
18885
- throw new Error("Package files do not match the specified format. Please fix the errors above.");
19104
+ throw new Error(
19105
+ "Package files do not match the specified format. Please fix the errors above."
19106
+ );
18886
19107
  }
18887
19108
  if (fileValidation.warnings.length > 0) {
18888
19109
  console.log(" \u26A0\uFE0F Format validation warnings:");
@@ -18916,19 +19137,12 @@ ${"=".repeat(60)}`);
18916
19137
  console.log("");
18917
19138
  console.log("\u{1F4E6} Creating package tarball...");
18918
19139
  const tarball = await createTarball(manifest);
18919
- const sizeInBytes = tarball.length;
18920
- const sizeInKB = sizeInBytes / 1024;
18921
- const sizeInMB = sizeInBytes / (1024 * 1024);
18922
- let sizeDisplay;
18923
- if (sizeInMB >= 1) {
18924
- sizeDisplay = `${sizeInMB.toFixed(2)}MB`;
18925
- } else {
18926
- sizeDisplay = `${sizeInKB.toFixed(2)}KB`;
18927
- }
18928
- console.log(` Size: ${sizeDisplay}`);
19140
+ console.log(` Size: ${formatTarballSize(tarball.length)}`);
18929
19141
  console.log("");
18930
19142
  if (selectedOrgId) {
18931
- console.log(` Publishing as organization: ${(_b = userInfo.organizations.find((org) => org.id === selectedOrgId)) == null ? void 0 : _b.name}`);
19143
+ console.log(
19144
+ ` Publishing as organization: ${(_b = userInfo.organizations.find((org) => org.id === selectedOrgId)) == null ? void 0 : _b.name}`
19145
+ );
18932
19146
  console.log(` Organization ID: ${selectedOrgId}`);
18933
19147
  }
18934
19148
  if (options.dryRun) {
@@ -18984,22 +19198,34 @@ ${"=".repeat(60)}`);
18984
19198
  } catch (err) {
18985
19199
  const pkgError = err instanceof Error ? err.message : String(err);
18986
19200
  lastError = err instanceof Error ? err : new Error(String(err));
18987
- const displayName = getSafePackageName(manifest, userInfo, packageName);
19201
+ const displayName = getSafePackageName(
19202
+ manifest,
19203
+ userInfo,
19204
+ packageName
19205
+ );
18988
19206
  if (isRetriableError(pkgError) && retryCount < MAX_RETRIES) {
18989
- console.error(`
18990
- \u26A0\uFE0F Temporary error publishing ${displayName}: ${pkgError}`);
18991
- console.error(` Will retry (${retryCount + 1}/${MAX_RETRIES})...
18992
- `);
19207
+ console.error(
19208
+ `
19209
+ \u26A0\uFE0F Temporary error publishing ${displayName}: ${pkgError}`
19210
+ );
19211
+ console.error(
19212
+ ` Will retry (${retryCount + 1}/${MAX_RETRIES})...
19213
+ `
19214
+ );
18993
19215
  retryCount++;
18994
19216
  } else {
18995
19217
  if (retryCount >= MAX_RETRIES) {
18996
- console.error(`
19218
+ console.error(
19219
+ `
18997
19220
  \u274C Failed to publish ${displayName} after ${MAX_RETRIES} retries: ${pkgError}
18998
- `);
19221
+ `
19222
+ );
18999
19223
  } else {
19000
- console.error(`
19224
+ console.error(
19225
+ `
19001
19226
  \u274C Failed to publish ${displayName}: ${pkgError}
19002
- `);
19227
+ `
19228
+ );
19003
19229
  }
19004
19230
  failedPackages.push({
19005
19231
  name: displayName,
@@ -19014,9 +19240,13 @@ ${"=".repeat(60)}`);
19014
19240
  if (collections.length > 0 && shouldPublishCollections) {
19015
19241
  let filteredCollections = collections;
19016
19242
  if (options.collection) {
19017
- filteredCollections = collections.filter((c) => c.id === options.collection);
19243
+ filteredCollections = collections.filter(
19244
+ (c) => c.id === options.collection
19245
+ );
19018
19246
  if (filteredCollections.length === 0) {
19019
- throw new Error(`Collection "${options.collection}" not found in manifest. Available collections: ${collections.map((c) => c.id).join(", ")}`);
19247
+ throw new Error(
19248
+ `Collection "${options.collection}" not found in manifest. Available collections: ${collections.map((c) => c.id).join(", ")}`
19249
+ );
19020
19250
  }
19021
19251
  console.log(` \u2713 Found collection "${options.collection}"
19022
19252
  `);
@@ -19035,7 +19265,9 @@ ${"=".repeat(60)}`);
19035
19265
  console.log(` Packages: ${collection.packages.length}`);
19036
19266
  console.log("");
19037
19267
  if (options.dryRun) {
19038
- console.log("\u2705 Dry run successful! Collection is ready to publish.");
19268
+ console.log(
19269
+ "\u2705 Dry run successful! Collection is ready to publish."
19270
+ );
19039
19271
  publishedCollections.push({
19040
19272
  id: collection.id,
19041
19273
  name: collection.name,
@@ -19064,7 +19296,9 @@ ${"=".repeat(60)}`);
19064
19296
  console.log(` Name: ${result.name_slug}`);
19065
19297
  console.log(` Version: ${result.version || "1.0.0"}`);
19066
19298
  console.log("");
19067
- console.log(`\u{1F4A1} Install: prpm install collections/${result.name_slug}`);
19299
+ console.log(
19300
+ `\u{1F4A1} Install: prpm install collections/${result.name_slug}`
19301
+ );
19068
19302
  console.log("");
19069
19303
  publishedCollections.push({
19070
19304
  id: collection.id,
@@ -19073,9 +19307,11 @@ ${"=".repeat(60)}`);
19073
19307
  });
19074
19308
  } catch (err) {
19075
19309
  const collError = err instanceof Error ? err.message : String(err);
19076
- console.error(`
19310
+ console.error(
19311
+ `
19077
19312
  \u274C Failed to publish collection ${collection.id}: ${collError}
19078
- `);
19313
+ `
19314
+ );
19079
19315
  failedCollections.push({
19080
19316
  id: collection.id,
19081
19317
  error: collError
@@ -19083,14 +19319,18 @@ ${"=".repeat(60)}`);
19083
19319
  }
19084
19320
  }
19085
19321
  if (publishedCollections.length > 0) {
19086
- console.log(`\u2705 Successfully published ${publishedCollections.length} collection(s):`);
19322
+ console.log(
19323
+ `\u2705 Successfully published ${publishedCollections.length} collection(s):`
19324
+ );
19087
19325
  publishedCollections.forEach((coll) => {
19088
19326
  console.log(` - ${coll.name} (${coll.id}) v${coll.version}`);
19089
19327
  });
19090
19328
  console.log("");
19091
19329
  }
19092
19330
  if (failedCollections.length > 0) {
19093
- console.log(`\u274C Failed to publish ${failedCollections.length} collection(s):`);
19331
+ console.log(
19332
+ `\u274C Failed to publish ${failedCollections.length} collection(s):`
19333
+ );
19094
19334
  failedCollections.forEach((coll) => {
19095
19335
  console.log(` - ${coll.id}: ${coll.error}`);
19096
19336
  });
@@ -19104,12 +19344,16 @@ ${"=".repeat(60)}`);
19104
19344
  console.log(`${"=".repeat(60)}
19105
19345
  `);
19106
19346
  if (publishedPackages.length > 0) {
19107
- const hasAuthorOverride = publishedPackages.some((pkg) => pkg.authorOverride);
19347
+ const hasAuthorOverride = publishedPackages.some(
19348
+ (pkg) => pkg.authorOverride
19349
+ );
19108
19350
  if (hasAuthorOverride) {
19109
19351
  console.log(`\u{1F510} Admin author override active
19110
19352
  `);
19111
19353
  }
19112
- console.log(`\u2705 Successfully published ${publishedPackages.length} package(s):`);
19354
+ console.log(
19355
+ `\u2705 Successfully published ${publishedPackages.length} package(s):`
19356
+ );
19113
19357
  publishedPackages.forEach((pkg) => {
19114
19358
  const overrideSuffix = pkg.authorOverride ? ` (as ${pkg.authorOverride})` : "";
19115
19359
  console.log(` - ${pkg.name}@${pkg.version}${overrideSuffix}`);
@@ -19120,16 +19364,24 @@ ${"=".repeat(60)}`);
19120
19364
  console.log("");
19121
19365
  }
19122
19366
  if (failedPackages.length > 0) {
19123
- console.log(`\u274C Failed to publish ${failedPackages.length} package(s):`);
19367
+ console.log(
19368
+ `\u274C Failed to publish ${failedPackages.length} package(s):`
19369
+ );
19124
19370
  failedPackages.forEach((pkg) => {
19125
19371
  console.log(` - ${pkg.name}: ${pkg.error}`);
19126
19372
  });
19127
19373
  console.log("");
19128
19374
  if (failedPackages.some((pkg) => pkg.error.includes("Forbidden"))) {
19129
19375
  console.log("\u{1F4A1} Forbidden errors usually mean:");
19130
- console.log(" - The package already exists and you don't have permission to update it");
19131
- console.log(" - The package belongs to an organization and you're not a member with publish rights");
19132
- console.log(" - Try: prpm whoami (to check your organization memberships)");
19376
+ console.log(
19377
+ " - The package already exists and you don't have permission to update it"
19378
+ );
19379
+ console.log(
19380
+ " - The package belongs to an organization and you're not a member with publish rights"
19381
+ );
19382
+ console.log(
19383
+ " - Try: prpm whoami (to check your organization memberships)"
19384
+ );
19133
19385
  console.log("");
19134
19386
  }
19135
19387
  }
@@ -19184,7 +19436,16 @@ ${"=".repeat(60)}`);
19184
19436
  }
19185
19437
  }
19186
19438
  function createPublishCommand() {
19187
- return new import_commander13.Command("publish").description("Publish packages and collections to the registry").option("--access <type>", "Package access (public or private) - overrides manifest setting").option("--tag <tag>", "NPM-style tag (e.g., latest, beta)", "latest").option("--dry-run", "Validate package without publishing").option("--package <name>", "Publish only a specific package from multi-package manifest").option("--collection <id>", "Publish only a specific collection from manifest").action(async (options) => {
19439
+ return new import_commander13.Command("publish").description("Publish packages and collections to the registry").option(
19440
+ "--access <type>",
19441
+ "Package access (public or private) - overrides manifest setting"
19442
+ ).option("--tag <tag>", "NPM-style tag (e.g., latest, beta)", "latest").option("--dry-run", "Validate package without publishing").option(
19443
+ "--package <name>",
19444
+ "Publish only a specific package from multi-package manifest"
19445
+ ).option(
19446
+ "--collection <id>",
19447
+ "Publish only a specific collection from manifest"
19448
+ ).option("-l, --list", "List all packages in prpm.json without publishing").action(async (options) => {
19188
19449
  await handlePublish(options);
19189
19450
  });
19190
19451
  }
@@ -21146,58 +21407,58 @@ function createStarredCommand() {
21146
21407
  // src/commands/convert.ts
21147
21408
  init_cjs_shims();
21148
21409
  var import_commander27 = require("commander");
21149
- var import_promises8 = require("fs/promises");
21150
- var import_path18 = require("path");
21410
+ var import_promises10 = require("fs/promises");
21411
+ var import_path20 = require("path");
21151
21412
  var import_fs16 = require("fs");
21152
21413
  var import_readline = require("readline");
21153
21414
  var import_chalk2 = __toESM(require_source());
21154
21415
  init_errors();
21155
21416
  init_dist();
21156
21417
  function getDefaultPath(format, filename, subtype, customName) {
21157
- const baseName = customName || (0, import_path18.basename)(filename, (0, import_path18.extname)(filename));
21418
+ const baseName = customName || (0, import_path20.basename)(filename, (0, import_path20.extname)(filename));
21158
21419
  switch (format) {
21159
21420
  case "cursor":
21160
21421
  if (subtype === "slash-command") {
21161
- return (0, import_path18.join)(process.cwd(), ".cursor", "commands", `${baseName}.md`);
21422
+ return (0, import_path20.join)(process.cwd(), ".cursor", "commands", `${baseName}.md`);
21162
21423
  }
21163
- return (0, import_path18.join)(process.cwd(), ".cursor", "rules", `${baseName}.mdc`);
21424
+ return (0, import_path20.join)(process.cwd(), ".cursor", "rules", `${baseName}.mdc`);
21164
21425
  case "claude":
21165
21426
  if (subtype === "skill") {
21166
- return (0, import_path18.join)(process.cwd(), ".claude", "skills", baseName, "SKILL.md");
21427
+ return (0, import_path20.join)(process.cwd(), ".claude", "skills", baseName, "SKILL.md");
21167
21428
  } else if (subtype === "slash-command") {
21168
- return (0, import_path18.join)(process.cwd(), ".claude", "commands", `${baseName}.md`);
21429
+ return (0, import_path20.join)(process.cwd(), ".claude", "commands", `${baseName}.md`);
21169
21430
  } else {
21170
- return (0, import_path18.join)(process.cwd(), ".claude", "agents", `${baseName}.md`);
21431
+ return (0, import_path20.join)(process.cwd(), ".claude", "agents", `${baseName}.md`);
21171
21432
  }
21172
21433
  case "windsurf":
21173
- return (0, import_path18.join)(process.cwd(), ".windsurf", "rules", `${baseName}.md`);
21434
+ return (0, import_path20.join)(process.cwd(), ".windsurf", "rules", `${baseName}.md`);
21174
21435
  case "kiro":
21175
21436
  if (subtype === "hook") {
21176
- return (0, import_path18.join)(process.cwd(), ".kiro", "hooks", `${baseName}.kiro.hook`);
21437
+ return (0, import_path20.join)(process.cwd(), ".kiro", "hooks", `${baseName}.kiro.hook`);
21177
21438
  }
21178
21439
  if (subtype === "agent") {
21179
- return (0, import_path18.join)(process.cwd(), ".kiro", "agents", `${baseName}.json`);
21440
+ return (0, import_path20.join)(process.cwd(), ".kiro", "agents", `${baseName}.json`);
21180
21441
  }
21181
- return (0, import_path18.join)(process.cwd(), ".kiro", "steering", `${baseName}.md`);
21442
+ return (0, import_path20.join)(process.cwd(), ".kiro", "steering", `${baseName}.md`);
21182
21443
  case "copilot":
21183
- return (0, import_path18.join)(process.cwd(), ".github", "instructions", `${baseName}.instructions.md`);
21444
+ return (0, import_path20.join)(process.cwd(), ".github", "instructions", `${baseName}.instructions.md`);
21184
21445
  case "continue":
21185
21446
  if (subtype === "slash-command" || subtype === "prompt") {
21186
- return (0, import_path18.join)(process.cwd(), ".continue", "prompts", `${baseName}.md`);
21447
+ return (0, import_path20.join)(process.cwd(), ".continue", "prompts", `${baseName}.md`);
21187
21448
  }
21188
- return (0, import_path18.join)(process.cwd(), ".continue", "rules", `${baseName}.md`);
21449
+ return (0, import_path20.join)(process.cwd(), ".continue", "rules", `${baseName}.md`);
21189
21450
  case "agents.md":
21190
- return (0, import_path18.join)(process.cwd(), "agents.md");
21451
+ return (0, import_path20.join)(process.cwd(), "agents.md");
21191
21452
  case "gemini":
21192
- return (0, import_path18.join)(process.cwd(), ".gemini", "commands", `${baseName}.toml`);
21453
+ return (0, import_path20.join)(process.cwd(), ".gemini", "commands", `${baseName}.toml`);
21193
21454
  case "ruler":
21194
- return (0, import_path18.join)(process.cwd(), ".ruler", `${baseName}.md`);
21455
+ return (0, import_path20.join)(process.cwd(), ".ruler", `${baseName}.md`);
21195
21456
  default:
21196
21457
  throw new CLIError(`Unknown format: ${format}`);
21197
21458
  }
21198
21459
  }
21199
21460
  function detectFormat(content, filepath) {
21200
- const ext = (0, import_path18.extname)(filepath).toLowerCase();
21461
+ const ext = (0, import_path20.extname)(filepath).toLowerCase();
21201
21462
  if (ext === ".mdc" || filepath.includes(".cursor/rules") || filepath.includes(".cursor/commands")) {
21202
21463
  return "cursor";
21203
21464
  }
@@ -21219,7 +21480,7 @@ function detectFormat(content, filepath) {
21219
21480
  if (filepath.includes(".continue/rules") || filepath.includes(".continue/prompts") || filepath.includes(".continuerules")) {
21220
21481
  return "continue";
21221
21482
  }
21222
- if ((0, import_path18.basename)(filepath) === "agents.md") {
21483
+ if ((0, import_path20.basename)(filepath) === "agents.md") {
21223
21484
  return "agents.md";
21224
21485
  }
21225
21486
  if (ext === ".toml" || filepath.includes(".gemini/commands")) {
@@ -21263,7 +21524,7 @@ async function handleConvert(sourcePath, options) {
21263
21524
  console.log(import_chalk2.default.dim("Reading source file..."));
21264
21525
  let content;
21265
21526
  try {
21266
- content = await (0, import_promises8.readFile)(sourcePath, "utf-8");
21527
+ content = await (0, import_promises10.readFile)(sourcePath, "utf-8");
21267
21528
  } catch (error) {
21268
21529
  throw new CLIError(`Failed to read source file: ${error.message}`);
21269
21530
  }
@@ -21384,10 +21645,10 @@ async function handleConvert(sourcePath, options) {
21384
21645
  return;
21385
21646
  }
21386
21647
  }
21387
- const outputDir = (0, import_path18.dirname)(outputPath);
21388
- await (0, import_promises8.mkdir)(outputDir, { recursive: true });
21648
+ const outputDir = (0, import_path20.dirname)(outputPath);
21649
+ await (0, import_promises10.mkdir)(outputDir, { recursive: true });
21389
21650
  console.log(import_chalk2.default.dim("Writing converted file..."));
21390
- await (0, import_promises8.writeFile)(outputPath, result.content, "utf-8");
21651
+ await (0, import_promises10.writeFile)(outputPath, result.content, "utf-8");
21391
21652
  console.log(import_chalk2.default.green(`\u2713 Converted file written to ${outputPath}`));
21392
21653
  console.log();
21393
21654
  if (options.to === "cursor") {
@@ -21451,7 +21712,7 @@ Valid subtypes: ${validSubtypes.join(", ")}`
21451
21712
  init_cjs_shims();
21452
21713
  var import_commander28 = require("commander");
21453
21714
  var import_fs17 = require("fs");
21454
- var import_path19 = require("path");
21715
+ var import_path21 = require("path");
21455
21716
  var import_chalk3 = __toESM(require_source());
21456
21717
  init_errors();
21457
21718
  init_lockfile();
@@ -21467,7 +21728,7 @@ async function exportToRuler(options) {
21467
21728
  }
21468
21729
  console.log(import_chalk3.default.green(`\u2713 Found ${packages.length} installed package${packages.length === 1 ? "" : "s"}`));
21469
21730
  console.log();
21470
- const outputDir = options.output || (0, import_path19.join)(process.cwd(), ".ruler");
21731
+ const outputDir = options.output || (0, import_path21.join)(process.cwd(), ".ruler");
21471
21732
  let rulerExists = false;
21472
21733
  try {
21473
21734
  await import_fs17.promises.access(outputDir);
@@ -21494,7 +21755,7 @@ async function exportToRuler(options) {
21494
21755
  const content = await import_fs17.promises.readFile(pkg.installedPath, "utf-8");
21495
21756
  const rulerContent = createRulerFormat(pkg.id, pkg.version, content, pkg.format, pkg.subtype);
21496
21757
  const rulerFilename = `${packageName}.md`;
21497
- const rulerPath = (0, import_path19.join)(outputDir, rulerFilename);
21758
+ const rulerPath = (0, import_path21.join)(outputDir, rulerFilename);
21498
21759
  await import_fs17.promises.writeFile(rulerPath, rulerContent, "utf-8");
21499
21760
  console.log(import_chalk3.default.green(`\u2713 Exported ${pkg.id} \u2192 ${rulerFilename}`));
21500
21761
  exportedCount++;
@@ -21534,7 +21795,7 @@ function createRulerFormat(packageId, version, content, format, subtype) {
21534
21795
  return frontmatter + contentWithoutFrontmatter;
21535
21796
  }
21536
21797
  async function ensureRulerConfig(rulerDir) {
21537
- const configPath = (0, import_path19.join)((0, import_path19.dirname)(rulerDir), "ruler.toml");
21798
+ const configPath = (0, import_path21.join)((0, import_path21.dirname)(rulerDir), "ruler.toml");
21538
21799
  try {
21539
21800
  await import_fs17.promises.access(configPath);
21540
21801
  console.log(import_chalk3.default.dim("\u2139 ruler.toml already exists (not modified)"));
@@ -21632,7 +21893,7 @@ init_telemetry();
21632
21893
  init_errors();
21633
21894
  function getVersion() {
21634
21895
  try {
21635
- const packageJsonPath = (0, import_path20.join)(__dirname, "../package.json");
21896
+ const packageJsonPath = (0, import_path22.join)(__dirname, "../package.json");
21636
21897
  const packageJson = JSON.parse((0, import_fs18.readFileSync)(packageJsonPath, "utf-8"));
21637
21898
  return packageJson.version || "0.0.0";
21638
21899
  } catch {