zcf 2.8.0 → 2.8.1

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
@@ -24,8 +24,9 @@ Menu options include:
24
24
 
25
25
  - `1` Full initialization (equivalent to `zcf i`)
26
26
  - `2` Import workflows (equivalent to `zcf u`)
27
- - `3-7` Configuration management (API/CCR, MCP, Model, AI personality, etc.)
28
- - `R` Claude Code Router management (new feature)
27
+ - `3-7` Configuration management (API/CCR, MCP, Model settings, AI personality, etc.)
28
+ - `R` Claude Code Router management (enhanced in v2.8.1)
29
+ - `U` ccusage - Claude Code usage analysis
29
30
  - More features...
30
31
 
31
32
  ### Or, use direct commands:
@@ -54,7 +55,7 @@ npx zcf → select 2 # Execute workflow update via menu
54
55
 
55
56
  #### 🎯 BMad Workflow (v2.7 New Feature)
56
57
 
57
- BMad (Business-Minded Agile Development) is an enterprise-grade workflow system that provides:
58
+ [BMad](https://github.com/bmad-code-org/BMAD-METHOD) (BMad-Method: Universal AI Agent Framework) is an enterprise-grade workflow system that provides:
58
59
 
59
60
  - Complete team of specialized AI agents (PO, PM, Architect, Dev, QA, etc.)
60
61
  - Structured development process with quality gates
@@ -63,19 +64,28 @@ BMad (Business-Minded Agile Development) is an enterprise-grade workflow system
63
64
 
64
65
  After installation, use `/bmad-init` to initialize the BMad workflow in your project.
65
66
 
66
- #### 🚀 CCR (Claude Code Router) Support (v2.8 New Feature)
67
+ #### 🚀 CCR (Claude Code Router) Support (v2.8+ Enhanced)
67
68
 
68
- CCR is a powerful proxy router that enables:
69
+ [CCR](https://github.com/musistudio/claude-code-router/blob/main/README.md) is a powerful proxy router that enables:
69
70
 
70
71
  - **Free Model Access**: Use free AI models (like Gemini, DeepSeek) through Claude Code interface
71
72
  - **Custom Routing**: Route different types of requests to different models based on your rules
72
73
  - **Cost Optimization**: Significantly reduce API costs by using appropriate models for different tasks
73
74
  - **Easy Management**: Interactive menu for CCR configuration and service control
75
+ - **Auto Updates**: Automatic version checking and updates for CCR and Claude Code (v2.8.1+)
74
76
 
75
77
  To access CCR features:
76
78
 
77
79
  ```bash
78
80
  npx zcf ccr # Open CCR management menu
81
+ # or
82
+ npx zcf → select R
83
+ ```
84
+
85
+ Check for updates (v2.8.1+):
86
+
87
+ ```bash
88
+ npx zcf check-updates # Check and update Claude Code and CCR to latest versions
79
89
  ```
80
90
 
81
91
  CCR menu options:
@@ -163,7 +173,7 @@ After configuration:
163
173
  ```bash
164
174
  $ npx zcf
165
175
 
166
- ZCF - Zero-Config Claude-Code Flow v2.3.0
176
+ ZCF - Zero-Config Claude-Code Flow
167
177
 
168
178
  ? Select ZCF display language / 选择ZCF显示语言:
169
179
  ❯ 简体中文
@@ -179,10 +189,14 @@ Select function:
179
189
  6. Configure Claude global memory - Configure AI output language and personality
180
190
  7. Import recommended environment variables and permissions - Import privacy protection environment variables and system permissions
181
191
 
192
+ --------- Other Tools ----------
193
+ R. CCR Management - Claude Code Router management
194
+ U. CCUsage - Claude Code usage analysis tool
195
+
182
196
  ------------ ZCF ------------
183
197
  0. Select display language / 更改显示语言 - Change ZCF interface language
184
198
  -. Clear preference cache - Clear preference language and other caches
185
- q. Exit
199
+ Q. Exit
186
200
 
187
201
  Enter your choice: _
188
202
  ```
@@ -268,13 +282,13 @@ Enter your choice: _
268
282
 
269
283
  #### Commands Quick Reference
270
284
 
271
- | Command | Alias | Description |
272
- | ------------ | ------- | --------------------------------------------- |
273
- | `zcf` | - | Show interactive menu (v2.0 default command) |
274
- | `zcf init` | `zcf i` | Initialize Claude Code configuration |
275
- | `zcf update` | `zcf u` | Update workflow-related md files with backup |
276
- | `zcf ccu` | - | Run Claude Code usage analysis tool |
277
- | `zcf ccr` | - | Open CCR (Claude Code Router) management menu |
285
+ | Command | Alias | Description |
286
+ | ------------ | ------- | ------------------------------------------------------------------------------------- |
287
+ | `zcf` | - | Show interactive menu (v2.0 default command) |
288
+ | `zcf init` | `zcf i` | Initialize Claude Code configuration |
289
+ | `zcf update` | `zcf u` | Update workflow-related md files with backup |
290
+ | `zcf ccu` | - | Run Claude Code usage analysis tool - [ccusage](https://github.com/ryoppippi/ccusage) |
291
+ | `zcf ccr` | - | Open CCR (Claude Code Router) management menu |
278
292
 
279
293
  #### Common Options
280
294
 
@@ -466,14 +480,28 @@ To protect user data security, the following operations require explicit confirm
466
480
 
467
481
  ## 🙏 Acknowledgments
468
482
 
469
- Some prompts in this project are inspired by the following excellent works:
483
+ This project is inspired by and incorporates the following open source projects:
470
484
 
471
- - [Linux.do - Share a universal Prompt for AI to generate only necessary code, welcome to optimize together~](https://linux.do/t/topic/830802)
472
- - [Linux.do - Don't worry about claude code degradation, using agent and command combination to break down tasks in detail may help you](https://linux.do/t/topic/815230)
473
- - [Linux.do - cursor rapid development rules](https://linux.do/t/topic/697566)
485
+ - [LINUX DO - The New Ideal Community](https://linux.do)
486
+ - [CCR](https://github.com/musistudio/claude-code-router)
487
+ - [ccusage](https://github.com/ryoppippi/ccusage)
488
+ - [BMad Method](https://github.com/bmad-code-org/BMAD-METHOD)
474
489
 
475
490
  Thanks to these community contributors for sharing!
476
491
 
492
+ ## ❤️ Support & Sponsorship
493
+
494
+ If you find this project helpful, please consider sponsoring its development. Your support is greatly appreciated!
495
+
496
+ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/UfoMiao)
497
+
498
+ <table>
499
+ <tr>
500
+ <td><img src="/src/assets/alipay.webp" width="200" alt="Alipay" /></td>
501
+ <td><img src="/src/assets/wechat.webp" width="200" alt="WeChat Pay" /></td>
502
+ </tr>
503
+ </table>
504
+
477
505
  ## 📄 License
478
506
 
479
507
  MIT License
@@ -5,13 +5,21 @@ import { join, dirname } from 'pathe';
5
5
  import dayjs from 'dayjs';
6
6
  import { fileURLToPath } from 'node:url';
7
7
  import { exec } from 'tinyexec';
8
- import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
9
- import { exec as exec$1 } from 'node:child_process';
10
- import { promisify } from 'node:util';
8
+ import { exec as exec$1 } from 'child_process';
9
+ import { promisify } from 'util';
10
+ import ora from 'ora';
11
+ import prompts$1 from 'prompts';
12
+ import { readFile as readFile$1, writeFile as writeFile$1, mkdir } from 'fs/promises';
13
+ import { join as join$1 } from 'path';
14
+ import { homedir as homedir$1 } from 'os';
15
+ import semver from 'semver';
16
+ import { rm, mkdir as mkdir$1, copyFile as copyFile$1 } from 'node:fs/promises';
17
+ import { exec as exec$2 } from 'node:child_process';
18
+ import { promisify as promisify$1 } from 'node:util';
11
19
  import { homedir, platform } from 'node:os';
12
- import { join as join$1 } from 'node:path';
20
+ import { join as join$2 } from 'node:path';
13
21
 
14
- const version = "2.8.0";
22
+ const version = "2.8.1";
15
23
  const homepage = "https://github.com/UfoMiao/zcf";
16
24
 
17
25
  const common$1 = {
@@ -123,11 +131,21 @@ const configuration$1 = {
123
131
  // Model configuration
124
132
  selectDefaultModel: "\u9009\u62E9\u9ED8\u8BA4\u6A21\u578B",
125
133
  modelConfigSuccess: "\u9ED8\u8BA4\u6A21\u578B\u5DF2\u914D\u7F6E",
134
+ existingModelConfig: "\u68C0\u6D4B\u5230\u5DF2\u6709\u6A21\u578B\u914D\u7F6E",
135
+ currentModel: "\u5F53\u524D\u6A21\u578B",
136
+ modifyModel: "\u662F\u5426\u4FEE\u6539\u6A21\u578B\u914D\u7F6E\uFF1F",
137
+ keepModel: "\u4FDD\u6301\u5F53\u524D\u6A21\u578B\u914D\u7F6E",
138
+ defaultModelOption: "\u9ED8\u8BA4\uFF08\u8BA9 Claude Code \u81EA\u52A8\u9009\u62E9\uFF09",
139
+ modelConfigured: "\u9ED8\u8BA4\u6A21\u578B\u5DF2\u914D\u7F6E",
126
140
  // AI memory configuration
127
141
  selectMemoryOption: "\u9009\u62E9\u914D\u7F6E\u9009\u9879",
128
142
  configureAiLanguage: "\u914D\u7F6E AI \u8F93\u51FA\u8BED\u8A00",
129
143
  configureAiPersonality: "\u914D\u7F6E AI \u4E2A\u6027\u98CE\u683C",
130
144
  aiLanguageConfigured: "AI \u8F93\u51FA\u8BED\u8A00\u5DF2\u914D\u7F6E",
145
+ existingLanguageConfig: "\u68C0\u6D4B\u5230\u5DF2\u6709 AI \u8F93\u51FA\u8BED\u8A00\u914D\u7F6E",
146
+ currentLanguage: "\u5F53\u524D\u8BED\u8A00",
147
+ modifyLanguage: "\u662F\u5426\u4FEE\u6539 AI \u8F93\u51FA\u8BED\u8A00\uFF1F",
148
+ keepLanguage: "\u4FDD\u6301\u5F53\u524D\u8BED\u8A00\u914D\u7F6E",
131
149
  // AI personality
132
150
  selectAiPersonality: "\u9009\u62E9 AI \u4E2A\u6027\u98CE\u683C",
133
151
  customPersonalityHint: "\u5B9A\u4E49\u4F60\u81EA\u5DF1\u7684\u4E2A\u6027",
@@ -430,6 +448,24 @@ const ccrMessages$1 = {
430
448
  ccrUiApiKeyHint: "\u4F7F\u7528\u6B64\u5BC6\u94A5\u767B\u5F55 CCR UI \u754C\u9762"
431
449
  };
432
450
 
451
+ const updater$1 = {
452
+ checkingVersion: "\u6B63\u5728\u68C0\u67E5\u7248\u672C...",
453
+ checkingTools: "\u68C0\u67E5\u5DE5\u5177\u7248\u672C",
454
+ ccrNotInstalled: "CCR \u672A\u5B89\u88C5",
455
+ ccrUpToDate: "CCR \u5DF2\u662F\u6700\u65B0\u7248\u672C (v{version})",
456
+ claudeCodeNotInstalled: "Claude Code \u672A\u5B89\u88C5",
457
+ claudeCodeUpToDate: "Claude Code \u5DF2\u662F\u6700\u65B0\u7248\u672C (v{version})",
458
+ cannotCheckVersion: "\u65E0\u6CD5\u68C0\u67E5\u6700\u65B0\u7248\u672C",
459
+ currentVersion: "\u5F53\u524D\u7248\u672C: v{version}",
460
+ latestVersion: "\u6700\u65B0\u7248\u672C: v{version}",
461
+ confirmUpdate: "\u662F\u5426\u66F4\u65B0 {tool} \u5230\u6700\u65B0\u7248\u672C\uFF1F",
462
+ updateSkipped: "\u5DF2\u8DF3\u8FC7\u66F4\u65B0",
463
+ updating: "\u6B63\u5728\u66F4\u65B0 {tool}...",
464
+ updateSuccess: "{tool} \u66F4\u65B0\u6210\u529F\uFF01",
465
+ updateFailed: "{tool} \u66F4\u65B0\u5931\u8D25",
466
+ checkFailed: "\u7248\u672C\u68C0\u67E5\u5931\u8D25"
467
+ };
468
+
433
469
  const zhCN = {
434
470
  common: common$1,
435
471
  language: language$1,
@@ -443,7 +479,8 @@ const zhCN = {
443
479
  bmad: bmad$1,
444
480
  errors: errors$1,
445
481
  tools: tools$1,
446
- ccr: ccrMessages$1
482
+ ccr: ccrMessages$1,
483
+ updater: updater$1
447
484
  };
448
485
 
449
486
  const common = {
@@ -555,11 +592,21 @@ const configuration = {
555
592
  // Model configuration
556
593
  selectDefaultModel: "Select default model",
557
594
  modelConfigSuccess: "Default model configured",
595
+ existingModelConfig: "Existing model configuration detected",
596
+ currentModel: "Current model",
597
+ modifyModel: "Modify model configuration?",
598
+ keepModel: "Keeping existing model configuration",
599
+ defaultModelOption: "Default (Let Claude Code choose)",
600
+ modelConfigured: "Default model configured",
558
601
  // AI memory configuration
559
602
  selectMemoryOption: "Select configuration option",
560
603
  configureAiLanguage: "Configure AI output language",
561
604
  configureAiPersonality: "Configure AI personality",
562
605
  aiLanguageConfigured: "AI output language configured",
606
+ existingLanguageConfig: "Existing AI output language configuration detected",
607
+ currentLanguage: "Current language",
608
+ modifyLanguage: "Modify AI output language?",
609
+ keepLanguage: "Keeping existing language configuration",
563
610
  // AI personality
564
611
  selectAiPersonality: "Select AI personality",
565
612
  customPersonalityHint: "Define your own personality",
@@ -862,6 +909,24 @@ const ccrMessages = {
862
909
  ccrUiApiKeyHint: "Use this API key to login to CCR UI"
863
910
  };
864
911
 
912
+ const updater = {
913
+ checkingVersion: "Checking version...",
914
+ checkingTools: "Checking tool versions",
915
+ ccrNotInstalled: "CCR is not installed",
916
+ ccrUpToDate: "CCR is up to date (v{version})",
917
+ claudeCodeNotInstalled: "Claude Code is not installed",
918
+ claudeCodeUpToDate: "Claude Code is up to date (v{version})",
919
+ cannotCheckVersion: "Cannot check latest version",
920
+ currentVersion: "Current version: v{version}",
921
+ latestVersion: "Latest version: v{version}",
922
+ confirmUpdate: "Update {tool} to the latest version?",
923
+ updateSkipped: "Update skipped",
924
+ updating: "Updating {tool}...",
925
+ updateSuccess: "{tool} updated successfully!",
926
+ updateFailed: "{tool} update failed",
927
+ checkFailed: "Version check failed"
928
+ };
929
+
865
930
  const en = {
866
931
  common,
867
932
  language,
@@ -875,7 +940,8 @@ const en = {
875
940
  bmad,
876
941
  errors,
877
942
  tools,
878
- ccr: ccrMessages
943
+ ccr: ccrMessages,
944
+ updater
879
945
  };
880
946
 
881
947
  const I18N$1 = {
@@ -1672,7 +1738,11 @@ function updateDefaultModel(model) {
1672
1738
  if (existingSettings) {
1673
1739
  settings = existingSettings;
1674
1740
  }
1675
- settings.model = model;
1741
+ if (model === "default") {
1742
+ delete settings.model;
1743
+ } else {
1744
+ settings.model = model;
1745
+ }
1676
1746
  writeJsonConfig(SETTINGS_FILE, settings);
1677
1747
  }
1678
1748
  function mergeSettingsFile(templatePath, targetPath) {
@@ -1720,6 +1790,16 @@ function mergeSettingsFile(templatePath, targetPath) {
1720
1790
  }
1721
1791
  }
1722
1792
  }
1793
+ function getExistingModelConfig() {
1794
+ const settings = readJsonConfig(SETTINGS_FILE);
1795
+ if (!settings) {
1796
+ return null;
1797
+ }
1798
+ if (!settings.model) {
1799
+ return "default";
1800
+ }
1801
+ return settings.model;
1802
+ }
1723
1803
  function getExistingApiConfig() {
1724
1804
  const settings = readJsonConfig(SETTINGS_FILE);
1725
1805
  if (!settings || !settings.env) {
@@ -1953,11 +2033,223 @@ async function updatePromptOnly(configLang, scriptLang, aiOutputLang) {
1953
2033
  console.log("\n" + ansis.cyan(i18n.common.complete));
1954
2034
  }
1955
2035
 
2036
+ function format(template, replacements) {
2037
+ return template.replace(/\{(\w+)\}/g, (match, key) => {
2038
+ return replacements[key] || match;
2039
+ });
2040
+ }
2041
+
2042
+ const execAsync$3 = promisify(exec$1);
2043
+ const CACHE_DIR = join$1(homedir$1(), ".claude", "cache");
2044
+ const CACHE_FILE = join$1(CACHE_DIR, "version-cache.json");
2045
+ const CACHE_DURATION = 24 * 60 * 60 * 1e3;
2046
+ async function ensureCacheDir() {
2047
+ try {
2048
+ await mkdir(CACHE_DIR, { recursive: true });
2049
+ } catch (error) {
2050
+ }
2051
+ }
2052
+ async function readCache() {
2053
+ try {
2054
+ const content = await readFile$1(CACHE_FILE, "utf-8");
2055
+ return JSON.parse(content);
2056
+ } catch {
2057
+ return {};
2058
+ }
2059
+ }
2060
+ async function writeCache(cache) {
2061
+ await ensureCacheDir();
2062
+ await writeFile$1(CACHE_FILE, JSON.stringify(cache, null, 2));
2063
+ }
2064
+ async function getInstalledVersion(command) {
2065
+ try {
2066
+ let stdout;
2067
+ try {
2068
+ const result = await execAsync$3(`${command} -v`);
2069
+ stdout = result.stdout;
2070
+ } catch {
2071
+ const result = await execAsync$3(`${command} --version`);
2072
+ stdout = result.stdout;
2073
+ }
2074
+ const versionMatch = stdout.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
2075
+ return versionMatch ? versionMatch[1] : null;
2076
+ } catch {
2077
+ return null;
2078
+ }
2079
+ }
2080
+ async function getLatestVersion(packageName, useCache = true) {
2081
+ if (useCache) {
2082
+ const cache = await readCache();
2083
+ const cached = cache[packageName];
2084
+ if (cached && Date.now() - cached.checkedAt < CACHE_DURATION) {
2085
+ return cached.version;
2086
+ }
2087
+ }
2088
+ try {
2089
+ const { stdout } = await execAsync$3(`npm view ${packageName} version`);
2090
+ const version = stdout.trim();
2091
+ const cache = await readCache();
2092
+ cache[packageName] = {
2093
+ version,
2094
+ checkedAt: Date.now()
2095
+ };
2096
+ await writeCache(cache);
2097
+ return version;
2098
+ } catch {
2099
+ return null;
2100
+ }
2101
+ }
2102
+ function compareVersions(current, latest) {
2103
+ if (!semver.valid(current) || !semver.valid(latest)) {
2104
+ return -1;
2105
+ }
2106
+ return semver.compare(current, latest);
2107
+ }
2108
+ function shouldUpdate(current, latest) {
2109
+ return compareVersions(current, latest) < 0;
2110
+ }
2111
+ async function checkCcrVersion() {
2112
+ const currentVersion = await getInstalledVersion("ccr");
2113
+ let latestVersion = await getLatestVersion("@musistudio/claude-code-router");
2114
+ if (!latestVersion) {
2115
+ latestVersion = await getLatestVersion("claude-code-router");
2116
+ }
2117
+ return {
2118
+ installed: currentVersion !== null,
2119
+ currentVersion,
2120
+ latestVersion,
2121
+ needsUpdate: currentVersion && latestVersion ? shouldUpdate(currentVersion, latestVersion) : false
2122
+ };
2123
+ }
2124
+ async function checkClaudeCodeVersion() {
2125
+ const currentVersion = await getInstalledVersion("claude");
2126
+ const latestVersion = await getLatestVersion("@anthropic-ai/claude-code");
2127
+ return {
2128
+ installed: currentVersion !== null,
2129
+ currentVersion,
2130
+ latestVersion,
2131
+ needsUpdate: currentVersion && latestVersion ? shouldUpdate(currentVersion, latestVersion) : false
2132
+ };
2133
+ }
2134
+
2135
+ const execAsync$2 = promisify(exec$1);
2136
+ async function updateCcr(scriptLang, force = false) {
2137
+ const i18n = getTranslation(scriptLang);
2138
+ const spinner = ora(i18n.updater.checkingVersion).start();
2139
+ try {
2140
+ const { installed, currentVersion, latestVersion, needsUpdate } = await checkCcrVersion();
2141
+ spinner.stop();
2142
+ if (!installed) {
2143
+ console.log(ansis.yellow(i18n.updater.ccrNotInstalled));
2144
+ return false;
2145
+ }
2146
+ if (!needsUpdate && !force) {
2147
+ console.log(ansis.green(format(i18n.updater.ccrUpToDate, { version: currentVersion || "" })));
2148
+ return true;
2149
+ }
2150
+ if (!latestVersion) {
2151
+ console.log(ansis.yellow(i18n.updater.cannotCheckVersion));
2152
+ return false;
2153
+ }
2154
+ console.log(ansis.cyan(format(i18n.updater.currentVersion, { version: currentVersion || "" })));
2155
+ console.log(ansis.cyan(format(i18n.updater.latestVersion, { version: latestVersion })));
2156
+ const { confirm } = await prompts$1({
2157
+ type: "confirm",
2158
+ name: "confirm",
2159
+ message: format(i18n.updater.confirmUpdate, { tool: "CCR" }),
2160
+ initial: true
2161
+ });
2162
+ if (!confirm) {
2163
+ console.log(ansis.gray(i18n.updater.updateSkipped));
2164
+ return true;
2165
+ }
2166
+ const updateSpinner = ora(format(i18n.updater.updating, { tool: "CCR" })).start();
2167
+ try {
2168
+ try {
2169
+ await execAsync$2("npm update -g @musistudio/claude-code-router");
2170
+ } catch {
2171
+ await execAsync$2("npm update -g claude-code-router");
2172
+ }
2173
+ updateSpinner.succeed(format(i18n.updater.updateSuccess, { tool: "CCR" }));
2174
+ return true;
2175
+ } catch (error) {
2176
+ updateSpinner.fail(format(i18n.updater.updateFailed, { tool: "CCR" }));
2177
+ console.error(ansis.red(error instanceof Error ? error.message : String(error)));
2178
+ return false;
2179
+ }
2180
+ } catch (error) {
2181
+ spinner.fail(i18n.updater.checkFailed);
2182
+ console.error(ansis.red(error instanceof Error ? error.message : String(error)));
2183
+ return false;
2184
+ }
2185
+ }
2186
+ async function updateClaudeCode(scriptLang, force = false) {
2187
+ const i18n = getTranslation(scriptLang);
2188
+ const spinner = ora(i18n.updater.checkingVersion).start();
2189
+ try {
2190
+ const { installed, currentVersion, latestVersion, needsUpdate } = await checkClaudeCodeVersion();
2191
+ spinner.stop();
2192
+ if (!installed) {
2193
+ console.log(ansis.yellow(i18n.updater.claudeCodeNotInstalled));
2194
+ return false;
2195
+ }
2196
+ if (!needsUpdate && !force) {
2197
+ console.log(ansis.green(format(i18n.updater.claudeCodeUpToDate, { version: currentVersion || "" })));
2198
+ return true;
2199
+ }
2200
+ if (!latestVersion) {
2201
+ console.log(ansis.yellow(i18n.updater.cannotCheckVersion));
2202
+ return false;
2203
+ }
2204
+ console.log(ansis.cyan(format(i18n.updater.currentVersion, { version: currentVersion || "" })));
2205
+ console.log(ansis.cyan(format(i18n.updater.latestVersion, { version: latestVersion })));
2206
+ const { confirm } = await prompts$1({
2207
+ type: "confirm",
2208
+ name: "confirm",
2209
+ message: format(i18n.updater.confirmUpdate, { tool: "Claude Code" }),
2210
+ initial: true
2211
+ });
2212
+ if (!confirm) {
2213
+ console.log(ansis.gray(i18n.updater.updateSkipped));
2214
+ return true;
2215
+ }
2216
+ const updateSpinner = ora(format(i18n.updater.updating, { tool: "Claude Code" })).start();
2217
+ try {
2218
+ await execAsync$2("npm update -g @anthropic-ai/claude-code");
2219
+ updateSpinner.succeed(format(i18n.updater.updateSuccess, { tool: "Claude Code" }));
2220
+ return true;
2221
+ } catch (error) {
2222
+ updateSpinner.fail(format(i18n.updater.updateFailed, { tool: "Claude Code" }));
2223
+ console.error(ansis.red(error instanceof Error ? error.message : String(error)));
2224
+ return false;
2225
+ }
2226
+ } catch (error) {
2227
+ spinner.fail(i18n.updater.checkFailed);
2228
+ console.error(ansis.red(error instanceof Error ? error.message : String(error)));
2229
+ return false;
2230
+ }
2231
+ }
2232
+ async function checkAndUpdateTools(scriptLang) {
2233
+ const i18n = getTranslation(scriptLang);
2234
+ console.log(ansis.bold.cyan(`
2235
+ \u{1F50D} ${i18n.updater.checkingTools}
2236
+ `));
2237
+ await updateCcr(scriptLang);
2238
+ console.log();
2239
+ await updateClaudeCode(scriptLang);
2240
+ }
2241
+
1956
2242
  async function isClaudeCodeInstalled() {
1957
2243
  return await commandExists("claude");
1958
2244
  }
1959
2245
  async function installClaudeCode(lang) {
1960
2246
  const i18n = getTranslation(lang);
2247
+ const installed = await isClaudeCodeInstalled();
2248
+ if (installed) {
2249
+ console.log(ansis.green(`\u2714 ${i18n.installation.alreadyInstalled}`));
2250
+ await updateClaudeCode(lang);
2251
+ return;
2252
+ }
1961
2253
  if (isTermux()) {
1962
2254
  console.log(ansis.yellow(`\u2139 ${i18n.installation.termuxDetected}`));
1963
2255
  const termuxPrefix = getTermuxPrefix();
@@ -2064,6 +2356,13 @@ async function resolveAiOutputLanguage(scriptLang, commandLineOption, savedConfi
2064
2356
  return await selectAiOutputLanguage(scriptLang, scriptLang);
2065
2357
  }
2066
2358
 
2359
+ const prompts = {
2360
+ __proto__: null,
2361
+ resolveAiOutputLanguage: resolveAiOutputLanguage,
2362
+ selectAiOutputLanguage: selectAiOutputLanguage,
2363
+ selectScriptLanguage: selectScriptLanguage
2364
+ };
2365
+
2067
2366
  async function selectMcpServices(scriptLang) {
2068
2367
  const i18n = getTranslation(scriptLang);
2069
2368
  const choices = MCP_SERVICES.map((service) => ({
@@ -2182,7 +2481,7 @@ async function installWorkflowWithDependencies(config, configLang, scriptLang) {
2182
2481
  \u{1F4E6} ${i18n.workflow.installingWorkflow}: ${workflowName}...`));
2183
2482
  const commandsDir = join(CLAUDE_DIR, "commands", "zcf");
2184
2483
  if (!existsSync(commandsDir)) {
2185
- await mkdir(commandsDir, { recursive: true });
2484
+ await mkdir$1(commandsDir, { recursive: true });
2186
2485
  }
2187
2486
  for (const commandFile of config.commands) {
2188
2487
  const commandSource = join(rootDir, "templates", configLang, "workflow", config.category, "commands", commandFile);
@@ -2204,7 +2503,7 @@ async function installWorkflowWithDependencies(config, configLang, scriptLang) {
2204
2503
  if (config.autoInstallAgents && config.agents.length > 0) {
2205
2504
  const agentsCategoryDir = join(CLAUDE_DIR, "agents", "zcf", config.category);
2206
2505
  if (!existsSync(agentsCategoryDir)) {
2207
- await mkdir(agentsCategoryDir, { recursive: true });
2506
+ await mkdir$1(agentsCategoryDir, { recursive: true });
2208
2507
  }
2209
2508
  for (const agent of config.agents) {
2210
2509
  const agentSource = join(rootDir, "templates", configLang, "workflow", config.category, "agents", agent.filename);
@@ -2270,7 +2569,7 @@ async function cleanupOldVersionFiles(scriptLang) {
2270
2569
  }
2271
2570
  }
2272
2571
 
2273
- const execAsync$1 = promisify(exec$1);
2572
+ const execAsync$1 = promisify$1(exec$2);
2274
2573
  async function isCcrInstalled() {
2275
2574
  try {
2276
2575
  await execAsync$1("ccr version");
@@ -2289,6 +2588,7 @@ async function installCcr(scriptLang) {
2289
2588
  const installed = await isCcrInstalled();
2290
2589
  if (installed) {
2291
2590
  console.log(ansis.green(`\u2714 ${i18n.ccr.ccrAlreadyInstalled}`));
2591
+ await updateCcr(scriptLang);
2292
2592
  return;
2293
2593
  }
2294
2594
  console.log(ansis.cyan(`\u{1F4E6} ${i18n.ccr.installingCcr}`));
@@ -2298,6 +2598,7 @@ async function installCcr(scriptLang) {
2298
2598
  } catch (error) {
2299
2599
  if (error.message?.includes("EEXIST")) {
2300
2600
  console.log(ansis.yellow(`\u26A0 ${i18n.ccr.ccrAlreadyInstalled}`));
2601
+ await updateCcr(scriptLang);
2301
2602
  return;
2302
2603
  }
2303
2604
  console.error(ansis.red(`\u2716 ${i18n.ccr.ccrInstallFailed}`));
@@ -2453,9 +2754,9 @@ function getFallbackPresets() {
2453
2754
  ];
2454
2755
  }
2455
2756
 
2456
- const execAsync = promisify(exec$1);
2457
- const CCR_CONFIG_DIR = join$1(homedir(), ".claude-code-router");
2458
- const CCR_CONFIG_FILE = join$1(CCR_CONFIG_DIR, "config.json");
2757
+ const execAsync = promisify$1(exec$2);
2758
+ const CCR_CONFIG_DIR = join$2(homedir(), ".claude-code-router");
2759
+ const CCR_CONFIG_FILE = join$2(CCR_CONFIG_DIR, "config.json");
2459
2760
  const CCR_BACKUP_DIR = CCR_CONFIG_DIR;
2460
2761
  function ensureCcrConfigDir() {
2461
2762
  if (!existsSync(CCR_CONFIG_DIR)) {
@@ -2470,7 +2771,7 @@ function backupCcrConfig(scriptLang) {
2470
2771
  }
2471
2772
  const timestamp = dayjs().format("YYYY-MM-DDTHH-mm-ss-SSS") + "Z";
2472
2773
  const backupFileName = `config.json.${timestamp}.bak`;
2473
- const backupPath = join$1(CCR_BACKUP_DIR, backupFileName);
2774
+ const backupPath = join$2(CCR_BACKUP_DIR, backupFileName);
2474
2775
  console.log(ansis.cyan(`${i18n.ccr.backupCcrConfig}`));
2475
2776
  copyFileSync(CCR_CONFIG_FILE, backupPath);
2476
2777
  console.log(ansis.green(`\u2714 ${i18n.ccr.ccrBackupSuccess.replace("{path}", backupPath)}`));
@@ -3078,4 +3379,4 @@ async function openSettingsJson() {
3078
3379
  }
3079
3380
  }
3080
3381
 
3081
- export { readCcrConfig as $, AI_OUTPUT_LANGUAGES as A, backupMcpConfig as B, CLAUDE_DIR as C, mergeMcpServers as D, buildMcpServerConfig as E, fixWindowsMcpConfig as F, addCompletedOnboarding as G, getTranslation as H, I18N as I, addNumbersToChoices as J, updateZcfConfig as K, LEGACY_ZCF_CONFIG_FILE as L, MCP_SERVICES as M, readZcfConfig as N, resolveAiOutputLanguage as O, configureAiPersonality as P, isWindows as Q, selectMcpServices as R, SETTINGS_FILE as S, formatApiKeyDisplay as T, modifyApiConfigPartially as U, isCcrInstalled as V, installCcr as W, setupCcrConfiguration as X, validateApiKey as Y, ZCF_CONFIG_FILE as Z, readZcfConfigAsync as _, importRecommendedEnv as a, configureCcrFeature as a0, handleExitPromptError as a1, handleGeneralError as a2, displayBanner as a3, selectScriptLanguage as a4, updatePromptOnly as a5, selectAndInstallWorkflows as a6, version as a7, displayBannerWithInfo as a8, importRecommendedPermissions as b, commandExists as c, cleanupPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, SUPPORTED_LANGS as h, init as i, LANG_LABELS as j, isClaudeCodeInstalled as k, installClaudeCode as l, mergeAndCleanPermissions as m, ensureClaudeDir as n, openSettingsJson as o, backupExistingConfig as p, copyConfigFiles as q, configureApi as r, mergeConfigs as s, mergeSettingsFile as t, updateDefaultModel as u, getExistingApiConfig as v, applyAiLanguageDirective as w, getMcpConfigPath as x, readMcpConfig as y, writeMcpConfig as z };
3382
+ export { readCcrConfig as $, AI_OUTPUT_LANGUAGES as A, writeMcpConfig as B, CLAUDE_DIR as C, backupMcpConfig as D, mergeMcpServers as E, buildMcpServerConfig as F, fixWindowsMcpConfig as G, addCompletedOnboarding as H, I18N as I, getTranslation as J, addNumbersToChoices as K, LEGACY_ZCF_CONFIG_FILE as L, MCP_SERVICES as M, updateZcfConfig as N, readZcfConfig as O, configureAiPersonality as P, isWindows as Q, selectMcpServices as R, SETTINGS_FILE as S, formatApiKeyDisplay as T, modifyApiConfigPartially as U, isCcrInstalled as V, installCcr as W, setupCcrConfiguration as X, validateApiKey as Y, ZCF_CONFIG_FILE as Z, readZcfConfigAsync as _, importRecommendedEnv as a, configureCcrFeature as a0, handleExitPromptError as a1, handleGeneralError as a2, displayBanner as a3, selectScriptLanguage as a4, resolveAiOutputLanguage as a5, updatePromptOnly as a6, selectAndInstallWorkflows as a7, version as a8, displayBannerWithInfo as a9, checkAndUpdateTools as aa, prompts as ab, importRecommendedPermissions as b, commandExists as c, cleanupPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, SUPPORTED_LANGS as h, init as i, LANG_LABELS as j, isClaudeCodeInstalled as k, installClaudeCode as l, mergeAndCleanPermissions as m, ensureClaudeDir as n, openSettingsJson as o, backupExistingConfig as p, copyConfigFiles as q, configureApi as r, mergeConfigs as s, mergeSettingsFile as t, updateDefaultModel as u, getExistingModelConfig as v, getExistingApiConfig as w, applyAiLanguageDirective as x, getMcpConfigPath as y, readMcpConfig as z };
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import cac from 'cac';
3
3
  import ansis from 'ansis';
4
- import { H as getTranslation, Z as ZCF_CONFIG_FILE, h as SUPPORTED_LANGS, J as addNumbersToChoices, j as LANG_LABELS, K as updateZcfConfig, o as openSettingsJson, b as importRecommendedPermissions, a as importRecommendedEnv, N as readZcfConfig, O as resolveAiOutputLanguage, w as applyAiLanguageDirective, P as configureAiPersonality, u as updateDefaultModel, Q as isWindows, y as readMcpConfig, F as fixWindowsMcpConfig, z as writeMcpConfig, R as selectMcpServices, B as backupMcpConfig, M as MCP_SERVICES, E as buildMcpServerConfig, D as mergeMcpServers, v as getExistingApiConfig, T as formatApiKeyDisplay, G as addCompletedOnboarding, U as modifyApiConfigPartially, V as isCcrInstalled, W as installCcr, X as setupCcrConfiguration, Y as validateApiKey, r as configureApi, _ as readZcfConfigAsync, I as I18N, $ as readCcrConfig, a0 as configureCcrFeature, a1 as handleExitPromptError, a2 as handleGeneralError, a3 as displayBanner, a4 as selectScriptLanguage, a5 as updatePromptOnly, a6 as selectAndInstallWorkflows, a7 as version, a8 as displayBannerWithInfo, i as init } from './shared/zcf.CLtDS8Pu.mjs';
4
+ import { J as getTranslation, Z as ZCF_CONFIG_FILE, h as SUPPORTED_LANGS, K as addNumbersToChoices, j as LANG_LABELS, N as updateZcfConfig, o as openSettingsJson, b as importRecommendedPermissions, a as importRecommendedEnv, O as readZcfConfig, x as applyAiLanguageDirective, P as configureAiPersonality, v as getExistingModelConfig, u as updateDefaultModel, Q as isWindows, z as readMcpConfig, G as fixWindowsMcpConfig, B as writeMcpConfig, R as selectMcpServices, D as backupMcpConfig, M as MCP_SERVICES, F as buildMcpServerConfig, E as mergeMcpServers, w as getExistingApiConfig, T as formatApiKeyDisplay, H as addCompletedOnboarding, U as modifyApiConfigPartially, V as isCcrInstalled, W as installCcr, X as setupCcrConfiguration, Y as validateApiKey, r as configureApi, _ as readZcfConfigAsync, I as I18N, $ as readCcrConfig, a0 as configureCcrFeature, a1 as handleExitPromptError, a2 as handleGeneralError, a3 as displayBanner, a4 as selectScriptLanguage, a5 as resolveAiOutputLanguage, a6 as updatePromptOnly, a7 as selectAndInstallWorkflows, a8 as version, a9 as displayBannerWithInfo, i as init, aa as checkAndUpdateTools } from './chunks/simple-config.mjs';
5
5
  import inquirer from 'inquirer';
6
6
  import { existsSync, unlinkSync } from 'node:fs';
7
7
  import { x } from 'tinyexec';
@@ -12,6 +12,12 @@ import { promisify } from 'util';
12
12
  import 'pathe';
13
13
  import 'dayjs';
14
14
  import 'node:url';
15
+ import 'ora';
16
+ import 'prompts';
17
+ import 'fs/promises';
18
+ import 'path';
19
+ import 'os';
20
+ import 'semver';
15
21
  import 'node:fs/promises';
16
22
  import 'node:child_process';
17
23
  import 'node:util';
@@ -26,9 +32,15 @@ async function configureApiFeature(scriptLang) {
26
32
  if (existingApiConfig) {
27
33
  console.log("\n" + ansis.blue(`\u2139 ${i18n.api.existingApiConfig}`));
28
34
  console.log(ansis.gray(` ${i18n.api.apiConfigUrl}: ${existingApiConfig.url || i18n.common.notConfigured}`));
29
- console.log(ansis.gray(` ${i18n.api.apiConfigKey}: ${existingApiConfig.key ? formatApiKeyDisplay(existingApiConfig.key) : i18n.common.notConfigured}`));
30
- console.log(ansis.gray(` ${i18n.api.apiConfigAuthType}: ${existingApiConfig.authType || i18n.common.notConfigured}
31
- `));
35
+ console.log(
36
+ ansis.gray(
37
+ ` ${i18n.api.apiConfigKey}: ${existingApiConfig.key ? formatApiKeyDisplay(existingApiConfig.key) : i18n.common.notConfigured}`
38
+ )
39
+ );
40
+ console.log(
41
+ ansis.gray(` ${i18n.api.apiConfigAuthType}: ${existingApiConfig.authType || i18n.common.notConfigured}
42
+ `)
43
+ );
32
44
  const { action } = await inquirer.prompt({
33
45
  type: "list",
34
46
  name: "action",
@@ -209,21 +221,44 @@ async function configureMcpFeature(scriptLang) {
209
221
  }
210
222
  }
211
223
  async function configureDefaultModelFeature(scriptLang) {
224
+ const i18n = getTranslation(scriptLang);
225
+ const existingModel = getExistingModelConfig();
226
+ if (existingModel) {
227
+ console.log("\n" + ansis.blue(`\u2139 ${i18n.configuration.existingModelConfig || "Existing model configuration"}`));
228
+ const modelDisplay = existingModel === "default" ? i18n.configuration.defaultModelOption || "Default (Let Claude Code choose)" : existingModel.charAt(0).toUpperCase() + existingModel.slice(1);
229
+ console.log(ansis.gray(` ${i18n.configuration.currentModel || "Current model"}: ${modelDisplay}
230
+ `));
231
+ const { modify } = await inquirer.prompt({
232
+ type: "confirm",
233
+ name: "modify",
234
+ message: i18n.configuration.modifyModel || "Modify model configuration?",
235
+ default: false
236
+ });
237
+ if (!modify) {
238
+ console.log(ansis.green(`\u2714 ${i18n.configuration.keepModel || "Keeping existing model configuration"}`));
239
+ return;
240
+ }
241
+ }
212
242
  const { model } = await inquirer.prompt({
213
243
  type: "list",
214
244
  name: "model",
215
- message: "Select default model",
245
+ message: i18n.configuration.selectDefaultModel || "Select default model",
216
246
  choices: addNumbersToChoices([
247
+ {
248
+ name: i18n.configuration.defaultModelOption || "Default (Let Claude Code choose)",
249
+ value: "default"
250
+ },
217
251
  { name: "Opus", value: "opus" },
218
252
  { name: "Sonnet", value: "sonnet" }
219
- ])
253
+ ]),
254
+ default: existingModel ? ["opus", "sonnet", "default"].indexOf(existingModel) : 2
220
255
  });
221
256
  if (!model) {
222
257
  handleCancellation(scriptLang);
223
258
  return;
224
259
  }
225
260
  updateDefaultModel(model);
226
- console.log(ansis.green(`\u2714 Default model configured`));
261
+ console.log(ansis.green(`\u2714 ${i18n.configuration.modelConfigured || "Default model configured"}`));
227
262
  }
228
263
  async function configureAiMemoryFeature(scriptLang) {
229
264
  const i18n = getTranslation(scriptLang);
@@ -247,7 +282,26 @@ async function configureAiMemoryFeature(scriptLang) {
247
282
  }
248
283
  if (option === "language") {
249
284
  const zcfConfig = readZcfConfig();
250
- const aiOutputLang = await resolveAiOutputLanguage(scriptLang, void 0, zcfConfig);
285
+ const existingLang = zcfConfig?.aiOutputLang;
286
+ if (existingLang) {
287
+ console.log(
288
+ "\n" + ansis.blue(`\u2139 ${i18n.configuration.existingLanguageConfig || "Existing AI output language configuration"}`)
289
+ );
290
+ console.log(ansis.gray(` ${i18n.configuration.currentLanguage || "Current language"}: ${existingLang}
291
+ `));
292
+ const { modify } = await inquirer.prompt({
293
+ type: "confirm",
294
+ name: "modify",
295
+ message: i18n.configuration.modifyLanguage || "Modify AI output language?",
296
+ default: false
297
+ });
298
+ if (!modify) {
299
+ console.log(ansis.green(`\u2714 ${i18n.configuration.keepLanguage || "Keeping existing language configuration"}`));
300
+ return;
301
+ }
302
+ }
303
+ const { selectAiOutputLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.ab; });
304
+ const aiOutputLang = await selectAiOutputLanguage(scriptLang, scriptLang);
251
305
  applyAiLanguageDirective(aiOutputLang);
252
306
  updateZcfConfig({ aiOutputLang });
253
307
  console.log(ansis.green(`\u2714 ${i18n.configuration.aiLanguageConfigured || "AI output language configured"}`));
@@ -280,10 +334,12 @@ async function changeScriptLanguageFeature(currentLang) {
280
334
  type: "list",
281
335
  name: "lang",
282
336
  message: i18n.language.selectScriptLang,
283
- choices: addNumbersToChoices(SUPPORTED_LANGS.map((l) => ({
284
- name: LANG_LABELS[l],
285
- value: l
286
- }))),
337
+ choices: addNumbersToChoices(
338
+ SUPPORTED_LANGS.map((l) => ({
339
+ name: LANG_LABELS[l],
340
+ value: l
341
+ }))
342
+ ),
287
343
  default: SUPPORTED_LANGS.indexOf(currentLang)
288
344
  });
289
345
  if (!lang) {
@@ -302,15 +358,21 @@ async function configureEnvPermissionFeature(scriptLang) {
302
358
  message: i18n.configuration?.selectEnvPermissionOption || "Select option",
303
359
  choices: addNumbersToChoices([
304
360
  {
305
- name: `${i18n.configuration?.importRecommendedEnv || "Import environment"} ${ansis.gray("- " + (i18n.configuration?.importRecommendedEnvDesc || "Import env settings"))}`,
361
+ name: `${i18n.configuration?.importRecommendedEnv || "Import environment"} ${ansis.gray(
362
+ "- " + (i18n.configuration?.importRecommendedEnvDesc || "Import env settings")
363
+ )}`,
306
364
  value: "env"
307
365
  },
308
366
  {
309
- name: `${i18n.configuration?.importRecommendedPermissions || "Import permissions"} ${ansis.gray("- " + (i18n.configuration?.importRecommendedPermissionsDesc || "Import permission settings"))}`,
367
+ name: `${i18n.configuration?.importRecommendedPermissions || "Import permissions"} ${ansis.gray(
368
+ "- " + (i18n.configuration?.importRecommendedPermissionsDesc || "Import permission settings")
369
+ )}`,
310
370
  value: "permissions"
311
371
  },
312
372
  {
313
- name: `${i18n.configuration?.openSettingsJson || "Open settings"} ${ansis.gray("- " + (i18n.configuration?.openSettingsJsonDesc || "View settings file"))}`,
373
+ name: `${i18n.configuration?.openSettingsJson || "Open settings"} ${ansis.gray(
374
+ "- " + (i18n.configuration?.openSettingsJsonDesc || "View settings file")
375
+ )}`,
314
376
  value: "open"
315
377
  }
316
378
  ])
@@ -859,6 +921,16 @@ async function ccr(options = {}) {
859
921
  }
860
922
  }
861
923
 
924
+ async function checkUpdates(options = {}) {
925
+ const scriptLang = options.lang || await selectScriptLanguage();
926
+ try {
927
+ await checkAndUpdateTools(scriptLang);
928
+ } catch (error) {
929
+ console.error(ansis.red("Error checking updates:"), error);
930
+ process.exit(1);
931
+ }
932
+ }
933
+
862
934
  function setupCommands(cli) {
863
935
  cli.command("[lang]", "Show interactive menu (default)").option("--init", "Run full initialization directly").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").option("--force, -f", "Force overwrite existing configuration").action(async (lang, options) => {
864
936
  await handleDefaultCommand(lang, options);
@@ -875,6 +947,9 @@ function setupCommands(cli) {
875
947
  cli.command("ccu [...args]", "Run Claude Code usage analysis tool").allowUnknownOptions().action(async (args) => {
876
948
  await executeCcusage(args);
877
949
  });
950
+ cli.command("check-updates", "Check and update Claude Code and CCR to latest versions").alias("check").option("--lang, -l <lang>", "Display language (zh-CN, en)").action(async (options) => {
951
+ await checkUpdates({ lang: options.lang });
952
+ });
878
953
  cli.help((sections) => customizeHelp(sections));
879
954
  cli.version(version);
880
955
  }
package/dist/index.d.mts CHANGED
@@ -13,6 +13,7 @@ interface TranslationStructure {
13
13
  errors: any;
14
14
  tools: any;
15
15
  ccr: any;
16
+ updater: any;
16
17
  }
17
18
 
18
19
  interface McpService {
@@ -105,12 +106,16 @@ declare function backupExistingConfig(): string | null;
105
106
  declare function copyConfigFiles(lang: SupportedLang, onlyMd?: boolean): void;
106
107
  declare function configureApi(apiConfig: ApiConfig | null): ApiConfig | null;
107
108
  declare function mergeConfigs(sourceFile: string, targetFile: string): void;
108
- declare function updateDefaultModel(model: 'opus' | 'sonnet'): void;
109
+ declare function updateDefaultModel(model: 'opus' | 'sonnet' | 'default'): void;
109
110
  /**
110
111
  * Merge settings.json intelligently
111
112
  * Preserves user's environment variables and custom configurations
112
113
  */
113
114
  declare function mergeSettingsFile(templatePath: string, targetPath: string): void;
115
+ /**
116
+ * Get existing model configuration from settings.json
117
+ */
118
+ declare function getExistingModelConfig(): 'opus' | 'sonnet' | 'default' | null;
114
119
  /**
115
120
  * Get existing API configuration from settings.json
116
121
  */
@@ -150,5 +155,5 @@ declare function cleanupPermissions(templatePermissions: string[], userPermissio
150
155
  */
151
156
  declare function mergeAndCleanPermissions(templatePermissions: string[] | undefined, userPermissions: string[] | undefined): string[];
152
157
 
153
- export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, I18N, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
158
+ export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, I18N, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getExistingModelConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
154
159
  export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, McpServerConfig, McpService, SupportedLang };
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ interface TranslationStructure {
13
13
  errors: any;
14
14
  tools: any;
15
15
  ccr: any;
16
+ updater: any;
16
17
  }
17
18
 
18
19
  interface McpService {
@@ -105,12 +106,16 @@ declare function backupExistingConfig(): string | null;
105
106
  declare function copyConfigFiles(lang: SupportedLang, onlyMd?: boolean): void;
106
107
  declare function configureApi(apiConfig: ApiConfig | null): ApiConfig | null;
107
108
  declare function mergeConfigs(sourceFile: string, targetFile: string): void;
108
- declare function updateDefaultModel(model: 'opus' | 'sonnet'): void;
109
+ declare function updateDefaultModel(model: 'opus' | 'sonnet' | 'default'): void;
109
110
  /**
110
111
  * Merge settings.json intelligently
111
112
  * Preserves user's environment variables and custom configurations
112
113
  */
113
114
  declare function mergeSettingsFile(templatePath: string, targetPath: string): void;
115
+ /**
116
+ * Get existing model configuration from settings.json
117
+ */
118
+ declare function getExistingModelConfig(): 'opus' | 'sonnet' | 'default' | null;
114
119
  /**
115
120
  * Get existing API configuration from settings.json
116
121
  */
@@ -150,5 +155,5 @@ declare function cleanupPermissions(templatePermissions: string[], userPermissio
150
155
  */
151
156
  declare function mergeAndCleanPermissions(templatePermissions: string[] | undefined, userPermissions: string[] | undefined): string[];
152
157
 
153
- export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, I18N, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
158
+ export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, I18N, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getExistingModelConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
154
159
  export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, McpServerConfig, McpService, SupportedLang };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, I as I18N, j as LANG_LABELS, L as LEGACY_ZCF_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, h as SUPPORTED_LANGS, Z as ZCF_CONFIG_FILE, G as addCompletedOnboarding, w as applyAiLanguageDirective, p as backupExistingConfig, B as backupMcpConfig, E as buildMcpServerConfig, d as cleanupPermissions, c as commandExists, r as configureApi, q as copyConfigFiles, n as ensureClaudeDir, F as fixWindowsMcpConfig, v as getExistingApiConfig, x as getMcpConfigPath, g as getPlatform, a as importRecommendedEnv, b as importRecommendedPermissions, i as init, l as installClaudeCode, k as isClaudeCodeInstalled, m as mergeAndCleanPermissions, s as mergeConfigs, D as mergeMcpServers, t as mergeSettingsFile, o as openSettingsJson, y as readMcpConfig, u as updateDefaultModel, z as writeMcpConfig } from './shared/zcf.CLtDS8Pu.mjs';
1
+ export { A as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, I as I18N, j as LANG_LABELS, L as LEGACY_ZCF_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, h as SUPPORTED_LANGS, Z as ZCF_CONFIG_FILE, H as addCompletedOnboarding, x as applyAiLanguageDirective, p as backupExistingConfig, D as backupMcpConfig, F as buildMcpServerConfig, d as cleanupPermissions, c as commandExists, r as configureApi, q as copyConfigFiles, n as ensureClaudeDir, G as fixWindowsMcpConfig, w as getExistingApiConfig, v as getExistingModelConfig, y as getMcpConfigPath, g as getPlatform, a as importRecommendedEnv, b as importRecommendedPermissions, i as init, l as installClaudeCode, k as isClaudeCodeInstalled, m as mergeAndCleanPermissions, s as mergeConfigs, E as mergeMcpServers, t as mergeSettingsFile, o as openSettingsJson, z as readMcpConfig, u as updateDefaultModel, B as writeMcpConfig } from './chunks/simple-config.mjs';
2
2
  import 'inquirer';
3
3
  import 'ansis';
4
4
  import 'node:fs';
@@ -6,6 +6,14 @@ import 'pathe';
6
6
  import 'dayjs';
7
7
  import 'node:url';
8
8
  import 'tinyexec';
9
+ import 'child_process';
10
+ import 'util';
11
+ import 'ora';
12
+ import 'prompts';
13
+ import 'fs/promises';
14
+ import 'path';
15
+ import 'os';
16
+ import 'semver';
9
17
  import 'node:fs/promises';
10
18
  import 'node:child_process';
11
19
  import 'node:util';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zcf",
3
3
  "type": "module",
4
- "version": "2.8.0",
4
+ "version": "2.8.1",
5
5
  "description": "Zero-Config Claude-Code Flow - One-click configuration tool for Claude Code",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/UfoMiao/zcf",
@@ -21,12 +21,17 @@
21
21
  "templates"
22
22
  ],
23
23
  "dependencies": {
24
+ "@types/prompts": "^2.4.9",
25
+ "@types/semver": "^7.7.0",
24
26
  "ansis": "^3.17.0",
25
27
  "cac": "^6.7.14",
26
28
  "dayjs": "^1.11.13",
27
29
  "find-up-simple": "^1.0.1",
28
30
  "inquirer": "^12.9.0",
31
+ "ora": "^8.2.0",
29
32
  "pathe": "^2.0.3",
33
+ "prompts": "^2.4.2",
34
+ "semver": "^7.7.2",
30
35
  "tinyexec": "^1.0.1"
31
36
  },
32
37
  "devDependencies": {