prpm 0.1.10 → 0.1.12

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.
@@ -10,6 +10,7 @@ const registry_client_1 = require("@pr-pm/registry-client");
10
10
  const user_config_1 = require("../core/user-config");
11
11
  const lockfile_1 = require("../core/lockfile");
12
12
  const telemetry_1 = require("../core/telemetry");
13
+ const errors_1 = require("../core/errors");
13
14
  /**
14
15
  * Check for outdated packages
15
16
  */
@@ -91,8 +92,7 @@ async function handleOutdated() {
91
92
  }
92
93
  catch (err) {
93
94
  error = err instanceof Error ? err.message : String(err);
94
- console.error(`\n❌ Failed to check for updates: ${error}`);
95
- process.exit(1);
95
+ throw new errors_1.CLIError(`\n❌ Failed to check for updates: ${error}`, 1);
96
96
  }
97
97
  finally {
98
98
  await telemetry_1.telemetry.track({
@@ -126,6 +126,5 @@ function createOutdatedCommand() {
126
126
  .description('Check for package updates')
127
127
  .action(async () => {
128
128
  await handleOutdated();
129
- process.exit(0);
130
129
  });
131
130
  }
@@ -42,6 +42,7 @@ const commander_1 = require("commander");
42
42
  const user_config_1 = require("../core/user-config");
43
43
  const telemetry_1 = require("../core/telemetry");
44
44
  const readline = __importStar(require("readline"));
45
+ const errors_1 = require("../core/errors");
45
46
  /**
46
47
  * Create a readline interface for user input
47
48
  */
@@ -252,7 +253,7 @@ async function runSingle(packageName, input, options) {
252
253
  console.log(' - Subscribe to PRPM+: prpm subscribe');
253
254
  console.log(' - Check balance: prpm credits');
254
255
  }
255
- process.exit(1);
256
+ throw new errors_1.CLIError(`\n❌ Error: ${error instanceof Error ? error.message : String(error)}`, 1);
256
257
  }
257
258
  }
258
259
  /**
@@ -269,7 +270,7 @@ async function handlePlayground(packageName, input, options) {
269
270
  console.error('❌ Authentication required');
270
271
  console.log('\n💡 Please login first:');
271
272
  console.log(' prpm login');
272
- process.exit(1);
273
+ throw new errors_1.CLIError('❌ Authentication required', 1);
273
274
  }
274
275
  // Interactive mode or single query
275
276
  if (options.interactive || !input) {
@@ -285,7 +286,7 @@ async function handlePlayground(packageName, input, options) {
285
286
  catch (err) {
286
287
  error = err instanceof Error ? err.message : String(err);
287
288
  console.error(`\n❌ Playground execution failed: ${error}`);
288
- process.exit(1);
289
+ throw new errors_1.CLIError(`\n❌ Playground execution failed: ${error}`, 1);
289
290
  }
290
291
  finally {
291
292
  await telemetry_1.telemetry.track({
@@ -345,7 +346,6 @@ Note: Playground usage requires credits. Run 'prpm credits' to check balance.
345
346
  `)
346
347
  .action(async (packageName, input, options) => {
347
348
  await handlePlayground(packageName, input, options);
348
- process.exit(0);
349
349
  });
350
350
  return command;
351
351
  }
@@ -29,6 +29,5 @@ function createPopularCommand() {
29
29
  .option('--subtype <subtype>', 'Filter by subtype (rule, agent, skill, slash-command, prompt, workflow, tool, template, collection)')
30
30
  .action(async (options) => {
31
31
  await handlePopular(options);
32
- process.exit(0);
33
32
  });
34
33
  }
@@ -47,6 +47,7 @@ const crypto_1 = require("crypto");
47
47
  const registry_client_1 = require("@pr-pm/registry-client");
48
48
  const user_config_1 = require("../core/user-config");
49
49
  const telemetry_1 = require("../core/telemetry");
50
+ const errors_1 = require("../core/errors");
50
51
  const marketplace_converter_1 = require("../core/marketplace-converter");
51
52
  const schema_validator_1 = require("../core/schema-validator");
52
53
  const license_extractor_1 = require("../utils/license-extractor");
@@ -65,6 +66,7 @@ async function findAndLoadManifests() {
65
66
  let prpmJsonError = null;
66
67
  try {
67
68
  const content = await (0, promises_1.readFile)(prpmJsonPath, 'utf-8');
69
+ prpmJsonExists = true; // Mark file as found after successful read
68
70
  const manifest = JSON.parse(content);
69
71
  // Extract collections if present
70
72
  const collections = [];
@@ -349,8 +351,7 @@ async function handlePublish(options) {
349
351
  const config = await (0, user_config_1.getConfig)();
350
352
  // Check if logged in
351
353
  if (!config.token) {
352
- console.error('❌ Not logged in. Run "prpm login" first.');
353
- process.exit(1);
354
+ throw new errors_1.CLIError('❌ Not logged in. Run "prpm login" first.', 1);
354
355
  }
355
356
  console.log('📦 Publishing package...\n');
356
357
  // Read and validate manifests
@@ -712,41 +713,41 @@ async function handlePublish(options) {
712
713
  // Success if we published any packages OR collections
713
714
  success = publishedPackages.length > 0 || publishedCollections.length > 0;
714
715
  if (failedPackages.length > 0 && publishedPackages.length === 0 && publishedCollections.length === 0) {
715
- process.exit(1);
716
+ // Use the first failed package's error for telemetry
717
+ const firstError = failedPackages[0]?.error || 'Unknown error';
718
+ throw new errors_1.CLIError(firstError, 1);
716
719
  }
717
720
  }
718
721
  catch (err) {
719
722
  error = err instanceof Error ? err.message : String(err);
720
- console.error(`\n❌ Failed to publish package: ${error}\n`);
723
+ if (err instanceof errors_1.CLIError) {
724
+ throw err;
725
+ }
726
+ let errorMsg = `\n❌ Failed to publish package: ${error}\n`;
721
727
  // Provide helpful hints based on error type
722
728
  if (error.includes('Manifest validation failed')) {
723
- console.log('💡 Common validation issues:');
724
- console.log(' - Missing required fields (name, version, description, format)');
725
- console.log(' - Invalid format or subtype values');
726
- console.log(' - Description too short (min 10 chars) or too long (max 500 chars)');
727
- console.log(' - Package name must be lowercase with hyphens only');
728
- console.log('');
729
- console.log('💡 For Claude skills specifically:');
730
- console.log(' - Add "subtype": "skill" to your prpm.json');
731
- console.log(' - Ensure files include a SKILL.md file');
732
- console.log(' - Package name must be max 64 characters');
733
- console.log('');
734
- console.log('💡 View the schema: prpm schema');
735
- console.log('');
729
+ errorMsg += '\n💡 Common validation issues:\n';
730
+ errorMsg += ' - Missing required fields (name, version, description, format)\n';
731
+ errorMsg += ' - Invalid format or subtype values\n';
732
+ errorMsg += ' - Description too short (min 10 chars) or too long (max 500 chars)\n';
733
+ errorMsg += ' - Package name must be lowercase with hyphens only\n';
734
+ errorMsg += '\n💡 For Claude skills specifically:\n';
735
+ errorMsg += ' - Add "subtype": "skill" to your prpm.json\n';
736
+ errorMsg += ' - Ensure files include a SKILL.md file\n';
737
+ errorMsg += ' - Package name must be max 64 characters\n';
738
+ errorMsg += '\n💡 View the schema: prpm schema\n';
736
739
  }
737
740
  else if (error.includes('SKILL.md')) {
738
- console.log('💡 Claude skills require:');
739
- console.log(' - A file named SKILL.md (all caps) in your package');
740
- console.log(' - "format": "claude" and "subtype": "skill" in prpm.json');
741
- console.log('');
741
+ errorMsg += '\n💡 Claude skills require:\n';
742
+ errorMsg += ' - A file named SKILL.md (all caps) in your package\n';
743
+ errorMsg += ' - "format": "claude" and "subtype": "skill" in prpm.json\n';
742
744
  }
743
745
  else if (error.includes('No manifest file found')) {
744
- console.log('💡 Create a manifest file:');
745
- console.log(' - Run: prpm init');
746
- console.log(' - Or create prpm.json manually');
747
- console.log('');
746
+ errorMsg += '\n💡 Create a manifest file:\n';
747
+ errorMsg += ' - Run: prpm init\n';
748
+ errorMsg += ' - Or create prpm.json manually\n';
748
749
  }
749
- process.exit(1);
750
+ throw new errors_1.CLIError(errorMsg, 1);
750
751
  }
751
752
  finally {
752
753
  // Track telemetry
@@ -777,6 +778,5 @@ function createPublishCommand() {
777
778
  .option('--collection <id>', 'Publish only a specific collection from manifest')
778
779
  .action(async (options) => {
779
780
  await handlePublish(options);
780
- process.exit(0);
781
781
  });
782
782
  }
@@ -7,6 +7,7 @@ exports.handleSchema = handleSchema;
7
7
  exports.createSchemaCommand = createSchemaCommand;
8
8
  const commander_1 = require("commander");
9
9
  const schema_validator_1 = require("../core/schema-validator");
10
+ const errors_1 = require("../core/errors");
10
11
  /**
11
12
  * Handle the schema command
12
13
  */
@@ -14,15 +15,16 @@ async function handleSchema() {
14
15
  try {
15
16
  const schema = (0, schema_validator_1.getManifestSchema)();
16
17
  if (!schema) {
17
- console.error('❌ Schema not available');
18
- process.exit(1);
18
+ throw new errors_1.CLIError('❌ Schema not available', 1);
19
19
  }
20
20
  // Output the schema as pretty-printed JSON
21
21
  console.log(JSON.stringify(schema, null, 2));
22
22
  }
23
23
  catch (error) {
24
- console.error(`❌ Failed to export schema: ${error}`);
25
- process.exit(1);
24
+ if (error instanceof errors_1.CLIError) {
25
+ throw error;
26
+ }
27
+ throw new errors_1.CLIError(`❌ Failed to export schema: ${error}`, 1);
26
28
  }
27
29
  }
28
30
  /**
@@ -34,7 +36,6 @@ function createSchemaCommand() {
34
36
  .description('Display the PRPM manifest JSON schema')
35
37
  .action(async () => {
36
38
  await handleSchema();
37
- process.exit(0);
38
39
  });
39
40
  return command;
40
41
  }
@@ -43,6 +43,7 @@ const registry_client_1 = require("@pr-pm/registry-client");
43
43
  const user_config_1 = require("../core/user-config");
44
44
  const telemetry_1 = require("../core/telemetry");
45
45
  const readline = __importStar(require("readline"));
46
+ const errors_1 = require("../core/errors");
46
47
  /**
47
48
  * Get icon for package format and subtype
48
49
  */
@@ -377,7 +378,7 @@ async function handleSearch(query, options) {
377
378
  console.log(`\n💡 Tip: You're using a local registry. Make sure it's running or update ~/.prpmrc`);
378
379
  console.log(` To use the production registry, remove the registryUrl from ~/.prpmrc`);
379
380
  }
380
- process.exit(1);
381
+ throw new errors_1.CLIError(`\n❌ Search failed: ${error}`, 1);
381
382
  }
382
383
  finally {
383
384
  await telemetry_1.telemetry.track({
@@ -424,7 +425,7 @@ function createSearchCommand() {
424
425
  const validSubtypes = ['rule', 'agent', 'skill', 'slash-command', 'prompt', 'collection', 'chatmode'];
425
426
  if (options.format && !validFormats.includes(format)) {
426
427
  console.error(`❌ Format must be one of: ${validFormats.join(', ')}`);
427
- process.exit(1);
428
+ throw new errors_1.CLIError(`❌ Format must be one of: ${validFormats.join(', ')}`, 1);
428
429
  }
429
430
  if (options.subtype && !validSubtypes.includes(subtype)) {
430
431
  console.error(`❌ Subtype must be one of: ${validSubtypes.join(', ')}`);
@@ -437,10 +438,9 @@ function createSearchCommand() {
437
438
  console.log(` prpm search --subtype skill # List all skills`);
438
439
  console.log(` prpm search --format claude # List all Claude packages`);
439
440
  console.log(` prpm search --author prpm # List packages by @prpm`);
440
- process.exit(1);
441
+ throw new errors_1.CLIError(`❌ Subtype must be one of: ${validSubtypes.join(', ')}`, 1);
441
442
  }
442
443
  await handleSearch(query || '', { format, subtype, author, language: options.language, framework: options.framework, limit, page, interactive: options.interactive });
443
- process.exit(0);
444
444
  });
445
445
  return command;
446
446
  }
@@ -11,6 +11,7 @@ const telemetry_1 = require("../core/telemetry");
11
11
  const child_process_1 = require("child_process");
12
12
  const util_1 = require("util");
13
13
  const webapp_url_1 = require("../utils/webapp-url");
14
+ const errors_1 = require("../core/errors");
14
15
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
15
16
  /**
16
17
  * Make authenticated API call
@@ -102,7 +103,7 @@ async function handleSubscribe() {
102
103
  console.error('❌ Authentication required');
103
104
  console.log('\n💡 Please login first:');
104
105
  console.log(' prpm login');
105
- process.exit(1);
106
+ throw new errors_1.CLIError('❌ Authentication required', 1);
106
107
  }
107
108
  // Get current status
108
109
  console.log('🔍 Checking current subscription status...');
@@ -115,7 +116,7 @@ async function handleSubscribe() {
115
116
  console.log(` 🚀 Early access to new features`);
116
117
  console.log('\n💡 Manage your subscription at:');
117
118
  console.log(' https://prpm.dev/settings/billing');
118
- process.exit(0);
119
+ return;
119
120
  }
120
121
  console.log('\n✨ Subscribe to PRPM+ and get:');
121
122
  console.log(' 💰 100 monthly playground credits');
@@ -154,7 +155,7 @@ async function handleSubscribe() {
154
155
  catch (err) {
155
156
  error = err instanceof Error ? err.message : String(err);
156
157
  console.error(`\n❌ Subscription failed: ${error}`);
157
- process.exit(1);
158
+ throw new errors_1.CLIError(`\n❌ Subscription failed: ${error}`, 1);
158
159
  }
159
160
  finally {
160
161
  await telemetry_1.telemetry.track({
@@ -205,7 +206,6 @@ Note: You can cancel anytime from https://prpm.dev/settings/billing
205
206
  `)
206
207
  .action(async () => {
207
208
  await handleSubscribe();
208
- process.exit(0);
209
209
  });
210
210
  return command;
211
211
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createTelemetryCommand = createTelemetryCommand;
4
4
  const commander_1 = require("commander");
5
5
  const telemetry_1 = require("../core/telemetry");
6
+ const errors_1 = require("../core/errors");
6
7
  function createTelemetryCommand() {
7
8
  return new commander_1.Command('telemetry')
8
9
  .description('Manage telemetry and analytics settings')
@@ -16,7 +17,7 @@ function createStatusCommand() {
16
17
  return new commander_1.Command('status')
17
18
  .description('Show current telemetry status')
18
19
  .action(async () => {
19
- const enabled = telemetry_1.telemetry.isEnabled();
20
+ const enabled = await telemetry_1.telemetry.isEnabled();
20
21
  const stats = await telemetry_1.telemetry.getStats();
21
22
  console.log('📊 Telemetry Status:');
22
23
  console.log(` Status: ${enabled ? '✅ Enabled' : '❌ Disabled'}`);
@@ -33,7 +34,6 @@ function createStatusCommand() {
33
34
  else {
34
35
  console.log('\n💡 Telemetry is disabled. Run "prpm telemetry enable" to help improve the tool.');
35
36
  }
36
- process.exit(0);
37
37
  });
38
38
  }
39
39
  function createEnableCommand() {
@@ -43,7 +43,6 @@ function createEnableCommand() {
43
43
  await telemetry_1.telemetry.enable();
44
44
  console.log('✅ Telemetry enabled');
45
45
  console.log('📊 Anonymous usage data will be collected to help improve the tool.');
46
- process.exit(0);
47
46
  });
48
47
  }
49
48
  function createDisableCommand() {
@@ -53,7 +52,6 @@ function createDisableCommand() {
53
52
  await telemetry_1.telemetry.disable();
54
53
  console.log('❌ Telemetry disabled');
55
54
  console.log('📊 No usage data will be collected.');
56
- process.exit(0);
57
55
  });
58
56
  }
59
57
  function createStatsCommand() {
@@ -66,7 +64,6 @@ function createStatsCommand() {
66
64
  if (stats.lastEvent) {
67
65
  console.log(` Last event: ${stats.lastEvent}`);
68
66
  }
69
- process.exit(0);
70
67
  });
71
68
  }
72
69
  function createTestCommand() {
@@ -101,9 +98,7 @@ function createTestCommand() {
101
98
  console.log('4. Events may take 1-2 minutes to appear');
102
99
  }
103
100
  catch (error) {
104
- console.error('❌ Failed to send test event:', error);
105
- process.exit(1);
101
+ throw new errors_1.CLIError(`❌ Failed to send test event: ${error}`, 1);
106
102
  }
107
- process.exit(0);
108
103
  });
109
104
  }
@@ -9,6 +9,7 @@ const commander_1 = require("commander");
9
9
  const registry_client_1 = require("@pr-pm/registry-client");
10
10
  const user_config_1 = require("../core/user-config");
11
11
  const telemetry_1 = require("../core/telemetry");
12
+ const errors_1 = require("../core/errors");
12
13
  async function handleTrending(options) {
13
14
  const startTime = Date.now();
14
15
  let success = false;
@@ -41,7 +42,7 @@ async function handleTrending(options) {
41
42
  error = err instanceof Error ? err.message : String(err);
42
43
  console.error(`\n❌ Failed to fetch trending packages: ${error}`);
43
44
  console.log(`\n💡 Tip: Check your internet connection`);
44
- process.exit(1);
45
+ throw new errors_1.CLIError(`\n❌ Failed to fetch trending packages: ${error}`, 1);
45
46
  }
46
47
  finally {
47
48
  await telemetry_1.telemetry.track({
@@ -73,14 +74,13 @@ function createTrendingCommand() {
73
74
  const validSubtypes = ['rule', 'agent', 'skill', 'slash-command', 'prompt', 'workflow', 'tool', 'template', 'collection'];
74
75
  if (options.format && !validFormats.includes(format)) {
75
76
  console.error(`❌ Format must be one of: ${validFormats.join(', ')}`);
76
- process.exit(1);
77
+ throw new errors_1.CLIError(`❌ Format must be one of: ${validFormats.join(', ')}`, 1);
77
78
  }
78
79
  if (options.subtype && !validSubtypes.includes(subtype)) {
79
80
  console.error(`❌ Subtype must be one of: ${validSubtypes.join(', ')}`);
80
- process.exit(1);
81
+ throw new errors_1.CLIError(`❌ Subtype must be one of: ${validSubtypes.join(', ')}`, 1);
81
82
  }
82
83
  await handleTrending({ format, subtype, limit });
83
- process.exit(0);
84
84
  });
85
85
  return command;
86
86
  }
@@ -9,6 +9,7 @@ const commander_1 = require("commander");
9
9
  const lockfile_1 = require("../core/lockfile");
10
10
  const filesystem_1 = require("../core/filesystem");
11
11
  const fs_1 = require("fs");
12
+ const errors_1 = require("../core/errors");
12
13
  /**
13
14
  * Handle the uninstall command
14
15
  */
@@ -18,8 +19,7 @@ async function handleUninstall(name) {
18
19
  // Remove from lockfile and get package info
19
20
  const pkg = await (0, lockfile_1.removePackage)(name);
20
21
  if (!pkg) {
21
- console.error(`❌ Package "${name}" not found`);
22
- process.exit(1);
22
+ throw new errors_1.CLIError(`❌ Package "${name}" not found`, 1);
23
23
  }
24
24
  // Get destination directory using format and subtype
25
25
  const format = pkg.format || 'generic';
@@ -75,11 +75,12 @@ async function handleUninstall(name) {
75
75
  }
76
76
  }
77
77
  console.log(`✅ Successfully uninstalled ${name}`);
78
- process.exit(0);
79
78
  }
80
79
  catch (error) {
81
- console.error(`❌ Failed to uninstall package: ${error}`);
82
- process.exit(1);
80
+ if (error instanceof errors_1.CLIError) {
81
+ throw error;
82
+ }
83
+ throw new errors_1.CLIError(`❌ Failed to uninstall package: ${error}`, 1);
83
84
  }
84
85
  }
85
86
  /**
@@ -11,6 +11,7 @@ const user_config_1 = require("../core/user-config");
11
11
  const lockfile_1 = require("../core/lockfile");
12
12
  const install_1 = require("./install");
13
13
  const telemetry_1 = require("../core/telemetry");
14
+ const errors_1 = require("../core/errors");
14
15
  /**
15
16
  * Update packages to latest minor/patch versions
16
17
  */
@@ -76,8 +77,7 @@ async function handleUpdate(packageName, options = {}) {
76
77
  }
77
78
  catch (err) {
78
79
  error = err instanceof Error ? err.message : String(err);
79
- console.error(`\n❌ Update failed: ${error}`);
80
- process.exit(1);
80
+ throw new errors_1.CLIError(`\n❌ Update failed: ${error}`, 1);
81
81
  }
82
82
  finally {
83
83
  await telemetry_1.telemetry.track({
@@ -117,6 +117,5 @@ function createUpdateCommand() {
117
117
  .option('--all', 'Update all packages')
118
118
  .action(async (packageName, options) => {
119
119
  await handleUpdate(packageName, options);
120
- process.exit(0);
121
120
  });
122
121
  }
@@ -11,6 +11,7 @@ const user_config_1 = require("../core/user-config");
11
11
  const lockfile_1 = require("../core/lockfile");
12
12
  const install_1 = require("./install");
13
13
  const telemetry_1 = require("../core/telemetry");
14
+ const errors_1 = require("../core/errors");
14
15
  /**
15
16
  * Upgrade packages to latest versions (including major updates)
16
17
  */
@@ -75,8 +76,7 @@ async function handleUpgrade(packageName, options = {}) {
75
76
  }
76
77
  catch (err) {
77
78
  error = err instanceof Error ? err.message : String(err);
78
- console.error(`\n❌ Upgrade failed: ${error}`);
79
- process.exit(1);
79
+ throw new errors_1.CLIError(`\n❌ Upgrade failed: ${error}`, 1);
80
80
  }
81
81
  finally {
82
82
  await telemetry_1.telemetry.track({
@@ -117,6 +117,5 @@ function createUpgradeCommand() {
117
117
  .option('--force', 'Skip warning for major version upgrades')
118
118
  .action(async (packageName, options) => {
119
119
  await handleUpgrade(packageName, options);
120
- process.exit(0);
121
120
  });
122
121
  }
@@ -9,6 +9,7 @@ const commander_1 = require("commander");
9
9
  const user_config_1 = require("../core/user-config");
10
10
  const registry_client_1 = require("@pr-pm/registry-client");
11
11
  const telemetry_1 = require("../core/telemetry");
12
+ const errors_1 = require("../core/errors");
12
13
  /**
13
14
  * Show current logged-in user
14
15
  */
@@ -57,8 +58,7 @@ async function handleWhoami() {
57
58
  }
58
59
  catch (err) {
59
60
  error = err instanceof Error ? err.message : String(err);
60
- console.error(`❌ Error: ${error}`);
61
- process.exit(1);
61
+ throw new errors_1.CLIError(`❌ Error: ${error}`, 1);
62
62
  }
63
63
  finally {
64
64
  // Track telemetry
@@ -79,6 +79,5 @@ function createWhoamiCommand() {
79
79
  .description('Show current logged-in user')
80
80
  .action(async () => {
81
81
  await handleWhoami();
82
- process.exit(0);
83
82
  });
84
83
  }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLIError = void 0;
4
+ exports.createError = createError;
5
+ exports.createSuccess = createSuccess;
6
+ /**
7
+ * Custom error class for CLI commands
8
+ * Allows commands to throw errors with exit codes instead of calling process.exit()
9
+ */
10
+ class CLIError extends Error {
11
+ constructor(message, exitCode = 1) {
12
+ super(message);
13
+ this.name = 'CLIError';
14
+ this.exitCode = exitCode;
15
+ }
16
+ }
17
+ exports.CLIError = CLIError;
18
+ /**
19
+ * Creates a CLIError with exit code 1 (general error)
20
+ */
21
+ function createError(message) {
22
+ return new CLIError(message, 1);
23
+ }
24
+ /**
25
+ * Creates a CLIError with exit code 0 (success, used for early termination)
26
+ */
27
+ function createSuccess(message) {
28
+ return new CLIError(message || '', 0);
29
+ }
@@ -8,16 +8,38 @@ const fs_1 = require("fs");
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const os_1 = __importDefault(require("os"));
10
10
  const posthog_node_1 = require("posthog-node");
11
+ const user_config_1 = require("./user-config");
11
12
  class Telemetry {
12
13
  constructor() {
13
14
  this.events = [];
14
15
  this.maxEvents = 100; // Keep only last 100 events locally
15
16
  this.posthog = null;
17
+ this.userConfigChecked = false;
18
+ this.userTelemetryEnabled = true; // Default to true until checked
16
19
  this.configPath = path_1.default.join(os_1.default.homedir(), '.prpm', 'telemetry.json');
17
20
  this.config = this.loadConfig();
18
- this.initializePostHog();
19
21
  }
20
- initializePostHog() {
22
+ async checkUserConfig() {
23
+ if (this.userConfigChecked)
24
+ return;
25
+ try {
26
+ const userConfig = await (0, user_config_1.getConfig)();
27
+ this.userTelemetryEnabled = userConfig.telemetryEnabled ?? true;
28
+ }
29
+ catch (error) {
30
+ // If we can't load user config, default to enabled
31
+ this.userTelemetryEnabled = true;
32
+ }
33
+ this.userConfigChecked = true;
34
+ }
35
+ async initializePostHog() {
36
+ // Check user config first
37
+ await this.checkUserConfig();
38
+ // Only initialize if telemetry is enabled in user config
39
+ if (!this.userTelemetryEnabled) {
40
+ this.posthog = null;
41
+ return;
42
+ }
21
43
  try {
22
44
  this.posthog = new posthog_node_1.PostHog('phc_aO5lXLILeylHfb1ynszVwKbQKSzO91UGdXNhN5Q0Snl', {
23
45
  host: 'https://app.posthog.com',
@@ -59,6 +81,11 @@ class Telemetry {
59
81
  }
60
82
  }
61
83
  async track(event) {
84
+ // Check user config first
85
+ await this.checkUserConfig();
86
+ // Return early if telemetry is disabled in user config
87
+ if (!this.userTelemetryEnabled)
88
+ return;
62
89
  if (!this.config.enabled)
63
90
  return;
64
91
  const fullEvent = {
@@ -92,6 +119,10 @@ class Telemetry {
92
119
  }
93
120
  }
94
121
  async sendToAnalytics(event) {
122
+ // Initialize PostHog if needed (this will check user config)
123
+ if (!this.posthog && this.userTelemetryEnabled) {
124
+ await this.initializePostHog();
125
+ }
95
126
  // Send to PostHog
96
127
  await this.sendToPostHog(event);
97
128
  }
@@ -103,8 +134,9 @@ class Telemetry {
103
134
  this.config.enabled = false;
104
135
  await this.saveConfig();
105
136
  }
106
- isEnabled() {
107
- return this.config.enabled;
137
+ async isEnabled() {
138
+ await this.checkUserConfig();
139
+ return this.userTelemetryEnabled && this.config.enabled;
108
140
  }
109
141
  async getStats() {
110
142
  try {
package/dist/index.js CHANGED
@@ -32,6 +32,7 @@ const credits_1 = require("./commands/credits");
32
32
  const subscribe_1 = require("./commands/subscribe");
33
33
  const buy_credits_1 = require("./commands/buy-credits");
34
34
  const telemetry_2 = require("./core/telemetry");
35
+ const errors_1 = require("./core/errors");
35
36
  // Read version from package.json
36
37
  function getVersion() {
37
38
  try {
@@ -77,8 +78,28 @@ program.addCommand((0, buy_credits_1.createBuyCreditsCommand)());
77
78
  // Utility commands
78
79
  program.addCommand((0, schema_1.createSchemaCommand)());
79
80
  program.addCommand((0, config_1.createConfigCommand)());
80
- // Parse command line arguments
81
- program.parse();
81
+ // Parse command line arguments with error handling
82
+ (async () => {
83
+ try {
84
+ await program.parseAsync();
85
+ // Command completed successfully - let Node.js exit naturally
86
+ }
87
+ catch (error) {
88
+ if (error instanceof errors_1.CLIError) {
89
+ // Print error message if present
90
+ if (error.message) {
91
+ console.error(error.message);
92
+ }
93
+ // Exit with the error's exit code
94
+ process.exit(error.exitCode);
95
+ }
96
+ else {
97
+ // Unexpected error - print and exit with code 1
98
+ console.error('Unexpected error:', error);
99
+ process.exit(1);
100
+ }
101
+ }
102
+ })();
82
103
  // Cleanup telemetry on exit
83
104
  process.on('exit', () => {
84
105
  telemetry_2.telemetry.shutdown().catch(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prpm",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Prompt Package Manager CLI - Install and manage prompt-based files",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -45,8 +45,8 @@
45
45
  "license": "MIT",
46
46
  "dependencies": {
47
47
  "@octokit/rest": "^22.0.0",
48
- "@pr-pm/registry-client": "^1.3.8",
49
- "@pr-pm/types": "^0.2.9",
48
+ "@pr-pm/registry-client": "^1.3.10",
49
+ "@pr-pm/types": "^0.2.11",
50
50
  "ajv": "^8.17.1",
51
51
  "ajv-formats": "^3.0.1",
52
52
  "commander": "^11.1.0",