@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.
@@ -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
  };
@@ -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.7-sonnet',
13
+ 'claude-3-7-sonnet',
14
14
  'claude-sonnet-4',
15
- 'claude-sonnet-4.5',
15
+ 'claude-sonnet-4-5',
16
16
  'claude-opus-4',
17
- 'claude-opus-4.1',
18
- 'claude-opus-4.5'
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.5/4.6/4.7) - 智谱清言',
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-4.5',
126
+ 'glm-5',
127
+ 'glm-4.7',
115
128
  'glm-4.6',
116
- 'glm-4.7'
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.5/4.6/4.7) - ZhiPu Global',
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-4.5',
150
+ 'glm-5',
151
+ 'glm-4.7',
133
152
  'glm-4.6',
134
- 'glm-4.7'
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
- return JSON.parse(data);
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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kikkimo/claude-launcher",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "Interactive launcher for Claude Code with beautiful Claude-style interface",
5
5
  "main": "claude-launcher",
6
6
  "bin": {