prpm 0.1.17 → 1.0.0

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 (46) hide show
  1. package/dist/index.js +14257 -107
  2. package/package.json +11 -9
  3. package/dist/__tests__/e2e/test-helpers.js +0 -151
  4. package/dist/commands/buy-credits.js +0 -224
  5. package/dist/commands/catalog.js +0 -365
  6. package/dist/commands/collections.js +0 -655
  7. package/dist/commands/config.js +0 -161
  8. package/dist/commands/credits.js +0 -186
  9. package/dist/commands/index.js +0 -184
  10. package/dist/commands/info.js +0 -78
  11. package/dist/commands/init.js +0 -684
  12. package/dist/commands/install.js +0 -789
  13. package/dist/commands/list.js +0 -189
  14. package/dist/commands/login.js +0 -316
  15. package/dist/commands/outdated.js +0 -130
  16. package/dist/commands/playground.js +0 -570
  17. package/dist/commands/popular.js +0 -33
  18. package/dist/commands/publish.js +0 -803
  19. package/dist/commands/schema.js +0 -41
  20. package/dist/commands/search.js +0 -446
  21. package/dist/commands/subscribe.js +0 -211
  22. package/dist/commands/telemetry.js +0 -104
  23. package/dist/commands/trending.js +0 -86
  24. package/dist/commands/uninstall.js +0 -120
  25. package/dist/commands/update.js +0 -121
  26. package/dist/commands/upgrade.js +0 -121
  27. package/dist/commands/whoami.js +0 -83
  28. package/dist/core/claude-config.js +0 -91
  29. package/dist/core/cursor-config.js +0 -130
  30. package/dist/core/downloader.js +0 -64
  31. package/dist/core/errors.js +0 -29
  32. package/dist/core/filesystem.js +0 -242
  33. package/dist/core/lockfile.js +0 -292
  34. package/dist/core/marketplace-converter.js +0 -224
  35. package/dist/core/registry-client.js +0 -305
  36. package/dist/core/schema-validator.js +0 -74
  37. package/dist/core/telemetry.js +0 -253
  38. package/dist/core/user-config.js +0 -147
  39. package/dist/types/registry.js +0 -12
  40. package/dist/types.js +0 -36
  41. package/dist/utils/license-extractor.js +0 -122
  42. package/dist/utils/multi-package.js +0 -117
  43. package/dist/utils/parallel-publisher.js +0 -144
  44. package/dist/utils/script-executor.js +0 -72
  45. package/dist/utils/snippet-extractor.js +0 -77
  46. package/dist/utils/webapp-url.js +0 -44
@@ -1,570 +0,0 @@
1
- "use strict";
2
- /**
3
- * Playground command - Test packages with AI models
4
- */
5
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- var desc = Object.getOwnPropertyDescriptor(m, k);
8
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
- desc = { enumerable: true, get: function() { return m[k]; } };
10
- }
11
- Object.defineProperty(o, k2, desc);
12
- }) : (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- o[k2] = m[k];
15
- }));
16
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
- Object.defineProperty(o, "default", { enumerable: true, value: v });
18
- }) : function(o, v) {
19
- o["default"] = v;
20
- });
21
- var __importStar = (this && this.__importStar) || (function () {
22
- var ownKeys = function(o) {
23
- ownKeys = Object.getOwnPropertyNames || function (o) {
24
- var ar = [];
25
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
- return ar;
27
- };
28
- return ownKeys(o);
29
- };
30
- return function (mod) {
31
- if (mod && mod.__esModule) return mod;
32
- var result = {};
33
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
- __setModuleDefault(result, mod);
35
- return result;
36
- };
37
- })();
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.handlePlayground = handlePlayground;
40
- exports.createPlaygroundCommand = createPlaygroundCommand;
41
- const commander_1 = require("commander");
42
- const user_config_1 = require("../core/user-config");
43
- const telemetry_1 = require("../core/telemetry");
44
- const readline = __importStar(require("readline"));
45
- const fs = __importStar(require("fs"));
46
- const path = __importStar(require("path"));
47
- const errors_1 = require("../core/errors");
48
- /**
49
- * Create a readline interface for user input
50
- */
51
- function createReadline() {
52
- return readline.createInterface({
53
- input: process.stdin,
54
- output: process.stdout,
55
- });
56
- }
57
- /**
58
- * Prompt user for input
59
- */
60
- function prompt(rl, question) {
61
- return new Promise((resolve) => {
62
- rl.question(question, (answer) => {
63
- resolve(answer);
64
- });
65
- });
66
- }
67
- /**
68
- * Make authenticated API call to registry
69
- */
70
- async function apiCall(endpoint, method = 'GET', body) {
71
- const config = await (0, user_config_1.getConfig)();
72
- const baseUrl = (config.registryUrl || "https://registry.prpm.dev").replace(/\/$/, '');
73
- if (!config.token) {
74
- throw new Error('Authentication required. Please run `prpm login` first.');
75
- }
76
- const response = await fetch(`${baseUrl}${endpoint}`, {
77
- method,
78
- headers: {
79
- 'Content-Type': 'application/json',
80
- Authorization: `Bearer ${config.token}`,
81
- },
82
- body: body ? JSON.stringify(body) : undefined,
83
- });
84
- if (!response.ok) {
85
- const errorData = await response.json().catch(() => ({}));
86
- throw new Error(errorData.message || `API request failed: ${response.statusText}`);
87
- }
88
- return response;
89
- }
90
- /**
91
- * Resolve package name to UUID
92
- */
93
- async function resolvePackageId(packageName) {
94
- // If it's already a UUID, return it
95
- const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
96
- if (uuidRegex.test(packageName)) {
97
- return packageName;
98
- }
99
- // Look up package by name directly
100
- const config = await (0, user_config_1.getConfig)();
101
- const baseUrl = (config.registryUrl || "https://registry.prpm.dev").replace(/\/$/, '');
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}`);
105
- if (!response.ok) {
106
- if (response.status === 404) {
107
- throw new Error(`Package not found: ${packageName}`);
108
- }
109
- throw new Error(`Failed to fetch package: ${response.statusText}`);
110
- }
111
- const data = await response.json();
112
- return data.id;
113
- }
114
- /**
115
- * Execute a playground run
116
- */
117
- async function runPlayground(packageName, input, options, sessionId) {
118
- // Resolve package name to UUID
119
- const packageId = await resolvePackageId(packageName);
120
- const response = await apiCall('/api/v1/playground/run', 'POST', {
121
- package_id: packageId,
122
- package_version: options.version,
123
- input,
124
- model: options.model || 'sonnet',
125
- use_no_prompt: options.compare || false,
126
- session_id: sessionId,
127
- });
128
- return response.json();
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
- }
152
- /**
153
- * Format and display playground response
154
- */
155
- function displayResponse(result, showStats = true) {
156
- // Get the latest assistant response
157
- const lastMessage = result.conversation[result.conversation.length - 1];
158
- if (lastMessage?.role === 'assistant') {
159
- console.log('\n' + '─'.repeat(60));
160
- console.log('🤖 Assistant:');
161
- console.log('─'.repeat(60));
162
- console.log(lastMessage.content);
163
- console.log('─'.repeat(60));
164
- }
165
- if (showStats) {
166
- console.log(`\n📊 Stats:`);
167
- console.log(` Model: ${result.model}`);
168
- console.log(` Tokens: ${result.tokens_used.toLocaleString()}`);
169
- console.log(` Credits spent: ${result.credits_spent}`);
170
- console.log(` Credits remaining: ${result.credits_remaining}`);
171
- console.log(` Duration: ${result.duration_ms}ms`);
172
- }
173
- }
174
- /**
175
- * Run interactive playground session
176
- */
177
- async function runInteractive(packageName, options) {
178
- console.log('\n🎮 Interactive Playground Mode');
179
- console.log(` Package: ${packageName}`);
180
- console.log(` Model: ${options.model || 'sonnet'}`);
181
- if (options.compare) {
182
- console.log(` Mode: Comparing against no prompt (raw model baseline)`);
183
- }
184
- console.log(` Type 'exit' or 'quit' to end session\n`);
185
- const rl = createReadline();
186
- let sessionId;
187
- let turnCount = 0;
188
- try {
189
- while (true) {
190
- const input = await prompt(rl, `\n💬 You: `);
191
- if (input.trim().toLowerCase() === 'exit' || input.trim().toLowerCase() === 'quit') {
192
- console.log('\n👋 Ending playground session. Goodbye!');
193
- break;
194
- }
195
- if (!input.trim()) {
196
- console.log('❌ Please enter a message');
197
- continue;
198
- }
199
- try {
200
- console.log('\n⏳ Processing...');
201
- const result = await runPlayground(packageName, input, options, sessionId);
202
- // Store session ID for conversation continuity
203
- sessionId = result.session_id;
204
- turnCount++;
205
- displayResponse(result, true);
206
- }
207
- catch (error) {
208
- console.error(`\n❌ Error: ${error instanceof Error ? error.message : String(error)}`);
209
- if (error instanceof Error && error.message.includes('Insufficient credits')) {
210
- console.log('\n💡 Get more credits:');
211
- console.log(' - Purchase credits: prpm buy-credits');
212
- console.log(' - Subscribe to PRPM+: prpm subscribe');
213
- console.log(' - Check balance: prpm credits');
214
- break;
215
- }
216
- }
217
- }
218
- if (turnCount > 0) {
219
- console.log(`\n📝 Session summary: ${turnCount} turn(s)`);
220
- }
221
- }
222
- finally {
223
- rl.close();
224
- }
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
- }
359
- /**
360
- * Run single playground query
361
- */
362
- async function runSingle(packageName, input, options) {
363
- console.log(`\n🎮 Testing package: ${packageName}`);
364
- console.log(` Model: ${options.model || 'sonnet'}`);
365
- if (options.compare) {
366
- console.log(` Mode: Comparing with package vs. without (baseline)`);
367
- }
368
- try {
369
- if (options.compare) {
370
- // Comparison mode: run both with package and without
371
- console.log('\n⏳ Processing comparison (2 requests)...');
372
- // Run with package (without use_no_prompt flag)
373
- const withPackageOptions = { ...options, compare: false };
374
- const resultWithPackage = await runPlayground(packageName, input, withPackageOptions);
375
- // Run without package (with use_no_prompt flag)
376
- const withoutPackageOptions = { ...options, compare: true };
377
- const resultWithoutPackage = await runPlayground(packageName, input, withoutPackageOptions);
378
- // Display both results
379
- console.log('\n' + '═'.repeat(60));
380
- console.log('📦 WITH PACKAGE PROMPT');
381
- console.log('═'.repeat(60));
382
- displayResponse(resultWithPackage, false);
383
- console.log('\n' + '═'.repeat(60));
384
- console.log('🔵 WITHOUT PACKAGE (BASELINE)');
385
- console.log('═'.repeat(60));
386
- displayResponse(resultWithoutPackage, false);
387
- // Combined stats
388
- console.log(`\n📊 Combined Stats:`);
389
- console.log(` Total tokens: ${resultWithPackage.tokens_used + resultWithoutPackage.tokens_used}`);
390
- console.log(` Total credits: ${resultWithPackage.credits_spent + resultWithoutPackage.credits_spent}`);
391
- console.log(` Credits remaining: ${resultWithoutPackage.credits_remaining}`);
392
- }
393
- else {
394
- // Single mode: run with package only
395
- console.log('\n⏳ Processing...');
396
- const result = await runPlayground(packageName, input, options);
397
- displayResponse(result, true);
398
- }
399
- console.log(`\n💡 Tips:`);
400
- console.log(` - Use --interactive for multi-turn conversation`);
401
- console.log(` - Use --compare to test with and without the package prompt`);
402
- console.log(` - Use --model to choose different models (sonnet, opus, gpt-4o, etc.)`);
403
- }
404
- catch (error) {
405
- console.error(`\n❌ Error: ${error instanceof Error ? error.message : String(error)}`);
406
- if (error instanceof Error && error.message.includes('Insufficient credits')) {
407
- console.log('\n💡 Get more credits:');
408
- console.log(' - Purchase credits: prpm buy-credits');
409
- console.log(' - Subscribe to PRPM+: prpm subscribe');
410
- console.log(' - Check balance: prpm credits');
411
- }
412
- throw new errors_1.CLIError(`\n❌ Error: ${error instanceof Error ? error.message : String(error)}`, 1);
413
- }
414
- }
415
- /**
416
- * Handle the playground command
417
- */
418
- async function handlePlayground(options) {
419
- const startTime = Date.now();
420
- let success = false;
421
- let error;
422
- let customPromptMode = false;
423
- try {
424
- // Validate authentication
425
- const config = await (0, user_config_1.getConfig)();
426
- if (!config.token) {
427
- console.error('❌ Authentication required');
428
- console.log('\n💡 Please login first:');
429
- console.log(' prpm login');
430
- throw new errors_1.CLIError('❌ Authentication required', 1);
431
- }
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
- }
461
- }
462
- else {
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
- }
476
- }
477
- success = true;
478
- }
479
- catch (err) {
480
- error = err instanceof Error ? err.message : String(err);
481
- console.error(`\n❌ Playground execution failed: ${error}`);
482
- throw new errors_1.CLIError(`\n❌ Playground execution failed: ${error}`, 1);
483
- }
484
- finally {
485
- await telemetry_1.telemetry.track({
486
- command: 'playground',
487
- success,
488
- error,
489
- duration: Date.now() - startTime,
490
- data: {
491
- packageName: customPromptMode ? 'custom-prompt' : (options.package || 'unknown'),
492
- model: options.model || 'sonnet',
493
- compare: options.compare || false,
494
- interactive: options.interactive || false,
495
- customPrompt: customPromptMode,
496
- },
497
- });
498
- await telemetry_1.telemetry.shutdown();
499
- }
500
- }
501
- /**
502
- * Create the playground command
503
- */
504
- function createPlaygroundCommand() {
505
- const command = new commander_1.Command('playground');
506
- command
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)')
510
- .option('-m, --model <model>', 'AI model to use (sonnet, opus, gpt-4o, gpt-4o-mini, gpt-4-turbo)', 'sonnet')
511
- .option('-c, --compare', 'Compare against no prompt (test raw model baseline)', false)
512
- .option('-i, --interactive', 'Start interactive multi-turn conversation mode', false)
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)')
516
- .addHelpText('after', `
517
- Examples:
518
- # Test a package (single query)
519
- $ prpm playground --package @anthropic/code-reviewer --input "Review this code: console.log('hello')"
520
-
521
- # Interactive mode for multi-turn conversation
522
- $ prpm playground --package @anthropic/brainstorm-assistant --interactive
523
-
524
- # Compare with and without the package prompt
525
- $ prpm playground --package @user/custom-prompt --input "Test input" --compare
526
-
527
- # Use a different model
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"
530
-
531
- # Test specific version
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
550
-
551
- Available Models:
552
- sonnet - Claude 3.5 Sonnet (default, balanced performance)
553
- opus - Claude 3 Opus (most capable, higher cost)
554
- gpt-4o - GPT-4o (OpenAI's latest)
555
- gpt-4o-mini - GPT-4o Mini (faster, cheaper)
556
- gpt-4-turbo - GPT-4 Turbo
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
-
564
- Note: Playground usage requires credits. Run 'prpm credits' to check balance.
565
- `)
566
- .action(async (options) => {
567
- await handlePlayground(options);
568
- });
569
- return command;
570
- }
@@ -1,33 +0,0 @@
1
- "use strict";
2
- /**
3
- * Popular packages command implementation
4
- * Shows all-time popular packages (delegates to trending)
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.handlePopular = handlePopular;
8
- exports.createPopularCommand = createPopularCommand;
9
- const commander_1 = require("commander");
10
- const trending_1 = require("./trending");
11
- /**
12
- * Show popular packages (wrapper around trending)
13
- */
14
- async function handlePopular(options) {
15
- // Delegate to trending command
16
- console.log('📊 Popular Packages (All Time)\n');
17
- await (0, trending_1.handleTrending)({
18
- format: options.format,
19
- subtype: options.subtype
20
- });
21
- }
22
- /**
23
- * Create the popular command
24
- */
25
- function createPopularCommand() {
26
- return new commander_1.Command('popular')
27
- .description('Show popular packages (all time)')
28
- .option('--format <format>', 'Filter by format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, generic)')
29
- .option('--subtype <subtype>', 'Filter by subtype (rule, agent, skill, slash-command, prompt, workflow, tool, template, collection)')
30
- .action(async (options) => {
31
- await handlePopular(options);
32
- });
33
- }