prpm 0.0.7 → 0.0.8
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/config.js +167 -0
- package/dist/commands/index.js +17 -17
- package/dist/commands/info.js +2 -1
- package/dist/commands/init.js +670 -0
- package/dist/commands/install.js +128 -99
- package/dist/commands/list.js +7 -4
- package/dist/commands/login.js +4 -1
- package/dist/commands/outdated.js +4 -1
- package/dist/commands/popular.js +10 -3
- package/dist/commands/publish.js +100 -11
- package/dist/commands/schema.js +4 -1
- package/dist/commands/search.js +114 -84
- package/dist/commands/telemetry.js +6 -0
- package/dist/commands/trending.js +17 -7
- package/dist/commands/uninstall.js +4 -7
- package/dist/commands/update.js +5 -4
- package/dist/commands/upgrade.js +5 -4
- package/dist/commands/whoami.js +10 -1
- package/dist/core/filesystem.js +21 -15
- package/dist/core/lockfile.js +2 -2
- package/dist/core/marketplace-converter.js +11 -6
- package/dist/core/registry-client.js +14 -8
- package/dist/index.js +19 -1
- package/package.json +5 -1
- package/schemas/prpm-manifest.schema.json +197 -38
package/dist/commands/search.js
CHANGED
|
@@ -44,67 +44,85 @@ const user_config_1 = require("../core/user-config");
|
|
|
44
44
|
const telemetry_1 = require("../core/telemetry");
|
|
45
45
|
const readline = __importStar(require("readline"));
|
|
46
46
|
/**
|
|
47
|
-
* Get icon for package
|
|
47
|
+
* Get icon for package format and subtype
|
|
48
48
|
*/
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
function getPackageIcon(format, subtype) {
|
|
50
|
+
// Subtype icons take precedence
|
|
51
|
+
const subtypeIcons = {
|
|
52
|
+
'skill': '🎓',
|
|
53
|
+
'agent': '🤖',
|
|
54
54
|
'slash-command': '⚡',
|
|
55
|
-
'
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
mcp: '🔗',
|
|
55
|
+
'rule': '📋',
|
|
56
|
+
'prompt': '💬',
|
|
57
|
+
'workflow': '⚡',
|
|
58
|
+
'tool': '🔧',
|
|
59
|
+
'template': '📄',
|
|
60
|
+
'collection': '📦',
|
|
61
|
+
'chatmode': '💬',
|
|
63
62
|
};
|
|
64
|
-
|
|
63
|
+
// Format-specific icons for rules/defaults
|
|
64
|
+
const formatIcons = {
|
|
65
|
+
'claude': '🤖',
|
|
66
|
+
'cursor': '📋',
|
|
67
|
+
'windsurf': '🌊',
|
|
68
|
+
'continue': '➡️',
|
|
69
|
+
'copilot': '✈️',
|
|
70
|
+
'kiro': '🎯',
|
|
71
|
+
'mcp': '🔗',
|
|
72
|
+
'agents.md': '📝',
|
|
73
|
+
'generic': '📦',
|
|
74
|
+
};
|
|
75
|
+
return subtypeIcons[subtype] || formatIcons[format] || '📦';
|
|
65
76
|
}
|
|
66
77
|
/**
|
|
67
|
-
* Get human-readable label for package
|
|
78
|
+
* Get human-readable label for package format and subtype
|
|
68
79
|
*/
|
|
69
|
-
function
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
function getPackageLabel(format, subtype) {
|
|
81
|
+
const formatLabels = {
|
|
82
|
+
'claude': 'Claude',
|
|
83
|
+
'cursor': 'Cursor',
|
|
84
|
+
'windsurf': 'Windsurf',
|
|
85
|
+
'continue': 'Continue',
|
|
86
|
+
'copilot': 'GitHub Copilot',
|
|
87
|
+
'kiro': 'Kiro',
|
|
88
|
+
'mcp': 'MCP',
|
|
89
|
+
'agents.md': 'Agents.md',
|
|
90
|
+
'generic': '',
|
|
91
|
+
};
|
|
92
|
+
const subtypeLabels = {
|
|
93
|
+
'skill': 'Skill',
|
|
94
|
+
'agent': 'Agent',
|
|
74
95
|
'slash-command': 'Slash Command',
|
|
75
|
-
'
|
|
76
|
-
'
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
template: 'Template',
|
|
83
|
-
mcp: 'MCP Server',
|
|
96
|
+
'rule': 'Rule',
|
|
97
|
+
'prompt': 'Prompt',
|
|
98
|
+
'workflow': 'Workflow',
|
|
99
|
+
'tool': 'Tool',
|
|
100
|
+
'template': 'Template',
|
|
101
|
+
'collection': 'Collection',
|
|
102
|
+
'chatmode': 'Chat Mode',
|
|
84
103
|
};
|
|
85
|
-
|
|
104
|
+
const formatLabel = formatLabels[format];
|
|
105
|
+
const subtypeLabel = subtypeLabels[subtype];
|
|
106
|
+
if (format === 'generic') {
|
|
107
|
+
return subtypeLabel;
|
|
108
|
+
}
|
|
109
|
+
return `${formatLabel} ${subtypeLabel}`;
|
|
86
110
|
}
|
|
87
111
|
/**
|
|
88
|
-
* Map
|
|
112
|
+
* Map subtype filters for search
|
|
89
113
|
*/
|
|
90
|
-
function
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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] || {};
|
|
114
|
+
function buildSearchFilters(options) {
|
|
115
|
+
const searchOptions = {};
|
|
116
|
+
if (options.format) {
|
|
117
|
+
searchOptions.format = options.format;
|
|
118
|
+
}
|
|
119
|
+
if (options.subtype) {
|
|
120
|
+
searchOptions.subtype = options.subtype;
|
|
121
|
+
}
|
|
122
|
+
if (options.author) {
|
|
123
|
+
searchOptions.author = options.author;
|
|
124
|
+
}
|
|
125
|
+
return searchOptions;
|
|
108
126
|
}
|
|
109
127
|
/**
|
|
110
128
|
* Build webapp URL for search results
|
|
@@ -114,8 +132,10 @@ function buildWebappUrl(query, options, page = 1) {
|
|
|
114
132
|
const params = new URLSearchParams();
|
|
115
133
|
if (query)
|
|
116
134
|
params.append('q', query);
|
|
117
|
-
if (options.
|
|
118
|
-
params.append('
|
|
135
|
+
if (options.format)
|
|
136
|
+
params.append('format', options.format);
|
|
137
|
+
if (options.subtype)
|
|
138
|
+
params.append('subtype', options.subtype);
|
|
119
139
|
if (options.author)
|
|
120
140
|
params.append('author', options.author);
|
|
121
141
|
if (page > 1)
|
|
@@ -137,8 +157,8 @@ function displayResults(packages, total, page, limit) {
|
|
|
137
157
|
const downloads = pkg.total_downloads >= 1000
|
|
138
158
|
? `${(pkg.total_downloads / 1000).toFixed(1)}k`
|
|
139
159
|
: pkg.total_downloads;
|
|
140
|
-
const typeIcon =
|
|
141
|
-
const typeLabel =
|
|
160
|
+
const typeIcon = getPackageIcon(pkg.format, pkg.subtype);
|
|
161
|
+
const typeLabel = getPackageLabel(pkg.format, pkg.subtype);
|
|
142
162
|
// Add verified badge
|
|
143
163
|
let verifiedBadge = '';
|
|
144
164
|
if (pkg.featured || pkg.official || pkg.verified) {
|
|
@@ -254,29 +274,31 @@ async function handleSearch(query, options) {
|
|
|
254
274
|
let result = null;
|
|
255
275
|
let registryUrl = '';
|
|
256
276
|
try {
|
|
257
|
-
// Allow empty query when filtering by
|
|
277
|
+
// Allow empty query when filtering by format/subtype or author
|
|
258
278
|
if (query) {
|
|
259
279
|
console.log(`🔍 Searching for "${query}"...`);
|
|
260
280
|
}
|
|
261
|
-
else if (options.
|
|
262
|
-
|
|
281
|
+
else if (options.format || options.subtype) {
|
|
282
|
+
const filterType = options.subtype || options.format;
|
|
283
|
+
console.log(`🔍 Listing ${filterType} packages...`);
|
|
263
284
|
}
|
|
264
285
|
else if (options.author) {
|
|
265
286
|
console.log(`🔍 Listing packages by @${options.author}...`);
|
|
266
287
|
}
|
|
267
288
|
else {
|
|
268
|
-
console.log('❌ Please provide a search query or use --
|
|
289
|
+
console.log('❌ Please provide a search query or use --format/--subtype/--author to filter');
|
|
269
290
|
console.log('\n💡 Examples:');
|
|
270
291
|
console.log(' prpm search react');
|
|
271
|
-
console.log(' prpm search --
|
|
292
|
+
console.log(' prpm search --subtype skill');
|
|
293
|
+
console.log(' prpm search --format claude');
|
|
272
294
|
console.log(' prpm search --author prpm');
|
|
273
|
-
console.log(' prpm search react --
|
|
295
|
+
console.log(' prpm search react --subtype rule');
|
|
274
296
|
return;
|
|
275
297
|
}
|
|
276
298
|
const config = await (0, user_config_1.getConfig)();
|
|
277
299
|
registryUrl = config.registryUrl || 'https://registry.prpm.dev';
|
|
278
300
|
const client = (0, registry_client_1.getRegistryClient)(config);
|
|
279
|
-
//
|
|
301
|
+
// Build search options
|
|
280
302
|
const limit = options.limit || 20;
|
|
281
303
|
const page = options.page || 1;
|
|
282
304
|
const offset = (page - 1) * limit;
|
|
@@ -284,14 +306,12 @@ async function handleSearch(query, options) {
|
|
|
284
306
|
limit,
|
|
285
307
|
offset,
|
|
286
308
|
};
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
searchOptions.tags = mapped.tags;
|
|
294
|
-
}
|
|
309
|
+
// Add format/subtype filters
|
|
310
|
+
if (options.format) {
|
|
311
|
+
searchOptions.format = options.format;
|
|
312
|
+
}
|
|
313
|
+
if (options.subtype) {
|
|
314
|
+
searchOptions.subtype = options.subtype;
|
|
295
315
|
}
|
|
296
316
|
if (options.author) {
|
|
297
317
|
searchOptions.author = options.author;
|
|
@@ -359,7 +379,8 @@ async function handleSearch(query, options) {
|
|
|
359
379
|
duration: Date.now() - startTime,
|
|
360
380
|
data: {
|
|
361
381
|
query: query.substring(0, 100),
|
|
362
|
-
|
|
382
|
+
format: options.format,
|
|
383
|
+
subtype: options.subtype,
|
|
363
384
|
resultCount: success && result ? result.packages.length : 0,
|
|
364
385
|
page: options.page,
|
|
365
386
|
interactive: options.interactive,
|
|
@@ -373,32 +394,41 @@ function createSearchCommand() {
|
|
|
373
394
|
const command = new commander_1.Command('search');
|
|
374
395
|
command
|
|
375
396
|
.description('Search for packages in the registry')
|
|
376
|
-
.argument('[query]', 'Search query (optional when using --
|
|
377
|
-
.option('--
|
|
397
|
+
.argument('[query]', 'Search query (optional when using --format/--subtype or --author)')
|
|
398
|
+
.option('--format <format>', 'Filter by package format (cursor, claude, continue, windsurf, copilot, kiro, generic, mcp)')
|
|
399
|
+
.option('--subtype <subtype>', 'Filter by package subtype (rule, agent, skill, slash-command, prompt, workflow, tool, template, collection)')
|
|
378
400
|
.option('--author <username>', 'Filter by author username')
|
|
379
401
|
.option('--limit <number>', 'Number of results per page', '20')
|
|
380
402
|
.option('--page <number>', 'Page number (default: 1)', '1')
|
|
381
403
|
.option('--interactive', 'Enable interactive pagination (default: true for multiple pages)', true)
|
|
382
404
|
.option('--no-interactive', 'Disable interactive pagination')
|
|
383
405
|
.action(async (query, options) => {
|
|
384
|
-
const
|
|
406
|
+
const format = options.format;
|
|
407
|
+
const subtype = options.subtype;
|
|
385
408
|
const author = options.author;
|
|
386
409
|
const limit = options.limit ? parseInt(options.limit, 10) : 20;
|
|
387
410
|
const page = options.page ? parseInt(options.page, 10) : 1;
|
|
388
|
-
const
|
|
389
|
-
|
|
390
|
-
|
|
411
|
+
const validFormats = ['cursor', 'claude', 'continue', 'windsurf', 'copilot', 'kiro', 'generic', 'mcp'];
|
|
412
|
+
const validSubtypes = ['rule', 'agent', 'skill', 'slash-command', 'prompt', 'workflow', 'tool', 'template', 'collection'];
|
|
413
|
+
if (options.format && !validFormats.includes(format)) {
|
|
414
|
+
console.error(`❌ Format must be one of: ${validFormats.join(', ')}`);
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
417
|
+
if (options.subtype && !validSubtypes.includes(subtype)) {
|
|
418
|
+
console.error(`❌ Subtype must be one of: ${validSubtypes.join(', ')}`);
|
|
391
419
|
console.log(`\n💡 Examples:`);
|
|
392
|
-
console.log(` prpm search postgres --
|
|
393
|
-
console.log(` prpm search debugging --
|
|
394
|
-
console.log(` prpm search refactor --
|
|
395
|
-
console.log(` prpm search react --
|
|
396
|
-
console.log(` prpm search --
|
|
397
|
-
console.log(` prpm search --
|
|
398
|
-
console.log(` prpm search --
|
|
420
|
+
console.log(` prpm search postgres --subtype skill`);
|
|
421
|
+
console.log(` prpm search debugging --subtype agent`);
|
|
422
|
+
console.log(` prpm search refactor --subtype slash-command`);
|
|
423
|
+
console.log(` prpm search react --subtype rule`);
|
|
424
|
+
console.log(` prpm search --subtype slash-command # List all slash commands`);
|
|
425
|
+
console.log(` prpm search --subtype skill # List all skills`);
|
|
426
|
+
console.log(` prpm search --format claude # List all Claude packages`);
|
|
427
|
+
console.log(` prpm search --author prpm # List packages by @prpm`);
|
|
399
428
|
process.exit(1);
|
|
400
429
|
}
|
|
401
|
-
await handleSearch(query || '', {
|
|
430
|
+
await handleSearch(query || '', { format, subtype, author, limit, page, interactive: options.interactive });
|
|
431
|
+
process.exit(0);
|
|
402
432
|
});
|
|
403
433
|
return command;
|
|
404
434
|
}
|
|
@@ -33,6 +33,7 @@ function createStatusCommand() {
|
|
|
33
33
|
else {
|
|
34
34
|
console.log('\n💡 Telemetry is disabled. Run "prpm telemetry enable" to help improve the tool.');
|
|
35
35
|
}
|
|
36
|
+
process.exit(0);
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
function createEnableCommand() {
|
|
@@ -42,6 +43,7 @@ function createEnableCommand() {
|
|
|
42
43
|
await telemetry_1.telemetry.enable();
|
|
43
44
|
console.log('✅ Telemetry enabled');
|
|
44
45
|
console.log('📊 Anonymous usage data will be collected to help improve the tool.');
|
|
46
|
+
process.exit(0);
|
|
45
47
|
});
|
|
46
48
|
}
|
|
47
49
|
function createDisableCommand() {
|
|
@@ -51,6 +53,7 @@ function createDisableCommand() {
|
|
|
51
53
|
await telemetry_1.telemetry.disable();
|
|
52
54
|
console.log('❌ Telemetry disabled');
|
|
53
55
|
console.log('📊 No usage data will be collected.');
|
|
56
|
+
process.exit(0);
|
|
54
57
|
});
|
|
55
58
|
}
|
|
56
59
|
function createStatsCommand() {
|
|
@@ -63,6 +66,7 @@ function createStatsCommand() {
|
|
|
63
66
|
if (stats.lastEvent) {
|
|
64
67
|
console.log(` Last event: ${stats.lastEvent}`);
|
|
65
68
|
}
|
|
69
|
+
process.exit(0);
|
|
66
70
|
});
|
|
67
71
|
}
|
|
68
72
|
function createTestCommand() {
|
|
@@ -98,6 +102,8 @@ function createTestCommand() {
|
|
|
98
102
|
}
|
|
99
103
|
catch (error) {
|
|
100
104
|
console.error('❌ Failed to send test event:', error);
|
|
105
|
+
process.exit(1);
|
|
101
106
|
}
|
|
107
|
+
process.exit(0);
|
|
102
108
|
});
|
|
103
109
|
}
|
|
@@ -17,7 +17,7 @@ async function handleTrending(options) {
|
|
|
17
17
|
console.log(`🔥 Fetching trending packages...`);
|
|
18
18
|
const config = await (0, user_config_1.getConfig)();
|
|
19
19
|
const client = (0, registry_client_1.getRegistryClient)(config);
|
|
20
|
-
const packages = await client.getTrending(options.
|
|
20
|
+
const packages = await client.getTrending(options.format, options.subtype, options.limit || 10);
|
|
21
21
|
if (packages.length === 0) {
|
|
22
22
|
console.log('\n❌ No trending packages found');
|
|
23
23
|
return;
|
|
@@ -50,7 +50,8 @@ async function handleTrending(options) {
|
|
|
50
50
|
error,
|
|
51
51
|
duration: Date.now() - startTime,
|
|
52
52
|
data: {
|
|
53
|
-
|
|
53
|
+
format: options.format,
|
|
54
|
+
subtype: options.subtype,
|
|
54
55
|
limit: options.limit || 10,
|
|
55
56
|
},
|
|
56
57
|
});
|
|
@@ -61,16 +62,25 @@ function createTrendingCommand() {
|
|
|
61
62
|
const command = new commander_1.Command('trending');
|
|
62
63
|
command
|
|
63
64
|
.description('Show trending packages')
|
|
64
|
-
.option('--
|
|
65
|
+
.option('--format <format>', 'Filter by format (cursor, claude, continue, windsurf, copilot, kiro, generic)')
|
|
66
|
+
.option('--subtype <subtype>', 'Filter by subtype (rule, agent, skill, slash-command, prompt, workflow, tool, template, collection)')
|
|
65
67
|
.option('--limit <number>', 'Number of packages to show', '10')
|
|
66
68
|
.action(async (options) => {
|
|
67
|
-
const
|
|
69
|
+
const format = options.format;
|
|
70
|
+
const subtype = options.subtype;
|
|
68
71
|
const limit = options.limit ? parseInt(options.limit, 10) : 10;
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
const validFormats = ['cursor', 'claude', 'continue', 'windsurf', 'copilot', 'kiro', 'generic', 'mcp'];
|
|
73
|
+
const validSubtypes = ['rule', 'agent', 'skill', 'slash-command', 'prompt', 'workflow', 'tool', 'template', 'collection'];
|
|
74
|
+
if (options.format && !validFormats.includes(format)) {
|
|
75
|
+
console.error(`❌ Format must be one of: ${validFormats.join(', ')}`);
|
|
71
76
|
process.exit(1);
|
|
72
77
|
}
|
|
73
|
-
|
|
78
|
+
if (options.subtype && !validSubtypes.includes(subtype)) {
|
|
79
|
+
console.error(`❌ Subtype must be one of: ${validSubtypes.join(', ')}`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
await handleTrending({ format, subtype, limit });
|
|
83
|
+
process.exit(0);
|
|
74
84
|
});
|
|
75
85
|
return command;
|
|
76
86
|
}
|
|
@@ -21,13 +21,10 @@ async function handleUninstall(name) {
|
|
|
21
21
|
console.error(`❌ Package "${name}" not found`);
|
|
22
22
|
process.exit(1);
|
|
23
23
|
}
|
|
24
|
-
//
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
pkg.format === 'windsurf' ? 'windsurf' :
|
|
29
|
-
pkg.type);
|
|
30
|
-
const destDir = (0, filesystem_1.getDestinationDir)(effectiveType);
|
|
24
|
+
// Get destination directory using format and subtype
|
|
25
|
+
const format = pkg.format || 'generic';
|
|
26
|
+
const subtype = pkg.subtype || 'rule';
|
|
27
|
+
const destDir = (0, filesystem_1.getDestinationDir)(format, subtype);
|
|
31
28
|
const fileExtension = pkg.format === 'cursor' ? 'mdc' : 'md';
|
|
32
29
|
// Strip author namespace to get just the package name
|
|
33
30
|
const packageName = (0, filesystem_1.stripAuthorNamespace)(name);
|
package/dist/commands/update.js
CHANGED
|
@@ -59,9 +59,7 @@ async function handleUpdate(packageName, options = {}) {
|
|
|
59
59
|
}
|
|
60
60
|
console.log(`\n📦 Updating ${pkg.id}: ${currentVersion} → ${latestVersion}`);
|
|
61
61
|
// Install new version
|
|
62
|
-
await (0, install_1.handleInstall)(`${pkg.id}@${latestVersion}`, {
|
|
63
|
-
type: pkg.type,
|
|
64
|
-
});
|
|
62
|
+
await (0, install_1.handleInstall)(`${pkg.id}@${latestVersion}`, {});
|
|
65
63
|
updatedCount++;
|
|
66
64
|
}
|
|
67
65
|
catch (err) {
|
|
@@ -117,5 +115,8 @@ function createUpdateCommand() {
|
|
|
117
115
|
.description('Update packages to latest compatible versions (minor/patch only)')
|
|
118
116
|
.argument('[package]', 'Specific package to update (optional)')
|
|
119
117
|
.option('--all', 'Update all packages')
|
|
120
|
-
.action(
|
|
118
|
+
.action(async (packageName, options) => {
|
|
119
|
+
await handleUpdate(packageName, options);
|
|
120
|
+
process.exit(0);
|
|
121
|
+
});
|
|
121
122
|
}
|
package/dist/commands/upgrade.js
CHANGED
|
@@ -58,9 +58,7 @@ async function handleUpgrade(packageName, options = {}) {
|
|
|
58
58
|
console.log(` ⚠️ This is a major version upgrade and may contain breaking changes`);
|
|
59
59
|
}
|
|
60
60
|
// Install new version
|
|
61
|
-
await (0, install_1.handleInstall)(`${pkg.id}@${latestVersion}`, {
|
|
62
|
-
type: pkg.type,
|
|
63
|
-
});
|
|
61
|
+
await (0, install_1.handleInstall)(`${pkg.id}@${latestVersion}`, {});
|
|
64
62
|
upgradedCount++;
|
|
65
63
|
}
|
|
66
64
|
catch (err) {
|
|
@@ -117,5 +115,8 @@ function createUpgradeCommand() {
|
|
|
117
115
|
.argument('[package]', 'Specific package to upgrade (optional)')
|
|
118
116
|
.option('--all', 'Upgrade all packages')
|
|
119
117
|
.option('--force', 'Skip warning for major version upgrades')
|
|
120
|
-
.action(
|
|
118
|
+
.action(async (packageName, options) => {
|
|
119
|
+
await handleUpgrade(packageName, options);
|
|
120
|
+
process.exit(0);
|
|
121
|
+
});
|
|
121
122
|
}
|
package/dist/commands/whoami.js
CHANGED
|
@@ -45,7 +45,13 @@ async function handleWhoami() {
|
|
|
45
45
|
}
|
|
46
46
|
catch (apiError) {
|
|
47
47
|
// Fallback to simple username display if API call fails
|
|
48
|
+
// This can happen if the user's token is stale or the registry is unavailable
|
|
48
49
|
console.log(`${config.username}`);
|
|
50
|
+
// Show hint if it looks like an auth issue
|
|
51
|
+
const errorMessage = apiError instanceof Error ? apiError.message : String(apiError);
|
|
52
|
+
if (errorMessage.includes('User not found') || errorMessage.includes('Unauthorized')) {
|
|
53
|
+
console.log('💡 Tip: Your token may be outdated. Run "prpm login" to refresh.\n');
|
|
54
|
+
}
|
|
49
55
|
}
|
|
50
56
|
success = true;
|
|
51
57
|
}
|
|
@@ -71,5 +77,8 @@ async function handleWhoami() {
|
|
|
71
77
|
function createWhoamiCommand() {
|
|
72
78
|
return new commander_1.Command('whoami')
|
|
73
79
|
.description('Show current logged-in user')
|
|
74
|
-
.action(
|
|
80
|
+
.action(async () => {
|
|
81
|
+
await handleWhoami();
|
|
82
|
+
process.exit(0);
|
|
83
|
+
});
|
|
75
84
|
}
|
package/dist/core/filesystem.js
CHANGED
|
@@ -16,32 +16,38 @@ exports.stripAuthorNamespace = stripAuthorNamespace;
|
|
|
16
16
|
const fs_1 = require("fs");
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
/**
|
|
19
|
-
* Get the destination directory for a package
|
|
19
|
+
* Get the destination directory for a package based on format and subtype
|
|
20
20
|
*/
|
|
21
|
-
function getDestinationDir(
|
|
22
|
-
switch (
|
|
21
|
+
function getDestinationDir(format, subtype) {
|
|
22
|
+
switch (format) {
|
|
23
23
|
case 'cursor':
|
|
24
|
+
if (subtype === 'agent')
|
|
25
|
+
return '.cursor/agents';
|
|
26
|
+
if (subtype === 'slash-command')
|
|
27
|
+
return '.cursor/commands';
|
|
24
28
|
return '.cursor/rules';
|
|
25
|
-
case 'cursor-agent':
|
|
26
|
-
return '.cursor/agents';
|
|
27
|
-
case 'cursor-slash-command':
|
|
28
|
-
return '.cursor/commands';
|
|
29
29
|
case 'claude':
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return '.claude/
|
|
30
|
+
if (subtype === 'skill')
|
|
31
|
+
return '.claude/skills';
|
|
32
|
+
if (subtype === 'slash-command')
|
|
33
|
+
return '.claude/commands';
|
|
34
|
+
if (subtype === 'agent')
|
|
35
|
+
return '.claude/agents';
|
|
36
|
+
return '.claude/agents'; // Default for claude
|
|
37
37
|
case 'continue':
|
|
38
38
|
return '.continue/rules';
|
|
39
39
|
case 'windsurf':
|
|
40
40
|
return '.windsurf/rules';
|
|
41
|
+
case 'copilot':
|
|
42
|
+
return '.github/instructions';
|
|
43
|
+
case 'kiro':
|
|
44
|
+
return '.kiro/steering';
|
|
41
45
|
case 'generic':
|
|
42
46
|
return '.prompts';
|
|
47
|
+
case 'mcp':
|
|
48
|
+
return '.mcp/tools';
|
|
43
49
|
default:
|
|
44
|
-
throw new Error(`Unknown
|
|
50
|
+
throw new Error(`Unknown format: ${format}`);
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
53
|
/**
|
package/dist/core/lockfile.js
CHANGED
|
@@ -72,8 +72,8 @@ function addToLockfile(lockfile, packageId, packageInfo) {
|
|
|
72
72
|
resolved: packageInfo.tarballUrl,
|
|
73
73
|
integrity: '', // Will be set after download
|
|
74
74
|
dependencies: packageInfo.dependencies,
|
|
75
|
-
type: packageInfo.type,
|
|
76
75
|
format: packageInfo.format,
|
|
76
|
+
subtype: packageInfo.subtype,
|
|
77
77
|
installedPath: packageInfo.installedPath,
|
|
78
78
|
};
|
|
79
79
|
lockfile.generated = new Date().toISOString();
|
|
@@ -194,8 +194,8 @@ async function addPackage(packageInfo) {
|
|
|
194
194
|
version: packageInfo.version,
|
|
195
195
|
tarballUrl: packageInfo.tarballUrl,
|
|
196
196
|
dependencies: packageInfo.dependencies,
|
|
197
|
-
type: packageInfo.type,
|
|
198
197
|
format: packageInfo.format,
|
|
198
|
+
subtype: packageInfo.subtype,
|
|
199
199
|
installedPath: packageInfo.installedPath,
|
|
200
200
|
});
|
|
201
201
|
await writeLockfile(lockfile);
|
|
@@ -25,16 +25,20 @@ function marketplaceToManifest(marketplace, pluginIndex = 0) {
|
|
|
25
25
|
throw new Error(`Plugin index ${pluginIndex} out of range. Found ${marketplace.plugins.length} plugins.`);
|
|
26
26
|
}
|
|
27
27
|
const plugin = marketplace.plugins[pluginIndex];
|
|
28
|
-
// Determine package
|
|
29
|
-
let
|
|
28
|
+
// Determine package format and subtype based on what the plugin contains
|
|
29
|
+
let format = 'claude';
|
|
30
|
+
let subtype = 'rule';
|
|
30
31
|
if (plugin.agents && plugin.agents.length > 0) {
|
|
31
|
-
|
|
32
|
+
format = 'claude';
|
|
33
|
+
subtype = 'agent';
|
|
32
34
|
}
|
|
33
35
|
else if (plugin.skills && plugin.skills.length > 0) {
|
|
34
|
-
|
|
36
|
+
format = 'claude';
|
|
37
|
+
subtype = 'skill';
|
|
35
38
|
}
|
|
36
39
|
else if (plugin.commands && plugin.commands.length > 0) {
|
|
37
|
-
|
|
40
|
+
format = 'claude';
|
|
41
|
+
subtype = 'slash-command';
|
|
38
42
|
}
|
|
39
43
|
// Generate package name from plugin name
|
|
40
44
|
// Format: @owner/plugin-name
|
|
@@ -54,7 +58,8 @@ function marketplaceToManifest(marketplace, pluginIndex = 0) {
|
|
|
54
58
|
name: packageName,
|
|
55
59
|
version: plugin.version || marketplace.version || '1.0.0',
|
|
56
60
|
description: plugin.description || marketplace.description,
|
|
57
|
-
|
|
61
|
+
format,
|
|
62
|
+
subtype,
|
|
58
63
|
author: plugin.author || marketplace.owner,
|
|
59
64
|
files,
|
|
60
65
|
tags,
|
|
@@ -16,8 +16,10 @@ class RegistryClient {
|
|
|
16
16
|
*/
|
|
17
17
|
async search(query, options) {
|
|
18
18
|
const params = new URLSearchParams({ q: query });
|
|
19
|
-
if (options?.
|
|
20
|
-
params.append('
|
|
19
|
+
if (options?.format)
|
|
20
|
+
params.append('format', options.format);
|
|
21
|
+
if (options?.subtype)
|
|
22
|
+
params.append('subtype', options.subtype);
|
|
21
23
|
if (options?.tags)
|
|
22
24
|
options.tags.forEach(tag => params.append('tags', tag));
|
|
23
25
|
if (options?.limit)
|
|
@@ -87,10 +89,12 @@ class RegistryClient {
|
|
|
87
89
|
/**
|
|
88
90
|
* Get trending packages
|
|
89
91
|
*/
|
|
90
|
-
async getTrending(
|
|
92
|
+
async getTrending(format, subtype, limit = 20) {
|
|
91
93
|
const params = new URLSearchParams({ limit: limit.toString() });
|
|
92
|
-
if (
|
|
93
|
-
params.append('
|
|
94
|
+
if (format)
|
|
95
|
+
params.append('format', format);
|
|
96
|
+
if (subtype)
|
|
97
|
+
params.append('subtype', subtype);
|
|
94
98
|
const response = await this.fetch(`/api/v1/search/trending?${params}`);
|
|
95
99
|
const data = await response.json();
|
|
96
100
|
return data.packages;
|
|
@@ -98,10 +102,12 @@ class RegistryClient {
|
|
|
98
102
|
/**
|
|
99
103
|
* Get featured packages
|
|
100
104
|
*/
|
|
101
|
-
async getFeatured(
|
|
105
|
+
async getFeatured(format, subtype, limit = 20) {
|
|
102
106
|
const params = new URLSearchParams({ limit: limit.toString() });
|
|
103
|
-
if (
|
|
104
|
-
params.append('
|
|
107
|
+
if (format)
|
|
108
|
+
params.append('format', format);
|
|
109
|
+
if (subtype)
|
|
110
|
+
params.append('subtype', subtype);
|
|
105
111
|
const response = await this.fetch(`/api/v1/search/featured?${params}`);
|
|
106
112
|
const data = await response.json();
|
|
107
113
|
return data.packages;
|