@kamel-ahmed/proxy-claude 1.0.4 → 1.0.6
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/README.md +207 -44
- package/package.json +12 -7
- package/src/cli/accounts.js +1 -1
- package/src/cli/onboard.js +180 -69
package/README.md
CHANGED
|
@@ -4,12 +4,9 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/@kamel-ahmed/proxy-claude)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
|
-
<a href="https://buymeacoffee.com/badrinarayanans" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="50"></a>
|
|
8
7
|
|
|
9
8
|
A proxy server that exposes an **Anthropic-compatible API** backed by **Antigravity's Cloud Code**, letting you use Claude and Gemini models with **Claude Code CLI**.
|
|
10
9
|
|
|
11
|
-

|
|
12
|
-
|
|
13
10
|
## How It Works
|
|
14
11
|
|
|
15
12
|
```
|
|
@@ -28,65 +25,234 @@ A proxy server that exposes an **Anthropic-compatible API** backed by **Antigrav
|
|
|
28
25
|
|
|
29
26
|
## Prerequisites
|
|
30
27
|
|
|
31
|
-
- **Node.js** 18 or later
|
|
32
|
-
- **
|
|
28
|
+
- **Node.js** 18 or later (download from [nodejs.org](https://nodejs.org))
|
|
29
|
+
- **Claude Code CLI** (installed automatically by setup wizard)
|
|
30
|
+
- Google account(s) for authentication
|
|
33
31
|
|
|
34
32
|
---
|
|
35
33
|
|
|
36
34
|
## Installation
|
|
37
35
|
|
|
38
|
-
###
|
|
36
|
+
### Windows Installation
|
|
37
|
+
|
|
38
|
+
**Step 1: Install Node.js**
|
|
39
|
+
|
|
40
|
+
1. Download Node.js 18+ from [nodejs.org](https://nodejs.org)
|
|
41
|
+
2. Run the installer and follow the setup wizard
|
|
42
|
+
3. Restart your computer (or just close & reopen PowerShell)
|
|
43
|
+
4. Verify installation in PowerShell:
|
|
44
|
+
```powershell
|
|
45
|
+
node --version
|
|
46
|
+
npm --version
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Step 2: Install proxy-claude**
|
|
50
|
+
|
|
51
|
+
Open PowerShell or Command Prompt and run:
|
|
52
|
+
|
|
53
|
+
```powershell
|
|
54
|
+
npm install -g @kamel-ahmed/proxy-claude
|
|
55
|
+
proxy-claude init
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Step 3: Complete Setup Wizard**
|
|
59
|
+
|
|
60
|
+
The wizard will:
|
|
61
|
+
- ✅ Check Node.js and Claude Code CLI
|
|
62
|
+
- ✅ Add your Google account(s)
|
|
63
|
+
- ✅ Pick models for each tier
|
|
64
|
+
- ✅ Auto-configure settings
|
|
39
65
|
|
|
40
|
-
|
|
66
|
+
**Step 4: Start Using**
|
|
67
|
+
|
|
68
|
+
```powershell
|
|
69
|
+
proxy-claude
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
That's it! Claude Code will launch connected to the proxy.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### macOS/Linux Installation
|
|
77
|
+
|
|
78
|
+
**Step 1: Install Node.js** (if not already installed)
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# macOS with Homebrew
|
|
82
|
+
brew install node
|
|
83
|
+
|
|
84
|
+
# Or download from https://nodejs.org
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Step 2: Install proxy-claude**
|
|
41
88
|
|
|
42
89
|
```bash
|
|
43
|
-
# Install globally (recommended)
|
|
44
90
|
npm install -g @kamel-ahmed/proxy-claude
|
|
45
|
-
proxy-claude
|
|
91
|
+
proxy-claude init
|
|
92
|
+
```
|
|
46
93
|
|
|
47
|
-
|
|
48
|
-
npx @kamel-ahmed/proxy-claude setup
|
|
94
|
+
**Step 3: Start Using**
|
|
49
95
|
|
|
50
|
-
|
|
51
|
-
|
|
96
|
+
```bash
|
|
97
|
+
proxy-claude
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
### Quick Install (Recommended)
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Install globally
|
|
106
|
+
npm install -g @kamel-ahmed/proxy-claude
|
|
107
|
+
|
|
108
|
+
# Run setup wizard
|
|
109
|
+
proxy-claude init
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The setup wizard will:
|
|
113
|
+
1. ✅ Check prerequisites (Node.js, Claude Code CLI)
|
|
114
|
+
2. ✅ Help you add Google account(s)
|
|
115
|
+
3. ✅ Let you pick models for each tier (Opus, Sonnet, Haiku)
|
|
116
|
+
4. ✅ Auto-configure `~/.claude/settings.json`
|
|
117
|
+
|
|
118
|
+
After setup, just run:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
proxy-claude
|
|
52
122
|
```
|
|
53
123
|
|
|
54
|
-
|
|
124
|
+
This will:
|
|
125
|
+
1. Start the proxy server in the background
|
|
126
|
+
2. Wait for the server to be ready
|
|
127
|
+
3. Launch Claude Code CLI connected to the proxy
|
|
128
|
+
4. Automatically shut down the proxy when you exit
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
### Quick Install (All Platforms)
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Install globally
|
|
136
|
+
npm install -g @kamel-ahmed/proxy-claude
|
|
137
|
+
|
|
138
|
+
# Run setup wizard
|
|
139
|
+
proxy-claude init
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The setup wizard will:
|
|
143
|
+
1. ✅ Check prerequisites (Node.js, Claude Code CLI)
|
|
144
|
+
2. ✅ Help you add Google account(s)
|
|
145
|
+
3. ✅ Let you pick models for each tier (Opus, Sonnet, Haiku)
|
|
146
|
+
4. ✅ Auto-configure `~/.claude/settings.json`
|
|
147
|
+
|
|
148
|
+
After setup, just run:
|
|
55
149
|
|
|
56
150
|
```bash
|
|
57
151
|
proxy-claude
|
|
58
152
|
```
|
|
59
153
|
|
|
60
|
-
|
|
61
|
-
1. Start the proxy server in the background
|
|
62
|
-
2. Wait for the server to be ready
|
|
63
|
-
3. Launch
|
|
64
|
-
4. Automatically shut down the proxy when you exit
|
|
154
|
+
This will:
|
|
155
|
+
1. Start the proxy server in the background
|
|
156
|
+
2. Wait for the server to be ready
|
|
157
|
+
3. Launch Claude Code CLI connected to the proxy
|
|
158
|
+
4. Automatically shut down the proxy when you exit
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Troubleshooting
|
|
163
|
+
|
|
164
|
+
### Windows: "npm: The term 'npm' is not recognized"
|
|
165
|
+
|
|
166
|
+
**Solution:** Node.js wasn't installed correctly or PowerShell needs to be restarted.
|
|
167
|
+
|
|
168
|
+
1. Download and reinstall Node.js from [nodejs.org](https://nodejs.org)
|
|
169
|
+
2. Close PowerShell/Command Prompt completely
|
|
170
|
+
3. Reopen PowerShell as Administrator
|
|
171
|
+
4. Try again: `npm --version`
|
|
172
|
+
|
|
173
|
+
### Windows: "proxy-claude: The term 'proxy-claude' is not recognized"
|
|
174
|
+
|
|
175
|
+
**Solution:** npm install path isn't in your PATH environment variable.
|
|
176
|
+
|
|
177
|
+
```powershell
|
|
178
|
+
# Find where npm installed it
|
|
179
|
+
npm config get prefix
|
|
180
|
+
|
|
181
|
+
# Add to PATH (replace C:\Users\YourUsername\AppData\Roaming\npm if different):
|
|
182
|
+
$env:Path += ";C:\Users\$env:USERNAME\AppData\Roaming\npm"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Then close and reopen PowerShell.
|
|
186
|
+
|
|
187
|
+
### Port Already in Use
|
|
65
188
|
|
|
66
|
-
|
|
189
|
+
If port 8080 is already in use, specify a different port:
|
|
67
190
|
|
|
68
191
|
```bash
|
|
69
|
-
# Use a custom port
|
|
70
192
|
PORT=3000 proxy-claude
|
|
193
|
+
# or
|
|
194
|
+
proxy-claude --port 3000
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### "Claude Code CLI not found" Error
|
|
71
198
|
|
|
72
|
-
|
|
73
|
-
|
|
199
|
+
The setup wizard will automatically install Claude Code CLI for you. If it fails:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
npm install -g @anthropic-ai/claude-code
|
|
74
203
|
```
|
|
75
204
|
|
|
76
|
-
|
|
205
|
+
### Settings Not Persisting
|
|
77
206
|
|
|
78
|
-
|
|
207
|
+
The wizard auto-configures `~/.claude/settings.json`. You can verify it was created:
|
|
208
|
+
|
|
209
|
+
**Windows:**
|
|
210
|
+
```powershell
|
|
211
|
+
notepad "$env:USERPROFILE\.claude\settings.json"
|
|
212
|
+
```
|
|
79
213
|
|
|
214
|
+
**macOS/Linux:**
|
|
80
215
|
```bash
|
|
81
|
-
|
|
82
|
-
|
|
216
|
+
cat ~/.claude/settings.json
|
|
217
|
+
```
|
|
83
218
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
### CLI Commands
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
proxy-claude # Start proxy + Claude Code (default)
|
|
225
|
+
proxy-claude init # Run setup wizard
|
|
226
|
+
proxy-claude start # Start proxy server only
|
|
227
|
+
proxy-claude stop # Stop proxy server
|
|
228
|
+
proxy-claude status # Check if proxy is running
|
|
229
|
+
proxy-claude accounts # Manage Google accounts
|
|
230
|
+
proxy-claude refresh # Refresh account tokens
|
|
231
|
+
proxy-claude --help # Show all commands
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Custom port:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
PORT=3000 proxy-claude
|
|
238
|
+
proxy-claude --port 3000
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Cross-Platform Support
|
|
242
|
+
|
|
243
|
+
Works on **Windows**, **macOS**, and **Linux** with full feature parity.
|
|
244
|
+
|
|
245
|
+
### Alternative: npx (No Install)
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Run directly without installing
|
|
249
|
+
npx @kamel-ahmed/proxy-claude
|
|
250
|
+
|
|
251
|
+
# Or just start the server
|
|
252
|
+
npx @kamel-ahmed/proxy-claude start
|
|
87
253
|
```
|
|
88
254
|
|
|
89
|
-
###
|
|
255
|
+
### Development: Clone Repository
|
|
90
256
|
|
|
91
257
|
```bash
|
|
92
258
|
git clone https://github.com/badri-s2001/antigravity-claude-proxy.git
|
|
@@ -99,22 +265,23 @@ npm start
|
|
|
99
265
|
|
|
100
266
|
## Quick Start
|
|
101
267
|
|
|
102
|
-
|
|
268
|
+
If you used `proxy-claude init`, you're already set up! Just run:
|
|
103
269
|
|
|
104
270
|
```bash
|
|
105
|
-
|
|
106
|
-
|
|
271
|
+
proxy-claude
|
|
272
|
+
```
|
|
107
273
|
|
|
108
|
-
|
|
109
|
-
npx @kamel-ahmed/proxy-claude start
|
|
274
|
+
### Manual Setup (Alternative)
|
|
110
275
|
|
|
111
|
-
|
|
112
|
-
|
|
276
|
+
#### 1. Start the Proxy Server
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
proxy-claude start
|
|
113
280
|
```
|
|
114
281
|
|
|
115
282
|
The server runs on `http://localhost:8080` by default.
|
|
116
283
|
|
|
117
|
-
|
|
284
|
+
#### 2. Link Account(s)
|
|
118
285
|
|
|
119
286
|
Choose one of the following methods to authorize the proxy:
|
|
120
287
|
|
|
@@ -616,8 +783,4 @@ This project is based on insights and code from:
|
|
|
616
783
|
|
|
617
784
|
MIT
|
|
618
785
|
|
|
619
|
-
---
|
|
620
|
-
|
|
621
|
-
## Star History
|
|
622
|
-
|
|
623
|
-
[](https://www.star-history.com/#badrisnarayanan/antigravity-claude-proxy&type=date&legend=top-left)
|
|
786
|
+
---
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kamel-ahmed/proxy-claude",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"description": "Cross-platform CLI proxy for Antigravity Cloud Code. Use Claude & Gemini models with Claude Code CLI on Windows, macOS, and Linux.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -45,17 +45,22 @@
|
|
|
45
45
|
"anthropic",
|
|
46
46
|
"antigravity",
|
|
47
47
|
"proxy",
|
|
48
|
-
"
|
|
48
|
+
"gemini",
|
|
49
|
+
"claude-code",
|
|
50
|
+
"cross-platform",
|
|
51
|
+
"windows",
|
|
52
|
+
"macos",
|
|
53
|
+
"linux"
|
|
49
54
|
],
|
|
50
|
-
"author": "Kamel Ahmed",
|
|
55
|
+
"author": "Kamel Ahmed <kamel.ahmed.mostafa.kamel@gmail.com>",
|
|
51
56
|
"license": "MIT",
|
|
52
57
|
"repository": {
|
|
53
58
|
"type": "git",
|
|
54
|
-
"url": "git+https://github.com/
|
|
59
|
+
"url": "git+https://github.com/KamelAhmed01/antigravity-claude-proxy.git"
|
|
55
60
|
},
|
|
56
|
-
"homepage": "https://github.com/
|
|
61
|
+
"homepage": "https://github.com/KamelAhmed01/antigravity-claude-proxy#readme",
|
|
57
62
|
"bugs": {
|
|
58
|
-
"url": "https://github.com/
|
|
63
|
+
"url": "https://github.com/KamelAhmed01/antigravity-claude-proxy/issues"
|
|
59
64
|
},
|
|
60
65
|
"publishConfig": {
|
|
61
66
|
"access": "public"
|
package/src/cli/accounts.js
CHANGED
package/src/cli/onboard.js
CHANGED
|
@@ -50,41 +50,36 @@ const ACCOUNTS_FILE = path.join(CONFIG_DIR, 'accounts.json');
|
|
|
50
50
|
const CLAUDE_CONFIG_DIR = path.join(PLATFORM.homeDir, '.claude');
|
|
51
51
|
const CLAUDE_SETTINGS_FILE = path.join(CLAUDE_CONFIG_DIR, 'settings.json');
|
|
52
52
|
|
|
53
|
-
//
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
53
|
+
// All available models in Antigravity (fetched dynamically, but this is a fallback)
|
|
54
|
+
const ALL_MODELS = [
|
|
55
|
+
// Claude models
|
|
56
|
+
{ id: 'claude-opus-4-5-thinking', family: 'claude', tier: 'opus', description: 'Claude Opus 4.5 with thinking' },
|
|
57
|
+
{ id: 'claude-sonnet-4-5-thinking', family: 'claude', tier: 'sonnet', description: 'Claude Sonnet 4.5 with thinking' },
|
|
58
|
+
{ id: 'claude-sonnet-4-5', family: 'claude', tier: 'sonnet', description: 'Claude Sonnet 4.5' },
|
|
59
|
+
// Gemini models
|
|
60
|
+
{ id: 'gemini-3-pro-high', family: 'gemini', tier: 'opus', description: 'Gemini 3 Pro High (best quality)' },
|
|
61
|
+
{ id: 'gemini-3-pro-low', family: 'gemini', tier: 'sonnet', description: 'Gemini 3 Pro Low' },
|
|
62
|
+
{ id: 'gemini-3-flash', family: 'gemini', tier: 'sonnet', description: 'Gemini 3 Flash (fast)' },
|
|
63
|
+
{ id: 'gemini-2.5-flash-lite', family: 'gemini', tier: 'haiku', description: 'Gemini 2.5 Flash Lite (fastest)' },
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
// Model tier descriptions
|
|
67
|
+
const TIER_INFO = {
|
|
68
|
+
opus: {
|
|
69
|
+
name: 'Opus (Primary)',
|
|
70
|
+
description: 'Main model for complex tasks',
|
|
71
|
+
envKey: 'ANTHROPIC_DEFAULT_OPUS_MODEL',
|
|
65
72
|
},
|
|
66
|
-
|
|
67
|
-
name: '
|
|
68
|
-
description: '
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
73
|
+
sonnet: {
|
|
74
|
+
name: 'Sonnet (Default)',
|
|
75
|
+
description: 'Balanced model for most tasks',
|
|
76
|
+
envKey: 'ANTHROPIC_DEFAULT_SONNET_MODEL',
|
|
77
|
+
},
|
|
78
|
+
haiku: {
|
|
79
|
+
name: 'Haiku (Fast)',
|
|
80
|
+
description: 'Quick model for simple tasks & background',
|
|
81
|
+
envKey: 'ANTHROPIC_DEFAULT_HAIKU_MODEL',
|
|
76
82
|
},
|
|
77
|
-
balanced: {
|
|
78
|
-
name: 'Balanced (Claude + Gemini)',
|
|
79
|
-
description: 'Claude for main tasks, Gemini for background',
|
|
80
|
-
models: {
|
|
81
|
-
ANTHROPIC_MODEL: 'claude-sonnet-4-5-thinking',
|
|
82
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL: 'claude-opus-4-5-thinking',
|
|
83
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL: 'claude-sonnet-4-5-thinking',
|
|
84
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL: 'gemini-2.5-flash-lite',
|
|
85
|
-
CLAUDE_CODE_SUBAGENT_MODEL: 'gemini-3-flash',
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
83
|
};
|
|
89
84
|
|
|
90
85
|
/**
|
|
@@ -215,6 +210,65 @@ function getExistingAccounts() {
|
|
|
215
210
|
return [];
|
|
216
211
|
}
|
|
217
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Fetch available models from the API using account token
|
|
215
|
+
*/
|
|
216
|
+
async function fetchAvailableModels(accounts) {
|
|
217
|
+
if (!accounts || accounts.length === 0) {
|
|
218
|
+
return ALL_MODELS;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
// Get token from first account
|
|
223
|
+
const account = accounts[0];
|
|
224
|
+
const token = account.accessToken;
|
|
225
|
+
|
|
226
|
+
if (!token) {
|
|
227
|
+
return ALL_MODELS;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Import the model API
|
|
231
|
+
const { fetchAvailableModels: fetchModels } = await import('../cloudcode/model-api.js');
|
|
232
|
+
const data = await fetchModels(token);
|
|
233
|
+
|
|
234
|
+
if (data && data.models) {
|
|
235
|
+
const models = [];
|
|
236
|
+
for (const [modelId, modelData] of Object.entries(data.models)) {
|
|
237
|
+
// Only include Claude and Gemini models
|
|
238
|
+
if (!modelId.includes('claude') && !modelId.includes('gemini')) continue;
|
|
239
|
+
|
|
240
|
+
// Determine family
|
|
241
|
+
const family = modelId.includes('claude') ? 'claude' : 'gemini';
|
|
242
|
+
|
|
243
|
+
// Determine tier based on model name
|
|
244
|
+
let tier = 'sonnet';
|
|
245
|
+
if (modelId.includes('opus') || modelId.includes('pro-high')) tier = 'opus';
|
|
246
|
+
else if (modelId.includes('haiku') || modelId.includes('flash-lite')) tier = 'haiku';
|
|
247
|
+
|
|
248
|
+
// Check if model has quota (remaining > 0)
|
|
249
|
+
const hasQuota = modelData.remainingFraction === undefined || modelData.remainingFraction > 0;
|
|
250
|
+
|
|
251
|
+
models.push({
|
|
252
|
+
id: modelId,
|
|
253
|
+
family,
|
|
254
|
+
tier,
|
|
255
|
+
description: modelData.displayName || modelId,
|
|
256
|
+
hasQuota,
|
|
257
|
+
remainingFraction: modelData.remainingFraction,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (models.length > 0) {
|
|
262
|
+
return models;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
} catch (error) {
|
|
266
|
+
print(`Could not fetch models from API: ${error.message}`, 'warn');
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return ALL_MODELS;
|
|
270
|
+
}
|
|
271
|
+
|
|
218
272
|
/**
|
|
219
273
|
* Add Google account via OAuth
|
|
220
274
|
*/
|
|
@@ -260,9 +314,69 @@ function saveClaudeSettings(settings) {
|
|
|
260
314
|
}
|
|
261
315
|
|
|
262
316
|
/**
|
|
263
|
-
*
|
|
317
|
+
* Select a model for a specific tier
|
|
318
|
+
*/
|
|
319
|
+
async function selectModelForTier(rl, tier, availableModels) {
|
|
320
|
+
const tierInfo = TIER_INFO[tier];
|
|
321
|
+
console.log('');
|
|
322
|
+
console.log(`${COLORS.bold}${tierInfo.name}${COLORS.reset} - ${COLORS.dim}${tierInfo.description}${COLORS.reset}`);
|
|
323
|
+
console.log('');
|
|
324
|
+
|
|
325
|
+
// Filter models that are suitable for this tier or higher
|
|
326
|
+
// opus can use any model, sonnet can use sonnet/haiku, haiku uses haiku
|
|
327
|
+
const tierPriority = { opus: 3, sonnet: 2, haiku: 1 };
|
|
328
|
+
const minTier = tierPriority[tier];
|
|
329
|
+
|
|
330
|
+
const suitableModels = availableModels.filter(m => {
|
|
331
|
+
const modelTier = tierPriority[m.tier] || 2;
|
|
332
|
+
return modelTier >= minTier - 1; // Allow one tier lower
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
// Sort: models with quota first, then by family (claude first), then by tier
|
|
336
|
+
suitableModels.sort((a, b) => {
|
|
337
|
+
// Quota status
|
|
338
|
+
if (a.hasQuota !== b.hasQuota) return a.hasQuota ? -1 : 1;
|
|
339
|
+
// Family (claude first for opus/sonnet, gemini first for haiku)
|
|
340
|
+
if (tier === 'haiku') {
|
|
341
|
+
if (a.family !== b.family) return a.family === 'gemini' ? -1 : 1;
|
|
342
|
+
} else {
|
|
343
|
+
if (a.family !== b.family) return a.family === 'claude' ? -1 : 1;
|
|
344
|
+
}
|
|
345
|
+
// Tier priority
|
|
346
|
+
return (tierPriority[b.tier] || 0) - (tierPriority[a.tier] || 0);
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Display models
|
|
350
|
+
console.log(`${COLORS.dim}Available models:${COLORS.reset}`);
|
|
351
|
+
suitableModels.forEach((model, index) => {
|
|
352
|
+
const quotaStatus = model.hasQuota === false
|
|
353
|
+
? `${COLORS.red}(no quota)${COLORS.reset}`
|
|
354
|
+
: model.remainingFraction !== undefined
|
|
355
|
+
? `${COLORS.green}(${Math.round(model.remainingFraction * 100)}% quota)${COLORS.reset}`
|
|
356
|
+
: '';
|
|
357
|
+
const familyBadge = model.family === 'claude'
|
|
358
|
+
? `${COLORS.magenta}[Claude]${COLORS.reset}`
|
|
359
|
+
: `${COLORS.blue}[Gemini]${COLORS.reset}`;
|
|
360
|
+
console.log(` ${COLORS.cyan}${index + 1}.${COLORS.reset} ${model.id} ${familyBadge} ${quotaStatus}`);
|
|
361
|
+
});
|
|
362
|
+
console.log('');
|
|
363
|
+
|
|
364
|
+
// Default to first model with quota
|
|
365
|
+
const defaultIndex = suitableModels.findIndex(m => m.hasQuota !== false) + 1 || 1;
|
|
366
|
+
|
|
367
|
+
const choice = await prompt(rl, `Select model for ${tier} (1-${suitableModels.length})`, String(defaultIndex));
|
|
368
|
+
const index = parseInt(choice, 10) - 1;
|
|
369
|
+
|
|
370
|
+
if (index >= 0 && index < suitableModels.length) {
|
|
371
|
+
return suitableModels[index].id;
|
|
372
|
+
}
|
|
373
|
+
return suitableModels[0]?.id || ALL_MODELS.find(m => m.tier === tier)?.id;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Configure Claude Code settings with selected models
|
|
264
378
|
*/
|
|
265
|
-
function
|
|
379
|
+
function configureClaudeSettingsWithModels(modelConfig, port = 8080) {
|
|
266
380
|
const existing = loadClaudeSettings();
|
|
267
381
|
|
|
268
382
|
const newSettings = {
|
|
@@ -271,7 +385,11 @@ function configureClaudeSettings(modelPreset, port = 8080) {
|
|
|
271
385
|
...(existing.env || {}),
|
|
272
386
|
ANTHROPIC_AUTH_TOKEN: 'proxy-claude',
|
|
273
387
|
ANTHROPIC_BASE_URL: `http://localhost:${port}`,
|
|
274
|
-
|
|
388
|
+
ANTHROPIC_MODEL: modelConfig.sonnet, // Default model is sonnet
|
|
389
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: modelConfig.opus,
|
|
390
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: modelConfig.sonnet,
|
|
391
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: modelConfig.haiku,
|
|
392
|
+
CLAUDE_CODE_SUBAGENT_MODEL: modelConfig.haiku, // Subagent uses haiku for efficiency
|
|
275
393
|
ENABLE_EXPERIMENTAL_MCP_CLI: 'true',
|
|
276
394
|
}
|
|
277
395
|
};
|
|
@@ -286,33 +404,9 @@ function configureClaudeSettings(modelPreset, port = 8080) {
|
|
|
286
404
|
}
|
|
287
405
|
|
|
288
406
|
/**
|
|
289
|
-
*
|
|
407
|
+
* Print summary with selected models
|
|
290
408
|
*/
|
|
291
|
-
|
|
292
|
-
console.log('');
|
|
293
|
-
console.log(`${COLORS.bold}Available model configurations:${COLORS.reset}`);
|
|
294
|
-
console.log('');
|
|
295
|
-
|
|
296
|
-
const presets = Object.entries(MODEL_PRESETS);
|
|
297
|
-
presets.forEach(([key, preset], index) => {
|
|
298
|
-
console.log(` ${COLORS.cyan}${index + 1}.${COLORS.reset} ${COLORS.bold}${preset.name}${COLORS.reset}`);
|
|
299
|
-
console.log(` ${COLORS.dim}${preset.description}${COLORS.reset}`);
|
|
300
|
-
});
|
|
301
|
-
console.log('');
|
|
302
|
-
|
|
303
|
-
const choice = await prompt(rl, 'Select configuration (1-3)', '1');
|
|
304
|
-
const index = parseInt(choice, 10) - 1;
|
|
305
|
-
|
|
306
|
-
if (index >= 0 && index < presets.length) {
|
|
307
|
-
return presets[index];
|
|
308
|
-
}
|
|
309
|
-
return presets[0]; // Default to first option
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Print summary
|
|
314
|
-
*/
|
|
315
|
-
function printSummary(accounts, modelPreset, port) {
|
|
409
|
+
function printSummary(accounts, modelConfig, port) {
|
|
316
410
|
console.log('');
|
|
317
411
|
console.log(`${COLORS.green}╔══════════════════════════════════════════════════════════╗${COLORS.reset}`);
|
|
318
412
|
console.log(`${COLORS.green}║${COLORS.reset} ${COLORS.bold}${COLORS.green}Setup Complete!${COLORS.reset} ${COLORS.green}║${COLORS.reset}`);
|
|
@@ -321,7 +415,9 @@ function printSummary(accounts, modelPreset, port) {
|
|
|
321
415
|
|
|
322
416
|
console.log(`${COLORS.bold}Configuration Summary:${COLORS.reset}`);
|
|
323
417
|
console.log(` ${COLORS.dim}•${COLORS.reset} Accounts: ${accounts.length} configured`);
|
|
324
|
-
console.log(` ${COLORS.dim}•${COLORS.reset}
|
|
418
|
+
console.log(` ${COLORS.dim}•${COLORS.reset} Opus model: ${COLORS.cyan}${modelConfig.opus}${COLORS.reset}`);
|
|
419
|
+
console.log(` ${COLORS.dim}•${COLORS.reset} Sonnet model: ${COLORS.cyan}${modelConfig.sonnet}${COLORS.reset}`);
|
|
420
|
+
console.log(` ${COLORS.dim}•${COLORS.reset} Haiku model: ${COLORS.cyan}${modelConfig.haiku}${COLORS.reset}`);
|
|
325
421
|
console.log(` ${COLORS.dim}•${COLORS.reset} Proxy port: ${port}`);
|
|
326
422
|
console.log(` ${COLORS.dim}•${COLORS.reset} Settings saved to: ${CLAUDE_SETTINGS_FILE}`);
|
|
327
423
|
console.log('');
|
|
@@ -422,11 +518,26 @@ export async function runOnboarding(options = {}) {
|
|
|
422
518
|
// Step 3: Model Configuration
|
|
423
519
|
printStep(++currentStep, totalSteps, 'Model Configuration');
|
|
424
520
|
|
|
425
|
-
print('
|
|
426
|
-
|
|
521
|
+
print('Fetching available models from your account...', 'step');
|
|
522
|
+
const availableModels = await fetchAvailableModels(accounts);
|
|
523
|
+
print(`Found ${availableModels.length} models available`, 'success');
|
|
524
|
+
|
|
525
|
+
console.log('');
|
|
526
|
+
print('Now select a model for each tier. Models with quota are shown first.', 'info');
|
|
527
|
+
print(`${COLORS.dim}Tip: Use Gemini for Haiku to save your Claude quota!${COLORS.reset}`, 'info');
|
|
528
|
+
|
|
529
|
+
// Select model for each tier
|
|
530
|
+
const modelConfig = {
|
|
531
|
+
opus: await selectModelForTier(rl, 'opus', availableModels),
|
|
532
|
+
sonnet: await selectModelForTier(rl, 'sonnet', availableModels),
|
|
533
|
+
haiku: await selectModelForTier(rl, 'haiku', availableModels),
|
|
534
|
+
};
|
|
427
535
|
|
|
428
|
-
|
|
429
|
-
print(
|
|
536
|
+
console.log('');
|
|
537
|
+
print('Model configuration:', 'success');
|
|
538
|
+
console.log(` ${COLORS.dim}Opus:${COLORS.reset} ${COLORS.cyan}${modelConfig.opus}${COLORS.reset}`);
|
|
539
|
+
console.log(` ${COLORS.dim}Sonnet:${COLORS.reset} ${COLORS.cyan}${modelConfig.sonnet}${COLORS.reset}`);
|
|
540
|
+
console.log(` ${COLORS.dim}Haiku:${COLORS.reset} ${COLORS.cyan}${modelConfig.haiku}${COLORS.reset}`);
|
|
430
541
|
|
|
431
542
|
// Step 4: Apply Configuration
|
|
432
543
|
printStep(++currentStep, totalSteps, 'Applying Configuration');
|
|
@@ -435,11 +546,11 @@ export async function runOnboarding(options = {}) {
|
|
|
435
546
|
|
|
436
547
|
// Configure Claude Code settings
|
|
437
548
|
print('Configuring Claude Code settings...', 'step');
|
|
438
|
-
|
|
549
|
+
configureClaudeSettingsWithModels(modelConfig, port);
|
|
439
550
|
print(`Settings saved to ${CLAUDE_SETTINGS_FILE}`, 'success');
|
|
440
551
|
|
|
441
552
|
// Print summary
|
|
442
|
-
printSummary(accounts,
|
|
553
|
+
printSummary(accounts, modelConfig, port);
|
|
443
554
|
|
|
444
555
|
rl.close();
|
|
445
556
|
return true;
|