@kikkimo/claude-launcher 2.5.0 → 3.1.0
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/CHANGELOG.md +70 -0
- package/README.md +23 -13
- package/claude-launcher +1244 -432
- package/docs/README-zh.md +23 -13
- package/lib/api-manager.js +629 -70
- package/lib/auth/password-input.js +8 -4
- package/lib/auth/password-validator.js +83 -48
- package/lib/i18n/index.js +4 -3
- package/lib/i18n/language-manager.js +4 -3
- package/lib/i18n/locales/de.js +229 -13
- package/lib/i18n/locales/en.js +235 -13
- package/lib/i18n/locales/es.js +229 -13
- package/lib/i18n/locales/fr.js +229 -13
- package/lib/i18n/locales/it.js +229 -13
- package/lib/i18n/locales/ja.js +229 -13
- package/lib/i18n/locales/ko.js +229 -13
- package/lib/i18n/locales/pt.js +229 -13
- package/lib/i18n/locales/ru.js +229 -13
- package/lib/i18n/locales/zh-TW.js +229 -13
- package/lib/i18n/locales/zh.js +235 -13
- package/lib/launcher.js +167 -110
- package/lib/presets/providers.js +143 -39
- package/lib/ui/api-editor.js +668 -0
- package/lib/ui/i18n-labels.js +16 -0
- package/lib/ui/interactive-table.js +216 -99
- package/lib/ui/menu.js +79 -62
- package/lib/ui/prompts.js +168 -139
- package/lib/ui/screen.js +125 -0
- package/lib/utils/stdin-manager.js +11 -9
- package/lib/utils/version-checker.js +65 -4
- package/lib/validators.js +102 -1
- package/package.json +2 -2
- package/docs/superpowers/plans/2026-03-31-update-models-and-auto-mode.md +0 -1414
- package/docs/superpowers/specs/2026-03-31-update-models-and-auto-mode-design.md +0 -187
package/lib/launcher.js
CHANGED
|
@@ -7,11 +7,111 @@ const colors = require('./ui/colors');
|
|
|
7
7
|
const i18n = require('./i18n');
|
|
8
8
|
const { getProvider } = require('./presets/providers');
|
|
9
9
|
const stdinManager = require('./utils/stdin-manager');
|
|
10
|
+
const { loadConfigSync } = require('./utils/version-checker');
|
|
11
|
+
|
|
12
|
+
// Module-level flag for console handoff state
|
|
13
|
+
let consoleRelinquished = false;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Detach stdin and suspend stdinManager so the child process owns the terminal
|
|
17
|
+
*/
|
|
18
|
+
function relinquishConsoleToChild() {
|
|
19
|
+
if (consoleRelinquished) return;
|
|
20
|
+
consoleRelinquished = true;
|
|
21
|
+
try {
|
|
22
|
+
if (process.stdin.isTTY) {
|
|
23
|
+
process.stdin.setRawMode(false);
|
|
24
|
+
}
|
|
25
|
+
} catch (_) {}
|
|
26
|
+
|
|
27
|
+
// Detach only current scope listeners to avoid affecting other modules
|
|
28
|
+
if (stdinManager.activeScope && typeof stdinManager.activeScope.detach === 'function') {
|
|
29
|
+
stdinManager.activeScope.detach();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Suspend stdin manager so no new listeners are attached while Claude is running
|
|
33
|
+
if (typeof stdinManager.suspend === 'function') {
|
|
34
|
+
stdinManager.suspend();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Restore stdinManager after child process exits
|
|
40
|
+
*/
|
|
41
|
+
function restoreConsoleForLauncher() {
|
|
42
|
+
if (!consoleRelinquished) return;
|
|
43
|
+
consoleRelinquished = false;
|
|
44
|
+
if (typeof stdinManager.resume === 'function') {
|
|
45
|
+
stdinManager.resume();
|
|
46
|
+
}
|
|
47
|
+
stdinManager.enableCtrlC();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Handle launch failures with optional rollback and user prompt
|
|
52
|
+
*/
|
|
53
|
+
function handleLaunchFailure(message, opts = {}) {
|
|
54
|
+
if (opts.afterHandover) {
|
|
55
|
+
restoreConsoleForLauncher();
|
|
56
|
+
} else {
|
|
57
|
+
stdinManager.enableCtrlC();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Rollback launch statistics if callback provided — pass error message for lastError
|
|
61
|
+
if (typeof opts.rollbackFn === 'function') {
|
|
62
|
+
try { opts.rollbackFn(message); } catch (_) {}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log(colors.red + '[x] ' + message + colors.reset);
|
|
66
|
+
console.log(colors.gray + i18n.tSync('ui.general.press_key_return_menu') + colors.reset);
|
|
67
|
+
|
|
68
|
+
if (process.stdin.isTTY) {
|
|
69
|
+
try {
|
|
70
|
+
process.stdin.setRawMode(true);
|
|
71
|
+
process.stdin.resume();
|
|
72
|
+
} catch (_) {
|
|
73
|
+
// Ignore setup failures
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Set timeout to prevent infinite hanging
|
|
77
|
+
const timeoutId = setTimeout(() => {
|
|
78
|
+
try {
|
|
79
|
+
process.stdin.setRawMode(false);
|
|
80
|
+
} catch (_) {
|
|
81
|
+
// Ignore cleanup failures
|
|
82
|
+
}
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}, 60000); // 60 second timeout
|
|
85
|
+
|
|
86
|
+
process.stdin.once('data', () => {
|
|
87
|
+
clearTimeout(timeoutId);
|
|
88
|
+
try {
|
|
89
|
+
process.stdin.setRawMode(false);
|
|
90
|
+
} catch (_) {
|
|
91
|
+
// Ignore cleanup failures
|
|
92
|
+
}
|
|
93
|
+
// Exit after user acknowledges the error
|
|
94
|
+
process.exit(1);
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
// For non-TTY environments, exit immediately
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
10
101
|
|
|
11
102
|
/**
|
|
12
103
|
* Launch Claude Code with specified environment variables
|
|
13
104
|
*/
|
|
14
|
-
function launchClaude(command, envVars = {}, disableAuthTokens = false) {
|
|
105
|
+
function launchClaude(command, envVars = {}, disableAuthTokens = false, opts = {}) {
|
|
106
|
+
// Inject telemetry control from config
|
|
107
|
+
const launcherConfig = loadConfigSync();
|
|
108
|
+
if (launcherConfig.disableTelemetry) {
|
|
109
|
+
envVars.DISABLE_TELEMETRY = '1';
|
|
110
|
+
}
|
|
111
|
+
if (launcherConfig.noFlicker) {
|
|
112
|
+
envVars.CLAUDE_CODE_NO_FLICKER = '1';
|
|
113
|
+
}
|
|
114
|
+
|
|
15
115
|
// Disable Ctrl+C monitoring before launching Claude Code
|
|
16
116
|
// This allows Ctrl+C to be handled exclusively by Claude Code process
|
|
17
117
|
stdinManager.disableCtrlC();
|
|
@@ -40,90 +140,14 @@ function launchClaude(command, envVars = {}, disableAuthTokens = false) {
|
|
|
40
140
|
|
|
41
141
|
// Disable conflicting auth tokens when using third-party API
|
|
42
142
|
if (disableAuthTokens) {
|
|
43
|
-
// Only delete CLAUDE_CODE_OAUTH_TOKEN - keep ANTHROPIC_AUTH_TOKEN that we just set
|
|
44
143
|
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
45
|
-
|
|
144
|
+
delete env.ANTHROPIC_API_KEY;
|
|
46
145
|
}
|
|
47
146
|
|
|
48
147
|
// Parse command and arguments
|
|
49
148
|
const args = command.split(' ');
|
|
50
149
|
const cmd = args.shift();
|
|
51
150
|
|
|
52
|
-
let consoleRelinquished = false;
|
|
53
|
-
const relinquishConsoleToChild = () => {
|
|
54
|
-
if (consoleRelinquished) return;
|
|
55
|
-
consoleRelinquished = true;
|
|
56
|
-
// Do the minimal changes: switch to cooked mode and detach current scope, but do not pause stdin nor swallow signals
|
|
57
|
-
try {
|
|
58
|
-
if (process.stdin.isTTY) {
|
|
59
|
-
process.stdin.setRawMode(false);
|
|
60
|
-
}
|
|
61
|
-
} catch (_) {}
|
|
62
|
-
|
|
63
|
-
// Detach only current scope listeners to avoid affecting other modules
|
|
64
|
-
if (stdinManager.activeScope && typeof stdinManager.activeScope.detach === 'function') {
|
|
65
|
-
stdinManager.activeScope.detach();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Suspend stdin manager so no new listeners are attached while Claude is running
|
|
69
|
-
if (typeof stdinManager.suspend === 'function') {
|
|
70
|
-
stdinManager.suspend();
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const restoreConsoleForLauncher = () => {
|
|
75
|
-
if (!consoleRelinquished) return;
|
|
76
|
-
consoleRelinquished = false;
|
|
77
|
-
if (typeof stdinManager.resume === 'function') {
|
|
78
|
-
stdinManager.resume();
|
|
79
|
-
}
|
|
80
|
-
stdinManager.enableCtrlC();
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const handleLaunchFailure = (message, opts = {}) => {
|
|
84
|
-
if (opts.afterHandover) {
|
|
85
|
-
restoreConsoleForLauncher();
|
|
86
|
-
} else {
|
|
87
|
-
stdinManager.enableCtrlC();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
console.log(colors.red + '[x] ' + message + colors.reset);
|
|
91
|
-
console.log(colors.gray + i18n.tSync('ui.general.press_key_return_menu') + colors.reset);
|
|
92
|
-
|
|
93
|
-
if (process.stdin.isTTY) {
|
|
94
|
-
try {
|
|
95
|
-
process.stdin.setRawMode(true);
|
|
96
|
-
process.stdin.resume();
|
|
97
|
-
} catch (_) {
|
|
98
|
-
// Ignore setup failures
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Set timeout to prevent infinite hanging
|
|
102
|
-
const timeoutId = setTimeout(() => {
|
|
103
|
-
try {
|
|
104
|
-
process.stdin.setRawMode(false);
|
|
105
|
-
} catch (_) {
|
|
106
|
-
// Ignore cleanup failures
|
|
107
|
-
}
|
|
108
|
-
process.exit(1);
|
|
109
|
-
}, 60000); // 60 second timeout
|
|
110
|
-
|
|
111
|
-
process.stdin.once('data', () => {
|
|
112
|
-
clearTimeout(timeoutId);
|
|
113
|
-
try {
|
|
114
|
-
process.stdin.setRawMode(false);
|
|
115
|
-
} catch (_) {
|
|
116
|
-
// Ignore cleanup failures
|
|
117
|
-
}
|
|
118
|
-
// Exit after user acknowledges the error
|
|
119
|
-
process.exit(1);
|
|
120
|
-
});
|
|
121
|
-
} else {
|
|
122
|
-
// For non-TTY environments, exit immediately
|
|
123
|
-
process.exit(1);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
151
|
try {
|
|
128
152
|
// Clean up terminal state before launching Claude
|
|
129
153
|
if (process.stdin.isTTY) {
|
|
@@ -135,15 +159,8 @@ function launchClaude(command, envVars = {}, disableAuthTokens = false) {
|
|
|
135
159
|
}
|
|
136
160
|
}
|
|
137
161
|
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
// This ensures only the current scope's listeners are detached while
|
|
141
|
-
// preserving any listeners from other modules.
|
|
142
|
-
//
|
|
143
|
-
// Note: Do NOT remove global SIGINT/SIGTERM handlers here.
|
|
144
|
-
// The existing handlers already check stdinManager.isSuspended() and
|
|
145
|
-
// will properly ignore signals during child process execution.
|
|
146
|
-
// Removing all handlers would break other modules and degrade reliability.
|
|
162
|
+
// Relinquish console before spawn so the child inherits a clean terminal
|
|
163
|
+
relinquishConsoleToChild();
|
|
147
164
|
|
|
148
165
|
// Launch Claude in current terminal, inherit stdio
|
|
149
166
|
const child = spawn(cmd, args, {
|
|
@@ -153,19 +170,22 @@ function launchClaude(command, envVars = {}, disableAuthTokens = false) {
|
|
|
153
170
|
shell: true
|
|
154
171
|
});
|
|
155
172
|
|
|
156
|
-
relinquishConsoleToChild();
|
|
157
|
-
|
|
158
173
|
child.on('close', (code) => {
|
|
159
174
|
restoreConsoleForLauncher();
|
|
160
175
|
process.exit(code || 0);
|
|
161
176
|
});
|
|
162
177
|
|
|
163
178
|
child.on('error', (error) => {
|
|
164
|
-
handleLaunchFailure('Error running Claude: ' + error.message, {
|
|
179
|
+
handleLaunchFailure('Error running Claude: ' + error.message, {
|
|
180
|
+
afterHandover: true,
|
|
181
|
+
rollbackFn: opts.rollbackFn
|
|
182
|
+
});
|
|
165
183
|
});
|
|
166
184
|
|
|
167
185
|
} catch (error) {
|
|
168
|
-
handleLaunchFailure('Error launching Claude Code: ' + error.message
|
|
186
|
+
handleLaunchFailure('Error launching Claude Code: ' + error.message, {
|
|
187
|
+
rollbackFn: opts.rollbackFn
|
|
188
|
+
});
|
|
169
189
|
}
|
|
170
190
|
}
|
|
171
191
|
|
|
@@ -196,47 +216,83 @@ function launchClaudeAutoMode() {
|
|
|
196
216
|
* Get environment variables based on provider type
|
|
197
217
|
*/
|
|
198
218
|
function getProviderEnvVars(api) {
|
|
199
|
-
// Decrypt the auth token (all tokens are stored encrypted)
|
|
200
219
|
const { decrypt } = require('./crypto');
|
|
201
220
|
const decrypted = decrypt(api.authToken);
|
|
202
|
-
|
|
203
221
|
if (!decrypted.success) {
|
|
204
|
-
console.error('Failed to decrypt auth token:', decrypted.error);
|
|
205
222
|
throw new Error('Failed to decrypt API auth token. Please check your configuration.');
|
|
206
223
|
}
|
|
207
224
|
|
|
208
225
|
const authToken = decrypted.value;
|
|
209
226
|
|
|
210
|
-
|
|
227
|
+
// Step 1: Base variables
|
|
228
|
+
const env = {
|
|
211
229
|
ANTHROPIC_BASE_URL: api.baseUrl,
|
|
212
230
|
ANTHROPIC_AUTH_TOKEN: authToken,
|
|
213
231
|
ANTHROPIC_MODEL: api.model,
|
|
214
|
-
ANTHROPIC_SMALL_FAST_MODEL: api.smallFastModel || api.model
|
|
232
|
+
ANTHROPIC_SMALL_FAST_MODEL: api.smallFastModel || api.model,
|
|
215
233
|
};
|
|
216
234
|
|
|
217
|
-
//
|
|
235
|
+
// Step 2: Provider-level defaults
|
|
218
236
|
const providerConfig = getProvider(api.provider);
|
|
219
|
-
|
|
220
237
|
if (providerConfig && providerConfig.envVars) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
238
|
+
Object.assign(env, providerConfig.envVars);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const { PREDEFINED_MODEL_ENV_KEYS, PREDEFINED_RUNTIME_KEYS, TYPE_A_FIELDS, RESERVED_ENV_KEYS } = require('./validators');
|
|
242
|
+
|
|
243
|
+
// Step 3: modelEnvVars (whitelist, non-empty)
|
|
244
|
+
if (api.modelEnvVars) {
|
|
245
|
+
for (const key of PREDEFINED_MODEL_ENV_KEYS) {
|
|
246
|
+
const val = api.modelEnvVars[key];
|
|
247
|
+
if (val !== undefined && val !== '') env[key] = val;
|
|
248
|
+
}
|
|
226
249
|
}
|
|
227
250
|
|
|
228
|
-
|
|
251
|
+
// Step 4: runtimeEnvVars (whitelist, non-empty, skip "off")
|
|
252
|
+
if (api.runtimeEnvVars) {
|
|
253
|
+
for (const key of PREDEFINED_RUNTIME_KEYS) {
|
|
254
|
+
const val = api.runtimeEnvVars[key];
|
|
255
|
+
if (val !== undefined && val !== '' && val !== 'off') env[key] = val;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Step 5: customEnvVars (skip reserved/predefined)
|
|
260
|
+
if (api.customEnvVars) {
|
|
261
|
+
const allPredefined = new Set([...RESERVED_ENV_KEYS, ...PREDEFINED_RUNTIME_KEYS, ...PREDEFINED_MODEL_ENV_KEYS]);
|
|
262
|
+
for (const [key, val] of Object.entries(api.customEnvVars)) {
|
|
263
|
+
if (allPredefined.has(key)) continue;
|
|
264
|
+
if (val !== undefined && val !== '') env[key] = val;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Step 6: Remove Type A fields with "off" (tombstone)
|
|
269
|
+
if (api.runtimeEnvVars) {
|
|
270
|
+
for (const key of TYPE_A_FIELDS) {
|
|
271
|
+
if (api.runtimeEnvVars[key] === 'off') delete env[key];
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return env;
|
|
229
276
|
}
|
|
230
277
|
|
|
231
278
|
/**
|
|
232
279
|
* Launch Claude with third-party API configuration
|
|
233
280
|
*/
|
|
234
|
-
function launchClaudeWithApi(api, skipPermissions = false) {
|
|
281
|
+
function launchClaudeWithApi(api, skipPermissions = false, opts = {}) {
|
|
235
282
|
const command = skipPermissions
|
|
236
283
|
? 'claude --dangerously-skip-permissions'
|
|
237
284
|
: 'claude';
|
|
238
285
|
|
|
239
|
-
|
|
286
|
+
let envVars;
|
|
287
|
+
try {
|
|
288
|
+
envVars = getProviderEnvVars(api);
|
|
289
|
+
} catch (error) {
|
|
290
|
+
handleLaunchFailure('Failed to prepare API environment: ' + error.message, {
|
|
291
|
+
afterHandover: true,
|
|
292
|
+
rollbackFn: opts.rollbackFn
|
|
293
|
+
});
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
240
296
|
|
|
241
297
|
console.log('');
|
|
242
298
|
console.log(colors.bright + colors.orange + '🔗 ' + i18n.tSync('launch.using_third_party_api') + colors.reset);
|
|
@@ -254,8 +310,8 @@ function launchClaudeWithApi(api, skipPermissions = false) {
|
|
|
254
310
|
if (providerConfig && providerConfig.envVars && Object.keys(providerConfig.envVars).length > 0) {
|
|
255
311
|
console.log(colors.yellow + ' ⚡ ' + i18n.tSync('launch.provider_optimizations_applied') + colors.reset);
|
|
256
312
|
|
|
257
|
-
// Display specific optimizations
|
|
258
|
-
const msRaw =
|
|
313
|
+
// Display specific optimizations from merged envVars
|
|
314
|
+
const msRaw = envVars.API_TIMEOUT_MS;
|
|
259
315
|
const ms = Number(msRaw);
|
|
260
316
|
if (Number.isFinite(ms) && ms > 0) {
|
|
261
317
|
const timeoutSec = Math.floor(ms / 1000);
|
|
@@ -281,7 +337,7 @@ function launchClaudeWithApi(api, skipPermissions = false) {
|
|
|
281
337
|
|
|
282
338
|
console.log('');
|
|
283
339
|
|
|
284
|
-
launchClaude(command, envVars, true);
|
|
340
|
+
launchClaude(command, envVars, true, { rollbackFn: opts.rollbackFn });
|
|
285
341
|
}
|
|
286
342
|
|
|
287
343
|
/**
|
|
@@ -365,5 +421,6 @@ module.exports = {
|
|
|
365
421
|
launchClaudeAutoMode,
|
|
366
422
|
launchClaudeWithApi,
|
|
367
423
|
getProviderEnvVars,
|
|
368
|
-
testApiConnection
|
|
424
|
+
testApiConnection,
|
|
425
|
+
handleLaunchFailure
|
|
369
426
|
};
|
package/lib/presets/providers.js
CHANGED
|
@@ -4,50 +4,106 @@
|
|
|
4
4
|
* Note: Only includes APIs that are compatible with Claude Code's Anthropic API format
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
// Template factory: same-gen fast model downgrade via lookup map
|
|
8
|
+
function makeFastMapTemplate(fastMap) {
|
|
9
|
+
return {
|
|
10
|
+
getValues(model) {
|
|
11
|
+
const fastModel = fastMap[model] || model;
|
|
12
|
+
return {
|
|
13
|
+
ANTHROPIC_CUSTOM_MODEL_OPTION: model,
|
|
14
|
+
ANTHROPIC_CUSTOM_MODEL_OPTION_NAME: model,
|
|
15
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: model,
|
|
16
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: model,
|
|
17
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: fastModel,
|
|
18
|
+
CLAUDE_CODE_SUBAGENT_MODEL: fastModel,
|
|
19
|
+
smallFastModel: fastModel,
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Template factory: for providers with single model, no tier split
|
|
26
|
+
function makeSingleTemplate() {
|
|
27
|
+
return {
|
|
28
|
+
getValues(model) {
|
|
29
|
+
return {
|
|
30
|
+
ANTHROPIC_CUSTOM_MODEL_OPTION: model,
|
|
31
|
+
ANTHROPIC_CUSTOM_MODEL_OPTION_NAME: model,
|
|
32
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: model,
|
|
33
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: model,
|
|
34
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: model,
|
|
35
|
+
CLAUDE_CODE_SUBAGENT_MODEL: model,
|
|
36
|
+
smallFastModel: model,
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Anthropic models — defined as const so the template factory can reference them
|
|
43
|
+
const anthropicModels = [
|
|
44
|
+
'claude-opus-4-7',
|
|
45
|
+
'claude-sonnet-4-6',
|
|
46
|
+
'claude-haiku-4-5-20251001',
|
|
47
|
+
'claude-sonnet-4-5',
|
|
48
|
+
'claude-opus-4-6',
|
|
49
|
+
'claude-opus-4-5',
|
|
50
|
+
];
|
|
51
|
+
|
|
7
52
|
const providers = {
|
|
8
53
|
anthropic: {
|
|
9
54
|
name: 'Anthropic (Official)',
|
|
10
55
|
baseUrl: 'https://api.anthropic.com',
|
|
11
|
-
models:
|
|
12
|
-
'claude-3-5-haiku-20241022',
|
|
13
|
-
'claude-3-7-sonnet',
|
|
14
|
-
'claude-sonnet-4',
|
|
15
|
-
'claude-sonnet-4-5',
|
|
16
|
-
'claude-opus-4',
|
|
17
|
-
'claude-opus-4-1',
|
|
18
|
-
'claude-opus-4-5',
|
|
19
|
-
'claude-opus-4-6'
|
|
20
|
-
],
|
|
21
|
-
// Version aliases for upgrade detection (manually maintained)
|
|
22
|
-
// Covers ALL models in each series for comprehensive upgrade detection
|
|
56
|
+
models: anthropicModels,
|
|
23
57
|
versionAliases: {
|
|
24
|
-
|
|
25
|
-
'claude-opus-4': 'claude-opus-4-
|
|
26
|
-
'claude-opus-4-
|
|
27
|
-
'claude-opus-4-
|
|
28
|
-
|
|
29
|
-
'claude-sonnet-4': 'claude-sonnet-4-
|
|
30
|
-
'claude-3-7-sonnet': 'claude-sonnet-4-
|
|
58
|
+
'claude-opus-4': 'claude-opus-4-7',
|
|
59
|
+
'claude-opus-4-1': 'claude-opus-4-7',
|
|
60
|
+
'claude-opus-4-5': 'claude-opus-4-7',
|
|
61
|
+
'claude-opus-4-6': 'claude-opus-4-7',
|
|
62
|
+
'claude-sonnet-4': 'claude-sonnet-4-6',
|
|
63
|
+
'claude-sonnet-4-5': 'claude-sonnet-4-6',
|
|
64
|
+
'claude-3-7-sonnet': 'claude-sonnet-4-6',
|
|
31
65
|
},
|
|
32
66
|
authTokenFormat: 'sk-ant-api03-...',
|
|
33
67
|
description: 'Official Anthropic API - Fully compatible',
|
|
34
68
|
requiresToken: true,
|
|
35
|
-
compatibility: 'native'
|
|
69
|
+
compatibility: 'native',
|
|
70
|
+
envVars: {
|
|
71
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: '0',
|
|
72
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: '1',
|
|
73
|
+
},
|
|
74
|
+
modelEnvTemplate: {
|
|
75
|
+
getValues(model) {
|
|
76
|
+
const latestSonnet = anthropicModels.find(m => m.includes('sonnet')) || model;
|
|
77
|
+
const latestOpus = anthropicModels.find(m => m.includes('opus')) || model;
|
|
78
|
+
const latestHaiku = anthropicModels.find(m => m.includes('haiku')) || model;
|
|
79
|
+
return {
|
|
80
|
+
ANTHROPIC_CUSTOM_MODEL_OPTION: model,
|
|
81
|
+
ANTHROPIC_CUSTOM_MODEL_OPTION_NAME: model,
|
|
82
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: latestSonnet,
|
|
83
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: latestOpus,
|
|
84
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: latestHaiku,
|
|
85
|
+
CLAUDE_CODE_SUBAGENT_MODEL: latestHaiku,
|
|
86
|
+
smallFastModel: latestHaiku,
|
|
87
|
+
};
|
|
88
|
+
},
|
|
89
|
+
},
|
|
36
90
|
},
|
|
37
91
|
moonshot: {
|
|
38
|
-
name: 'Moonshot AI (Kimi-K2.5/K2-Thinking)',
|
|
92
|
+
name: 'Moonshot AI (Kimi-K2.6/K2.5/K2-Thinking)',
|
|
39
93
|
baseUrl: 'https://api.moonshot.cn/anthropic',
|
|
40
94
|
models: [
|
|
95
|
+
'kimi-k2.6',
|
|
41
96
|
'kimi-k2.5',
|
|
42
97
|
'kimi-k2-thinking',
|
|
43
|
-
'kimi-k2-thinking-turbo'
|
|
98
|
+
'kimi-k2-thinking-turbo',
|
|
44
99
|
],
|
|
45
100
|
versionAliases: {
|
|
46
|
-
'kimi-k2-0711-preview': 'kimi-k2.
|
|
47
|
-
'kimi-k2-0905-preview': 'kimi-k2.
|
|
48
|
-
'kimi-k2-turbo-preview': 'kimi-k2.
|
|
49
|
-
'kimi-k2-thinking': 'kimi-k2.
|
|
50
|
-
'kimi-k2-thinking-turbo': 'kimi-k2.
|
|
101
|
+
'kimi-k2-0711-preview': 'kimi-k2.6',
|
|
102
|
+
'kimi-k2-0905-preview': 'kimi-k2.6',
|
|
103
|
+
'kimi-k2-turbo-preview': 'kimi-k2.6',
|
|
104
|
+
'kimi-k2-thinking': 'kimi-k2.6',
|
|
105
|
+
'kimi-k2-thinking-turbo': 'kimi-k2.6',
|
|
106
|
+
'kimi-k2.5': 'kimi-k2.6',
|
|
51
107
|
},
|
|
52
108
|
authTokenFormat: 'sk-...',
|
|
53
109
|
description: 'Moonshot AI - Provides Anthropic-compatible API',
|
|
@@ -55,8 +111,12 @@ const providers = {
|
|
|
55
111
|
compatibility: 'anthropic-compatible',
|
|
56
112
|
envVars: {
|
|
57
113
|
API_TIMEOUT_MS: '3000000',
|
|
58
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1'
|
|
114
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
|
|
115
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: '0',
|
|
116
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: '1',
|
|
117
|
+
CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK: '1'
|
|
59
118
|
},
|
|
119
|
+
modelEnvTemplate: makeFastMapTemplate({"kimi-k2.6":"kimi-k2-thinking-turbo","kimi-k2-thinking":"kimi-k2-thinking-turbo"}),
|
|
60
120
|
note: 'Requires extended timeout for large responses'
|
|
61
121
|
},
|
|
62
122
|
kimi_for_coding: {
|
|
@@ -71,8 +131,12 @@ const providers = {
|
|
|
71
131
|
compatibility: 'anthropic-compatible',
|
|
72
132
|
envVars: {
|
|
73
133
|
API_TIMEOUT_MS: '3000000',
|
|
74
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1'
|
|
134
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
|
|
135
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: '0',
|
|
136
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: '1',
|
|
137
|
+
CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK: '1'
|
|
75
138
|
},
|
|
139
|
+
modelEnvTemplate: makeSingleTemplate(),
|
|
76
140
|
note: 'Requires extended timeout for large responses'
|
|
77
141
|
},
|
|
78
142
|
minimax_cn: {
|
|
@@ -80,8 +144,12 @@ const providers = {
|
|
|
80
144
|
baseUrl: 'https://api.minimaxi.com/anthropic',
|
|
81
145
|
models: [
|
|
82
146
|
'MiniMax-M2.7',
|
|
147
|
+
'MiniMax-M2.7-highspeed',
|
|
83
148
|
'MiniMax-M2.5',
|
|
84
|
-
'MiniMax-M2.
|
|
149
|
+
'MiniMax-M2.5-highspeed',
|
|
150
|
+
'MiniMax-M2.1',
|
|
151
|
+
'MiniMax-M2.1-highspeed',
|
|
152
|
+
'MiniMax-M2',
|
|
85
153
|
],
|
|
86
154
|
versionAliases: {
|
|
87
155
|
'MiniMax-M2.1': 'MiniMax-M2.7',
|
|
@@ -93,8 +161,12 @@ const providers = {
|
|
|
93
161
|
compatibility: 'anthropic-compatible',
|
|
94
162
|
envVars: {
|
|
95
163
|
API_TIMEOUT_MS: '3000000',
|
|
96
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1'
|
|
164
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
|
|
165
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: '0',
|
|
166
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: '1',
|
|
167
|
+
CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK: '1'
|
|
97
168
|
},
|
|
169
|
+
modelEnvTemplate: makeFastMapTemplate({"MiniMax-M2.7":"MiniMax-M2.7-highspeed","MiniMax-M2.5":"MiniMax-M2.5-highspeed","MiniMax-M2.1":"MiniMax-M2.1-highspeed"}),
|
|
98
170
|
note: 'Requires extended timeout for large responses'
|
|
99
171
|
},
|
|
100
172
|
minimax_global: {
|
|
@@ -102,8 +174,12 @@ const providers = {
|
|
|
102
174
|
baseUrl: 'https://api.minimax.io/anthropic',
|
|
103
175
|
models: [
|
|
104
176
|
'MiniMax-M2.7',
|
|
177
|
+
'MiniMax-M2.7-highspeed',
|
|
105
178
|
'MiniMax-M2.5',
|
|
106
|
-
'MiniMax-M2.
|
|
179
|
+
'MiniMax-M2.5-highspeed',
|
|
180
|
+
'MiniMax-M2.1',
|
|
181
|
+
'MiniMax-M2.1-highspeed',
|
|
182
|
+
'MiniMax-M2',
|
|
107
183
|
],
|
|
108
184
|
versionAliases: {
|
|
109
185
|
'MiniMax-M2.1': 'MiniMax-M2.7',
|
|
@@ -115,26 +191,41 @@ const providers = {
|
|
|
115
191
|
compatibility: 'anthropic-compatible',
|
|
116
192
|
envVars: {
|
|
117
193
|
API_TIMEOUT_MS: '3000000',
|
|
118
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1'
|
|
194
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
|
|
195
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: '0',
|
|
196
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: '1',
|
|
197
|
+
CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK: '1'
|
|
119
198
|
},
|
|
199
|
+
modelEnvTemplate: makeFastMapTemplate({"MiniMax-M2.7":"MiniMax-M2.7-highspeed","MiniMax-M2.5":"MiniMax-M2.5-highspeed","MiniMax-M2.1":"MiniMax-M2.1-highspeed"}),
|
|
120
200
|
note: 'Requires extended timeout for large responses'
|
|
121
201
|
},
|
|
122
202
|
deepseek: {
|
|
123
|
-
name: 'DeepSeek (
|
|
203
|
+
name: 'DeepSeek (V4-Pro/V4-Flash)',
|
|
124
204
|
baseUrl: 'https://api.deepseek.com/anthropic',
|
|
125
205
|
models: [
|
|
206
|
+
'deepseek-v4-pro[1m]',
|
|
207
|
+
'deepseek-v4-flash[1m]',
|
|
126
208
|
'deepseek-chat',
|
|
127
|
-
'deepseek-reasoner'
|
|
209
|
+
'deepseek-reasoner',
|
|
128
210
|
],
|
|
211
|
+
versionAliases: {
|
|
212
|
+
'deepseek-chat': 'deepseek-v4-flash[1m]',
|
|
213
|
+
'deepseek-reasoner': 'deepseek-v4-pro[1m]',
|
|
214
|
+
},
|
|
129
215
|
authTokenFormat: 'sk-...',
|
|
130
216
|
description: 'DeepSeek AI - Anthropic-compatible endpoint',
|
|
131
217
|
requiresToken: true,
|
|
132
218
|
compatibility: 'anthropic-compatible',
|
|
133
219
|
envVars: {
|
|
134
220
|
API_TIMEOUT_MS: '600000',
|
|
135
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1'
|
|
221
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
|
|
222
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: '0',
|
|
223
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: '1',
|
|
224
|
+
CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK: '1',
|
|
225
|
+
CLAUDE_CODE_EFFORT_LEVEL: 'max',
|
|
136
226
|
},
|
|
137
|
-
|
|
227
|
+
modelEnvTemplate: makeFastMapTemplate({"deepseek-v4-pro[1m]":"deepseek-v4-flash[1m]"}),
|
|
228
|
+
note: 'Requires extended timeout for complex reasoning tasks',
|
|
138
229
|
},
|
|
139
230
|
zhipu: {
|
|
140
231
|
name: 'ZhiPu AI (GLM-5.1/5-Turbo/5/4.7) - 智谱清言',
|
|
@@ -158,8 +249,12 @@ const providers = {
|
|
|
158
249
|
compatibility: 'anthropic-compatible',
|
|
159
250
|
envVars: {
|
|
160
251
|
API_TIMEOUT_MS: '3000000',
|
|
161
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1'
|
|
252
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
|
|
253
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: '0',
|
|
254
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: '1',
|
|
255
|
+
CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK: '1'
|
|
162
256
|
},
|
|
257
|
+
modelEnvTemplate: makeFastMapTemplate({"glm-5.1":"glm-5-turbo"}),
|
|
163
258
|
note: 'Requires extended timeout for large responses'
|
|
164
259
|
},
|
|
165
260
|
zai: {
|
|
@@ -184,8 +279,12 @@ const providers = {
|
|
|
184
279
|
compatibility: 'anthropic-compatible',
|
|
185
280
|
envVars: {
|
|
186
281
|
API_TIMEOUT_MS: '3000000',
|
|
187
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1'
|
|
282
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
|
|
283
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: '0',
|
|
284
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: '1',
|
|
285
|
+
CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK: '1'
|
|
188
286
|
},
|
|
287
|
+
modelEnvTemplate: makeFastMapTemplate({"glm-5.1":"glm-5-turbo"}),
|
|
189
288
|
note: 'Requires extended timeout for large responses'
|
|
190
289
|
},
|
|
191
290
|
custom: {
|
|
@@ -198,6 +297,11 @@ const providers = {
|
|
|
198
297
|
description: 'Custom server with Anthropic-compatible API',
|
|
199
298
|
requiresToken: true,
|
|
200
299
|
compatibility: 'anthropic-compatible',
|
|
300
|
+
envVars: {
|
|
301
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: '0',
|
|
302
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: '1',
|
|
303
|
+
},
|
|
304
|
+
modelEnvTemplate: makeSingleTemplate(),
|
|
201
305
|
note: 'Replace URL and model with your actual server details'
|
|
202
306
|
}
|
|
203
307
|
};
|