prpm 0.1.11 โ†’ 0.1.13

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.
@@ -87,7 +87,9 @@ async function handleCollectionsSearch(query, options) {
87
87
  if (c.description) {
88
88
  console.log(` ${c.description.substring(0, 70)}${c.description.length > 70 ? '...' : ''}`);
89
89
  }
90
- console.log(` ๐Ÿ‘ค by @${c.author}${c.verified ? ' โœ“' : ''}`);
90
+ if (c.author) {
91
+ console.log(` ๐Ÿ‘ค by @${c.author}${c.verified ? ' โœ“' : ''}`);
92
+ }
91
93
  console.log(` โฌ‡๏ธ ${c.downloads.toLocaleString()} installs ยท โญ ${c.stars.toLocaleString()} stars`);
92
94
  console.log('');
93
95
  });
@@ -101,7 +103,9 @@ async function handleCollectionsSearch(query, options) {
101
103
  if (c.description) {
102
104
  console.log(` ${c.description.substring(0, 70)}${c.description.length > 70 ? '...' : ''}`);
103
105
  }
104
- console.log(` ๐Ÿ‘ค by @${c.author}${c.verified ? ' โœ“' : ''}`);
106
+ if (c.author) {
107
+ console.log(` ๐Ÿ‘ค by @${c.author}${c.verified ? ' โœ“' : ''}`);
108
+ }
105
109
  console.log(` โฌ‡๏ธ ${c.downloads.toLocaleString()} installs ยท โญ ${c.stars.toLocaleString()} stars`);
106
110
  console.log('');
107
111
  });
@@ -169,7 +173,9 @@ async function handleCollectionsList(options) {
169
173
  if (c.description) {
170
174
  console.log(` ${c.description.substring(0, 70)}${c.description.length > 70 ? '...' : ''}`);
171
175
  }
172
- console.log(` ๐Ÿ‘ค by @${c.author}${c.verified ? ' โœ“' : ''}`);
176
+ if (c.author) {
177
+ console.log(` ๐Ÿ‘ค by @${c.author}${c.verified ? ' โœ“' : ''}`);
178
+ }
173
179
  console.log(` โฌ‡๏ธ ${c.downloads.toLocaleString()} installs ยท โญ ${c.stars.toLocaleString()} stars`);
174
180
  console.log('');
175
181
  });
@@ -183,7 +189,9 @@ async function handleCollectionsList(options) {
183
189
  if (c.description) {
184
190
  console.log(` ${c.description.substring(0, 70)}${c.description.length > 70 ? '...' : ''}`);
185
191
  }
186
- console.log(` ๐Ÿ‘ค by @${c.author}${c.verified ? ' โœ“' : ''}`);
192
+ if (c.author) {
193
+ console.log(` ๐Ÿ‘ค by @${c.author}${c.verified ? ' โœ“' : ''}`);
194
+ }
187
195
  console.log(` โฌ‡๏ธ ${c.downloads.toLocaleString()} installs ยท โญ ${c.stars.toLocaleString()} stars`);
188
196
  console.log('');
189
197
  });
@@ -265,7 +273,9 @@ async function handleCollectionInfo(collectionSpec) {
265
273
  console.log(` Stars: ${collection.stars.toLocaleString()}`);
266
274
  console.log(` Version: ${collection.version}`);
267
275
  console.log(` Packages: ${collection.packages.length}`);
268
- console.log(` Author: ${collection.author}${collection.verified ? ' โœ“' : ''}`);
276
+ if (collection.author) {
277
+ console.log(` Author: ${collection.author}${collection.verified ? ' โœ“' : ''}`);
278
+ }
269
279
  if (collection.category) {
270
280
  console.log(` Category: ${collection.category}`);
271
281
  }
@@ -503,8 +513,10 @@ async function handleCollectionInstall(collectionSpec, options) {
503
513
  try {
504
514
  console.log(`\n ${progress} Installing ${pkg.packageId}@${pkg.version}...`);
505
515
  // Only pass 'as' format if user explicitly requested it via --as flag
506
- // Otherwise, let handleInstall auto-detect the format based on existing directories
507
- // This ensures collections respect existing .claude or .cursor directories
516
+ // Otherwise, handleInstall will use this priority order:
517
+ // 1. defaultFormat from .prpmrc config
518
+ // 2. Auto-detection based on existing directories
519
+ // 3. Package native format
508
520
  const installOptions = {
509
521
  fromCollection: {
510
522
  scope,
@@ -224,18 +224,29 @@ async function handleInstall(packageSpec, options) {
224
224
  console.log(` ${pkg.name} ${pkg.official ? '๐Ÿ…' : ''}`);
225
225
  console.log(` ${pkg.description || 'No description'}`);
226
226
  console.log(` ${typeIcon} Type: ${typeLabel}`);
227
- // Determine format preference with auto-detection
227
+ // Determine format preference with priority order:
228
+ // 1. CLI --as flag (highest priority)
229
+ // 2. defaultFormat from .prpmrc config
230
+ // 3. Auto-detection based on existing directories
231
+ // 4. Package native format (fallback)
228
232
  let format = options.as;
229
- // Auto-detect format if not explicitly specified
230
233
  if (!format) {
231
- const detectedFormat = await (0, filesystem_1.autoDetectFormat)();
232
- if (detectedFormat) {
233
- format = detectedFormat;
234
- console.log(` ๐Ÿ” Auto-detected ${format} format (found .${format}/ directory)`);
234
+ // Check for config default format
235
+ if (config.defaultFormat) {
236
+ format = config.defaultFormat;
237
+ console.log(` โš™๏ธ Using default format from config: ${format}`);
235
238
  }
236
239
  else {
237
- // No existing directories found, use package's native format
238
- format = pkg.format;
240
+ // Auto-detect format based on existing directories
241
+ const detectedFormat = await (0, filesystem_1.autoDetectFormat)();
242
+ if (detectedFormat) {
243
+ format = detectedFormat;
244
+ console.log(` ๐Ÿ” Auto-detected ${format} format (found .${format}/ directory)`);
245
+ }
246
+ else {
247
+ // No config or detection, use package's native format
248
+ format = pkg.format;
249
+ }
239
250
  }
240
251
  }
241
252
  // Special handling for Claude packages: default to CLAUDE.md if it doesn't exist
@@ -42,6 +42,8 @@ const commander_1 = require("commander");
42
42
  const user_config_1 = require("../core/user-config");
43
43
  const telemetry_1 = require("../core/telemetry");
44
44
  const readline = __importStar(require("readline"));
45
+ const fs = __importStar(require("fs"));
46
+ const path = __importStar(require("path"));
45
47
  const errors_1 = require("../core/errors");
46
48
  /**
47
49
  * Create a readline interface for user input
@@ -126,6 +128,28 @@ async function runPlayground(packageName, input, options, sessionId) {
126
128
  });
127
129
  return response.json();
128
130
  }
131
+ /**
132
+ * Execute a custom prompt playground run
133
+ */
134
+ async function runCustomPrompt(customPrompt, input, options, sessionId) {
135
+ const response = await apiCall('/api/v1/custom-prompt/run', 'POST', {
136
+ custom_prompt: customPrompt,
137
+ input,
138
+ model: options.model || 'sonnet',
139
+ session_id: sessionId,
140
+ });
141
+ return response.json();
142
+ }
143
+ /**
144
+ * Read custom prompt from file
145
+ */
146
+ function readPromptFile(filePath) {
147
+ const absolutePath = path.resolve(filePath);
148
+ if (!fs.existsSync(absolutePath)) {
149
+ throw new Error(`Prompt file not found: ${filePath}`);
150
+ }
151
+ return fs.readFileSync(absolutePath, 'utf-8');
152
+ }
129
153
  /**
130
154
  * Format and display playground response
131
155
  */
@@ -200,6 +224,139 @@ async function runInteractive(packageName, options) {
200
224
  rl.close();
201
225
  }
202
226
  }
227
+ /**
228
+ * Run interactive custom prompt session
229
+ */
230
+ async function runCustomInteractive(customPrompt, options) {
231
+ console.log('\n๐ŸŽฎ Interactive Custom Prompt Mode');
232
+ console.log(` Model: ${options.model || 'sonnet'}`);
233
+ console.log(` Type 'exit' or 'quit' to end session\n`);
234
+ const rl = createReadline();
235
+ let sessionId;
236
+ let turnCount = 0;
237
+ try {
238
+ while (true) {
239
+ const input = await prompt(rl, `\n๐Ÿ’ฌ You: `);
240
+ if (input.trim().toLowerCase() === 'exit' || input.trim().toLowerCase() === 'quit') {
241
+ console.log('\n๐Ÿ‘‹ Ending playground session. Goodbye!');
242
+ break;
243
+ }
244
+ if (!input.trim()) {
245
+ console.log('โŒ Please enter a message');
246
+ continue;
247
+ }
248
+ try {
249
+ console.log('\nโณ Processing...');
250
+ const result = await runCustomPrompt(customPrompt, input, options, sessionId);
251
+ // Store session ID for conversation continuity
252
+ sessionId = result.session_id;
253
+ turnCount++;
254
+ displayResponse(result, true);
255
+ }
256
+ catch (error) {
257
+ console.error(`\nโŒ Error: ${error instanceof Error ? error.message : String(error)}`);
258
+ if (error instanceof Error && error.message.includes('Insufficient credits')) {
259
+ console.log('\n๐Ÿ’ก Get more credits:');
260
+ console.log(' - Purchase credits: prpm buy-credits');
261
+ console.log(' - Subscribe to PRPM+: prpm subscribe');
262
+ console.log(' - Check balance: prpm credits');
263
+ break;
264
+ }
265
+ }
266
+ }
267
+ if (turnCount > 0) {
268
+ console.log(`\n๐Ÿ“ Session summary: ${turnCount} turn(s)`);
269
+ }
270
+ }
271
+ finally {
272
+ rl.close();
273
+ }
274
+ }
275
+ /**
276
+ * Run baseline (no prompt) comparison
277
+ */
278
+ async function runBaseline(input, options) {
279
+ // Use a minimal package but with use_no_prompt flag to get raw model baseline
280
+ // We need any valid package ID because the API requires it, but the prompt will be ignored
281
+ // Let's use a well-known minimal package (we'll search for any package)
282
+ const config = await (0, user_config_1.getConfig)();
283
+ const baseUrl = (config.registryUrl || "https://registry.prpm.dev").replace(/\/$/, '');
284
+ // Get any package to use for baseline comparison (the prompt will be ignored anyway)
285
+ const searchResponse = await fetch(`${baseUrl}/api/v1/search?q=coding&limit=1`);
286
+ if (!searchResponse.ok) {
287
+ throw new Error('Failed to find a package for baseline comparison');
288
+ }
289
+ const searchData = await searchResponse.json();
290
+ if (!searchData.packages || searchData.packages.length === 0) {
291
+ throw new Error('No packages found for baseline comparison');
292
+ }
293
+ const dummyPackageId = searchData.packages[0].id;
294
+ // Call playground with use_no_prompt flag (this ignores the package prompt)
295
+ const response = await apiCall('/api/v1/playground/run', 'POST', {
296
+ package_id: dummyPackageId,
297
+ input,
298
+ model: options.model || 'sonnet',
299
+ use_no_prompt: true, // This makes it a raw baseline with no system prompt
300
+ });
301
+ return response.json();
302
+ }
303
+ /**
304
+ * Run single custom prompt query
305
+ */
306
+ async function runCustomSingle(customPrompt, input, options) {
307
+ console.log(`\n๐ŸŽฎ Testing custom prompt`);
308
+ console.log(` Model: ${options.model || 'sonnet'}`);
309
+ console.log(` Credits: 2x normal cost (custom prompts)`);
310
+ if (options.compare) {
311
+ console.log(` Mode: Comparing custom prompt vs. no prompt (baseline)`);
312
+ }
313
+ try {
314
+ if (options.compare) {
315
+ // Comparison mode: run with custom prompt and without any prompt
316
+ console.log('\nโณ Processing comparison (2 requests)...');
317
+ // Run with custom prompt
318
+ const resultWithPrompt = await runCustomPrompt(customPrompt, input, options);
319
+ // Run baseline (no prompt at all)
320
+ const resultBaseline = await runBaseline(input, options);
321
+ // Display both results
322
+ console.log('\n' + 'โ•'.repeat(60));
323
+ console.log('โœจ WITH CUSTOM PROMPT');
324
+ console.log('โ•'.repeat(60));
325
+ displayResponse(resultWithPrompt, false);
326
+ console.log('\n' + 'โ•'.repeat(60));
327
+ console.log('๐Ÿ”ต WITHOUT PROMPT (BASELINE)');
328
+ console.log('โ•'.repeat(60));
329
+ displayResponse(resultBaseline, false);
330
+ // Combined stats
331
+ console.log(`\n๐Ÿ“Š Combined Stats:`);
332
+ console.log(` Total tokens: ${resultWithPrompt.tokens_used + resultBaseline.tokens_used}`);
333
+ console.log(` Total credits: ${resultWithPrompt.credits_spent + resultBaseline.credits_spent}`);
334
+ console.log(` Credits remaining: ${resultBaseline.credits_remaining}`);
335
+ console.log(`\n๐Ÿ’ก Compare the responses to evaluate your custom prompt's effectiveness!`);
336
+ }
337
+ else {
338
+ // Single mode: run with custom prompt only
339
+ console.log('\nโณ Processing...');
340
+ const result = await runCustomPrompt(customPrompt, input, options);
341
+ displayResponse(result, true);
342
+ console.log(`\n๐Ÿ’ก Tips:`);
343
+ console.log(` - Use --interactive for multi-turn conversation`);
344
+ console.log(` - Use --compare to test against baseline (no prompt)`);
345
+ console.log(` - Use --prompt-file to iterate on a prompt file`);
346
+ console.log(` - Custom prompts cost 2x credits (no caching)`);
347
+ }
348
+ }
349
+ catch (error) {
350
+ console.error(`\nโŒ Error: ${error instanceof Error ? error.message : String(error)}`);
351
+ if (error instanceof Error && error.message.includes('Insufficient credits')) {
352
+ console.log('\n๐Ÿ’ก Get more credits:');
353
+ console.log(' - Purchase credits: prpm buy-credits');
354
+ console.log(' - Subscribe to PRPM+: prpm subscribe');
355
+ console.log(' - Check balance: prpm credits');
356
+ }
357
+ throw new errors_1.CLIError(`\nโŒ Error: ${error instanceof Error ? error.message : String(error)}`, 1);
358
+ }
359
+ }
203
360
  /**
204
361
  * Run single playground query
205
362
  */
@@ -259,10 +416,11 @@ async function runSingle(packageName, input, options) {
259
416
  /**
260
417
  * Handle the playground command
261
418
  */
262
- async function handlePlayground(packageName, input, options) {
419
+ async function handlePlayground(options) {
263
420
  const startTime = Date.now();
264
421
  let success = false;
265
422
  let error;
423
+ let customPromptMode = false;
266
424
  try {
267
425
  // Validate authentication
268
426
  const config = await (0, user_config_1.getConfig)();
@@ -272,14 +430,50 @@ async function handlePlayground(packageName, input, options) {
272
430
  console.log(' prpm login');
273
431
  throw new errors_1.CLIError('โŒ Authentication required', 1);
274
432
  }
275
- // Interactive mode or single query
276
- if (options.interactive || !input) {
277
- // Interactive mode
278
- await runInteractive(packageName, options);
433
+ // Check for custom prompt mode
434
+ if (options.custom || options.promptFile) {
435
+ customPromptMode = true;
436
+ // Get custom prompt from option or file
437
+ let customPrompt;
438
+ if (options.promptFile) {
439
+ console.log(`๐Ÿ“„ Loading prompt from: ${options.promptFile}`);
440
+ customPrompt = readPromptFile(options.promptFile);
441
+ console.log(`โœ… Loaded ${customPrompt.length} characters\n`);
442
+ }
443
+ else {
444
+ customPrompt = options.custom;
445
+ }
446
+ // Validate custom prompt length
447
+ if (customPrompt.length < 10) {
448
+ throw new Error('Custom prompt too short (minimum 10 characters)');
449
+ }
450
+ if (customPrompt.length > 50000) {
451
+ throw new Error('Custom prompt too long (maximum 50000 characters)');
452
+ }
453
+ // Interactive mode or single query
454
+ if (options.interactive || !options.input) {
455
+ // Interactive mode with custom prompt
456
+ await runCustomInteractive(customPrompt, options);
457
+ }
458
+ else {
459
+ // Single query mode with custom prompt
460
+ await runCustomSingle(customPrompt, options.input, options);
461
+ }
279
462
  }
280
463
  else {
281
- // Single query mode
282
- await runSingle(packageName, input, options);
464
+ // Regular package-based playground
465
+ if (!options.package) {
466
+ throw new Error('Either --package or --custom/--prompt-file is required');
467
+ }
468
+ // Interactive mode or single query
469
+ if (options.interactive || !options.input) {
470
+ // Interactive mode
471
+ await runInteractive(options.package, options);
472
+ }
473
+ else {
474
+ // Single query mode
475
+ await runSingle(options.package, options.input, options);
476
+ }
283
477
  }
284
478
  success = true;
285
479
  }
@@ -295,10 +489,11 @@ async function handlePlayground(packageName, input, options) {
295
489
  error,
296
490
  duration: Date.now() - startTime,
297
491
  data: {
298
- packageName,
492
+ packageName: customPromptMode ? 'custom-prompt' : (options.package || 'unknown'),
299
493
  model: options.model || 'sonnet',
300
494
  compare: options.compare || false,
301
495
  interactive: options.interactive || false,
496
+ customPrompt: customPromptMode,
302
497
  },
303
498
  });
304
499
  await telemetry_1.telemetry.shutdown();
@@ -310,30 +505,49 @@ async function handlePlayground(packageName, input, options) {
310
505
  function createPlaygroundCommand() {
311
506
  const command = new commander_1.Command('playground');
312
507
  command
313
- .description('Test a package with AI models in the playground')
314
- .argument('<package>', 'Package name to test')
315
- .argument('[input]', 'Input text to send to the model (omit for interactive mode)')
508
+ .description('Test a package or custom prompt with AI models in the playground')
509
+ .option('-p, --package <name>', 'Package name to test')
510
+ .option('--input <text>', 'Input text to send to the model (omit for interactive mode)')
316
511
  .option('-m, --model <model>', 'AI model to use (sonnet, opus, gpt-4o, gpt-4o-mini, gpt-4-turbo)', 'sonnet')
317
512
  .option('-c, --compare', 'Compare against no prompt (test raw model baseline)', false)
318
513
  .option('-i, --interactive', 'Start interactive multi-turn conversation mode', false)
319
514
  .option('-v, --version <version>', 'Specific package version to test')
515
+ .option('--custom <prompt>', 'Use a custom prompt string (verified authors only)')
516
+ .option('--prompt-file <file>', 'Load custom prompt from a file (verified authors only)')
320
517
  .addHelpText('after', `
321
518
  Examples:
322
- # Single query with default model (Sonnet)
323
- $ prpm playground @anthropic/code-reviewer "Review this code: console.log('hello')"
519
+ # Test a package (single query)
520
+ $ prpm playground --package @anthropic/code-reviewer --input "Review this code: console.log('hello')"
324
521
 
325
522
  # Interactive mode for multi-turn conversation
326
- $ prpm playground @anthropic/brainstorm-assistant --interactive
523
+ $ prpm playground --package @anthropic/brainstorm-assistant --interactive
327
524
 
328
525
  # Compare with and without the package prompt
329
- $ prpm playground @user/custom-prompt "Test input" --compare
526
+ $ prpm playground --package @user/custom-prompt --input "Test input" --compare
330
527
 
331
528
  # Use a different model
332
- $ prpm playground @user/prompt --model opus "Complex task requiring Opus"
333
- $ prpm playground @user/prompt --model gpt-4o "Test with GPT-4o"
529
+ $ prpm playground --package @user/prompt --model opus --input "Complex task requiring Opus"
530
+ $ prpm playground --package @user/prompt --model gpt-4o --input "Test with GPT-4o"
334
531
 
335
532
  # Test specific version
336
- $ prpm playground @user/prompt@1.2.0 "Test input"
533
+ $ prpm playground --package @user/prompt --version 1.2.0 --input "Test input"
534
+
535
+ # Use a custom prompt string (verified authors only)
536
+ $ prpm playground --custom "You are a helpful coding assistant" --input "Explain async/await"
537
+
538
+ # Load custom prompt from a file (verified authors only)
539
+ $ prpm playground --prompt-file ./my-prompt.txt --input "Test input"
540
+
541
+ # Compare custom prompt against baseline (no prompt)
542
+ $ prpm playground --custom "You are concise" --input "Explain recursion" --compare
543
+ $ prpm playground --prompt-file ./my-prompt.txt --input "Test" --compare
544
+
545
+ # Interactive mode with custom prompt from file
546
+ $ prpm playground --prompt-file ./my-prompt.txt --interactive
547
+
548
+ # Short flags for common usage
549
+ $ prpm playground -p @user/prompt --input "Test this"
550
+ $ prpm playground -p @user/prompt -i
337
551
 
338
552
  Available Models:
339
553
  sonnet - Claude 3.5 Sonnet (default, balanced performance)
@@ -342,10 +556,16 @@ Available Models:
342
556
  gpt-4o-mini - GPT-4o Mini (faster, cheaper)
343
557
  gpt-4-turbo - GPT-4 Turbo
344
558
 
559
+ Custom Prompts:
560
+ - Available to verified authors (link your GitHub account)
561
+ - Cost 2x normal credits (no prompt caching)
562
+ - Min 10 characters, max 50,000 characters
563
+ - Perfect for iterating on prompt files locally
564
+
345
565
  Note: Playground usage requires credits. Run 'prpm credits' to check balance.
346
566
  `)
347
- .action(async (packageName, input, options) => {
348
- await handlePlayground(packageName, input, options);
567
+ .action(async (options) => {
568
+ await handlePlayground(options);
349
569
  });
350
570
  return command;
351
571
  }
@@ -21,57 +21,41 @@ async function handleUninstall(name) {
21
21
  if (!pkg) {
22
22
  throw new errors_1.CLIError(`โŒ Package "${name}" not found`, 1);
23
23
  }
24
- // Get destination directory using format and subtype
25
- const format = pkg.format || 'generic';
26
- const subtype = pkg.subtype || 'rule';
24
+ // Get the installation path from lock file if available, otherwise calculate it
27
25
  const packageName = (0, filesystem_1.stripAuthorNamespace)(name);
28
- const destDir = (0, filesystem_1.getDestinationDir)(format, subtype, packageName);
29
- const fileExtension = pkg.format === 'cursor' ? 'mdc' : 'md';
30
- // For Claude skills, delete the entire directory (may contain multiple files)
31
- if (format === 'claude' && subtype === 'skill') {
32
- // Claude skills are in .claude/skills/${packageName}/ directory
33
- // Delete the entire directory (includes SKILL.md, EXAMPLES.md, docs/, etc.)
34
- try {
35
- const stats = await fs_1.promises.stat(destDir);
36
- if (stats.isDirectory()) {
37
- await fs_1.promises.rm(destDir, { recursive: true, force: true });
38
- console.log(` ๐Ÿ—‘๏ธ Deleted directory: ${destDir}`);
39
- }
26
+ let targetPath;
27
+ if (pkg.installedPath) {
28
+ // Use the exact path where it was installed (from lock file)
29
+ targetPath = pkg.installedPath;
30
+ console.log(` ๐Ÿ“ Using installation path from lock file: ${targetPath}`);
31
+ }
32
+ else {
33
+ // Fallback: warn user that installedPath is missing (shouldn't happen with recent installations)
34
+ console.warn(` โš ๏ธ No installation path in lock file for ${name}`);
35
+ console.warn(` โš ๏ธ This may indicate an old or corrupted lock file`);
36
+ throw new errors_1.CLIError(`Cannot uninstall ${name}: installation path unknown`, 1);
37
+ }
38
+ // Check if the target path is a directory or file and delete accordingly
39
+ try {
40
+ const stats = await fs_1.promises.stat(targetPath);
41
+ if (stats.isDirectory()) {
42
+ // Delete entire directory
43
+ await fs_1.promises.rm(targetPath, { recursive: true, force: true });
44
+ console.log(` ๐Ÿ—‘๏ธ Deleted directory: ${targetPath}`);
40
45
  }
41
- catch (error) {
42
- const err = error;
43
- if (err.code === 'ENOENT') {
44
- console.warn(` โš ๏ธ Skill directory not found: ${destDir}`);
45
- }
46
- else {
47
- console.warn(` โš ๏ธ Could not delete skill directory: ${err.message}`);
48
- }
46
+ else if (stats.isFile()) {
47
+ // Delete single file
48
+ await fs_1.promises.unlink(targetPath);
49
+ console.log(` ๐Ÿ—‘๏ธ Deleted file: ${targetPath}`);
49
50
  }
50
51
  }
51
- else {
52
- // For other formats, try single file first
53
- const singleFilePath = `${destDir}/${packageName}.${fileExtension}`;
54
- if (await (0, filesystem_1.fileExists)(singleFilePath)) {
55
- // Single file package
56
- await (0, filesystem_1.deleteFile)(singleFilePath);
57
- console.log(` ๐Ÿ—‘๏ธ Deleted file: ${singleFilePath}`);
52
+ catch (error) {
53
+ const err = error;
54
+ if (err.code === 'ENOENT') {
55
+ console.warn(` โš ๏ธ File/directory not found: ${targetPath}`);
58
56
  }
59
57
  else {
60
- // Try multi-file package directory
61
- const packageDir = `${destDir}/${packageName}`;
62
- try {
63
- const stats = await fs_1.promises.stat(packageDir);
64
- if (stats.isDirectory()) {
65
- await fs_1.promises.rm(packageDir, { recursive: true, force: true });
66
- console.log(` ๐Ÿ—‘๏ธ Deleted directory: ${packageDir}`);
67
- }
68
- }
69
- catch (error) {
70
- const err = error;
71
- if (err.code !== 'ENOENT') {
72
- console.warn(` โš ๏ธ Could not delete package files: ${err.message}`);
73
- }
74
- }
58
+ throw err;
75
59
  }
76
60
  }
77
61
  console.log(`โœ… Successfully uninstalled ${name}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prpm",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Prompt Package Manager CLI - Install and manage prompt-based files",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -45,8 +45,8 @@
45
45
  "license": "MIT",
46
46
  "dependencies": {
47
47
  "@octokit/rest": "^22.0.0",
48
- "@pr-pm/registry-client": "^1.3.9",
49
- "@pr-pm/types": "^0.2.10",
48
+ "@pr-pm/registry-client": "^1.3.11",
49
+ "@pr-pm/types": "^0.2.12",
50
50
  "ajv": "^8.17.1",
51
51
  "ajv-formats": "^3.0.1",
52
52
  "commander": "^11.1.0",