@plexor-dev/claude-code-plugin 0.1.0-beta.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.
- package/LICENSE +21 -0
- package/README.md +117 -0
- package/commands/plexor-config.md +43 -0
- package/commands/plexor-enabled.md +36 -0
- package/commands/plexor-login.md +87 -0
- package/commands/plexor-logout.md +50 -0
- package/commands/plexor-mode.md +25 -0
- package/commands/plexor-provider.md +25 -0
- package/commands/plexor-settings.md +93 -0
- package/commands/plexor-status.md +46 -0
- package/lib/constants.js +40 -0
- package/package.json +49 -0
- package/scripts/postinstall.js +102 -0
- package/scripts/uninstall.js +67 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Plexor AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# @plexor-dev/claude-code-plugin
|
|
2
|
+
|
|
3
|
+
LLM cost optimization plugin for Claude Code. Save up to 90% on AI costs through intelligent prompt optimization and multi-provider routing.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @plexor-dev/claude-code-plugin
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This installs slash commands to `~/.claude/commands/`.
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
1. **Install the plugin** (see above)
|
|
16
|
+
|
|
17
|
+
2. **Open Claude Code** and run:
|
|
18
|
+
```
|
|
19
|
+
/plexor-login
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
3. **Follow the prompts** to authenticate via browser
|
|
23
|
+
|
|
24
|
+
4. **Set the gateway URL** in your terminal:
|
|
25
|
+
```bash
|
|
26
|
+
export ANTHROPIC_BASE_URL="https://api.plexor.dev/v1/gateway/anthropic"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
5. **Restart Claude Code** - all prompts are now optimized!
|
|
30
|
+
|
|
31
|
+
## Commands
|
|
32
|
+
|
|
33
|
+
| Command | Description |
|
|
34
|
+
|---------|-------------|
|
|
35
|
+
| `/plexor-login` | Authenticate with Plexor |
|
|
36
|
+
| `/plexor-status` | View usage stats and savings |
|
|
37
|
+
| `/plexor-mode` | Set optimization mode (eco/balanced/quality/passthrough) |
|
|
38
|
+
| `/plexor-provider` | Force specific provider (auto/claude/deepseek/mistral/gemini) |
|
|
39
|
+
| `/plexor-config` | Quick config (enable/disable/cache/reset) |
|
|
40
|
+
| `/plexor-settings` | Advanced settings (API URL, mode, provider) |
|
|
41
|
+
| `/plexor-enabled` | Enable/disable the proxy |
|
|
42
|
+
| `/plexor-logout` | Sign out and clear credentials |
|
|
43
|
+
|
|
44
|
+
## How It Works
|
|
45
|
+
|
|
46
|
+
Plexor acts as an intelligent gateway between Claude Code and LLM providers:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Claude Code → Plexor Gateway → Best Provider (Anthropic/DeepSeek/Mistral/Gemini/OpenAI)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The gateway:
|
|
53
|
+
- **Optimizes prompts** to reduce token usage
|
|
54
|
+
- **Routes requests** to the most cost-effective provider
|
|
55
|
+
- **Maintains quality** based on your selected mode
|
|
56
|
+
- **Tracks savings** so you can see your ROI
|
|
57
|
+
|
|
58
|
+
## Optimization Modes
|
|
59
|
+
|
|
60
|
+
| Mode | Savings | Best For |
|
|
61
|
+
|------|---------|----------|
|
|
62
|
+
| **eco** | 60-90% | Development, testing, iteration |
|
|
63
|
+
| **balanced** | 40-60% | Most production workloads |
|
|
64
|
+
| **quality** | 20-40% | Critical responses, customer-facing |
|
|
65
|
+
| **passthrough** | 0% | Debugging, comparison |
|
|
66
|
+
|
|
67
|
+
## Pricing
|
|
68
|
+
|
|
69
|
+
- **Beta**: $1/month (unlimited requests)
|
|
70
|
+
- Savings typically 10-100x the subscription cost
|
|
71
|
+
|
|
72
|
+
## Configuration
|
|
73
|
+
|
|
74
|
+
Settings are stored in `~/.plexor/config.json`:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"version": 1,
|
|
79
|
+
"auth": {
|
|
80
|
+
"api_key": "plx_...",
|
|
81
|
+
"email": "user@example.com"
|
|
82
|
+
},
|
|
83
|
+
"settings": {
|
|
84
|
+
"enabled": true,
|
|
85
|
+
"mode": "balanced",
|
|
86
|
+
"preferred_provider": "auto"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Uninstall
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npm uninstall -g @plexor-dev/claude-code-plugin
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
To fully remove:
|
|
98
|
+
```bash
|
|
99
|
+
unset ANTHROPIC_BASE_URL
|
|
100
|
+
rm -rf ~/.plexor
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Requirements
|
|
104
|
+
|
|
105
|
+
- Node.js 16+
|
|
106
|
+
- Claude Code CLI
|
|
107
|
+
- macOS, Linux, or Windows (WSL)
|
|
108
|
+
|
|
109
|
+
## Support
|
|
110
|
+
|
|
111
|
+
- **Documentation**: https://plexor.dev/docs
|
|
112
|
+
- **Issues**: https://github.com/plexor-ai/claude-code-plugin/issues
|
|
113
|
+
- **Email**: hello@plexor.dev
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Configure Plexor settings
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Plexor Config
|
|
6
|
+
|
|
7
|
+
Configure Plexor optimization settings.
|
|
8
|
+
|
|
9
|
+
## Arguments
|
|
10
|
+
|
|
11
|
+
$ARGUMENTS - Configuration command and value
|
|
12
|
+
|
|
13
|
+
## Supported Commands
|
|
14
|
+
|
|
15
|
+
- `plexor-config show` - Show current configuration
|
|
16
|
+
- `plexor-config enable` - Enable Plexor optimization
|
|
17
|
+
- `plexor-config disable` - Disable Plexor optimization
|
|
18
|
+
- `plexor-config cache on|off` - Enable/disable local cache
|
|
19
|
+
- `plexor-config provider <name>` - Set preferred provider (anthropic, deepseek, auto)
|
|
20
|
+
- `plexor-config reset` - Reset to default configuration
|
|
21
|
+
|
|
22
|
+
## Instructions
|
|
23
|
+
|
|
24
|
+
1. Parse the arguments to determine the command
|
|
25
|
+
2. Read current config from ~/.plexor/config.json
|
|
26
|
+
3. Apply the requested change
|
|
27
|
+
4. Save updated config
|
|
28
|
+
5. Display confirmation
|
|
29
|
+
|
|
30
|
+
## Output
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Plexor Configuration Updated
|
|
34
|
+
============================
|
|
35
|
+
|
|
36
|
+
Local cache: Enabled → Disabled
|
|
37
|
+
|
|
38
|
+
Current settings:
|
|
39
|
+
├── Optimization: Enabled
|
|
40
|
+
├── Local cache: Disabled
|
|
41
|
+
├── Preferred provider: Auto
|
|
42
|
+
└── Telemetry: Enabled
|
|
43
|
+
```
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Enable or disable Plexor proxy (routes all traffic through Plexor API)
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Toggle Plexor proxy mode on or off.
|
|
6
|
+
|
|
7
|
+
**IMPORTANT**: Use the `AskUserQuestion` tool to present the user with these options:
|
|
8
|
+
|
|
9
|
+
Question: "Enable Plexor proxy? (routes all prompts through Plexor for optimization)"
|
|
10
|
+
Header: "Proxy"
|
|
11
|
+
Options:
|
|
12
|
+
1. **Enable** - Route all traffic through Plexor API (60-90% cost savings)
|
|
13
|
+
2. **Disable** - Direct to Anthropic (no optimization)
|
|
14
|
+
|
|
15
|
+
After the user selects an option:
|
|
16
|
+
|
|
17
|
+
### If Enable:
|
|
18
|
+
1. Update ~/.plexor/config.json: `{"enabled": true}`
|
|
19
|
+
2. Inform user to set environment variable:
|
|
20
|
+
```
|
|
21
|
+
export ANTHROPIC_BASE_URL="http://localhost:8000/gateway/anthropic"
|
|
22
|
+
```
|
|
23
|
+
3. Tell user to restart Claude Code: `claude --continue`
|
|
24
|
+
4. Explain benefits:
|
|
25
|
+
- 60-90% cost reduction via Mistral/DeepSeek/Gemini/OpenAI routing
|
|
26
|
+
- Automatic provider selection based on mode
|
|
27
|
+
- Session tracking and savings analytics
|
|
28
|
+
|
|
29
|
+
### If Disable:
|
|
30
|
+
1. Update ~/.plexor/config.json: `{"enabled": false}`
|
|
31
|
+
2. Inform user to unset environment variable:
|
|
32
|
+
```
|
|
33
|
+
unset ANTHROPIC_BASE_URL
|
|
34
|
+
```
|
|
35
|
+
3. Tell user to restart Claude Code: `claude --continue`
|
|
36
|
+
4. Note: Prompts will go directly to Anthropic at full price
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Authenticate with Plexor to enable optimization
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Plexor Login
|
|
6
|
+
|
|
7
|
+
Authenticate with your Plexor account to enable LLM cost optimization.
|
|
8
|
+
|
|
9
|
+
## Instructions
|
|
10
|
+
|
|
11
|
+
1. Check if already authenticated by reading ~/.plexor/config.json
|
|
12
|
+
2. If already authenticated and valid, show current account info and status
|
|
13
|
+
3. If not authenticated, initiate device flow:
|
|
14
|
+
a. Call POST https://api.plexor.dev/v1/auth/device-code to get device_code and user_code
|
|
15
|
+
b. Display the user code and verification URL to the user
|
|
16
|
+
c. Open https://plexor.dev/auth/device in the user's browser
|
|
17
|
+
d. Poll POST https://api.plexor.dev/v1/auth/device-token every 5 seconds
|
|
18
|
+
e. On success, save API key to ~/.plexor/config.json
|
|
19
|
+
f. Verify the key works by calling GET https://api.plexor.dev/v1/user
|
|
20
|
+
|
|
21
|
+
4. After successful authentication, configure the gateway:
|
|
22
|
+
a. Set ANTHROPIC_BASE_URL to route traffic through Plexor gateway
|
|
23
|
+
b. Inform user they need to restart Claude Code
|
|
24
|
+
|
|
25
|
+
## Config File
|
|
26
|
+
|
|
27
|
+
Location: ~/.plexor/config.json
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"version": 1,
|
|
32
|
+
"auth": {
|
|
33
|
+
"api_key": "plx_...",
|
|
34
|
+
"email": "user@example.com",
|
|
35
|
+
"tier": "beta",
|
|
36
|
+
"authenticated_at": "2025-12-16T20:00:00Z"
|
|
37
|
+
},
|
|
38
|
+
"settings": {
|
|
39
|
+
"enabled": true,
|
|
40
|
+
"preferred_provider": "auto",
|
|
41
|
+
"mode": "balanced"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Output (New User)
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Plexor Login
|
|
50
|
+
============
|
|
51
|
+
|
|
52
|
+
1. Open this URL in your browser:
|
|
53
|
+
https://plexor.dev/auth/device
|
|
54
|
+
|
|
55
|
+
2. Enter this code:
|
|
56
|
+
ABCD-1234
|
|
57
|
+
|
|
58
|
+
Waiting for authentication... ✓
|
|
59
|
+
|
|
60
|
+
✓ Authenticated as user@example.com
|
|
61
|
+
✓ Plan: Beta ($1/month)
|
|
62
|
+
✓ Plexor gateway configured
|
|
63
|
+
|
|
64
|
+
To activate, run this in your terminal:
|
|
65
|
+
|
|
66
|
+
export ANTHROPIC_BASE_URL="https://api.plexor.dev/v1/gateway/anthropic"
|
|
67
|
+
|
|
68
|
+
Then restart Claude Code. All prompts will be optimized automatically.
|
|
69
|
+
|
|
70
|
+
Run /plexor-status to see your savings.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Output (Already Authenticated)
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
Plexor Login
|
|
77
|
+
============
|
|
78
|
+
|
|
79
|
+
Already authenticated as user@example.com
|
|
80
|
+
Plan: Beta ($1/month)
|
|
81
|
+
Status: Active
|
|
82
|
+
|
|
83
|
+
Gateway URL: https://api.plexor.dev/v1/gateway/anthropic
|
|
84
|
+
|
|
85
|
+
Run /plexor-status to see your savings.
|
|
86
|
+
Run /plexor-logout to sign out.
|
|
87
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Log out from Plexor and clear credentials
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Plexor Logout
|
|
6
|
+
|
|
7
|
+
Log out from your Plexor account and clear stored credentials.
|
|
8
|
+
|
|
9
|
+
## Instructions
|
|
10
|
+
|
|
11
|
+
1. Read the current configuration from ~/.plexor/config.json
|
|
12
|
+
2. If not authenticated, inform the user they are not logged in
|
|
13
|
+
3. If authenticated:
|
|
14
|
+
a. Clear the API key from the configuration
|
|
15
|
+
b. Preserve non-sensitive settings (mode, provider preferences)
|
|
16
|
+
c. Save the updated configuration
|
|
17
|
+
4. Remind user to restore original Anthropic URL
|
|
18
|
+
5. Display confirmation message
|
|
19
|
+
|
|
20
|
+
## Output
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Plexor Logout
|
|
24
|
+
=============
|
|
25
|
+
|
|
26
|
+
✓ Successfully logged out
|
|
27
|
+
✓ API key cleared from ~/.plexor/config.json
|
|
28
|
+
|
|
29
|
+
To restore direct Anthropic access, run:
|
|
30
|
+
|
|
31
|
+
unset ANTHROPIC_BASE_URL
|
|
32
|
+
|
|
33
|
+
Then restart Claude Code.
|
|
34
|
+
|
|
35
|
+
Note: Your Plexor subscription is still active.
|
|
36
|
+
To manage billing: https://plexor.dev/billing
|
|
37
|
+
|
|
38
|
+
To use Plexor again, run /plexor-login
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Output (Not Logged In)
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Plexor Logout
|
|
45
|
+
=============
|
|
46
|
+
|
|
47
|
+
You are not currently logged in.
|
|
48
|
+
|
|
49
|
+
Run /plexor-login to authenticate.
|
|
50
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Set Plexor optimization mode (eco/balanced/quality/passthrough)
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Set the Plexor optimization mode.
|
|
6
|
+
|
|
7
|
+
**IMPORTANT**: Use the `AskUserQuestion` tool to present the user with these options:
|
|
8
|
+
|
|
9
|
+
Question: "Which optimization mode would you like to use?"
|
|
10
|
+
Header: "Mode"
|
|
11
|
+
Options:
|
|
12
|
+
1. **eco** - Maximum cost savings (Ministral 3B $0.04/$0.04 - cheapest)
|
|
13
|
+
2. **balanced** - Cost-first with fallbacks (DeepSeek → Gemini Flash → Mistral → GPT-5-nano → Claude Haiku)
|
|
14
|
+
3. **quality** - Premium models (Claude Opus 4.5 → Gemini Pro → Mistral Large → GPT-5.1)
|
|
15
|
+
4. **passthrough** - No optimization, direct passthrough to requested model
|
|
16
|
+
|
|
17
|
+
After the user selects an option:
|
|
18
|
+
1. Update ~/.plexor/config.json with the selected mode
|
|
19
|
+
2. Set the X-Plexor-Mode header for future requests
|
|
20
|
+
3. Confirm the change and explain the cost/quality trade-offs
|
|
21
|
+
|
|
22
|
+
Cost comparison (per 1M tokens input/output):
|
|
23
|
+
- eco: Mistral Ministral 3B $0.04/$0.04 (cheapest)
|
|
24
|
+
- balanced: DeepSeek $0.14/$0.28, Gemini 2.5 Flash $0.15/$0.60, Mistral Small $0.1/$0.3
|
|
25
|
+
- quality: Claude Opus 4.5 $5/$25, Gemini 2.5 Pro $1.25/$10, Mistral Large $2/$6
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Force a specific LLM provider (claude/openai/deepseek/mistral/gemini/auto)
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Force Plexor to use a specific LLM provider or enable automatic routing.
|
|
6
|
+
|
|
7
|
+
**IMPORTANT**: Use the `AskUserQuestion` tool to present the user with these options:
|
|
8
|
+
|
|
9
|
+
Question: "Which provider would you like to use?"
|
|
10
|
+
Header: "Provider"
|
|
11
|
+
Options:
|
|
12
|
+
1. **auto** - Automatic routing (cheapest first: Mistral → DeepSeek → Gemini → OpenAI → Claude)
|
|
13
|
+
2. **mistral** - Force Mistral (Ministral 3B $0.04/$0.04, Small $0.1/$0.3, Large $2/$6)
|
|
14
|
+
3. **deepseek** - Force DeepSeek ($0.14/$0.28 per MTok)
|
|
15
|
+
4. **gemini** - Force Gemini (2.0 Flash $0.10/$0.40, 2.5 Flash $0.15/$0.60, 2.5 Pro $1.25/$10)
|
|
16
|
+
5. **openai** - Force OpenAI (GPT-5-nano $0.05/$0.40, GPT-5.1 $1.25/$10)
|
|
17
|
+
6. **claude** - Force Anthropic (Haiku 4.5 $1/$5, Sonnet 4.5 $3/$15, Opus 4.5 $5/$25)
|
|
18
|
+
|
|
19
|
+
After the user selects an option:
|
|
20
|
+
1. Update ~/.plexor/config.json with the selected provider
|
|
21
|
+
2. Set the X-Plexor-Force-Provider header for future requests
|
|
22
|
+
3. Confirm the change and explain:
|
|
23
|
+
- The cost implications of the selected provider
|
|
24
|
+
- Model that will be used (based on current mode)
|
|
25
|
+
- When automatic routing might be more beneficial
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Configure Plexor settings (API URL, mode, provider preferences)
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Plexor Settings
|
|
6
|
+
|
|
7
|
+
View and configure Plexor settings. Manages the connection to the Plexor API gateway.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
- `/plexor-settings` - Show current settings
|
|
12
|
+
- `/plexor-settings api-url <url>` - Set the Plexor API URL
|
|
13
|
+
- `/plexor-settings mode <eco|balanced|quality|passthrough>` - Set optimization mode
|
|
14
|
+
- `/plexor-settings provider <auto|claude|openai|deepseek>` - Set provider preference
|
|
15
|
+
|
|
16
|
+
## Instructions
|
|
17
|
+
|
|
18
|
+
1. Read ~/.plexor/config.json
|
|
19
|
+
2. If no arguments, display current settings
|
|
20
|
+
3. If setting a value, update the config file
|
|
21
|
+
4. For api-url changes, remind user to set ANTHROPIC_BASE_URL
|
|
22
|
+
|
|
23
|
+
## Config File Location
|
|
24
|
+
|
|
25
|
+
~/.plexor/config.json
|
|
26
|
+
|
|
27
|
+
## Config Schema
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"enabled": true,
|
|
32
|
+
"apiUrl": "http://localhost:8000",
|
|
33
|
+
"apiKey": "plx_...",
|
|
34
|
+
"mode": "balanced",
|
|
35
|
+
"preferredProvider": "auto",
|
|
36
|
+
"localCacheEnabled": true,
|
|
37
|
+
"timeout": 5000
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## API URL Values
|
|
42
|
+
|
|
43
|
+
- **Development**: `http://localhost:8000`
|
|
44
|
+
- **Production**: `https://api.plexor.dev` (default)
|
|
45
|
+
|
|
46
|
+
## Output Examples
|
|
47
|
+
|
|
48
|
+
### Show settings:
|
|
49
|
+
```
|
|
50
|
+
┌─────────────────────────────────────────────┐
|
|
51
|
+
│ Plexor Settings │
|
|
52
|
+
├─────────────────────────────────────────────┤
|
|
53
|
+
│ API URL: http://localhost:8000 │
|
|
54
|
+
│ Mode: balanced │
|
|
55
|
+
│ Provider: auto │
|
|
56
|
+
│ Local Cache: enabled │
|
|
57
|
+
│ Timeout: 5000ms │
|
|
58
|
+
├─────────────────────────────────────────────┤
|
|
59
|
+
│ Proxy Status: NOT ACTIVE │
|
|
60
|
+
│ │
|
|
61
|
+
│ To activate proxy, run: │
|
|
62
|
+
│ export ANTHROPIC_BASE_URL="http://localhost:8000/gateway/anthropic"
|
|
63
|
+
│ claude --continue │
|
|
64
|
+
└─────────────────────────────────────────────┘
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Set API URL:
|
|
68
|
+
```
|
|
69
|
+
/plexor-settings api-url http://localhost:8000
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Output:
|
|
73
|
+
```
|
|
74
|
+
✓ API URL set to: http://localhost:8000
|
|
75
|
+
|
|
76
|
+
To route all traffic through Plexor, run:
|
|
77
|
+
export ANTHROPIC_BASE_URL="http://localhost:8000/gateway/anthropic"
|
|
78
|
+
claude --continue
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Set API URL (production):
|
|
82
|
+
```
|
|
83
|
+
/plexor-settings api-url https://api.plexor.dev
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Output:
|
|
87
|
+
```
|
|
88
|
+
✓ API URL set to: https://api.plexor.dev
|
|
89
|
+
|
|
90
|
+
To route all traffic through Plexor, run:
|
|
91
|
+
export ANTHROPIC_BASE_URL="https://api.plexor.dev/v1/gateway/anthropic"
|
|
92
|
+
claude --continue
|
|
93
|
+
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Show Plexor optimization statistics and savings
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Plexor Status
|
|
6
|
+
|
|
7
|
+
Display current Plexor status, configuration, and usage statistics.
|
|
8
|
+
|
|
9
|
+
## Instructions
|
|
10
|
+
|
|
11
|
+
1. Read the Plexor configuration from ~/.plexor/config.json
|
|
12
|
+
2. If not authenticated, show a message to run /plexor-login
|
|
13
|
+
3. If authenticated, call the Plexor API to get usage stats
|
|
14
|
+
4. Display a formatted summary including:
|
|
15
|
+
- Account status (Free/Pro/Team)
|
|
16
|
+
- This session: requests optimized, tokens saved, estimated savings
|
|
17
|
+
- This week: total requests, total tokens saved, total savings
|
|
18
|
+
- Current settings: optimization enabled, local cache status
|
|
19
|
+
|
|
20
|
+
## Output Format
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
┌─────────────────────────────────────────────┐
|
|
24
|
+
│ Plexor Status │
|
|
25
|
+
├─────────────────────────────────────────────┤
|
|
26
|
+
│ Account: Pro ($19/mo) │
|
|
27
|
+
│ Status: ● Active │
|
|
28
|
+
├─────────────────────────────────────────────┤
|
|
29
|
+
│ This Session │
|
|
30
|
+
│ ├── Requests: 47 │
|
|
31
|
+
│ ├── Tokens saved: 12,847 (31%) │
|
|
32
|
+
│ └── Est. savings: $0.42 │
|
|
33
|
+
├─────────────────────────────────────────────┤
|
|
34
|
+
│ This Week │
|
|
35
|
+
│ ├── Requests: 1,247 │
|
|
36
|
+
│ ├── Tokens saved: 482,938 (34%) │
|
|
37
|
+
│ └── Est. savings: $14.23 │
|
|
38
|
+
├─────────────────────────────────────────────┤
|
|
39
|
+
│ Settings │
|
|
40
|
+
│ ├── Optimization: Enabled │
|
|
41
|
+
│ ├── Local cache: Enabled │
|
|
42
|
+
│ └── Provider routing: DeepSeek preferred │
|
|
43
|
+
└─────────────────────────────────────────────┘
|
|
44
|
+
|
|
45
|
+
Dashboard: https://plexor.dev/dashboard
|
|
46
|
+
```
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plexor Claude Code Plugin - Constants
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
// API endpoints
|
|
10
|
+
PLEXOR_API_URL: process.env.PLEXOR_API_URL || 'https://api.plexor.dev',
|
|
11
|
+
PLEXOR_GATEWAY_URL: process.env.PLEXOR_GATEWAY_URL || 'https://api.plexor.dev/v1',
|
|
12
|
+
PLEXOR_AUTH_URL: 'https://plexor.dev/auth/device',
|
|
13
|
+
|
|
14
|
+
// File paths
|
|
15
|
+
PLEXOR_CONFIG_DIR: process.env.PLEXOR_CONFIG_DIR || path.join(os.homedir(), '.plexor'),
|
|
16
|
+
PLEXOR_CONFIG_FILE: path.join(
|
|
17
|
+
process.env.PLEXOR_CONFIG_DIR || path.join(os.homedir(), '.plexor'),
|
|
18
|
+
'config.json'
|
|
19
|
+
),
|
|
20
|
+
CLAUDE_COMMANDS_DIR: path.join(os.homedir(), '.claude', 'commands'),
|
|
21
|
+
|
|
22
|
+
// Config schema version
|
|
23
|
+
CONFIG_VERSION: 1,
|
|
24
|
+
|
|
25
|
+
// Default settings
|
|
26
|
+
DEFAULTS: {
|
|
27
|
+
enabled: true,
|
|
28
|
+
preferred_provider: 'auto',
|
|
29
|
+
telemetry: true,
|
|
30
|
+
local_cache: false
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
// API key prefix for identification
|
|
34
|
+
API_KEY_PREFIX: 'plx_',
|
|
35
|
+
|
|
36
|
+
// Timeouts (ms)
|
|
37
|
+
DEVICE_CODE_POLL_INTERVAL: 5000,
|
|
38
|
+
DEVICE_CODE_TIMEOUT: 900000, // 15 minutes
|
|
39
|
+
API_TIMEOUT: 30000
|
|
40
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@plexor-dev/claude-code-plugin",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"description": "LLM cost optimization plugin for Claude Code - Save up to 90% on AI costs",
|
|
5
|
+
"main": "lib/constants.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"postinstall": "node scripts/postinstall.js",
|
|
8
|
+
"preuninstall": "node scripts/uninstall.js",
|
|
9
|
+
"test": "node --test"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"commands/",
|
|
13
|
+
"scripts/",
|
|
14
|
+
"lib/",
|
|
15
|
+
"README.md",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"claude",
|
|
23
|
+
"claude-code",
|
|
24
|
+
"llm",
|
|
25
|
+
"optimization",
|
|
26
|
+
"plexor",
|
|
27
|
+
"cost-savings",
|
|
28
|
+
"ai",
|
|
29
|
+
"anthropic"
|
|
30
|
+
],
|
|
31
|
+
"author": "Plexor <hello@plexor.dev>",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/plexor-dev/claude-code-plugin"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/plexor-dev/claude-code-plugin/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://plexor.dev",
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=16"
|
|
43
|
+
},
|
|
44
|
+
"os": [
|
|
45
|
+
"darwin",
|
|
46
|
+
"linux",
|
|
47
|
+
"win32"
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Plexor Claude Code Plugin - Postinstall Script
|
|
5
|
+
*
|
|
6
|
+
* Copies slash commands to ~/.claude/commands/ and creates
|
|
7
|
+
* the ~/.plexor/ configuration directory.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
|
|
14
|
+
const COMMANDS_SOURCE = path.join(__dirname, '..', 'commands');
|
|
15
|
+
const CLAUDE_COMMANDS_DIR = path.join(os.homedir(), '.claude', 'commands');
|
|
16
|
+
const PLEXOR_CONFIG_DIR = path.join(os.homedir(), '.plexor');
|
|
17
|
+
|
|
18
|
+
function main() {
|
|
19
|
+
try {
|
|
20
|
+
// Create ~/.claude/commands/ if not exists
|
|
21
|
+
fs.mkdirSync(CLAUDE_COMMANDS_DIR, { recursive: true });
|
|
22
|
+
|
|
23
|
+
// Create ~/.plexor/ with secure permissions (owner only)
|
|
24
|
+
fs.mkdirSync(PLEXOR_CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
25
|
+
|
|
26
|
+
// Get list of command files
|
|
27
|
+
const files = fs.readdirSync(COMMANDS_SOURCE)
|
|
28
|
+
.filter(f => f.endsWith('.md'));
|
|
29
|
+
|
|
30
|
+
if (files.length === 0) {
|
|
31
|
+
console.error('No command files found in package. Installation may be corrupt.');
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const installed = [];
|
|
36
|
+
const backed_up = [];
|
|
37
|
+
|
|
38
|
+
for (const file of files) {
|
|
39
|
+
const src = path.join(COMMANDS_SOURCE, file);
|
|
40
|
+
const dest = path.join(CLAUDE_COMMANDS_DIR, file);
|
|
41
|
+
|
|
42
|
+
// Backup existing file if present and different
|
|
43
|
+
if (fs.existsSync(dest)) {
|
|
44
|
+
const existingContent = fs.readFileSync(dest, 'utf8');
|
|
45
|
+
const newContent = fs.readFileSync(src, 'utf8');
|
|
46
|
+
|
|
47
|
+
if (existingContent !== newContent) {
|
|
48
|
+
const backupPath = dest + '.backup';
|
|
49
|
+
fs.copyFileSync(dest, backupPath);
|
|
50
|
+
backed_up.push(file);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fs.copyFileSync(src, dest);
|
|
55
|
+
installed.push(file.replace('.md', ''));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Print success message
|
|
59
|
+
console.log('');
|
|
60
|
+
console.log(' ╔═══════════════════════════════════════════════════════════╗');
|
|
61
|
+
console.log(' ║ ║');
|
|
62
|
+
console.log(' ║ Plexor Claude Code Plugin installed successfully! ║');
|
|
63
|
+
console.log(' ║ ║');
|
|
64
|
+
console.log(' ╚═══════════════════════════════════════════════════════════╝');
|
|
65
|
+
console.log('');
|
|
66
|
+
console.log(' Commands installed to ~/.claude/commands/:');
|
|
67
|
+
installed.forEach(cmd => {
|
|
68
|
+
console.log(` /${cmd}`);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
if (backed_up.length > 0) {
|
|
72
|
+
console.log('');
|
|
73
|
+
console.log(' Existing files backed up (.backup):');
|
|
74
|
+
backed_up.forEach(f => console.log(` ${f}`));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log('');
|
|
78
|
+
console.log(' Next steps:');
|
|
79
|
+
console.log(' 1. Open Claude Code');
|
|
80
|
+
console.log(' 2. Run /plexor-login to authenticate');
|
|
81
|
+
console.log(' 3. Start saving on LLM costs!');
|
|
82
|
+
console.log('');
|
|
83
|
+
console.log(' Documentation: https://plexor.dev/docs');
|
|
84
|
+
console.log('');
|
|
85
|
+
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error('');
|
|
88
|
+
console.error(' Plexor plugin installation failed');
|
|
89
|
+
console.error('');
|
|
90
|
+
console.error(` Error: ${error.message}`);
|
|
91
|
+
console.error('');
|
|
92
|
+
console.error(' Troubleshooting:');
|
|
93
|
+
console.error(' - Ensure you have write access to ~/.claude/commands/');
|
|
94
|
+
console.error(' - Try running with sudo if permission denied');
|
|
95
|
+
console.error('');
|
|
96
|
+
console.error(' Report issues: https://github.com/plexor-ai/claude-code-plugin/issues');
|
|
97
|
+
console.error('');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
main();
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Plexor Claude Code Plugin - Uninstall Script
|
|
5
|
+
*
|
|
6
|
+
* Removes slash commands from ~/.claude/commands/
|
|
7
|
+
* Optionally restores backups if they exist.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
|
|
14
|
+
const COMMANDS_SOURCE = path.join(__dirname, '..', 'commands');
|
|
15
|
+
const CLAUDE_COMMANDS_DIR = path.join(os.homedir(), '.claude', 'commands');
|
|
16
|
+
|
|
17
|
+
function main() {
|
|
18
|
+
try {
|
|
19
|
+
// Get list of our command files
|
|
20
|
+
const files = fs.readdirSync(COMMANDS_SOURCE)
|
|
21
|
+
.filter(f => f.endsWith('.md'));
|
|
22
|
+
|
|
23
|
+
const removed = [];
|
|
24
|
+
const restored = [];
|
|
25
|
+
|
|
26
|
+
for (const file of files) {
|
|
27
|
+
const dest = path.join(CLAUDE_COMMANDS_DIR, file);
|
|
28
|
+
const backupPath = dest + '.backup';
|
|
29
|
+
|
|
30
|
+
if (fs.existsSync(dest)) {
|
|
31
|
+
fs.unlinkSync(dest);
|
|
32
|
+
removed.push(file.replace('.md', ''));
|
|
33
|
+
|
|
34
|
+
// Restore backup if it exists
|
|
35
|
+
if (fs.existsSync(backupPath)) {
|
|
36
|
+
fs.renameSync(backupPath, dest);
|
|
37
|
+
restored.push(file);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (removed.length > 0) {
|
|
43
|
+
console.log('');
|
|
44
|
+
console.log(' Plexor plugin uninstalled');
|
|
45
|
+
console.log('');
|
|
46
|
+
console.log(' Removed commands:');
|
|
47
|
+
removed.forEach(cmd => console.log(` /${cmd}`));
|
|
48
|
+
|
|
49
|
+
if (restored.length > 0) {
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(' Restored from backup:');
|
|
52
|
+
restored.forEach(f => console.log(` ${f}`));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.log('');
|
|
56
|
+
console.log(' Note: ~/.plexor/ config directory was preserved.');
|
|
57
|
+
console.log(' To remove it: rm -rf ~/.plexor');
|
|
58
|
+
console.log('');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
} catch (error) {
|
|
62
|
+
// Don't fail uninstall on errors - just warn
|
|
63
|
+
console.warn(` Warning: Could not fully uninstall: ${error.message}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
main();
|