@plexor-dev/claude-code-plugin-staging 0.1.0-beta.8 → 0.1.0-beta.9

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.
@@ -14,8 +14,21 @@
14
14
  const fs = require('fs');
15
15
  const path = require('path');
16
16
 
17
- // Import settings manager for automatic Claude Code configuration
18
- const { settingsManager, PLEXOR_STAGING_URL, PLEXOR_PROD_URL } = require('../lib/settings-manager');
17
+ // Import settings manager with error handling for missing lib
18
+ let settingsManager, PLEXOR_STAGING_URL, PLEXOR_PROD_URL;
19
+ try {
20
+ const lib = require('../lib/settings-manager');
21
+ settingsManager = lib.settingsManager;
22
+ PLEXOR_STAGING_URL = lib.PLEXOR_STAGING_URL;
23
+ PLEXOR_PROD_URL = lib.PLEXOR_PROD_URL;
24
+ } catch (err) {
25
+ if (err.code === 'MODULE_NOT_FOUND') {
26
+ console.error('Error: Plexor plugin files are missing or corrupted.');
27
+ console.error(' Please reinstall: npm install @plexor-dev/claude-code-plugin-staging');
28
+ process.exit(1);
29
+ }
30
+ throw err;
31
+ }
19
32
 
20
33
  const CONFIG_PATH = path.join(process.env.HOME, '.plexor', 'config.json');
21
34
  const PLEXOR_DIR = path.join(process.env.HOME, '.plexor');
@@ -60,17 +73,27 @@ function saveConfig(config) {
60
73
 
61
74
  fs.writeFileSync(tempPath, JSON.stringify(config, null, 2), { mode: 0o600 });
62
75
  fs.renameSync(tempPath, CONFIG_PATH);
76
+ return true;
63
77
  } catch (err) {
64
78
  if (err.code === 'EACCES' || err.code === 'EPERM') {
65
- console.error(`Error: Cannot write to ${CONFIG_PATH}`);
79
+ console.error(`Error: Cannot write to ~/.plexor/config.json`);
66
80
  console.error(' Check file permissions or run with appropriate access.');
67
81
  } else {
68
82
  console.error('Failed to save config:', err.message);
69
83
  }
70
- throw err;
84
+ return false;
71
85
  }
72
86
  }
73
87
 
88
+ /**
89
+ * Validate API key format
90
+ * @param {string} key - API key to validate
91
+ * @returns {boolean} true if valid format
92
+ */
93
+ function isValidApiKeyFormat(key) {
94
+ return key && typeof key === 'string' && key.startsWith('plx_') && key.length >= 20;
95
+ }
96
+
74
97
  function main() {
75
98
  const args = process.argv.slice(2);
76
99
  const config = loadConfig();
@@ -118,27 +141,34 @@ function main() {
118
141
  // THE KEY FEATURE: Update Claude Code settings.json routing
119
142
  let routingUpdated = false;
120
143
  let missingApiKey = false;
144
+ let invalidApiKey = false;
121
145
 
122
146
  if (newEnabled) {
123
- // Enable routing - need API key from config
124
- if (apiKey) {
147
+ // Enable routing - need valid API key from config
148
+ if (!apiKey) {
149
+ missingApiKey = true;
150
+ } else if (!isValidApiKeyFormat(apiKey)) {
151
+ invalidApiKey = true;
152
+ } else {
125
153
  // Update Plexor plugin config first
126
154
  config.settings = config.settings || {};
127
155
  config.settings.enabled = newEnabled;
128
- saveConfig(config);
156
+ if (!saveConfig(config)) {
157
+ process.exit(1);
158
+ }
129
159
 
130
160
  // STAGING PACKAGE - uses staging API
131
161
  const apiUrl = config.settings?.apiUrl || 'https://staging.api.plexor.dev';
132
162
  const useStaging = apiUrl.includes('staging');
133
163
  routingUpdated = settingsManager.enablePlexorRouting(apiKey, { useStaging });
134
- } else {
135
- missingApiKey = true;
136
164
  }
137
165
  } else {
138
166
  // Update Plexor plugin config
139
167
  config.settings = config.settings || {};
140
168
  config.settings.enabled = newEnabled;
141
- saveConfig(config);
169
+ if (!saveConfig(config)) {
170
+ process.exit(1);
171
+ }
142
172
 
143
173
  // Disable routing - remove env vars from settings.json
144
174
  routingUpdated = settingsManager.disablePlexorRouting();
@@ -158,6 +188,19 @@ function main() {
158
188
  process.exit(1);
159
189
  }
160
190
 
191
+ // Show error if API key format is invalid
192
+ if (invalidApiKey) {
193
+ console.log(`┌─────────────────────────────────────────────┐`);
194
+ console.log(`│ ✗ Cannot Enable Plexor │`);
195
+ console.log(`├─────────────────────────────────────────────┤`);
196
+ console.log(`│ Invalid API key format in config. │`);
197
+ console.log(`│ Keys must start with "plx_" (20+ chars). │`);
198
+ console.log(`├─────────────────────────────────────────────┤`);
199
+ console.log(`│ Run /plexor-login <api-key> to fix. │`);
200
+ console.log(`└─────────────────────────────────────────────┘`);
201
+ process.exit(1);
202
+ }
203
+
161
204
  const newStatus = newEnabled ? '● Enabled' : '○ Disabled';
162
205
  const prevStatus = currentEnabled ? 'Enabled' : 'Disabled';
163
206
  const routingMsg = routingUpdated
@@ -13,8 +13,18 @@ const path = require('path');
13
13
  const https = require('https');
14
14
  const http = require('http');
15
15
 
16
- // Import settings manager for automatic Claude Code configuration
17
- const { settingsManager } = require('../lib/settings-manager');
16
+ // Import settings manager with error handling for missing lib
17
+ let settingsManager;
18
+ try {
19
+ settingsManager = require('../lib/settings-manager').settingsManager;
20
+ } catch (err) {
21
+ if (err.code === 'MODULE_NOT_FOUND') {
22
+ console.error('Error: Plexor plugin files are missing or corrupted.');
23
+ console.error(' Please reinstall: npm install @plexor-dev/claude-code-plugin-staging');
24
+ process.exit(1);
25
+ }
26
+ throw err;
27
+ }
18
28
 
19
29
  const CONFIG_PATH = path.join(process.env.HOME, '.plexor', 'config.json');
20
30
  const PLEXOR_DIR = path.join(process.env.HOME, '.plexor');
@@ -56,14 +66,15 @@ function saveConfig(config) {
56
66
 
57
67
  fs.writeFileSync(tempPath, JSON.stringify(config, null, 2), { mode: 0o600 });
58
68
  fs.renameSync(tempPath, CONFIG_PATH);
69
+ return true;
59
70
  } catch (err) {
60
71
  if (err.code === 'EACCES' || err.code === 'EPERM') {
61
- console.error(`Error: Cannot write to ${CONFIG_PATH}`);
72
+ console.error('Error: Cannot write to ~/.plexor/config.json');
62
73
  console.error(' Check file permissions or run with appropriate access.');
63
74
  } else {
64
75
  console.error('Failed to save config:', err.message);
65
76
  }
66
- throw err;
77
+ return false;
67
78
  }
68
79
  }
69
80
 
@@ -162,7 +173,9 @@ async function main() {
162
173
  config.auth.api_key = apiKey;
163
174
  config.settings = config.settings || {};
164
175
  config.settings.enabled = true;
165
- saveConfig(config);
176
+ if (!saveConfig(config)) {
177
+ process.exit(1);
178
+ }
166
179
 
167
180
  // AUTO-CONFIGURE CLAUDE CODE ROUTING
168
181
  // This is the key feature: automatically set ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN
@@ -15,18 +15,49 @@ const CACHE_PATH = path.join(PLEXOR_DIR, 'cache.json');
15
15
 
16
16
  function loadConfig() {
17
17
  try {
18
+ if (!fs.existsSync(CONFIG_PATH)) {
19
+ return null;
20
+ }
18
21
  const data = fs.readFileSync(CONFIG_PATH, 'utf8');
19
- return JSON.parse(data);
20
- } catch {
22
+ if (!data || data.trim() === '') {
23
+ return null;
24
+ }
25
+ const config = JSON.parse(data);
26
+ if (typeof config !== 'object' || config === null) {
27
+ return null;
28
+ }
29
+ return config;
30
+ } catch (err) {
31
+ if (err instanceof SyntaxError) {
32
+ console.warn('Warning: Config file is corrupted');
33
+ }
21
34
  return null;
22
35
  }
23
36
  }
24
37
 
25
38
  function saveConfig(config) {
26
- if (!fs.existsSync(PLEXOR_DIR)) {
27
- fs.mkdirSync(PLEXOR_DIR, { recursive: true, mode: 0o700 });
39
+ try {
40
+ if (!fs.existsSync(PLEXOR_DIR)) {
41
+ fs.mkdirSync(PLEXOR_DIR, { recursive: true, mode: 0o700 });
42
+ }
43
+
44
+ // Atomic write: write to temp file, then rename
45
+ const crypto = require('crypto');
46
+ const tempId = crypto.randomBytes(8).toString('hex');
47
+ const tempPath = path.join(PLEXOR_DIR, `.config.${tempId}.tmp`);
48
+
49
+ fs.writeFileSync(tempPath, JSON.stringify(config, null, 2), { mode: 0o600 });
50
+ fs.renameSync(tempPath, CONFIG_PATH);
51
+ return true;
52
+ } catch (err) {
53
+ if (err.code === 'EACCES' || err.code === 'EPERM') {
54
+ console.error('Error: Cannot write to ~/.plexor/config.json');
55
+ console.error(' Check file permissions or run with appropriate access.');
56
+ } else {
57
+ console.error('Failed to save config:', err.message);
58
+ }
59
+ return false;
28
60
  }
29
- fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 0o600 });
30
61
  }
31
62
 
32
63
  function deleteFile(filePath) {
@@ -61,7 +92,9 @@ function main() {
61
92
  delete config.auth.api_key;
62
93
  config.settings = config.settings || {};
63
94
  config.settings.enabled = false;
64
- saveConfig(config);
95
+ if (!saveConfig(config)) {
96
+ process.exit(1);
97
+ }
65
98
 
66
99
  // Clear session
67
100
  deleteFile(SESSION_PATH);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plexor-dev/claude-code-plugin-staging",
3
- "version": "0.1.0-beta.8",
3
+ "version": "0.1.0-beta.9",
4
4
  "description": "STAGING - LLM cost optimization plugin for Claude Code (internal testing)",
5
5
  "main": "lib/constants.js",
6
6
  "bin": {