zcf 1.0.2 → 1.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
@@ -7,10 +7,12 @@
7
7
  ## 🚀 快速开始
8
8
 
9
9
  ```bash
10
- npx zcf
10
+ npx zcf # 初始化配置(默认)
11
+ npx zcf u # 更新 Prompt 文档并备份旧配置(update 缩写)
11
12
  ```
12
13
 
13
- 运行后会自动:
14
+ 初始化后会自动:
15
+
14
16
  - 检测并安装 Claude Code
15
17
  - 配置 API 密钥
16
18
  - 选择并配置 MCP 服务
@@ -20,40 +22,45 @@ npx zcf
20
22
 
21
23
  配置完成后:
22
24
 
23
- - **项目第一次使用强烈建议先运行 `/init` 进行初始化,生成 CLAUDE.md 便于 AI 理解项目架构**
24
- - `<任务描述>` - 不使用任何工作流直接执行,会遵循 SOLID、KISS、DRY 和 YAGNI 原则,适合修复 Bug 等小任务
25
- - `/feat <任务描述>` - 开始新功能开发,分为 plan 和 ui 两个阶段
26
- - `/workflow <任务描述>` - 执行完整开发工作流,不是自动化,开始会给出多套方案,每一步会询问用户意见,可随时修改方案,掌控力 MAX
25
+ - **项目第一次使用强烈建议先运行 `/init` 进行初始化,生成 CLAUDE.md 便于 AI 理解项目架构**
26
+ - `<任务描述>` - 不使用任何工作流直接执行,会遵循 SOLID、KISS、DRY 和 YAGNI 原则,适合修复 Bug 等小任务
27
+ - `/feat <任务描述>` - 开始新功能开发,分为 plan 和 ui 两个阶段
28
+ - `/workflow <任务描述>` - 执行完整开发工作流,不是自动化,开始会给出多套方案,每一步会询问用户意见,可随时修改方案,掌控力 MAX
27
29
 
28
- > **PS**:
29
- >
30
- > - feat 和 workflow 这两套各有优势,可以都试试比较一下
31
- > - 生成的文档位置默认都是项目根目录下的 `.claude/xxx.md`,可以把 `.claude/` 加入项目的 `.gitignore` 里
30
+ > **PS**:
31
+ >
32
+ > - feat 和 workflow 这两套各有优势,可以都试试比较一下
33
+ > - 生成的文档位置默认都是项目根目录下的 `.claude/xxx.md`,可以把 `.claude/` 加入项目的 `.gitignore` 里
32
34
 
33
35
  ## ✨ ZCF 工具特性
34
36
 
35
37
  ### 🌏 双语支持
38
+
36
39
  - 脚本交互语言:控制安装过程的提示语言
37
40
  - 配置文件语言:决定安装哪套配置文件(zh-CN/en)
38
41
 
39
42
  ### 🔧 智能安装
43
+
40
44
  - 自动检测 Claude Code 安装状态
41
- - 支持 npm/yarn/pnpm 包管理器
45
+ - 使用 npm 进行自动安装(确保兼容性)
42
46
  - 跨平台支持(Windows/macOS/Linux)
43
47
  - 自动配置 MCP 服务(新增)
44
48
 
45
49
  ### 📦 完整配置
50
+
46
51
  - CLAUDE.md 系统指令
47
52
  - settings.json 设置文件
48
53
  - commands 自定义命令
49
54
  - agents AI 代理配置
50
55
 
51
56
  ### 🔐 API 配置
57
+
52
58
  - 自定义 API 支持
53
59
  - API Key 自动配置
54
60
  - 支持稍后在 claude 命令中配置(如 OAuth)
55
61
 
56
62
  ### 💾 配置管理
63
+
57
64
  - 智能备份现有配置(所有备份保存在 ~/.claude/backup/)
58
65
  - 配置合并选项
59
66
  - 安全的覆盖机制
@@ -113,18 +120,53 @@ $ npx zcf
113
120
 
114
121
  ### 命令行参数
115
122
 
123
+ #### 命令速查表
124
+
125
+ | 命令 | 缩写 | 说明 |
126
+ | ------------ | ------- | ---------------------- |
127
+ | `zcf` | - | 初始化配置(默认命令) |
128
+ | `zcf update` | `zcf u` | 更新 Prompt 文档并备份旧配置 |
129
+
130
+ #### 常用选项
131
+
116
132
  ```bash
117
133
  # 指定配置语言
118
134
  npx zcf --config-lang zh-CN
135
+ npx zcf -c zh-CN # 使用缩写
119
136
 
120
137
  # 强制覆盖现有配置
121
138
  npx zcf --force
139
+ npx zcf -f # 使用缩写
122
140
 
123
- # 跳过 Claude Code 安装检测
124
- npx zcf --skip-install
141
+ # 更新 Prompt 文档并备份旧配置(保留 API 和 MCP 配置)
142
+ npx zcf u # 使用 update 命令
143
+ npx zcf update # 完整命令
125
144
 
126
- # 帮助信息
145
+ # 查看帮助信息
127
146
  npx zcf --help
147
+ npx zcf -h
148
+
149
+ # 查看版本
150
+ npx zcf --version
151
+ npx zcf -v
152
+ ```
153
+
154
+ #### 使用示例
155
+
156
+ ```bash
157
+ # 首次安装,交互式配置
158
+ npx zcf
159
+
160
+ # 更新 Prompt 文档并备份旧配置,保留 API 和 MCP 配置
161
+ npx zcf u
162
+
163
+ # 强制使用中文配置重新初始化
164
+ npx zcf --config-lang zh-CN --force
165
+ npx zcf -c zh-CN -f # 使用缩写
166
+
167
+ # 更新到英文版 Prompt(降低 token 消耗)
168
+ npx zcf u --config-lang en
169
+ npx zcf u -c en # 使用缩写
128
170
  ```
129
171
 
130
172
  ## 📁 项目结构
@@ -190,8 +232,8 @@ claude-code-config/
190
232
 
191
233
  ```bash
192
234
  # 克隆项目
193
- git clone https://github.com/UfoMiao/claude-code-config.git
194
- cd claude-code-config
235
+ git clone https://github.com/UfoMiao/zcf.git
236
+ cd zcf
195
237
 
196
238
  # 安装依赖(使用 pnpm)
197
239
  pnpm install
@@ -235,4 +277,4 @@ MIT 许可证
235
277
 
236
278
  如果这个项目对你有帮助,请给我一个 ⭐️ Star!
237
279
 
238
- [![Star History Chart](https://api.star-history.com/svg?repos=UfoMiao/claude-code-config&type=Date)](https://star-history.com/#UfoMiao/claude-code-config&Date)
280
+ [![Star History Chart](https://api.star-history.com/svg?repos=UfoMiao/claude-code-config&type=Date)](https://star-history.com/#UfoMiao/claude-code-config&Date)
package/dist/cli.mjs CHANGED
@@ -1,25 +1,133 @@
1
1
  #!/usr/bin/env node
2
2
  import cac from 'cac';
3
- import { i as init } from './shared/zcf.C2Q2uOcq.mjs';
4
- import '@posva/prompts';
5
- import 'ansis';
6
- import 'node:fs';
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.S0xKCxNQ.mjs';
5
+ import prompts from '@posva/prompts';
6
+ import { existsSync } from 'node:fs';
7
7
  import 'node:os';
8
8
  import 'pathe';
9
9
  import 'dayjs';
10
10
  import 'tinyexec';
11
11
 
12
- const version = "1.0.2";
12
+ async function update(options = {}) {
13
+ try {
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
+ }
39
+ const i18n = I18N[scriptLang];
40
+ if (!existsSync(SETTINGS_FILE)) {
41
+ console.log(ansis.yellow(i18n.noExistingConfig));
42
+ process.exit(1);
43
+ }
44
+ let configLang = options.configLang;
45
+ if (!configLang) {
46
+ console.log(ansis.dim(` ${i18n.configLangHint["zh-CN"]}`));
47
+ console.log(ansis.dim(` ${i18n.configLangHint["en"]}
48
+ `));
49
+ const configResponse = await prompts({
50
+ type: "select",
51
+ name: "lang",
52
+ message: i18n.updateConfigLangPrompt,
53
+ choices: SUPPORTED_LANGS.map((l) => ({
54
+ title: `${LANG_LABELS[l]} - ${i18n.configLangHint[l]}`,
55
+ value: l
56
+ }))
57
+ });
58
+ if (!configResponse.lang) {
59
+ console.log(ansis.yellow(i18n.cancelled));
60
+ process.exit(0);
61
+ }
62
+ configLang = configResponse.lang;
63
+ }
64
+ console.log(ansis.cyan(`
65
+ ${i18n.updatingPrompts}
66
+ `));
67
+ await updatePromptOnly(configLang, scriptLang);
68
+ updateZcfConfig({
69
+ version,
70
+ preferredLang: scriptLang
71
+ });
72
+ } catch (error) {
73
+ const zcfConfig = readZcfConfig();
74
+ const defaultLang = zcfConfig?.preferredLang || "en";
75
+ const errorMsg = I18N[defaultLang].error;
76
+ console.error(ansis.red(`${errorMsg}:`), error);
77
+ process.exit(1);
78
+ }
79
+ }
13
80
 
14
81
  const cli = cac("zcf");
15
- cli.command("[lang]", "Initialize Claude Code configuration").option("--config-lang <lang>", "Configuration language (zh-CN, en)").option("--force", "Force overwrite existing configuration").option("--skip-install", "Skip Claude Code installation check").action(async (lang, options) => {
82
+ cli.command("[lang]", "Initialize Claude Code configuration (default)").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").option("--force, -f", "Force overwrite existing configuration").action(async (lang, options) => {
16
83
  await init({
17
84
  lang: lang || options.lang,
18
85
  configLang: options.configLang,
19
- force: options.force,
20
- skipInstall: options.skipInstall
86
+ force: options.force
21
87
  });
22
88
  });
23
- cli.help();
89
+ cli.command("update", "Update Claude Code prompts only").alias("u").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").action(async (options) => {
90
+ await update({ configLang: options.configLang });
91
+ });
92
+ cli.help((sections) => {
93
+ sections.unshift({
94
+ title: "",
95
+ body: ansis.cyan.bold(`ZCF - Zero-Config Claude-Code Flow v${version}`)
96
+ });
97
+ sections.push({
98
+ title: ansis.yellow("Commands:"),
99
+ body: [
100
+ ` ${ansis.cyan("zcf")} Initialize configuration (default)`,
101
+ ` ${ansis.cyan("zcf update")} | ${ansis.cyan("u")} Update prompts only with backup`,
102
+ "",
103
+ ansis.gray(" Shortcut:"),
104
+ ` ${ansis.cyan("zcf u")} Quick update`
105
+ ].join("\n")
106
+ });
107
+ sections.push({
108
+ title: ansis.yellow("Options:"),
109
+ body: [
110
+ ` ${ansis.green("--config-lang, -c")} <lang> Configuration language (zh-CN, en)`,
111
+ ` ${ansis.green("--force, -f")} Force overwrite existing configuration`,
112
+ ` ${ansis.green("--help, -h")} Display help`,
113
+ ` ${ansis.green("--version, -v")} Display version`
114
+ ].join("\n")
115
+ });
116
+ sections.push({
117
+ title: ansis.yellow("Examples:"),
118
+ body: [
119
+ ansis.gray(" # Initialize with interactive prompts"),
120
+ ` ${ansis.cyan("npx zcf")}`,
121
+ "",
122
+ ansis.gray(" # Update prompts only"),
123
+ ` ${ansis.cyan("npx zcf u")}`,
124
+ "",
125
+ ansis.gray(" # Force overwrite with Chinese config"),
126
+ ` ${ansis.cyan("npx zcf -c zh-CN -f")}`,
127
+ ` ${ansis.cyan("npx zcf --config-lang zh-CN --force")}`
128
+ ].join("\n")
129
+ });
130
+ return sections;
131
+ });
24
132
  cli.version(version);
25
133
  cli.parse();
package/dist/index.d.mts CHANGED
@@ -31,8 +31,9 @@ declare const CLAUDE_DIR: string;
31
31
  declare const SETTINGS_FILE: string;
32
32
  declare const CLAUDE_MD_FILE: string;
33
33
  declare const MCP_CONFIG_FILE: string;
34
+ declare const ZCF_CONFIG_FILE: string;
34
35
  declare const SUPPORTED_LANGS: readonly ["zh-CN", "en"];
35
- type SupportedLang = typeof SUPPORTED_LANGS[number];
36
+ type SupportedLang = (typeof SUPPORTED_LANGS)[number];
36
37
  declare const LANG_LABELS: {
37
38
  readonly 'zh-CN': "简体中文";
38
39
  readonly en: "English";
@@ -50,7 +51,6 @@ declare const I18N: {
50
51
  installSuccess: string;
51
52
  installFailed: string;
52
53
  npmNotFound: string;
53
- windowsRestartHint: string;
54
54
  configureApi: string;
55
55
  customApi: string;
56
56
  skipApi: string;
@@ -77,6 +77,14 @@ declare const I18N: {
77
77
  error: string;
78
78
  yes: string;
79
79
  no: string;
80
+ cancelled: string;
81
+ noExistingConfig: string;
82
+ updatingPrompts: string;
83
+ updateConfigLangPrompt: string;
84
+ updateConfigLangChoice: {
85
+ 'zh-CN': string;
86
+ en: string;
87
+ };
80
88
  };
81
89
  en: {
82
90
  selectScriptLang: string;
@@ -90,7 +98,6 @@ declare const I18N: {
90
98
  installSuccess: string;
91
99
  installFailed: string;
92
100
  npmNotFound: string;
93
- windowsRestartHint: string;
94
101
  configureApi: string;
95
102
  customApi: string;
96
103
  skipApi: string;
@@ -117,6 +124,14 @@ declare const I18N: {
117
124
  error: string;
118
125
  yes: string;
119
126
  no: string;
127
+ cancelled: string;
128
+ noExistingConfig: string;
129
+ updatingPrompts: string;
130
+ updateConfigLangPrompt: string;
131
+ updateConfigLangChoice: {
132
+ 'zh-CN': string;
133
+ en: string;
134
+ };
120
135
  };
121
136
  };
122
137
  declare const MCP_SERVICES: McpService[];
@@ -125,7 +140,6 @@ interface InitOptions {
125
140
  lang?: SupportedLang;
126
141
  configLang?: SupportedLang;
127
142
  force?: boolean;
128
- skipInstall?: boolean;
129
143
  }
130
144
  declare function init(options?: InitOptions): Promise<void>;
131
145
 
@@ -152,5 +166,5 @@ declare function backupMcpConfig(): string | null;
152
166
  declare function mergeMcpServers(existing: McpConfiguration | null, newServers: Record<string, McpServerConfig>): McpConfiguration;
153
167
  declare function buildMcpServerConfig(baseConfig: McpServerConfig, apiKey?: string, placeholder?: string): McpServerConfig;
154
168
 
155
- export { CLAUDE_DIR, CLAUDE_MD_FILE, I18N, LANG_LABELS, MCP_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, getMcpConfigPath, getPlatform, init, installClaudeCode, isClaudeCodeInstalled, mergeConfigs, mergeMcpServers, readMcpConfig, writeMcpConfig };
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 };
156
170
  export type { ApiConfig, McpConfiguration, McpServerConfig, McpService, SupportedLang };
package/dist/index.d.ts CHANGED
@@ -31,8 +31,9 @@ declare const CLAUDE_DIR: string;
31
31
  declare const SETTINGS_FILE: string;
32
32
  declare const CLAUDE_MD_FILE: string;
33
33
  declare const MCP_CONFIG_FILE: string;
34
+ declare const ZCF_CONFIG_FILE: string;
34
35
  declare const SUPPORTED_LANGS: readonly ["zh-CN", "en"];
35
- type SupportedLang = typeof SUPPORTED_LANGS[number];
36
+ type SupportedLang = (typeof SUPPORTED_LANGS)[number];
36
37
  declare const LANG_LABELS: {
37
38
  readonly 'zh-CN': "简体中文";
38
39
  readonly en: "English";
@@ -50,7 +51,6 @@ declare const I18N: {
50
51
  installSuccess: string;
51
52
  installFailed: string;
52
53
  npmNotFound: string;
53
- windowsRestartHint: string;
54
54
  configureApi: string;
55
55
  customApi: string;
56
56
  skipApi: string;
@@ -77,6 +77,14 @@ declare const I18N: {
77
77
  error: string;
78
78
  yes: string;
79
79
  no: string;
80
+ cancelled: string;
81
+ noExistingConfig: string;
82
+ updatingPrompts: string;
83
+ updateConfigLangPrompt: string;
84
+ updateConfigLangChoice: {
85
+ 'zh-CN': string;
86
+ en: string;
87
+ };
80
88
  };
81
89
  en: {
82
90
  selectScriptLang: string;
@@ -90,7 +98,6 @@ declare const I18N: {
90
98
  installSuccess: string;
91
99
  installFailed: string;
92
100
  npmNotFound: string;
93
- windowsRestartHint: string;
94
101
  configureApi: string;
95
102
  customApi: string;
96
103
  skipApi: string;
@@ -117,6 +124,14 @@ declare const I18N: {
117
124
  error: string;
118
125
  yes: string;
119
126
  no: string;
127
+ cancelled: string;
128
+ noExistingConfig: string;
129
+ updatingPrompts: string;
130
+ updateConfigLangPrompt: string;
131
+ updateConfigLangChoice: {
132
+ 'zh-CN': string;
133
+ en: string;
134
+ };
120
135
  };
121
136
  };
122
137
  declare const MCP_SERVICES: McpService[];
@@ -125,7 +140,6 @@ interface InitOptions {
125
140
  lang?: SupportedLang;
126
141
  configLang?: SupportedLang;
127
142
  force?: boolean;
128
- skipInstall?: boolean;
129
143
  }
130
144
  declare function init(options?: InitOptions): Promise<void>;
131
145
 
@@ -152,5 +166,5 @@ declare function backupMcpConfig(): string | null;
152
166
  declare function mergeMcpServers(existing: McpConfiguration | null, newServers: Record<string, McpServerConfig>): McpConfiguration;
153
167
  declare function buildMcpServerConfig(baseConfig: McpServerConfig, apiKey?: string, placeholder?: string): McpServerConfig;
154
168
 
155
- export { CLAUDE_DIR, CLAUDE_MD_FILE, I18N, LANG_LABELS, MCP_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, getMcpConfigPath, getPlatform, init, installClaudeCode, isClaudeCodeInstalled, mergeConfigs, mergeMcpServers, readMcpConfig, writeMcpConfig };
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 };
156
170
  export type { 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, 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.C2Q2uOcq.mjs';
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.S0xKCxNQ.mjs';
2
2
  import '@posva/prompts';
3
3
  import 'ansis';
4
4
  import 'node:fs';
@@ -6,14 +6,17 @@ import { join, dirname } from 'pathe';
6
6
  import dayjs from 'dayjs';
7
7
  import { exec } from 'tinyexec';
8
8
 
9
+ const version = "1.1.0";
10
+
9
11
  const CLAUDE_DIR = join(homedir(), ".claude");
10
12
  const SETTINGS_FILE = join(CLAUDE_DIR, "settings.json");
11
13
  const CLAUDE_MD_FILE = join(CLAUDE_DIR, "CLAUDE.md");
12
14
  const MCP_CONFIG_FILE = join(homedir(), ".claude.json");
15
+ const ZCF_CONFIG_FILE = join(homedir(), ".zcf.json");
13
16
  const SUPPORTED_LANGS = ["zh-CN", "en"];
14
17
  const LANG_LABELS = {
15
18
  "zh-CN": "\u7B80\u4F53\u4E2D\u6587",
16
- "en": "English"
19
+ en: "English"
17
20
  };
18
21
  const I18N = {
19
22
  "zh-CN": {
@@ -21,14 +24,13 @@ const I18N = {
21
24
  selectConfigLang: "\u9009\u62E9 Claude Code \u914D\u7F6E\u8BED\u8A00",
22
25
  configLangHint: {
23
26
  "zh-CN": "\u4E2D\u6587\u7248\uFF08\u4FBF\u4E8E\u4E2D\u6587\u7528\u6237\u81EA\u5B9A\u4E49\uFF09",
24
- "en": "\u82F1\u6587\u7248\uFF08\u63A8\u8350\uFF0Ctoken \u6D88\u8017\u66F4\u4F4E\uFF09"
27
+ en: "\u82F1\u6587\u7248\uFF08\u63A8\u8350\uFF0Ctoken \u6D88\u8017\u66F4\u4F4E\uFF09"
25
28
  },
26
29
  installPrompt: "\u68C0\u6D4B\u5230 Claude Code \u672A\u5B89\u88C5\uFF0C\u662F\u5426\u81EA\u52A8\u5B89\u88C5\uFF1F",
27
30
  installing: "\u6B63\u5728\u5B89\u88C5 Claude Code...",
28
31
  installSuccess: "Claude Code \u5B89\u88C5\u6210\u529F",
29
32
  installFailed: "Claude Code \u5B89\u88C5\u5931\u8D25",
30
33
  npmNotFound: "npm \u672A\u5B89\u88C5\u3002\u8BF7\u5148\u5B89\u88C5 Node.js \u548C npm\u3002",
31
- windowsRestartHint: "\u26A0 Windows \u7CFB\u7EDF\u8BF7\u91CD\u65B0\u6253\u5F00\u4E00\u4E2A\u65B0\u7684\u7EC8\u7AEF\u7A97\u53E3\uFF08cmd/PowerShell\uFF09\uFF0C\u7136\u540E\u8FD0\u884C claude \u547D\u4EE4",
32
34
  configureApi: "\u662F\u5426\u914D\u7F6E API\uFF1F",
33
35
  customApi: "\u914D\u7F6E API",
34
36
  skipApi: "\u8DF3\u8FC7\uFF08\u7A0D\u540E\u5728 claude \u547D\u4EE4\u4E2D\u81EA\u884C\u914D\u7F6E\uFF0C\u5982 OAuth\uFF09",
@@ -54,21 +56,28 @@ const I18N = {
54
56
  complete: "\u{1F389} \u914D\u7F6E\u5B8C\u6210\uFF01\u4F7F\u7528 'claude' \u547D\u4EE4\u5F00\u59CB\u4F53\u9A8C\u3002",
55
57
  error: "\u9519\u8BEF",
56
58
  yes: "\u662F",
57
- no: "\u5426"
59
+ no: "\u5426",
60
+ cancelled: "\u64CD\u4F5C\u5DF2\u53D6\u6D88",
61
+ noExistingConfig: "\u672A\u627E\u5230\u73B0\u6709\u914D\u7F6E\u3002\u8BF7\u5148\u8FD0\u884C `zcf`\u3002",
62
+ updatingPrompts: "\u6B63\u5728\u66F4\u65B0 Claude Code Prompt \u6587\u6863...",
63
+ updateConfigLangPrompt: "\u9009\u62E9\u914D\u7F6E\u8BED\u8A00",
64
+ updateConfigLangChoice: {
65
+ "zh-CN": "\u4E2D\u6587\u7248\u914D\u7F6E",
66
+ "en": "\u82F1\u6587\u7248\u914D\u7F6E"
67
+ }
58
68
  },
59
- "en": {
69
+ en: {
60
70
  selectScriptLang: "Select script language",
61
71
  selectConfigLang: "Select Claude Code configuration language",
62
72
  configLangHint: {
63
73
  "zh-CN": "Chinese (easier for Chinese users to customize)",
64
- "en": "English (recommended, lower token consumption)"
74
+ en: "English (recommended, lower token consumption)"
65
75
  },
66
76
  installPrompt: "Claude Code not found. Install automatically?",
67
77
  installing: "Installing Claude Code...",
68
78
  installSuccess: "Claude Code installed successfully",
69
79
  installFailed: "Failed to install Claude Code",
70
80
  npmNotFound: "npm is not installed. Please install Node.js and npm first.",
71
- windowsRestartHint: "\u26A0 On Windows, please open a new terminal window (cmd/PowerShell) and run the claude command",
72
81
  configureApi: "Configure API?",
73
82
  customApi: "Configure API",
74
83
  skipApi: "Skip (configure later in claude command, e.g., OAuth)",
@@ -94,7 +103,15 @@ const I18N = {
94
103
  complete: "\u{1F389} Setup complete! Use 'claude' command to start.",
95
104
  error: "Error",
96
105
  yes: "Yes",
97
- no: "No"
106
+ no: "No",
107
+ cancelled: "Operation cancelled",
108
+ noExistingConfig: "No existing configuration found. Please run `zcf` first.",
109
+ updatingPrompts: "Updating Claude Code prompt documents...",
110
+ updateConfigLangPrompt: "Select configuration language",
111
+ updateConfigLangChoice: {
112
+ "zh-CN": "Chinese configuration",
113
+ "en": "English configuration"
114
+ }
98
115
  }
99
116
  };
100
117
  const MCP_SERVICES = [
@@ -165,6 +182,29 @@ const MCP_SERVICES = [
165
182
  }
166
183
  ];
167
184
 
185
+ function displayBanner(subtitle) {
186
+ const defaultSubtitle = "One-click configuration tool for Claude Code";
187
+ const subtitleText = subtitle || defaultSubtitle;
188
+ const paddedSubtitle = subtitleText.padEnd(60, " ");
189
+ console.log(
190
+ ansis.cyan.bold(`
191
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
192
+ \u2551 \u2551
193
+ \u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2551
194
+ \u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2551
195
+ \u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2551
196
+ \u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2551
197
+ \u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2551
198
+ \u2551 \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u2551
199
+ \u2551 \u2551
200
+ \u2551 ${ansis.white.bold("Zero-Config Claude-Code Flow")} \u2551
201
+ \u2551 ${ansis.gray(paddedSubtitle)} \u2551
202
+ \u2551 \u2551
203
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
204
+ `)
205
+ );
206
+ }
207
+
168
208
  function ensureClaudeDir() {
169
209
  if (!existsSync(CLAUDE_DIR)) {
170
210
  mkdirSync(CLAUDE_DIR, { recursive: true });
@@ -318,8 +358,8 @@ function getPlatform() {
318
358
  async function commandExists(command) {
319
359
  try {
320
360
  const cmd = getPlatform() === "windows" ? "where" : "which";
321
- await exec(cmd, [command]);
322
- return true;
361
+ const res = await exec(cmd, [command]);
362
+ return res.exitCode === 0;
323
363
  } catch {
324
364
  return false;
325
365
  }
@@ -336,18 +376,7 @@ async function installClaudeCode(lang) {
336
376
  throw new Error(i18n.npmNotFound);
337
377
  }
338
378
  await exec("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
339
- await new Promise((resolve) => setTimeout(resolve, 2e3));
340
- if (await isClaudeCodeInstalled()) {
341
- console.log(`\u2714 ${i18n.installSuccess}`);
342
- } else {
343
- if (getPlatform() === "windows") {
344
- console.log(`\u2714 ${i18n.installSuccess}`);
345
- console.log(`
346
- \u26A0 ${i18n.windowsRestartHint}`);
347
- } else {
348
- console.log(`\u2714 ${i18n.installSuccess}`);
349
- }
350
- }
379
+ console.log(`\u2714 ${i18n.installSuccess}`);
351
380
  } catch (error) {
352
381
  console.error(`\u2716 ${i18n.installFailed}`);
353
382
  throw error;
@@ -417,8 +446,50 @@ function buildMcpServerConfig(baseConfig, apiKey, placeholder = "YOUR_EXA_API_KE
417
446
  return config;
418
447
  }
419
448
 
449
+ function readZcfConfig() {
450
+ try {
451
+ if (!existsSync(ZCF_CONFIG_FILE)) {
452
+ return null;
453
+ }
454
+ const content = readFileSync(ZCF_CONFIG_FILE, "utf-8");
455
+ return JSON.parse(content);
456
+ } catch (error) {
457
+ console.error("Failed to read zcf config:", error);
458
+ return null;
459
+ }
460
+ }
461
+ function writeZcfConfig(config) {
462
+ try {
463
+ writeFileSync(ZCF_CONFIG_FILE, JSON.stringify(config, null, 2));
464
+ } catch (error) {
465
+ console.error("Failed to write zcf config:", error);
466
+ }
467
+ }
468
+ function updateZcfConfig(updates) {
469
+ const existingConfig = readZcfConfig();
470
+ const newConfig = {
471
+ version: updates.version || existingConfig?.version || "1.0.0",
472
+ preferredLang: updates.preferredLang || existingConfig?.preferredLang || "en",
473
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
474
+ };
475
+ writeZcfConfig(newConfig);
476
+ }
477
+
478
+ async function updatePromptOnly(configLang, scriptLang) {
479
+ const i18n = I18N[scriptLang];
480
+ const backupDir = backupExistingConfig();
481
+ if (backupDir) {
482
+ console.log(ansis.gray(`\u2714 ${i18n.backupSuccess}: ${backupDir}`));
483
+ }
484
+ copyConfigFiles(configLang, true);
485
+ console.log(ansis.green(`\u2714 ${i18n.configSuccess} ${CLAUDE_DIR}`));
486
+ console.log("\n" + ansis.cyan(i18n.complete));
487
+ }
420
488
  async function init(options = {}) {
421
489
  try {
490
+ displayBanner();
491
+ console.log(ansis.gray(` Version: ${ansis.cyan(version)} | ${ansis.cyan("https://github.com/UfoMiao/zcf")}
492
+ `));
422
493
  let scriptLang = options.lang;
423
494
  if (!scriptLang) {
424
495
  const response = await prompts({
@@ -430,6 +501,10 @@ async function init(options = {}) {
430
501
  value: l
431
502
  }))
432
503
  });
504
+ if (!response.lang) {
505
+ console.log(ansis.yellow("\u64CD\u4F5C\u5DF2\u53D6\u6D88 / Operation cancelled"));
506
+ process.exit(0);
507
+ }
433
508
  scriptLang = response.lang;
434
509
  }
435
510
  if (!scriptLang) {
@@ -448,27 +523,31 @@ async function init(options = {}) {
448
523
  value: l
449
524
  }))
450
525
  });
526
+ if (!response.lang) {
527
+ console.log(ansis.yellow(i18n.cancelled));
528
+ process.exit(0);
529
+ }
451
530
  configLang = response.lang;
452
531
  }
453
- let wasAlreadyInstalled = true;
454
- if (!options.skipInstall) {
455
- const installed = await isClaudeCodeInstalled();
456
- wasAlreadyInstalled = installed;
457
- if (!installed) {
458
- const response = await prompts({
459
- type: "confirm",
460
- name: "shouldInstall",
461
- message: i18n.installPrompt,
462
- initial: true
463
- });
464
- if (response.shouldInstall) {
465
- await installClaudeCode(scriptLang);
466
- } else {
467
- console.log(ansis.yellow(i18n.skip));
468
- }
532
+ const installed = await isClaudeCodeInstalled();
533
+ if (!installed) {
534
+ const response = await prompts({
535
+ type: "confirm",
536
+ name: "shouldInstall",
537
+ message: i18n.installPrompt,
538
+ initial: true
539
+ });
540
+ if (response.shouldInstall === void 0) {
541
+ console.log(ansis.yellow(i18n.cancelled));
542
+ process.exit(0);
543
+ }
544
+ if (response.shouldInstall) {
545
+ await installClaudeCode(scriptLang);
469
546
  } else {
470
- console.log(ansis.green(`\u2714 ${i18n.installSuccess}`));
547
+ console.log(ansis.yellow(i18n.skip));
471
548
  }
549
+ } else {
550
+ console.log(ansis.green(`\u2714 ${i18n.installSuccess}`));
472
551
  }
473
552
  ensureClaudeDir();
474
553
  let onlyUpdateDocs = false;
@@ -485,6 +564,10 @@ async function init(options = {}) {
485
564
  { title: i18n.skip, value: "skip" }
486
565
  ]
487
566
  });
567
+ if (!actionResponse.action) {
568
+ console.log(ansis.yellow(i18n.cancelled));
569
+ process.exit(0);
570
+ }
488
571
  action = actionResponse.action;
489
572
  if (action === "skip") {
490
573
  console.log(ansis.yellow(i18n.skip));
@@ -506,6 +589,10 @@ async function init(options = {}) {
506
589
  { title: i18n.skipApi, value: "skip" }
507
590
  ]
508
591
  });
592
+ if (!apiResponse.apiChoice) {
593
+ console.log(ansis.yellow(i18n.cancelled));
594
+ process.exit(0);
595
+ }
509
596
  const apiChoice = apiResponse.apiChoice;
510
597
  if (apiChoice === "custom") {
511
598
  const urlResponse = await prompts({
@@ -522,6 +609,10 @@ async function init(options = {}) {
522
609
  }
523
610
  }
524
611
  });
612
+ if (urlResponse.url === void 0) {
613
+ console.log(ansis.yellow(i18n.cancelled));
614
+ process.exit(0);
615
+ }
525
616
  const url = urlResponse.url;
526
617
  const keyResponse = await prompts({
527
618
  type: "text",
@@ -529,6 +620,10 @@ async function init(options = {}) {
529
620
  message: i18n.enterApiKey,
530
621
  validate: (value) => !!value || "API Key is required"
531
622
  });
623
+ if (keyResponse.key === void 0) {
624
+ console.log(ansis.yellow(i18n.cancelled));
625
+ process.exit(0);
626
+ }
532
627
  const key = keyResponse.key;
533
628
  apiConfig = { url, key };
534
629
  }
@@ -565,6 +660,10 @@ async function init(options = {}) {
565
660
  message: i18n.configureMcp,
566
661
  initial: true
567
662
  });
663
+ if (mcpResponse.shouldConfigureMcp === void 0) {
664
+ console.log(ansis.yellow(i18n.cancelled));
665
+ process.exit(0);
666
+ }
568
667
  if (mcpResponse.shouldConfigureMcp) {
569
668
  const choices = [
570
669
  {
@@ -586,6 +685,10 @@ async function init(options = {}) {
586
685
  instructions: false,
587
686
  hint: "- Space to select. Return to submit"
588
687
  });
688
+ if (selectedResponse.services === void 0) {
689
+ console.log(ansis.yellow(i18n.cancelled));
690
+ process.exit(0);
691
+ }
589
692
  let selectedServices = selectedResponse.services || [];
590
693
  if (selectedServices.includes("ALL")) {
591
694
  selectedServices = MCP_SERVICES.map((s) => s.id);
@@ -607,6 +710,10 @@ async function init(options = {}) {
607
710
  message: service.apiKeyPrompt[scriptLang],
608
711
  validate: (value) => !!value || "API Key is required"
609
712
  });
713
+ if (apiKeyResponse.apiKey === void 0) {
714
+ console.log(ansis.yellow(`${i18n.skip}: ${service.name[scriptLang]}`));
715
+ continue;
716
+ }
610
717
  if (apiKeyResponse.apiKey) {
611
718
  config = buildMcpServerConfig(service.config, apiKeyResponse.apiKey, service.apiKeyPlaceholder);
612
719
  } else {
@@ -626,16 +733,16 @@ async function init(options = {}) {
626
733
  }
627
734
  }
628
735
  }
736
+ updateZcfConfig({
737
+ version,
738
+ preferredLang: scriptLang
739
+ });
629
740
  console.log(ansis.green(`\u2714 ${i18n.configSuccess} ${CLAUDE_DIR}`));
630
741
  console.log("\n" + ansis.cyan(i18n.complete));
631
- if (getPlatform() === "windows" && !wasAlreadyInstalled) {
632
- console.log(ansis.yellow(`
633
- ${i18n.windowsRestartHint}`));
634
- }
635
742
  } catch (error) {
636
743
  console.error(ansis.red(`${I18N[options.lang || "en"].error}:`), error);
637
744
  process.exit(1);
638
745
  }
639
746
  }
640
747
 
641
- export { CLAUDE_DIR as C, I18N as I, LANG_LABELS as L, MCP_CONFIG_FILE as M, SETTINGS_FILE as S, 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, writeMcpConfig as w };
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 };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zcf",
3
3
  "type": "module",
4
- "version": "1.0.2",
4
+ "version": "1.1.0",
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",
@@ -72,7 +72,7 @@ You are a professional AI programming assistant following a structured core work
72
72
 
73
73
  - Must have user approval before execution
74
74
  - Strictly follow the plan for coding implementation
75
- - Store plan summary (with context and plan) in project root directory `.claude/task-name.md`
75
+ - Store plan summary (with context and plan) in project root directory `.claude/plan/task-name.md`
76
76
  - Request user feedback after key steps and completion
77
77
 
78
78
  ### 5. `[Mode: Optimize]` - Code Optimization
@@ -142,7 +142,7 @@ Starting structured development workflow with quality gates...
142
142
  - Implement according to approved plan
143
143
  - Follow development best practices
144
144
  - Add usage methods before import statements (critical rule)
145
- - Store execution plan in project root directory `.claude/task-name.md`
145
+ - Store execution plan in project root directory `.claude/plan/task-name.md`
146
146
  - Request feedback at key milestones
147
147
 
148
148
  ### 🚀 Phase 5: Code Optimization
@@ -168,7 +168,8 @@ Starting structured development workflow with quality gates...
168
168
  ```
169
169
  project/ # Project root directory
170
170
  ├── .claude/
171
- │ └── task-name.md # Execution plan and context (in project root)
171
+ │ └── plan/
172
+ │ └── task-name.md # Execution plan and context (in project root)
172
173
  ├── src/
173
174
  │ ├── components/
174
175
  │ ├── services/
@@ -50,7 +50,7 @@ allowed-tools:
50
50
  1. `[模式:研究]`:理解需求。
51
51
  2. `[模式:构思]`:提供至少两种可行方案及评估(例如:`方案 1:描述`)。
52
52
  3. `[模式:计划]`:将选定方案细化为详尽、有序、可执行的步骤清单(含原子操作:文件、函数/类、逻辑概要;预期结果;新库用 `Context7` 查询)。不写完整代码。完成后请求用户批准。
53
- 4. `[模式:执行]`:必须用户批准方可执行。严格按计划编码执行。计划简要(含上下文和计划)存入当前项目根目录的`.claude/任务名.md`。关键步骤后及完成时请求用户反馈。
53
+ 4. `[模式:执行]`:必须用户批准方可执行。严格按计划编码执行。计划简要(含上下文和计划)存入当前项目根目录的`.claude/plan/任务名.md`。关键步骤后及完成时请求用户反馈。
54
54
  5. `[模式:优化]`:在 `[模式:执行]` 完成后,必须自动进行本模式 `[模式:优化]`,自动检查并分析本次任务已实现(仅本次对话产生的相关代码),在 `[模式:执行]` 下产生的相关代码。聚焦冗余、低效、垃圾代码,提出具体优化建议(含优化理由与预期收益),用户确认后执行相关优化功能。
55
55
  6. `[模式:评审]`:对照计划评估执行结果,报告问题与建议。完成后请求用户确认。
56
56
 
@@ -107,7 +107,7 @@ allowed-tools:
107
107
  - 根据批准的计划实施
108
108
  - 遵循开发最佳实践
109
109
  - 在导入语句之前添加使用方法(关键规则)
110
- - 在项目根目录 `.claude/任务名.md` 中存储执行计划
110
+ - 在项目根目录 `.claude/plan/任务名.md` 中存储执行计划
111
111
  - 在关键里程碑请求反馈
112
112
 
113
113
  ### 🚀 阶段 5:代码优化
@@ -133,7 +133,8 @@ allowed-tools:
133
133
  ```
134
134
  project/ # 项目根目录
135
135
  ├── .claude/
136
- │ └── 任务名.md # 执行计划和上下文(在项目根目录)
136
+ │ └── plan/
137
+ │ └── 任务名.md # 执行计划和上下文(在项目根目录)
137
138
  ├── src/
138
139
  │ ├── components/
139
140
  │ ├── services/