@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.
- package/commands/plexor-enabled.js +53 -10
- package/commands/plexor-login.js +18 -5
- package/commands/plexor-logout.js +39 -6
- package/package.json +1 -1
|
@@ -14,8 +14,21 @@
|
|
|
14
14
|
const fs = require('fs');
|
|
15
15
|
const path = require('path');
|
|
16
16
|
|
|
17
|
-
// Import settings manager
|
|
18
|
-
|
|
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
|
|
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
|
-
|
|
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
|
package/commands/plexor-login.js
CHANGED
|
@@ -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
|
|
17
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
20
|
-
|
|
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
|
-
|
|
27
|
-
fs.
|
|
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