zcf 1.1.2 → 1.1.4

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
@@ -1,5 +1,8 @@
1
1
  # ZCF - Zero-Config Claude-Code Flow
2
2
 
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
+ [![Claude Code](https://img.shields.io/badge/Claude-Code-blue)](https://claude.ai/code)
5
+
3
6
  **中文** | [English](README_EN.md)
4
7
 
5
8
  > 零配置,一键搞定 Claude Code 环境设置 - 支持中英文双语配置和智能代理系统
@@ -29,6 +32,7 @@ npx zcf u # 仅导入工作流:快速添加 AI 工作流和命令系统
29
32
  完整初始化(`npx zcf`)会自动:
30
33
 
31
34
  - ✅ 检测并安装 Claude Code
35
+ - ✅ 选择 AI 输出语言(新增)
32
36
  - ✅ 配置 API 密钥
33
37
  - ✅ 选择并配置 MCP 服务
34
38
  - ✅ 设置所有必要的配置文件
@@ -49,10 +53,11 @@ npx zcf u # 仅导入工作流:快速添加 AI 工作流和命令系统
49
53
 
50
54
  ## ✨ ZCF 工具特性
51
55
 
52
- ### 🌏 双语支持
56
+ ### 🌏 多语言支持
53
57
 
54
58
  - 脚本交互语言:控制安装过程的提示语言
55
59
  - 配置文件语言:决定安装哪套配置文件(zh-CN/en)
60
+ - AI 输出语言:选择 AI 回复使用的语言(支持简体中文、English 及自定义语言)
56
61
 
57
62
  ### 🔧 智能安装
58
63
 
@@ -70,9 +75,11 @@ npx zcf u # 仅导入工作流:快速添加 AI 工作流和命令系统
70
75
 
71
76
  ### 🔐 API 配置
72
77
 
73
- - 自定义 API 支持
74
- - API Key 自动配置
75
- - 支持稍后在 claude 命令中配置(如 OAuth)
78
+ - 支持两种认证方式:
79
+ - **Auth Token**:适用于通过 OAuth 或浏览器登录获取的令牌
80
+ - **API Key**:适用于从 Anthropic Console 获取的 API 密钥
81
+ - 自定义 API URL 支持
82
+ - 支持稍后在 claude 命令中配置
76
83
 
77
84
  ### 💾 配置管理
78
85
 
@@ -96,16 +103,26 @@ $ npx zcf
96
103
  ❯ 简体中文 (zh-CN) - 中文版(便于中文用户自定义)
97
104
  English (en) - 英文版(推荐,token 消耗更低)
98
105
 
106
+ ? 选择 AI 输出语言:
107
+ AI 将使用此语言回复你的问题
108
+ ❯ 简体中文
109
+ English
110
+ Custom
111
+ (支持日语、法语、德语等多种语言)
112
+
99
113
  ? 检测到 Claude Code 未安装,是否自动安装?(Y/n)
100
114
 
101
115
  ✔ Claude Code 安装成功
102
116
 
103
- ? 是否配置 API
104
- 配置 API
105
- 跳过(稍后在 claude 命令中自行配置,如 OAuth)
117
+ ? 选择 API 认证方式
118
+ 使用 Auth Token (OAuth 认证)
119
+ 适用于通过 OAuth 或浏览器登录获取的令牌
120
+ 使用 API Key (密钥认证)
121
+ 适用于从 Anthropic Console 获取的 API 密钥
122
+ 跳过(稍后手动配置)
106
123
 
107
124
  ? 请输入 API URL: https://api.anthropic.com
108
- ? 请输入 API Key: sk-xxx
125
+ ? 请输入 Auth Token 或 API Key: xxx
109
126
 
110
127
  ? 检测到已有配置文件,如何处理?
111
128
  ❯ 备份并覆盖全部
@@ -198,9 +215,9 @@ claude-code-config/
198
215
  │ ├── utils/ # 工具函数
199
216
  │ └── constants.ts # 常量定义
200
217
  ├── templates/ # 配置模板
218
+ │ ├── settings.json # 基础配置(含隐私保护环境变量)
201
219
  │ ├── en/ # 英文版
202
220
  │ │ ├── CLAUDE.md # 核心原则
203
- │ │ ├── settings.json
204
221
  │ │ ├── agents/ # AI 代理
205
222
  │ │ └── commands/ # 命令定义
206
223
  │ └── zh-CN/ # 中文版
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 { s as displayBanner, t as readZcfConfig, b as SUPPORTED_LANGS, L as LANG_LABELS, u as updateZcfConfig, v as version, I as I18N, S as SETTINGS_FILE, x as updatePromptOnly, i as init } from './shared/zcf.3cK6W2AW.mjs';
4
+ import { t as displayBanner, u as selectScriptLanguage, v as readZcfConfig, I as I18N, S as SETTINGS_FILE, b as SUPPORTED_LANGS, L as LANG_LABELS, x as resolveAiOutputLanguage, y as updatePromptOnly, z as updateZcfConfig, B as version, i as init } from './shared/zcf.DK7kfRoM.mjs';
5
5
  import prompts from '@posva/prompts';
6
6
  import { existsSync } from 'node:fs';
7
7
  import 'node:os';
@@ -12,30 +12,8 @@ import 'tinyexec';
12
12
  async function update(options = {}) {
13
13
  try {
14
14
  displayBanner("Update configuration for Claude Code");
15
- let zcfConfig = readZcfConfig();
16
- let scriptLang;
17
- if (!zcfConfig) {
18
- const langResponse = await prompts({
19
- type: "select",
20
- name: "lang",
21
- message: "Select script language / \u9009\u62E9\u811A\u672C\u8BED\u8A00",
22
- choices: SUPPORTED_LANGS.map((l) => ({
23
- title: LANG_LABELS[l],
24
- value: l
25
- }))
26
- });
27
- if (!langResponse.lang) {
28
- console.log(ansis.yellow("Operation cancelled / \u64CD\u4F5C\u5DF2\u53D6\u6D88"));
29
- process.exit(0);
30
- }
31
- scriptLang = langResponse.lang;
32
- updateZcfConfig({
33
- version,
34
- preferredLang: scriptLang
35
- });
36
- } else {
37
- scriptLang = zcfConfig.preferredLang;
38
- }
15
+ const scriptLang = await selectScriptLanguage();
16
+ const zcfConfig = readZcfConfig();
39
17
  const i18n = I18N[scriptLang];
40
18
  if (!existsSync(SETTINGS_FILE)) {
41
19
  console.log(ansis.yellow(i18n.noExistingConfig));
@@ -61,13 +39,15 @@ async function update(options = {}) {
61
39
  }
62
40
  configLang = configResponse.lang;
63
41
  }
42
+ const aiOutputLang = await resolveAiOutputLanguage(scriptLang, options.aiOutputLang, zcfConfig);
64
43
  console.log(ansis.cyan(`
65
44
  ${i18n.updatingPrompts}
66
45
  `));
67
- await updatePromptOnly(configLang, scriptLang);
46
+ await updatePromptOnly(configLang, scriptLang, aiOutputLang);
68
47
  updateZcfConfig({
69
48
  version,
70
- preferredLang: scriptLang
49
+ preferredLang: scriptLang,
50
+ aiOutputLang
71
51
  });
72
52
  } catch (error) {
73
53
  const zcfConfig = readZcfConfig();
package/dist/index.d.mts CHANGED
@@ -38,10 +38,28 @@ declare const LANG_LABELS: {
38
38
  readonly 'zh-CN': "简体中文";
39
39
  readonly en: "English";
40
40
  };
41
+ declare const AI_OUTPUT_LANGUAGES: {
42
+ readonly 'zh-CN': {
43
+ readonly label: "简体中文";
44
+ readonly directive: "Always respond in Chinese-simplified";
45
+ };
46
+ readonly en: {
47
+ readonly label: "English";
48
+ readonly directive: "Always respond in English";
49
+ };
50
+ readonly custom: {
51
+ readonly label: "Custom";
52
+ readonly directive: "";
53
+ };
54
+ };
55
+ type AiOutputLanguage = keyof typeof AI_OUTPUT_LANGUAGES;
41
56
  declare const I18N: {
42
57
  'zh-CN': {
43
58
  selectScriptLang: string;
44
59
  selectConfigLang: string;
60
+ selectAiOutputLang: string;
61
+ aiOutputLangHint: string;
62
+ enterCustomLanguage: string;
45
63
  configLangHint: {
46
64
  'zh-CN': string;
47
65
  en: string;
@@ -52,9 +70,13 @@ declare const I18N: {
52
70
  installFailed: string;
53
71
  npmNotFound: string;
54
72
  configureApi: string;
55
- customApi: string;
73
+ useAuthToken: string;
74
+ authTokenDesc: string;
75
+ useApiKey: string;
76
+ apiKeyDesc: string;
56
77
  skipApi: string;
57
78
  enterApiUrl: string;
79
+ enterAuthToken: string;
58
80
  enterApiKey: string;
59
81
  existingConfig: string;
60
82
  backupAndOverwrite: string;
@@ -89,6 +111,9 @@ declare const I18N: {
89
111
  en: {
90
112
  selectScriptLang: string;
91
113
  selectConfigLang: string;
114
+ selectAiOutputLang: string;
115
+ aiOutputLangHint: string;
116
+ enterCustomLanguage: string;
92
117
  configLangHint: {
93
118
  'zh-CN': string;
94
119
  en: string;
@@ -99,9 +124,13 @@ declare const I18N: {
99
124
  installFailed: string;
100
125
  npmNotFound: string;
101
126
  configureApi: string;
102
- customApi: string;
127
+ useAuthToken: string;
128
+ authTokenDesc: string;
129
+ useApiKey: string;
130
+ apiKeyDesc: string;
103
131
  skipApi: string;
104
132
  enterApiUrl: string;
133
+ enterAuthToken: string;
105
134
  enterApiKey: string;
106
135
  existingConfig: string;
107
136
  backupAndOverwrite: string;
@@ -139,6 +168,7 @@ declare const MCP_SERVICES: McpService[];
139
168
  interface InitOptions {
140
169
  lang?: SupportedLang;
141
170
  configLang?: SupportedLang;
171
+ aiOutputLang?: AiOutputLanguage | string;
142
172
  force?: boolean;
143
173
  }
144
174
  declare function init(options?: InitOptions): Promise<void>;
@@ -155,9 +185,11 @@ declare function copyConfigFiles(lang: SupportedLang, onlyMd?: boolean): void;
155
185
  interface ApiConfig {
156
186
  url: string;
157
187
  key: string;
188
+ authType?: 'auth_token' | 'api_key';
158
189
  }
159
190
  declare function configureApi(apiConfig: ApiConfig | null): void;
160
191
  declare function mergeConfigs(sourceFile: string, targetFile: string): void;
192
+ declare function applyAiLanguageDirective(aiOutputLang: AiOutputLanguage | string): void;
161
193
 
162
194
  declare function getMcpConfigPath(): string;
163
195
  declare function readMcpConfig(): McpConfiguration | null;
@@ -166,5 +198,5 @@ declare function backupMcpConfig(): string | null;
166
198
  declare function mergeMcpServers(existing: McpConfiguration | null, newServers: Record<string, McpServerConfig>): McpConfiguration;
167
199
  declare function buildMcpServerConfig(baseConfig: McpServerConfig, apiKey?: string, placeholder?: string): McpServerConfig;
168
200
 
169
- export { CLAUDE_DIR, CLAUDE_MD_FILE, I18N, LANG_LABELS, MCP_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, getMcpConfigPath, getPlatform, init, installClaudeCode, isClaudeCodeInstalled, mergeConfigs, mergeMcpServers, readMcpConfig, writeMcpConfig };
170
- export type { ApiConfig, McpConfiguration, McpServerConfig, McpService, SupportedLang };
201
+ export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, I18N, LANG_LABELS, MCP_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, getMcpConfigPath, getPlatform, init, installClaudeCode, isClaudeCodeInstalled, mergeConfigs, mergeMcpServers, readMcpConfig, writeMcpConfig };
202
+ export type { AiOutputLanguage, ApiConfig, McpConfiguration, McpServerConfig, McpService, SupportedLang };
package/dist/index.d.ts CHANGED
@@ -38,10 +38,28 @@ declare const LANG_LABELS: {
38
38
  readonly 'zh-CN': "简体中文";
39
39
  readonly en: "English";
40
40
  };
41
+ declare const AI_OUTPUT_LANGUAGES: {
42
+ readonly 'zh-CN': {
43
+ readonly label: "简体中文";
44
+ readonly directive: "Always respond in Chinese-simplified";
45
+ };
46
+ readonly en: {
47
+ readonly label: "English";
48
+ readonly directive: "Always respond in English";
49
+ };
50
+ readonly custom: {
51
+ readonly label: "Custom";
52
+ readonly directive: "";
53
+ };
54
+ };
55
+ type AiOutputLanguage = keyof typeof AI_OUTPUT_LANGUAGES;
41
56
  declare const I18N: {
42
57
  'zh-CN': {
43
58
  selectScriptLang: string;
44
59
  selectConfigLang: string;
60
+ selectAiOutputLang: string;
61
+ aiOutputLangHint: string;
62
+ enterCustomLanguage: string;
45
63
  configLangHint: {
46
64
  'zh-CN': string;
47
65
  en: string;
@@ -52,9 +70,13 @@ declare const I18N: {
52
70
  installFailed: string;
53
71
  npmNotFound: string;
54
72
  configureApi: string;
55
- customApi: string;
73
+ useAuthToken: string;
74
+ authTokenDesc: string;
75
+ useApiKey: string;
76
+ apiKeyDesc: string;
56
77
  skipApi: string;
57
78
  enterApiUrl: string;
79
+ enterAuthToken: string;
58
80
  enterApiKey: string;
59
81
  existingConfig: string;
60
82
  backupAndOverwrite: string;
@@ -89,6 +111,9 @@ declare const I18N: {
89
111
  en: {
90
112
  selectScriptLang: string;
91
113
  selectConfigLang: string;
114
+ selectAiOutputLang: string;
115
+ aiOutputLangHint: string;
116
+ enterCustomLanguage: string;
92
117
  configLangHint: {
93
118
  'zh-CN': string;
94
119
  en: string;
@@ -99,9 +124,13 @@ declare const I18N: {
99
124
  installFailed: string;
100
125
  npmNotFound: string;
101
126
  configureApi: string;
102
- customApi: string;
127
+ useAuthToken: string;
128
+ authTokenDesc: string;
129
+ useApiKey: string;
130
+ apiKeyDesc: string;
103
131
  skipApi: string;
104
132
  enterApiUrl: string;
133
+ enterAuthToken: string;
105
134
  enterApiKey: string;
106
135
  existingConfig: string;
107
136
  backupAndOverwrite: string;
@@ -139,6 +168,7 @@ declare const MCP_SERVICES: McpService[];
139
168
  interface InitOptions {
140
169
  lang?: SupportedLang;
141
170
  configLang?: SupportedLang;
171
+ aiOutputLang?: AiOutputLanguage | string;
142
172
  force?: boolean;
143
173
  }
144
174
  declare function init(options?: InitOptions): Promise<void>;
@@ -155,9 +185,11 @@ declare function copyConfigFiles(lang: SupportedLang, onlyMd?: boolean): void;
155
185
  interface ApiConfig {
156
186
  url: string;
157
187
  key: string;
188
+ authType?: 'auth_token' | 'api_key';
158
189
  }
159
190
  declare function configureApi(apiConfig: ApiConfig | null): void;
160
191
  declare function mergeConfigs(sourceFile: string, targetFile: string): void;
192
+ declare function applyAiLanguageDirective(aiOutputLang: AiOutputLanguage | string): void;
161
193
 
162
194
  declare function getMcpConfigPath(): string;
163
195
  declare function readMcpConfig(): McpConfiguration | null;
@@ -166,5 +198,5 @@ declare function backupMcpConfig(): string | null;
166
198
  declare function mergeMcpServers(existing: McpConfiguration | null, newServers: Record<string, McpServerConfig>): McpConfiguration;
167
199
  declare function buildMcpServerConfig(baseConfig: McpServerConfig, apiKey?: string, placeholder?: string): McpServerConfig;
168
200
 
169
- export { CLAUDE_DIR, CLAUDE_MD_FILE, I18N, LANG_LABELS, MCP_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, getMcpConfigPath, getPlatform, init, installClaudeCode, isClaudeCodeInstalled, mergeConfigs, mergeMcpServers, readMcpConfig, writeMcpConfig };
170
- export type { ApiConfig, McpConfiguration, McpServerConfig, McpService, SupportedLang };
201
+ export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, I18N, LANG_LABELS, MCP_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, getMcpConfigPath, getPlatform, init, installClaudeCode, isClaudeCodeInstalled, mergeConfigs, mergeMcpServers, readMcpConfig, writeMcpConfig };
202
+ export type { AiOutputLanguage, ApiConfig, McpConfiguration, McpServerConfig, McpService, SupportedLang };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { C as CLAUDE_DIR, a as CLAUDE_MD_FILE, I as I18N, L as LANG_LABELS, M as MCP_CONFIG_FILE, d as MCP_SERVICES, S as SETTINGS_FILE, b as SUPPORTED_LANGS, Z as ZCF_CONFIG_FILE, j as backupExistingConfig, o as backupMcpConfig, q as buildMcpServerConfig, c as commandExists, l as configureApi, k as copyConfigFiles, h as ensureClaudeDir, n as getMcpConfigPath, g as getPlatform, i as init, f as installClaudeCode, e as isClaudeCodeInstalled, m as mergeConfigs, p as mergeMcpServers, r as readMcpConfig, w as writeMcpConfig } from './shared/zcf.3cK6W2AW.mjs';
1
+ export { A as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, a as CLAUDE_MD_FILE, I as I18N, L as LANG_LABELS, M as MCP_CONFIG_FILE, d as MCP_SERVICES, S as SETTINGS_FILE, b as SUPPORTED_LANGS, Z as ZCF_CONFIG_FILE, n as applyAiLanguageDirective, j as backupExistingConfig, p as backupMcpConfig, s as buildMcpServerConfig, c as commandExists, l as configureApi, k as copyConfigFiles, h as ensureClaudeDir, o as getMcpConfigPath, g as getPlatform, i as init, f as installClaudeCode, e as isClaudeCodeInstalled, m as mergeConfigs, q as mergeMcpServers, r as readMcpConfig, w as writeMcpConfig } from './shared/zcf.DK7kfRoM.mjs';
2
2
  import '@posva/prompts';
3
3
  import 'ansis';
4
4
  import 'node:fs';
@@ -6,7 +6,7 @@ import { join, dirname } from 'pathe';
6
6
  import dayjs from 'dayjs';
7
7
  import { exec } from 'tinyexec';
8
8
 
9
- const version = "1.1.2";
9
+ const version = "1.1.4";
10
10
 
11
11
  const CLAUDE_DIR = join(homedir(), ".claude");
12
12
  const SETTINGS_FILE = join(CLAUDE_DIR, "settings.json");
@@ -18,10 +18,18 @@ const LANG_LABELS = {
18
18
  "zh-CN": "\u7B80\u4F53\u4E2D\u6587",
19
19
  en: "English"
20
20
  };
21
+ const AI_OUTPUT_LANGUAGES = {
22
+ "zh-CN": { label: "\u7B80\u4F53\u4E2D\u6587", directive: "Always respond in Chinese-simplified" },
23
+ en: { label: "English", directive: "Always respond in English" },
24
+ custom: { label: "Custom", directive: "" }
25
+ };
21
26
  const I18N = {
22
27
  "zh-CN": {
23
28
  selectScriptLang: "\u9009\u62E9\u811A\u672C\u8BED\u8A00",
24
29
  selectConfigLang: "\u9009\u62E9 Claude Code \u914D\u7F6E\u8BED\u8A00",
30
+ selectAiOutputLang: "\u9009\u62E9 AI \u8F93\u51FA\u8BED\u8A00",
31
+ aiOutputLangHint: "AI \u5C06\u4F7F\u7528\u6B64\u8BED\u8A00\u56DE\u590D\u4F60\u7684\u95EE\u9898",
32
+ enterCustomLanguage: "\u8BF7\u8F93\u5165\u81EA\u5B9A\u4E49\u8BED\u8A00\uFF08\u4F8B\u5982\uFF1AJapanese, French \u7B49\uFF09",
25
33
  configLangHint: {
26
34
  "zh-CN": "\u4E2D\u6587\u7248\uFF08\u4FBF\u4E8E\u4E2D\u6587\u7528\u6237\u81EA\u5B9A\u4E49\uFF09",
27
35
  en: "\u82F1\u6587\u7248\uFF08\u63A8\u8350\uFF0Ctoken \u6D88\u8017\u66F4\u4F4E\uFF09"
@@ -31,10 +39,14 @@ const I18N = {
31
39
  installSuccess: "Claude Code \u5B89\u88C5\u6210\u529F",
32
40
  installFailed: "Claude Code \u5B89\u88C5\u5931\u8D25",
33
41
  npmNotFound: "npm \u672A\u5B89\u88C5\u3002\u8BF7\u5148\u5B89\u88C5 Node.js \u548C npm\u3002",
34
- configureApi: "\u662F\u5426\u914D\u7F6E API\uFF1F",
35
- customApi: "\u914D\u7F6E API",
36
- skipApi: "\u8DF3\u8FC7\uFF08\u7A0D\u540E\u5728 claude \u547D\u4EE4\u4E2D\u81EA\u884C\u914D\u7F6E\uFF0C\u5982 OAuth\uFF09",
42
+ configureApi: "\u9009\u62E9 API \u8BA4\u8BC1\u65B9\u5F0F",
43
+ useAuthToken: "\u4F7F\u7528 Auth Token (OAuth \u8BA4\u8BC1)",
44
+ authTokenDesc: "\u9002\u7528\u4E8E\u901A\u8FC7 OAuth \u6216\u6D4F\u89C8\u5668\u767B\u5F55\u83B7\u53D6\u7684\u4EE4\u724C",
45
+ useApiKey: "\u4F7F\u7528 API Key (\u5BC6\u94A5\u8BA4\u8BC1)",
46
+ apiKeyDesc: "\u9002\u7528\u4E8E\u4ECE Anthropic Console \u83B7\u53D6\u7684 API \u5BC6\u94A5",
47
+ skipApi: "\u8DF3\u8FC7\uFF08\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\uFF09",
37
48
  enterApiUrl: "\u8BF7\u8F93\u5165 API URL",
49
+ enterAuthToken: "\u8BF7\u8F93\u5165 Auth Token",
38
50
  enterApiKey: "\u8BF7\u8F93\u5165 API Key",
39
51
  existingConfig: "\u68C0\u6D4B\u5230\u5DF2\u6709\u914D\u7F6E\u6587\u4EF6\uFF0C\u5982\u4F55\u5904\u7406\uFF1F",
40
52
  backupAndOverwrite: "\u5907\u4EFD\u5E76\u8986\u76D6\u5168\u90E8",
@@ -63,12 +75,15 @@ const I18N = {
63
75
  updateConfigLangPrompt: "\u9009\u62E9\u914D\u7F6E\u8BED\u8A00",
64
76
  updateConfigLangChoice: {
65
77
  "zh-CN": "\u4E2D\u6587\u7248\u914D\u7F6E",
66
- "en": "\u82F1\u6587\u7248\u914D\u7F6E"
78
+ en: "\u82F1\u6587\u7248\u914D\u7F6E"
67
79
  }
68
80
  },
69
81
  en: {
70
82
  selectScriptLang: "Select script language",
71
83
  selectConfigLang: "Select Claude Code configuration language",
84
+ selectAiOutputLang: "Select AI output language",
85
+ aiOutputLangHint: "AI will respond to you in this language",
86
+ enterCustomLanguage: "Enter custom language (e.g., Japanese, French, etc.)",
72
87
  configLangHint: {
73
88
  "zh-CN": "Chinese (easier for Chinese users to customize)",
74
89
  en: "English (recommended, lower token consumption)"
@@ -78,10 +93,14 @@ const I18N = {
78
93
  installSuccess: "Claude Code installed successfully",
79
94
  installFailed: "Failed to install Claude Code",
80
95
  npmNotFound: "npm is not installed. Please install Node.js and npm first.",
81
- configureApi: "Configure API?",
82
- customApi: "Configure API",
83
- skipApi: "Skip (configure later in claude command, e.g., OAuth)",
96
+ configureApi: "Select API authentication method",
97
+ useAuthToken: "Use Auth Token (OAuth authentication)",
98
+ authTokenDesc: "For tokens obtained via OAuth or browser login",
99
+ useApiKey: "Use API Key (Key authentication)",
100
+ apiKeyDesc: "For API keys from Anthropic Console",
101
+ skipApi: "Skip (configure manually later)",
84
102
  enterApiUrl: "Enter API URL",
103
+ enterAuthToken: "Enter Auth Token",
85
104
  enterApiKey: "Enter API Key",
86
105
  existingConfig: "Existing config detected. How to proceed?",
87
106
  backupAndOverwrite: "Backup and overwrite all",
@@ -110,7 +129,7 @@ const I18N = {
110
129
  updateConfigLangPrompt: "Select configuration language",
111
130
  updateConfigLangChoice: {
112
131
  "zh-CN": "Chinese configuration",
113
- "en": "English configuration"
132
+ en: "English configuration"
114
133
  }
115
134
  }
116
135
  };
@@ -238,6 +257,7 @@ function copyConfigFiles(lang, onlyMd = false) {
238
257
  const distDir = dirname(dirname(currentFilePath));
239
258
  const rootDir = dirname(distDir);
240
259
  const sourceDir = join(rootDir, "templates", lang);
260
+ const baseTemplateDir = join(rootDir, "templates");
241
261
  if (!existsSync(sourceDir)) {
242
262
  throw new Error(`Template directory not found: ${sourceDir}`);
243
263
  }
@@ -245,6 +265,11 @@ function copyConfigFiles(lang, onlyMd = false) {
245
265
  copyMdFiles(sourceDir, CLAUDE_DIR);
246
266
  } else {
247
267
  copyDirectory(sourceDir, CLAUDE_DIR);
268
+ const baseSettingsPath = join(baseTemplateDir, "settings.json");
269
+ const destSettingsPath = join(CLAUDE_DIR, "settings.json");
270
+ if (existsSync(baseSettingsPath)) {
271
+ copyFileSync(baseSettingsPath, destSettingsPath);
272
+ }
248
273
  }
249
274
  }
250
275
  function copyMdFiles(src, dest) {
@@ -269,6 +294,9 @@ function copyDirectory(src, dest) {
269
294
  }
270
295
  const entries = readdirSync(src);
271
296
  for (const entry of entries) {
297
+ if (entry === "settings.json") {
298
+ continue;
299
+ }
272
300
  const srcPath = join(src, entry);
273
301
  const destPath = join(dest, entry);
274
302
  const stat = statSync(srcPath);
@@ -318,7 +346,11 @@ function configureApi(apiConfig) {
318
346
  console.error("Failed to parse existing settings.json, using defaults:", error);
319
347
  }
320
348
  }
321
- settings.env.ANTHROPIC_API_KEY = apiConfig.key;
349
+ if (apiConfig.authType === "api_key") {
350
+ settings.env.ANTHROPIC_API_KEY = apiConfig.key;
351
+ } else {
352
+ settings.env.ANTHROPIC_AUTH_TOKEN = apiConfig.key;
353
+ }
322
354
  settings.env.ANTHROPIC_BASE_URL = apiConfig.url;
323
355
  writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2));
324
356
  }
@@ -348,6 +380,30 @@ function deepMerge(target, source) {
348
380
  }
349
381
  return result;
350
382
  }
383
+ function applyAiLanguageDirective(aiOutputLang) {
384
+ if (!existsSync(CLAUDE_MD_FILE)) {
385
+ return;
386
+ }
387
+ let content = readFileSync(CLAUDE_MD_FILE, "utf-8");
388
+ const lines = content.split("\n");
389
+ if (lines[0] && lines[0].startsWith("Always respond in")) {
390
+ lines.shift();
391
+ if (lines[0] === "") {
392
+ lines.shift();
393
+ }
394
+ content = lines.join("\n");
395
+ }
396
+ let directive = "";
397
+ if (aiOutputLang === "custom") {
398
+ return;
399
+ } else if (AI_OUTPUT_LANGUAGES[aiOutputLang]) {
400
+ directive = AI_OUTPUT_LANGUAGES[aiOutputLang].directive;
401
+ } else {
402
+ directive = `Always respond in ${aiOutputLang}`;
403
+ }
404
+ const newContent = directive + "\n\n" + content;
405
+ writeFileSync(CLAUDE_MD_FILE, newContent, "utf-8");
406
+ }
351
407
 
352
408
  function getPlatform() {
353
409
  const p = platform();
@@ -470,18 +526,99 @@ function updateZcfConfig(updates) {
470
526
  const newConfig = {
471
527
  version: updates.version || existingConfig?.version || "1.0.0",
472
528
  preferredLang: updates.preferredLang || existingConfig?.preferredLang || "en",
529
+ aiOutputLang: updates.aiOutputLang || existingConfig?.aiOutputLang,
473
530
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
474
531
  };
475
532
  writeZcfConfig(newConfig);
476
533
  }
477
534
 
478
- async function updatePromptOnly(configLang, scriptLang) {
535
+ async function selectAiOutputLanguage(scriptLang, defaultLang) {
536
+ const i18n = I18N[scriptLang];
537
+ console.log(ansis.dim(`
538
+ ${i18n.aiOutputLangHint}
539
+ `));
540
+ const aiLangChoices = Object.entries(AI_OUTPUT_LANGUAGES).map(([key, value]) => ({
541
+ title: value.label,
542
+ value: key
543
+ }));
544
+ const defaultChoice = defaultLang || (scriptLang === "zh-CN" ? "zh-CN" : "en");
545
+ const aiLangResponse = await prompts({
546
+ type: "select",
547
+ name: "lang",
548
+ message: i18n.selectAiOutputLang,
549
+ choices: aiLangChoices,
550
+ initial: aiLangChoices.findIndex((c) => c.value === defaultChoice)
551
+ });
552
+ if (!aiLangResponse.lang) {
553
+ console.log(ansis.yellow(i18n.cancelled));
554
+ process.exit(0);
555
+ }
556
+ let aiOutputLang = aiLangResponse.lang;
557
+ if (aiOutputLang === "custom") {
558
+ const customLangResponse = await prompts({
559
+ type: "text",
560
+ name: "customLang",
561
+ message: i18n.enterCustomLanguage,
562
+ validate: (value) => !!value || "Language is required"
563
+ });
564
+ if (!customLangResponse.customLang) {
565
+ console.log(ansis.yellow(i18n.cancelled));
566
+ process.exit(0);
567
+ }
568
+ return customLangResponse.customLang;
569
+ }
570
+ return aiOutputLang;
571
+ }
572
+ async function selectScriptLanguage(currentLang) {
573
+ const zcfConfig = readZcfConfig();
574
+ if (zcfConfig?.preferredLang) {
575
+ return zcfConfig.preferredLang;
576
+ }
577
+ if (currentLang) {
578
+ return currentLang;
579
+ }
580
+ const response = await prompts({
581
+ type: "select",
582
+ name: "lang",
583
+ message: "Select script language / \u9009\u62E9\u811A\u672C\u8BED\u8A00",
584
+ choices: SUPPORTED_LANGS.map((l) => ({
585
+ title: LANG_LABELS[l],
586
+ value: l
587
+ }))
588
+ });
589
+ if (!response.lang) {
590
+ console.log(ansis.yellow("Operation cancelled / \u64CD\u4F5C\u5DF2\u53D6\u6D88"));
591
+ process.exit(0);
592
+ }
593
+ const scriptLang = response.lang;
594
+ updateZcfConfig({
595
+ version,
596
+ preferredLang: scriptLang
597
+ });
598
+ return scriptLang;
599
+ }
600
+ async function resolveAiOutputLanguage(scriptLang, commandLineOption, savedConfig) {
601
+ const i18n = I18N[scriptLang];
602
+ if (commandLineOption) {
603
+ return commandLineOption;
604
+ }
605
+ if (savedConfig?.aiOutputLang) {
606
+ console.log(ansis.gray(`\u2714 ${i18n.aiOutputLangHint}: ${savedConfig.aiOutputLang}`));
607
+ return savedConfig.aiOutputLang;
608
+ }
609
+ return await selectAiOutputLanguage(scriptLang, scriptLang);
610
+ }
611
+
612
+ async function updatePromptOnly(configLang, scriptLang, aiOutputLang) {
479
613
  const i18n = I18N[scriptLang];
480
614
  const backupDir = backupExistingConfig();
481
615
  if (backupDir) {
482
616
  console.log(ansis.gray(`\u2714 ${i18n.backupSuccess}: ${backupDir}`));
483
617
  }
484
618
  copyConfigFiles(configLang, true);
619
+ if (aiOutputLang) {
620
+ applyAiLanguageDirective(aiOutputLang);
621
+ }
485
622
  console.log(ansis.green(`\u2714 ${i18n.configSuccess} ${CLAUDE_DIR}`));
486
623
  console.log("\n" + ansis.cyan(i18n.complete));
487
624
  }
@@ -490,27 +627,7 @@ async function init(options = {}) {
490
627
  displayBanner();
491
628
  console.log(ansis.gray(` Version: ${ansis.cyan(version)} | ${ansis.cyan("https://github.com/UfoMiao/zcf")}
492
629
  `));
493
- let scriptLang = options.lang;
494
- if (!scriptLang) {
495
- const response = await prompts({
496
- type: "select",
497
- name: "lang",
498
- message: "Select script language / \u9009\u62E9\u811A\u672C\u8BED\u8A00",
499
- choices: SUPPORTED_LANGS.map((l) => ({
500
- title: LANG_LABELS[l],
501
- value: l
502
- }))
503
- });
504
- if (!response.lang) {
505
- console.log(ansis.yellow("\u64CD\u4F5C\u5DF2\u53D6\u6D88 / Operation cancelled"));
506
- process.exit(0);
507
- }
508
- scriptLang = response.lang;
509
- }
510
- if (!scriptLang) {
511
- console.error(ansis.red("Language not selected"));
512
- process.exit(1);
513
- }
630
+ const scriptLang = await selectScriptLanguage(options.lang);
514
631
  const i18n = I18N[scriptLang];
515
632
  let configLang = options.configLang;
516
633
  if (!configLang) {
@@ -529,6 +646,8 @@ async function init(options = {}) {
529
646
  }
530
647
  configLang = response.lang;
531
648
  }
649
+ const zcfConfig = readZcfConfig();
650
+ const aiOutputLang = await resolveAiOutputLanguage(scriptLang, options.aiOutputLang, zcfConfig);
532
651
  const installed = await isClaudeCodeInstalled();
533
652
  if (!installed) {
534
653
  const response = await prompts({
@@ -585,8 +704,20 @@ async function init(options = {}) {
585
704
  name: "apiChoice",
586
705
  message: i18n.configureApi,
587
706
  choices: [
588
- { title: i18n.customApi, value: "custom" },
589
- { title: i18n.skipApi, value: "skip" }
707
+ {
708
+ title: i18n.useAuthToken,
709
+ value: "auth_token",
710
+ description: ansis.gray(i18n.authTokenDesc)
711
+ },
712
+ {
713
+ title: i18n.useApiKey,
714
+ value: "api_key",
715
+ description: ansis.gray(i18n.apiKeyDesc)
716
+ },
717
+ {
718
+ title: i18n.skipApi,
719
+ value: "skip"
720
+ }
590
721
  ]
591
722
  });
592
723
  if (!apiResponse.apiChoice) {
@@ -594,7 +725,7 @@ async function init(options = {}) {
594
725
  process.exit(0);
595
726
  }
596
727
  const apiChoice = apiResponse.apiChoice;
597
- if (apiChoice === "custom") {
728
+ if (apiChoice === "auth_token" || apiChoice === "api_key") {
598
729
  const urlResponse = await prompts({
599
730
  type: "text",
600
731
  name: "url",
@@ -614,18 +745,19 @@ async function init(options = {}) {
614
745
  process.exit(0);
615
746
  }
616
747
  const url = urlResponse.url;
748
+ const keyMessage = apiChoice === "auth_token" ? i18n.enterAuthToken : i18n.enterApiKey;
617
749
  const keyResponse = await prompts({
618
750
  type: "text",
619
751
  name: "key",
620
- message: i18n.enterApiKey,
621
- validate: (value) => !!value || "API Key is required"
752
+ message: keyMessage,
753
+ validate: (value) => !!value || `${apiChoice === "auth_token" ? "Auth Token" : "API Key"} is required`
622
754
  });
623
755
  if (keyResponse.key === void 0) {
624
756
  console.log(ansis.yellow(i18n.cancelled));
625
757
  process.exit(0);
626
758
  }
627
759
  const key = keyResponse.key;
628
- apiConfig = { url, key };
760
+ apiConfig = { url, key, authType: apiChoice };
629
761
  }
630
762
  }
631
763
  if (action === "backup") {
@@ -649,6 +781,7 @@ async function init(options = {}) {
649
781
  } else if (action === "new") {
650
782
  copyConfigFiles(configLang, false);
651
783
  }
784
+ applyAiLanguageDirective(aiOutputLang);
652
785
  if (apiConfig && !onlyUpdateDocs) {
653
786
  configureApi(apiConfig);
654
787
  console.log(ansis.green(`\u2714 ${i18n.apiConfigSuccess}`));
@@ -735,7 +868,8 @@ async function init(options = {}) {
735
868
  }
736
869
  updateZcfConfig({
737
870
  version,
738
- preferredLang: scriptLang
871
+ preferredLang: scriptLang,
872
+ aiOutputLang
739
873
  });
740
874
  console.log(ansis.green(`\u2714 ${i18n.configSuccess} ${CLAUDE_DIR}`));
741
875
  console.log("\n" + ansis.cyan(i18n.complete));
@@ -745,4 +879,4 @@ async function init(options = {}) {
745
879
  }
746
880
  }
747
881
 
748
- export { CLAUDE_DIR as C, I18N as I, LANG_LABELS as L, MCP_CONFIG_FILE as M, SETTINGS_FILE as S, ZCF_CONFIG_FILE as Z, CLAUDE_MD_FILE as a, SUPPORTED_LANGS as b, commandExists as c, MCP_SERVICES as d, isClaudeCodeInstalled as e, installClaudeCode as f, getPlatform as g, ensureClaudeDir as h, init as i, backupExistingConfig as j, copyConfigFiles as k, configureApi as l, mergeConfigs as m, getMcpConfigPath as n, backupMcpConfig as o, mergeMcpServers as p, buildMcpServerConfig as q, readMcpConfig as r, displayBanner as s, readZcfConfig as t, updateZcfConfig as u, version as v, writeMcpConfig as w, updatePromptOnly as x };
882
+ export { AI_OUTPUT_LANGUAGES as A, version as B, CLAUDE_DIR as C, I18N as I, LANG_LABELS as L, MCP_CONFIG_FILE as M, SETTINGS_FILE as S, ZCF_CONFIG_FILE as Z, CLAUDE_MD_FILE as a, SUPPORTED_LANGS as b, commandExists as c, MCP_SERVICES as d, isClaudeCodeInstalled as e, installClaudeCode as f, getPlatform as g, ensureClaudeDir as h, init as i, backupExistingConfig as j, copyConfigFiles as k, configureApi as l, mergeConfigs as m, applyAiLanguageDirective as n, getMcpConfigPath as o, backupMcpConfig as p, mergeMcpServers as q, readMcpConfig as r, buildMcpServerConfig as s, displayBanner as t, selectScriptLanguage as u, readZcfConfig as v, writeMcpConfig as w, resolveAiOutputLanguage as x, updatePromptOnly as y, updateZcfConfig as z };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zcf",
3
3
  "type": "module",
4
- "version": "1.1.2",
4
+ "version": "1.1.4",
5
5
  "description": "Zero-Config Claude-Code Flow - One-click configuration tool for Claude Code",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/UfoMiao/zcf#readme",
@@ -1,5 +1,3 @@
1
- Always respond in Chinese-simplified
2
-
3
1
  You are an experienced [professional domain, e.g., Software Development Engineer / System Designer / Code Architect], specializing in building [core strengths, e.g., high-performance / maintainable / robust / domain-driven] solutions.
4
2
 
5
3
  Your mission is: **Review, understand, and iteratively improve/advance a [project type, e.g., existing codebase / software project / technical process].**
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
3
- "env": {},
3
+ "env": {
4
+ "DISABLE_TELEMETRY": "1",
5
+ "DISABLE_ERROR_REPORTING": "1",
6
+ "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
7
+ },
4
8
  "includeCoAuthoredBy": false,
5
9
  "permissions": {
6
10
  "allow": [
@@ -22,4 +26,4 @@
22
26
  },
23
27
  "hooks": {},
24
28
  "model": "opus"
25
- }
29
+ }
@@ -1,5 +1,3 @@
1
- Always respond in Chinese-simplified
2
-
3
1
  你是一名经验丰富的[专业领域,例如:软件开发工程师 / 系统设计师 / 代码架构师],专注于构建[核心特长,例如:高性能 / 可维护 / 健壮 / 领域驱动]的解决方案。
4
2
 
5
3
  你的任务是:**审查、理解并迭代式地改进/推进一个[项目类型,例如:现有代码库 / 软件项目 / 技术流程]。**
@@ -1,25 +0,0 @@
1
- {
2
- "$schema": "https://json.schemastore.org/claude-code-settings.json",
3
- "env": {},
4
- "includeCoAuthoredBy": false,
5
- "permissions": {
6
- "allow": [
7
- "Bash(*)",
8
- "LS(*)",
9
- "Read(*)",
10
- "Write(*)",
11
- "Edit(*)",
12
- "MultiEdit(*)",
13
- "Glob(*)",
14
- "Grep(*)",
15
- "WebFetch(*)",
16
- "WebSearch(*)",
17
- "TodoWrite(*)",
18
- "NotebookRead(*)",
19
- "NotebookEdit(*)"
20
- ],
21
- "deny": []
22
- },
23
- "hooks": {},
24
- "model": "opus"
25
- }