@nvae/llmswitch 0.5.0 → 0.6.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.
@@ -4,6 +4,7 @@ import { formatLabel } from "../formats/compatibility.js";
4
4
  import { deleteProfile, ensureDefaultProvider, getActiveProfile, getDefaultProfile, listProfiles, publicProfileView, requireProfile, resolveProfileOrThrow, saveProfile, setDefaultProfile, } from "../store/profiles.js";
5
5
  import { formatProxySummary } from "../utils/proxy.js";
6
6
  import { runToolFlow } from "./setup-cmd.js";
7
+ import { launchTool } from "./launch.js";
7
8
  import { exitOnCancel, formatProfileListLabel, promptEditProfile, promptProfileDraft, resolveModelsInteractive, } from "./prompts.js";
8
9
  export function registerToolCommand(program, tool) {
9
10
  const cmd = program
@@ -37,7 +38,11 @@ export function registerToolCommand(program, tool) {
37
38
  .action(async (name, opts) => {
38
39
  ensureDefaultProvider(tool);
39
40
  const profileName = await resolveProfileName(tool, name);
40
- const profile = resolveProfileOrThrow(tool, profileName);
41
+ let profile = resolveProfileOrThrow(tool, profileName);
42
+ // 交互模式下:启用前可选切换默认模型
43
+ if (!opts?.json && process.stdin.isTTY) {
44
+ profile = await maybePickDefaultModel(tool, profile);
45
+ }
41
46
  const result = await applyProfile(tool, profile);
42
47
  if (opts?.json) {
43
48
  console.log(JSON.stringify(result, null, 2));
@@ -48,6 +53,9 @@ export function registerToolCommand(program, tool) {
48
53
  if (result.backupPath)
49
54
  console.log(`备份:${result.backupPath}`);
50
55
  console.log(result.restartHint);
56
+ if (process.stdin.isTTY) {
57
+ await maybeLaunchNow(tool, profile);
58
+ }
51
59
  });
52
60
  cmd
53
61
  .command("current")
@@ -285,6 +293,77 @@ function printProfileDetails(tool, profile, flags) {
285
293
  .filter(Boolean)
286
294
  .join("\n"), flags.title || `${tool} / ${profile.name}`);
287
295
  }
296
+ /**
297
+ * 启用供应商前:若模型列表内有多个候选,交互选择默认模型;
298
+ * 只有一个模型时直接跳过。支持手动输入不在列表中的模型 ID。
299
+ */
300
+ async function maybePickDefaultModel(tool, profile) {
301
+ const list = profile.models.list.length
302
+ ? profile.models.list
303
+ : [profile.models.default];
304
+ if (list.length <= 1)
305
+ return profile;
306
+ const picked = await p.select({
307
+ message: `选择 ${profile.displayName || profile.name} 的默认模型`,
308
+ options: [
309
+ ...list.map((model) => ({
310
+ value: model,
311
+ label: model,
312
+ hint: model === profile.models.default ? "当前默认" : undefined,
313
+ })),
314
+ { value: "__manual__", label: "手动输入模型 ID" },
315
+ ],
316
+ initialValue: profile.models.default,
317
+ });
318
+ exitOnCancel(picked);
319
+ let model = picked;
320
+ if (picked === "__manual__") {
321
+ const input = await p.text({
322
+ message: "模型 ID",
323
+ placeholder: profile.models.default,
324
+ });
325
+ if (p.isCancel(input) || !input.trim()) {
326
+ p.cancel("已取消");
327
+ process.exit(0);
328
+ }
329
+ model = input.trim();
330
+ }
331
+ if (model === profile.models.default)
332
+ return profile;
333
+ const updated = {
334
+ ...profile,
335
+ models: {
336
+ ...profile.models,
337
+ default: model,
338
+ list: profile.models.list.includes(model)
339
+ ? profile.models.list
340
+ : [...profile.models.list, model],
341
+ },
342
+ };
343
+ saveProfile(tool, updated);
344
+ return requireProfile(tool, updated.name);
345
+ }
346
+ /** 启用完成后:询问是否立即启动该工具。 */
347
+ async function maybeLaunchNow(tool, profile) {
348
+ const launch = await p.confirm({
349
+ message: `是否现在启动 ${tool}?`,
350
+ initialValue: true,
351
+ });
352
+ if (p.isCancel(launch)) {
353
+ p.cancel("已取消");
354
+ process.exit(0);
355
+ }
356
+ if (!launch)
357
+ return;
358
+ try {
359
+ await launchTool({ tool, profile: profile.name });
360
+ }
361
+ catch (err) {
362
+ const msg = err instanceof Error ? err.message : String(err);
363
+ p.log.error(msg);
364
+ p.log.warn(`未能启动。稍后可用:llms launch ${tool},或设置 ${tool.toUpperCase()}_BIN 指定可执行文件。`);
365
+ }
366
+ }
288
367
  async function configureProfileModels(tool, profile) {
289
368
  p.log.step(`配置 ${profile.displayName || profile.name} 的模型`);
290
369
  const resolved = await resolveModelsInteractive({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nvae/llmswitch",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "CLI to switch LLM providers and models for Claude Code, Codex, and OpenCode",
5
5
  "type": "module",
6
6
  "bin": {