@plexor-dev/claude-code-plugin 0.1.0-beta.11 → 0.1.0-beta.13
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-login.md +17 -9
- package/hooks/intercept.js +42 -25
- package/package.json +1 -1
- package/scripts/plexor-cli.sh +41 -0
package/commands/plexor-login.md
CHANGED
|
@@ -12,7 +12,7 @@ Authenticate with your Plexor account to enable LLM cost optimization.
|
|
|
12
12
|
|
|
13
13
|
Use the Read tool to read `~/.plexor/config.json`.
|
|
14
14
|
|
|
15
|
-
If the file exists and has
|
|
15
|
+
If the file exists and has `auth.api_key` that starts with "plx_", the user is already authenticated. Show them:
|
|
16
16
|
```
|
|
17
17
|
Plexor Login
|
|
18
18
|
============
|
|
@@ -35,20 +35,28 @@ Tell them: "Please provide your Plexor API key (starts with 'plx_'):"
|
|
|
35
35
|
|
|
36
36
|
**Step 3: Save the configuration**
|
|
37
37
|
|
|
38
|
-
Once the user provides an API key, use the Write tool to create/update `~/.plexor/config.json`:
|
|
38
|
+
Once the user provides an API key (or it was passed as an argument), use the Write tool to create/update `~/.plexor/config.json`:
|
|
39
39
|
|
|
40
40
|
```json
|
|
41
41
|
{
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
|
|
42
|
+
"version": 1,
|
|
43
|
+
"auth": {
|
|
44
|
+
"api_key": "[user's API key]",
|
|
45
|
+
"authenticated_at": "[current ISO timestamp]"
|
|
46
|
+
},
|
|
47
|
+
"settings": {
|
|
48
|
+
"enabled": true,
|
|
49
|
+
"apiUrl": "https://api.plexor.dev",
|
|
50
|
+
"preferred_provider": "auto",
|
|
51
|
+
"mode": "balanced",
|
|
52
|
+
"localCacheEnabled": true,
|
|
53
|
+
"timeout": 5000
|
|
54
|
+
}
|
|
49
55
|
}
|
|
50
56
|
```
|
|
51
57
|
|
|
58
|
+
**IMPORTANT**: If the user provided the API key as an argument (e.g., `/plexor-login plx_abc123`), use that key directly instead of asking for it.
|
|
59
|
+
|
|
52
60
|
**Step 4: Verify the key works**
|
|
53
61
|
|
|
54
62
|
Make a test request to verify authentication:
|
package/hooks/intercept.js
CHANGED
|
@@ -157,55 +157,59 @@ class PlexorClient {
|
|
|
157
157
|
async function main() {
|
|
158
158
|
const startTime = Date.now();
|
|
159
159
|
|
|
160
|
+
let input;
|
|
161
|
+
let request;
|
|
162
|
+
|
|
160
163
|
try {
|
|
161
|
-
|
|
162
|
-
|
|
164
|
+
input = await readStdin();
|
|
165
|
+
request = JSON.parse(input);
|
|
163
166
|
|
|
164
|
-
// CRITICAL:
|
|
165
|
-
//
|
|
166
|
-
|
|
167
|
-
|
|
167
|
+
// CRITICAL: Check for slash commands FIRST (before agentic check)
|
|
168
|
+
// Slash commands like /plexor-status should pass through unchanged
|
|
169
|
+
// Must check before isAgenticRequest since all Claude Code requests have tools
|
|
170
|
+
if (isSlashCommand(request)) {
|
|
171
|
+
logger.debug('Slash command detected, passing through unchanged');
|
|
168
172
|
recordPassthrough();
|
|
169
173
|
return output({
|
|
170
174
|
...request,
|
|
171
175
|
plexor_cwd: process.cwd(),
|
|
172
176
|
_plexor: {
|
|
173
|
-
source: '
|
|
174
|
-
reason: '
|
|
177
|
+
source: 'passthrough_slash_command',
|
|
178
|
+
reason: 'slash_command_detected',
|
|
175
179
|
cwd: process.cwd(),
|
|
176
180
|
latency_ms: Date.now() - startTime
|
|
177
181
|
}
|
|
178
182
|
});
|
|
179
183
|
}
|
|
180
184
|
|
|
181
|
-
// CRITICAL: Skip optimization for
|
|
182
|
-
//
|
|
183
|
-
if (
|
|
184
|
-
logger.debug('
|
|
185
|
+
// CRITICAL: Skip optimization for CLI commands requiring tool execution
|
|
186
|
+
// Azure CLI, AWS CLI, kubectl, etc. need tools to be preserved
|
|
187
|
+
if (requiresToolExecution(request)) {
|
|
188
|
+
logger.debug('CLI tool execution detected, passing through unchanged');
|
|
185
189
|
recordPassthrough();
|
|
186
190
|
return output({
|
|
187
191
|
...request,
|
|
188
192
|
plexor_cwd: process.cwd(),
|
|
189
193
|
_plexor: {
|
|
190
|
-
source: '
|
|
191
|
-
reason: '
|
|
194
|
+
source: 'passthrough_cli',
|
|
195
|
+
reason: 'cli_tool_execution_detected',
|
|
192
196
|
cwd: process.cwd(),
|
|
193
197
|
latency_ms: Date.now() - startTime
|
|
194
198
|
}
|
|
195
199
|
});
|
|
196
200
|
}
|
|
197
201
|
|
|
198
|
-
// CRITICAL: Skip optimization for
|
|
199
|
-
//
|
|
200
|
-
if (
|
|
201
|
-
logger.debug('
|
|
202
|
+
// CRITICAL: Skip optimization for agentic/tool-using requests
|
|
203
|
+
// Modifying messages breaks the agent loop and causes infinite loops
|
|
204
|
+
if (isAgenticRequest(request)) {
|
|
205
|
+
logger.debug('Agentic request detected, passing through unchanged');
|
|
202
206
|
recordPassthrough();
|
|
203
207
|
return output({
|
|
204
208
|
...request,
|
|
205
209
|
plexor_cwd: process.cwd(),
|
|
206
210
|
_plexor: {
|
|
207
|
-
source: '
|
|
208
|
-
reason: '
|
|
211
|
+
source: 'passthrough_agentic',
|
|
212
|
+
reason: 'tool_use_detected',
|
|
209
213
|
cwd: process.cwd(),
|
|
210
214
|
latency_ms: Date.now() - startTime
|
|
211
215
|
}
|
|
@@ -307,17 +311,30 @@ async function main() {
|
|
|
307
311
|
logger.error(`[Plexor] Error: ${error.message}`);
|
|
308
312
|
logger.debug(error.stack);
|
|
309
313
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const request = JSON.parse(input);
|
|
314
|
+
// Use already-parsed request if available, otherwise pass through raw
|
|
315
|
+
if (request) {
|
|
313
316
|
return output({
|
|
314
317
|
...request,
|
|
315
318
|
_plexor: {
|
|
316
319
|
error: error.message,
|
|
317
|
-
source: '
|
|
320
|
+
source: 'passthrough_error'
|
|
318
321
|
}
|
|
319
322
|
});
|
|
320
|
-
}
|
|
323
|
+
} else if (input) {
|
|
324
|
+
// Try to parse the input we already read
|
|
325
|
+
try {
|
|
326
|
+
const req = JSON.parse(input);
|
|
327
|
+
return output({
|
|
328
|
+
...req,
|
|
329
|
+
_plexor: {
|
|
330
|
+
error: error.message,
|
|
331
|
+
source: 'passthrough_error'
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
} catch {
|
|
335
|
+
process.exit(1);
|
|
336
|
+
}
|
|
337
|
+
} else {
|
|
321
338
|
process.exit(1);
|
|
322
339
|
}
|
|
323
340
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Plexor CLI - Claude Code with intelligent optimization
|
|
3
|
+
|
|
4
|
+
# Only show Plexor branding if ANTHROPIC_BASE_URL points to Plexor
|
|
5
|
+
if [[ "$ANTHROPIC_BASE_URL" == *"plexor"* ]]; then
|
|
6
|
+
# Colors
|
|
7
|
+
CYAN='\033[0;36m'
|
|
8
|
+
GREEN='\033[0;32m'
|
|
9
|
+
YELLOW='\033[0;33m'
|
|
10
|
+
DIM='\033[2m'
|
|
11
|
+
NC='\033[0m' # No Color
|
|
12
|
+
|
|
13
|
+
# Plexor ASCII art
|
|
14
|
+
echo -e "${CYAN}"
|
|
15
|
+
cat << 'EOF'
|
|
16
|
+
____ __
|
|
17
|
+
/ __ \/ /__ _ ______ _____
|
|
18
|
+
/ /_/ / / _ \| |/_/ __ \/ ___/
|
|
19
|
+
/ ____/ / __/> </ /_/ / /
|
|
20
|
+
/_/ /_/\___/_/|_|\____/_/
|
|
21
|
+
|
|
22
|
+
EOF
|
|
23
|
+
echo -e "${NC}"
|
|
24
|
+
|
|
25
|
+
# Show status
|
|
26
|
+
CONFIG_FILE="$HOME/.plexor/config.json"
|
|
27
|
+
if [ -f "$CONFIG_FILE" ]; then
|
|
28
|
+
ENABLED=$(jq -r '.settings.enabled // false' "$CONFIG_FILE" 2>/dev/null)
|
|
29
|
+
MODE=$(jq -r '.settings.mode // "balanced"' "$CONFIG_FILE" 2>/dev/null)
|
|
30
|
+
|
|
31
|
+
if [ "$ENABLED" = "true" ]; then
|
|
32
|
+
echo -e "${GREEN}●${NC} Optimization: ${GREEN}Active${NC} (${MODE} mode)"
|
|
33
|
+
else
|
|
34
|
+
echo -e "${YELLOW}○${NC} Optimization: ${DIM}Disabled${NC}"
|
|
35
|
+
fi
|
|
36
|
+
echo ""
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Launch claude with all arguments passed through
|
|
41
|
+
exec claude "$@"
|