prpm 0.1.4 ā 0.1.6
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/buy-credits.js +223 -0
- package/dist/commands/credits.js +186 -0
- package/dist/commands/hooks.js +280 -0
- package/dist/commands/playground.js +351 -0
- package/dist/commands/publish.js +1 -0
- package/dist/commands/remove.js +76 -0
- package/dist/commands/search.js +15 -1
- package/dist/commands/subscribe.js +209 -0
- package/dist/index.js +9 -0
- package/package.json +3 -3
|
@@ -0,0 +1,351 @@
|
|
|
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
|
+
/**
|
|
46
|
+
* Create a readline interface for user input
|
|
47
|
+
*/
|
|
48
|
+
function createReadline() {
|
|
49
|
+
return readline.createInterface({
|
|
50
|
+
input: process.stdin,
|
|
51
|
+
output: process.stdout,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Prompt user for input
|
|
56
|
+
*/
|
|
57
|
+
function prompt(rl, question) {
|
|
58
|
+
return new Promise((resolve) => {
|
|
59
|
+
rl.question(question, (answer) => {
|
|
60
|
+
resolve(answer);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Make authenticated API call to registry
|
|
66
|
+
*/
|
|
67
|
+
async function apiCall(endpoint, method = 'GET', body) {
|
|
68
|
+
const config = await (0, user_config_1.getConfig)();
|
|
69
|
+
const baseUrl = (config.registryUrl || "https://registry.prpm.dev").replace(/\/$/, '');
|
|
70
|
+
if (!config.token) {
|
|
71
|
+
throw new Error('Authentication required. Please run `prpm login` first.');
|
|
72
|
+
}
|
|
73
|
+
const response = await fetch(`${baseUrl}${endpoint}`, {
|
|
74
|
+
method,
|
|
75
|
+
headers: {
|
|
76
|
+
'Content-Type': 'application/json',
|
|
77
|
+
Authorization: `Bearer ${config.token}`,
|
|
78
|
+
},
|
|
79
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
80
|
+
});
|
|
81
|
+
if (!response.ok) {
|
|
82
|
+
const errorData = await response.json().catch(() => ({}));
|
|
83
|
+
throw new Error(errorData.message || `API request failed: ${response.statusText}`);
|
|
84
|
+
}
|
|
85
|
+
return response;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Resolve package name to UUID
|
|
89
|
+
*/
|
|
90
|
+
async function resolvePackageId(packageName) {
|
|
91
|
+
// If it's already a UUID, return it
|
|
92
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
93
|
+
if (uuidRegex.test(packageName)) {
|
|
94
|
+
return packageName;
|
|
95
|
+
}
|
|
96
|
+
// Search for the package by name
|
|
97
|
+
const config = await (0, user_config_1.getConfig)();
|
|
98
|
+
const baseUrl = (config.registryUrl || "https://registry.prpm.dev").replace(/\/$/, '');
|
|
99
|
+
const response = await fetch(`${baseUrl}/api/v1/search?q=${encodeURIComponent(packageName)}&limit=10`);
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
throw new Error(`Failed to search for package: ${response.statusText}`);
|
|
102
|
+
}
|
|
103
|
+
const data = await response.json();
|
|
104
|
+
// Find exact match
|
|
105
|
+
const exactMatch = data.packages.find(pkg => pkg.name === packageName);
|
|
106
|
+
if (exactMatch) {
|
|
107
|
+
return exactMatch.id;
|
|
108
|
+
}
|
|
109
|
+
// If no exact match, throw error
|
|
110
|
+
throw new Error(`Package not found: ${packageName}`);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Execute a playground run
|
|
114
|
+
*/
|
|
115
|
+
async function runPlayground(packageName, input, options, sessionId) {
|
|
116
|
+
// Resolve package name to UUID
|
|
117
|
+
const packageId = await resolvePackageId(packageName);
|
|
118
|
+
const response = await apiCall('/api/v1/playground/run', 'POST', {
|
|
119
|
+
package_id: packageId,
|
|
120
|
+
package_version: options.version,
|
|
121
|
+
input,
|
|
122
|
+
model: options.model || 'sonnet',
|
|
123
|
+
use_no_prompt: options.compare || false,
|
|
124
|
+
session_id: sessionId,
|
|
125
|
+
});
|
|
126
|
+
return response.json();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Format and display playground response
|
|
130
|
+
*/
|
|
131
|
+
function displayResponse(result, showStats = true) {
|
|
132
|
+
// Get the latest assistant response
|
|
133
|
+
const lastMessage = result.conversation[result.conversation.length - 1];
|
|
134
|
+
if (lastMessage?.role === 'assistant') {
|
|
135
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
136
|
+
console.log('š¤ Assistant:');
|
|
137
|
+
console.log('ā'.repeat(60));
|
|
138
|
+
console.log(lastMessage.content);
|
|
139
|
+
console.log('ā'.repeat(60));
|
|
140
|
+
}
|
|
141
|
+
if (showStats) {
|
|
142
|
+
console.log(`\nš Stats:`);
|
|
143
|
+
console.log(` Model: ${result.model}`);
|
|
144
|
+
console.log(` Tokens: ${result.tokens_used.toLocaleString()}`);
|
|
145
|
+
console.log(` Credits spent: ${result.credits_spent}`);
|
|
146
|
+
console.log(` Credits remaining: ${result.credits_remaining}`);
|
|
147
|
+
console.log(` Duration: ${result.duration_ms}ms`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Run interactive playground session
|
|
152
|
+
*/
|
|
153
|
+
async function runInteractive(packageName, options) {
|
|
154
|
+
console.log('\nš® Interactive Playground Mode');
|
|
155
|
+
console.log(` Package: ${packageName}`);
|
|
156
|
+
console.log(` Model: ${options.model || 'sonnet'}`);
|
|
157
|
+
if (options.compare) {
|
|
158
|
+
console.log(` Mode: Comparing against no prompt (raw model baseline)`);
|
|
159
|
+
}
|
|
160
|
+
console.log(` Type 'exit' or 'quit' to end session\n`);
|
|
161
|
+
const rl = createReadline();
|
|
162
|
+
let sessionId;
|
|
163
|
+
let turnCount = 0;
|
|
164
|
+
try {
|
|
165
|
+
while (true) {
|
|
166
|
+
const input = await prompt(rl, `\nš¬ You: `);
|
|
167
|
+
if (input.trim().toLowerCase() === 'exit' || input.trim().toLowerCase() === 'quit') {
|
|
168
|
+
console.log('\nš Ending playground session. Goodbye!');
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
if (!input.trim()) {
|
|
172
|
+
console.log('ā Please enter a message');
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
console.log('\nā³ Processing...');
|
|
177
|
+
const result = await runPlayground(packageName, input, options, sessionId);
|
|
178
|
+
// Store session ID for conversation continuity
|
|
179
|
+
sessionId = result.session_id;
|
|
180
|
+
turnCount++;
|
|
181
|
+
displayResponse(result, true);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
console.error(`\nā Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
185
|
+
if (error instanceof Error && error.message.includes('Insufficient credits')) {
|
|
186
|
+
console.log('\nš” Get more credits:');
|
|
187
|
+
console.log(' - Purchase credits: prpm buy-credits');
|
|
188
|
+
console.log(' - Subscribe to PRPM+: prpm subscribe');
|
|
189
|
+
console.log(' - Check balance: prpm credits');
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (turnCount > 0) {
|
|
195
|
+
console.log(`\nš Session summary: ${turnCount} turn(s)`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
rl.close();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Run single playground query
|
|
204
|
+
*/
|
|
205
|
+
async function runSingle(packageName, input, options) {
|
|
206
|
+
console.log(`\nš® Testing package: ${packageName}`);
|
|
207
|
+
console.log(` Model: ${options.model || 'sonnet'}`);
|
|
208
|
+
if (options.compare) {
|
|
209
|
+
console.log(` Mode: Comparing with package vs. without (baseline)`);
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
if (options.compare) {
|
|
213
|
+
// Comparison mode: run both with package and without
|
|
214
|
+
console.log('\nā³ Processing comparison (2 requests)...');
|
|
215
|
+
// Run with package (without use_no_prompt flag)
|
|
216
|
+
const withPackageOptions = { ...options, compare: false };
|
|
217
|
+
const resultWithPackage = await runPlayground(packageName, input, withPackageOptions);
|
|
218
|
+
// Run without package (with use_no_prompt flag)
|
|
219
|
+
const withoutPackageOptions = { ...options, compare: true };
|
|
220
|
+
const resultWithoutPackage = await runPlayground(packageName, input, withoutPackageOptions);
|
|
221
|
+
// Display both results
|
|
222
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
223
|
+
console.log('š¦ WITH PACKAGE PROMPT');
|
|
224
|
+
console.log('ā'.repeat(60));
|
|
225
|
+
displayResponse(resultWithPackage, false);
|
|
226
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
227
|
+
console.log('šµ WITHOUT PACKAGE (BASELINE)');
|
|
228
|
+
console.log('ā'.repeat(60));
|
|
229
|
+
displayResponse(resultWithoutPackage, false);
|
|
230
|
+
// Combined stats
|
|
231
|
+
console.log(`\nš Combined Stats:`);
|
|
232
|
+
console.log(` Total tokens: ${resultWithPackage.tokens_used + resultWithoutPackage.tokens_used}`);
|
|
233
|
+
console.log(` Total credits: ${resultWithPackage.credits_spent + resultWithoutPackage.credits_spent}`);
|
|
234
|
+
console.log(` Credits remaining: ${resultWithoutPackage.credits_remaining}`);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
// Single mode: run with package only
|
|
238
|
+
console.log('\nā³ Processing...');
|
|
239
|
+
const result = await runPlayground(packageName, input, options);
|
|
240
|
+
displayResponse(result, true);
|
|
241
|
+
}
|
|
242
|
+
console.log(`\nš” Tips:`);
|
|
243
|
+
console.log(` - Use --interactive for multi-turn conversation`);
|
|
244
|
+
console.log(` - Use --compare to test with and without the package prompt`);
|
|
245
|
+
console.log(` - Use --model to choose different models (sonnet, opus, gpt-4o, etc.)`);
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
console.error(`\nā Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
249
|
+
if (error instanceof Error && error.message.includes('Insufficient credits')) {
|
|
250
|
+
console.log('\nš” Get more credits:');
|
|
251
|
+
console.log(' - Purchase credits: prpm buy-credits');
|
|
252
|
+
console.log(' - Subscribe to PRPM+: prpm subscribe');
|
|
253
|
+
console.log(' - Check balance: prpm credits');
|
|
254
|
+
}
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Handle the playground command
|
|
260
|
+
*/
|
|
261
|
+
async function handlePlayground(packageName, input, options) {
|
|
262
|
+
const startTime = Date.now();
|
|
263
|
+
let success = false;
|
|
264
|
+
let error;
|
|
265
|
+
try {
|
|
266
|
+
// Validate authentication
|
|
267
|
+
const config = await (0, user_config_1.getConfig)();
|
|
268
|
+
if (!config.token) {
|
|
269
|
+
console.error('ā Authentication required');
|
|
270
|
+
console.log('\nš” Please login first:');
|
|
271
|
+
console.log(' prpm login');
|
|
272
|
+
process.exit(1);
|
|
273
|
+
}
|
|
274
|
+
// Interactive mode or single query
|
|
275
|
+
if (options.interactive || !input) {
|
|
276
|
+
// Interactive mode
|
|
277
|
+
await runInteractive(packageName, options);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// Single query mode
|
|
281
|
+
await runSingle(packageName, input, options);
|
|
282
|
+
}
|
|
283
|
+
success = true;
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
error = err instanceof Error ? err.message : String(err);
|
|
287
|
+
console.error(`\nā Playground execution failed: ${error}`);
|
|
288
|
+
process.exit(1);
|
|
289
|
+
}
|
|
290
|
+
finally {
|
|
291
|
+
await telemetry_1.telemetry.track({
|
|
292
|
+
command: 'playground',
|
|
293
|
+
success,
|
|
294
|
+
error,
|
|
295
|
+
duration: Date.now() - startTime,
|
|
296
|
+
data: {
|
|
297
|
+
packageName,
|
|
298
|
+
model: options.model || 'sonnet',
|
|
299
|
+
compare: options.compare || false,
|
|
300
|
+
interactive: options.interactive || false,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
await telemetry_1.telemetry.shutdown();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Create the playground command
|
|
308
|
+
*/
|
|
309
|
+
function createPlaygroundCommand() {
|
|
310
|
+
const command = new commander_1.Command('playground');
|
|
311
|
+
command
|
|
312
|
+
.description('Test a package with AI models in the playground')
|
|
313
|
+
.argument('<package>', 'Package name to test')
|
|
314
|
+
.argument('[input]', 'Input text to send to the model (omit for interactive mode)')
|
|
315
|
+
.option('-m, --model <model>', 'AI model to use (sonnet, opus, gpt-4o, gpt-4o-mini, gpt-4-turbo)', 'sonnet')
|
|
316
|
+
.option('-c, --compare', 'Compare against no prompt (test raw model baseline)', false)
|
|
317
|
+
.option('-i, --interactive', 'Start interactive multi-turn conversation mode', false)
|
|
318
|
+
.option('-v, --version <version>', 'Specific package version to test')
|
|
319
|
+
.addHelpText('after', `
|
|
320
|
+
Examples:
|
|
321
|
+
# Single query with default model (Sonnet)
|
|
322
|
+
$ prpm playground @anthropic/code-reviewer "Review this code: console.log('hello')"
|
|
323
|
+
|
|
324
|
+
# Interactive mode for multi-turn conversation
|
|
325
|
+
$ prpm playground @anthropic/brainstorm-assistant --interactive
|
|
326
|
+
|
|
327
|
+
# Compare with and without the package prompt
|
|
328
|
+
$ prpm playground @user/custom-prompt "Test input" --compare
|
|
329
|
+
|
|
330
|
+
# Use a different model
|
|
331
|
+
$ prpm playground @user/prompt --model opus "Complex task requiring Opus"
|
|
332
|
+
$ prpm playground @user/prompt --model gpt-4o "Test with GPT-4o"
|
|
333
|
+
|
|
334
|
+
# Test specific version
|
|
335
|
+
$ prpm playground @user/prompt@1.2.0 "Test input"
|
|
336
|
+
|
|
337
|
+
Available Models:
|
|
338
|
+
sonnet - Claude 3.5 Sonnet (default, balanced performance)
|
|
339
|
+
opus - Claude 3 Opus (most capable, higher cost)
|
|
340
|
+
gpt-4o - GPT-4o (OpenAI's latest)
|
|
341
|
+
gpt-4o-mini - GPT-4o Mini (faster, cheaper)
|
|
342
|
+
gpt-4-turbo - GPT-4 Turbo
|
|
343
|
+
|
|
344
|
+
Note: Playground usage requires credits. Run 'prpm credits' to check balance.
|
|
345
|
+
`)
|
|
346
|
+
.action(async (packageName, input, options) => {
|
|
347
|
+
await handlePlayground(packageName, input, options);
|
|
348
|
+
process.exit(0);
|
|
349
|
+
});
|
|
350
|
+
return command;
|
|
351
|
+
}
|
package/dist/commands/publish.js
CHANGED
|
@@ -90,6 +90,7 @@ async function findAndLoadManifests() {
|
|
|
90
90
|
homepage: pkg.homepage ?? multiManifest.homepage,
|
|
91
91
|
documentation: pkg.documentation ?? multiManifest.documentation,
|
|
92
92
|
organization: pkg.organization ?? multiManifest.organization,
|
|
93
|
+
private: pkg.private ?? multiManifest.private,
|
|
93
94
|
tags: pkg.tags ?? multiManifest.tags,
|
|
94
95
|
keywords: pkg.keywords ?? multiManifest.keywords,
|
|
95
96
|
subtype: pkg.subtype,
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Remove command implementation
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.handleRemove = handleRemove;
|
|
7
|
+
exports.createRemoveCommand = createRemoveCommand;
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const lockfile_1 = require("../core/lockfile");
|
|
10
|
+
const filesystem_1 = require("../core/filesystem");
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
/**
|
|
13
|
+
* Handle the remove command
|
|
14
|
+
*/
|
|
15
|
+
async function handleRemove(name) {
|
|
16
|
+
try {
|
|
17
|
+
console.log(`šļø Removing package: ${name}`);
|
|
18
|
+
// Remove from lockfile and get package info
|
|
19
|
+
const pkg = await (0, lockfile_1.removePackage)(name);
|
|
20
|
+
if (!pkg) {
|
|
21
|
+
console.error(`ā Package "${name}" not found`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
// Determine file path based on package type and format
|
|
25
|
+
const effectiveType = (pkg.format === 'claude' ? 'claude-skill' :
|
|
26
|
+
pkg.format === 'cursor' ? 'cursor' :
|
|
27
|
+
pkg.format === 'continue' ? 'continue' :
|
|
28
|
+
pkg.format === 'windsurf' ? 'windsurf' :
|
|
29
|
+
pkg.type);
|
|
30
|
+
const destDir = (0, filesystem_1.getDestinationDir)(effectiveType);
|
|
31
|
+
const fileExtension = pkg.format === 'cursor' ? 'mdc' : 'md';
|
|
32
|
+
// Strip author namespace to get just the package name
|
|
33
|
+
const packageName = (0, filesystem_1.stripAuthorNamespace)(name);
|
|
34
|
+
// Try single file first
|
|
35
|
+
const singleFilePath = `${destDir}/${packageName}.${fileExtension}`;
|
|
36
|
+
if (await (0, filesystem_1.fileExists)(singleFilePath)) {
|
|
37
|
+
// Single file package
|
|
38
|
+
await (0, filesystem_1.deleteFile)(singleFilePath);
|
|
39
|
+
console.log(` šļø Deleted file: ${singleFilePath}`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Try multi-file package directory
|
|
43
|
+
const packageDir = `${destDir}/${packageName}`;
|
|
44
|
+
try {
|
|
45
|
+
const stats = await fs_1.promises.stat(packageDir);
|
|
46
|
+
if (stats.isDirectory()) {
|
|
47
|
+
await fs_1.promises.rm(packageDir, { recursive: true, force: true });
|
|
48
|
+
console.log(` šļø Deleted directory: ${packageDir}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
const err = error;
|
|
53
|
+
if (err.code !== 'ENOENT') {
|
|
54
|
+
console.warn(` ā ļø Could not delete package files: ${err.message}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
console.log(`ā
Successfully removed ${name}`);
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.error(`ā Failed to remove package: ${error}`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Create the remove command
|
|
68
|
+
*/
|
|
69
|
+
function createRemoveCommand() {
|
|
70
|
+
const command = new commander_1.Command('remove');
|
|
71
|
+
command
|
|
72
|
+
.description('Remove a prompt package')
|
|
73
|
+
.argument('<id>', 'Package ID to remove')
|
|
74
|
+
.action(handleRemove);
|
|
75
|
+
return command;
|
|
76
|
+
}
|
package/dist/commands/search.js
CHANGED
|
@@ -134,6 +134,10 @@ function buildWebappUrl(query, options, page = 1) {
|
|
|
134
134
|
params.append('subtype', options.subtype);
|
|
135
135
|
if (options.author)
|
|
136
136
|
params.append('author', options.author);
|
|
137
|
+
if (options.language)
|
|
138
|
+
params.append('language', options.language);
|
|
139
|
+
if (options.framework)
|
|
140
|
+
params.append('framework', options.framework);
|
|
137
141
|
if (page > 1)
|
|
138
142
|
params.append('page', page.toString());
|
|
139
143
|
return `${baseUrl}/search?${params.toString()}`;
|
|
@@ -312,6 +316,12 @@ async function handleSearch(query, options) {
|
|
|
312
316
|
if (options.author) {
|
|
313
317
|
searchOptions.author = options.author;
|
|
314
318
|
}
|
|
319
|
+
if (options.language) {
|
|
320
|
+
searchOptions.language = options.language;
|
|
321
|
+
}
|
|
322
|
+
if (options.framework) {
|
|
323
|
+
searchOptions.framework = options.framework;
|
|
324
|
+
}
|
|
315
325
|
result = await client.search(query || '', searchOptions);
|
|
316
326
|
if (!result || result.packages.length === 0) {
|
|
317
327
|
console.log('\nā No packages found');
|
|
@@ -377,6 +387,8 @@ async function handleSearch(query, options) {
|
|
|
377
387
|
query: query.substring(0, 100),
|
|
378
388
|
format: options.format,
|
|
379
389
|
subtype: options.subtype,
|
|
390
|
+
language: options.language,
|
|
391
|
+
framework: options.framework,
|
|
380
392
|
resultCount: success && result ? result.packages.length : 0,
|
|
381
393
|
page: options.page,
|
|
382
394
|
interactive: options.interactive,
|
|
@@ -394,6 +406,8 @@ function createSearchCommand() {
|
|
|
394
406
|
.option('--format <format>', 'Filter by package format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, generic, mcp)')
|
|
395
407
|
.option('--subtype <subtype>', 'Filter by package subtype (rule, agent, skill, slash-command, prompt, workflow, tool, template, collection)')
|
|
396
408
|
.option('--author <username>', 'Filter by author username')
|
|
409
|
+
.option('--language <language>', 'Filter by programming language (javascript, typescript, python, etc.)')
|
|
410
|
+
.option('--framework <framework>', 'Filter by framework (react, nextjs, django, etc.)')
|
|
397
411
|
.option('--limit <number>', 'Number of results per page', '20')
|
|
398
412
|
.option('--page <number>', 'Page number (default: 1)', '1')
|
|
399
413
|
.option('--interactive', 'Enable interactive pagination (default: true for multiple pages)', true)
|
|
@@ -423,7 +437,7 @@ function createSearchCommand() {
|
|
|
423
437
|
console.log(` prpm search --author prpm # List packages by @prpm`);
|
|
424
438
|
process.exit(1);
|
|
425
439
|
}
|
|
426
|
-
await handleSearch(query || '', { format, subtype, author, limit, page, interactive: options.interactive });
|
|
440
|
+
await handleSearch(query || '', { format, subtype, author, language: options.language, framework: options.framework, limit, page, interactive: options.interactive });
|
|
427
441
|
process.exit(0);
|
|
428
442
|
});
|
|
429
443
|
return command;
|