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 +9 -3
- package/lib/desktop.js +15 -12
- package/package.json +1 -1
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
|
|
44
|
-
|
|
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 =
|
|
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
|
|
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
|
|
147
|
+
const isMocked = options.runner !== undefined;
|
|
142
148
|
|
|
143
|
-
for (
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
await sleep(waitMs);
|
|
154
|
+
if (waitAfter && !isMocked) {
|
|
155
|
+
await sleep(waitAfter);
|
|
153
156
|
}
|
|
154
157
|
}
|
|
155
158
|
|