prpm 0.2.0 ā 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 -109
- package/package.json +11 -9
- package/dist/__tests__/e2e/test-helpers.js +0 -153
- 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 -829
- package/dist/commands/list.js +0 -198
- package/dist/commands/login.js +0 -316
- package/dist/commands/outdated.js +0 -130
- package/dist/commands/playground.js +0 -637
- 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/starred.js +0 -147
- 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 -246
- package/dist/core/lockfile.js +0 -292
- package/dist/core/marketplace-converter.js +0 -224
- package/dist/core/prompts.js +0 -62
- 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 -9
- 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,211 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Subscribe command - Subscribe to PRPM+ for monthly credits
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.handleSubscribe = handleSubscribe;
|
|
7
|
-
exports.createSubscribeCommand = createSubscribeCommand;
|
|
8
|
-
const commander_1 = require("commander");
|
|
9
|
-
const user_config_1 = require("../core/user-config");
|
|
10
|
-
const telemetry_1 = require("../core/telemetry");
|
|
11
|
-
const child_process_1 = require("child_process");
|
|
12
|
-
const util_1 = require("util");
|
|
13
|
-
const webapp_url_1 = require("../utils/webapp-url");
|
|
14
|
-
const errors_1 = require("../core/errors");
|
|
15
|
-
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
16
|
-
/**
|
|
17
|
-
* Make authenticated API call
|
|
18
|
-
*/
|
|
19
|
-
async function apiCall(endpoint) {
|
|
20
|
-
const config = await (0, user_config_1.getConfig)();
|
|
21
|
-
const baseUrl = (config.registryUrl || "https://registry.prpm.dev").replace(/\/$/, '');
|
|
22
|
-
if (!config.token) {
|
|
23
|
-
throw new Error('Authentication required. Please run `prpm login` first.');
|
|
24
|
-
}
|
|
25
|
-
const response = await fetch(`${baseUrl}${endpoint}`, {
|
|
26
|
-
headers: {
|
|
27
|
-
Authorization: `Bearer ${config.token}`,
|
|
28
|
-
},
|
|
29
|
-
});
|
|
30
|
-
if (!response.ok) {
|
|
31
|
-
const errorData = await response.json().catch(() => ({}));
|
|
32
|
-
throw new Error(errorData.message || `API request failed: ${response.statusText}`);
|
|
33
|
-
}
|
|
34
|
-
return response;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Get current subscription status
|
|
38
|
-
*/
|
|
39
|
-
async function getSubscriptionStatus() {
|
|
40
|
-
const response = await apiCall('/api/v1/playground/credits');
|
|
41
|
-
return response.json();
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Open URL in default browser
|
|
45
|
-
*/
|
|
46
|
-
async function openBrowser(url) {
|
|
47
|
-
const platform = process.platform;
|
|
48
|
-
let command;
|
|
49
|
-
if (platform === 'darwin') {
|
|
50
|
-
command = `open "${url}"`;
|
|
51
|
-
}
|
|
52
|
-
else if (platform === 'win32') {
|
|
53
|
-
command = `start "" "${url}"`;
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
// Linux and other Unix-like systems
|
|
57
|
-
command = `xdg-open "${url}"`;
|
|
58
|
-
}
|
|
59
|
-
try {
|
|
60
|
-
await execAsync(command);
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
// If automatic opening fails, just show the URL
|
|
64
|
-
console.log(`\nš Please open this URL in your browser:`);
|
|
65
|
-
console.log(` ${url}`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Poll for subscription status change
|
|
70
|
-
*/
|
|
71
|
-
async function pollForSubscription(initialStatus, maxAttempts = 60, intervalMs = 2000) {
|
|
72
|
-
console.log('\nā³ Waiting for subscription confirmation...');
|
|
73
|
-
console.log(' (This may take a minute. Press Ctrl+C to cancel)');
|
|
74
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
75
|
-
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
76
|
-
try {
|
|
77
|
-
const status = await getSubscriptionStatus();
|
|
78
|
-
if (status.prpm_plus_status === 'active' && initialStatus !== 'active') {
|
|
79
|
-
return true;
|
|
80
|
-
}
|
|
81
|
-
// Show progress indicator
|
|
82
|
-
if (attempt % 5 === 0 && attempt > 0) {
|
|
83
|
-
process.stdout.write('.');
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
catch (error) {
|
|
87
|
-
// Continue polling even if there's an error
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Handle the subscribe command
|
|
95
|
-
*/
|
|
96
|
-
async function handleSubscribe() {
|
|
97
|
-
const startTime = Date.now();
|
|
98
|
-
let success = false;
|
|
99
|
-
let error;
|
|
100
|
-
try {
|
|
101
|
-
const config = await (0, user_config_1.getConfig)();
|
|
102
|
-
if (!config.token) {
|
|
103
|
-
console.error('ā Authentication required');
|
|
104
|
-
console.log('\nš” Please login first:');
|
|
105
|
-
console.log(' prpm login');
|
|
106
|
-
throw new errors_1.CLIError('ā Authentication required', 1);
|
|
107
|
-
}
|
|
108
|
-
// Get current status
|
|
109
|
-
console.log('š Checking current subscription status...');
|
|
110
|
-
const initialStatus = await getSubscriptionStatus();
|
|
111
|
-
if (initialStatus.prpm_plus_status === 'active') {
|
|
112
|
-
console.log('\nā
You are already subscribed to PRPM+!');
|
|
113
|
-
console.log(`\nš Current benefits:`);
|
|
114
|
-
console.log(` š° Monthly credits: ${initialStatus.monthly_credits}`);
|
|
115
|
-
console.log(` š¦ Priority support`);
|
|
116
|
-
console.log(` š Early access to new features`);
|
|
117
|
-
console.log('\nš” Manage your subscription at:');
|
|
118
|
-
console.log(' https://prpm.dev/settings/billing');
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
console.log('\n⨠Subscribe to PRPM+ and get:');
|
|
122
|
-
console.log(' š° 100 monthly playground credits');
|
|
123
|
-
console.log(' ā»ļø Rollover unused credits (up to 200)');
|
|
124
|
-
console.log(' š¦ Priority support');
|
|
125
|
-
console.log(' š Early access to new features');
|
|
126
|
-
console.log('\nšµ Pricing:');
|
|
127
|
-
console.log(' $6/month for individuals');
|
|
128
|
-
console.log(' $3/month for verified organization members (50% off)');
|
|
129
|
-
// Open subscription page
|
|
130
|
-
const webappUrl = (0, webapp_url_1.getWebappUrl)(config.registryUrl || 'https://registry.prpm.dev');
|
|
131
|
-
const subscribeUrl = `${webappUrl}/playground/credits/subscribe`;
|
|
132
|
-
console.log(`\nš Opening subscription page in your browser...`);
|
|
133
|
-
await openBrowser(subscribeUrl);
|
|
134
|
-
// Poll for subscription confirmation
|
|
135
|
-
const subscribed = await pollForSubscription(initialStatus.prpm_plus_status);
|
|
136
|
-
if (subscribed) {
|
|
137
|
-
const updatedStatus = await getSubscriptionStatus();
|
|
138
|
-
console.log('\n\nš Successfully subscribed to PRPM+!');
|
|
139
|
-
console.log('\nš Your benefits:');
|
|
140
|
-
console.log(` š° Monthly credits: ${updatedStatus.monthly_credits}`);
|
|
141
|
-
console.log(` š³ Current balance: ${updatedStatus.balance} credits`);
|
|
142
|
-
console.log('\nā
You can now:');
|
|
143
|
-
console.log(' - Test packages in playground: prpm playground <package> "<input>"');
|
|
144
|
-
console.log(' - Check credits anytime: prpm credits');
|
|
145
|
-
success = true;
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
console.log('\n\nā±ļø Subscription process timed out or was canceled.');
|
|
149
|
-
console.log('\nš” If you completed the subscription, run this to verify:');
|
|
150
|
-
console.log(' prpm credits');
|
|
151
|
-
console.log('\nš” Or visit your account settings:');
|
|
152
|
-
console.log(' https://prpm.dev/settings/billing');
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
catch (err) {
|
|
156
|
-
error = err instanceof Error ? err.message : String(err);
|
|
157
|
-
console.error(`\nā Subscription failed: ${error}`);
|
|
158
|
-
throw new errors_1.CLIError(`\nā Subscription failed: ${error}`, 1);
|
|
159
|
-
}
|
|
160
|
-
finally {
|
|
161
|
-
await telemetry_1.telemetry.track({
|
|
162
|
-
command: 'subscribe',
|
|
163
|
-
success,
|
|
164
|
-
error,
|
|
165
|
-
duration: Date.now() - startTime,
|
|
166
|
-
});
|
|
167
|
-
await telemetry_1.telemetry.shutdown();
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Create the subscribe command
|
|
172
|
-
*/
|
|
173
|
-
function createSubscribeCommand() {
|
|
174
|
-
const command = new commander_1.Command('subscribe');
|
|
175
|
-
command
|
|
176
|
-
.description('Subscribe to PRPM+ for monthly playground credits and benefits')
|
|
177
|
-
.addHelpText('after', `
|
|
178
|
-
PRPM+ Benefits:
|
|
179
|
-
⨠100 monthly playground credits (worth $6+ in API costs)
|
|
180
|
-
ā»ļø Rollover unused credits up to 200 (1-month expiry)
|
|
181
|
-
š¦ Priority support and bug fixes
|
|
182
|
-
š Early access to new features
|
|
183
|
-
š¬ Access to PRPM+ community
|
|
184
|
-
|
|
185
|
-
Pricing:
|
|
186
|
-
Individual: $6/month
|
|
187
|
-
Organization: $3/month (50% discount for verified org members)
|
|
188
|
-
|
|
189
|
-
How it works:
|
|
190
|
-
1. Opens subscription page in your browser
|
|
191
|
-
2. Complete payment with Stripe
|
|
192
|
-
3. Credits are added automatically
|
|
193
|
-
4. Start testing packages immediately
|
|
194
|
-
|
|
195
|
-
Examples:
|
|
196
|
-
# Subscribe to PRPM+
|
|
197
|
-
$ prpm subscribe
|
|
198
|
-
|
|
199
|
-
# After subscribing, check your credits
|
|
200
|
-
$ prpm credits
|
|
201
|
-
|
|
202
|
-
# Test packages in playground
|
|
203
|
-
$ prpm playground @anthropic/assistant "Help me brainstorm ideas"
|
|
204
|
-
|
|
205
|
-
Note: You can cancel anytime from https://prpm.dev/settings/billing
|
|
206
|
-
`)
|
|
207
|
-
.action(async () => {
|
|
208
|
-
await handleSubscribe();
|
|
209
|
-
});
|
|
210
|
-
return command;
|
|
211
|
-
}
|
|
@@ -1,104 +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
|
-
const errors_1 = require("../core/errors");
|
|
7
|
-
function createTelemetryCommand() {
|
|
8
|
-
return new commander_1.Command('telemetry')
|
|
9
|
-
.description('Manage telemetry and analytics settings')
|
|
10
|
-
.addCommand(createStatusCommand(), { hidden: true })
|
|
11
|
-
.addCommand(createEnableCommand())
|
|
12
|
-
.addCommand(createDisableCommand())
|
|
13
|
-
.addCommand(createStatsCommand(), { hidden: true })
|
|
14
|
-
.addCommand(createTestCommand(), { hidden: true });
|
|
15
|
-
}
|
|
16
|
-
function createStatusCommand() {
|
|
17
|
-
return new commander_1.Command('status')
|
|
18
|
-
.description('Show current telemetry status')
|
|
19
|
-
.action(async () => {
|
|
20
|
-
const enabled = await telemetry_1.telemetry.isEnabled();
|
|
21
|
-
const stats = await telemetry_1.telemetry.getStats();
|
|
22
|
-
console.log('š Telemetry Status:');
|
|
23
|
-
console.log(` Status: ${enabled ? 'ā
Enabled' : 'ā Disabled'}`);
|
|
24
|
-
console.log(` Analytics: š PostHog`);
|
|
25
|
-
console.log(` Total events: ${stats.totalEvents}`);
|
|
26
|
-
if (stats.lastEvent) {
|
|
27
|
-
console.log(` Last event: ${stats.lastEvent}`);
|
|
28
|
-
}
|
|
29
|
-
if (enabled) {
|
|
30
|
-
console.log('\nš” Telemetry helps us improve the tool by collecting anonymous usage data.');
|
|
31
|
-
console.log(' Data is sent to PostHog for analysis.');
|
|
32
|
-
console.log(' Run "prpm telemetry disable" to opt out.');
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
console.log('\nš” Telemetry is disabled. Run "prpm telemetry enable" to help improve the tool.');
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
function createEnableCommand() {
|
|
40
|
-
return new commander_1.Command('enable')
|
|
41
|
-
.description('Enable telemetry and analytics')
|
|
42
|
-
.action(async () => {
|
|
43
|
-
await telemetry_1.telemetry.enable();
|
|
44
|
-
console.log('ā
Telemetry enabled');
|
|
45
|
-
console.log('š Anonymous usage data will be collected to help improve the tool.');
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
function createDisableCommand() {
|
|
49
|
-
return new commander_1.Command('disable')
|
|
50
|
-
.description('Disable telemetry and analytics')
|
|
51
|
-
.action(async () => {
|
|
52
|
-
await telemetry_1.telemetry.disable();
|
|
53
|
-
console.log('ā Telemetry disabled');
|
|
54
|
-
console.log('š No usage data will be collected.');
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
function createStatsCommand() {
|
|
58
|
-
return new commander_1.Command('stats')
|
|
59
|
-
.description('Show telemetry statistics')
|
|
60
|
-
.action(async () => {
|
|
61
|
-
const stats = await telemetry_1.telemetry.getStats();
|
|
62
|
-
console.log('š Telemetry Statistics:');
|
|
63
|
-
console.log(` Total events: ${stats.totalEvents}`);
|
|
64
|
-
if (stats.lastEvent) {
|
|
65
|
-
console.log(` Last event: ${stats.lastEvent}`);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
function createTestCommand() {
|
|
70
|
-
return new commander_1.Command('test')
|
|
71
|
-
.description('Send a test event to PostHog')
|
|
72
|
-
.action(async () => {
|
|
73
|
-
console.log('š§Ŗ Sending test event to PostHog...');
|
|
74
|
-
try {
|
|
75
|
-
await telemetry_1.telemetry.track({
|
|
76
|
-
command: 'test',
|
|
77
|
-
success: true,
|
|
78
|
-
duration: 100,
|
|
79
|
-
data: {
|
|
80
|
-
testType: 'manual',
|
|
81
|
-
message: 'This is a test event from PPM CLI',
|
|
82
|
-
timestamp: new Date().toISOString(),
|
|
83
|
-
uniqueId: Math.random().toString(36).substring(7),
|
|
84
|
-
},
|
|
85
|
-
});
|
|
86
|
-
console.log('ā
Test event sent successfully!');
|
|
87
|
-
console.log('š Check your PostHog dashboard for the event: prpm_test');
|
|
88
|
-
console.log('š Dashboard: https://app.posthog.com');
|
|
89
|
-
console.log('ā° Note: Events may take 1-2 minutes to appear in the dashboard');
|
|
90
|
-
// Wait a moment for the event to be sent
|
|
91
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
92
|
-
const stats = await telemetry_1.telemetry.getStats();
|
|
93
|
-
console.log(`š Total events now: ${stats.totalEvents}`);
|
|
94
|
-
console.log('\nš Troubleshooting tips:');
|
|
95
|
-
console.log('1. Check the "Live Events" section in PostHog');
|
|
96
|
-
console.log('2. Look for events with name "prpm_test"');
|
|
97
|
-
console.log('3. Make sure you\'re in the correct PostHog project');
|
|
98
|
-
console.log('4. Events may take 1-2 minutes to appear');
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
throw new errors_1.CLIError(`ā Failed to send test event: ${error}`, 1);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
}
|
|
@@ -1,86 +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
|
-
const errors_1 = require("../core/errors");
|
|
13
|
-
async function handleTrending(options) {
|
|
14
|
-
const startTime = Date.now();
|
|
15
|
-
let success = false;
|
|
16
|
-
let error;
|
|
17
|
-
try {
|
|
18
|
-
console.log(`š„ Fetching trending packages...`);
|
|
19
|
-
const config = await (0, user_config_1.getConfig)();
|
|
20
|
-
const client = (0, registry_client_1.getRegistryClient)(config);
|
|
21
|
-
const packages = await client.getTrending(options.format, options.subtype, options.limit || 10);
|
|
22
|
-
if (packages.length === 0) {
|
|
23
|
-
console.log('\nā No trending packages found');
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
console.log(`\n⨠Trending packages (last 7 days):\n`);
|
|
27
|
-
packages.forEach((pkg, index) => {
|
|
28
|
-
const verified = pkg.verified ? 'ā' : ' ';
|
|
29
|
-
const rating = pkg.rating_average ? `ā ${pkg.rating_average.toFixed(1)}` : '';
|
|
30
|
-
const downloads = pkg.total_downloads >= 1000
|
|
31
|
-
? `${(pkg.total_downloads / 1000).toFixed(1)}k`
|
|
32
|
-
: pkg.total_downloads;
|
|
33
|
-
console.log(`${index + 1}. [${verified}] ${pkg.name} ${rating}`);
|
|
34
|
-
console.log(` ${pkg.description || 'No description'}`);
|
|
35
|
-
console.log(` š„ ${downloads} downloads`);
|
|
36
|
-
console.log();
|
|
37
|
-
});
|
|
38
|
-
console.log(`š” Install a package: prpm install <package-id>`);
|
|
39
|
-
success = true;
|
|
40
|
-
}
|
|
41
|
-
catch (err) {
|
|
42
|
-
error = err instanceof Error ? err.message : String(err);
|
|
43
|
-
console.error(`\nā Failed to fetch trending packages: ${error}`);
|
|
44
|
-
console.log(`\nš” Tip: Check your internet connection`);
|
|
45
|
-
throw new errors_1.CLIError(`\nā Failed to fetch trending packages: ${error}`, 1);
|
|
46
|
-
}
|
|
47
|
-
finally {
|
|
48
|
-
await telemetry_1.telemetry.track({
|
|
49
|
-
command: 'trending',
|
|
50
|
-
success,
|
|
51
|
-
error,
|
|
52
|
-
duration: Date.now() - startTime,
|
|
53
|
-
data: {
|
|
54
|
-
format: options.format,
|
|
55
|
-
subtype: options.subtype,
|
|
56
|
-
limit: options.limit || 10,
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
await telemetry_1.telemetry.shutdown();
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function createTrendingCommand() {
|
|
63
|
-
const command = new commander_1.Command('trending');
|
|
64
|
-
command
|
|
65
|
-
.description('Show trending packages')
|
|
66
|
-
.option('--format <format>', 'Filter by format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, generic)')
|
|
67
|
-
.option('--subtype <subtype>', 'Filter by subtype (rule, agent, skill, slash-command, prompt, workflow, tool, template, collection)')
|
|
68
|
-
.option('--limit <number>', 'Number of packages to show', '10')
|
|
69
|
-
.action(async (options) => {
|
|
70
|
-
const format = options.format;
|
|
71
|
-
const subtype = options.subtype;
|
|
72
|
-
const limit = options.limit ? parseInt(options.limit, 10) : 10;
|
|
73
|
-
const validFormats = ['cursor', 'claude', 'continue', 'windsurf', 'copilot', 'kiro', 'agents.md', 'generic', 'mcp'];
|
|
74
|
-
const validSubtypes = ['rule', 'agent', 'skill', 'slash-command', 'prompt', 'workflow', 'tool', 'template', 'collection'];
|
|
75
|
-
if (options.format && !validFormats.includes(format)) {
|
|
76
|
-
console.error(`ā Format must be one of: ${validFormats.join(', ')}`);
|
|
77
|
-
throw new errors_1.CLIError(`ā Format must be one of: ${validFormats.join(', ')}`, 1);
|
|
78
|
-
}
|
|
79
|
-
if (options.subtype && !validSubtypes.includes(subtype)) {
|
|
80
|
-
console.error(`ā Subtype must be one of: ${validSubtypes.join(', ')}`);
|
|
81
|
-
throw new errors_1.CLIError(`ā Subtype must be one of: ${validSubtypes.join(', ')}`, 1);
|
|
82
|
-
}
|
|
83
|
-
await handleTrending({ format, subtype, limit });
|
|
84
|
-
});
|
|
85
|
-
return command;
|
|
86
|
-
}
|
|
@@ -1,120 +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
|
-
const errors_1 = require("../core/errors");
|
|
13
|
-
/**
|
|
14
|
-
* Handle the uninstall command
|
|
15
|
-
*/
|
|
16
|
-
async function handleUninstall(name) {
|
|
17
|
-
try {
|
|
18
|
-
console.log(`šļø Uninstalling package: ${name}`);
|
|
19
|
-
// Remove from lockfile and get package info
|
|
20
|
-
const pkg = await (0, lockfile_1.removePackage)(name);
|
|
21
|
-
if (!pkg) {
|
|
22
|
-
throw new errors_1.CLIError(`ā Package "${name}" not found`, 1);
|
|
23
|
-
}
|
|
24
|
-
// Special handling for Claude hooks
|
|
25
|
-
if (pkg.format === 'claude' && pkg.subtype === 'hook' && pkg.hookMetadata) {
|
|
26
|
-
const settingsPath = pkg.installedPath || '.claude/settings.json';
|
|
27
|
-
try {
|
|
28
|
-
// Read settings.json
|
|
29
|
-
const settingsContent = await fs_1.promises.readFile(settingsPath, 'utf-8');
|
|
30
|
-
const settings = JSON.parse(settingsContent);
|
|
31
|
-
if (settings.hooks) {
|
|
32
|
-
let removedCount = 0;
|
|
33
|
-
// Remove hooks with matching hook ID from each event
|
|
34
|
-
for (const event of pkg.hookMetadata.events) {
|
|
35
|
-
if (settings.hooks[event]) {
|
|
36
|
-
const originalLength = settings.hooks[event].length;
|
|
37
|
-
settings.hooks[event] = settings.hooks[event].filter((hook) => hook.__prpm_hook_id !== pkg.hookMetadata.hookId);
|
|
38
|
-
const newLength = settings.hooks[event].length;
|
|
39
|
-
removedCount += originalLength - newLength;
|
|
40
|
-
// Clean up empty event arrays
|
|
41
|
-
if (settings.hooks[event].length === 0) {
|
|
42
|
-
delete settings.hooks[event];
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
// Write updated settings back
|
|
47
|
-
await fs_1.promises.writeFile(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
|
|
48
|
-
console.log(` šŖ Removed ${removedCount} hook(s) from ${settingsPath}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
const err = error;
|
|
53
|
-
if (err.code === 'ENOENT') {
|
|
54
|
-
console.warn(` ā ļø Settings file not found: ${settingsPath}`);
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
throw new Error(`Failed to remove hooks from settings: ${error}`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
console.log(`ā
Successfully uninstalled ${name}`);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
// Standard file/directory uninstall for non-hook packages
|
|
64
|
-
const packageName = (0, filesystem_1.stripAuthorNamespace)(name);
|
|
65
|
-
let targetPath;
|
|
66
|
-
if (pkg.installedPath) {
|
|
67
|
-
// Use the exact path where it was installed (from lock file)
|
|
68
|
-
targetPath = pkg.installedPath;
|
|
69
|
-
console.log(` š Using installation path from lock file: ${targetPath}`);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
// Fallback: warn user that installedPath is missing (shouldn't happen with recent installations)
|
|
73
|
-
console.warn(` ā ļø No installation path in lock file for ${name}`);
|
|
74
|
-
console.warn(` ā ļø This may indicate an old or corrupted lock file`);
|
|
75
|
-
throw new errors_1.CLIError(`Cannot uninstall ${name}: installation path unknown`, 1);
|
|
76
|
-
}
|
|
77
|
-
// Check if the target path is a directory or file and delete accordingly
|
|
78
|
-
try {
|
|
79
|
-
const stats = await fs_1.promises.stat(targetPath);
|
|
80
|
-
if (stats.isDirectory()) {
|
|
81
|
-
// Delete entire directory
|
|
82
|
-
await fs_1.promises.rm(targetPath, { recursive: true, force: true });
|
|
83
|
-
console.log(` šļø Deleted directory: ${targetPath}`);
|
|
84
|
-
}
|
|
85
|
-
else if (stats.isFile()) {
|
|
86
|
-
// Delete single file
|
|
87
|
-
await fs_1.promises.unlink(targetPath);
|
|
88
|
-
console.log(` šļø Deleted file: ${targetPath}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
const err = error;
|
|
93
|
-
if (err.code === 'ENOENT') {
|
|
94
|
-
console.warn(` ā ļø File/directory not found: ${targetPath}`);
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
throw err;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
console.log(`ā
Successfully uninstalled ${name}`);
|
|
101
|
-
}
|
|
102
|
-
catch (error) {
|
|
103
|
-
if (error instanceof errors_1.CLIError) {
|
|
104
|
-
throw error;
|
|
105
|
-
}
|
|
106
|
-
throw new errors_1.CLIError(`ā Failed to uninstall package: ${error}`, 1);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Create the uninstall command
|
|
111
|
-
*/
|
|
112
|
-
function createUninstallCommand() {
|
|
113
|
-
const command = new commander_1.Command('uninstall');
|
|
114
|
-
command
|
|
115
|
-
.description('Uninstall a prompt package')
|
|
116
|
-
.argument('<id>', 'Package ID to uninstall')
|
|
117
|
-
.alias('remove') // Keep 'remove' as an alias for backwards compatibility
|
|
118
|
-
.action(handleUninstall);
|
|
119
|
-
return command;
|
|
120
|
-
}
|
package/dist/commands/update.js
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Update command - Update packages to latest compatible versions
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.handleUpdate = handleUpdate;
|
|
7
|
-
exports.createUpdateCommand = createUpdateCommand;
|
|
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 lockfile_1 = require("../core/lockfile");
|
|
12
|
-
const install_1 = require("./install");
|
|
13
|
-
const telemetry_1 = require("../core/telemetry");
|
|
14
|
-
const errors_1 = require("../core/errors");
|
|
15
|
-
/**
|
|
16
|
-
* Update packages to latest minor/patch versions
|
|
17
|
-
*/
|
|
18
|
-
async function handleUpdate(packageName, options = {}) {
|
|
19
|
-
const startTime = Date.now();
|
|
20
|
-
let success = false;
|
|
21
|
-
let error;
|
|
22
|
-
let updatedCount = 0;
|
|
23
|
-
try {
|
|
24
|
-
const config = await (0, user_config_1.getConfig)();
|
|
25
|
-
const client = (0, registry_client_1.getRegistryClient)(config);
|
|
26
|
-
const installedPackages = await (0, lockfile_1.listPackages)();
|
|
27
|
-
if (installedPackages.length === 0) {
|
|
28
|
-
console.log('No packages installed.');
|
|
29
|
-
success = true;
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
// Determine which packages to update
|
|
33
|
-
let packagesToUpdate = installedPackages;
|
|
34
|
-
if (packageName) {
|
|
35
|
-
// Update specific package
|
|
36
|
-
packagesToUpdate = installedPackages.filter(p => p.id === packageName);
|
|
37
|
-
if (packagesToUpdate.length === 0) {
|
|
38
|
-
throw new Error(`Package ${packageName} is not installed`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
console.log('š Checking for updates...\n');
|
|
42
|
-
for (const pkg of packagesToUpdate) {
|
|
43
|
-
try {
|
|
44
|
-
// Get package info from registry
|
|
45
|
-
const registryPkg = await client.getPackage(pkg.id);
|
|
46
|
-
if (!registryPkg.latest_version || !pkg.version) {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
const currentVersion = pkg.version;
|
|
50
|
-
const latestVersion = registryPkg.latest_version.version;
|
|
51
|
-
// Only update if it's a minor or patch update (not major)
|
|
52
|
-
const updateType = getUpdateType(currentVersion, latestVersion);
|
|
53
|
-
if (updateType === 'major') {
|
|
54
|
-
console.log(`āļø Skipping ${pkg.id} (major update ${currentVersion} ā ${latestVersion}, use upgrade)`);
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
if (currentVersion === latestVersion) {
|
|
58
|
-
console.log(`ā
${pkg.id} is already up to date (${currentVersion})`);
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
console.log(`\nš¦ Updating ${pkg.id}: ${currentVersion} ā ${latestVersion}`);
|
|
62
|
-
// Install new version
|
|
63
|
-
await (0, install_1.handleInstall)(`${pkg.id}@${latestVersion}`, {});
|
|
64
|
-
updatedCount++;
|
|
65
|
-
}
|
|
66
|
-
catch (err) {
|
|
67
|
-
console.error(` ā Failed to update ${pkg.id}: ${err instanceof Error ? err.message : String(err)}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
if (updatedCount === 0) {
|
|
71
|
-
console.log('\nā
All packages are up to date!\n');
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
console.log(`\nā
Updated ${updatedCount} package(s)\n`);
|
|
75
|
-
}
|
|
76
|
-
success = true;
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
error = err instanceof Error ? err.message : String(err);
|
|
80
|
-
throw new errors_1.CLIError(`\nā Update failed: ${error}`, 1);
|
|
81
|
-
}
|
|
82
|
-
finally {
|
|
83
|
-
await telemetry_1.telemetry.track({
|
|
84
|
-
command: 'update',
|
|
85
|
-
success,
|
|
86
|
-
error,
|
|
87
|
-
duration: Date.now() - startTime,
|
|
88
|
-
data: {
|
|
89
|
-
packageName,
|
|
90
|
-
updatedCount,
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
await telemetry_1.telemetry.shutdown();
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Determine update type based on semver
|
|
98
|
-
*/
|
|
99
|
-
function getUpdateType(current, latest) {
|
|
100
|
-
const currentParts = current.split('.').map(Number);
|
|
101
|
-
const latestParts = latest.split('.').map(Number);
|
|
102
|
-
const [currMajor = 0, currMinor = 0, currPatch = 0] = currentParts;
|
|
103
|
-
const [latestMajor = 0, latestMinor = 0, latestPatch = 0] = latestParts;
|
|
104
|
-
if (latestMajor > currMajor)
|
|
105
|
-
return 'major';
|
|
106
|
-
if (latestMinor > currMinor)
|
|
107
|
-
return 'minor';
|
|
108
|
-
return 'patch';
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Create the update command
|
|
112
|
-
*/
|
|
113
|
-
function createUpdateCommand() {
|
|
114
|
-
return new commander_1.Command('update')
|
|
115
|
-
.description('Update packages to latest compatible versions (minor/patch only)')
|
|
116
|
-
.argument('[package]', 'Specific package to update (optional)')
|
|
117
|
-
.option('--all', 'Update all packages')
|
|
118
|
-
.action(async (packageName, options) => {
|
|
119
|
-
await handleUpdate(packageName, options);
|
|
120
|
-
});
|
|
121
|
-
}
|