prpm 1.2.1 → 2.0.1

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 (67) hide show
  1. package/README.md +90 -862
  2. package/dist/index.js +23233 -65
  3. package/dist/schemas/agents-md.schema.json +24 -0
  4. package/dist/schemas/aider.schema.json +24 -0
  5. package/dist/schemas/canonical.schema.json +435 -0
  6. package/dist/schemas/claude-agent.schema.json +62 -0
  7. package/dist/schemas/claude-hook.schema.json +70 -0
  8. package/dist/schemas/claude-plugin.schema.json +122 -0
  9. package/dist/schemas/claude-skill.schema.json +51 -0
  10. package/dist/schemas/claude-slash-command.schema.json +77 -0
  11. package/dist/schemas/claude.schema.json +52 -0
  12. package/dist/schemas/continue.schema.json +98 -0
  13. package/dist/schemas/copilot.schema.json +76 -0
  14. package/dist/schemas/cursor-command.schema.json +27 -0
  15. package/dist/schemas/cursor-hooks.schema.json +59 -0
  16. package/dist/schemas/cursor.schema.json +74 -0
  17. package/dist/schemas/droid-hook.schema.json +103 -0
  18. package/dist/schemas/droid-skill.schema.json +46 -0
  19. package/dist/schemas/droid-slash-command.schema.json +53 -0
  20. package/dist/schemas/droid.schema.json +46 -0
  21. package/dist/schemas/format-registry.schema.json +99 -0
  22. package/dist/schemas/gemini-md.schema.json +24 -0
  23. package/dist/schemas/gemini.schema.json +30 -0
  24. package/dist/schemas/kiro-agent.schema.json +146 -0
  25. package/dist/schemas/kiro-hook.schema.json +120 -0
  26. package/dist/schemas/kiro-steering.schema.json +74 -0
  27. package/dist/schemas/mcp-server.schema.json +130 -0
  28. package/dist/schemas/opencode-slash-command.schema.json +60 -0
  29. package/dist/schemas/opencode.schema.json +111 -0
  30. package/dist/schemas/prpm-manifest.schema.json +733 -0
  31. package/dist/schemas/replit.schema.json +21 -0
  32. package/dist/schemas/ruler.schema.json +22 -0
  33. package/dist/schemas/trae.schema.json +24 -0
  34. package/dist/schemas/windsurf.schema.json +22 -0
  35. package/dist/schemas/zencoder.schema.json +51 -0
  36. package/package.json +20 -14
  37. package/schemas/prpm-manifest.schema.json +465 -39
  38. package/dist/__tests__/e2e/test-helpers.js +0 -150
  39. package/dist/commands/collections.js +0 -606
  40. package/dist/commands/index.js +0 -186
  41. package/dist/commands/info.js +0 -82
  42. package/dist/commands/install.js +0 -477
  43. package/dist/commands/list.js +0 -166
  44. package/dist/commands/login.js +0 -281
  45. package/dist/commands/outdated.js +0 -128
  46. package/dist/commands/popular.js +0 -27
  47. package/dist/commands/publish.js +0 -274
  48. package/dist/commands/schema.js +0 -37
  49. package/dist/commands/search.js +0 -404
  50. package/dist/commands/telemetry.js +0 -103
  51. package/dist/commands/trending.js +0 -76
  52. package/dist/commands/uninstall.js +0 -77
  53. package/dist/commands/update.js +0 -121
  54. package/dist/commands/upgrade.js +0 -121
  55. package/dist/commands/whoami.js +0 -75
  56. package/dist/core/claude-config.js +0 -91
  57. package/dist/core/cursor-config.js +0 -130
  58. package/dist/core/downloader.js +0 -64
  59. package/dist/core/filesystem.js +0 -124
  60. package/dist/core/lockfile.js +0 -239
  61. package/dist/core/marketplace-converter.js +0 -198
  62. package/dist/core/registry-client.js +0 -265
  63. package/dist/core/schema-validator.js +0 -74
  64. package/dist/core/telemetry.js +0 -175
  65. package/dist/core/user-config.js +0 -79
  66. package/dist/types/registry.js +0 -5
  67. package/dist/types.js +0 -5
@@ -1,404 +0,0 @@
1
- "use strict";
2
- /**
3
- * Search command - Search for packages in the registry
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.handleSearch = handleSearch;
40
- exports.createSearchCommand = createSearchCommand;
41
- const commander_1 = require("commander");
42
- const registry_client_1 = require("@pr-pm/registry-client");
43
- const user_config_1 = require("../core/user-config");
44
- const telemetry_1 = require("../core/telemetry");
45
- const readline = __importStar(require("readline"));
46
- /**
47
- * Get icon for package type
48
- */
49
- function getTypeIcon(type) {
50
- const icons = {
51
- skill: 'šŸŽ“',
52
- agent: 'šŸ¤–',
53
- command: '⚔',
54
- 'slash-command': '⚔',
55
- 'claude-slash-command': '⚔',
56
- rule: 'šŸ“‹',
57
- plugin: 'šŸ”Œ',
58
- prompt: 'šŸ’¬',
59
- workflow: '⚔',
60
- tool: 'šŸ”§',
61
- template: 'šŸ“„',
62
- mcp: 'šŸ”—',
63
- };
64
- return icons[type] || 'šŸ“¦';
65
- }
66
- /**
67
- * Get human-readable label for package type
68
- */
69
- function getTypeLabel(type) {
70
- const labels = {
71
- skill: 'Skill',
72
- agent: 'Agent',
73
- command: 'Slash Command',
74
- 'slash-command': 'Slash Command',
75
- 'claude-slash-command': 'Slash Command',
76
- 'claude-agent': 'Agent',
77
- rule: 'Rule',
78
- plugin: 'Plugin',
79
- prompt: 'Prompt',
80
- workflow: 'Workflow',
81
- tool: 'Tool',
82
- template: 'Template',
83
- mcp: 'MCP Server',
84
- };
85
- return labels[type] || type;
86
- }
87
- /**
88
- * Map user-friendly CLI types to registry schema
89
- */
90
- function mapTypeToRegistry(cliType) {
91
- const typeMap = {
92
- rule: { type: 'cursor', tags: ['cursor-rule'] },
93
- // Skills are packages with type=claude-skill
94
- skill: { type: 'claude-skill' },
95
- // Agents are packages with type=claude-agent or claude (not claude-skill)
96
- agent: { type: 'claude-agent' },
97
- // Slash commands are packages with type=claude-slash-command
98
- command: { type: 'claude-slash-command' },
99
- 'slash-command': { type: 'claude-slash-command' },
100
- mcp: { type: 'mcp' },
101
- plugin: { type: 'generic', tags: ['plugin'] },
102
- prompt: { type: 'generic', tags: ['prompt'] },
103
- workflow: { type: 'generic', tags: ['workflow'] },
104
- tool: { type: 'generic', tags: ['tool'] },
105
- template: { type: 'generic', tags: ['template'] },
106
- };
107
- return typeMap[cliType] || {};
108
- }
109
- /**
110
- * Build webapp URL for search results
111
- */
112
- function buildWebappUrl(query, options, page = 1) {
113
- const baseUrl = process.env.PRPM_WEBAPP_URL || 'https://prpm.dev';
114
- const params = new URLSearchParams();
115
- if (query)
116
- params.append('q', query);
117
- if (options.type)
118
- params.append('type', options.type);
119
- if (options.author)
120
- params.append('author', options.author);
121
- if (page > 1)
122
- params.append('page', page.toString());
123
- return `${baseUrl}/search?${params.toString()}`;
124
- }
125
- /**
126
- * Display search results
127
- */
128
- function displayResults(packages, total, page, limit) {
129
- const startIdx = (page - 1) * limit + 1;
130
- const endIdx = Math.min(page * limit, total);
131
- console.log('\n' + '─'.repeat(80));
132
- console.log(`šŸ“¦ Results ${startIdx}-${endIdx} of ${total}`.padEnd(80));
133
- console.log('─'.repeat(80) + '\n');
134
- packages.forEach((pkg, idx) => {
135
- const num = startIdx + idx;
136
- const rating = pkg.rating_average ? `⭐ ${pkg.rating_average.toFixed(1)}` : '';
137
- const downloads = pkg.total_downloads >= 1000
138
- ? `${(pkg.total_downloads / 1000).toFixed(1)}k`
139
- : pkg.total_downloads;
140
- const typeIcon = getTypeIcon(pkg.type);
141
- const typeLabel = getTypeLabel(pkg.type);
142
- // Add verified badge
143
- let verifiedBadge = '';
144
- if (pkg.featured || pkg.official || pkg.verified) {
145
- verifiedBadge = ' | āœ… Verified';
146
- }
147
- console.log(`\x1b[1m${num}. ${pkg.name}\x1b[0m ${rating}`);
148
- console.log(` ${pkg.description || 'No description'}`);
149
- console.log(` ${typeIcon} ${typeLabel} | šŸ“„ ${downloads} downloads | šŸ·ļø ${pkg.tags.slice(0, 3).join(', ')}${verifiedBadge}`);
150
- console.log();
151
- });
152
- console.log('─'.repeat(80));
153
- }
154
- /**
155
- * Prompt user for pagination action
156
- */
157
- function promptUser() {
158
- return new Promise((resolve) => {
159
- const rl = readline.createInterface({
160
- input: process.stdin,
161
- output: process.stdout,
162
- });
163
- rl.question('', (answer) => {
164
- rl.close();
165
- resolve(answer.trim().toLowerCase());
166
- });
167
- });
168
- }
169
- /**
170
- * Interactive pagination handler
171
- */
172
- async function handlePagination(query, options, client, searchOptions, initialResult, webappBaseUrl) {
173
- let currentPage = 1;
174
- let result = initialResult;
175
- const totalPages = Math.ceil(result.total / options.limit);
176
- while (true) {
177
- // Display current page
178
- displayResults(result.packages, result.total, currentPage, options.limit);
179
- // Show navigation options
180
- console.log('\nšŸ’” \x1b[1mOptions:\x1b[0m');
181
- if (currentPage < totalPages) {
182
- console.log(' \x1b[36mn\x1b[0m - Next page');
183
- }
184
- if (currentPage > 1) {
185
- console.log(' \x1b[36mp\x1b[0m - Previous page');
186
- }
187
- console.log(' \x1b[36m1-' + result.packages.length + '\x1b[0m - Install package by number');
188
- console.log(' \x1b[36mw\x1b[0m - View in web browser');
189
- console.log(' \x1b[36mq\x1b[0m - Quit');
190
- // Show webapp link
191
- const webappUrl = buildWebappUrl(query, options, currentPage);
192
- console.log(`\n🌐 \x1b[2mView in browser: ${webappUrl}\x1b[0m`);
193
- process.stdout.write('\nšŸ‘‰ ');
194
- const input = await promptUser();
195
- if (input === 'q' || input === 'quit' || input === 'exit') {
196
- console.log('\n✨ Happy coding!\n');
197
- break;
198
- }
199
- if (input === 'n' || input === 'next') {
200
- if (currentPage < totalPages) {
201
- currentPage++;
202
- const offset = (currentPage - 1) * options.limit;
203
- result = await client.search(query || '', { ...searchOptions, offset });
204
- console.clear();
205
- }
206
- else {
207
- console.log('\nāŒ Already on last page');
208
- await new Promise(resolve => setTimeout(resolve, 1000));
209
- console.clear();
210
- }
211
- continue;
212
- }
213
- if (input === 'p' || input === 'prev' || input === 'previous') {
214
- if (currentPage > 1) {
215
- currentPage--;
216
- const offset = (currentPage - 1) * options.limit;
217
- result = await client.search(query || '', { ...searchOptions, offset });
218
- console.clear();
219
- }
220
- else {
221
- console.log('\nāŒ Already on first page');
222
- await new Promise(resolve => setTimeout(resolve, 1000));
223
- console.clear();
224
- }
225
- continue;
226
- }
227
- if (input === 'w' || input === 'web' || input === 'browser') {
228
- const url = buildWebappUrl(query, options, currentPage);
229
- console.log(`\n🌐 Opening: ${url}`);
230
- console.log(' (Copy and paste this URL into your browser)\n');
231
- await new Promise(resolve => setTimeout(resolve, 2000));
232
- console.clear();
233
- continue;
234
- }
235
- // Check if input is a number for installation
236
- const num = parseInt(input, 10);
237
- if (!isNaN(num) && num >= 1 && num <= result.packages.length) {
238
- const pkg = result.packages[num - 1];
239
- console.log(`\nšŸ“¦ To install: \x1b[36mprpm install ${pkg.name}\x1b[0m`);
240
- console.log(` More info: \x1b[36mprpm info ${pkg.name}\x1b[0m\n`);
241
- await new Promise(resolve => setTimeout(resolve, 2000));
242
- console.clear();
243
- continue;
244
- }
245
- console.log('\nāŒ Invalid option. Try again.');
246
- await new Promise(resolve => setTimeout(resolve, 1000));
247
- console.clear();
248
- }
249
- }
250
- async function handleSearch(query, options) {
251
- const startTime = Date.now();
252
- let success = false;
253
- let error;
254
- let result = null;
255
- let registryUrl = '';
256
- try {
257
- // Allow empty query when filtering by type or author
258
- if (query) {
259
- console.log(`šŸ” Searching for "${query}"...`);
260
- }
261
- else if (options.type) {
262
- console.log(`šŸ” Listing ${options.type} packages...`);
263
- }
264
- else if (options.author) {
265
- console.log(`šŸ” Listing packages by @${options.author}...`);
266
- }
267
- else {
268
- console.log('āŒ Please provide a search query or use --type/--author to filter');
269
- console.log('\nšŸ’” Examples:');
270
- console.log(' prpm search react');
271
- console.log(' prpm search --type skill');
272
- console.log(' prpm search --author prpm');
273
- console.log(' prpm search react --type rule');
274
- return;
275
- }
276
- const config = await (0, user_config_1.getConfig)();
277
- registryUrl = config.registryUrl || 'https://registry.prpm.dev';
278
- const client = (0, registry_client_1.getRegistryClient)(config);
279
- // Map CLI type to registry schema
280
- const limit = options.limit || 20;
281
- const page = options.page || 1;
282
- const offset = (page - 1) * limit;
283
- const searchOptions = {
284
- limit,
285
- offset,
286
- };
287
- if (options.type) {
288
- const mapped = mapTypeToRegistry(options.type);
289
- if (mapped.type) {
290
- searchOptions.type = mapped.type;
291
- }
292
- if (mapped.tags) {
293
- searchOptions.tags = mapped.tags;
294
- }
295
- }
296
- if (options.author) {
297
- searchOptions.author = options.author;
298
- }
299
- result = await client.search(query || '', searchOptions);
300
- if (!result || result.packages.length === 0) {
301
- console.log('\nāŒ No packages found');
302
- console.log(`\nTry:`);
303
- console.log(` - Broadening your search terms`);
304
- console.log(` - Checking spelling`);
305
- console.log(` - Browsing trending: prpm trending`);
306
- // Suggest webapp even if no results
307
- const webappUrl = buildWebappUrl(query, options);
308
- console.log(`\n🌐 View in browser: ${webappUrl}`);
309
- return;
310
- }
311
- // If interactive mode is disabled or only one page, show simple results
312
- const totalPages = Math.ceil(result.total / limit);
313
- const shouldPaginate = options.interactive !== false && totalPages > 1;
314
- if (!shouldPaginate) {
315
- displayResults(result.packages, result.total, page, limit);
316
- console.log('\nšŸ’” \x1b[1mQuick Actions:\x1b[0m');
317
- console.log(' Install: \x1b[36mprpm install <package-id>\x1b[0m');
318
- console.log(' More info: \x1b[36mprpm info <package-id>\x1b[0m');
319
- if (totalPages > 1) {
320
- console.log(`\nšŸ“„ \x1b[1mMore Results:\x1b[0m`);
321
- console.log(` Page ${page} of ${totalPages}`);
322
- if (page < totalPages) {
323
- console.log(` Next page: \x1b[36mprpm search "${query}" --page ${page + 1}\x1b[0m`);
324
- }
325
- console.log(` Interactive mode: \x1b[36mprpm search "${query}" --interactive\x1b[0m`);
326
- }
327
- // Always show webapp link
328
- const webappUrl = buildWebappUrl(query, options, page);
329
- console.log(`\n🌐 \x1b[1mView in Browser:\x1b[0m`);
330
- console.log(` ${webappUrl}`);
331
- if (page < totalPages) {
332
- const nextPageUrl = buildWebappUrl(query, options, page + 1);
333
- console.log(` Next page: ${nextPageUrl}`);
334
- }
335
- console.log();
336
- }
337
- else {
338
- // Interactive pagination mode
339
- await handlePagination(query, { ...options, limit }, client, searchOptions, result, registryUrl);
340
- }
341
- success = true;
342
- }
343
- catch (err) {
344
- error = err instanceof Error ? err.message : String(err);
345
- console.error(`\nāŒ Search failed: ${error}`);
346
- console.log(` Registry: ${registryUrl}`);
347
- // Provide helpful hint if using localhost
348
- if (registryUrl.includes('localhost')) {
349
- console.log(`\nšŸ’” Tip: You're using a local registry. Make sure it's running or update ~/.prpmrc`);
350
- console.log(` To use the production registry, remove the registryUrl from ~/.prpmrc`);
351
- }
352
- process.exit(1);
353
- }
354
- finally {
355
- await telemetry_1.telemetry.track({
356
- command: 'search',
357
- success,
358
- error,
359
- duration: Date.now() - startTime,
360
- data: {
361
- query: query.substring(0, 100),
362
- type: options.type,
363
- resultCount: success && result ? result.packages.length : 0,
364
- page: options.page,
365
- interactive: options.interactive,
366
- },
367
- });
368
- // Ensure telemetry is flushed before exit
369
- await telemetry_1.telemetry.shutdown();
370
- }
371
- }
372
- function createSearchCommand() {
373
- const command = new commander_1.Command('search');
374
- command
375
- .description('Search for packages in the registry')
376
- .argument('[query]', 'Search query (optional when using --type or --author)')
377
- .option('--type <type>', 'Filter by package type (skill, agent, command, slash-command, rule, plugin, prompt, workflow, tool, template, mcp)')
378
- .option('--author <username>', 'Filter by author username')
379
- .option('--limit <number>', 'Number of results per page', '20')
380
- .option('--page <number>', 'Page number (default: 1)', '1')
381
- .option('--interactive', 'Enable interactive pagination (default: true for multiple pages)', true)
382
- .option('--no-interactive', 'Disable interactive pagination')
383
- .action(async (query, options) => {
384
- const type = options.type;
385
- const author = options.author;
386
- const limit = options.limit ? parseInt(options.limit, 10) : 20;
387
- const page = options.page ? parseInt(options.page, 10) : 1;
388
- const validTypes = ['skill', 'agent', 'command', 'slash-command', 'rule', 'plugin', 'prompt', 'workflow', 'tool', 'template', 'mcp'];
389
- if (options.type && !validTypes.includes(type)) {
390
- console.error(`āŒ Type must be one of: ${validTypes.join(', ')}`);
391
- console.log(`\nšŸ’” Examples:`);
392
- console.log(` prpm search postgres --type skill`);
393
- console.log(` prpm search debugging --type agent`);
394
- console.log(` prpm search refactor --type command`);
395
- console.log(` prpm search react --type rule`);
396
- console.log(` prpm search --type command # List all slash commands`);
397
- console.log(` prpm search --type skill # List all skills`);
398
- console.log(` prpm search --author prpm # List packages by @pr-pm`);
399
- process.exit(1);
400
- }
401
- await handleSearch(query || '', { type, author, limit, page, interactive: options.interactive });
402
- });
403
- return command;
404
- }
@@ -1,103 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createTelemetryCommand = createTelemetryCommand;
4
- const commander_1 = require("commander");
5
- const telemetry_1 = require("../core/telemetry");
6
- function createTelemetryCommand() {
7
- return new commander_1.Command('telemetry')
8
- .description('Manage telemetry and analytics settings')
9
- .addCommand(createStatusCommand(), { hidden: true })
10
- .addCommand(createEnableCommand())
11
- .addCommand(createDisableCommand())
12
- .addCommand(createStatsCommand(), { hidden: true })
13
- .addCommand(createTestCommand(), { hidden: true });
14
- }
15
- function createStatusCommand() {
16
- return new commander_1.Command('status')
17
- .description('Show current telemetry status')
18
- .action(async () => {
19
- const enabled = telemetry_1.telemetry.isEnabled();
20
- const stats = await telemetry_1.telemetry.getStats();
21
- console.log('šŸ“Š Telemetry Status:');
22
- console.log(` Status: ${enabled ? 'āœ… Enabled' : 'āŒ Disabled'}`);
23
- console.log(` Analytics: šŸ“ˆ PostHog`);
24
- console.log(` Total events: ${stats.totalEvents}`);
25
- if (stats.lastEvent) {
26
- console.log(` Last event: ${stats.lastEvent}`);
27
- }
28
- if (enabled) {
29
- console.log('\nšŸ’” Telemetry helps us improve the tool by collecting anonymous usage data.');
30
- console.log(' Data is sent to PostHog for analysis.');
31
- console.log(' Run "prpm telemetry disable" to opt out.');
32
- }
33
- else {
34
- console.log('\nšŸ’” Telemetry is disabled. Run "prpm telemetry enable" to help improve the tool.');
35
- }
36
- });
37
- }
38
- function createEnableCommand() {
39
- return new commander_1.Command('enable')
40
- .description('Enable telemetry and analytics')
41
- .action(async () => {
42
- await telemetry_1.telemetry.enable();
43
- console.log('āœ… Telemetry enabled');
44
- console.log('šŸ“Š Anonymous usage data will be collected to help improve the tool.');
45
- });
46
- }
47
- function createDisableCommand() {
48
- return new commander_1.Command('disable')
49
- .description('Disable telemetry and analytics')
50
- .action(async () => {
51
- await telemetry_1.telemetry.disable();
52
- console.log('āŒ Telemetry disabled');
53
- console.log('šŸ“Š No usage data will be collected.');
54
- });
55
- }
56
- function createStatsCommand() {
57
- return new commander_1.Command('stats')
58
- .description('Show telemetry statistics')
59
- .action(async () => {
60
- const stats = await telemetry_1.telemetry.getStats();
61
- console.log('šŸ“Š Telemetry Statistics:');
62
- console.log(` Total events: ${stats.totalEvents}`);
63
- if (stats.lastEvent) {
64
- console.log(` Last event: ${stats.lastEvent}`);
65
- }
66
- });
67
- }
68
- function createTestCommand() {
69
- return new commander_1.Command('test')
70
- .description('Send a test event to PostHog')
71
- .action(async () => {
72
- console.log('🧪 Sending test event to PostHog...');
73
- try {
74
- await telemetry_1.telemetry.track({
75
- command: 'test',
76
- success: true,
77
- duration: 100,
78
- data: {
79
- testType: 'manual',
80
- message: 'This is a test event from PPM CLI',
81
- timestamp: new Date().toISOString(),
82
- uniqueId: Math.random().toString(36).substring(7),
83
- },
84
- });
85
- console.log('āœ… Test event sent successfully!');
86
- console.log('šŸ“ˆ Check your PostHog dashboard for the event: prpm_test');
87
- console.log('šŸ”— Dashboard: https://app.posthog.com');
88
- console.log('ā° Note: Events may take 1-2 minutes to appear in the dashboard');
89
- // Wait a moment for the event to be sent
90
- await new Promise(resolve => setTimeout(resolve, 3000));
91
- const stats = await telemetry_1.telemetry.getStats();
92
- console.log(`šŸ“Š Total events now: ${stats.totalEvents}`);
93
- console.log('\nšŸ” Troubleshooting tips:');
94
- console.log('1. Check the "Live Events" section in PostHog');
95
- console.log('2. Look for events with name "prpm_test"');
96
- console.log('3. Make sure you\'re in the correct PostHog project');
97
- console.log('4. Events may take 1-2 minutes to appear');
98
- }
99
- catch (error) {
100
- console.error('āŒ Failed to send test event:', error);
101
- }
102
- });
103
- }
@@ -1,76 +0,0 @@
1
- "use strict";
2
- /**
3
- * Trending command - Show trending packages
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.handleTrending = handleTrending;
7
- exports.createTrendingCommand = createTrendingCommand;
8
- const commander_1 = require("commander");
9
- const registry_client_1 = require("@pr-pm/registry-client");
10
- const user_config_1 = require("../core/user-config");
11
- const telemetry_1 = require("../core/telemetry");
12
- async function handleTrending(options) {
13
- const startTime = Date.now();
14
- let success = false;
15
- let error;
16
- try {
17
- console.log(`šŸ”„ Fetching trending packages...`);
18
- const config = await (0, user_config_1.getConfig)();
19
- const client = (0, registry_client_1.getRegistryClient)(config);
20
- const packages = await client.getTrending(options.type, options.limit || 10);
21
- if (packages.length === 0) {
22
- console.log('\nāŒ No trending packages found');
23
- return;
24
- }
25
- console.log(`\n✨ Trending packages (last 7 days):\n`);
26
- packages.forEach((pkg, index) => {
27
- const verified = pkg.verified ? 'āœ“' : ' ';
28
- const rating = pkg.rating_average ? `⭐ ${pkg.rating_average.toFixed(1)}` : '';
29
- const downloads = pkg.total_downloads >= 1000
30
- ? `${(pkg.total_downloads / 1000).toFixed(1)}k`
31
- : pkg.total_downloads;
32
- console.log(`${index + 1}. [${verified}] ${pkg.name} ${rating}`);
33
- console.log(` ${pkg.description || 'No description'}`);
34
- console.log(` šŸ“„ ${downloads} downloads`);
35
- console.log();
36
- });
37
- console.log(`šŸ’” Install a package: prpm install <package-id>`);
38
- success = true;
39
- }
40
- catch (err) {
41
- error = err instanceof Error ? err.message : String(err);
42
- console.error(`\nāŒ Failed to fetch trending packages: ${error}`);
43
- console.log(`\nšŸ’” Tip: Check your internet connection`);
44
- process.exit(1);
45
- }
46
- finally {
47
- await telemetry_1.telemetry.track({
48
- command: 'trending',
49
- success,
50
- error,
51
- duration: Date.now() - startTime,
52
- data: {
53
- type: options.type,
54
- limit: options.limit || 10,
55
- },
56
- });
57
- await telemetry_1.telemetry.shutdown();
58
- }
59
- }
60
- function createTrendingCommand() {
61
- const command = new commander_1.Command('trending');
62
- command
63
- .description('Show trending packages')
64
- .option('--type <type>', 'Filter by package type (cursor, claude, continue)')
65
- .option('--limit <number>', 'Number of packages to show', '10')
66
- .action(async (options) => {
67
- const type = options.type;
68
- const limit = options.limit ? parseInt(options.limit, 10) : 10;
69
- if (options.type && !['cursor', 'claude', 'continue', 'windsurf', 'generic'].includes(type)) {
70
- console.error('āŒ Type must be one of: cursor, claude, continue, windsurf, generic');
71
- process.exit(1);
72
- }
73
- await handleTrending({ type, limit });
74
- });
75
- return command;
76
- }
@@ -1,77 +0,0 @@
1
- "use strict";
2
- /**
3
- * Uninstall command implementation
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.handleUninstall = handleUninstall;
7
- exports.createUninstallCommand = createUninstallCommand;
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 uninstall command
14
- */
15
- async function handleUninstall(name) {
16
- try {
17
- console.log(`šŸ—‘ļø Uninstalling 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 uninstalled ${name}`);
59
- process.exit(0);
60
- }
61
- catch (error) {
62
- console.error(`āŒ Failed to uninstall package: ${error}`);
63
- process.exit(1);
64
- }
65
- }
66
- /**
67
- * Create the uninstall command
68
- */
69
- function createUninstallCommand() {
70
- const command = new commander_1.Command('uninstall');
71
- command
72
- .description('Uninstall a prompt package')
73
- .argument('<id>', 'Package ID to uninstall')
74
- .alias('remove') // Keep 'remove' as an alias for backwards compatibility
75
- .action(handleUninstall);
76
- return command;
77
- }