zcf 3.1.3 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +50 -21
  2. package/dist/chunks/claude-code-config-manager.mjs +705 -0
  3. package/dist/chunks/claude-code-incremental-manager.mjs +393 -0
  4. package/dist/chunks/codex-config-switch.mjs +2 -174
  5. package/dist/chunks/codex-provider-manager.mjs +193 -0
  6. package/dist/chunks/codex-uninstaller.mjs +1 -1
  7. package/dist/chunks/commands.mjs +117 -0
  8. package/dist/chunks/simple-config.mjs +578 -193
  9. package/dist/cli.mjs +284 -142
  10. package/dist/i18n/locales/en/api.json +1 -2
  11. package/dist/i18n/locales/en/cli.json +2 -0
  12. package/dist/i18n/locales/en/codex.json +0 -1
  13. package/dist/i18n/locales/en/common.json +2 -2
  14. package/dist/i18n/locales/en/errors.json +1 -0
  15. package/dist/i18n/locales/en/multi-config.json +61 -0
  16. package/dist/i18n/locales/zh-CN/api.json +1 -2
  17. package/dist/i18n/locales/zh-CN/cli.json +2 -0
  18. package/dist/i18n/locales/zh-CN/codex.json +0 -1
  19. package/dist/i18n/locales/zh-CN/common.json +2 -2
  20. package/dist/i18n/locales/zh-CN/errors.json +1 -0
  21. package/dist/i18n/locales/zh-CN/multi-config.json +61 -0
  22. package/dist/index.d.mts +6 -2
  23. package/dist/index.d.ts +6 -2
  24. package/dist/index.mjs +1 -1
  25. package/package.json +1 -1
  26. package/templates/claude-code/en/workflow/git/commands/git-commit.md +1 -0
  27. package/templates/claude-code/zh-CN/workflow/git/commands/git-commit.md +1 -0
  28. package/templates/codex/en/workflow/git/prompts/git-cleanBranches.md +102 -0
  29. package/templates/codex/en/workflow/git/prompts/git-commit.md +158 -0
  30. package/templates/codex/en/workflow/git/prompts/git-rollback.md +90 -0
  31. package/templates/codex/en/workflow/git/prompts/git-worktree.md +276 -0
  32. package/templates/codex/en/workflow/sixStep/prompts/workflow.md +140 -121
  33. package/templates/codex/zh-CN/workflow/git/prompts/git-cleanBranches.md +102 -0
  34. package/templates/codex/zh-CN/workflow/git/prompts/git-commit.md +158 -0
  35. package/templates/codex/zh-CN/workflow/git/prompts/git-rollback.md +90 -0
  36. package/templates/codex/zh-CN/workflow/git/prompts/git-worktree.md +276 -0
  37. package/templates/codex/zh-CN/workflow/sixStep/prompts/workflow.md +16 -33
package/dist/cli.mjs CHANGED
@@ -1,17 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import cac from 'cac';
3
3
  import ansis from 'ansis';
4
- import { a5 as ensureI18nInitialized, a0 as i18n, a8 as readCcrConfig, a9 as isCcrInstalled, aa as installCcr, ab as configureCcrFeature, ac as handleExitPromptError, ad as handleGeneralError, p as SUPPORTED_LANGS, a7 as addNumbersToChoices, q as LANG_LABELS, ae as updateZcfConfig, af as changeLanguage, ag as readZcfConfig, o as openSettingsJson, d as importRecommendedPermissions, b as importRecommendedEnv, T as applyAiLanguageDirective, ah as configureOutputStyle, Q as getExistingModelConfig, N as updateCustomModel, O as updateDefaultModel, ai as isWindows, t as readMcpConfig, y as fixWindowsMcpConfig, w as writeMcpConfig, aj as selectMcpServices, u as backupMcpConfig, ak as getMcpServices, x as buildMcpServerConfig, v as mergeMcpServers, al as setupCcrConfiguration, R as getExistingApiConfig, V as promptApiConfigurationAction, am as modifyApiConfigPartially, an as validateApiKey, K as configureApi, ao as formatApiKeyDisplay, U as switchToOfficialLogin, ap as COMETIX_COMMAND_NAME, aq as COMETIX_COMMANDS, ar as installCometixLine, as as checkAndUpdateTools, at as readJsonConfig, au as writeJsonConfig, j as ZCF_CONFIG_FILE, av as displayBanner, aw as runCodexUpdate, ax as version, ay as resolveAiOutputLanguage, az as updatePromptOnly, aA as selectAndInstallWorkflows, aB as checkClaudeCodeVersionAndPrompt, n as isCodeToolType, D as DEFAULT_CODE_TOOL_TYPE, aC as displayBannerWithInfo, l as CODE_TOOL_BANNERS, aD as runCodexUninstall, aE as configureCodexMcp, aF as configureCodexApi, aG as runCodexWorkflowImport, aH as runCodexFullInit, i as init, aI as listCodexProviders, aJ as getCurrentCodexProvider, aK as switchCodexProvider, a1 as readCodexConfig, aL as switchToOfficialLogin$1, aM as switchToProvider, aN as readZcfConfigAsync, aO as initI18n, aP as selectScriptLanguage } from './chunks/simple-config.mjs';
4
+ import { a2 as ensureI18nInitialized, a3 as i18n, ai as readCcrConfig, aj as isCcrInstalled, ak as installCcr, al as configureCcrFeature, am as handleExitPromptError, an as handleGeneralError, q as SUPPORTED_LANGS, a4 as addNumbersToChoices, s as LANG_LABELS, ao as updateZcfConfig, ap as changeLanguage, aq as readZcfConfig, o as openSettingsJson, d as importRecommendedPermissions, b as importRecommendedEnv, V as applyAiLanguageDirective, ar as configureOutputStyle, T as getExistingModelConfig, P as updateCustomModel, Q as updateDefaultModel, as as isWindows, v as readMcpConfig, B as fixWindowsMcpConfig, w as writeMcpConfig, at as selectMcpServices, x as backupMcpConfig, au as getMcpServices, z as buildMcpServerConfig, y as mergeMcpServers, av as setupCcrConfiguration, U as getExistingApiConfig, X as promptApiConfigurationAction, aw as modifyApiConfigPartially, a5 as validateApiKey, N as configureApi, ax as formatApiKeyDisplay, W as switchToOfficialLogin, ay as COMETIX_COMMAND_NAME, az as COMETIX_COMMANDS, aA as installCometixLine, aB as checkAndUpdateTools, aC as runCodexUpdate, aD as resolveCodeType$1, aa as readJsonConfig, aE as writeJsonConfig, j as ZCF_CONFIG_FILE, aF as displayBanner, aG as version, aH as resolveAiOutputLanguage, aI as updatePromptOnly, aJ as selectAndInstallWorkflows, aK as checkClaudeCodeVersionAndPrompt, r as resolveCodeToolType$1, D as DEFAULT_CODE_TOOL_TYPE, p as isCodeToolType, aL as displayBannerWithInfo, l as CODE_TOOL_BANNERS, aM as runCodexUninstall, aN as configureCodexMcp, aO as configureCodexApi, aP as runCodexWorkflowImportWithLanguageSelection, aQ as runCodexFullInit, i as init, aR as switchCodexProvider, aS as listCodexProviders, ae as readCodexConfig, aT as switchToOfficialLogin$1, aU as switchToProvider, aV as readZcfConfigAsync, aW as initI18n, aX as selectScriptLanguage } from './chunks/simple-config.mjs';
5
5
  import { existsSync } from 'node:fs';
6
6
  import { homedir } from 'node:os';
7
7
  import inquirer from 'inquirer';
8
8
  import { join } from 'pathe';
9
- import { exec, spawn } from 'node:child_process';
10
- import { promisify } from 'node:util';
9
+ import { runCcrStop, runCcrStart, runCcrRestart, runCcrStatus, runCcrUi } from './chunks/commands.mjs';
11
10
  import process from 'node:process';
12
11
  import { x, exec as exec$1 } from 'tinyexec';
12
+ import { exec, spawn } from 'node:child_process';
13
+ import { promisify } from 'node:util';
13
14
  import { pathExists } from 'fs-extra';
14
15
  import { m as moveToTrash } from './shared/zcf.DGjQxTq_.mjs';
16
+ import { ClaudeCodeConfigManager } from './chunks/claude-code-config-manager.mjs';
15
17
  import 'dayjs';
16
18
  import 'node:url';
17
19
  import 'ora';
@@ -22,103 +24,6 @@ import 'i18next';
22
24
  import 'i18next-fs-backend';
23
25
  import 'trash';
24
26
 
25
- const execAsync$1 = promisify(exec);
26
- async function runCcrUi(apiKey) {
27
- ensureI18nInitialized();
28
- console.log(ansis.cyan(`
29
- \u{1F5A5}\uFE0F ${i18n.t("ccr:startingCcrUi")}`));
30
- if (apiKey) {
31
- console.log(ansis.bold.green(`
32
- \u{1F511} ${i18n.t("ccr:ccrUiApiKey") || "CCR UI API Key"}: ${apiKey}`));
33
- console.log(ansis.gray(` ${i18n.t("ccr:ccrUiApiKeyHint") || "Use this API key to login to CCR UI"}
34
- `));
35
- }
36
- try {
37
- const { stdout, stderr } = await execAsync$1("ccr ui");
38
- if (stdout)
39
- console.log(stdout);
40
- if (stderr)
41
- console.error(ansis.yellow(stderr));
42
- console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrUiStarted")}`));
43
- } catch (error) {
44
- console.error(ansis.red(`\u2716 ${i18n.t("ccr:ccrCommandFailed")}: ${error instanceof Error ? error.message : String(error)}`));
45
- throw error;
46
- }
47
- }
48
- async function runCcrStatus() {
49
- ensureI18nInitialized();
50
- console.log(ansis.cyan(`
51
- \u{1F4CA} ${i18n.t("ccr:checkingCcrStatus")}`));
52
- try {
53
- const { stdout, stderr } = await execAsync$1("ccr status");
54
- if (stdout) {
55
- console.log(`
56
- ${ansis.bold(i18n.t("ccr:ccrStatusTitle"))}`);
57
- console.log(stdout);
58
- }
59
- if (stderr)
60
- console.error(ansis.yellow(stderr));
61
- } catch (error) {
62
- console.error(ansis.red(`\u2716 ${i18n.t("ccr:ccrCommandFailed")}: ${error instanceof Error ? error.message : String(error)}`));
63
- throw error;
64
- }
65
- }
66
- async function runCcrRestart() {
67
- ensureI18nInitialized();
68
- console.log(ansis.cyan(`
69
- \u{1F504} ${i18n.t("ccr:restartingCcr")}`));
70
- try {
71
- const { stdout, stderr } = await execAsync$1("ccr restart");
72
- if (stdout)
73
- console.log(stdout);
74
- if (stderr)
75
- console.error(ansis.yellow(stderr));
76
- console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrRestarted")}`));
77
- } catch (error) {
78
- console.error(ansis.red(`\u2716 ${i18n.t("ccr:ccrCommandFailed")}: ${error instanceof Error ? error.message : String(error)}`));
79
- throw error;
80
- }
81
- }
82
- async function runCcrStart() {
83
- ensureI18nInitialized();
84
- console.log(ansis.cyan(`
85
- \u25B6\uFE0F ${i18n.t("ccr:startingCcr")}`));
86
- try {
87
- const { stdout, stderr } = await execAsync$1("ccr start");
88
- if (stdout)
89
- console.log(stdout);
90
- if (stderr)
91
- console.error(ansis.yellow(stderr));
92
- console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrStarted")}`));
93
- } catch (error) {
94
- if (error.stdout && error.stdout.includes("Loaded JSON config from:")) {
95
- console.log(error.stdout);
96
- if (error.stderr)
97
- console.error(ansis.yellow(error.stderr));
98
- console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrStarted")}`));
99
- } else {
100
- console.error(ansis.red(`\u2716 ${i18n.t("ccr:ccrCommandFailed")}: ${error instanceof Error ? error.message : String(error)}`));
101
- throw error;
102
- }
103
- }
104
- }
105
- async function runCcrStop() {
106
- ensureI18nInitialized();
107
- console.log(ansis.cyan(`
108
- \u23F9\uFE0F ${i18n.t("ccr:stoppingCcr")}`));
109
- try {
110
- const { stdout, stderr } = await execAsync$1("ccr stop");
111
- if (stdout)
112
- console.log(stdout);
113
- if (stderr)
114
- console.error(ansis.yellow(stderr));
115
- console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrStopped")}`));
116
- } catch (error) {
117
- console.error(ansis.red(`\u2716 ${i18n.t("ccr:ccrCommandFailed")}: ${error instanceof Error ? error.message : String(error)}`));
118
- throw error;
119
- }
120
- }
121
-
122
27
  function isCcrConfigured() {
123
28
  const CCR_CONFIG_FILE = join(homedir(), ".claude-code-router", "config.json");
124
29
  if (!existsSync(CCR_CONFIG_FILE)) {
@@ -257,6 +162,13 @@ async function handleOfficialLoginMode() {
257
162
  }
258
163
  async function handleCustomApiMode() {
259
164
  ensureI18nInitialized();
165
+ const zcfConfig = readZcfConfig();
166
+ const codeToolType = zcfConfig?.codeToolType || "claude-code";
167
+ if (codeToolType === "claude-code") {
168
+ const { configureIncrementalManagement } = await import('./chunks/claude-code-incremental-manager.mjs');
169
+ await configureIncrementalManagement();
170
+ return;
171
+ }
260
172
  const existingConfig = getExistingApiConfig();
261
173
  if (existingConfig) {
262
174
  const configAction = await promptApiConfigurationAction();
@@ -553,7 +465,7 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existi
553
465
  return;
554
466
  }
555
467
  }
556
- const { selectAiOutputLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aR; });
468
+ const { selectAiOutputLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.b2; });
557
469
  const aiOutputLang = await selectAiOutputLanguage();
558
470
  applyAiLanguageDirective(aiOutputLang);
559
471
  updateZcfConfig({ aiOutputLang });
@@ -586,7 +498,7 @@ async function changeScriptLanguageFeature(currentLang) {
586
498
  }
587
499
  async function configureCodexDefaultModelFeature() {
588
500
  ensureI18nInitialized();
589
- const { readCodexConfig } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aS; });
501
+ const { readCodexConfig } = await import('./chunks/simple-config.mjs').then(function (n) { return n.b3; });
590
502
  const existingConfig = readCodexConfig();
591
503
  const currentModel = existingConfig?.model;
592
504
  if (currentModel) {
@@ -691,7 +603,7 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existi
691
603
  return;
692
604
  }
693
605
  }
694
- const { selectAiOutputLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aR; });
606
+ const { selectAiOutputLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.b2; });
695
607
  const aiOutputLang = await selectAiOutputLanguage();
696
608
  await updateCodexLanguageDirective(aiOutputLang);
697
609
  updateZcfConfig({ aiOutputLang });
@@ -699,14 +611,14 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existi
699
611
  } else if (option === "systemPrompt") {
700
612
  const zcfConfig = readZcfConfig();
701
613
  const currentLang = zcfConfig?.aiOutputLang || "English";
702
- const { runCodexSystemPromptSelection } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aS; });
614
+ const { runCodexSystemPromptSelection } = await import('./chunks/simple-config.mjs').then(function (n) { return n.b3; });
703
615
  await runCodexSystemPromptSelection();
704
616
  await ensureLanguageDirectiveInAgents(currentLang);
705
617
  console.log(ansis.green(`\u2714 ${i18n.t("configuration:systemPromptConfigured")}`));
706
618
  }
707
619
  }
708
620
  async function updateCodexModelProvider(modelProvider) {
709
- const { readCodexConfig, writeCodexConfig, backupCodexConfig, getBackupMessage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aS; });
621
+ const { readCodexConfig, writeCodexConfig, backupCodexConfig, getBackupMessage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.b3; });
710
622
  const backupPath = backupCodexConfig();
711
623
  if (backupPath) {
712
624
  console.log(ansis.gray(getBackupMessage(backupPath)));
@@ -727,7 +639,7 @@ async function updateCodexModelProvider(modelProvider) {
727
639
  writeCodexConfig(updatedConfig);
728
640
  }
729
641
  async function ensureLanguageDirectiveInAgents(aiOutputLang) {
730
- const { readFile, writeFile, exists } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aQ; });
642
+ const { readFile, writeFile, exists } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aZ; });
731
643
  const { homedir } = await import('node:os');
732
644
  const { join } = await import('pathe');
733
645
  const CODEX_AGENTS_FILE = join(homedir(), ".codex", "AGENTS.md");
@@ -745,7 +657,7 @@ async function ensureLanguageDirectiveInAgents(aiOutputLang) {
745
657
  const langLabel = languageLabels[aiOutputLang] || aiOutputLang;
746
658
  const hasLanguageDirective = /\*\*Most Important:\s*Always respond in [^*]+\*\*/i.test(content);
747
659
  if (!hasLanguageDirective) {
748
- const { backupCodexAgents, getBackupMessage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aS; });
660
+ const { backupCodexAgents, getBackupMessage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.b3; });
749
661
  const backupPath = backupCodexAgents();
750
662
  if (backupPath) {
751
663
  console.log(ansis.gray(getBackupMessage(backupPath)));
@@ -762,8 +674,8 @@ async function ensureLanguageDirectiveInAgents(aiOutputLang) {
762
674
  }
763
675
  }
764
676
  async function updateCodexLanguageDirective(aiOutputLang) {
765
- const { readFile, writeFile, exists } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aQ; });
766
- const { backupCodexAgents, getBackupMessage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aS; });
677
+ const { readFile, writeFile, exists } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aZ; });
678
+ const { backupCodexAgents, getBackupMessage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.b3; });
767
679
  const { homedir } = await import('node:os');
768
680
  const { join } = await import('pathe');
769
681
  const CODEX_AGENTS_FILE = join(homedir(), ".codex", "AGENTS.md");
@@ -1042,10 +954,55 @@ async function runCometixMenuFeature() {
1042
954
  await showCometixMenu();
1043
955
  }
1044
956
 
957
+ class ToolUpdateScheduler {
958
+ /**
959
+ * Update tools based on code type
960
+ * @param codeType - The code tool type to update
961
+ * @param skipPrompt - Whether to skip interactive prompts
962
+ */
963
+ async updateByCodeType(codeType, skipPrompt = false) {
964
+ await ensureI18nInitialized();
965
+ switch (codeType) {
966
+ case "claude-code":
967
+ await this.updateClaudeCodeTools(skipPrompt);
968
+ break;
969
+ case "codex":
970
+ await this.updateCodexTools(skipPrompt);
971
+ break;
972
+ default:
973
+ throw new Error(`Unsupported code type: ${codeType}`);
974
+ }
975
+ }
976
+ /**
977
+ * Update Claude Code related tools
978
+ * @param skipPrompt - Whether to skip interactive prompts
979
+ */
980
+ async updateClaudeCodeTools(skipPrompt) {
981
+ await checkAndUpdateTools(skipPrompt);
982
+ }
983
+ /**
984
+ * Update Codex tools
985
+ * @param skipPrompt - Whether to skip interactive prompts
986
+ */
987
+ async updateCodexTools(skipPrompt) {
988
+ await runCodexUpdate(false, skipPrompt);
989
+ }
990
+ }
991
+
1045
992
  async function checkUpdates(options = {}) {
1046
993
  try {
1047
994
  const skipPrompt = options.skipPrompt || false;
1048
- await checkAndUpdateTools(skipPrompt);
995
+ let codeType;
996
+ try {
997
+ codeType = await resolveCodeType$1(options.codeType);
998
+ } catch (err) {
999
+ const errorMessage = err instanceof Error ? err.message : String(err);
1000
+ console.error(ansis.red(`${errorMessage}
1001
+ Defaulting to "claude-code".`));
1002
+ codeType = "claude-code";
1003
+ }
1004
+ const scheduler = new ToolUpdateScheduler();
1005
+ await scheduler.updateByCodeType(codeType, skipPrompt);
1049
1006
  } catch (error) {
1050
1007
  const errorMessage = error instanceof Error ? error.message : String(error);
1051
1008
  console.error(ansis.red(`${i18n.t("updater:errorCheckingUpdates")} ${errorMessage}`));
@@ -1791,8 +1748,11 @@ function displayUninstallResult(mode, results) {
1791
1748
  }
1792
1749
 
1793
1750
  function resolveCodeToolType(optionValue, savedValue) {
1794
- if (isCodeToolType(optionValue)) {
1795
- return optionValue;
1751
+ if (optionValue !== void 0) {
1752
+ const resolved = resolveCodeToolType$1(optionValue);
1753
+ if (resolved !== DEFAULT_CODE_TOOL_TYPE || optionValue === DEFAULT_CODE_TOOL_TYPE) {
1754
+ return resolved;
1755
+ }
1796
1756
  }
1797
1757
  if (savedValue && isCodeToolType(savedValue)) {
1798
1758
  return savedValue;
@@ -1824,13 +1784,15 @@ async function update(options = {}) {
1824
1784
  }
1825
1785
  return;
1826
1786
  }
1827
- const { resolveTemplateLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.aR; });
1787
+ const { resolveTemplateLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.b2; });
1828
1788
  const configLang = await resolveTemplateLanguage(
1829
1789
  options.configLang,
1830
1790
  // Command line option
1831
- zcfConfig
1791
+ zcfConfig,
1792
+ options.skipPrompt
1793
+ // Non-interactive mode flag
1832
1794
  );
1833
- const aiOutputLang = await resolveAiOutputLanguage(i18n.language, options.aiOutputLang, zcfConfig);
1795
+ const aiOutputLang = await resolveAiOutputLanguage(i18n.language, options.aiOutputLang, zcfConfig, options.skipPrompt);
1834
1796
  console.log(ansis.cyan(`
1835
1797
  ${i18n.t("configuration:updatingPrompts")}
1836
1798
  `));
@@ -2096,7 +2058,7 @@ async function showCodexMenu() {
2096
2058
  await runCodexFullInit();
2097
2059
  break;
2098
2060
  case "2":
2099
- await runCodexWorkflowImport();
2061
+ await runCodexWorkflowImportWithLanguageSelection();
2100
2062
  break;
2101
2063
  case "3":
2102
2064
  await configureCodexApi();
@@ -2191,14 +2153,15 @@ async function configSwitchCommand(options) {
2191
2153
  try {
2192
2154
  ensureI18nInitialized();
2193
2155
  if (options.list) {
2194
- await handleListProviders();
2156
+ await handleList(options.codeType);
2195
2157
  return;
2196
2158
  }
2197
- if (options.provider) {
2198
- await handleDirectSwitch(options.provider);
2159
+ if (options.target) {
2160
+ const resolvedCodeType = resolveCodeType(options.codeType);
2161
+ await handleDirectSwitch(resolvedCodeType, options.target);
2199
2162
  return;
2200
2163
  }
2201
- await handleInteractiveSwitch();
2164
+ await handleInteractiveSwitch(options.codeType);
2202
2165
  } catch (error) {
2203
2166
  if (process.env.NODE_ENV === "test" || process.env.VITEST) {
2204
2167
  throw error;
@@ -2206,29 +2169,199 @@ async function configSwitchCommand(options) {
2206
2169
  handleGeneralError(error);
2207
2170
  }
2208
2171
  }
2209
- async function handleListProviders() {
2172
+ function resolveCodeType(codeType) {
2173
+ if (codeType !== void 0) {
2174
+ const resolved = resolveCodeToolType$1(codeType);
2175
+ return resolved;
2176
+ }
2177
+ const zcfConfig = readZcfConfig();
2178
+ if (zcfConfig?.codeToolType && isCodeToolType(zcfConfig.codeToolType)) {
2179
+ return zcfConfig.codeToolType;
2180
+ }
2181
+ return DEFAULT_CODE_TOOL_TYPE;
2182
+ }
2183
+ async function handleList(codeType) {
2184
+ const targetCodeType = resolveCodeType(codeType);
2185
+ if (targetCodeType === "claude-code") {
2186
+ await listClaudeCodeProfiles();
2187
+ } else if (targetCodeType === "codex") {
2188
+ await listCodexProvidersWithDisplay();
2189
+ }
2190
+ }
2191
+ async function listCodexProvidersWithDisplay() {
2210
2192
  const providers = await listCodexProviders();
2211
- const currentProvider = await getCurrentCodexProvider();
2212
- console.log(ansis.cyan(i18n.t("codex:listProvidersTitle")));
2213
- console.log("");
2214
- if (providers.length === 0) {
2193
+ const existingConfig = readCodexConfig();
2194
+ const currentProvider = existingConfig?.modelProvider;
2195
+ const isCommented = existingConfig?.modelProviderCommented;
2196
+ if (!providers || providers.length === 0) {
2215
2197
  console.log(ansis.yellow(i18n.t("codex:noProvidersAvailable")));
2216
2198
  return;
2217
2199
  }
2218
- if (currentProvider) {
2219
- console.log(ansis.green(`${i18n.t("codex:currentProvider", { provider: currentProvider })}`));
2220
- console.log("");
2200
+ console.log(ansis.bold(i18n.t("codex:listProvidersTitle")));
2201
+ console.log();
2202
+ if (currentProvider && !isCommented) {
2203
+ console.log(ansis.cyan(i18n.t("codex:currentProvider", { provider: currentProvider })));
2204
+ console.log();
2205
+ }
2206
+ providers.forEach((provider) => {
2207
+ const isCurrent = currentProvider === provider.id && !isCommented;
2208
+ const status = isCurrent ? ansis.green("\u25CF ") : " ";
2209
+ const current = isCurrent ? ansis.yellow(` (${i18n.t("common:current")})`) : "";
2210
+ console.log(`${status}${ansis.white(provider.name)}${current}`);
2211
+ console.log(` ${ansis.cyan(`ID: ${provider.id}`)} ${ansis.gray(`(${provider.baseUrl})`)}`);
2212
+ if (provider.envKey) {
2213
+ console.log(` ${ansis.gray(`Env: ${provider.envKey}`)}`);
2214
+ }
2215
+ console.log();
2216
+ });
2217
+ }
2218
+ async function listClaudeCodeProfiles() {
2219
+ const config = ClaudeCodeConfigManager.readConfig();
2220
+ if (!config || !config.profiles || Object.keys(config.profiles).length === 0) {
2221
+ console.log(ansis.yellow(i18n.t("multi-config:noClaudeCodeProfilesAvailable")));
2222
+ return;
2221
2223
  }
2222
- for (const provider of providers) {
2223
- const marker = currentProvider === provider.id ? ansis.green("\u25CF ") : " ";
2224
- console.log(`${marker}${ansis.cyan(provider.id)} - ${provider.name}`);
2225
- console.log(` ${ansis.gray(provider.baseUrl)}`);
2224
+ console.log(ansis.bold(i18n.t("multi-config:availableClaudeCodeProfiles")));
2225
+ console.log();
2226
+ const currentProfileId = config.currentProfileId;
2227
+ Object.values(config.profiles).forEach((profile) => {
2228
+ const isCurrent = profile.id === currentProfileId;
2229
+ const status = isCurrent ? ansis.green("\u25CF ") : " ";
2230
+ const current = isCurrent ? ansis.yellow(i18n.t("common:current")) : "";
2231
+ console.log(`${status}${ansis.white(profile.name)}${current}`);
2232
+ console.log(` ${ansis.cyan(`ID: ${profile.id}`)} ${ansis.gray(`(${profile.authType})`)}`);
2233
+ console.log();
2234
+ });
2235
+ }
2236
+ async function handleDirectSwitch(codeType, target) {
2237
+ const resolvedCodeType = resolveCodeType(codeType);
2238
+ if (resolvedCodeType === "claude-code") {
2239
+ await handleClaudeCodeDirectSwitch(target);
2240
+ } else if (resolvedCodeType === "codex") {
2241
+ await switchCodexProvider(target);
2226
2242
  }
2227
2243
  }
2228
- async function handleDirectSwitch(providerId) {
2229
- await switchCodexProvider(providerId);
2244
+ async function handleClaudeCodeDirectSwitch(target) {
2245
+ if (target === "official") {
2246
+ const result = await ClaudeCodeConfigManager.switchToOfficial();
2247
+ if (result.success) {
2248
+ try {
2249
+ await ClaudeCodeConfigManager.applyProfileSettings(null);
2250
+ console.log(ansis.green(i18n.t("multi-config:successfullySwitchedToOfficial")));
2251
+ } catch (error) {
2252
+ const reason = error instanceof Error ? error.message : String(error);
2253
+ console.log(ansis.red(reason));
2254
+ }
2255
+ } else {
2256
+ console.log(ansis.red(i18n.t("multi-config:failedToSwitchToOfficial", { error: result.error })));
2257
+ }
2258
+ } else if (target === "ccr") {
2259
+ const result = await ClaudeCodeConfigManager.switchToCcr();
2260
+ if (result.success) {
2261
+ try {
2262
+ const profile = ClaudeCodeConfigManager.getProfileById("ccr-proxy");
2263
+ await ClaudeCodeConfigManager.applyProfileSettings(profile);
2264
+ console.log(ansis.green(i18n.t("multi-config:successfullySwitchedToCcr")));
2265
+ } catch (error) {
2266
+ const reason = error instanceof Error ? error.message : String(error);
2267
+ console.log(ansis.red(reason));
2268
+ }
2269
+ } else {
2270
+ console.log(ansis.red(i18n.t("multi-config:failedToSwitchToCcr", { error: result.error })));
2271
+ }
2272
+ } else {
2273
+ const config = ClaudeCodeConfigManager.readConfig();
2274
+ if (!config || !config.profiles || Object.keys(config.profiles).length === 0) {
2275
+ console.log(ansis.yellow(i18n.t("multi-config:noClaudeCodeProfilesAvailable")));
2276
+ return;
2277
+ }
2278
+ const normalizedTarget = target.trim();
2279
+ let resolvedId = normalizedTarget;
2280
+ let resolvedProfile = config.profiles[normalizedTarget];
2281
+ if (!resolvedProfile) {
2282
+ const match = Object.entries(config.profiles).find(([, profile]) => profile.name === normalizedTarget);
2283
+ if (match) {
2284
+ resolvedId = match[0];
2285
+ resolvedProfile = match[1];
2286
+ }
2287
+ }
2288
+ if (!resolvedProfile) {
2289
+ console.log(ansis.red(i18n.t("multi-config:profileNameNotFound", { name: target })));
2290
+ return;
2291
+ }
2292
+ const result = await ClaudeCodeConfigManager.switchProfile(resolvedId);
2293
+ if (result.success) {
2294
+ try {
2295
+ await ClaudeCodeConfigManager.applyProfileSettings({ ...resolvedProfile, id: resolvedId });
2296
+ console.log(ansis.green(i18n.t("multi-config:successfullySwitchedToProfile", { name: resolvedProfile.name })));
2297
+ } catch (error) {
2298
+ const reason = error instanceof Error ? error.message : String(error);
2299
+ console.log(ansis.red(reason));
2300
+ }
2301
+ } else {
2302
+ console.log(ansis.red(i18n.t("multi-config:failedToSwitchToProfile", { error: result.error })));
2303
+ }
2304
+ }
2230
2305
  }
2231
- async function handleInteractiveSwitch() {
2306
+ async function handleInteractiveSwitch(codeType) {
2307
+ const resolvedCodeType = resolveCodeType(codeType);
2308
+ if (resolvedCodeType === "claude-code") {
2309
+ await handleClaudeCodeInteractiveSwitch();
2310
+ } else if (resolvedCodeType === "codex") {
2311
+ await handleCodexInteractiveSwitch();
2312
+ }
2313
+ }
2314
+ async function handleClaudeCodeInteractiveSwitch() {
2315
+ const config = ClaudeCodeConfigManager.readConfig();
2316
+ if (!config || !config.profiles || Object.keys(config.profiles).length === 0) {
2317
+ console.log(ansis.yellow(i18n.t("multi-config:noClaudeCodeProfilesAvailable")));
2318
+ return;
2319
+ }
2320
+ const currentProfileId = config.currentProfileId;
2321
+ const createClaudeCodeChoices = (profiles, currentProfileId2) => {
2322
+ const choices2 = [];
2323
+ const isOfficialMode = !currentProfileId2 || currentProfileId2 === "official";
2324
+ choices2.push({
2325
+ name: isOfficialMode ? `${ansis.green("\u25CF ")}${i18n.t("codex:useOfficialLogin")} ${ansis.yellow(`(${i18n.t("common:current")})`)}` : ` ${i18n.t("codex:useOfficialLogin")}`,
2326
+ value: "official"
2327
+ });
2328
+ const isCcrMode = currentProfileId2 === "ccr-proxy";
2329
+ choices2.push({
2330
+ name: isCcrMode ? `${ansis.green("\u25CF ")}CCR Proxy ${ansis.yellow("(current)")}` : ` CCR Proxy`,
2331
+ value: "ccr"
2332
+ });
2333
+ Object.values(profiles).filter((profile) => profile.id !== "ccr-proxy").forEach((profile) => {
2334
+ const isCurrent = profile.id === currentProfileId2;
2335
+ choices2.push({
2336
+ name: isCurrent ? `${ansis.green("\u25CF ")}${profile.name} ${ansis.yellow("(current)")}` : ` ${profile.name}`,
2337
+ value: profile.id
2338
+ });
2339
+ });
2340
+ return choices2;
2341
+ };
2342
+ const choices = createClaudeCodeChoices(config.profiles, currentProfileId);
2343
+ try {
2344
+ const { selectedConfig } = await inquirer.prompt([{
2345
+ type: "list",
2346
+ name: "selectedConfig",
2347
+ message: i18n.t("multi-config:selectClaudeCodeConfiguration"),
2348
+ choices: addNumbersToChoices(choices)
2349
+ }]);
2350
+ if (!selectedConfig) {
2351
+ console.log(ansis.yellow(i18n.t("multi-config:cancelled")));
2352
+ return;
2353
+ }
2354
+ await handleClaudeCodeDirectSwitch(selectedConfig);
2355
+ } catch (error) {
2356
+ if (error.name === "ExitPromptError") {
2357
+ console.log(ansis.cyan(`
2358
+ ${i18n.t("common:goodbye")}`));
2359
+ return;
2360
+ }
2361
+ throw error;
2362
+ }
2363
+ }
2364
+ async function handleCodexInteractiveSwitch() {
2232
2365
  const providers = await listCodexProviders();
2233
2366
  if (!providers || providers.length === 0) {
2234
2367
  console.log(ansis.yellow(i18n.t("codex:noProvidersAvailable")));
@@ -2356,7 +2489,7 @@ function customizeHelp(sections) {
2356
2489
  ` ${ansis.green("--workflows, -w")} <list> ${i18n.t("cli:help.optionDescriptions.workflows")} (${i18n.t("cli:help.defaults.prefix")} all workflows)`,
2357
2490
  ` ${ansis.green("--output-styles, -o")} <styles> ${i18n.t("cli:help.optionDescriptions.outputStyles")} (${i18n.t("cli:help.defaults.prefix")} all custom styles)`,
2358
2491
  ` ${ansis.green("--default-output-style, -d")} <style> ${i18n.t("cli:help.optionDescriptions.defaultOutputStyle")} (${i18n.t("cli:help.defaults.prefix")} engineer-professional)`,
2359
- ` ${ansis.green("--code-type, -T")} <type> ${i18n.t("cli:help.optionDescriptions.codeToolType")} (claude-code, codex)`,
2492
+ ` ${ansis.green("--code-type, -T")} <type> ${i18n.t("cli:help.optionDescriptions.codeToolType")} (claude-code, codex, cc=claude-code, cx=codex)`,
2360
2493
  ` ${ansis.green("--install-cometix-line, -x")} <value> ${i18n.t("cli:help.optionDescriptions.installStatuslineTool")} (${i18n.t("cli:help.defaults.prefix")} true)`
2361
2494
  ].join("\n")
2362
2495
  });
@@ -2387,6 +2520,14 @@ function customizeHelp(sections) {
2387
2520
  ` ${ansis.cyan("npx zcf check-updates")} ${ansis.gray(`# ${i18n.t("cli:help.defaults.updateTools")}`)}`,
2388
2521
  ` ${ansis.cyan("npx zcf check")}`,
2389
2522
  "",
2523
+ ansis.gray(` # ${i18n.t("cli:help.exampleDescriptions.checkClaudeCode")}`),
2524
+ ` ${ansis.cyan("npx zcf check --code-type claude-code")}`,
2525
+ ` ${ansis.cyan("npx zcf check -T cc")}`,
2526
+ "",
2527
+ ansis.gray(` # ${i18n.t("cli:help.exampleDescriptions.checkCodex")}`),
2528
+ ` ${ansis.cyan("npx zcf check --code-type codex")}`,
2529
+ ` ${ansis.cyan("npx zcf check -T cx")}`,
2530
+ "",
2390
2531
  ansis.gray(` # ${i18n.t("cli:help.exampleDescriptions.nonInteractiveModeCicd")}`),
2391
2532
  ` ${ansis.cyan('npx zcf i --skip-prompt --api-type api_key --api-key "sk-ant-..."')}`,
2392
2533
  ` ${ansis.cyan('npx zcf i --skip-prompt --all-lang zh-CN --api-type api_key --api-key "key"')}`,
@@ -2403,10 +2544,10 @@ async function setupCommands(cli) {
2403
2544
  await initI18n(defaultLang);
2404
2545
  } catch {
2405
2546
  }
2406
- 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").option("--code-type, -T <codeType>", "Select code tool type (claude-code, codex)").action(await withLanguageResolution(async () => {
2547
+ 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").option("--code-type, -T <codeType>", "Select code tool type (claude-code, codex, cc, cx)").action(await withLanguageResolution(async () => {
2407
2548
  await showMainMenu();
2408
2549
  }));
2409
- 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("--code-type, -T <codeType>", "Select code tool type (claude-code, codex)").option("--install-cometix-line, -x <value>", `Install CCometixLine statusline tool (true/false), ${i18n.t("cli:help.defaults.prefix")} true`).action(await withLanguageResolution(async (options) => {
2550
+ 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("--code-type, -T <codeType>", "Select code tool type (claude-code, codex, cc, cx)").option("--install-cometix-line, -x <value>", `Install CCometixLine statusline tool (true/false), ${i18n.t("cli:help.defaults.prefix")} true`).option("--api-configs <configs>", "API configurations as JSON string for multiple profiles").option("--api-configs-file <file>", "Path to JSON file containing API configurations").action(await withLanguageResolution(async (options) => {
2410
2551
  await init(options);
2411
2552
  }));
2412
2553
  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) => {
@@ -2418,17 +2559,18 @@ async function setupCommands(cli) {
2418
2559
  cli.command("ccu [...args]", "Run Claude Code usage analysis tool").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").allowUnknownOptions().action(await withLanguageResolution(async (args) => {
2419
2560
  await executeCcusage(args);
2420
2561
  }));
2421
- cli.command("config-switch [provider]", "Switch Codex provider or list available providers").alias("cs").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--list", "List available providers").action(await withLanguageResolution(async (provider, options) => {
2562
+ cli.command("config-switch [target]", "Switch Codex provider or Claude Code configuration, or list available configurations").alias("cs").option("--code-type, -T <type>", "Code tool type (claude-code, codex, cc, cx)").option("--lang <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--list, -l", "List available configurations").action(await withLanguageResolution(async (target, options) => {
2422
2563
  await configSwitchCommand({
2423
- provider,
2564
+ target,
2565
+ codeType: options.codeType,
2424
2566
  list: options.list
2425
2567
  });
2426
2568
  }));
2427
2569
  cli.command("uninstall", "Remove ZCF configurations and tools").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--mode, -m <mode>", "Uninstall mode (complete/custom/interactive), default: interactive").option("--items, -i <items>", "Comma-separated items for custom uninstall mode").action(await withLanguageResolution(async (options) => {
2428
2570
  await uninstall(options);
2429
2571
  }));
2430
- cli.command("check-updates", "Check and update Claude Code and CCR to latest versions").alias("check").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").action(await withLanguageResolution(async () => {
2431
- await checkUpdates();
2572
+ cli.command("check-updates", "Check and update Claude Code and CCR to latest versions").alias("check").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--code-type, -T <codeType>", "Select code tool type (claude-code, codex, cc, cx)").action(await withLanguageResolution(async (options) => {
2573
+ await checkUpdates(options);
2432
2574
  }));
2433
2575
  cli.help((sections) => customizeHelp(sections));
2434
2576
  cli.version(version);
@@ -6,7 +6,6 @@
6
6
  "apiKeyDesc": "For API keys from Anthropic Console",
7
7
  "apiKeyValidation.example": "Example format: sk-abcdef123456_789xyz",
8
8
  "authTokenDesc": "For tokens obtained via OAuth or browser login",
9
- "ccrProxyDesc": "Use multiple AI models via Claude Code Router",
10
9
  "configureApi": "Select API authentication method",
11
10
  "enterApiKey": "Enter API Key",
12
11
  "enterApiUrl": "Enter API URL",
@@ -24,7 +23,7 @@
24
23
  "modifyApiUrl": "Modify API URL",
25
24
  "modifyAuthType": "Modify auth type",
26
25
  "modifyPartialConfig": "Modify partial configuration",
27
- "selectApiAction": "Select API processing operation",
26
+
28
27
  "selectApiMode": "Select API configuration mode",
29
28
  "selectCustomConfigAction": "Select custom configuration action",
30
29
  "selectModifyItems": "Select items to modify",
@@ -39,6 +39,8 @@
39
39
  "help.exampleDescriptions.runClaudeCodeUsageAnalysis": "Run Claude Code usage analysis",
40
40
  "help.exampleDescriptions.uninstallConfigurations": "Uninstall configurations and tools",
41
41
  "help.exampleDescriptions.checkAndUpdateTools": "Check and update tools",
42
+ "help.exampleDescriptions.checkClaudeCode": "Check and update Claude Code tools",
43
+ "help.exampleDescriptions.checkCodex": "Check and update Codex tools",
42
44
  "help.exampleDescriptions.nonInteractiveModeCicd": "Non-interactive mode (CI/CD)",
43
45
  "banner.subtitle": "One-click configuration tool for Claude Code",
44
46
  "banner.updateSubtitle": "Update configuration for Claude Code",
@@ -87,7 +87,6 @@
87
87
  "useOfficialLogin": "Use Official Login",
88
88
  "apiConfigSwitchPrompt": "Select API configuration to switch to",
89
89
  "agentsFileNotFound": "AGENTS.md file not found, please configure system prompt first",
90
- "checkingVersion": "Checking version...",
91
90
  "currentVersion": "Current version: v{version}",
92
91
  "latestVersion": "Latest version: v{version}",
93
92
  "confirmUpdate": "Update Codex to the latest version?",