prpm 0.1.12 ā 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/playground.js +249 -30
- package/dist/commands/uninstall.js +29 -45
- package/package.json +3 -3
|
@@ -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
|
|
@@ -94,21 +96,20 @@ async function resolvePackageId(packageName) {
|
|
|
94
96
|
if (uuidRegex.test(packageName)) {
|
|
95
97
|
return packageName;
|
|
96
98
|
}
|
|
97
|
-
//
|
|
99
|
+
// Look up package by name directly
|
|
98
100
|
const config = await (0, user_config_1.getConfig)();
|
|
99
101
|
const baseUrl = (config.registryUrl || "https://registry.prpm.dev").replace(/\/$/, '');
|
|
100
|
-
|
|
102
|
+
// URL encode the package name to handle scoped packages like @user/package
|
|
103
|
+
const encodedName = encodeURIComponent(packageName);
|
|
104
|
+
const response = await fetch(`${baseUrl}/api/v1/packages/${encodedName}`);
|
|
101
105
|
if (!response.ok) {
|
|
102
|
-
|
|
106
|
+
if (response.status === 404) {
|
|
107
|
+
throw new Error(`Package not found: ${packageName}`);
|
|
108
|
+
}
|
|
109
|
+
throw new Error(`Failed to fetch package: ${response.statusText}`);
|
|
103
110
|
}
|
|
104
111
|
const data = await response.json();
|
|
105
|
-
|
|
106
|
-
const exactMatch = data.packages.find(pkg => pkg.name === packageName);
|
|
107
|
-
if (exactMatch) {
|
|
108
|
-
return exactMatch.id;
|
|
109
|
-
}
|
|
110
|
-
// If no exact match, throw error
|
|
111
|
-
throw new Error(`Package not found: ${packageName}`);
|
|
112
|
+
return data.id;
|
|
112
113
|
}
|
|
113
114
|
/**
|
|
114
115
|
* Execute a playground run
|
|
@@ -126,6 +127,28 @@ async function runPlayground(packageName, input, options, sessionId) {
|
|
|
126
127
|
});
|
|
127
128
|
return response.json();
|
|
128
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Execute a custom prompt playground run
|
|
132
|
+
*/
|
|
133
|
+
async function runCustomPrompt(customPrompt, input, options, sessionId) {
|
|
134
|
+
const response = await apiCall('/api/v1/custom-prompt/run', 'POST', {
|
|
135
|
+
custom_prompt: customPrompt,
|
|
136
|
+
input,
|
|
137
|
+
model: options.model || 'sonnet',
|
|
138
|
+
session_id: sessionId,
|
|
139
|
+
});
|
|
140
|
+
return response.json();
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Read custom prompt from file
|
|
144
|
+
*/
|
|
145
|
+
function readPromptFile(filePath) {
|
|
146
|
+
const absolutePath = path.resolve(filePath);
|
|
147
|
+
if (!fs.existsSync(absolutePath)) {
|
|
148
|
+
throw new Error(`Prompt file not found: ${filePath}`);
|
|
149
|
+
}
|
|
150
|
+
return fs.readFileSync(absolutePath, 'utf-8');
|
|
151
|
+
}
|
|
129
152
|
/**
|
|
130
153
|
* Format and display playground response
|
|
131
154
|
*/
|
|
@@ -200,6 +223,139 @@ async function runInteractive(packageName, options) {
|
|
|
200
223
|
rl.close();
|
|
201
224
|
}
|
|
202
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Run interactive custom prompt session
|
|
228
|
+
*/
|
|
229
|
+
async function runCustomInteractive(customPrompt, options) {
|
|
230
|
+
console.log('\nš® Interactive Custom Prompt Mode');
|
|
231
|
+
console.log(` Model: ${options.model || 'sonnet'}`);
|
|
232
|
+
console.log(` Type 'exit' or 'quit' to end session\n`);
|
|
233
|
+
const rl = createReadline();
|
|
234
|
+
let sessionId;
|
|
235
|
+
let turnCount = 0;
|
|
236
|
+
try {
|
|
237
|
+
while (true) {
|
|
238
|
+
const input = await prompt(rl, `\nš¬ You: `);
|
|
239
|
+
if (input.trim().toLowerCase() === 'exit' || input.trim().toLowerCase() === 'quit') {
|
|
240
|
+
console.log('\nš Ending playground session. Goodbye!');
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
if (!input.trim()) {
|
|
244
|
+
console.log('ā Please enter a message');
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
try {
|
|
248
|
+
console.log('\nā³ Processing...');
|
|
249
|
+
const result = await runCustomPrompt(customPrompt, input, options, sessionId);
|
|
250
|
+
// Store session ID for conversation continuity
|
|
251
|
+
sessionId = result.session_id;
|
|
252
|
+
turnCount++;
|
|
253
|
+
displayResponse(result, true);
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
console.error(`\nā Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
257
|
+
if (error instanceof Error && error.message.includes('Insufficient credits')) {
|
|
258
|
+
console.log('\nš” Get more credits:');
|
|
259
|
+
console.log(' - Purchase credits: prpm buy-credits');
|
|
260
|
+
console.log(' - Subscribe to PRPM+: prpm subscribe');
|
|
261
|
+
console.log(' - Check balance: prpm credits');
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (turnCount > 0) {
|
|
267
|
+
console.log(`\nš Session summary: ${turnCount} turn(s)`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
rl.close();
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Run baseline (no prompt) comparison
|
|
276
|
+
*/
|
|
277
|
+
async function runBaseline(input, options) {
|
|
278
|
+
// Use a minimal package but with use_no_prompt flag to get raw model baseline
|
|
279
|
+
// We need any valid package ID because the API requires it, but the prompt will be ignored
|
|
280
|
+
// Let's use a well-known minimal package (we'll search for any package)
|
|
281
|
+
const config = await (0, user_config_1.getConfig)();
|
|
282
|
+
const baseUrl = (config.registryUrl || "https://registry.prpm.dev").replace(/\/$/, '');
|
|
283
|
+
// Get any package to use for baseline comparison (the prompt will be ignored anyway)
|
|
284
|
+
const searchResponse = await fetch(`${baseUrl}/api/v1/search?q=coding&limit=1`);
|
|
285
|
+
if (!searchResponse.ok) {
|
|
286
|
+
throw new Error('Failed to find a package for baseline comparison');
|
|
287
|
+
}
|
|
288
|
+
const searchData = await searchResponse.json();
|
|
289
|
+
if (!searchData.packages || searchData.packages.length === 0) {
|
|
290
|
+
throw new Error('No packages found for baseline comparison');
|
|
291
|
+
}
|
|
292
|
+
const dummyPackageId = searchData.packages[0].id;
|
|
293
|
+
// Call playground with use_no_prompt flag (this ignores the package prompt)
|
|
294
|
+
const response = await apiCall('/api/v1/playground/run', 'POST', {
|
|
295
|
+
package_id: dummyPackageId,
|
|
296
|
+
input,
|
|
297
|
+
model: options.model || 'sonnet',
|
|
298
|
+
use_no_prompt: true, // This makes it a raw baseline with no system prompt
|
|
299
|
+
});
|
|
300
|
+
return response.json();
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Run single custom prompt query
|
|
304
|
+
*/
|
|
305
|
+
async function runCustomSingle(customPrompt, input, options) {
|
|
306
|
+
console.log(`\nš® Testing custom prompt`);
|
|
307
|
+
console.log(` Model: ${options.model || 'sonnet'}`);
|
|
308
|
+
console.log(` Credits: 2x normal cost (custom prompts)`);
|
|
309
|
+
if (options.compare) {
|
|
310
|
+
console.log(` Mode: Comparing custom prompt vs. no prompt (baseline)`);
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
if (options.compare) {
|
|
314
|
+
// Comparison mode: run with custom prompt and without any prompt
|
|
315
|
+
console.log('\nā³ Processing comparison (2 requests)...');
|
|
316
|
+
// Run with custom prompt
|
|
317
|
+
const resultWithPrompt = await runCustomPrompt(customPrompt, input, options);
|
|
318
|
+
// Run baseline (no prompt at all)
|
|
319
|
+
const resultBaseline = await runBaseline(input, options);
|
|
320
|
+
// Display both results
|
|
321
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
322
|
+
console.log('⨠WITH CUSTOM PROMPT');
|
|
323
|
+
console.log('ā'.repeat(60));
|
|
324
|
+
displayResponse(resultWithPrompt, false);
|
|
325
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
326
|
+
console.log('šµ WITHOUT PROMPT (BASELINE)');
|
|
327
|
+
console.log('ā'.repeat(60));
|
|
328
|
+
displayResponse(resultBaseline, false);
|
|
329
|
+
// Combined stats
|
|
330
|
+
console.log(`\nš Combined Stats:`);
|
|
331
|
+
console.log(` Total tokens: ${resultWithPrompt.tokens_used + resultBaseline.tokens_used}`);
|
|
332
|
+
console.log(` Total credits: ${resultWithPrompt.credits_spent + resultBaseline.credits_spent}`);
|
|
333
|
+
console.log(` Credits remaining: ${resultBaseline.credits_remaining}`);
|
|
334
|
+
console.log(`\nš” Compare the responses to evaluate your custom prompt's effectiveness!`);
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
// Single mode: run with custom prompt only
|
|
338
|
+
console.log('\nā³ Processing...');
|
|
339
|
+
const result = await runCustomPrompt(customPrompt, input, options);
|
|
340
|
+
displayResponse(result, true);
|
|
341
|
+
console.log(`\nš” Tips:`);
|
|
342
|
+
console.log(` - Use --interactive for multi-turn conversation`);
|
|
343
|
+
console.log(` - Use --compare to test against baseline (no prompt)`);
|
|
344
|
+
console.log(` - Use --prompt-file to iterate on a prompt file`);
|
|
345
|
+
console.log(` - Custom prompts cost 2x credits (no caching)`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
console.error(`\nā Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
350
|
+
if (error instanceof Error && error.message.includes('Insufficient credits')) {
|
|
351
|
+
console.log('\nš” Get more credits:');
|
|
352
|
+
console.log(' - Purchase credits: prpm buy-credits');
|
|
353
|
+
console.log(' - Subscribe to PRPM+: prpm subscribe');
|
|
354
|
+
console.log(' - Check balance: prpm credits');
|
|
355
|
+
}
|
|
356
|
+
throw new errors_1.CLIError(`\nā Error: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
203
359
|
/**
|
|
204
360
|
* Run single playground query
|
|
205
361
|
*/
|
|
@@ -259,10 +415,11 @@ async function runSingle(packageName, input, options) {
|
|
|
259
415
|
/**
|
|
260
416
|
* Handle the playground command
|
|
261
417
|
*/
|
|
262
|
-
async function handlePlayground(
|
|
418
|
+
async function handlePlayground(options) {
|
|
263
419
|
const startTime = Date.now();
|
|
264
420
|
let success = false;
|
|
265
421
|
let error;
|
|
422
|
+
let customPromptMode = false;
|
|
266
423
|
try {
|
|
267
424
|
// Validate authentication
|
|
268
425
|
const config = await (0, user_config_1.getConfig)();
|
|
@@ -272,14 +429,50 @@ async function handlePlayground(packageName, input, options) {
|
|
|
272
429
|
console.log(' prpm login');
|
|
273
430
|
throw new errors_1.CLIError('ā Authentication required', 1);
|
|
274
431
|
}
|
|
275
|
-
//
|
|
276
|
-
if (options.
|
|
277
|
-
|
|
278
|
-
|
|
432
|
+
// Check for custom prompt mode
|
|
433
|
+
if (options.custom || options.promptFile) {
|
|
434
|
+
customPromptMode = true;
|
|
435
|
+
// Get custom prompt from option or file
|
|
436
|
+
let customPrompt;
|
|
437
|
+
if (options.promptFile) {
|
|
438
|
+
console.log(`š Loading prompt from: ${options.promptFile}`);
|
|
439
|
+
customPrompt = readPromptFile(options.promptFile);
|
|
440
|
+
console.log(`ā
Loaded ${customPrompt.length} characters\n`);
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
customPrompt = options.custom;
|
|
444
|
+
}
|
|
445
|
+
// Validate custom prompt length
|
|
446
|
+
if (customPrompt.length < 10) {
|
|
447
|
+
throw new Error('Custom prompt too short (minimum 10 characters)');
|
|
448
|
+
}
|
|
449
|
+
if (customPrompt.length > 50000) {
|
|
450
|
+
throw new Error('Custom prompt too long (maximum 50000 characters)');
|
|
451
|
+
}
|
|
452
|
+
// Interactive mode or single query
|
|
453
|
+
if (options.interactive || !options.input) {
|
|
454
|
+
// Interactive mode with custom prompt
|
|
455
|
+
await runCustomInteractive(customPrompt, options);
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
// Single query mode with custom prompt
|
|
459
|
+
await runCustomSingle(customPrompt, options.input, options);
|
|
460
|
+
}
|
|
279
461
|
}
|
|
280
462
|
else {
|
|
281
|
-
//
|
|
282
|
-
|
|
463
|
+
// Regular package-based playground
|
|
464
|
+
if (!options.package) {
|
|
465
|
+
throw new Error('Either --package or --custom/--prompt-file is required');
|
|
466
|
+
}
|
|
467
|
+
// Interactive mode or single query
|
|
468
|
+
if (options.interactive || !options.input) {
|
|
469
|
+
// Interactive mode
|
|
470
|
+
await runInteractive(options.package, options);
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
// Single query mode
|
|
474
|
+
await runSingle(options.package, options.input, options);
|
|
475
|
+
}
|
|
283
476
|
}
|
|
284
477
|
success = true;
|
|
285
478
|
}
|
|
@@ -295,10 +488,11 @@ async function handlePlayground(packageName, input, options) {
|
|
|
295
488
|
error,
|
|
296
489
|
duration: Date.now() - startTime,
|
|
297
490
|
data: {
|
|
298
|
-
packageName,
|
|
491
|
+
packageName: customPromptMode ? 'custom-prompt' : (options.package || 'unknown'),
|
|
299
492
|
model: options.model || 'sonnet',
|
|
300
493
|
compare: options.compare || false,
|
|
301
494
|
interactive: options.interactive || false,
|
|
495
|
+
customPrompt: customPromptMode,
|
|
302
496
|
},
|
|
303
497
|
});
|
|
304
498
|
await telemetry_1.telemetry.shutdown();
|
|
@@ -310,30 +504,49 @@ async function handlePlayground(packageName, input, options) {
|
|
|
310
504
|
function createPlaygroundCommand() {
|
|
311
505
|
const command = new commander_1.Command('playground');
|
|
312
506
|
command
|
|
313
|
-
.description('Test a package with AI models in the playground')
|
|
314
|
-
.
|
|
315
|
-
.
|
|
507
|
+
.description('Test a package or custom prompt with AI models in the playground')
|
|
508
|
+
.option('-p, --package <name>', 'Package name to test')
|
|
509
|
+
.option('--input <text>', 'Input text to send to the model (omit for interactive mode)')
|
|
316
510
|
.option('-m, --model <model>', 'AI model to use (sonnet, opus, gpt-4o, gpt-4o-mini, gpt-4-turbo)', 'sonnet')
|
|
317
511
|
.option('-c, --compare', 'Compare against no prompt (test raw model baseline)', false)
|
|
318
512
|
.option('-i, --interactive', 'Start interactive multi-turn conversation mode', false)
|
|
319
513
|
.option('-v, --version <version>', 'Specific package version to test')
|
|
514
|
+
.option('--custom <prompt>', 'Use a custom prompt string (verified authors only)')
|
|
515
|
+
.option('--prompt-file <file>', 'Load custom prompt from a file (verified authors only)')
|
|
320
516
|
.addHelpText('after', `
|
|
321
517
|
Examples:
|
|
322
|
-
#
|
|
323
|
-
$ prpm playground @anthropic/code-reviewer "Review this code: console.log('hello')"
|
|
518
|
+
# Test a package (single query)
|
|
519
|
+
$ prpm playground --package @anthropic/code-reviewer --input "Review this code: console.log('hello')"
|
|
324
520
|
|
|
325
521
|
# Interactive mode for multi-turn conversation
|
|
326
|
-
$ prpm playground @anthropic/brainstorm-assistant --interactive
|
|
522
|
+
$ prpm playground --package @anthropic/brainstorm-assistant --interactive
|
|
327
523
|
|
|
328
524
|
# Compare with and without the package prompt
|
|
329
|
-
$ prpm playground @user/custom-prompt "Test input" --compare
|
|
525
|
+
$ prpm playground --package @user/custom-prompt --input "Test input" --compare
|
|
330
526
|
|
|
331
527
|
# 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"
|
|
528
|
+
$ prpm playground --package @user/prompt --model opus --input "Complex task requiring Opus"
|
|
529
|
+
$ prpm playground --package @user/prompt --model gpt-4o --input "Test with GPT-4o"
|
|
334
530
|
|
|
335
531
|
# Test specific version
|
|
336
|
-
$ prpm playground @user/prompt
|
|
532
|
+
$ prpm playground --package @user/prompt --version 1.2.0 --input "Test input"
|
|
533
|
+
|
|
534
|
+
# Use a custom prompt string (verified authors only)
|
|
535
|
+
$ prpm playground --custom "You are a helpful coding assistant" --input "Explain async/await"
|
|
536
|
+
|
|
537
|
+
# Load custom prompt from a file (verified authors only)
|
|
538
|
+
$ prpm playground --prompt-file ./my-prompt.txt --input "Test input"
|
|
539
|
+
|
|
540
|
+
# Compare custom prompt against baseline (no prompt)
|
|
541
|
+
$ prpm playground --custom "You are concise" --input "Explain recursion" --compare
|
|
542
|
+
$ prpm playground --prompt-file ./my-prompt.txt --input "Test" --compare
|
|
543
|
+
|
|
544
|
+
# Interactive mode with custom prompt from file
|
|
545
|
+
$ prpm playground --prompt-file ./my-prompt.txt --interactive
|
|
546
|
+
|
|
547
|
+
# Short flags for common usage
|
|
548
|
+
$ prpm playground -p @user/prompt --input "Test this"
|
|
549
|
+
$ prpm playground -p @user/prompt -i
|
|
337
550
|
|
|
338
551
|
Available Models:
|
|
339
552
|
sonnet - Claude 3.5 Sonnet (default, balanced performance)
|
|
@@ -342,10 +555,16 @@ Available Models:
|
|
|
342
555
|
gpt-4o-mini - GPT-4o Mini (faster, cheaper)
|
|
343
556
|
gpt-4-turbo - GPT-4 Turbo
|
|
344
557
|
|
|
558
|
+
Custom Prompts:
|
|
559
|
+
- Available to verified authors (link your GitHub account)
|
|
560
|
+
- Cost 2x normal credits (no prompt caching)
|
|
561
|
+
- Min 10 characters, max 50,000 characters
|
|
562
|
+
- Perfect for iterating on prompt files locally
|
|
563
|
+
|
|
345
564
|
Note: Playground usage requires credits. Run 'prpm credits' to check balance.
|
|
346
565
|
`)
|
|
347
|
-
.action(async (
|
|
348
|
-
await handlePlayground(
|
|
566
|
+
.action(async (options) => {
|
|
567
|
+
await handlePlayground(options);
|
|
349
568
|
});
|
|
350
569
|
return command;
|
|
351
570
|
}
|
|
@@ -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
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "0.1.14",
|
|
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.
|
|
49
|
-
"@pr-pm/types": "^0.2.
|
|
48
|
+
"@pr-pm/registry-client": "^1.3.12",
|
|
49
|
+
"@pr-pm/types": "^0.2.13",
|
|
50
50
|
"ajv": "^8.17.1",
|
|
51
51
|
"ajv-formats": "^3.0.1",
|
|
52
52
|
"commander": "^11.1.0",
|