@daylenjeez/ccm-switch 1.2.3 → 1.2.6

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
@@ -64,6 +64,8 @@ Active: OpenRouter
64
64
 
65
65
  You can also run `ccm sync` at any time to pull the latest cc-switch configurations into `~/.ccm/config.json`.
66
66
 
67
+ > ⚠️ **Known Issue**: After ccm modifies `~/.claude/settings.json`, cc-switch will automatically sync the content back to its database, overwriting the current provider's `settings_config`. If the configurations differ between the two tools, the original configuration stored in cc-switch will be modified.
68
+
67
69
  ## ➕ Adding Configurations
68
70
 
69
71
  ### Interactive wizard (recommended)
@@ -202,7 +204,11 @@ Use `ccm clear` to delete them automatically, or clean them up manually:
202
204
  - `~/.ccm/config.json` — profiles
203
205
  - `~/.claude/settings.json` — may still contain an active `env` profile written by ccm
204
206
 
205
- > Do **not** delete `~/.cc-switch/cc-switch.db` unless you are also uninstalling cc-switch; that database is owned by cc-switch.
207
+ Then remove the CLI:
208
+
209
+ ```bash
210
+ npm uninstall -g @daylenjeez/ccm-switch
211
+ ```
206
212
 
207
213
  ## 📄 License
208
214
 
package/README.zh-CN.md CHANGED
@@ -10,7 +10,7 @@
10
10
  [![license](https://img.shields.io/npm/l/@daylenjeez/ccm-switch.svg?style=flat-square)](https://github.com/daylenjeez/ccm-switch/blob/main/LICENSE)
11
11
  [![node](https://img.shields.io/badge/node-%3E%3D18-brightgreen?style=flat-square)](https://nodejs.org)
12
12
 
13
- English | [中文文档](https://github.com/daylenjeez/ccm-switch/blob/main/README.zh-CN.md)
13
+ [English](https://github.com/daylenjeez/ccm-switch/blob/main/README.md) | 中文文档
14
14
 
15
15
  [安装](#-安装) · [快速开始](#-快速开始) · [命令一览](#-命令一览) · [工作原理](#%EF%B8%8F-工作原理)
16
16
 
@@ -20,12 +20,12 @@ English | [中文文档](https://github.com/daylenjeez/ccm-switch/blob/main/READ
20
20
 
21
21
  ## ✨ 亮点
22
22
 
23
- - 🔌 **cc-switch 无缝对接** — 直接读取 [cc-switch](https://github.com/farion1231/cc-switch) 数据库,无需迁移
24
- - 🧙 **交互式向导** — `ccm add` 逐步引导,输入 `<` 可返回上一步
25
- - ⚡ **一键切换** — `ccm use OpenRouter` 或 `ccm ls` 方向键选择
26
- - 🛡️ **安全切换** — 自动保留 `language`、`permissions` 等个人设置
27
- - 🚀 **零配置上手** — 直接 `ccm init`,跟着提示走,无需阅读文档
28
- - 🌍 **中英双语** — `ccm locale set zh/en` 切换界面语言
23
+ - 🔌 **cc-switch Integration** — 直接读取 `cc-switch` 数据库,无需迁移
24
+ - 🧙 **Interactive Wizard** — `ccm add` 逐步引导,输入 `<` 可返回上一步
25
+ - ⚡ **One-command Switch** — `ccm use OpenRouter` 或 `ccm ls` 方向键选择
26
+ - 🛡️ **Safe Switching** — 自动保留 `language`、`permissions` 等个人设置
27
+ - 🚀 **Zero Config** — 直接 `ccm init`,跟着提示走,无需阅读文档
28
+ - 🌍 **i18n** — `ccm locale set zh/en` 切换界面语言
29
29
 
30
30
  ## 📦 安装
31
31
 
@@ -64,6 +64,8 @@ $ ccm init
64
64
 
65
65
  你也可以随时运行 `ccm sync` 将最新的 cc-switch 配置同步到 `~/.ccm/config.json`。
66
66
 
67
+ > ⚠️ **已知问题**:ccm 修改 `~/.claude/settings.json` 后,cc-switch 会自动将该内容同步回数据库,覆盖当前 provider 的 `settings_config`。如果两个工具中的配置不一致,cc-switch 中存储的原始配置将被修改。
68
+
67
69
  ## ➕ 添加配置
68
70
 
69
71
  ### 交互式向导(推荐)
@@ -202,7 +204,11 @@ Claude Code 启动时读取 `~/.claude/settings.json`,`env` 字段控制 API
202
204
  - `~/.ccm/config.json` — 配置方案
203
205
  - `~/.claude/settings.json` — 可能仍包含 ccm 写入的 `env` 配置
204
206
 
205
- > 除非你也卸载了 cc-switch,否则**不要**删除 `~/.cc-switch/cc-switch.db`;该数据库由 cc-switch 管理。
207
+ 然后移除 CLI:
208
+
209
+ ```bash
210
+ npm uninstall -g @daylenjeez/ccm-switch
211
+ ```
206
212
 
207
213
  ## 📄 License
208
214
 
package/dist/claude.d.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  export declare function readClaudeSettings(): Record<string, unknown>;
2
- export declare function applyProfile(settingsConfig: Record<string, unknown>): void;
3
- export declare function clearEnvFromSettings(): void;
2
+ export declare function applyProfile(_name: string, settingsConfig: Record<string, unknown>): void;
4
3
  export declare function getSettingsPath(): string;
package/dist/claude.js CHANGED
@@ -7,7 +7,7 @@ export function readClaudeSettings() {
7
7
  return {};
8
8
  return JSON.parse(readFileSync(SETTINGS_PATH, "utf-8"));
9
9
  }
10
- export function applyProfile(settingsConfig) {
10
+ export function applyProfile(_name, settingsConfig) {
11
11
  const current = readClaudeSettings();
12
12
  // 保留用户级字段,用 profile 的配置覆盖
13
13
  const preserved = {};
@@ -20,15 +20,6 @@ export function applyProfile(settingsConfig) {
20
20
  const merged = { ...preserved, ...settingsConfig };
21
21
  writeFileSync(SETTINGS_PATH, JSON.stringify(merged, null, 2));
22
22
  }
23
- export function clearEnvFromSettings() {
24
- if (!existsSync(SETTINGS_PATH))
25
- return;
26
- const current = readClaudeSettings();
27
- if (!("env" in current))
28
- return;
29
- delete current.env;
30
- writeFileSync(SETTINGS_PATH, JSON.stringify(current, null, 2));
31
- }
32
23
  export function getSettingsPath() {
33
24
  return SETTINGS_PATH;
34
25
  }
package/dist/i18n/en.js CHANGED
@@ -121,8 +121,6 @@ const en = {
121
121
  "clear.confirm": "Delete all ccm data files? (y/N) ",
122
122
  "clear.cancelled": "Cancelled",
123
123
  "clear.removed": "✓ Deleted {path}",
124
- "clear.clear_env": "Also clear env config in ~/.claude/settings.json? (y/N) ",
125
- "clear.env_cleared": "✓ Cleared env config",
126
124
  "clear.done": "✓ Cleanup complete",
127
125
  // store errors
128
126
  "store.db_not_found": "cc-switch database not found: {path}",
package/dist/i18n/zh.d.ts CHANGED
@@ -102,8 +102,6 @@ declare const zh: {
102
102
  readonly "clear.confirm": "确认删除所有 ccm 数据文件?(y/N) ";
103
103
  readonly "clear.cancelled": "已取消清理";
104
104
  readonly "clear.removed": "✓ 已删除 {path}";
105
- readonly "clear.clear_env": "是否同时清除 ~/.claude/settings.json 中的 env 配置?(y/N) ";
106
- readonly "clear.env_cleared": "✓ 已清除 env 配置";
107
105
  readonly "clear.done": "✓ 清理完成";
108
106
  readonly "store.db_not_found": "cc-switch 数据库不存在: {path}";
109
107
  };
package/dist/i18n/zh.js CHANGED
@@ -121,8 +121,6 @@ const zh = {
121
121
  "clear.confirm": "确认删除所有 ccm 数据文件?(y/N) ",
122
122
  "clear.cancelled": "已取消清理",
123
123
  "clear.removed": "✓ 已删除 {path}",
124
- "clear.clear_env": "是否同时清除 ~/.claude/settings.json 中的 env 配置?(y/N) ",
125
- "clear.env_cleared": "✓ 已清除 env 配置",
126
124
  "clear.done": "✓ 清理完成",
127
125
  // store errors
128
126
  "store.db_not_found": "cc-switch 数据库不存在: {path}",
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { Command } from "commander";
3
3
  import chalk from "chalk";
4
4
  import { readRc, writeRc, getStore } from "./utils.js";
5
5
  import { ccSwitchExists } from "./store/cc-switch.js";
6
- import { readClaudeSettings, applyProfile, clearEnvFromSettings, getSettingsPath } from "./claude.js";
6
+ import { readClaudeSettings, applyProfile } from "./claude.js";
7
7
  import { createInterface } from "readline";
8
8
  import { spawnSync } from "child_process";
9
9
  import { writeFileSync, readFileSync, unlinkSync, existsSync } from "fs";
@@ -240,17 +240,6 @@ program
240
240
  unlinkSync(rcPath);
241
241
  console.log(chalk.green(t("clear.removed", { path: rcPath })));
242
242
  }
243
- const settingsPath = getSettingsPath();
244
- if (existsSync(settingsPath)) {
245
- const settings = readClaudeSettings();
246
- if ("env" in settings) {
247
- const clearEnv = await ask(t("clear.clear_env"));
248
- if (clearEnv.toLowerCase() === "y") {
249
- clearEnvFromSettings();
250
- console.log(chalk.green(t("clear.env_cleared")));
251
- }
252
- }
253
- }
254
243
  console.log(chalk.green(t("clear.done")));
255
244
  });
256
245
  // ccm list
@@ -271,8 +260,8 @@ program
271
260
  if (name === current)
272
261
  return;
273
262
  const profile = store.get(name);
274
- applyProfile(profile.settingsConfig);
275
263
  store.setCurrent(profile.name);
264
+ applyProfile(profile.name, profile.settingsConfig);
276
265
  const env = (profile.settingsConfig.env || {});
277
266
  const model = env["ANTHROPIC_MODEL"] || t("common.model_default");
278
267
  console.log(chalk.green(t("use.done", { name: chalk.bold(profile.name) })));
@@ -366,8 +355,8 @@ program
366
355
  const profile = await resolveProfile(store, name);
367
356
  if (!profile)
368
357
  return;
369
- applyProfile(profile.settingsConfig);
370
358
  store.setCurrent(profile.name);
359
+ applyProfile(profile.name, profile.settingsConfig);
371
360
  const env = (profile.settingsConfig.env || {});
372
361
  const model = env["ANTHROPIC_MODEL"] || t("common.model_default");
373
362
  console.log(chalk.green(t("use.done", { name: chalk.bold(profile.name) })));
@@ -425,8 +414,8 @@ async function saveAndSwitch(store, name, settingsConfig) {
425
414
  console.log(chalk.green(t("add.done", { name })));
426
415
  const switchChoice = await ask(t("add.switch_confirm"));
427
416
  if (switchChoice.toLowerCase() !== "n") {
428
- applyProfile(settingsConfig);
429
417
  store.setCurrent(name);
418
+ applyProfile(name, settingsConfig);
430
419
  console.log(chalk.green(t("use.done", { name: chalk.bold(name) })));
431
420
  console.log(chalk.gray(` ${t("use.restart")}`));
432
421
  }
@@ -685,14 +674,14 @@ program
685
674
  if (profile.name !== current) {
686
675
  const switchChoice = await ask(t("add.switch_confirm"));
687
676
  if (switchChoice.toLowerCase() !== "n") {
688
- applyProfile(settingsConfig);
689
677
  store.setCurrent(profile.name);
678
+ applyProfile(profile.name, settingsConfig);
690
679
  console.log(chalk.green(t("use.done", { name: chalk.bold(profile.name) })));
691
680
  console.log(chalk.gray(` ${t("use.restart")}`));
692
681
  }
693
682
  }
694
683
  else {
695
- applyProfile(settingsConfig);
684
+ applyProfile(profile.name, settingsConfig);
696
685
  console.log(chalk.gray(` ${t("use.restart")}`));
697
686
  }
698
687
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daylenjeez/ccm-switch",
3
- "version": "1.2.3",
3
+ "version": "1.2.6",
4
4
  "description": "Claude Code Model Switcher - 快速切换 Claude Code 自定义模型配置",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/claude.ts CHANGED
@@ -9,7 +9,7 @@ export function readClaudeSettings(): Record<string, unknown> {
9
9
  return JSON.parse(readFileSync(SETTINGS_PATH, "utf-8"));
10
10
  }
11
11
 
12
- export function applyProfile(settingsConfig: Record<string, unknown>): void {
12
+ export function applyProfile(_name: string, settingsConfig: Record<string, unknown>): void {
13
13
  const current = readClaudeSettings();
14
14
 
15
15
  // 保留用户级字段,用 profile 的配置覆盖
@@ -25,14 +25,6 @@ export function applyProfile(settingsConfig: Record<string, unknown>): void {
25
25
  writeFileSync(SETTINGS_PATH, JSON.stringify(merged, null, 2));
26
26
  }
27
27
 
28
- export function clearEnvFromSettings(): void {
29
- if (!existsSync(SETTINGS_PATH)) return;
30
- const current = readClaudeSettings();
31
- if (!("env" in current)) return;
32
- delete current.env;
33
- writeFileSync(SETTINGS_PATH, JSON.stringify(current, null, 2));
34
- }
35
-
36
28
  export function getSettingsPath(): string {
37
29
  return SETTINGS_PATH;
38
30
  }
package/src/i18n/en.ts CHANGED
@@ -141,8 +141,6 @@ const en: Record<TranslationKey, string> = {
141
141
  "clear.confirm": "Delete all ccm data files? (y/N) ",
142
142
  "clear.cancelled": "Cancelled",
143
143
  "clear.removed": "✓ Deleted {path}",
144
- "clear.clear_env": "Also clear env config in ~/.claude/settings.json? (y/N) ",
145
- "clear.env_cleared": "✓ Cleared env config",
146
144
  "clear.done": "✓ Cleanup complete",
147
145
 
148
146
  // store errors
package/src/i18n/zh.ts CHANGED
@@ -139,8 +139,6 @@ const zh = {
139
139
  "clear.confirm": "确认删除所有 ccm 数据文件?(y/N) ",
140
140
  "clear.cancelled": "已取消清理",
141
141
  "clear.removed": "✓ 已删除 {path}",
142
- "clear.clear_env": "是否同时清除 ~/.claude/settings.json 中的 env 配置?(y/N) ",
143
- "clear.env_cleared": "✓ 已清除 env 配置",
144
142
  "clear.done": "✓ 清理完成",
145
143
 
146
144
  // store errors
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ import { Command } from "commander";
4
4
  import chalk from "chalk";
5
5
  import { readRc, writeRc, getStore } from "./utils.js";
6
6
  import { ccSwitchExists } from "./store/cc-switch.js";
7
- import { readClaudeSettings, applyProfile, clearEnvFromSettings, getSettingsPath } from "./claude.js";
7
+ import { readClaudeSettings, applyProfile } from "./claude.js";
8
8
  import { createInterface } from "readline";
9
9
  import { spawnSync } from "child_process";
10
10
  import { writeFileSync, readFileSync, unlinkSync, existsSync } from "fs";
@@ -270,18 +270,6 @@ program
270
270
  console.log(chalk.green(t("clear.removed", { path: rcPath })));
271
271
  }
272
272
 
273
- const settingsPath = getSettingsPath();
274
- if (existsSync(settingsPath)) {
275
- const settings = readClaudeSettings();
276
- if ("env" in settings) {
277
- const clearEnv = await ask(t("clear.clear_env"));
278
- if (clearEnv.toLowerCase() === "y") {
279
- clearEnvFromSettings();
280
- console.log(chalk.green(t("clear.env_cleared")));
281
- }
282
- }
283
- }
284
-
285
273
  console.log(chalk.green(t("clear.done")));
286
274
  });
287
275
 
@@ -304,8 +292,8 @@ program
304
292
  const switchTo = (name: string) => {
305
293
  if (name === current) return;
306
294
  const profile = store.get(name)!;
307
- applyProfile(profile.settingsConfig);
308
295
  store.setCurrent(profile.name);
296
+ applyProfile(profile.name, profile.settingsConfig);
309
297
  const env = (profile.settingsConfig.env || {}) as Record<string, string>;
310
298
  const model = env["ANTHROPIC_MODEL"] || t("common.model_default");
311
299
  console.log(chalk.green(t("use.done", { name: chalk.bold(profile.name) })));
@@ -406,8 +394,8 @@ program
406
394
  const profile = await resolveProfile(store, name);
407
395
  if (!profile) return;
408
396
 
409
- applyProfile(profile.settingsConfig);
410
397
  store.setCurrent(profile.name);
398
+ applyProfile(profile.name, profile.settingsConfig);
411
399
 
412
400
  const env = (profile.settingsConfig.env || {}) as Record<string, string>;
413
401
  const model = env["ANTHROPIC_MODEL"] || t("common.model_default");
@@ -469,8 +457,8 @@ async function saveAndSwitch(store: ReturnType<typeof ensureStore>, name: string
469
457
 
470
458
  const switchChoice = await ask(t("add.switch_confirm"));
471
459
  if (switchChoice.toLowerCase() !== "n") {
472
- applyProfile(settingsConfig);
473
460
  store.setCurrent(name);
461
+ applyProfile(name, settingsConfig);
474
462
  console.log(chalk.green(t("use.done", { name: chalk.bold(name) })));
475
463
  console.log(chalk.gray(` ${t("use.restart")}`));
476
464
  }
@@ -758,13 +746,13 @@ program
758
746
  if (profile.name !== current) {
759
747
  const switchChoice = await ask(t("add.switch_confirm"));
760
748
  if (switchChoice.toLowerCase() !== "n") {
761
- applyProfile(settingsConfig);
762
749
  store.setCurrent(profile.name);
750
+ applyProfile(profile.name, settingsConfig);
763
751
  console.log(chalk.green(t("use.done", { name: chalk.bold(profile.name) })));
764
752
  console.log(chalk.gray(` ${t("use.restart")}`));
765
753
  }
766
754
  } else {
767
- applyProfile(settingsConfig);
755
+ applyProfile(profile.name, settingsConfig);
768
756
  console.log(chalk.gray(` ${t("use.restart")}`));
769
757
  }
770
758
  });