prpm 0.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.
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ /**
3
+ * Login command implementation
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.handleLogin = handleLogin;
40
+ exports.createLoginCommand = createLoginCommand;
41
+ const commander_1 = require("commander");
42
+ const http_1 = require("http");
43
+ const telemetry_1 = require("../core/telemetry");
44
+ const user_config_1 = require("../core/user-config");
45
+ /**
46
+ * Start OAuth callback server
47
+ */
48
+ function startCallbackServer() {
49
+ return new Promise((resolve, reject) => {
50
+ const server = (0, http_1.createServer)((req, res) => {
51
+ const url = new URL(req.url || '', 'http://localhost:8765');
52
+ if (url.pathname === '/callback') {
53
+ const token = url.searchParams.get('token') || undefined;
54
+ const username = url.searchParams.get('username') || undefined;
55
+ const error = url.searchParams.get('error') || undefined;
56
+ if (error) {
57
+ res.writeHead(400, { 'Content-Type': 'text/html' });
58
+ res.end(`
59
+ <html>
60
+ <body>
61
+ <h1>āŒ Authentication Failed</h1>
62
+ <p>Error: ${error}</p>
63
+ <p>You can close this window.</p>
64
+ </body>
65
+ </html>
66
+ `);
67
+ server.close();
68
+ reject(new Error(`OAuth error: ${error}`));
69
+ return;
70
+ }
71
+ if (token) {
72
+ res.writeHead(200, { 'Content-Type': 'text/html' });
73
+ res.end(`
74
+ <html>
75
+ <body>
76
+ <h1>āœ… Authentication Successful!</h1>
77
+ <p>You can close this window and return to your terminal.</p>
78
+ </body>
79
+ </html>
80
+ `);
81
+ server.close();
82
+ resolve({ token, username });
83
+ }
84
+ else {
85
+ res.writeHead(400, { 'Content-Type': 'text/html' });
86
+ res.end(`
87
+ <html>
88
+ <body>
89
+ <h1>āŒ Invalid Request</h1>
90
+ <p>No token received from authentication.</p>
91
+ </body>
92
+ </html>
93
+ `);
94
+ server.close();
95
+ reject(new Error('No token received'));
96
+ }
97
+ }
98
+ });
99
+ server.listen(8765, () => {
100
+ console.log(' Waiting for authentication...');
101
+ });
102
+ // Timeout after 5 minutes
103
+ setTimeout(() => {
104
+ server.close();
105
+ reject(new Error('Authentication timeout'));
106
+ }, 5 * 60 * 1000);
107
+ });
108
+ }
109
+ /**
110
+ * Login with GitHub OAuth
111
+ */
112
+ async function loginWithOAuth(registryUrl) {
113
+ console.log('\nšŸ” Opening browser for GitHub authentication...\n');
114
+ // Open browser to registry OAuth page with CLI redirect
115
+ const callbackUrl = 'http://localhost:8765/callback';
116
+ const authUrl = `${registryUrl}/api/v1/auth/github?redirect=${encodeURIComponent(callbackUrl)}`;
117
+ console.log(` If browser doesn't open, visit: ${authUrl}\n`);
118
+ // Try to open browser
119
+ const { exec } = await Promise.resolve().then(() => __importStar(require('child_process')));
120
+ const platform = process.platform;
121
+ const cmd = platform === 'darwin' ? 'open' : platform === 'win32' ? 'start' : 'xdg-open';
122
+ exec(`${cmd} "${authUrl}"`);
123
+ // Start callback server and receive token directly
124
+ console.log(' Waiting for authentication...\n');
125
+ const result = await startCallbackServer();
126
+ if (!result.token) {
127
+ throw new Error('No token received from authentication');
128
+ }
129
+ // Extract username from token if not provided
130
+ let username = result.username || '';
131
+ if (!username) {
132
+ // Decode JWT to get username (basic JWT decode without verification)
133
+ try {
134
+ const payload = JSON.parse(Buffer.from(result.token.split('.')[1], 'base64').toString());
135
+ username = payload.username || 'unknown';
136
+ }
137
+ catch (e) {
138
+ username = 'unknown';
139
+ }
140
+ }
141
+ return { token: result.token, username: username || 'unknown' };
142
+ }
143
+ /**
144
+ * Login with manual token
145
+ */
146
+ async function loginWithToken(token, registryUrl) {
147
+ // Verify token by making a request to /api/v1/user
148
+ const response = await fetch(`${registryUrl}/api/v1/user`, {
149
+ headers: {
150
+ 'Authorization': `Bearer ${token}`,
151
+ },
152
+ });
153
+ if (!response.ok) {
154
+ throw new Error('Invalid token');
155
+ }
156
+ const user = await response.json();
157
+ return { token, username: user.username };
158
+ }
159
+ /**
160
+ * Handle login command
161
+ */
162
+ async function handleLogin(options) {
163
+ const startTime = Date.now();
164
+ let success = false;
165
+ let error;
166
+ try {
167
+ const config = await (0, user_config_1.getConfig)();
168
+ const registryUrl = config.registryUrl || 'https://registry.prpm.dev';
169
+ console.log('šŸ”‘ PRMP Login\n');
170
+ let result;
171
+ if (options.token) {
172
+ // Manual token login
173
+ console.log('šŸ” Logging in with provided token...\n');
174
+ result = await loginWithToken(options.token, registryUrl);
175
+ }
176
+ else {
177
+ // OAuth login
178
+ result = await loginWithOAuth(registryUrl);
179
+ }
180
+ // Save token to config
181
+ await (0, user_config_1.saveConfig)({
182
+ ...config,
183
+ token: result.token,
184
+ username: result.username,
185
+ });
186
+ console.log('āœ… Successfully logged in!\n');
187
+ console.log(` Username: ${result.username}`);
188
+ console.log(` Registry: ${registryUrl}\n`);
189
+ console.log('šŸ’” You can now publish packages with "prpm publish"\n');
190
+ success = true;
191
+ }
192
+ catch (err) {
193
+ error = err instanceof Error ? err.message : String(err);
194
+ console.error(`\nāŒ Login failed: ${error}\n`);
195
+ console.error('šŸ’” Try again or use "prpm login --token YOUR_TOKEN"\n');
196
+ process.exit(1);
197
+ }
198
+ finally {
199
+ // Track telemetry
200
+ await telemetry_1.telemetry.track({
201
+ command: 'login',
202
+ success,
203
+ error,
204
+ duration: Date.now() - startTime,
205
+ data: {
206
+ method: options.token ? 'token' : 'oauth',
207
+ },
208
+ });
209
+ }
210
+ }
211
+ /**
212
+ * Create the login command
213
+ */
214
+ function createLoginCommand() {
215
+ return new commander_1.Command('login')
216
+ .description('Login to the PRMP registry')
217
+ .option('--token <token>', 'Login with a personal access token')
218
+ .action(handleLogin);
219
+ }
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ /**
3
+ * Outdated command - Check for package updates
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleOutdated = handleOutdated;
7
+ exports.createOutdatedCommand = createOutdatedCommand;
8
+ const commander_1 = require("commander");
9
+ const registry_client_1 = require("@prpm/registry-client");
10
+ const user_config_1 = require("../core/user-config");
11
+ const config_1 = require("../core/config");
12
+ const telemetry_1 = require("../core/telemetry");
13
+ /**
14
+ * Check for outdated packages
15
+ */
16
+ async function handleOutdated() {
17
+ const startTime = Date.now();
18
+ let success = false;
19
+ let error;
20
+ try {
21
+ console.log('šŸ” Checking for package updates...\n');
22
+ const config = await (0, user_config_1.getConfig)();
23
+ const client = (0, registry_client_1.getRegistryClient)(config);
24
+ const installedPackages = await (0, config_1.listPackages)();
25
+ if (installedPackages.length === 0) {
26
+ console.log('No packages installed.');
27
+ success = true;
28
+ return;
29
+ }
30
+ const outdated = [];
31
+ for (const pkg of installedPackages) {
32
+ try {
33
+ // Get package info from registry
34
+ const registryPkg = await client.getPackage(pkg.id);
35
+ if (!registryPkg.latest_version || !pkg.version) {
36
+ continue;
37
+ }
38
+ const currentVersion = pkg.version;
39
+ const latestVersion = registryPkg.latest_version.version;
40
+ // Check if update available
41
+ if (currentVersion !== latestVersion) {
42
+ const updateType = getUpdateType(currentVersion, latestVersion);
43
+ outdated.push({
44
+ id: pkg.id,
45
+ current: currentVersion,
46
+ latest: latestVersion,
47
+ type: updateType,
48
+ });
49
+ }
50
+ }
51
+ catch (err) {
52
+ // Skip packages that can't be found in registry
53
+ continue;
54
+ }
55
+ }
56
+ if (outdated.length === 0) {
57
+ console.log('āœ… All packages are up to date!\n');
58
+ success = true;
59
+ return;
60
+ }
61
+ // Display outdated packages
62
+ console.log(`šŸ“¦ ${outdated.length} package(s) have updates available:\n`);
63
+ // Group by update type
64
+ const major = outdated.filter(p => p.type === 'major');
65
+ const minor = outdated.filter(p => p.type === 'minor');
66
+ const patch = outdated.filter(p => p.type === 'patch');
67
+ if (major.length > 0) {
68
+ console.log('šŸ”“ Major Updates (breaking changes possible):');
69
+ major.forEach(pkg => {
70
+ console.log(` ${pkg.id.padEnd(30)} ${pkg.current} → ${pkg.latest}`);
71
+ });
72
+ console.log('');
73
+ }
74
+ if (minor.length > 0) {
75
+ console.log('🟔 Minor Updates (new features):');
76
+ minor.forEach(pkg => {
77
+ console.log(` ${pkg.id.padEnd(30)} ${pkg.current} → ${pkg.latest}`);
78
+ });
79
+ console.log('');
80
+ }
81
+ if (patch.length > 0) {
82
+ console.log('🟢 Patch Updates (bug fixes):');
83
+ patch.forEach(pkg => {
84
+ console.log(` ${pkg.id.padEnd(30)} ${pkg.current} → ${pkg.latest}`);
85
+ });
86
+ console.log('');
87
+ }
88
+ console.log('šŸ’” Run "prpm update" to update to latest minor/patch versions');
89
+ console.log('šŸ’” Run "prpm upgrade" to upgrade to latest major versions\n');
90
+ success = true;
91
+ }
92
+ catch (err) {
93
+ error = err instanceof Error ? err.message : String(err);
94
+ console.error(`\nāŒ Failed to check for updates: ${error}`);
95
+ process.exit(1);
96
+ }
97
+ finally {
98
+ await telemetry_1.telemetry.track({
99
+ command: 'outdated',
100
+ success,
101
+ error,
102
+ duration: Date.now() - startTime,
103
+ });
104
+ }
105
+ }
106
+ /**
107
+ * Determine update type based on semver
108
+ */
109
+ function getUpdateType(current, latest) {
110
+ const currentParts = current.split('.').map(Number);
111
+ const latestParts = latest.split('.').map(Number);
112
+ const [currMajor = 0, currMinor = 0, currPatch = 0] = currentParts;
113
+ const [latestMajor = 0, latestMinor = 0, latestPatch = 0] = latestParts;
114
+ if (latestMajor > currMajor)
115
+ return 'major';
116
+ if (latestMinor > currMinor)
117
+ return 'minor';
118
+ return 'patch';
119
+ }
120
+ /**
121
+ * Create the outdated command
122
+ */
123
+ function createOutdatedCommand() {
124
+ return new commander_1.Command('outdated')
125
+ .description('Check for package updates')
126
+ .action(handleOutdated);
127
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /**
3
+ * Popular packages command implementation
4
+ * Shows all-time popular packages (delegates to trending)
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.handlePopular = handlePopular;
8
+ exports.createPopularCommand = createPopularCommand;
9
+ const commander_1 = require("commander");
10
+ const trending_1 = require("./trending");
11
+ /**
12
+ * Show popular packages (wrapper around trending)
13
+ */
14
+ async function handlePopular(options) {
15
+ // Delegate to trending command
16
+ console.log('šŸ“Š Popular Packages (All Time)\n');
17
+ await (0, trending_1.handleTrending)({ type: options.type });
18
+ }
19
+ /**
20
+ * Create the popular command
21
+ */
22
+ function createPopularCommand() {
23
+ return new commander_1.Command('popular')
24
+ .description('Show popular packages (all time)')
25
+ .option('-t, --type <type>', 'Filter by package type (cursor, claude, continue, windsurf)')
26
+ .action(handlePopular);
27
+ }
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ /**
3
+ * Publish command implementation
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.handlePublish = handlePublish;
40
+ exports.createPublishCommand = createPublishCommand;
41
+ const commander_1 = require("commander");
42
+ const promises_1 = require("fs/promises");
43
+ const path_1 = require("path");
44
+ const tar = __importStar(require("tar"));
45
+ const os_1 = require("os");
46
+ const crypto_1 = require("crypto");
47
+ const registry_client_1 = require("@prpm/registry-client");
48
+ const user_config_1 = require("../core/user-config");
49
+ const telemetry_1 = require("../core/telemetry");
50
+ /**
51
+ * Validate package manifest
52
+ */
53
+ async function validateManifest(manifestPath) {
54
+ try {
55
+ const content = await (0, promises_1.readFile)(manifestPath, 'utf-8');
56
+ const manifest = JSON.parse(content);
57
+ // Required fields
58
+ const required = ['name', 'version', 'description', 'type'];
59
+ const missing = required.filter(field => !manifest[field]);
60
+ if (missing.length > 0) {
61
+ throw new Error(`Missing required fields: ${missing.join(', ')}`);
62
+ }
63
+ // Validate name format
64
+ if (!/^(@[a-z0-9-]+\/)?[a-z0-9-]+$/.test(manifest.name)) {
65
+ throw new Error('Package name must be lowercase alphanumeric with hyphens only');
66
+ }
67
+ // Validate version format
68
+ if (!/^\d+\.\d+\.\d+/.test(manifest.version)) {
69
+ throw new Error('Version must be semver format (e.g., 1.0.0)');
70
+ }
71
+ // Validate type
72
+ const validTypes = ['cursor', 'claude', 'continue', 'windsurf', 'generic'];
73
+ if (!validTypes.includes(manifest.type)) {
74
+ throw new Error(`Type must be one of: ${validTypes.join(', ')}`);
75
+ }
76
+ return manifest;
77
+ }
78
+ catch (error) {
79
+ if (error instanceof Error && error.message.includes('ENOENT')) {
80
+ throw new Error('prpm.json not found. Run this command in your package directory.');
81
+ }
82
+ throw error;
83
+ }
84
+ }
85
+ /**
86
+ * Create tarball from current directory
87
+ */
88
+ async function createTarball(manifest) {
89
+ const tmpDir = (0, path_1.join)((0, os_1.tmpdir)(), `prpm-${(0, crypto_1.randomBytes)(8).toString('hex')}`);
90
+ const tarballPath = (0, path_1.join)(tmpDir, 'package.tar.gz');
91
+ try {
92
+ // Get files to include (from manifest.files or default)
93
+ const files = manifest.files || [
94
+ 'prpm.json',
95
+ '.cursorrules',
96
+ 'README.md',
97
+ 'LICENSE',
98
+ '.clinerules',
99
+ '.continuerc.json',
100
+ '.windsurfrules'
101
+ ];
102
+ // Check which files exist
103
+ const existingFiles = [];
104
+ for (const file of files) {
105
+ try {
106
+ await (0, promises_1.stat)(file);
107
+ existingFiles.push(file);
108
+ }
109
+ catch {
110
+ // File doesn't exist, skip
111
+ }
112
+ }
113
+ if (existingFiles.length === 0) {
114
+ throw new Error('No package files found to include in tarball');
115
+ }
116
+ // Create tarball
117
+ await tar.create({
118
+ gzip: true,
119
+ file: tarballPath,
120
+ cwd: process.cwd(),
121
+ }, existingFiles);
122
+ // Read tarball into buffer
123
+ const tarballBuffer = await (0, promises_1.readFile)(tarballPath);
124
+ // Check size (max 10MB)
125
+ const sizeMB = tarballBuffer.length / (1024 * 1024);
126
+ if (sizeMB > 10) {
127
+ throw new Error(`Package size (${sizeMB.toFixed(2)}MB) exceeds 10MB limit`);
128
+ }
129
+ return tarballBuffer;
130
+ }
131
+ catch (error) {
132
+ throw error;
133
+ }
134
+ }
135
+ /**
136
+ * Publish a package to the registry
137
+ */
138
+ async function handlePublish(options) {
139
+ const startTime = Date.now();
140
+ let success = false;
141
+ let error;
142
+ let packageName;
143
+ let version;
144
+ try {
145
+ const config = await (0, user_config_1.getConfig)();
146
+ // Check if logged in
147
+ if (!config.token) {
148
+ console.error('āŒ Not logged in. Run "prpm login" first.');
149
+ process.exit(1);
150
+ }
151
+ console.log('šŸ“¦ Publishing package...\n');
152
+ // Read and validate manifest
153
+ console.log('šŸ” Validating package manifest...');
154
+ const manifestPath = (0, path_1.join)(process.cwd(), 'prpm.json');
155
+ const manifest = await validateManifest(manifestPath);
156
+ packageName = manifest.name;
157
+ version = manifest.version;
158
+ console.log(` Package: ${manifest.name}@${manifest.version}`);
159
+ console.log(` Type: ${manifest.type}`);
160
+ console.log(` Description: ${manifest.description}`);
161
+ console.log('');
162
+ // Create tarball
163
+ console.log('šŸ“¦ Creating package tarball...');
164
+ const tarball = await createTarball(manifest);
165
+ const sizeMB = (tarball.length / (1024 * 1024)).toFixed(2);
166
+ console.log(` Size: ${sizeMB}MB`);
167
+ console.log('');
168
+ if (options.dryRun) {
169
+ console.log('āœ… Dry run successful! Package is ready to publish.');
170
+ console.log(' Run without --dry-run to publish.');
171
+ success = true;
172
+ return;
173
+ }
174
+ // Publish to registry
175
+ console.log('šŸš€ Publishing to registry...');
176
+ const client = (0, registry_client_1.getRegistryClient)(config);
177
+ const result = await client.publish(manifest, tarball);
178
+ console.log('');
179
+ console.log('āœ… Package published successfully!');
180
+ console.log('');
181
+ console.log(` Package: ${result.name}@${result.version}`);
182
+ console.log(` Install: prpm install ${result.name}`);
183
+ console.log(` View: ${config.registryUrl}/packages/${result.id}`);
184
+ console.log('');
185
+ success = true;
186
+ }
187
+ catch (err) {
188
+ error = err instanceof Error ? err.message : String(err);
189
+ console.error(`\nāŒ Failed to publish package: ${error}\n`);
190
+ process.exit(1);
191
+ }
192
+ finally {
193
+ // Track telemetry
194
+ await telemetry_1.telemetry.track({
195
+ command: 'publish',
196
+ success,
197
+ error,
198
+ duration: Date.now() - startTime,
199
+ data: {
200
+ packageName,
201
+ version,
202
+ dryRun: options.dryRun,
203
+ },
204
+ });
205
+ }
206
+ }
207
+ /**
208
+ * Create the publish command
209
+ */
210
+ function createPublishCommand() {
211
+ return new commander_1.Command('publish')
212
+ .description('Publish a package to the registry')
213
+ .option('--access <type>', 'Package access (public or private)', 'public')
214
+ .option('--tag <tag>', 'NPM-style tag (e.g., latest, beta)', 'latest')
215
+ .option('--dry-run', 'Validate package without publishing')
216
+ .action(handlePublish);
217
+ }
@@ -0,0 +1,43 @@
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 config_1 = require("../core/config");
10
+ const filesystem_1 = require("../core/filesystem");
11
+ /**
12
+ * Handle the remove command
13
+ */
14
+ async function handleRemove(id) {
15
+ try {
16
+ console.log(`šŸ—‘ļø Removing package: ${id}`);
17
+ // Remove from config and get package info
18
+ const pkg = await (0, config_1.removePackage)(id);
19
+ if (!pkg) {
20
+ console.error(`āŒ Package "${id}" not found`);
21
+ process.exit(1);
22
+ }
23
+ // Delete the file
24
+ console.log(`šŸ“ Deleting file: ${pkg.dest}`);
25
+ await (0, filesystem_1.deleteFile)(pkg.dest);
26
+ console.log(`āœ… Successfully removed ${id} (${pkg.type})`);
27
+ }
28
+ catch (error) {
29
+ console.error(`āŒ Failed to remove package: ${error}`);
30
+ process.exit(1);
31
+ }
32
+ }
33
+ /**
34
+ * Create the remove command
35
+ */
36
+ function createRemoveCommand() {
37
+ const command = new commander_1.Command('remove');
38
+ command
39
+ .description('Remove a prompt package')
40
+ .argument('<id>', 'Package ID to remove')
41
+ .action(handleRemove);
42
+ return command;
43
+ }