yingclaw 1.6.1 → 1.6.3

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 CHANGED
@@ -48,6 +48,12 @@ claw switch # 快速切换模型(无需重新输入 Key)
48
48
  claw status # 查看当前配置,验证 Key 是否有效
49
49
  ```
50
50
 
51
+ ## 卸载
52
+
53
+ ```bash
54
+ npm uninstall -g yingclaw
55
+ ```
56
+
51
57
  ## 原理
52
58
 
53
59
  各厂商均原生支持 Anthropic API 格式。本工具会自动写入 Claude Code 所需的环境变量,包括:
package/bin/cli.js CHANGED
@@ -17,7 +17,7 @@ const {
17
17
  const { execSync, spawn, spawnSync } = require('child_process');
18
18
  const https = require('https');
19
19
  const pkg = require('../package.json');
20
- const { buildStatusView } = require('../lib/panel');
20
+ const { buildMenuStatusLines, buildStatusView } = require('../lib/panel');
21
21
 
22
22
  const program = new Command();
23
23
 
@@ -453,23 +453,19 @@ async function renderStatusBar(apiStatus) {
453
453
  claudeInstalled,
454
454
  env: process.env,
455
455
  });
456
- let dot;
457
- if (apiStatus === true) dot = chalk.green('●');
458
- else if (apiStatus === false) dot = chalk.red('');
459
- else if (apiStatus === null) dot = chalk.yellow('●');
460
- else dot = chalk.dim('●'); // 未检测
461
- const apiTag = apiStatus === true ? chalk.green(' API ✓')
462
- : apiStatus === false ? chalk.red(' API ✘')
463
- : apiStatus === null ? chalk.yellow(' 网络异常')
464
- : '';
465
- const envTag = view.envActive ? chalk.green(' env ✓') : chalk.yellow(' env 未生效');
466
- const legacyTag = view.warnings.length > 0 ? chalk.yellow(' 旧模型') : '';
467
- cfgPart = `${dot} ${chalk.white(view.providerName)}${apiTag}${envTag}${legacyTag}\n ${chalk.dim('主 ')}${chalk.yellow(view.mainModel)}${chalk.dim(' 快 ')}${chalk.yellow(view.fastModel)}`;
456
+ const statusLines = buildMenuStatusLines(view, { apiStatus, claudeInstalled });
457
+ cfgPart = statusLines.map((line, index) => {
458
+ if (index === 0) return line.replace('API 正常', chalk.green('API 正常')).replace('API Key 无效', chalk.red('API Key 无效')).replace('网络/服务异常', chalk.yellow('网络/服务异常'));
459
+ if (line.startsWith('环境变量未生效')) return chalk.yellow(line);
460
+ if (line.startsWith('旧模型名')) return chalk.yellow(line);
461
+ if (line.startsWith('主模型')) return line.replace(view.mainModel, chalk.yellow(view.mainModel)).replace(view.fastModel, chalk.yellow(view.fastModel));
462
+ return line;
463
+ }).join('\n ');
468
464
  } else {
469
465
  cfgPart = chalk.red('●') + ' ' + chalk.dim('未配置');
470
466
  }
471
467
 
472
- return ` ${claudeIcon} ${claudeText} ${cfgPart}`;
468
+ return config ? ` ${cfgPart}` : ` ${claudeIcon} ${claudeText} ${cfgPart}`;
473
469
  }
474
470
 
475
471
  async function runMenu() {
package/lib/config.js CHANGED
@@ -12,8 +12,8 @@ const PROVIDERS = {
12
12
  modelsUrl: 'https://api.deepseek.com/v1/models',
13
13
  fastModel: 'deepseek-v4-flash',
14
14
  models: [
15
- { name: 'DeepSeek V4 Flash(快速)', value: 'deepseek-v4-flash' },
16
15
  { name: 'DeepSeek V4 Pro(强力)', value: 'deepseek-v4-pro[1m]' },
16
+ { name: 'DeepSeek V4 Flash(快速)', value: 'deepseek-v4-flash' },
17
17
  ],
18
18
  },
19
19
  qwen: {
@@ -57,6 +57,17 @@ const PROVIDERS = {
57
57
  },
58
58
  };
59
59
 
60
+ function normalizeModelIds(providerKey, ids) {
61
+ if (providerKey !== 'deepseek') return ids;
62
+
63
+ const mapped = ids.map((id) => id === 'deepseek-v4-pro' ? 'deepseek-v4-pro[1m]' : id);
64
+ const preferred = ['deepseek-v4-pro[1m]', 'deepseek-v4-flash'];
65
+ return [
66
+ ...preferred.filter((id) => mapped.includes(id)),
67
+ ...mapped.filter((id) => !preferred.includes(id)),
68
+ ];
69
+ }
70
+
60
71
  // 联网拉取厂商支持的模型列表,失败返回 null
61
72
  function fetchModels(providerKey, apiKey) {
62
73
  return new Promise((resolve) => {
@@ -86,7 +97,7 @@ function fetchModels(providerKey, apiKey) {
86
97
  const list = parsed.data || parsed.models || [];
87
98
  const ids = list.map(m => m.id || m.model || m.name).filter(Boolean);
88
99
  if (ids.length === 0) return resolve(null);
89
- resolve(ids);
100
+ resolve(normalizeModelIds(providerKey, ids));
90
101
  } catch {
91
102
  resolve(null);
92
103
  }
@@ -245,6 +256,7 @@ module.exports = {
245
256
  fetchModels,
246
257
  resetConfig,
247
258
  validateConfig,
259
+ normalizeModelIds,
248
260
  resolveFastModel,
249
261
  providerKeyFromBaseUrl,
250
262
  buildClaudeEnv,
package/lib/panel.js CHANGED
@@ -46,4 +46,25 @@ function buildStatusView(config, options = {}) {
46
46
  };
47
47
  }
48
48
 
49
- module.exports = { buildStatusView, apiStatusText, isEnvActive };
49
+ function buildMenuStatusLines(view, options = {}) {
50
+ const claudeText = options.claudeInstalled ? 'Claude 已安装' : 'Claude 未安装';
51
+ const lines = [
52
+ `${claudeText} · ${view.providerName} · ${apiStatusText(options.apiStatus)}`,
53
+ ];
54
+
55
+ if (view.envActive) {
56
+ lines.push('环境变量已生效');
57
+ } else {
58
+ lines.push('环境变量未生效:运行 source ~/.zshrc 或重开终端');
59
+ }
60
+
61
+ lines.push(`主模型 ${view.mainModel} · 快速模型 ${view.fastModel}`);
62
+
63
+ if (view.warnings.some((warning) => warning.includes('旧 DeepSeek 模型名'))) {
64
+ lines.push('旧模型名:选择下方“切换厂商或模型”更新');
65
+ }
66
+
67
+ return lines;
68
+ }
69
+
70
+ module.exports = { buildMenuStatusLines, buildStatusView, apiStatusText, isEnvActive };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yingclaw",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "description": "Claude Code × 国产大模型一键接入:DeepSeek、Qwen、MiniMax、GLM、MiMo",
5
5
  "main": "index.js",
6
6
  "bin": {