zcf 3.0.2 → 3.1.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.
package/README.md CHANGED
@@ -30,7 +30,7 @@ Menu options include:
30
30
  - `2` Import workflows (equivalent to `zcf u`)
31
31
  - `3` Configure API or CCR - API configuration or CCR proxy setup
32
32
  - `4` Configure MCP - MCP service configuration and management
33
- - `5` Configure default model - Set default model (opus/sonnet/opusplan/custom)
33
+ - `5` Configure default model - Set default model (opus/sonnet/sonnet 1m/custom)
34
34
  - `6` Configure AI memory - Configure AI output language and global output style
35
35
  - `7` Configure environment permissions - Import environment variables and permissions
36
36
  - `R` Claude Code Router management (enhanced in v2.8.1)
@@ -44,7 +44,7 @@ Menu options include:
44
44
  **Model Configuration (Option 5)**: Configure your default Claude model with flexible options:
45
45
  - **Default**: Let Claude Code automatically choose the best model for each task
46
46
  - **Opus**: Use Claude-3.5-Opus exclusively (high token consumption, use with caution)
47
- - **OpusPlan**: Use Opus for planning, Sonnet for implementation (recommended balance)
47
+ - **Sonnet 1M**: Use Sonnet with 1M context window for larger context tasks
48
48
  - **Custom**: Specify your own model names for both primary and fast tasks (supports any custom model)
49
49
 
50
50
  **AI Memory Configuration (Option 6)**: Personalize your AI assistant:
@@ -124,7 +124,7 @@ When using `--skip-prompt`, the following parameters are available:
124
124
  | `--api-url, -u` | Custom API URL | URL string | No | official API |
125
125
  | `--mcp-services, -m` | MCP services to install (multi-select, comma-separated) | `context7`, `open-websearch`, `spec-workflow`, `mcp-deepwiki`, `Playwright`, `exa`, or `skip` for none | No | `all` |
126
126
  | `--workflows, -w` | Workflows to install (multi-select, comma-separated) | `commonTools`, `sixStepsWorkflow`, `featPlanUx`, `gitWorkflow`, `bmadWorkflow`, or `skip` for none | No | `all` |
127
- | `--output-styles, -o` | Output styles to install (multi-select, comma-separated) | `engineer-professional`, `nekomata-engineer`, `laowang-engineer`, or `skip` for none | No | `all` |
127
+ | `--output-styles, -o` | Output styles to install (multi-select, comma-separated) | `engineer-professional`, `nekomata-engineer`, `laowang-engineer`, `ojousama-engineer`, or `skip` for none | No | `all` |
128
128
  | `--default-output-style, -d` | Default output style | Same as output styles plus built-in: `default`, `explanatory`, `learning` | No | `engineer-professional` |
129
129
  | `--install-cometix-line, -x` | Install CCometixLine statusline tool | `true`, `false` | No | `true` |
130
130
 
@@ -214,6 +214,7 @@ ZCF now supports customizable AI output styles to personalize your Claude Code e
214
214
  - `engineer-professional`: Professional software engineer following SOLID, KISS, DRY, YAGNI principles
215
215
  - `nekomata-engineer`: Professional catgirl engineer UFO Nya, combining rigorous engineering with cute catgirl traits
216
216
  - `laowang-engineer`: Laowang grumpy tech style, never tolerates code errors and non-standard code
217
+ - `ojousama-engineer`: Tsundere blonde ojou-sama programmer Halley-chan, combining rigorous engineering excellence with tsundere ojou-sama traits
217
218
  - Built-in styles: `default`, `explanatory`, `learning` (always available)
218
219
 
219
220
  **Features:**
@@ -364,7 +365,7 @@ After configuration:
364
365
  - Script interaction language: Controls installation prompts language
365
366
  - Configuration file language: Determines which configuration set to install (zh-CN/en)
366
367
  - AI output language: Choose the language for AI responses (supports Chinese, English, and custom languages)
367
- - AI output styles: Support multiple preset styles (Professional Engineer, Nekomata Engineer, Laowang Engineer) for customized experience
368
+ - AI output styles: Support multiple preset styles (Professional Engineer, Nekomata Engineer, Laowang Engineer, Ojou-sama Engineer) for customized experience
368
369
 
369
370
  ### 🔧 Smart Installation
370
371
 
@@ -421,7 +422,7 @@ Select function:
421
422
  2. Import workflow - Import/update workflow-related files only
422
423
  3. Configure API - Configure API URL and authentication (supports CCR proxy)
423
424
  4. Configure MCP - Configure MCP services (includes Windows fix)
424
- 5. Configure default model - Set default model (opus/sonnet/opusplan/custom)
425
+ 5. Configure default model - Set default model (opus/sonnet/sonnet 1m/custom)
425
426
  6. Configure Claude global memory - Configure AI output language and output styles
426
427
  7. Import recommended environment variables and permissions - Import privacy protection environment variables and system permissions
427
428
 
@@ -443,15 +444,17 @@ Enter your choice: _
443
444
 
444
445
  ```bash
445
446
  ? Select Claude Code configuration language:
446
- 简体中文 (zh-CN) - Chinese (easier for Chinese users to customize)
447
- English (en) - English (recommended, lower token consumption)
447
+ English (en) - English (recommended, lower token consumption)
448
+ 简体中文 (zh-CN) - Chinese (easier for Chinese users to customize)
449
+ 日本語 (ja) - Japanese (日本のユーザー向け)
448
450
 
449
451
  ? Select AI output language:
450
452
  AI will respond to you in this language
451
- 简体中文
452
- English
453
+ English
454
+ 简体中文
455
+ 日本語
453
456
  Custom
454
- (Supports Japanese, French, German, and more)
457
+ (Supports French, German, and more)
455
458
 
456
459
  ? Claude Code not found. Install automatically? (Y/n)
457
460
 
@@ -464,12 +467,14 @@ Enter your choice: _
464
467
  Skip - Skip configuration update
465
468
 
466
469
  ? Select API authentication method
467
- ❯ Use Auth Token (OAuth authentication)
470
+ ❯ Use Official Login
471
+ Use official authentication system without API configuration
472
+ Use Auth Token (OAuth authentication)
468
473
  For tokens obtained via OAuth or browser login
469
474
  Use API Key (Key authentication)
470
475
  For API keys from Anthropic Console
471
476
  Configure CCR Proxy (Claude Code Router)
472
- Use free models and custom routing to reduce costs and explore the possibilities of Claude Code
477
+ Use multiple AI models via proxy routing to reduce costs and explore possibilities
473
478
  Skip (configure manually later)
474
479
 
475
480
  ? Enter API URL: https://api.anthropic.com
@@ -479,34 +484,12 @@ Enter your choice: _
479
484
  ❯ Engineer Professional - Professional software engineer following SOLID, KISS, DRY, YAGNI principles
480
485
  Nekomata Engineer - Professional catgirl engineer UFO Nya, combining rigorous engineering with cute catgirl traits
481
486
  Laowang Grumpy Tech - Laowang grumpy tech style, never tolerates code errors and non-standard code
487
+ Ojou-sama Engineer - Tsundere blonde ojou-sama programmer Halley-chan, combining rigorous engineering excellence with tsundere ojou-sama traits
482
488
 
483
489
  ? Select global default output style:
484
490
  ❯ Engineer Professional
485
491
 
486
- ? Configure MCP services? (Y/n)
487
-
488
- ? Select MCP services to install:
489
- ❯ context7 - Get latest library and framework documentation
490
- mcp-deepwiki - Access deepwiki.com knowledge base
491
- Playwright - Browser automation and web testing
492
- exa - Advanced search and enterprise research tools
493
-
494
- ? Select workflows to install:
495
- ❯ Common Tools Workflow - init-project and related agents
496
- Six Steps Workflow - Complete six-stage development process
497
- Feature Planning UX - Complete feature development lifecycle
498
- Git Workflow - Git operations and branch management
499
- BMad Workflow - AI-driven agile development methodology
500
-
501
- ? Install CCometixLine statusline tool? (Y/n)
502
-
503
- ✔ Setup complete! Claude Code environment is ready
504
- ```
505
-
506
- ✔ All config files backed up to ~/.claude/backup/xxx
507
- ✔ Config files copied to ~/.claude
508
-
509
- ? Select workflows to install (space to select, enter to confirm)
492
+ ? Select workflows to install (space to select, enter to confirm):
510
493
  ❯ ◉ Common Tools (init-project + init-architect + get-current-datetime) - Essential project initialization and utility commands
511
494
  ◉ Six Steps Workflow (workflow) - Complete 6-phase development process
512
495
  ◉ Feature Planning and UX Design (feat + planner + ui-ux-designer) - Structured feature development
@@ -525,24 +508,24 @@ Enter your choice: _
525
508
  ✔ Installed command: zcf/bmad-init.md
526
509
  ✔ Workflow installation successful
527
510
 
528
- ✔ API configured
529
-
530
511
  ? Configure MCP services? (Y/n)
531
512
 
532
- ? Select MCP services to install (space to select, enter to confirm)
533
- Install all
534
- Context7 Documentation Query - Query latest library docs and code examples
535
- DeepWiki - Query GitHub repository docs and examples
536
- Playwright Browser Control - Direct browser automation control
537
- Exa AI Search - Web search using Exa AI
538
-
539
- ? Enter Exa API Key (get from https://dashboard.exa.ai/api-keys)
513
+ ? Select MCP services to install (space to select, enter to confirm):
514
+ Context7 Documentation Query - Query latest library docs and code examples
515
+ DeepWiki - Query GitHub repository docs and examples
516
+ Playwright Browser Control - Direct browser automation control
517
+ Exa AI Search - Web search using Exa AI
518
+ Install all services
540
519
 
541
520
  ✔ MCP services configured
542
521
 
522
+ ? Install CCometixLine statusline tool? (Y/n)
523
+
524
+ ✔ Setup complete! Claude Code environment is ready
525
+
543
526
  🎉 Setup complete! Use 'claude' command to start.
544
527
 
545
- ````
528
+ ```
546
529
 
547
530
  ### Command Line Options
548
531
 
@@ -581,7 +564,7 @@ npx zcf -h
581
564
  # Show version
582
565
  npx zcf --version
583
566
  npx zcf -v
584
- ````
567
+ ```
585
568
 
586
569
  #### Usage Examples
587
570
 
@@ -1,6 +1,6 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { Y as readCodexConfig, _ as backupCodexComplete, $ as writeCodexConfig, a0 as writeAuthFile, a1 as ensureI18nInitialized, a2 as detectConfigManagementMode, X as i18n, a3 as addNumbersToChoices } from './simple-config.mjs';
3
+ import { a1 as readCodexConfig, a2 as backupCodexComplete, a3 as writeCodexConfig, a4 as writeAuthFile, a5 as ensureI18nInitialized, a6 as detectConfigManagementMode, a0 as i18n, a7 as addNumbersToChoices } from './simple-config.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:process';
6
6
  import 'node:child_process';
@@ -2,7 +2,7 @@ import { homedir } from 'node:os';
2
2
  import { pathExists } from 'fs-extra';
3
3
  import { join } from 'pathe';
4
4
  import { exec } from 'tinyexec';
5
- import { X as i18n } from './simple-config.mjs';
5
+ import { a0 as i18n } from './simple-config.mjs';
6
6
  import { m as moveToTrash } from '../shared/zcf.DGjQxTq_.mjs';
7
7
  import 'node:fs';
8
8
  import 'node:process';
@@ -16,7 +16,7 @@ import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
16
16
  import i18next from 'i18next';
17
17
  import Backend from 'i18next-fs-backend';
18
18
 
19
- const version = "3.0.2";
19
+ const version = "3.1.0";
20
20
  const homepage = "https://github.com/UfoMiao/zcf";
21
21
 
22
22
  const i18n = i18next.createInstance();
@@ -123,6 +123,15 @@ async function changeLanguage(lng) {
123
123
  await i18n.changeLanguage(lng);
124
124
  }
125
125
 
126
+ const index = {
127
+ __proto__: null,
128
+ changeLanguage: changeLanguage,
129
+ ensureI18nInitialized: ensureI18nInitialized,
130
+ format: format,
131
+ i18n: i18n,
132
+ initI18n: initI18n
133
+ };
134
+
126
135
  const MCP_SERVICE_CONFIGS = [
127
136
  {
128
137
  id: "context7",
@@ -355,6 +364,7 @@ const CLAUDE_DIR = join(homedir(), ".claude");
355
364
  const SETTINGS_FILE = join(CLAUDE_DIR, "settings.json");
356
365
  const CLAUDE_MD_FILE = join(CLAUDE_DIR, "CLAUDE.md");
357
366
  const ClAUDE_CONFIG_FILE = join(homedir(), ".claude.json");
367
+ const CLAUDE_VSC_CONFIG_FILE = join(CLAUDE_DIR, "config.json");
358
368
  const ZCF_CONFIG_DIR = join(homedir(), ".ufomiao", "zcf");
359
369
  const ZCF_CONFIG_FILE = join(ZCF_CONFIG_DIR, "config.toml");
360
370
  const LEGACY_ZCF_CONFIG_FILES = [
@@ -398,6 +408,7 @@ const constants = {
398
408
  AI_OUTPUT_LANGUAGES: AI_OUTPUT_LANGUAGES,
399
409
  CLAUDE_DIR: CLAUDE_DIR,
400
410
  CLAUDE_MD_FILE: CLAUDE_MD_FILE,
411
+ CLAUDE_VSC_CONFIG_FILE: CLAUDE_VSC_CONFIG_FILE,
401
412
  CODE_TOOL_BANNERS: CODE_TOOL_BANNERS,
402
413
  CODE_TOOL_TYPES: CODE_TOOL_TYPES,
403
414
  ClAUDE_CONFIG_FILE: ClAUDE_CONFIG_FILE,
@@ -992,6 +1003,19 @@ function manageApiKeyApproval(apiKey) {
992
1003
  console.error(i18n.t("mcp:apiKeyApprovalFailed"), error);
993
1004
  }
994
1005
  }
1006
+ function setPrimaryApiKey() {
1007
+ try {
1008
+ let config = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
1009
+ if (!config) {
1010
+ config = {};
1011
+ }
1012
+ config.primaryApiKey = "zcf";
1013
+ writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, config);
1014
+ } catch (error) {
1015
+ ensureI18nInitialized();
1016
+ console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
1017
+ }
1018
+ }
995
1019
 
996
1020
  const claudeConfig = {
997
1021
  __proto__: null,
@@ -1005,6 +1029,7 @@ const claudeConfig = {
1005
1029
  mergeMcpServers: mergeMcpServers,
1006
1030
  readMcpConfig: readMcpConfig,
1007
1031
  removeApiKeyFromRejected: removeApiKeyFromRejected,
1032
+ setPrimaryApiKey: setPrimaryApiKey,
1008
1033
  writeMcpConfig: writeMcpConfig
1009
1034
  };
1010
1035
 
@@ -1102,6 +1127,14 @@ function configureApi(apiConfig) {
1102
1127
  settings.env.ANTHROPIC_BASE_URL = apiConfig.url;
1103
1128
  }
1104
1129
  writeJsonConfig(SETTINGS_FILE, settings);
1130
+ if (apiConfig.authType) {
1131
+ try {
1132
+ setPrimaryApiKey();
1133
+ } catch (error) {
1134
+ ensureI18nInitialized();
1135
+ console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
1136
+ }
1137
+ }
1105
1138
  try {
1106
1139
  addCompletedOnboarding();
1107
1140
  } catch (error) {
@@ -1246,6 +1279,67 @@ function applyAiLanguageDirective(aiOutputLang) {
1246
1279
  }
1247
1280
  writeFile(claudeFile, directive);
1248
1281
  }
1282
+ function switchToOfficialLogin$1() {
1283
+ try {
1284
+ ensureI18nInitialized();
1285
+ const settings = readJsonConfig(SETTINGS_FILE) || {};
1286
+ if (settings.env) {
1287
+ delete settings.env.ANTHROPIC_BASE_URL;
1288
+ delete settings.env.ANTHROPIC_AUTH_TOKEN;
1289
+ delete settings.env.ANTHROPIC_API_KEY;
1290
+ }
1291
+ writeJsonConfig(SETTINGS_FILE, settings);
1292
+ const vscConfig = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
1293
+ if (vscConfig) {
1294
+ delete vscConfig.primaryApiKey;
1295
+ writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, vscConfig);
1296
+ }
1297
+ const mcpConfig = readMcpConfig();
1298
+ if (mcpConfig) {
1299
+ delete mcpConfig.hasCompletedOnboarding;
1300
+ writeMcpConfig(mcpConfig);
1301
+ }
1302
+ console.log(i18n.t("api:officialLoginConfigured"));
1303
+ return true;
1304
+ } catch (error) {
1305
+ ensureI18nInitialized();
1306
+ console.error(i18n.t("api:officialLoginFailed"), error);
1307
+ return false;
1308
+ }
1309
+ }
1310
+ async function promptApiConfigurationAction() {
1311
+ ensureI18nInitialized();
1312
+ const existingConfig = getExistingApiConfig();
1313
+ if (!existingConfig) {
1314
+ return null;
1315
+ }
1316
+ console.log(`
1317
+ ${ansis.blue(`\u2139 ${i18n.t("api:existingApiConfig")}`)}`);
1318
+ console.log(ansis.gray(` ${i18n.t("api:apiConfigUrl")}: ${existingConfig.url || "N/A"}`));
1319
+ console.log(ansis.gray(` ${i18n.t("api:apiConfigKey")}: ${existingConfig.key ? `***${existingConfig.key.slice(-4)}` : "N/A"}`));
1320
+ console.log(ansis.gray(` ${i18n.t("api:apiConfigAuthType")}: ${existingConfig.authType || "N/A"}
1321
+ `));
1322
+ const { choice } = await inquirer.prompt({
1323
+ type: "list",
1324
+ name: "choice",
1325
+ message: i18n.t("api:selectCustomConfigAction"),
1326
+ choices: [
1327
+ {
1328
+ name: i18n.t("api:modifyPartialConfig"),
1329
+ value: "modify-partial"
1330
+ },
1331
+ {
1332
+ name: i18n.t("api:modifyAllConfig"),
1333
+ value: "modify-all"
1334
+ },
1335
+ {
1336
+ name: i18n.t("api:keepExistingConfig"),
1337
+ value: "keep-existing"
1338
+ }
1339
+ ]
1340
+ });
1341
+ return choice || null;
1342
+ }
1249
1343
 
1250
1344
  const PROVIDER_PRESETS_URL = "https://pub-0dc3e1677e894f07bbea11b17a29e032.r2.dev/providers.json";
1251
1345
  async function fetchProviderPresets() {
@@ -1443,6 +1537,12 @@ async function configureCcrProxy(ccrConfig) {
1443
1537
  settings.env.ANTHROPIC_BASE_URL = `http://${host}:${port}`;
1444
1538
  settings.env.ANTHROPIC_API_KEY = apiKey;
1445
1539
  writeJsonConfig(SETTINGS_FILE, settings);
1540
+ try {
1541
+ setPrimaryApiKey();
1542
+ } catch (error) {
1543
+ ensureI18nInitialized();
1544
+ console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
1545
+ }
1446
1546
  }
1447
1547
  async function selectCcrPreset() {
1448
1548
  ensureI18nInitialized();
@@ -3021,6 +3121,11 @@ async function runCodexSystemPromptSelection() {
3021
3121
  id: "nekomata-engineer",
3022
3122
  name: i18n.t("configuration:outputStyles.nekomata-engineer.name"),
3023
3123
  description: i18n.t("configuration:outputStyles.nekomata-engineer.description")
3124
+ },
3125
+ {
3126
+ id: "ojousama-engineer",
3127
+ name: i18n.t("configuration:outputStyles.ojousama-engineer.name"),
3128
+ description: i18n.t("configuration:outputStyles.ojousama-engineer.description")
3024
3129
  }
3025
3130
  ].filter((style) => exists(join(systemPromptSrc, `${style.id}.md`)));
3026
3131
  if (availablePrompts.length === 0)
@@ -3811,6 +3916,11 @@ const OUTPUT_STYLES = [
3811
3916
  isCustom: true,
3812
3917
  filePath: "laowang-engineer.md"
3813
3918
  },
3919
+ {
3920
+ id: "ojousama-engineer",
3921
+ isCustom: true,
3922
+ filePath: "ojousama-engineer.md"
3923
+ },
3814
3924
  // Built-in styles (no template files)
3815
3925
  {
3816
3926
  id: "default",
@@ -3899,6 +4009,11 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
3899
4009
  id: "nekomata-engineer",
3900
4010
  name: i18n.t("configuration:outputStyles.nekomata-engineer.name"),
3901
4011
  description: i18n.t("configuration:outputStyles.nekomata-engineer.description")
4012
+ },
4013
+ {
4014
+ id: "ojousama-engineer",
4015
+ name: i18n.t("configuration:outputStyles.ojousama-engineer.name"),
4016
+ description: i18n.t("configuration:outputStyles.ojousama-engineer.description")
3902
4017
  }
3903
4018
  ];
3904
4019
  const availableStyles = getAvailableOutputStyles();
@@ -4014,6 +4129,11 @@ async function configureApiCompletely(preselectedAuthType) {
4014
4129
  name: "authType",
4015
4130
  message: i18n.t("api:configureApi"),
4016
4131
  choices: addNumbersToChoices([
4132
+ {
4133
+ name: i18n.t("api:useOfficialLogin"),
4134
+ value: "official",
4135
+ short: i18n.t("api:useOfficialLogin")
4136
+ },
4017
4137
  {
4018
4138
  name: `${i18n.t("api:useAuthToken")} - ${ansis.gray(i18n.t("api:authTokenDesc"))}`,
4019
4139
  value: "auth_token",
@@ -4032,6 +4152,15 @@ async function configureApiCompletely(preselectedAuthType) {
4032
4152
  }
4033
4153
  authType = selectedAuthType;
4034
4154
  }
4155
+ if (authType === "official") {
4156
+ const success = switchToOfficialLogin$1();
4157
+ if (success) {
4158
+ return null;
4159
+ } else {
4160
+ console.log(ansis.red(i18n.t("api:officialLoginFailed")));
4161
+ return null;
4162
+ }
4163
+ }
4035
4164
  const { url } = await inquirer.prompt({
4036
4165
  type: "input",
4037
4166
  name: "url",
@@ -4688,6 +4817,80 @@ async function init(options = {}) {
4688
4817
  const zcfConfig = readZcfConfig();
4689
4818
  const codeToolType = resolveCodeToolType(options.codeType, zcfConfig?.codeToolType);
4690
4819
  options.codeType = codeToolType;
4820
+ async function selectApiConfigurationMode() {
4821
+ const { apiMode } = await inquirer.prompt({
4822
+ type: "list",
4823
+ name: "apiMode",
4824
+ message: i18n.t("api:selectApiMode"),
4825
+ choices: [
4826
+ {
4827
+ name: i18n.t("api:useOfficialLogin"),
4828
+ value: "official"
4829
+ },
4830
+ {
4831
+ name: i18n.t("api:customApiConfig"),
4832
+ value: "custom"
4833
+ },
4834
+ {
4835
+ name: i18n.t("api:useCcrProxy"),
4836
+ value: "ccr"
4837
+ },
4838
+ {
4839
+ name: i18n.t("api:skipApi"),
4840
+ value: "skip"
4841
+ }
4842
+ ]
4843
+ });
4844
+ return apiMode;
4845
+ }
4846
+ async function handleCustomApiConfiguration(existingConfig) {
4847
+ if (existingConfig) {
4848
+ const customConfigAction = await promptApiConfigurationAction();
4849
+ if (customConfigAction === "modify-partial") {
4850
+ await modifyApiConfigPartially(existingConfig);
4851
+ return null;
4852
+ } else if (customConfigAction === "modify-all") {
4853
+ return await configureApiCompletely();
4854
+ } else if (customConfigAction === "keep-existing") {
4855
+ try {
4856
+ addCompletedOnboarding();
4857
+ } catch (error) {
4858
+ console.error(ansis.red(i18n.t("errors:failedToSetOnboarding")), error);
4859
+ }
4860
+ try {
4861
+ setPrimaryApiKey();
4862
+ } catch (error) {
4863
+ const { ensureI18nInitialized, i18n: i18nModule } = await Promise.resolve().then(function () { return index; });
4864
+ ensureI18nInitialized();
4865
+ console.error(i18nModule.t("mcp:primaryApiKeySetFailed"), error);
4866
+ }
4867
+ return null;
4868
+ }
4869
+ } else {
4870
+ const { apiChoice } = await inquirer.prompt({
4871
+ type: "list",
4872
+ name: "apiChoice",
4873
+ message: i18n.t("api:configureApi"),
4874
+ choices: [
4875
+ {
4876
+ name: `${i18n.t("api:useAuthToken")} - ${ansis.gray(i18n.t("api:authTokenDesc"))}`,
4877
+ value: "auth_token",
4878
+ short: i18n.t("api:useAuthToken")
4879
+ },
4880
+ {
4881
+ name: `${i18n.t("api:useApiKey")} - ${ansis.gray(i18n.t("api:apiKeyDesc"))}`,
4882
+ value: "api_key",
4883
+ short: i18n.t("api:useApiKey")
4884
+ }
4885
+ ]
4886
+ });
4887
+ if (!apiChoice) {
4888
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
4889
+ process.exit(0);
4890
+ }
4891
+ return await configureApiCompletely(apiChoice);
4892
+ }
4893
+ }
4691
4894
  if (!options.skipBanner) {
4692
4895
  displayBannerWithInfo(CODE_TOOL_BANNERS[codeToolType] || "ZCF");
4693
4896
  }
@@ -4859,94 +5062,22 @@ async function init(options = {}) {
4859
5062
  }
4860
5063
  } else {
4861
5064
  const existingApiConfig = getExistingApiConfig();
4862
- if (existingApiConfig) {
4863
- console.log(`
4864
- ${ansis.blue(`\u2139 ${i18n.t("api:existingApiConfig")}`)}`);
4865
- console.log(ansis.gray(` ${i18n.t("api:apiConfigUrl")}: ${existingApiConfig.url || i18n.t("common:notConfigured")}`));
4866
- console.log(
4867
- ansis.gray(
4868
- ` ${i18n.t("api:apiConfigKey")}: ${existingApiConfig.key ? formatApiKeyDisplay(existingApiConfig.key) : i18n.t("common:notConfigured")}`
4869
- )
4870
- );
4871
- console.log(
4872
- ansis.gray(` ${i18n.t("api:apiConfigAuthType")}: ${existingApiConfig.authType || i18n.t("common:notConfigured")}
4873
- `)
4874
- );
4875
- const { action: apiAction } = await inquirer.prompt({
4876
- type: "list",
4877
- name: "action",
4878
- message: i18n.t("api:selectApiAction"),
4879
- choices: addNumbersToChoices([
4880
- { name: i18n.t("api:keepExistingConfig"), value: "keep" },
4881
- { name: i18n.t("api:modifyAllConfig"), value: "modify-all" },
4882
- { name: i18n.t("api:modifyPartialConfig"), value: "modify-partial" },
4883
- { name: i18n.t("api:useCcrProxy"), value: "use-ccr" },
4884
- { name: i18n.t("api:skipApi"), value: "skip" }
4885
- ])
4886
- });
4887
- if (!apiAction) {
4888
- console.log(ansis.yellow(i18n.t("common:cancelled")));
4889
- process.exit(0);
4890
- }
4891
- if (apiAction === "keep" || apiAction === "skip") {
4892
- apiConfig = null;
4893
- if (apiAction === "keep") {
4894
- try {
4895
- addCompletedOnboarding();
4896
- } catch (error) {
4897
- console.error(ansis.red(i18n.t("errors:failedToSetOnboarding")), error);
4898
- }
4899
- }
4900
- } else if (apiAction === "modify-partial") {
4901
- await modifyApiConfigPartially(existingApiConfig);
4902
- apiConfig = null;
4903
- } else if (apiAction === "modify-all") {
4904
- apiConfig = await configureApiCompletely();
4905
- } else if (apiAction === "use-ccr") {
4906
- const ccrStatus = await isCcrInstalled();
4907
- if (!ccrStatus.hasCorrectPackage) {
4908
- await installCcr();
4909
- } else {
4910
- console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrAlreadyInstalled")}`));
4911
- }
4912
- const ccrConfigured = await setupCcrConfiguration();
4913
- if (ccrConfigured) {
4914
- console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrSetupComplete")}`));
5065
+ const apiMode = await selectApiConfigurationMode();
5066
+ switch (apiMode) {
5067
+ case "official": {
5068
+ const success = switchToOfficialLogin$1();
5069
+ if (success) {
5070
+ console.log(ansis.green(`\u2714 ${i18n.t("api:officialLoginConfigured")}`));
4915
5071
  apiConfig = null;
5072
+ } else {
5073
+ console.log(ansis.red(i18n.t("api:officialLoginFailed")));
4916
5074
  }
5075
+ break;
4917
5076
  }
4918
- } else {
4919
- const { apiChoice } = await inquirer.prompt({
4920
- type: "list",
4921
- name: "apiChoice",
4922
- message: i18n.t("api:configureApi"),
4923
- choices: [
4924
- {
4925
- name: `${i18n.t("api:useAuthToken")} - ${ansis.gray(i18n.t("api:authTokenDesc"))}`,
4926
- value: "auth_token",
4927
- short: i18n.t("api:useAuthToken")
4928
- },
4929
- {
4930
- name: `${i18n.t("api:useApiKey")} - ${ansis.gray(i18n.t("api:apiKeyDesc"))}`,
4931
- value: "api_key",
4932
- short: i18n.t("api:useApiKey")
4933
- },
4934
- {
4935
- name: `${i18n.t("api:useCcrProxy")} - ${ansis.gray(i18n.t("api:ccrProxyDesc"))}`,
4936
- value: "ccr_proxy",
4937
- short: i18n.t("api:useCcrProxy")
4938
- },
4939
- {
4940
- name: i18n.t("api:skipApi"),
4941
- value: "skip"
4942
- }
4943
- ]
4944
- });
4945
- if (!apiChoice) {
4946
- console.log(ansis.yellow(i18n.t("common:cancelled")));
4947
- process.exit(0);
4948
- }
4949
- if (apiChoice === "ccr_proxy") {
5077
+ case "custom":
5078
+ apiConfig = await handleCustomApiConfiguration(existingApiConfig);
5079
+ break;
5080
+ case "ccr": {
4950
5081
  const ccrStatus = await isCcrInstalled();
4951
5082
  if (!ccrStatus.hasCorrectPackage) {
4952
5083
  await installCcr();
@@ -4958,9 +5089,14 @@ ${ansis.blue(`\u2139 ${i18n.t("api:existingApiConfig")}`)}`);
4958
5089
  console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrSetupComplete")}`));
4959
5090
  apiConfig = null;
4960
5091
  }
4961
- } else if (apiChoice !== "skip") {
4962
- apiConfig = await configureApiCompletely(apiChoice);
5092
+ break;
4963
5093
  }
5094
+ case "skip":
5095
+ apiConfig = null;
5096
+ break;
5097
+ default:
5098
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
5099
+ process.exit(0);
4964
5100
  }
4965
5101
  }
4966
5102
  }
@@ -5205,4 +5341,4 @@ async function openSettingsJson() {
5205
5341
  }
5206
5342
  }
5207
5343
 
5208
- export { writeCodexConfig as $, AI_OUTPUT_LANGUAGES as A, removeApiKeyFromRejected as B, CLAUDE_DIR as C, DEFAULT_CODE_TOOL_TYPE as D, manageApiKeyApproval as E, ensureClaudeDir as F, backupExistingConfig as G, copyConfigFiles as H, configureApi as I, mergeConfigs as J, updateCustomModel as K, LEGACY_ZCF_CONFIG_FILES as L, updateDefaultModel as M, mergeSettingsFile as N, getExistingModelConfig as O, getExistingApiConfig as P, applyAiLanguageDirective as Q, isClaudeCodeInstalled as R, SETTINGS_FILE as S, installClaudeCode as T, isLocalClaudeCodeInstalled as U, getInstallationStatus as V, removeLocalClaudeCode as W, i18n as X, readCodexConfig as Y, ZCF_CONFIG_DIR as Z, backupCodexComplete as _, commandExists as a, writeAuthFile as a0, ensureI18nInitialized as a1, detectConfigManagementMode as a2, addNumbersToChoices as a3, readCcrConfig as a4, isCcrInstalled as a5, installCcr as a6, configureCcrFeature as a7, handleExitPromptError as a8, handleGeneralError as a9, configureCodexMcp as aA, configureCodexApi as aB, runCodexWorkflowImport as aC, runCodexFullInit as aD, listCodexProviders as aE, getCurrentCodexProvider as aF, switchCodexProvider as aG, switchToOfficialLogin as aH, switchToProvider as aI, readZcfConfigAsync as aJ, initI18n as aK, selectScriptLanguage as aL, fsOperations as aM, prompts as aN, codex as aO, updateZcfConfig as aa, changeLanguage as ab, readZcfConfig as ac, configureOutputStyle as ad, isWindows as ae, selectMcpServices as af, getMcpServices as ag, formatApiKeyDisplay as ah, modifyApiConfigPartially as ai, setupCcrConfiguration as aj, validateApiKey as ak, COMETIX_COMMAND_NAME as al, COMETIX_COMMANDS as am, installCometixLine as an, checkAndUpdateTools as ao, readJsonConfig as ap, writeJsonConfig as aq, displayBanner as ar, runCodexUpdate as as, version as at, resolveAiOutputLanguage as au, updatePromptOnly as av, selectAndInstallWorkflows as aw, checkClaudeCodeVersionAndPrompt as ax, displayBannerWithInfo as ay, runCodexUninstall as az, importRecommendedEnv as b, cleanupPermissions as c, importRecommendedPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, ZCF_CONFIG_FILE as h, init as i, CODE_TOOL_TYPES as j, CODE_TOOL_BANNERS as k, isCodeToolType as l, mergeAndCleanPermissions as m, SUPPORTED_LANGS as n, openSettingsJson as o, LANG_LABELS as p, getAiOutputLanguageLabel as q, getMcpConfigPath as r, readMcpConfig as s, backupMcpConfig as t, mergeMcpServers as u, buildMcpServerConfig as v, writeMcpConfig as w, fixWindowsMcpConfig as x, addCompletedOnboarding as y, ensureApiKeyApproved as z };
5344
+ export { removeLocalClaudeCode as $, AI_OUTPUT_LANGUAGES as A, ensureApiKeyApproved as B, CLAUDE_DIR as C, DEFAULT_CODE_TOOL_TYPE as D, removeApiKeyFromRejected as E, manageApiKeyApproval as F, setPrimaryApiKey as G, ensureClaudeDir as H, backupExistingConfig as I, copyConfigFiles as J, configureApi as K, LEGACY_ZCF_CONFIG_FILES as L, mergeConfigs as M, updateCustomModel as N, updateDefaultModel as O, mergeSettingsFile as P, getExistingModelConfig as Q, getExistingApiConfig as R, SETTINGS_FILE as S, applyAiLanguageDirective as T, switchToOfficialLogin$1 as U, promptApiConfigurationAction as V, isClaudeCodeInstalled as W, installClaudeCode as X, isLocalClaudeCodeInstalled as Y, ZCF_CONFIG_DIR as Z, getInstallationStatus as _, commandExists as a, i18n as a0, readCodexConfig as a1, backupCodexComplete as a2, writeCodexConfig as a3, writeAuthFile as a4, ensureI18nInitialized as a5, detectConfigManagementMode as a6, addNumbersToChoices as a7, readCcrConfig as a8, isCcrInstalled as a9, selectAndInstallWorkflows as aA, checkClaudeCodeVersionAndPrompt as aB, displayBannerWithInfo as aC, runCodexUninstall as aD, configureCodexMcp as aE, configureCodexApi as aF, runCodexWorkflowImport as aG, runCodexFullInit as aH, listCodexProviders as aI, getCurrentCodexProvider as aJ, switchCodexProvider as aK, switchToOfficialLogin as aL, switchToProvider as aM, readZcfConfigAsync as aN, initI18n as aO, selectScriptLanguage as aP, fsOperations as aQ, prompts as aR, codex as aS, installCcr as aa, configureCcrFeature as ab, handleExitPromptError as ac, handleGeneralError as ad, updateZcfConfig as ae, changeLanguage as af, readZcfConfig as ag, configureOutputStyle as ah, isWindows as ai, selectMcpServices as aj, getMcpServices as ak, setupCcrConfiguration as al, modifyApiConfigPartially as am, validateApiKey as an, formatApiKeyDisplay as ao, COMETIX_COMMAND_NAME as ap, COMETIX_COMMANDS as aq, installCometixLine as ar, checkAndUpdateTools as as, readJsonConfig as at, writeJsonConfig as au, displayBanner as av, runCodexUpdate as aw, version as ax, resolveAiOutputLanguage as ay, updatePromptOnly as az, importRecommendedEnv as b, cleanupPermissions as c, importRecommendedPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, CLAUDE_VSC_CONFIG_FILE as h, init as i, ZCF_CONFIG_FILE as j, CODE_TOOL_TYPES as k, CODE_TOOL_BANNERS as l, mergeAndCleanPermissions as m, isCodeToolType as n, openSettingsJson as o, SUPPORTED_LANGS as p, LANG_LABELS as q, getAiOutputLanguageLabel as r, getMcpConfigPath as s, readMcpConfig as t, backupMcpConfig as u, mergeMcpServers as v, writeMcpConfig as w, buildMcpServerConfig as x, fixWindowsMcpConfig as y, addCompletedOnboarding as z };