@kikkimo/claude-launcher 2.3.0 → 2.4.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 +41 -0
- package/README.md +22 -8
- package/claude-launcher +390 -42
- package/docs/README-zh.md +22 -8
- package/lib/api-manager.js +135 -1
- package/lib/i18n/locales/de.js +68 -3
- package/lib/i18n/locales/en.js +66 -2
- package/lib/i18n/locales/es.js +68 -3
- package/lib/i18n/locales/fr.js +68 -3
- package/lib/i18n/locales/it.js +66 -2
- package/lib/i18n/locales/ja.js +68 -3
- package/lib/i18n/locales/ko.js +68 -3
- package/lib/i18n/locales/pt.js +66 -2
- package/lib/i18n/locales/ru.js +66 -2
- package/lib/i18n/locales/zh-TW.js +68 -3
- package/lib/i18n/locales/zh.js +68 -3
- package/lib/presets/providers.js +61 -11
- package/lib/utils/model-upgrade-checker.js +103 -0
- package/lib/utils/version-checker.js +22 -3
- package/package.json +1 -1
package/lib/i18n/locales/zh.js
CHANGED
|
@@ -28,6 +28,12 @@ module.exports = {
|
|
|
28
28
|
change_password: "修改密码",
|
|
29
29
|
back: "返回主菜单"
|
|
30
30
|
},
|
|
31
|
+
remove_api: {
|
|
32
|
+
title: "删除API",
|
|
33
|
+
delete_single: "删除单个API",
|
|
34
|
+
clear_all: "清空所有API",
|
|
35
|
+
back: "返回"
|
|
36
|
+
},
|
|
31
37
|
language: {
|
|
32
38
|
title: "语言设置",
|
|
33
39
|
current: "当前语言:{0}",
|
|
@@ -44,6 +50,9 @@ module.exports = {
|
|
|
44
50
|
no_apis: "未配置第三方API",
|
|
45
51
|
add_api_first: "请先使用\"添加新的第三方API\"添加API",
|
|
46
52
|
all_apis_removed: "所有API已被删除",
|
|
53
|
+
all_apis_cleared: "已清空 {0} 个API",
|
|
54
|
+
clear_cancelled: "清空操作已取消",
|
|
55
|
+
current_api_count: "当前API数量:{0}",
|
|
47
56
|
apis_removed_or_none: "所有API已被删除或未配置任何API。",
|
|
48
57
|
removal_cancelled: "取消删除",
|
|
49
58
|
operation_cancelled: "操作已取消",
|
|
@@ -79,7 +88,9 @@ module.exports = {
|
|
|
79
88
|
enter_model_name: "输入模型名称:",
|
|
80
89
|
select_provider: "选择提供商:",
|
|
81
90
|
enter_import_file: "输入导入文件路径:",
|
|
82
|
-
ctrl_c_again: "再次按 Ctrl+C 退出程序"
|
|
91
|
+
ctrl_c_again: "再次按 Ctrl+C 退出程序",
|
|
92
|
+
confirm_clear_all: "这将永久删除所有 {0} 个API。此操作无法撤销。",
|
|
93
|
+
confirm_clear_all_input: "输入 CLEAR 以确认清空:"
|
|
83
94
|
}
|
|
84
95
|
},
|
|
85
96
|
|
|
@@ -493,7 +504,8 @@ module.exports = {
|
|
|
493
504
|
"最低密码强度:良好(拒绝弱密码和极弱密码)"
|
|
494
505
|
],
|
|
495
506
|
example_strong_password: "强密码示例:{0}",
|
|
496
|
-
new_password_attempt: "新密码(尝试 {0}/{1}):"
|
|
507
|
+
new_password_attempt: "新密码(尝试 {0}/{1}):",
|
|
508
|
+
confirm_password_prompt: "确认密码:"
|
|
497
509
|
}
|
|
498
510
|
},
|
|
499
511
|
|
|
@@ -504,7 +516,27 @@ module.exports = {
|
|
|
504
516
|
active_api: "激活的API:{0}",
|
|
505
517
|
most_used: "最常用的API:{0}",
|
|
506
518
|
total_usage: "总使用次数:{0}次",
|
|
507
|
-
no_usage: "无使用记录"
|
|
519
|
+
no_usage: "无使用记录",
|
|
520
|
+
|
|
521
|
+
// 增强统计(新增)
|
|
522
|
+
success_rate: "整体成功率:{0}",
|
|
523
|
+
|
|
524
|
+
header_name: "API名称",
|
|
525
|
+
header_usage: "使用次数",
|
|
526
|
+
header_success: "成功率",
|
|
527
|
+
header_last_used: "最后使用",
|
|
528
|
+
|
|
529
|
+
time_never: "从未使用",
|
|
530
|
+
time_just_now: "刚刚",
|
|
531
|
+
time_minutes_ago: "{0}分钟前",
|
|
532
|
+
time_hours_ago: "{0}小时前",
|
|
533
|
+
time_days_ago: "{0}天前",
|
|
534
|
+
|
|
535
|
+
menu_view: "查看统计详情",
|
|
536
|
+
menu_reset: "重置统计",
|
|
537
|
+
menu_back: "返回",
|
|
538
|
+
reset_confirm: "确定重置所有统计数据? [y/N]",
|
|
539
|
+
reset_success: "统计数据已重置"
|
|
508
540
|
},
|
|
509
541
|
|
|
510
542
|
// 版本更新
|
|
@@ -534,5 +566,38 @@ module.exports = {
|
|
|
534
566
|
update_command: "更新命令:npm update -g @kikkimo/claude-launcher",
|
|
535
567
|
up_to_date: "您使用的是最新版本",
|
|
536
568
|
unexpected_error: "检查过程中发生意外错误"
|
|
569
|
+
},
|
|
570
|
+
|
|
571
|
+
// 模型升级功能
|
|
572
|
+
model_upgrade: {
|
|
573
|
+
notification: "模型升级可用: {0} → {1}",
|
|
574
|
+
notification_api: "API: {0}",
|
|
575
|
+
notification_hint: "前往「第三方API管理 > 模型升级设置」进行升级",
|
|
576
|
+
auto_upgraded: "模型已自动升级: {0} → {1}",
|
|
577
|
+
|
|
578
|
+
settings_title: "模型升级设置",
|
|
579
|
+
current_config: "当前配置",
|
|
580
|
+
auto_upgrade_label: "自动使用最新模型",
|
|
581
|
+
auto_upgrade_on: "开启",
|
|
582
|
+
auto_upgrade_off: "关闭",
|
|
583
|
+
|
|
584
|
+
menu_toggle_auto_on: "自动升级 [● 开启]",
|
|
585
|
+
menu_toggle_auto_off: "自动升级 [○ 关闭]",
|
|
586
|
+
menu_manual_upgrade: "手动一键升级所有模型",
|
|
587
|
+
menu_back: "返回",
|
|
588
|
+
|
|
589
|
+
manual_title: "模型升级检查",
|
|
590
|
+
manual_checking: "正在检查 {0} 个 API 配置...",
|
|
591
|
+
manual_api_current: "当前: {0}",
|
|
592
|
+
manual_api_latest: "最新: {0}",
|
|
593
|
+
manual_api_uptodate: "(已是最新)",
|
|
594
|
+
manual_api_no_info: "(无升级信息)",
|
|
595
|
+
manual_confirm: "升级此模型? [y/N]",
|
|
596
|
+
manual_upgraded: "已升级: {0} → {1}",
|
|
597
|
+
manual_skipped: "已跳过",
|
|
598
|
+
|
|
599
|
+
manual_complete: "升级完成!",
|
|
600
|
+
manual_stats_upgraded: "已升级: {0} 个",
|
|
601
|
+
manual_stats_skipped: "已跳过: {0} 个 ({1} 个已是最新, {2} 个无升级信息)"
|
|
537
602
|
}
|
|
538
603
|
};
|
package/lib/presets/providers.js
CHANGED
|
@@ -10,13 +10,25 @@ const providers = {
|
|
|
10
10
|
baseUrl: 'https://api.anthropic.com',
|
|
11
11
|
models: [
|
|
12
12
|
'claude-3-5-haiku-20241022',
|
|
13
|
-
'claude-3
|
|
13
|
+
'claude-3-7-sonnet',
|
|
14
14
|
'claude-sonnet-4',
|
|
15
|
-
'claude-sonnet-4
|
|
15
|
+
'claude-sonnet-4-5',
|
|
16
16
|
'claude-opus-4',
|
|
17
|
-
'claude-opus-4
|
|
18
|
-
'claude-opus-4
|
|
17
|
+
'claude-opus-4-1',
|
|
18
|
+
'claude-opus-4-5',
|
|
19
|
+
'claude-opus-4-6'
|
|
19
20
|
],
|
|
21
|
+
// Version aliases for upgrade detection (manually maintained)
|
|
22
|
+
// Covers ALL models in each series for comprehensive upgrade detection
|
|
23
|
+
versionAliases: {
|
|
24
|
+
// Opus series -> latest opus
|
|
25
|
+
'claude-opus-4': 'claude-opus-4-6',
|
|
26
|
+
'claude-opus-4-1': 'claude-opus-4-6',
|
|
27
|
+
'claude-opus-4-5': 'claude-opus-4-6',
|
|
28
|
+
// Sonnet series -> latest sonnet
|
|
29
|
+
'claude-sonnet-4': 'claude-sonnet-4-5',
|
|
30
|
+
'claude-3-7-sonnet': 'claude-sonnet-4-5'
|
|
31
|
+
},
|
|
20
32
|
authTokenFormat: 'sk-ant-api03-...',
|
|
21
33
|
description: 'Official Anthropic API - Fully compatible',
|
|
22
34
|
requiresToken: true,
|
|
@@ -108,13 +120,19 @@ const providers = {
|
|
|
108
120
|
note: 'Requires extended timeout for complex reasoning tasks'
|
|
109
121
|
},
|
|
110
122
|
zhipu: {
|
|
111
|
-
name: 'ZhiPu AI (GLM-4.
|
|
123
|
+
name: 'ZhiPu AI (GLM-5/4.7/4.6/4.5) - 智谱清言',
|
|
112
124
|
baseUrl: 'https://open.bigmodel.cn/api/anthropic',
|
|
113
125
|
models: [
|
|
114
|
-
'glm-
|
|
126
|
+
'glm-5',
|
|
127
|
+
'glm-4.7',
|
|
115
128
|
'glm-4.6',
|
|
116
|
-
'glm-4.
|
|
129
|
+
'glm-4.5'
|
|
117
130
|
],
|
|
131
|
+
versionAliases: {
|
|
132
|
+
'glm-4.5': 'glm-5',
|
|
133
|
+
'glm-4.6': 'glm-5',
|
|
134
|
+
'glm-4.7': 'glm-5'
|
|
135
|
+
},
|
|
118
136
|
authTokenFormat: 'sk-...',
|
|
119
137
|
description: 'ZhiPu AI (智谱清言) - Anthropic-compatible API for mainland China',
|
|
120
138
|
requiresToken: true,
|
|
@@ -126,13 +144,19 @@ const providers = {
|
|
|
126
144
|
note: 'Requires extended timeout for large responses'
|
|
127
145
|
},
|
|
128
146
|
zai: {
|
|
129
|
-
name: 'Z.ai (GLM-4.
|
|
147
|
+
name: 'Z.ai (GLM-5/4.7/4.6/4.5) - ZhiPu Global',
|
|
130
148
|
baseUrl: 'https://api.z.ai/api/anthropic',
|
|
131
149
|
models: [
|
|
132
|
-
'glm-
|
|
150
|
+
'glm-5',
|
|
151
|
+
'glm-4.7',
|
|
133
152
|
'glm-4.6',
|
|
134
|
-
'glm-4.
|
|
153
|
+
'glm-4.5'
|
|
135
154
|
],
|
|
155
|
+
versionAliases: {
|
|
156
|
+
'glm-4.5': 'glm-5',
|
|
157
|
+
'glm-4.6': 'glm-5',
|
|
158
|
+
'glm-4.7': 'glm-5'
|
|
159
|
+
},
|
|
136
160
|
authTokenFormat: 'sk-...',
|
|
137
161
|
description: 'Z.ai (ZhiPu AI Global) - Anthropic-compatible API for international users',
|
|
138
162
|
requiresToken: true,
|
|
@@ -194,10 +218,36 @@ function detectProvider(baseUrl) {
|
|
|
194
218
|
return 'custom';
|
|
195
219
|
}
|
|
196
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Get latest model name for a given model
|
|
223
|
+
* @param {string} modelName - Current model name
|
|
224
|
+
* @param {string} providerId - Provider ID
|
|
225
|
+
* @returns {string|null} Latest model name or null if no upgrade available
|
|
226
|
+
*/
|
|
227
|
+
function getLatestModel(modelName, providerId) {
|
|
228
|
+
const provider = providers[providerId];
|
|
229
|
+
if (!provider || !provider.versionAliases) {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
return provider.versionAliases[modelName] || null;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Check if a model has a newer version available
|
|
237
|
+
* @param {string} modelName - Current model name
|
|
238
|
+
* @param {string} providerId - Provider ID
|
|
239
|
+
* @returns {boolean} True if upgrade is available
|
|
240
|
+
*/
|
|
241
|
+
function hasModelUpgrade(modelName, providerId) {
|
|
242
|
+
return getLatestModel(modelName, providerId) !== null;
|
|
243
|
+
}
|
|
244
|
+
|
|
197
245
|
module.exports = {
|
|
198
246
|
providers,
|
|
199
247
|
getAllProviders,
|
|
200
248
|
getProvider,
|
|
201
249
|
getSuggestedModels,
|
|
202
|
-
detectProvider
|
|
250
|
+
detectProvider,
|
|
251
|
+
getLatestModel,
|
|
252
|
+
hasModelUpgrade
|
|
203
253
|
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model Upgrade Checker
|
|
3
|
+
* Detects available model upgrades with time-based caching (same pattern as version-checker)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { getLatestModel } = require('../presets/providers');
|
|
7
|
+
const versionChecker = require('./version-checker');
|
|
8
|
+
|
|
9
|
+
const CHECK_INTERVAL_HOURS = 12;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Check all APIs for available upgrades
|
|
13
|
+
* @param {ApiManager} apiManager - ApiManager instance (dependency injection)
|
|
14
|
+
* @returns {Array} Array of upgrade info objects
|
|
15
|
+
*/
|
|
16
|
+
function checkAllApiUpgrades(apiManager) {
|
|
17
|
+
const apis = apiManager.getApis();
|
|
18
|
+
const upgrades = [];
|
|
19
|
+
|
|
20
|
+
for (const api of apis) {
|
|
21
|
+
const latestModel = getLatestModel(api.model, api.provider);
|
|
22
|
+
if (latestModel) {
|
|
23
|
+
upgrades.push({
|
|
24
|
+
apiId: api.id,
|
|
25
|
+
apiName: api.name,
|
|
26
|
+
providerId: api.provider,
|
|
27
|
+
currentModel: api.model,
|
|
28
|
+
latestModel: latestModel
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return upgrades;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Check for model upgrades with caching
|
|
38
|
+
* @param {ApiManager} apiManager - ApiManager instance
|
|
39
|
+
* @param {boolean} force - Force check regardless of cache
|
|
40
|
+
* @returns {Promise<{upgrades: Array, needsCheck: boolean}>}
|
|
41
|
+
*/
|
|
42
|
+
async function checkForModelUpgrades(apiManager, force = false) {
|
|
43
|
+
const config = await versionChecker.loadConfig();
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
const cacheDuration = CHECK_INTERVAL_HOURS * 60 * 60 * 1000;
|
|
46
|
+
|
|
47
|
+
const needsCheck = force ||
|
|
48
|
+
!config.lastModelUpgradeCheck ||
|
|
49
|
+
(now - config.lastModelUpgradeCheck > cacheDuration);
|
|
50
|
+
|
|
51
|
+
if (!needsCheck) {
|
|
52
|
+
return { upgrades: [], needsCheck: false };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const upgrades = checkAllApiUpgrades(apiManager);
|
|
56
|
+
|
|
57
|
+
// Update last check time
|
|
58
|
+
config.lastModelUpgradeCheck = now;
|
|
59
|
+
await versionChecker.saveConfig(config);
|
|
60
|
+
|
|
61
|
+
return { upgrades, needsCheck: true };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get auto upgrade setting
|
|
66
|
+
* @returns {Promise<boolean>} Whether auto upgrade is enabled
|
|
67
|
+
*/
|
|
68
|
+
async function isAutoUpgradeEnabled() {
|
|
69
|
+
const config = await versionChecker.loadConfig();
|
|
70
|
+
return config.autoModelUpgrade === true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Perform auto upgrade for all APIs with available upgrades
|
|
75
|
+
* @param {ApiManager} apiManager - ApiManager instance
|
|
76
|
+
* @param {Array} upgrades - Array of upgrade info from checkForModelUpgrades
|
|
77
|
+
* @returns {Array} Array of upgraded API info
|
|
78
|
+
*/
|
|
79
|
+
function performAutoUpgrade(apiManager, upgrades) {
|
|
80
|
+
const upgraded = [];
|
|
81
|
+
|
|
82
|
+
for (const upgrade of upgrades) {
|
|
83
|
+
try {
|
|
84
|
+
apiManager.updateApiModel(upgrade.apiId, upgrade.latestModel);
|
|
85
|
+
upgraded.push({
|
|
86
|
+
apiName: upgrade.apiName,
|
|
87
|
+
from: upgrade.currentModel,
|
|
88
|
+
to: upgrade.latestModel
|
|
89
|
+
});
|
|
90
|
+
} catch (error) {
|
|
91
|
+
// Skip failed upgrades silently
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return upgraded;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = {
|
|
99
|
+
checkAllApiUpgrades,
|
|
100
|
+
checkForModelUpgrades,
|
|
101
|
+
isAutoUpgradeEnabled,
|
|
102
|
+
performAutoUpgrade
|
|
103
|
+
};
|
|
@@ -22,13 +22,21 @@ async function loadConfig() {
|
|
|
22
22
|
try {
|
|
23
23
|
const configPath = getConfigPath();
|
|
24
24
|
const data = await fs.readFile(configPath, 'utf8');
|
|
25
|
-
|
|
25
|
+
const config = JSON.parse(data);
|
|
26
|
+
|
|
27
|
+
// Add new fields for backward compatibility
|
|
28
|
+
if (config.autoModelUpgrade === undefined) config.autoModelUpgrade = false;
|
|
29
|
+
if (config.lastModelUpgradeCheck === undefined) config.lastModelUpgradeCheck = 0;
|
|
30
|
+
|
|
31
|
+
return config;
|
|
26
32
|
} catch (error) {
|
|
27
33
|
// Return default config if file doesn't exist
|
|
28
34
|
return {
|
|
29
35
|
language: 'zh',
|
|
30
36
|
lastVersionCheck: 0,
|
|
31
|
-
cachedLatestVersion: null
|
|
37
|
+
cachedLatestVersion: null,
|
|
38
|
+
autoModelUpgrade: false,
|
|
39
|
+
lastModelUpgradeCheck: 0
|
|
32
40
|
};
|
|
33
41
|
}
|
|
34
42
|
}
|
|
@@ -231,10 +239,21 @@ async function forceCheckForUpdates(timeoutMs = 15000) {
|
|
|
231
239
|
}
|
|
232
240
|
}
|
|
233
241
|
|
|
242
|
+
/**
|
|
243
|
+
* Set auto model upgrade setting
|
|
244
|
+
* @param {boolean} enabled - Whether to enable auto model upgrade
|
|
245
|
+
*/
|
|
246
|
+
async function setAutoModelUpgrade(enabled) {
|
|
247
|
+
const config = await loadConfig();
|
|
248
|
+
config.autoModelUpgrade = enabled;
|
|
249
|
+
await saveConfig(config);
|
|
250
|
+
}
|
|
251
|
+
|
|
234
252
|
module.exports = {
|
|
235
253
|
checkForUpdates,
|
|
236
254
|
forceCheckForUpdates,
|
|
237
255
|
clearCache,
|
|
238
256
|
loadConfig,
|
|
239
|
-
saveConfig
|
|
257
|
+
saveConfig,
|
|
258
|
+
setAutoModelUpgrade
|
|
240
259
|
};
|