yingclaw 1.8.1 → 1.8.2

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/bin/cli.js CHANGED
@@ -196,6 +196,7 @@ async function configureCustomProvider({ chalk, ora, existingConfig }) {
196
196
  apiKey,
197
197
  model,
198
198
  fastModel,
199
+ availableModels: onlineResult?.models || (model ? [model, fastModel].filter(Boolean) : []),
199
200
  };
200
201
  }
201
202
 
@@ -283,7 +284,7 @@ async function runConfigFlow({ writeCodeEnv = false } = {}) {
283
284
  if (!overwrite) return;
284
285
  }
285
286
 
286
- let providerKey, provider, apiKey, model, customConfig;
287
+ let providerKey, provider, apiKey, model, customConfig, availableModels;
287
288
  let step = 'provider';
288
289
 
289
290
  while (true) {
@@ -319,9 +320,11 @@ async function runConfigFlow({ writeCodeEnv = false } = {}) {
319
320
  if (onlineModels && onlineModels.length > 0) {
320
321
  fetchSpinner.succeed(chalk.green(`已获取 ${onlineModels.length} 个可用模型`));
321
322
  modelChoices = onlineModels.map(id => ({ name: id, value: id }));
323
+ availableModels = onlineModels;
322
324
  } else {
323
325
  fetchSpinner.warn(chalk.yellow('无法获取在线列表,使用内置默认列表'));
324
326
  modelChoices = provider.models;
327
+ availableModels = provider.models.map(m => m.value);
325
328
  }
326
329
 
327
330
  const m = await select({ loop: false,
@@ -342,7 +345,7 @@ async function runConfigFlow({ writeCodeEnv = false } = {}) {
342
345
  let cfg;
343
346
  try {
344
347
  const fastModel = customConfig?.fastModel || resolveFastModel(provider, model);
345
- cfg = customConfig || { provider: providerKey, model, fastModel, apiKey, baseUrl: provider.baseUrl };
348
+ cfg = customConfig || { provider: providerKey, model, fastModel, apiKey, baseUrl: provider.baseUrl, availableModels };
346
349
  saveConfig(cfg);
347
350
  if (writeCodeEnv) {
348
351
  ({ file } = writeEnvToZshrc(cfg.baseUrl, cfg.apiKey, cfg.model, cfg.fastModel));
@@ -589,12 +592,15 @@ program
589
592
  const fetchSpinner = ora('正在获取可用模型...').start();
590
593
  const onlineModels = await fetchModels(providerKey, apiKey);
591
594
  let modelChoices;
595
+ let availableModels;
592
596
  if (onlineModels && onlineModels.length > 0) {
593
597
  fetchSpinner.succeed(chalk.green(`已获取 ${onlineModels.length} 个可用模型`));
594
598
  modelChoices = onlineModels.map(id => ({ name: id, value: id }));
599
+ availableModels = onlineModels;
595
600
  } else {
596
601
  fetchSpinner.warn(chalk.yellow('无法获取在线列表,使用内置默认列表'));
597
602
  modelChoices = provider.models;
603
+ availableModels = provider.models.map(m => m.value);
598
604
  }
599
605
 
600
606
  const model = await select({ loop: false,
@@ -608,7 +614,7 @@ program
608
614
 
609
615
  const spinner = ora('切换中...').start();
610
616
  const fastModel = resolveFastModel(provider, model);
611
- const newConfig = { ...config, provider: providerKey, model, fastModel, baseUrl: provider.baseUrl, apiKey };
617
+ const newConfig = { ...config, provider: providerKey, model, fastModel, baseUrl: provider.baseUrl, apiKey, availableModels };
612
618
  saveConfig(newConfig);
613
619
  await new Promise(r => setTimeout(r, 300));
614
620
  spinner.succeed(chalk.green(`API 连接已切换至 ${provider.name} · ${model}`));
package/lib/desktop.js CHANGED
@@ -40,12 +40,17 @@ function readJsonFile(file) {
40
40
  }
41
41
  }
42
42
 
43
- function uniqueModels(model, fastModel) {
44
- return [...new Set([model, fastModel].filter(Boolean))];
43
+ function collectModels(config) {
44
+ // 优先用 config 中保存的全量模型列表(setup/switch 时联网拉取的)
45
+ // 退化:主模型 + 快速模型
46
+ const list = Array.isArray(config.availableModels) && config.availableModels.length > 0
47
+ ? [config.model, config.fastModel, ...config.availableModels]
48
+ : [config.model, config.fastModel];
49
+ return [...new Set(list.filter(Boolean))];
45
50
  }
46
51
 
47
52
  function buildClaudeDesktopEnterpriseConfig(config, options = {}) {
48
- const models = uniqueModels(config.model, config.fastModel);
53
+ const models = collectModels(config);
49
54
  const baseUrl = normalizeAnthropicBaseUrl(config.baseUrl);
50
55
  if (!baseUrl.startsWith('https://')) {
51
56
  throw new Error('Claude 桌面应用要求 Gateway Base URL 使用 HTTPS');
@@ -121,9 +126,10 @@ function clearClaudeDesktopConfig(options = {}) {
121
126
 
122
127
  function buildClaudeDesktopOpenCommands(platform = process.platform) {
123
128
  if (platform !== 'darwin') return null;
124
- // 先 quit open:避免已运行的实例缓存了旧配置
129
+ // 先 graceful quit,再 force kill 兜底,最后 open
125
130
  return [
126
- { command: 'osascript', args: ['-e', 'tell application "Claude" to quit'], optional: true },
131
+ { command: 'osascript', args: ['-e', 'tell application "Claude" to quit'], optional: true, waitAfter: 600 },
132
+ { command: 'pkill', args: ['-x', 'Claude'], optional: true, waitAfter: 400 },
127
133
  { command: 'open', args: ['-a', 'Claude'] },
128
134
  ];
129
135
  }
@@ -138,18 +144,15 @@ async function openClaudeDesktop(options = {}) {
138
144
  if (!commands) return { result: 'unsupported' };
139
145
 
140
146
  const runner = options.runner || spawnSync;
141
- const waitMs = options.waitMs ?? 700;
147
+ const isMocked = options.runner !== undefined;
142
148
 
143
- for (let i = 0; i < commands.length; i++) {
144
- const { command, args, optional } = commands[i];
149
+ for (const { command, args, optional, waitAfter } of commands) {
145
150
  const result = runner(command, args, { stdio: 'ignore', windowsHide: true });
146
- // optional 命令失败(比如 Claude 没在运行)不报错
147
151
  if (result.status !== 0 && !optional) {
148
152
  throw new Error('Claude 桌面应用打开失败');
149
153
  }
150
- // quit 后等一下再 open,给系统清理资源的时间
151
- if (i === 0 && commands.length > 1 && options.runner === undefined) {
152
- await sleep(waitMs);
154
+ if (waitAfter && !isMocked) {
155
+ await sleep(waitAfter);
153
156
  }
154
157
  }
155
158
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yingclaw",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "Claude Code × 国产大模型一键接入:DeepSeek、Kimi、Qwen、MiniMax、GLM、MiMo",
5
5
  "main": "index.js",
6
6
  "bin": {