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.
- package/dist/index.js +14257 -107
- package/package.json +11 -9
- package/dist/__tests__/e2e/test-helpers.js +0 -151
- package/dist/commands/buy-credits.js +0 -224
- package/dist/commands/catalog.js +0 -365
- package/dist/commands/collections.js +0 -655
- package/dist/commands/config.js +0 -161
- package/dist/commands/credits.js +0 -186
- package/dist/commands/index.js +0 -184
- package/dist/commands/info.js +0 -78
- package/dist/commands/init.js +0 -684
- package/dist/commands/install.js +0 -789
- package/dist/commands/list.js +0 -189
- package/dist/commands/login.js +0 -316
- package/dist/commands/outdated.js +0 -130
- package/dist/commands/playground.js +0 -570
- package/dist/commands/popular.js +0 -33
- package/dist/commands/publish.js +0 -803
- package/dist/commands/schema.js +0 -41
- package/dist/commands/search.js +0 -446
- package/dist/commands/subscribe.js +0 -211
- package/dist/commands/telemetry.js +0 -104
- package/dist/commands/trending.js +0 -86
- package/dist/commands/uninstall.js +0 -120
- package/dist/commands/update.js +0 -121
- package/dist/commands/upgrade.js +0 -121
- package/dist/commands/whoami.js +0 -83
- package/dist/core/claude-config.js +0 -91
- package/dist/core/cursor-config.js +0 -130
- package/dist/core/downloader.js +0 -64
- package/dist/core/errors.js +0 -29
- package/dist/core/filesystem.js +0 -242
- package/dist/core/lockfile.js +0 -292
- package/dist/core/marketplace-converter.js +0 -224
- package/dist/core/registry-client.js +0 -305
- package/dist/core/schema-validator.js +0 -74
- package/dist/core/telemetry.js +0 -253
- package/dist/core/user-config.js +0 -147
- package/dist/types/registry.js +0 -12
- package/dist/types.js +0 -36
- package/dist/utils/license-extractor.js +0 -122
- package/dist/utils/multi-package.js +0 -117
- package/dist/utils/parallel-publisher.js +0 -144
- package/dist/utils/script-executor.js +0 -72
- package/dist/utils/snippet-extractor.js +0 -77
- 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
|
-
}
|
package/dist/commands/popular.js
DELETED
|
@@ -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
|
-
}
|