zcf 2.12.6 → 2.12.8

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 UfoMiao & WitMiao
3
+ Copyright (c) 2025-PRESENT UfoMiao <https://github.com/UfoMiao> & Miao Da <https://github.com/WitMiao>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -24,13 +24,29 @@ 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 settings, AI output style, environment permissions, etc.)
27
+ - `3` Configure API or CCR - API configuration or CCR proxy setup
28
+ - `4` Configure MCP - MCP service configuration and management
29
+ - `5` Configure default model - Set default model (opus/sonnet/opusplan/custom)
30
+ - `6` Configure AI memory - Configure AI output language and global output style
31
+ - `7` Configure environment permissions - Import environment variables and permissions
28
32
  - `R` Claude Code Router management (enhanced in v2.8.1)
29
33
  - `U` ccusage - Claude Code usage analysis
30
34
  - `L` CCometixLine - High-performance statusline tool with Git integration and real-time usage tracking (v2.9.9+ new)
31
35
  - `+` Check updates - Check and update Claude Code, CCR and CCometixLine versions (v2.9.9+ enhanced)
32
36
  - More features...
33
37
 
38
+ #### 🎯 Key Configuration Features
39
+
40
+ **Model Configuration (Option 5)**: Configure your default Claude model with flexible options:
41
+ - **Default**: Let Claude Code automatically choose the best model for each task
42
+ - **Opus**: Use Claude-3.5-Opus exclusively (high token consumption, use with caution)
43
+ - **OpusPlan**: Use Opus for planning, Sonnet for implementation (recommended balance)
44
+ - **Custom**: Specify your own model names for both primary and fast tasks (supports any custom model)
45
+
46
+ **AI Memory Configuration (Option 6)**: Personalize your AI assistant:
47
+ - **AI Output Language**: Set the language for AI responses (Chinese, English, or custom)
48
+ - **Global Output Style**: Configure AI personality and response style
49
+
34
50
  ### Or, use direct commands:
35
51
 
36
52
  #### 🆕 First time using Claude Code
@@ -311,7 +327,7 @@ Select function:
311
327
  2. Import workflow - Import/update workflow-related files only
312
328
  3. Configure API - Configure API URL and authentication (supports CCR proxy)
313
329
  4. Configure MCP - Configure MCP services (includes Windows fix)
314
- 5. Configure default model - Set default model (opus/sonnet)
330
+ 5. Configure default model - Set default model (opus/sonnet/opusplan/custom)
315
331
  6. Configure Claude global memory - Configure AI output language and output styles
316
332
  7. Import recommended environment variables and permissions - Import privacy protection environment variables and system permissions
317
333
 
@@ -2,20 +2,20 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, readd
2
2
  import process from 'node:process';
3
3
  import ansis from 'ansis';
4
4
  import inquirer from 'inquirer';
5
- import { fileURLToPath } from 'node:url';
6
- import i18next from 'i18next';
7
- import Backend from 'i18next-fs-backend';
8
- import { dirname, join } from 'pathe';
9
5
  import { exec as exec$1 } from 'node:child_process';
10
6
  import { homedir, platform } from 'node:os';
11
7
  import { promisify } from 'node:util';
12
8
  import dayjs from 'dayjs';
9
+ import { dirname, join } from 'pathe';
10
+ import { fileURLToPath } from 'node:url';
13
11
  import ora from 'ora';
14
12
  import semver from 'semver';
15
13
  import { exec } from 'tinyexec';
16
14
  import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
15
+ import i18next from 'i18next';
16
+ import Backend from 'i18next-fs-backend';
17
17
 
18
- const version = "2.12.6";
18
+ const version = "2.12.8";
19
19
  const homepage = "https://github.com/UfoMiao/zcf";
20
20
 
21
21
  const i18n = i18next.createInstance();
@@ -345,22 +345,10 @@ const AI_OUTPUT_LANGUAGES = {
345
345
  "en": { directive: "Always respond in English" },
346
346
  "custom": { directive: "" }
347
347
  };
348
- let _i18n = null;
349
- function getI18nInstance() {
350
- if (!_i18n) {
351
- try {
352
- const i18nModule = eval('require("./i18n")');
353
- _i18n = i18nModule.i18n;
354
- } catch {
355
- }
356
- }
357
- return _i18n;
358
- }
359
348
  function getAiOutputLanguageLabel(lang) {
360
349
  if (lang in LANG_LABELS) {
361
350
  return LANG_LABELS[lang];
362
351
  }
363
- const i18n = getI18nInstance();
364
352
  if (lang === "custom" && i18n?.isInitialized) {
365
353
  try {
366
354
  return i18n.t("language:labels.custom");
@@ -883,14 +871,42 @@ function mergeConfigs(sourceFile, targetFile) {
883
871
  const merged = deepMerge(target, source);
884
872
  writeJsonConfig(targetFile, merged);
885
873
  }
874
+ function updateCustomModel(primaryModel, fastModel) {
875
+ if (!primaryModel?.trim() && !fastModel?.trim()) {
876
+ return;
877
+ }
878
+ let settings = getDefaultSettings();
879
+ const existingSettings = readJsonConfig(SETTINGS_FILE);
880
+ if (existingSettings) {
881
+ settings = existingSettings;
882
+ }
883
+ delete settings.model;
884
+ settings.env = settings.env || {};
885
+ if (primaryModel?.trim()) {
886
+ settings.env.ANTHROPIC_MODEL = primaryModel.trim();
887
+ }
888
+ if (fastModel?.trim()) {
889
+ settings.env.ANTHROPIC_SMALL_FAST_MODEL = fastModel.trim();
890
+ }
891
+ writeJsonConfig(SETTINGS_FILE, settings);
892
+ }
886
893
  function updateDefaultModel(model) {
887
894
  let settings = getDefaultSettings();
888
895
  const existingSettings = readJsonConfig(SETTINGS_FILE);
889
896
  if (existingSettings) {
890
897
  settings = existingSettings;
891
898
  }
899
+ if (!settings.env) {
900
+ settings.env = {};
901
+ }
902
+ if (model !== "custom" && settings.env) {
903
+ delete settings.env.ANTHROPIC_MODEL;
904
+ delete settings.env.ANTHROPIC_SMALL_FAST_MODEL;
905
+ }
892
906
  if (model === "default") {
893
907
  delete settings.model;
908
+ } else if (model === "custom") {
909
+ delete settings.model;
894
910
  } else {
895
911
  settings.model = model;
896
912
  }
@@ -940,6 +956,9 @@ function getExistingModelConfig() {
940
956
  if (!settings) {
941
957
  return null;
942
958
  }
959
+ if (settings.env && (settings.env.ANTHROPIC_MODEL || settings.env.ANTHROPIC_SMALL_FAST_MODEL)) {
960
+ return "custom";
961
+ }
943
962
  if (!settings.model) {
944
963
  return "default";
945
964
  }
@@ -1484,8 +1503,7 @@ async function checkClaudeCodeVersionAndPrompt(skipPrompt = false) {
1484
1503
  return;
1485
1504
  }
1486
1505
  const { updateClaudeCode } = await Promise.resolve().then(function () { return autoUpdater; });
1487
- const forceUpdate = skipPrompt;
1488
- await updateClaudeCode(forceUpdate);
1506
+ await updateClaudeCode(false, skipPrompt);
1489
1507
  } catch (error) {
1490
1508
  const errorMessage = error instanceof Error ? error.message : String(error);
1491
1509
  console.warn(`Claude Code version check failed: ${errorMessage}`);
@@ -1493,7 +1511,7 @@ async function checkClaudeCodeVersionAndPrompt(skipPrompt = false) {
1493
1511
  }
1494
1512
 
1495
1513
  const execAsync$2 = promisify(exec$1);
1496
- async function updateCcr(force = false) {
1514
+ async function updateCcr(force = false, skipPrompt = false) {
1497
1515
  ensureI18nInitialized();
1498
1516
  const spinner = ora(i18n.t("updater:checkingVersion")).start();
1499
1517
  try {
@@ -1513,15 +1531,19 @@ async function updateCcr(force = false) {
1513
1531
  }
1514
1532
  console.log(ansis.cyan(format(i18n.t("updater:currentVersion"), { version: currentVersion || "" })));
1515
1533
  console.log(ansis.cyan(format(i18n.t("updater:latestVersion"), { version: latestVersion })));
1516
- const { confirm } = await inquirer.prompt({
1517
- type: "confirm",
1518
- name: "confirm",
1519
- message: format(i18n.t("updater:confirmUpdate"), { tool: "CCR" }),
1520
- default: true
1521
- });
1522
- if (!confirm) {
1523
- console.log(ansis.gray(i18n.t("updater:updateSkipped")));
1524
- return true;
1534
+ if (!skipPrompt) {
1535
+ const { confirm } = await inquirer.prompt({
1536
+ type: "confirm",
1537
+ name: "confirm",
1538
+ message: format(i18n.t("updater:confirmUpdate"), { tool: "CCR" }),
1539
+ default: true
1540
+ });
1541
+ if (!confirm) {
1542
+ console.log(ansis.gray(i18n.t("updater:updateSkipped")));
1543
+ return true;
1544
+ }
1545
+ } else {
1546
+ console.log(ansis.cyan(format(i18n.t("updater:autoUpdating"), { tool: "CCR" })));
1525
1547
  }
1526
1548
  const updateSpinner = ora(format(i18n.t("updater:updating"), { tool: "CCR" })).start();
1527
1549
  try {
@@ -1539,7 +1561,7 @@ async function updateCcr(force = false) {
1539
1561
  return false;
1540
1562
  }
1541
1563
  }
1542
- async function updateClaudeCode(force = false) {
1564
+ async function updateClaudeCode(force = false, skipPrompt = false) {
1543
1565
  ensureI18nInitialized();
1544
1566
  const spinner = ora(i18n.t("updater:checkingVersion")).start();
1545
1567
  try {
@@ -1559,15 +1581,19 @@ async function updateClaudeCode(force = false) {
1559
1581
  }
1560
1582
  console.log(ansis.cyan(format(i18n.t("updater:currentVersion"), { version: currentVersion || "" })));
1561
1583
  console.log(ansis.cyan(format(i18n.t("updater:latestVersion"), { version: latestVersion })));
1562
- const { confirm } = await inquirer.prompt({
1563
- type: "confirm",
1564
- name: "confirm",
1565
- message: format(i18n.t("updater:confirmUpdate"), { tool: "Claude Code" }),
1566
- default: true
1567
- });
1568
- if (!confirm) {
1569
- console.log(ansis.gray(i18n.t("updater:updateSkipped")));
1570
- return true;
1584
+ if (!skipPrompt) {
1585
+ const { confirm } = await inquirer.prompt({
1586
+ type: "confirm",
1587
+ name: "confirm",
1588
+ message: format(i18n.t("updater:confirmUpdate"), { tool: "Claude Code" }),
1589
+ default: true
1590
+ });
1591
+ if (!confirm) {
1592
+ console.log(ansis.gray(i18n.t("updater:updateSkipped")));
1593
+ return true;
1594
+ }
1595
+ } else {
1596
+ console.log(ansis.cyan(format(i18n.t("updater:autoUpdating"), { tool: "Claude Code" })));
1571
1597
  }
1572
1598
  const updateSpinner = ora(format(i18n.t("updater:updating"), { tool: "Claude Code" })).start();
1573
1599
  try {
@@ -1585,7 +1611,7 @@ async function updateClaudeCode(force = false) {
1585
1611
  return false;
1586
1612
  }
1587
1613
  }
1588
- async function updateCometixLine(force = false) {
1614
+ async function updateCometixLine(force = false, skipPrompt = false) {
1589
1615
  ensureI18nInitialized();
1590
1616
  const spinner = ora(i18n.t("updater:checkingVersion")).start();
1591
1617
  try {
@@ -1605,15 +1631,19 @@ async function updateCometixLine(force = false) {
1605
1631
  }
1606
1632
  console.log(ansis.cyan(format(i18n.t("updater:currentVersion"), { version: currentVersion || "" })));
1607
1633
  console.log(ansis.cyan(format(i18n.t("updater:latestVersion"), { version: latestVersion })));
1608
- const { confirm } = await inquirer.prompt({
1609
- type: "confirm",
1610
- name: "confirm",
1611
- message: format(i18n.t("updater:confirmUpdate"), { tool: "CCometixLine" }),
1612
- default: true
1613
- });
1614
- if (!confirm) {
1615
- console.log(ansis.gray(i18n.t("updater:updateSkipped")));
1616
- return true;
1634
+ if (!skipPrompt) {
1635
+ const { confirm } = await inquirer.prompt({
1636
+ type: "confirm",
1637
+ name: "confirm",
1638
+ message: format(i18n.t("updater:confirmUpdate"), { tool: "CCometixLine" }),
1639
+ default: true
1640
+ });
1641
+ if (!confirm) {
1642
+ console.log(ansis.gray(i18n.t("updater:updateSkipped")));
1643
+ return true;
1644
+ }
1645
+ } else {
1646
+ console.log(ansis.cyan(format(i18n.t("updater:autoUpdating"), { tool: "CCometixLine" })));
1617
1647
  }
1618
1648
  const updateSpinner = ora(format(i18n.t("updater:updating"), { tool: "CCometixLine" })).start();
1619
1649
  try {
@@ -1631,16 +1661,49 @@ async function updateCometixLine(force = false) {
1631
1661
  return false;
1632
1662
  }
1633
1663
  }
1634
- async function checkAndUpdateTools() {
1664
+ async function checkAndUpdateTools(skipPrompt = false) {
1635
1665
  ensureI18nInitialized();
1636
1666
  console.log(ansis.bold.cyan(`
1637
1667
  \u{1F50D} ${i18n.t("updater:checkingTools")}
1638
1668
  `));
1639
- await updateCcr();
1669
+ const results = [];
1670
+ try {
1671
+ const success = await updateCcr(false, skipPrompt);
1672
+ results.push({ tool: "CCR", success });
1673
+ } catch (error) {
1674
+ const errorMessage = error instanceof Error ? error.message : String(error);
1675
+ console.error(ansis.red(`\u274C ${format(i18n.t("updater:updateFailed"), { tool: "CCR" })}: ${errorMessage}`));
1676
+ results.push({ tool: "CCR", success: false, error: errorMessage });
1677
+ }
1640
1678
  console.log();
1641
- await updateClaudeCode();
1679
+ try {
1680
+ const success = await updateClaudeCode(false, skipPrompt);
1681
+ results.push({ tool: "Claude Code", success });
1682
+ } catch (error) {
1683
+ const errorMessage = error instanceof Error ? error.message : String(error);
1684
+ console.error(ansis.red(`\u274C ${format(i18n.t("updater:updateFailed"), { tool: "Claude Code" })}: ${errorMessage}`));
1685
+ results.push({ tool: "Claude Code", success: false, error: errorMessage });
1686
+ }
1642
1687
  console.log();
1643
- await updateCometixLine();
1688
+ try {
1689
+ const success = await updateCometixLine(false, skipPrompt);
1690
+ results.push({ tool: "CCometixLine", success });
1691
+ } catch (error) {
1692
+ const errorMessage = error instanceof Error ? error.message : String(error);
1693
+ console.error(ansis.red(`\u274C ${format(i18n.t("updater:updateFailed"), { tool: "CCometixLine" })}: ${errorMessage}`));
1694
+ results.push({ tool: "CCometixLine", success: false, error: errorMessage });
1695
+ }
1696
+ if (skipPrompt) {
1697
+ console.log(ansis.bold.cyan(`
1698
+ \u{1F4CB} ${i18n.t("updater:updateSummary")}`));
1699
+ for (const result of results) {
1700
+ if (result.success) {
1701
+ console.log(ansis.green(`\u2714 ${result.tool}: ${i18n.t("updater:success")}`));
1702
+ } else {
1703
+ console.log(ansis.red(`\u274C ${result.tool}: ${i18n.t("updater:failed")} ${result.error ? `(${result.error})` : ""}`));
1704
+ }
1705
+ }
1706
+ }
1644
1707
  }
1645
1708
 
1646
1709
  const autoUpdater = {
@@ -3156,4 +3219,4 @@ async function openSettingsJson() {
3156
3219
  }
3157
3220
  }
3158
3221
 
3159
- export { getMcpServices as $, AI_OUTPUT_LANGUAGES as A, readMcpConfig as B, CLAUDE_DIR as C, writeMcpConfig as D, backupMcpConfig as E, mergeMcpServers as F, buildMcpServerConfig as G, fixWindowsMcpConfig as H, addCompletedOnboarding as I, ensureI18nInitialized as J, i18n as K, LEGACY_ZCF_CONFIG_FILE as L, readCcrConfig as M, isCcrInstalled as N, installCcr as O, configureCcrFeature as P, handleExitPromptError as Q, handleGeneralError as R, SETTINGS_FILE as S, addNumbersToChoices as T, updateZcfConfig as U, changeLanguage as V, readZcfConfig as W, configureOutputStyle as X, isWindows as Y, ZCF_CONFIG_FILE as Z, selectMcpServices as _, commandExists as a, formatApiKeyDisplay as a0, modifyApiConfigPartially as a1, setupCcrConfiguration as a2, validateApiKey as a3, COMETIX_COMMAND_NAME as a4, COMETIX_COMMANDS as a5, installCometixLine as a6, checkAndUpdateTools as a7, displayBanner as a8, resolveAiOutputLanguage as a9, updatePromptOnly as aa, selectAndInstallWorkflows as ab, checkClaudeCodeVersionAndPrompt as ac, version as ad, displayBannerWithInfo as ae, readZcfConfigAsync as af, initI18n as ag, selectScriptLanguage as ah, prompts as ai, importRecommendedEnv as b, cleanupPermissions as c, importRecommendedPermissions 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, getAiOutputLanguageLabel as k, ensureClaudeDir as l, mergeAndCleanPermissions as m, backupExistingConfig as n, openSettingsJson as o, copyConfigFiles as p, configureApi as q, mergeConfigs as r, mergeSettingsFile as s, getExistingModelConfig as t, updateDefaultModel as u, getExistingApiConfig as v, applyAiLanguageDirective as w, isClaudeCodeInstalled as x, installClaudeCode as y, getMcpConfigPath as z };
3222
+ export { selectMcpServices as $, AI_OUTPUT_LANGUAGES as A, getMcpConfigPath as B, CLAUDE_DIR as C, readMcpConfig as D, writeMcpConfig as E, backupMcpConfig as F, mergeMcpServers as G, buildMcpServerConfig as H, fixWindowsMcpConfig as I, addCompletedOnboarding as J, ensureI18nInitialized as K, LEGACY_ZCF_CONFIG_FILE as L, i18n as M, readCcrConfig as N, isCcrInstalled as O, installCcr as P, configureCcrFeature as Q, handleExitPromptError as R, SETTINGS_FILE as S, handleGeneralError as T, addNumbersToChoices as U, updateZcfConfig as V, changeLanguage as W, readZcfConfig as X, configureOutputStyle as Y, ZCF_CONFIG_FILE as Z, isWindows as _, commandExists as a, getMcpServices as a0, formatApiKeyDisplay as a1, modifyApiConfigPartially as a2, setupCcrConfiguration as a3, validateApiKey as a4, COMETIX_COMMAND_NAME as a5, COMETIX_COMMANDS as a6, installCometixLine as a7, checkAndUpdateTools as a8, displayBanner as a9, resolveAiOutputLanguage as aa, updatePromptOnly as ab, selectAndInstallWorkflows as ac, checkClaudeCodeVersionAndPrompt as ad, version as ae, displayBannerWithInfo as af, readZcfConfigAsync as ag, initI18n as ah, selectScriptLanguage as ai, prompts as aj, importRecommendedEnv as b, cleanupPermissions as c, importRecommendedPermissions 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, getAiOutputLanguageLabel as k, ensureClaudeDir as l, mergeAndCleanPermissions as m, backupExistingConfig as n, openSettingsJson as o, copyConfigFiles as p, configureApi as q, mergeConfigs as r, updateDefaultModel as s, mergeSettingsFile as t, updateCustomModel as u, getExistingModelConfig as v, getExistingApiConfig as w, applyAiLanguageDirective as x, isClaudeCodeInstalled as y, installClaudeCode 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 { J as ensureI18nInitialized, K as i18n, M as readCcrConfig, N as isCcrInstalled, O as installCcr, P as configureCcrFeature, Q as handleExitPromptError, R as handleGeneralError, Z as ZCF_CONFIG_FILE, h as SUPPORTED_LANGS, T as addNumbersToChoices, j as LANG_LABELS, U as updateZcfConfig, V as changeLanguage, o as openSettingsJson, d as importRecommendedPermissions, b as importRecommendedEnv, W as readZcfConfig, w as applyAiLanguageDirective, X as configureOutputStyle, t as getExistingModelConfig, u as updateDefaultModel, Y as isWindows, B as readMcpConfig, H as fixWindowsMcpConfig, D as writeMcpConfig, _ as selectMcpServices, E as backupMcpConfig, $ as getMcpServices, G as buildMcpServerConfig, F as mergeMcpServers, v as getExistingApiConfig, a0 as formatApiKeyDisplay, I as addCompletedOnboarding, a1 as modifyApiConfigPartially, a2 as setupCcrConfiguration, a3 as validateApiKey, q as configureApi, a4 as COMETIX_COMMAND_NAME, a5 as COMETIX_COMMANDS, a6 as installCometixLine, a7 as checkAndUpdateTools, a8 as displayBanner, a9 as resolveAiOutputLanguage, aa as updatePromptOnly, ab as selectAndInstallWorkflows, ac as checkClaudeCodeVersionAndPrompt, ad as version, ae as displayBannerWithInfo, i as init, af as readZcfConfigAsync, ag as initI18n, ah as selectScriptLanguage } from './chunks/simple-config.mjs';
4
+ import { K as ensureI18nInitialized, M as i18n, N as readCcrConfig, O as isCcrInstalled, P as installCcr, Q as configureCcrFeature, R as handleExitPromptError, T as handleGeneralError, Z as ZCF_CONFIG_FILE, h as SUPPORTED_LANGS, U as addNumbersToChoices, j as LANG_LABELS, V as updateZcfConfig, W as changeLanguage, o as openSettingsJson, d as importRecommendedPermissions, b as importRecommendedEnv, X as readZcfConfig, x as applyAiLanguageDirective, Y as configureOutputStyle, v as getExistingModelConfig, u as updateCustomModel, s as updateDefaultModel, _ as isWindows, D as readMcpConfig, I as fixWindowsMcpConfig, E as writeMcpConfig, $ as selectMcpServices, F as backupMcpConfig, a0 as getMcpServices, H as buildMcpServerConfig, G as mergeMcpServers, w as getExistingApiConfig, a1 as formatApiKeyDisplay, J as addCompletedOnboarding, a2 as modifyApiConfigPartially, a3 as setupCcrConfiguration, a4 as validateApiKey, q as configureApi, a5 as COMETIX_COMMAND_NAME, a6 as COMETIX_COMMANDS, a7 as installCometixLine, a8 as checkAndUpdateTools, a9 as displayBanner, aa as resolveAiOutputLanguage, ab as updatePromptOnly, ac as selectAndInstallWorkflows, ad as checkClaudeCodeVersionAndPrompt, ae as version, af as displayBannerWithInfo, i as init, ag as readZcfConfigAsync, ah as initI18n, ai as selectScriptLanguage } from './chunks/simple-config.mjs';
5
5
  import { existsSync, unlinkSync } from 'node:fs';
6
6
  import { homedir } from 'node:os';
7
7
  import inquirer from 'inquirer';
@@ -10,13 +10,13 @@ import { exec, spawn } from 'node:child_process';
10
10
  import { promisify } from 'node:util';
11
11
  import process from 'node:process';
12
12
  import { x } from 'tinyexec';
13
- import 'node:url';
14
- import 'i18next';
15
- import 'i18next-fs-backend';
16
13
  import 'dayjs';
14
+ import 'node:url';
17
15
  import 'ora';
18
16
  import 'semver';
19
17
  import 'node:fs/promises';
18
+ import 'i18next';
19
+ import 'i18next-fs-backend';
20
20
 
21
21
  const execAsync$1 = promisify(exec);
22
22
  async function runCcrUi(apiKey) {
@@ -340,10 +340,11 @@ ${ansis.blue(`\u2139 ${i18n.t("api:existingApiConfig")}`)}`);
340
340
  const { url } = await inquirer.prompt({
341
341
  type: "input",
342
342
  name: "url",
343
- message: i18n.t("api:enterApiUrl"),
344
- validate: async (value) => {
345
- if (!value)
346
- return i18n.t("api:urlRequired");
343
+ message: `${i18n.t("api:enterApiUrl")}${i18n.t("common:emptyToSkip")}`,
344
+ validate: (value) => {
345
+ if (!value) {
346
+ return true;
347
+ }
347
348
  try {
348
349
  void new URL(value);
349
350
  return true;
@@ -352,27 +353,27 @@ ${ansis.blue(`\u2139 ${i18n.t("api:existingApiConfig")}`)}`);
352
353
  }
353
354
  }
354
355
  });
355
- if (!url) {
356
+ if (url === void 0 || !url) {
356
357
  await handleCancellation();
357
358
  return;
358
359
  }
359
- const keyMessage = apiChoice === "auth_token" ? i18n.t("api:enterAuthToken") : i18n.t("api:enterApiKey");
360
+ const keyMessage = apiChoice === "auth_token" ? `${i18n.t("api:enterAuthToken")}${i18n.t("common:emptyToSkip")}` : `${i18n.t("api:enterApiKey")}${i18n.t("common:emptyToSkip")}`;
360
361
  const { key } = await inquirer.prompt({
361
362
  type: "input",
362
363
  name: "key",
363
364
  message: keyMessage,
364
- validate: async (value) => {
365
+ validate: (value) => {
365
366
  if (!value) {
366
- return i18n.t("api:keyRequired");
367
+ return true;
367
368
  }
368
- const validation = await validateApiKey(value);
369
+ const validation = validateApiKey(value);
369
370
  if (!validation.isValid) {
370
371
  return validation.error || i18n.t("api:invalidKeyFormat");
371
372
  }
372
373
  return true;
373
374
  }
374
375
  });
375
- if (!key) {
376
+ if (key === void 0 || !key) {
376
377
  await handleCancellation();
377
378
  return;
378
379
  }
@@ -473,17 +474,46 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingModelConfig") || "Existing
473
474
  {
474
475
  name: i18n.t("configuration:opusPlanModelOption") || "OpusPlan - Use Opus for planning, write code with sonnet, recommended",
475
476
  value: "opusplan"
477
+ },
478
+ {
479
+ name: i18n.t("configuration:customModelOption") || "Custom - Specify custom model names",
480
+ value: "custom"
476
481
  }
477
482
  ]),
478
- default: existingModel ? ["default", "opus", "opusplan"].indexOf(existingModel) : 0
483
+ default: existingModel ? ["default", "opus", "opusplan", "custom"].indexOf(existingModel) : 0
479
484
  });
480
485
  if (!model) {
481
486
  await handleCancellation();
482
487
  return;
483
488
  }
489
+ if (model === "custom") {
490
+ const { primaryModel, fastModel } = await promptCustomModels();
491
+ if (!primaryModel.trim() && !fastModel.trim()) {
492
+ console.log(ansis.yellow(`\u26A0 ${i18n.t("configuration:customModelSkipped") || "Custom model configuration skipped"}`));
493
+ return;
494
+ }
495
+ updateCustomModel(primaryModel, fastModel);
496
+ console.log(ansis.green(`\u2714 ${i18n.t("configuration:customModelConfigured") || "Custom model configuration completed"}`));
497
+ return;
498
+ }
484
499
  updateDefaultModel(model);
485
500
  console.log(ansis.green(`\u2714 ${i18n.t("configuration:modelConfigured") || "Default model configured"}`));
486
501
  }
502
+ async function promptCustomModels() {
503
+ const { primaryModel } = await inquirer.prompt({
504
+ type: "input",
505
+ name: "primaryModel",
506
+ message: `${i18n.t("configuration:enterPrimaryModel")}${i18n.t("common:emptyToSkip")}`,
507
+ default: ""
508
+ });
509
+ const { fastModel } = await inquirer.prompt({
510
+ type: "input",
511
+ name: "fastModel",
512
+ message: `${i18n.t("configuration:enterFastModel")}${i18n.t("common:emptyToSkip")}`,
513
+ default: ""
514
+ });
515
+ return { primaryModel, fastModel };
516
+ }
487
517
  async function configureAiMemoryFeature() {
488
518
  ensureI18nInitialized();
489
519
  const { option } = await inquirer.prompt({
@@ -525,7 +555,7 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existi
525
555
  return;
526
556
  }
527
557
  }
528
- const { selectAiOutputLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.ai; });
558
+ const { selectAiOutputLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aj; });
529
559
  const aiOutputLang = await selectAiOutputLanguage();
530
560
  applyAiLanguageDirective(aiOutputLang);
531
561
  updateZcfConfig({ aiOutputLang });
@@ -825,11 +855,13 @@ async function runCometixMenuFeature() {
825
855
  await showCometixMenu();
826
856
  }
827
857
 
828
- async function checkUpdates() {
858
+ async function checkUpdates(options = {}) {
829
859
  try {
830
- await checkAndUpdateTools();
860
+ const skipPrompt = options.skipPrompt || false;
861
+ await checkAndUpdateTools(skipPrompt);
831
862
  } catch (error) {
832
- console.error(ansis.red(i18n.t("updater:errorCheckingUpdates")), error);
863
+ const errorMessage = error instanceof Error ? error.message : String(error);
864
+ console.error(ansis.red(`${i18n.t("updater:errorCheckingUpdates")} ${errorMessage}`));
833
865
  process.exit(1);
834
866
  }
835
867
  }
@@ -1120,12 +1152,12 @@ function customizeHelp(sections) {
1120
1152
  ` ${ansis.green("--api-url, -u")} <url> ${i18n.t("cli:help.optionDescriptions.customApiUrl")}`,
1121
1153
  ` ${ansis.green("--ai-output-lang, -a")} <lang> ${i18n.t("cli:help.optionDescriptions.aiOutputLanguage")}`,
1122
1154
  ` ${ansis.green("--all-lang, -g")} <lang> ${i18n.t("cli:help.optionDescriptions.setAllLanguageParams")}`,
1123
- ` ${ansis.green("--config-action, -r")} <action> ${i18n.t("cli:help.optionDescriptions.configHandling")} (default: backup)`,
1124
- ` ${ansis.green("--mcp-services, -m")} <list> ${i18n.t("cli:help.optionDescriptions.mcpServices")} (default: all non-key services)`,
1125
- ` ${ansis.green("--workflows, -w")} <list> ${i18n.t("cli:help.optionDescriptions.workflows")} (default: all workflows)`,
1126
- ` ${ansis.green("--output-styles, -o")} <styles> ${i18n.t("cli:help.optionDescriptions.outputStyles")} (default: all custom styles)`,
1127
- ` ${ansis.green("--default-output-style, -d")} <style> ${i18n.t("cli:help.optionDescriptions.defaultOutputStyle")} (default: engineer-professional)`,
1128
- ` ${ansis.green("--install-cometix-line, -x")} <value> ${i18n.t("cli:help.optionDescriptions.installStatuslineTool")} (default: true)`
1155
+ ` ${ansis.green("--config-action, -r")} <action> ${i18n.t("cli:help.optionDescriptions.configHandling")} (${i18n.t("cli:help.defaults.prefix")} backup)`,
1156
+ ` ${ansis.green("--mcp-services, -m")} <list> ${i18n.t("cli:help.optionDescriptions.mcpServices")} (${i18n.t("cli:help.defaults.prefix")} all non-key services)`,
1157
+ ` ${ansis.green("--workflows, -w")} <list> ${i18n.t("cli:help.optionDescriptions.workflows")} (${i18n.t("cli:help.defaults.prefix")} all workflows)`,
1158
+ ` ${ansis.green("--output-styles, -o")} <styles> ${i18n.t("cli:help.optionDescriptions.outputStyles")} (${i18n.t("cli:help.defaults.prefix")} all custom styles)`,
1159
+ ` ${ansis.green("--default-output-style, -d")} <style> ${i18n.t("cli:help.optionDescriptions.defaultOutputStyle")} (${i18n.t("cli:help.defaults.prefix")} engineer-professional)`,
1160
+ ` ${ansis.green("--install-cometix-line, -x")} <value> ${i18n.t("cli:help.optionDescriptions.installStatuslineTool")} (${i18n.t("cli:help.defaults.prefix")} true)`
1129
1161
  ].join("\n")
1130
1162
  });
1131
1163
  sections.push({
@@ -1145,11 +1177,11 @@ function customizeHelp(sections) {
1145
1177
  ` ${ansis.cyan("npx zcf ccr")}`,
1146
1178
  "",
1147
1179
  ansis.gray(` # ${i18n.t("cli:help.exampleDescriptions.runClaudeCodeUsageAnalysis")}`),
1148
- ` ${ansis.cyan("npx zcf ccu")} ${ansis.gray("# Daily usage (default)")}`,
1180
+ ` ${ansis.cyan("npx zcf ccu")} ${ansis.gray(`# ${i18n.t("cli:help.defaults.dailyUsage")}`)}`,
1149
1181
  ` ${ansis.cyan("npx zcf ccu monthly --json")}`,
1150
1182
  "",
1151
1183
  ansis.gray(` # ${i18n.t("cli:help.exampleDescriptions.checkAndUpdateTools")}`),
1152
- ` ${ansis.cyan("npx zcf check-updates")} ${ansis.gray("# Update Claude Code, CCR and CCometixLine")}`,
1184
+ ` ${ansis.cyan("npx zcf check-updates")} ${ansis.gray(`# ${i18n.t("cli:help.defaults.updateTools")}`)}`,
1153
1185
  ` ${ansis.cyan("npx zcf check")}`,
1154
1186
  "",
1155
1187
  ansis.gray(` # ${i18n.t("cli:help.exampleDescriptions.nonInteractiveModeCicd")}`),
@@ -1171,7 +1203,7 @@ async function setupCommands(cli) {
1171
1203
  cli.command("", "Show interactive menu (default)").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").option("--force, -f", "Force overwrite existing configuration").action(await withLanguageResolution(async () => {
1172
1204
  await showMainMenu();
1173
1205
  }));
1174
- cli.command("init", "Initialize Claude Code configuration").alias("i").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").option("--ai-output-lang, -a <lang>", "AI output language").option("--force, -f", "Force overwrite existing configuration").option("--skip-prompt, -s", "Skip all interactive prompts (non-interactive mode)").option("--config-action, -r <action>", "Config handling (new/backup/merge/docs-only/skip), default: backup").option("--api-type, -t <type>", "API type (auth_token/api_key/ccr_proxy/skip)").option("--api-key, -k <key>", "API key (used for both API key and auth token types)").option("--api-url, -u <url>", "Custom API URL").option("--mcp-services, -m <services>", 'Comma-separated MCP services to install (context7,mcp-deepwiki,Playwright,exa), "skip" to skip all, "all" for all non-key services, default: all').option("--workflows, -w <workflows>", 'Comma-separated workflows to install (sixStepsWorkflow,featPlanUx,gitWorkflow,bmadWorkflow), "skip" to skip all, "all" for all workflows, default: all').option("--output-styles, -o <styles>", 'Comma-separated output styles (engineer-professional,nekomata-engineer,laowang-engineer,default,explanatory,learning), "skip" to skip all, "all" for all custom styles, default: all').option("--default-output-style, -d <style>", "Default output style, default: engineer-professional").option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--install-cometix-line, -x <value>", "Install CCometixLine statusline tool (true/false), default: true").action(await withLanguageResolution(async (options) => {
1206
+ cli.command("init", "Initialize Claude Code configuration").alias("i").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").option("--ai-output-lang, -a <lang>", "AI output language").option("--force, -f", "Force overwrite existing configuration").option("--skip-prompt, -s", "Skip all interactive prompts (non-interactive mode)").option("--config-action, -r <action>", `Config handling (new/backup/merge/docs-only/skip), ${i18n.t("cli:help.defaults.prefix")} backup`).option("--api-type, -t <type>", "API type (auth_token/api_key/ccr_proxy/skip)").option("--api-key, -k <key>", "API key (used for both API key and auth token types)").option("--api-url, -u <url>", "Custom API URL").option("--mcp-services, -m <services>", `Comma-separated MCP services to install (context7,mcp-deepwiki,Playwright,exa), "skip" to skip all, "all" for all non-key services, ${i18n.t("cli:help.defaults.prefix")} all`).option("--workflows, -w <workflows>", `Comma-separated workflows to install (sixStepsWorkflow,featPlanUx,gitWorkflow,bmadWorkflow), "skip" to skip all, "all" for all workflows, ${i18n.t("cli:help.defaults.prefix")} all`).option("--output-styles, -o <styles>", `Comma-separated output styles (engineer-professional,nekomata-engineer,laowang-engineer,default,explanatory,learning), "skip" to skip all, "all" for all custom styles, ${i18n.t("cli:help.defaults.prefix")} all`).option("--default-output-style, -d <style>", `Default output style, ${i18n.t("cli:help.defaults.prefix")} engineer-professional`).option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--install-cometix-line, -x <value>", `Install CCometixLine statusline tool (true/false), ${i18n.t("cli:help.defaults.prefix")} true`).action(await withLanguageResolution(async (options) => {
1175
1207
  await init(options);
1176
1208
  }));
1177
1209
  cli.command("update", "Update Claude Code prompts only").alias("u").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").action(await withLanguageResolution(async (options) => {
@@ -11,8 +11,8 @@
11
11
  "enterApiKey": "Enter API Key",
12
12
  "enterApiUrl": "Enter API URL",
13
13
  "enterAuthToken": "Enter Auth Token",
14
- "enterNewApiKey": "Enter new API Key (current: {{key}})",
15
- "enterNewApiUrl": "Enter new API URL (current: {{url}})",
14
+ "enterNewApiKey": "Enter new API Key (current: {key})",
15
+ "enterNewApiUrl": "Enter new API URL (current: {url})",
16
16
  "existingApiConfig": "Existing API configuration detected:",
17
17
  "invalidKeyFormat": "Invalid key format",
18
18
  "invalidUrl": "Invalid URL",
@@ -26,7 +26,7 @@
26
26
  "modifyPartialConfig": "Modify partial configuration",
27
27
  "selectApiAction": "Select API processing operation",
28
28
  "selectModifyItems": "Select items to modify",
29
- "selectNewAuthType": "Select new auth type (current: {{type}})",
29
+ "selectNewAuthType": "Select new auth type (current: {type})",
30
30
  "skipApi": "Skip (configure manually later)",
31
31
  "urlRequired": "URL is required",
32
32
  "useApiKey": "Use API Key (Key authentication)",
@@ -1,9 +1,9 @@
1
1
  {
2
- "help.commands": "Commands:",
3
- "help.shortcuts": "Shortcuts:",
4
- "help.options": "Options:",
5
- "help.examples": "Examples:",
6
- "help.nonInteractiveMode": "Non-interactive mode (for CI/CD):",
2
+ "help.commands": "Commands",
3
+ "help.shortcuts": "Shortcuts",
4
+ "help.options": "Options",
5
+ "help.examples": "Examples",
6
+ "help.nonInteractiveMode": "Non-interactive mode (for CI/CD)",
7
7
  "help.commandDescriptions.showInteractiveMenuDefault": "Show interactive menu (default)",
8
8
  "help.commandDescriptions.initClaudeCodeConfig": "Initialize Claude Code configuration",
9
9
  "help.commandDescriptions.updateWorkflowFiles": "Update workflow-related md files",
@@ -38,5 +38,8 @@
38
38
  "help.exampleDescriptions.checkAndUpdateTools": "Check and update tools",
39
39
  "help.exampleDescriptions.nonInteractiveModeCicd": "Non-interactive mode (CI/CD)",
40
40
  "banner.subtitle": "One-click configuration tool for Claude Code",
41
- "banner.updateSubtitle": "Update configuration for Claude Code"
41
+ "banner.updateSubtitle": "Update configuration for Claude Code",
42
+ "help.defaults.dailyUsage": "Daily usage (default)",
43
+ "help.defaults.updateTools": "Update Claude Code, CCR and CCometixLine",
44
+ "help.defaults.prefix": "default:"
42
45
  }
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "multiSelectHint": " (Space to select, a to select all, i to invert, Enter to confirm)",
3
3
  "skip": "Skip",
4
+ "emptyToSkip": " (press Enter with empty content to skip)",
4
5
  "cancelled": "Operation cancelled",
5
6
  "error": "Error",
6
7
  "complete": "🎉 Setup complete! Use 'claude' command to start.",
@@ -8,10 +8,15 @@
8
8
  "configureAiLanguage": "Configure AI output language",
9
9
  "configureOutputStyle": "Configure global AI output style",
10
10
  "confirmClearCache": "Confirm clear all ZCF preference cache?",
11
+ "customModelConfigured": "Custom model configuration completed",
12
+ "customModelOption": "Custom - Specify custom model names",
13
+ "customModelSkipped": "Custom model configuration skipped",
11
14
  "currentLanguage": "Current language",
12
15
  "currentModel": "Current model",
13
16
  "defaultModelOption": "Default - Let Claude Code choose",
14
17
  "defaultStyle": "Default style",
18
+ "enterFastModel": "Enter fast model name for background tasks",
19
+ "enterPrimaryModel": "Enter primary model name",
15
20
  "envImportSuccess": "Environment variables imported",
16
21
  "existingConfig": "Existing config detected. How to proceed?",
17
22
  "existingLanguageConfig": "Existing AI output language configuration detected",
@@ -2,15 +2,15 @@
2
2
  "failedToRemoveFile": "Failed to remove file:",
3
3
  "failedToSetOnboarding": "Failed to set onboarding completion flag:",
4
4
  "failedToWriteMcpConfig": "Failed to write MCP config:",
5
- "invalidConfigAction": "Invalid configAction value: {{value}}. Must be 'new', 'backup', 'merge', 'docs-only', or 'skip'",
6
- "invalidApiType": "Invalid apiType value: {{value}}. Must be 'auth_token', 'api_key', 'ccr_proxy', or 'skip'",
5
+ "invalidConfigAction": "Invalid configAction value: {value}. Must be 'new', 'backup', 'merge', 'docs-only', or 'skip'",
6
+ "invalidApiType": "Invalid apiType value: {value}. Must be 'auth_token', 'api_key', 'ccr_proxy', or 'skip'",
7
7
  "apiKeyRequiredForApiKey": "API key is required when apiType is \"api_key\"",
8
8
  "apiKeyRequiredForAuthToken": "API key is required when apiType is \"auth_token\"",
9
- "invalidMcpService": "Invalid MCP service: {{service}}. Available services: {{validServices}}",
10
- "invalidOutputStyle": "Invalid output style: {{style}}. Available styles: {{validStyles}}",
11
- "invalidDefaultOutputStyle": "Invalid default output style: {{style}}. Available styles: {{validStyles}}",
12
- "invalidWorkflow": "Invalid workflow: {{workflow}}. Available workflows: {{validWorkflows}}",
13
- "invalidModel": "Invalid model: {{model}}. Expected 'opus', 'sonnet', or 'opusplan'",
9
+ "invalidMcpService": "Invalid MCP service: {service}. Available services: {validServices}",
10
+ "invalidOutputStyle": "Invalid output style: {style}. Available styles: {validStyles}",
11
+ "invalidDefaultOutputStyle": "Invalid default output style: {style}. Available styles: {validStyles}",
12
+ "invalidWorkflow": "Invalid workflow: {workflow}. Available workflows: {validWorkflows}",
13
+ "invalidModel": "Invalid model: {model}. Expected 'opus', 'sonnet', or 'opusplan'",
14
14
  "invalidEnvConfig": "Invalid env configuration: expected object",
15
15
  "invalidBaseUrl": "Invalid ANTHROPIC_BASE_URL: expected string",
16
16
  "invalidApiKeyConfig": "Invalid ANTHROPIC_API_KEY: expected string",
@@ -9,7 +9,7 @@
9
9
  "menuDescriptions.configureApiOrCcr": "Configure API URL, authentication or CCR proxy",
10
10
  "menuDescriptions.configureEnvPermission": "Import privacy protection environment variables and system permissions",
11
11
  "menuDescriptions.configureMcp": "Configure MCP services (includes Windows fix)",
12
- "menuDescriptions.configureModel": "Set default model (opus/sonnet)",
12
+ "menuDescriptions.configureModel": "Set default model (opus/sonnet/opusplan/custom)",
13
13
  "menuDescriptions.fullInit": "Install Claude Code + Import workflow + Configure API or CCR proxy + Configure MCP services",
14
14
  "menuDescriptions.importWorkflow": "Import/update workflow-related files only",
15
15
  "menuOptions.ccrManagement": "CCR",
@@ -1,20 +1,24 @@
1
1
  {
2
+ "autoUpdating": "Auto-updating {tool}...",
2
3
  "cannotCheckVersion": "Cannot check latest version",
3
4
  "ccrNotInstalled": "CCR is not installed",
4
- "ccrUpToDate": "CCR is up to date (v{{version}})",
5
+ "ccrUpToDate": "CCR is up to date (v{version})",
5
6
  "checkFailed": "Version check failed",
6
7
  "checkingTools": "Checking tool versions",
7
8
  "checkingVersion": "Checking version...",
8
9
  "claudeCodeNotInstalled": "Claude Code is not installed",
9
- "claudeCodeUpToDate": "Claude Code is up to date (v{{version}})",
10
+ "claudeCodeUpToDate": "Claude Code is up to date (v{version})",
10
11
  "cometixLineNotInstalled": "CCometixLine is not installed",
11
- "cometixLineUpToDate": "CCometixLine is up to date (v{{version}})",
12
- "confirmUpdate": "Update {{tool}} to the latest version?",
13
- "currentVersion": "Current version: v{{version}}",
12
+ "cometixLineUpToDate": "CCometixLine is up to date (v{version})",
13
+ "confirmUpdate": "Update {tool} to the latest version?",
14
+ "currentVersion": "Current version: v{version}",
14
15
  "errorCheckingUpdates": "Error checking updates:",
15
- "latestVersion": "Latest version: v{{version}}",
16
- "updateFailed": "{{tool}} update failed",
16
+ "failed": "failed",
17
+ "latestVersion": "Latest version: v{version}",
18
+ "success": "success",
19
+ "updateFailed": "{tool} update failed",
17
20
  "updateSkipped": "Update skipped",
18
- "updateSuccess": "{{tool}} updated successfully!",
19
- "updating": "Updating {{tool}}..."
21
+ "updateSuccess": "{tool} updated successfully!",
22
+ "updateSummary": "Update Summary",
23
+ "updating": "Updating {tool}..."
20
24
  }
@@ -11,8 +11,8 @@
11
11
  "enterApiKey": "请输入 API Key",
12
12
  "enterApiUrl": "请输入 API URL",
13
13
  "enterAuthToken": "请输入 Auth Token",
14
- "enterNewApiKey": "请输入新的 API Key(当前:{{key}})",
15
- "enterNewApiUrl": "请输入新的 API URL(当前:{{url}})",
14
+ "enterNewApiKey": "请输入新的 API Key(当前:{key})",
15
+ "enterNewApiUrl": "请输入新的 API URL(当前:{url})",
16
16
  "existingApiConfig": "检测到已有 API 配置:",
17
17
  "invalidKeyFormat": "无效的密钥格式",
18
18
  "invalidUrl": "无效的 URL",
@@ -26,7 +26,7 @@
26
26
  "modifyPartialConfig": "修改部分配置",
27
27
  "selectApiAction": "请选择API处理操作",
28
28
  "selectModifyItems": "请选择要修改的项",
29
- "selectNewAuthType": "选择新的认证类型(当前:{{type}})",
29
+ "selectNewAuthType": "选择新的认证类型(当前:{type})",
30
30
  "skipApi": "跳过(稍后手动配置)",
31
31
  "urlRequired": "URL 为必填项",
32
32
  "useApiKey": "使用 API Key (密钥认证)",
@@ -1,9 +1,9 @@
1
1
  {
2
- "help.commands": "命令:",
3
- "help.shortcuts": "快捷方式:",
4
- "help.options": "选项:",
5
- "help.examples": "示例:",
6
- "help.nonInteractiveMode": "非交互模式(适用于CI/CD):",
2
+ "help.commands": "命令",
3
+ "help.shortcuts": "快捷方式",
4
+ "help.options": "选项",
5
+ "help.examples": "示例",
6
+ "help.nonInteractiveMode": "非交互模式(适用于CI/CD",
7
7
  "help.commandDescriptions.showInteractiveMenuDefault": "显示交互式菜单(默认)",
8
8
  "help.commandDescriptions.initClaudeCodeConfig": "初始化 Claude Code 配置",
9
9
  "help.commandDescriptions.updateWorkflowFiles": "仅更新工作流相关md",
@@ -38,5 +38,8 @@
38
38
  "help.exampleDescriptions.checkAndUpdateTools": "检查并更新工具",
39
39
  "help.exampleDescriptions.nonInteractiveModeCicd": "非交互模式(CI/CD)",
40
40
  "banner.subtitle": "Claude Code 一键配置工具",
41
- "banner.updateSubtitle": "更新 Claude Code 配置"
41
+ "banner.updateSubtitle": "更新 Claude Code 配置",
42
+ "help.defaults.dailyUsage": "每日用量(默认)",
43
+ "help.defaults.updateTools": "更新 Claude Code、CCR 和 CCometixLine",
44
+ "help.defaults.prefix": "默认:"
42
45
  }
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "multiSelectHint": "(空格选择,a全选,i反选,回车确认)",
3
3
  "skip": "跳过",
4
+ "emptyToSkip": "(空内容回车则跳过)",
4
5
  "cancelled": "操作已取消",
5
6
  "error": "错误",
6
7
  "complete": "🎉 配置完成!使用 'claude' 命令开始体验。",
@@ -8,10 +8,15 @@
8
8
  "configureAiLanguage": "配置 AI 输出语言",
9
9
  "configureOutputStyle": "配置全局 AI 输出风格",
10
10
  "confirmClearCache": "确认清除所有 ZCF 偏好缓存?",
11
+ "customModelConfigured": "自定义模型配置完成",
12
+ "customModelOption": "自定义 - 指定自定义模型名称",
13
+ "customModelSkipped": "已跳过自定义模型配置",
11
14
  "currentLanguage": "当前语言",
12
15
  "currentModel": "当前模型",
13
16
  "defaultModelOption": "默认 - 让 Claude Code 自动选择",
14
17
  "defaultStyle": "默认风格",
18
+ "enterFastModel": "请输入后台任务的快速模型名称",
19
+ "enterPrimaryModel": "请输入主要使用的模型名称",
15
20
  "envImportSuccess": "环境变量已导入",
16
21
  "existingConfig": "检测到已有配置文件,如何处理?",
17
22
  "existingLanguageConfig": "检测到已有 AI 输出语言配置",
@@ -2,15 +2,15 @@
2
2
  "failedToRemoveFile": "删除文件失败:",
3
3
  "failedToSetOnboarding": "设置入门完成标志失败:",
4
4
  "failedToWriteMcpConfig": "写入 MCP 配置失败:",
5
- "invalidConfigAction": "无效的配置操作值:{{value}}。必须是 'new', 'backup', 'merge', 'docs-only', 或 'skip'",
6
- "invalidApiType": "无效的 API 类型值:{{value}}。必须是 'auth_token', 'api_key', 'ccr_proxy', 或 'skip'",
5
+ "invalidConfigAction": "无效的配置操作值:{value}。必须是 'new', 'backup', 'merge', 'docs-only', 或 'skip'",
6
+ "invalidApiType": "无效的 API 类型值:{value}。必须是 'auth_token', 'api_key', 'ccr_proxy', 或 'skip'",
7
7
  "apiKeyRequiredForApiKey": "当 apiType 为 \"api_key\" 时需要 API key",
8
8
  "apiKeyRequiredForAuthToken": "当 apiType 为 \"auth_token\" 时需要 API key",
9
- "invalidMcpService": "无效的 MCP 服务:{{service}}。可用的服务:{{validServices}}",
10
- "invalidOutputStyle": "无效的输出样式:{{style}}。可用的样式:{{validStyles}}",
11
- "invalidDefaultOutputStyle": "无效的默认输出样式:{{style}}。可用的样式:{{validStyles}}",
12
- "invalidWorkflow": "无效的工作流:{{workflow}}。可用的工作流:{{validWorkflows}}",
13
- "invalidModel": "无效的模型:{{model}}。期望的值:'opus', 'sonnet', 或 'opusplan'",
9
+ "invalidMcpService": "无效的 MCP 服务:{service}。可用的服务:{validServices}",
10
+ "invalidOutputStyle": "无效的输出样式:{style}。可用的样式:{validStyles}",
11
+ "invalidDefaultOutputStyle": "无效的默认输出样式:{style}。可用的样式:{validStyles}",
12
+ "invalidWorkflow": "无效的工作流:{workflow}。可用的工作流:{validWorkflows}",
13
+ "invalidModel": "无效的模型:{model}。期望的值:'opus', 'sonnet', 或 'opusplan'",
14
14
  "invalidEnvConfig": "无效的环境配置:期望对象类型",
15
15
  "invalidBaseUrl": "无效的 ANTHROPIC_BASE_URL:期望字符串类型",
16
16
  "invalidApiKeyConfig": "无效的 ANTHROPIC_API_KEY:期望字符串类型",
@@ -9,7 +9,7 @@
9
9
  "menuDescriptions.configureApiOrCcr": "配置 API URL、认证信息或 CCR 代理",
10
10
  "menuDescriptions.configureEnvPermission": "导入隐私保护环境变量和系统权限配置",
11
11
  "menuDescriptions.configureMcp": "配置 MCP 服务(含 Windows 修复)",
12
- "menuDescriptions.configureModel": "设置默认模型(opus/sonnet",
12
+ "menuDescriptions.configureModel": "设置默认模型(opus/sonnet/opusplan/自定义)",
13
13
  "menuDescriptions.fullInit": "安装 Claude Code + 导入工作流 + 配置 API 或 CCR 代理 + 配置 MCP 服务",
14
14
  "menuDescriptions.importWorkflow": "仅导入/更新工作流相关文件",
15
15
  "menuOptions.ccrManagement": "CCR",
@@ -1,20 +1,24 @@
1
1
  {
2
+ "autoUpdating": "正在自动更新 {tool}...",
2
3
  "cannotCheckVersion": "无法检查最新版本",
3
4
  "ccrNotInstalled": "CCR 未安装",
4
- "ccrUpToDate": "CCR 已是最新版本 (v{{version}})",
5
+ "ccrUpToDate": "CCR 已是最新版本 (v{version})",
5
6
  "checkFailed": "版本检查失败",
6
7
  "checkingTools": "检查工具版本",
7
8
  "checkingVersion": "检查版本中...",
8
9
  "claudeCodeNotInstalled": "Claude Code 未安装",
9
- "claudeCodeUpToDate": "Claude Code 已是最新版本 (v{{version}})",
10
+ "claudeCodeUpToDate": "Claude Code 已是最新版本 (v{version})",
10
11
  "cometixLineNotInstalled": "CCometixLine 未安装",
11
- "cometixLineUpToDate": "CCometixLine 已是最新版本 (v{{version}})",
12
- "confirmUpdate": "将 {{tool}} 更新到最新版本?",
13
- "currentVersion": "当前版本: v{{version}}",
12
+ "cometixLineUpToDate": "CCometixLine 已是最新版本 (v{version})",
13
+ "confirmUpdate": "将 {tool} 更新到最新版本?",
14
+ "currentVersion": "当前版本: v{version}",
14
15
  "errorCheckingUpdates": "检查更新时出错:",
15
- "latestVersion": "最新版本: v{{version}}",
16
- "updateFailed": "{{tool}} 更新失败",
16
+ "failed": "失败",
17
+ "latestVersion": "最新版本: v{version}",
18
+ "success": "成功",
19
+ "updateFailed": "{tool} 更新失败",
17
20
  "updateSkipped": "跳过更新",
18
- "updateSuccess": "{{tool}} 更新成功!",
19
- "updating": "正在更新 {{tool}}..."
21
+ "updateSuccess": "{tool} 更新成功!",
22
+ "updateSummary": "更新摘要",
23
+ "updating": "正在更新 {tool}..."
20
24
  }
package/dist/index.d.mts CHANGED
@@ -79,7 +79,18 @@ declare function backupExistingConfig(): string | null;
79
79
  declare function copyConfigFiles(onlyMd?: boolean): void;
80
80
  declare function configureApi(apiConfig: ApiConfig | null): ApiConfig | null;
81
81
  declare function mergeConfigs(sourceFile: string, targetFile: string): void;
82
- declare function updateDefaultModel(model: 'opus' | 'sonnet' | 'opusplan' | 'default'): void;
82
+ /**
83
+ * Update custom model configuration using environment variables
84
+ * @param primaryModel - Primary model name for general tasks
85
+ * @param fastModel - Fast model name for background tasks (optional)
86
+ */
87
+ declare function updateCustomModel(primaryModel?: string, fastModel?: string): void;
88
+ /**
89
+ * Update the default model configuration in settings.json
90
+ * @param model - The model type to set: opus, sonnet, opusplan, default, or custom
91
+ * Note: 'custom' model type is handled differently - it should use environment variables instead
92
+ */
93
+ declare function updateDefaultModel(model: 'opus' | 'sonnet' | 'opusplan' | 'default' | 'custom'): void;
83
94
  /**
84
95
  * Merge settings.json intelligently
85
96
  * Preserves user's environment variables and custom configurations
@@ -88,7 +99,7 @@ declare function mergeSettingsFile(templatePath: string, targetPath: string): vo
88
99
  /**
89
100
  * Get existing model configuration from settings.json
90
101
  */
91
- declare function getExistingModelConfig(): 'opus' | 'sonnet' | 'opusplan' | 'default' | null;
102
+ declare function getExistingModelConfig(): 'opus' | 'sonnet' | 'opusplan' | 'default' | 'custom' | null;
92
103
  /**
93
104
  * Get existing API configuration from settings.json
94
105
  */
@@ -127,12 +138,12 @@ declare function cleanupPermissions(templatePermissions: string[], userPermissio
127
138
  */
128
139
  declare function mergeAndCleanPermissions(templatePermissions: string[] | undefined, userPermissions: string[] | undefined): string[];
129
140
 
130
- declare function getPlatform(): "windows" | "macos" | "linux";
141
+ declare function getPlatform(): 'windows' | 'macos' | 'linux';
131
142
  declare function commandExists(command: string): Promise<boolean>;
132
143
 
133
144
  declare function importRecommendedEnv(): Promise<void>;
134
145
  declare function importRecommendedPermissions(): Promise<void>;
135
146
  declare function openSettingsJson(): Promise<void>;
136
147
 
137
- export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getAiOutputLanguageLabel, getExistingApiConfig, getExistingModelConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
148
+ export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getAiOutputLanguageLabel, getExistingApiConfig, getExistingModelConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateCustomModel, updateDefaultModel, writeMcpConfig };
138
149
  export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, McpServerConfig, McpService, SupportedLang };
package/dist/index.d.ts CHANGED
@@ -79,7 +79,18 @@ declare function backupExistingConfig(): string | null;
79
79
  declare function copyConfigFiles(onlyMd?: boolean): void;
80
80
  declare function configureApi(apiConfig: ApiConfig | null): ApiConfig | null;
81
81
  declare function mergeConfigs(sourceFile: string, targetFile: string): void;
82
- declare function updateDefaultModel(model: 'opus' | 'sonnet' | 'opusplan' | 'default'): void;
82
+ /**
83
+ * Update custom model configuration using environment variables
84
+ * @param primaryModel - Primary model name for general tasks
85
+ * @param fastModel - Fast model name for background tasks (optional)
86
+ */
87
+ declare function updateCustomModel(primaryModel?: string, fastModel?: string): void;
88
+ /**
89
+ * Update the default model configuration in settings.json
90
+ * @param model - The model type to set: opus, sonnet, opusplan, default, or custom
91
+ * Note: 'custom' model type is handled differently - it should use environment variables instead
92
+ */
93
+ declare function updateDefaultModel(model: 'opus' | 'sonnet' | 'opusplan' | 'default' | 'custom'): void;
83
94
  /**
84
95
  * Merge settings.json intelligently
85
96
  * Preserves user's environment variables and custom configurations
@@ -88,7 +99,7 @@ declare function mergeSettingsFile(templatePath: string, targetPath: string): vo
88
99
  /**
89
100
  * Get existing model configuration from settings.json
90
101
  */
91
- declare function getExistingModelConfig(): 'opus' | 'sonnet' | 'opusplan' | 'default' | null;
102
+ declare function getExistingModelConfig(): 'opus' | 'sonnet' | 'opusplan' | 'default' | 'custom' | null;
92
103
  /**
93
104
  * Get existing API configuration from settings.json
94
105
  */
@@ -127,12 +138,12 @@ declare function cleanupPermissions(templatePermissions: string[], userPermissio
127
138
  */
128
139
  declare function mergeAndCleanPermissions(templatePermissions: string[] | undefined, userPermissions: string[] | undefined): string[];
129
140
 
130
- declare function getPlatform(): "windows" | "macos" | "linux";
141
+ declare function getPlatform(): 'windows' | 'macos' | 'linux';
131
142
  declare function commandExists(command: string): Promise<boolean>;
132
143
 
133
144
  declare function importRecommendedEnv(): Promise<void>;
134
145
  declare function importRecommendedPermissions(): Promise<void>;
135
146
  declare function openSettingsJson(): Promise<void>;
136
147
 
137
- export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getAiOutputLanguageLabel, getExistingApiConfig, getExistingModelConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
148
+ export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getAiOutputLanguageLabel, getExistingApiConfig, getExistingModelConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateCustomModel, updateDefaultModel, writeMcpConfig };
138
149
  export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, McpServerConfig, McpService, SupportedLang };
package/dist/index.mjs CHANGED
@@ -1,17 +1,17 @@
1
- export { A as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, j as LANG_LABELS, L as LEGACY_ZCF_CONFIG_FILE, S as SETTINGS_FILE, h as SUPPORTED_LANGS, Z as ZCF_CONFIG_FILE, I as addCompletedOnboarding, w as applyAiLanguageDirective, n as backupExistingConfig, E as backupMcpConfig, G as buildMcpServerConfig, c as cleanupPermissions, a as commandExists, q as configureApi, p as copyConfigFiles, l as ensureClaudeDir, H as fixWindowsMcpConfig, k as getAiOutputLanguageLabel, v as getExistingApiConfig, t as getExistingModelConfig, z as getMcpConfigPath, g as getPlatform, b as importRecommendedEnv, d as importRecommendedPermissions, i as init, y as installClaudeCode, x as isClaudeCodeInstalled, m as mergeAndCleanPermissions, r as mergeConfigs, F as mergeMcpServers, s as mergeSettingsFile, o as openSettingsJson, B as readMcpConfig, u as updateDefaultModel, D as writeMcpConfig } from './chunks/simple-config.mjs';
1
+ export { A as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, j as LANG_LABELS, L as LEGACY_ZCF_CONFIG_FILE, S as SETTINGS_FILE, h as SUPPORTED_LANGS, Z as ZCF_CONFIG_FILE, J as addCompletedOnboarding, x as applyAiLanguageDirective, n as backupExistingConfig, F as backupMcpConfig, H as buildMcpServerConfig, c as cleanupPermissions, a as commandExists, q as configureApi, p as copyConfigFiles, l as ensureClaudeDir, I as fixWindowsMcpConfig, k as getAiOutputLanguageLabel, w as getExistingApiConfig, v as getExistingModelConfig, B as getMcpConfigPath, g as getPlatform, b as importRecommendedEnv, d as importRecommendedPermissions, i as init, z as installClaudeCode, y as isClaudeCodeInstalled, m as mergeAndCleanPermissions, r as mergeConfigs, G as mergeMcpServers, t as mergeSettingsFile, o as openSettingsJson, D as readMcpConfig, u as updateCustomModel, s as updateDefaultModel, E as writeMcpConfig } from './chunks/simple-config.mjs';
2
2
  import 'node:fs';
3
3
  import 'node:process';
4
4
  import 'ansis';
5
5
  import 'inquirer';
6
- import 'node:url';
7
- import 'i18next';
8
- import 'i18next-fs-backend';
9
- import 'pathe';
10
6
  import 'node:child_process';
11
7
  import 'node:os';
12
8
  import 'node:util';
13
9
  import 'dayjs';
10
+ import 'pathe';
11
+ import 'node:url';
14
12
  import 'ora';
15
13
  import 'semver';
16
14
  import 'tinyexec';
17
15
  import 'node:fs/promises';
16
+ import 'i18next';
17
+ import 'i18next-fs-backend';
package/package.json CHANGED
@@ -1,14 +1,20 @@
1
1
  {
2
2
  "name": "zcf",
3
3
  "type": "module",
4
- "version": "2.12.6",
4
+ "version": "2.12.8",
5
5
  "description": "Zero-Config Claude-Code Flow - One-click configuration tool for Claude Code",
6
+ "author": {
7
+ "name": "Miao Da",
8
+ "email": "ufo025174@gmail.com",
9
+ "url": "https://github.com/WitMiao"
10
+ },
6
11
  "license": "MIT",
7
12
  "homepage": "https://github.com/UfoMiao/zcf",
8
13
  "repository": {
9
14
  "type": "git",
10
15
  "url": "git+https://github.com/UfoMiao/zcf.git"
11
16
  },
17
+ "bugs": "https://github.com/UfoMiao/zcf/issues",
12
18
  "keywords": [
13
19
  "claude",
14
20
  "claude-code",
@@ -35,13 +41,13 @@
35
41
  ],
36
42
  "dependencies": {
37
43
  "@types/semver": "^7.7.0",
38
- "ansis": "^3.17.0",
44
+ "ansis": "^4.1.0",
39
45
  "cac": "^6.7.14",
40
- "dayjs": "^1.11.13",
46
+ "dayjs": "^1.11.18",
41
47
  "find-up-simple": "^1.0.1",
42
48
  "i18next": "^25.4.2",
43
49
  "i18next-fs-backend": "^2.6.0",
44
- "inquirer": "^12.9.0",
50
+ "inquirer": "^12.9.4",
45
51
  "ora": "^8.2.0",
46
52
  "pathe": "^2.0.3",
47
53
  "semver": "^7.7.2",
@@ -49,19 +55,29 @@
49
55
  },
50
56
  "devDependencies": {
51
57
  "@antfu/eslint-config": "^5.2.1",
52
- "@changesets/cli": "^2.29.5",
53
- "@types/inquirer": "^9.0.8",
54
- "@types/node": "^22.17.0",
58
+ "@changesets/cli": "^2.29.6",
59
+ "@commitlint/cli": "^19.8.1",
60
+ "@commitlint/config-conventional": "^19.8.1",
61
+ "@commitlint/types": "^19.8.1",
62
+ "@types/inquirer": "^9.0.9",
63
+ "@types/node": "^22.18.0",
55
64
  "@vitest/coverage-v8": "^3.2.4",
56
65
  "@vitest/ui": "^3.2.4",
57
- "eslint": "^9.33.0",
66
+ "eslint": "^9.34.0",
58
67
  "eslint-plugin-format": "^1.0.1",
59
68
  "glob": "^11.0.3",
60
- "tsx": "^4.20.3",
69
+ "husky": "^9.1.7",
70
+ "lint-staged": "^16.1.6",
71
+ "tsx": "^4.20.5",
61
72
  "typescript": "^5.9.2",
62
- "unbuild": "^3.6.0",
73
+ "unbuild": "^3.6.1",
63
74
  "vitest": "^3.2.4"
64
75
  },
76
+ "lint-staged": {
77
+ "*": [
78
+ "pnpm lint"
79
+ ]
80
+ },
65
81
  "scripts": {
66
82
  "dev": "tsx ./src/cli.ts",
67
83
  "build": "unbuild",
@@ -71,11 +87,14 @@
71
87
  "lint:fix": "eslint --fix",
72
88
  "test": "vitest",
73
89
  "test:ui": "vitest --ui",
74
- "test:coverage": "vitest --coverage",
90
+ "test:coverage": "vitest run --coverage",
75
91
  "test:run": "vitest run",
76
92
  "test:watch": "vitest watch",
77
93
  "changeset": "changeset",
78
94
  "version": "changeset version",
79
- "release": "pnpm build && changeset publish"
95
+ "update:deps": "pnpx taze major -r -w",
96
+ "release": "pnpm build && changeset publish",
97
+ "commitlint": "commitlint",
98
+ "commitlint:check": "commitlint --from HEAD~1 --to HEAD --verbose"
80
99
  }
81
100
  }
@@ -22,6 +22,7 @@
22
22
  "TodoWrite",
23
23
  "NotebookRead",
24
24
  "NotebookEdit",
25
+ "mcp__ide",
25
26
  "mcp__exa",
26
27
  "mcp__context7",
27
28
  "mcp__mcp-deepwiki",