zcf 1.2.0 → 2.0.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 +87 -20
- package/dist/cli.mjs +436 -10
- package/dist/index.d.mts +211 -10
- package/dist/index.d.ts +211 -10
- package/dist/index.mjs +2 -1
- package/dist/shared/zcf.DGNSM22u.mjs +1661 -0
- package/package.json +2 -2
- package/templates/CLAUDE.md +7 -0
- package/templates/en/mcp.md +6 -0
- package/templates/en/personality.md +1 -0
- package/templates/en/{CLAUDE.md → rules.md} +1 -10
- package/templates/zh-CN/mcp.md +6 -0
- package/templates/zh-CN/personality.md +1 -0
- package/templates/zh-CN/{CLAUDE.md → rules.md} +6 -15
- package/dist/shared/zcf.D3MMT8L8.mjs +0 -988
package/dist/cli.mjs
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import cac from 'cac';
|
|
3
3
|
import ansis from 'ansis';
|
|
4
|
-
import {
|
|
4
|
+
import { z as displayBanner, B as selectScriptLanguage, D as readZcfConfig, I as I18N, S as SETTINGS_FILE, d as SUPPORTED_LANGS, L as LANG_LABELS, E as resolveAiOutputLanguage, F as updatePromptOnly, G as updateZcfConfig, H as version, Z as ZCF_CONFIG_FILE, p as applyAiLanguageDirective, J as configureAiPersonality, u as updateDefaultModel, K as isWindows, r as readMcpConfig, x as fixWindowsMcpConfig, w as writeMcpConfig, M as MCP_SERVICES, s as backupMcpConfig, v as buildMcpServerConfig, t as mergeMcpServers, o as getExistingApiConfig, N as formatApiKeyDisplay, O as modifyApiConfigPartially, P as validateApiKey, l as configureApi, Q as displayBannerWithInfo, i as init } from './shared/zcf.DGNSM22u.mjs';
|
|
5
5
|
import prompts from '@posva/prompts';
|
|
6
|
-
import { existsSync } from 'node:fs';
|
|
6
|
+
import { existsSync, unlinkSync } from 'node:fs';
|
|
7
7
|
import 'node:os';
|
|
8
8
|
import 'pathe';
|
|
9
9
|
import 'dayjs';
|
|
10
|
+
import 'node:url';
|
|
10
11
|
import 'tinyexec';
|
|
11
12
|
|
|
12
13
|
async function update(options = {}) {
|
|
13
14
|
try {
|
|
14
|
-
|
|
15
|
+
if (!options.skipBanner) {
|
|
16
|
+
displayBanner("Update configuration for Claude Code");
|
|
17
|
+
}
|
|
15
18
|
const scriptLang = await selectScriptLanguage();
|
|
16
19
|
const zcfConfig = readZcfConfig();
|
|
17
20
|
const i18n = I18N[scriptLang];
|
|
@@ -58,11 +61,426 @@ ${i18n.updatingPrompts}
|
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
|
|
64
|
+
function handleCancellation(scriptLang) {
|
|
65
|
+
console.log(ansis.yellow(I18N[scriptLang].cancelled));
|
|
66
|
+
}
|
|
67
|
+
async function configureApiFeature(scriptLang) {
|
|
68
|
+
const i18n = I18N[scriptLang];
|
|
69
|
+
const existingApiConfig = getExistingApiConfig();
|
|
70
|
+
if (existingApiConfig) {
|
|
71
|
+
console.log("\n" + ansis.blue(`\u2139 ${i18n.existingApiConfig}`));
|
|
72
|
+
console.log(ansis.gray(` ${i18n.apiConfigUrl}: ${existingApiConfig.url || i18n.notConfigured}`));
|
|
73
|
+
console.log(ansis.gray(` ${i18n.apiConfigKey}: ${existingApiConfig.key ? formatApiKeyDisplay(existingApiConfig.key) : i18n.notConfigured}`));
|
|
74
|
+
console.log(ansis.gray(` ${i18n.apiConfigAuthType}: ${existingApiConfig.authType || i18n.notConfigured}
|
|
75
|
+
`));
|
|
76
|
+
const actionResponse = await prompts({
|
|
77
|
+
type: "select",
|
|
78
|
+
name: "action",
|
|
79
|
+
message: i18n.selectApiAction,
|
|
80
|
+
choices: [
|
|
81
|
+
{ title: i18n.keepExistingConfig, value: "keep" },
|
|
82
|
+
{ title: i18n.modifyAllConfig, value: "modify-all" },
|
|
83
|
+
{ title: i18n.modifyPartialConfig, value: "modify-partial" }
|
|
84
|
+
]
|
|
85
|
+
});
|
|
86
|
+
if (!actionResponse.action) {
|
|
87
|
+
handleCancellation(scriptLang);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (actionResponse.action === "keep") {
|
|
91
|
+
console.log(ansis.green(`\u2714 ${i18n.keepExistingConfig}`));
|
|
92
|
+
return;
|
|
93
|
+
} else if (actionResponse.action === "modify-partial") {
|
|
94
|
+
await modifyApiConfigPartially(existingApiConfig, i18n, scriptLang);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const apiResponse = await prompts({
|
|
99
|
+
type: "select",
|
|
100
|
+
name: "apiChoice",
|
|
101
|
+
message: i18n.configureApi,
|
|
102
|
+
choices: [
|
|
103
|
+
{
|
|
104
|
+
title: i18n.useAuthToken,
|
|
105
|
+
value: "auth_token",
|
|
106
|
+
description: ansis.gray(i18n.authTokenDesc)
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
title: i18n.useApiKey,
|
|
110
|
+
value: "api_key",
|
|
111
|
+
description: ansis.gray(i18n.apiKeyDesc)
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
title: i18n.skipApi,
|
|
115
|
+
value: "skip"
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
});
|
|
119
|
+
if (!apiResponse.apiChoice || apiResponse.apiChoice === "skip") {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const apiChoice = apiResponse.apiChoice;
|
|
123
|
+
const urlResponse = await prompts({
|
|
124
|
+
type: "text",
|
|
125
|
+
name: "url",
|
|
126
|
+
message: i18n.enterApiUrl,
|
|
127
|
+
validate: (value) => {
|
|
128
|
+
if (!value) return i18n.urlRequired;
|
|
129
|
+
try {
|
|
130
|
+
new URL(value);
|
|
131
|
+
return true;
|
|
132
|
+
} catch {
|
|
133
|
+
return i18n.invalidUrl;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
if (!urlResponse.url) {
|
|
138
|
+
handleCancellation(scriptLang);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const keyMessage = apiChoice === "auth_token" ? i18n.enterAuthToken : i18n.enterApiKey;
|
|
142
|
+
const keyResponse = await prompts({
|
|
143
|
+
type: "text",
|
|
144
|
+
name: "key",
|
|
145
|
+
message: keyMessage,
|
|
146
|
+
validate: (value) => {
|
|
147
|
+
if (!value) {
|
|
148
|
+
return i18n.keyRequired;
|
|
149
|
+
}
|
|
150
|
+
const validation = validateApiKey(value, scriptLang);
|
|
151
|
+
if (!validation.isValid) {
|
|
152
|
+
return validation.error || i18n.invalidKeyFormat;
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
if (!keyResponse.key) {
|
|
158
|
+
handleCancellation(scriptLang);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const apiConfig = { url: urlResponse.url, key: keyResponse.key, authType: apiChoice };
|
|
162
|
+
const configuredApi = configureApi(apiConfig);
|
|
163
|
+
if (configuredApi) {
|
|
164
|
+
console.log(ansis.green(`\u2714 ${i18n.apiConfigSuccess}`));
|
|
165
|
+
console.log(ansis.gray(` URL: ${configuredApi.url}`));
|
|
166
|
+
console.log(ansis.gray(` Key: ${formatApiKeyDisplay(configuredApi.key)}`));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async function configureMcpFeature(scriptLang) {
|
|
170
|
+
const i18n = I18N[scriptLang];
|
|
171
|
+
if (isWindows()) {
|
|
172
|
+
const fixResponse = await prompts({
|
|
173
|
+
type: "confirm",
|
|
174
|
+
name: "fixWindows",
|
|
175
|
+
message: i18n.fixWindowsMcp || "Fix Windows MCP configuration?",
|
|
176
|
+
initial: true
|
|
177
|
+
});
|
|
178
|
+
if (fixResponse.fixWindows) {
|
|
179
|
+
const existingConfig = readMcpConfig() || { mcpServers: {} };
|
|
180
|
+
const fixedConfig = fixWindowsMcpConfig(existingConfig);
|
|
181
|
+
writeMcpConfig(fixedConfig);
|
|
182
|
+
console.log(ansis.green(`\u2714 ${i18n.windowsMcpFixed || "Windows MCP configuration fixed"}`));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const choices = [
|
|
186
|
+
{
|
|
187
|
+
title: ansis.bold(i18n.allServices),
|
|
188
|
+
value: "ALL",
|
|
189
|
+
selected: false
|
|
190
|
+
},
|
|
191
|
+
...MCP_SERVICES.map((service) => ({
|
|
192
|
+
title: `${service.name[scriptLang]} - ${ansis.gray(service.description[scriptLang])}`,
|
|
193
|
+
value: service.id,
|
|
194
|
+
selected: false
|
|
195
|
+
}))
|
|
196
|
+
];
|
|
197
|
+
const selectedResponse = await prompts({
|
|
198
|
+
type: "multiselect",
|
|
199
|
+
name: "services",
|
|
200
|
+
message: i18n.selectMcpServices,
|
|
201
|
+
choices,
|
|
202
|
+
instructions: false,
|
|
203
|
+
hint: i18n.spaceToSelectReturn
|
|
204
|
+
});
|
|
205
|
+
if (!selectedResponse.services) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
let selectedServices = selectedResponse.services || [];
|
|
209
|
+
if (selectedServices.includes("ALL")) {
|
|
210
|
+
selectedServices = MCP_SERVICES.map((s) => s.id);
|
|
211
|
+
}
|
|
212
|
+
if (selectedServices.length > 0) {
|
|
213
|
+
const mcpBackupPath = backupMcpConfig();
|
|
214
|
+
if (mcpBackupPath) {
|
|
215
|
+
console.log(ansis.gray(`\u2714 ${i18n.mcpBackupSuccess}: ${mcpBackupPath}`));
|
|
216
|
+
}
|
|
217
|
+
const newServers = {};
|
|
218
|
+
for (const serviceId of selectedServices) {
|
|
219
|
+
const service = MCP_SERVICES.find((s) => s.id === serviceId);
|
|
220
|
+
if (!service) continue;
|
|
221
|
+
let config = service.config;
|
|
222
|
+
if (service.requiresApiKey) {
|
|
223
|
+
const apiKeyResponse = await prompts({
|
|
224
|
+
type: "text",
|
|
225
|
+
name: "apiKey",
|
|
226
|
+
message: service.apiKeyPrompt[scriptLang],
|
|
227
|
+
validate: (value) => !!value || i18n.keyRequired
|
|
228
|
+
});
|
|
229
|
+
if (apiKeyResponse.apiKey) {
|
|
230
|
+
config = buildMcpServerConfig(service.config, apiKeyResponse.apiKey, service.apiKeyPlaceholder);
|
|
231
|
+
} else {
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
newServers[service.id] = config;
|
|
236
|
+
}
|
|
237
|
+
const existingConfig = readMcpConfig();
|
|
238
|
+
let mergedConfig = mergeMcpServers(existingConfig, newServers);
|
|
239
|
+
mergedConfig = fixWindowsMcpConfig(mergedConfig);
|
|
240
|
+
writeMcpConfig(mergedConfig);
|
|
241
|
+
console.log(ansis.green(`\u2714 ${i18n.mcpConfigSuccess}`));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
async function configureDefaultModelFeature(scriptLang) {
|
|
245
|
+
const i18n = I18N[scriptLang];
|
|
246
|
+
const modelResponse = await prompts({
|
|
247
|
+
type: "select",
|
|
248
|
+
name: "model",
|
|
249
|
+
message: i18n.selectDefaultModel || "Select default model",
|
|
250
|
+
choices: [
|
|
251
|
+
{ title: "Opus", value: "opus" },
|
|
252
|
+
{ title: "Sonnet", value: "sonnet" }
|
|
253
|
+
]
|
|
254
|
+
});
|
|
255
|
+
if (!modelResponse.model) {
|
|
256
|
+
handleCancellation(scriptLang);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
updateDefaultModel(modelResponse.model);
|
|
260
|
+
console.log(ansis.green(`\u2714 ${i18n.modelConfigSuccess || "Default model configured"}`));
|
|
261
|
+
}
|
|
262
|
+
async function configureAiMemoryFeature(scriptLang) {
|
|
263
|
+
const i18n = I18N[scriptLang];
|
|
264
|
+
const memoryResponse = await prompts({
|
|
265
|
+
type: "select",
|
|
266
|
+
name: "option",
|
|
267
|
+
message: i18n.selectMemoryOption || "Select configuration option",
|
|
268
|
+
choices: [
|
|
269
|
+
{
|
|
270
|
+
title: i18n.configureAiLanguage || "Configure AI output language",
|
|
271
|
+
value: "language"
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
title: i18n.configureAiPersonality || "Configure AI personality",
|
|
275
|
+
value: "personality"
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
});
|
|
279
|
+
if (!memoryResponse.option) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (memoryResponse.option === "language") {
|
|
283
|
+
const zcfConfig = readZcfConfig();
|
|
284
|
+
const aiOutputLang = await resolveAiOutputLanguage(scriptLang, void 0, zcfConfig);
|
|
285
|
+
applyAiLanguageDirective(aiOutputLang);
|
|
286
|
+
updateZcfConfig({ aiOutputLang });
|
|
287
|
+
console.log(ansis.green(`\u2714 ${i18n.aiLanguageConfigured || "AI output language configured"}`));
|
|
288
|
+
} else {
|
|
289
|
+
await configureAiPersonality(scriptLang);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
async function clearZcfCacheFeature(scriptLang) {
|
|
293
|
+
const i18n = I18N[scriptLang];
|
|
294
|
+
const confirmResponse = await prompts({
|
|
295
|
+
type: "confirm",
|
|
296
|
+
name: "confirm",
|
|
297
|
+
message: i18n.confirmClearCache || "Clear all ZCF preferences cache?",
|
|
298
|
+
initial: false
|
|
299
|
+
});
|
|
300
|
+
if (!confirmResponse.confirm) {
|
|
301
|
+
handleCancellation(scriptLang);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (existsSync(ZCF_CONFIG_FILE)) {
|
|
305
|
+
unlinkSync(ZCF_CONFIG_FILE);
|
|
306
|
+
console.log(ansis.green(`\u2714 ${i18n.cacheCleared || "ZCF cache cleared"}`));
|
|
307
|
+
} else {
|
|
308
|
+
console.log(ansis.yellow(i18n.noCacheFound || "No cache found"));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
async function changeScriptLanguageFeature(currentLang) {
|
|
312
|
+
const i18n = I18N[currentLang];
|
|
313
|
+
const langResponse = await prompts({
|
|
314
|
+
type: "select",
|
|
315
|
+
name: "lang",
|
|
316
|
+
message: i18n.selectScriptLang,
|
|
317
|
+
choices: SUPPORTED_LANGS.map((l) => ({
|
|
318
|
+
title: LANG_LABELS[l],
|
|
319
|
+
value: l
|
|
320
|
+
})),
|
|
321
|
+
initial: SUPPORTED_LANGS.indexOf(currentLang)
|
|
322
|
+
});
|
|
323
|
+
if (!langResponse.lang) {
|
|
324
|
+
return currentLang;
|
|
325
|
+
}
|
|
326
|
+
updateZcfConfig({ preferredLang: langResponse.lang });
|
|
327
|
+
console.log(ansis.green(`\u2714 ${I18N[langResponse.lang].languageChanged || "Language changed"}`));
|
|
328
|
+
return langResponse.lang;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
async function showMainMenu() {
|
|
332
|
+
try {
|
|
333
|
+
displayBannerWithInfo();
|
|
334
|
+
const zcfConfig = readZcfConfig();
|
|
335
|
+
let scriptLang = zcfConfig?.preferredLang || await selectScriptLanguage();
|
|
336
|
+
let exitMenu = false;
|
|
337
|
+
while (!exitMenu) {
|
|
338
|
+
const i18n = I18N[scriptLang];
|
|
339
|
+
console.log(ansis.cyan(i18n.selectFunction));
|
|
340
|
+
console.log(" -------- Claude Code --------");
|
|
341
|
+
console.log(
|
|
342
|
+
` ${ansis.cyan("1.")} ${i18n.menuOptions.fullInit} ${ansis.gray("- " + i18n.menuDescriptions.fullInit)}`
|
|
343
|
+
);
|
|
344
|
+
console.log(
|
|
345
|
+
` ${ansis.cyan("2.")} ${i18n.menuOptions.importWorkflow} ${ansis.gray(
|
|
346
|
+
"- " + i18n.menuDescriptions.importWorkflow
|
|
347
|
+
)}`
|
|
348
|
+
);
|
|
349
|
+
console.log(
|
|
350
|
+
` ${ansis.cyan("3.")} ${i18n.menuOptions.configureApi} ${ansis.gray(
|
|
351
|
+
"- " + i18n.menuDescriptions.configureApi
|
|
352
|
+
)}`
|
|
353
|
+
);
|
|
354
|
+
console.log(
|
|
355
|
+
` ${ansis.cyan("4.")} ${i18n.menuOptions.configureMcp} ${ansis.gray(
|
|
356
|
+
"- " + i18n.menuDescriptions.configureMcp
|
|
357
|
+
)}`
|
|
358
|
+
);
|
|
359
|
+
console.log(
|
|
360
|
+
` ${ansis.cyan("5.")} ${i18n.menuOptions.configureModel} ${ansis.gray(
|
|
361
|
+
"- " + i18n.menuDescriptions.configureModel
|
|
362
|
+
)}`
|
|
363
|
+
);
|
|
364
|
+
console.log(
|
|
365
|
+
` ${ansis.cyan("6.")} ${i18n.menuOptions.configureAiMemory} ${ansis.gray(
|
|
366
|
+
"- " + i18n.menuDescriptions.configureAiMemory
|
|
367
|
+
)}`
|
|
368
|
+
);
|
|
369
|
+
console.log("");
|
|
370
|
+
console.log(" ------------ ZCF ------------");
|
|
371
|
+
console.log(
|
|
372
|
+
` ${ansis.cyan("0.")} ${i18n.menuOptions.changeLanguage} ${ansis.gray(
|
|
373
|
+
"- " + i18n.menuDescriptions.changeLanguage
|
|
374
|
+
)}`
|
|
375
|
+
);
|
|
376
|
+
console.log(
|
|
377
|
+
` ${ansis.cyan("-.")} ${i18n.menuOptions.clearCache} ${ansis.gray("- " + i18n.menuDescriptions.clearCache)}`
|
|
378
|
+
);
|
|
379
|
+
console.log(` ${ansis.red("q.")} ${ansis.red(i18n.menuOptions.exit)}`);
|
|
380
|
+
console.log("");
|
|
381
|
+
const response = await prompts({
|
|
382
|
+
type: "text",
|
|
383
|
+
name: "choice",
|
|
384
|
+
message: i18n.enterChoice || "Enter your choice",
|
|
385
|
+
validate: (value) => {
|
|
386
|
+
const valid = ["1", "2", "3", "4", "5", "6", "0", "-", "q", "Q"];
|
|
387
|
+
return valid.includes(value) || i18n.invalidChoice;
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
if (!response.choice) {
|
|
391
|
+
console.log(ansis.yellow(i18n.cancelled));
|
|
392
|
+
exitMenu = true;
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
switch (response.choice.toLowerCase()) {
|
|
396
|
+
case "1":
|
|
397
|
+
await init({ lang: scriptLang, skipBanner: true });
|
|
398
|
+
break;
|
|
399
|
+
case "2":
|
|
400
|
+
await update({ skipBanner: true });
|
|
401
|
+
break;
|
|
402
|
+
case "3":
|
|
403
|
+
await configureApiFeature(scriptLang);
|
|
404
|
+
break;
|
|
405
|
+
case "4":
|
|
406
|
+
await configureMcpFeature(scriptLang);
|
|
407
|
+
break;
|
|
408
|
+
case "5":
|
|
409
|
+
await configureDefaultModelFeature(scriptLang);
|
|
410
|
+
break;
|
|
411
|
+
case "6":
|
|
412
|
+
await configureAiMemoryFeature(scriptLang);
|
|
413
|
+
break;
|
|
414
|
+
case "-":
|
|
415
|
+
await clearZcfCacheFeature(scriptLang);
|
|
416
|
+
break;
|
|
417
|
+
case "0":
|
|
418
|
+
const newLang = await changeScriptLanguageFeature(scriptLang);
|
|
419
|
+
if (newLang !== scriptLang) {
|
|
420
|
+
scriptLang = newLang;
|
|
421
|
+
console.log("\n" + ansis.dim("\u2500".repeat(50)) + "\n");
|
|
422
|
+
const newI18n = I18N[scriptLang];
|
|
423
|
+
const continueResponse = await prompts({
|
|
424
|
+
type: "confirm",
|
|
425
|
+
name: "continue",
|
|
426
|
+
message: newI18n.returnToMenu,
|
|
427
|
+
initial: true
|
|
428
|
+
});
|
|
429
|
+
if (!continueResponse.continue) {
|
|
430
|
+
exitMenu = true;
|
|
431
|
+
console.log(ansis.cyan(newI18n.goodbye));
|
|
432
|
+
}
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
break;
|
|
436
|
+
case "q":
|
|
437
|
+
exitMenu = true;
|
|
438
|
+
console.log(ansis.cyan(i18n.goodbye));
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
if (!exitMenu && response.choice.toLowerCase() !== "q") {
|
|
442
|
+
console.log("\n" + ansis.dim("\u2500".repeat(50)) + "\n");
|
|
443
|
+
const continueResponse = await prompts({
|
|
444
|
+
type: "confirm",
|
|
445
|
+
name: "continue",
|
|
446
|
+
message: i18n.returnToMenu,
|
|
447
|
+
initial: true
|
|
448
|
+
});
|
|
449
|
+
if (!continueResponse.continue) {
|
|
450
|
+
exitMenu = true;
|
|
451
|
+
console.log(ansis.cyan(i18n.goodbye));
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
} catch (error) {
|
|
456
|
+
const zcfConfig = readZcfConfig();
|
|
457
|
+
const defaultLang = zcfConfig?.preferredLang || "en";
|
|
458
|
+
const errorMsg = I18N[defaultLang].error;
|
|
459
|
+
console.error(ansis.red(`${errorMsg}:`), error);
|
|
460
|
+
if (error instanceof Error) {
|
|
461
|
+
console.error(ansis.gray(`Stack: ${error.stack}`));
|
|
462
|
+
}
|
|
463
|
+
process.exit(1);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
61
467
|
const cli = cac("zcf");
|
|
62
|
-
cli.command("[lang]", "
|
|
468
|
+
cli.command("[lang]", "Show interactive menu (default)").option("--init", "Run full initialization directly").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").option("--force, -f", "Force overwrite existing configuration").action(async (lang, options) => {
|
|
469
|
+
if (options.init) {
|
|
470
|
+
await init({
|
|
471
|
+
lang: lang || options.lang,
|
|
472
|
+
configLang: options.configLang,
|
|
473
|
+
force: options.force
|
|
474
|
+
});
|
|
475
|
+
} else {
|
|
476
|
+
await showMainMenu();
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
cli.command("init", "Initialize Claude Code configuration").alias("i").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").option("--ai-output-lang, -a <lang>", "AI output language").option("--force, -f", "Force overwrite existing configuration").action(async (options) => {
|
|
63
480
|
await init({
|
|
64
|
-
lang:
|
|
481
|
+
lang: options.lang,
|
|
65
482
|
configLang: options.configLang,
|
|
483
|
+
aiOutputLang: options.aiOutputLang,
|
|
66
484
|
force: options.force
|
|
67
485
|
});
|
|
68
486
|
});
|
|
@@ -77,16 +495,19 @@ cli.help((sections) => {
|
|
|
77
495
|
sections.push({
|
|
78
496
|
title: ansis.yellow("Commands / \u547D\u4EE4:"),
|
|
79
497
|
body: [
|
|
80
|
-
` ${ansis.cyan("zcf")}
|
|
498
|
+
` ${ansis.cyan("zcf")} Show interactive menu (default) / \u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355\uFF08\u9ED8\u8BA4\uFF09`,
|
|
499
|
+
` ${ansis.cyan("zcf init")} | ${ansis.cyan("i")} Initialize Claude Code configuration / \u521D\u59CB\u5316 Claude Code \u914D\u7F6E`,
|
|
81
500
|
` ${ansis.cyan("zcf update")} | ${ansis.cyan("u")} Update workflow-related md files / \u4EC5\u66F4\u65B0\u5DE5\u4F5C\u6D41\u76F8\u5173md`,
|
|
82
501
|
"",
|
|
83
|
-
ansis.gray("
|
|
502
|
+
ansis.gray(" Shortcuts / \u5FEB\u6377\u65B9\u5F0F:"),
|
|
503
|
+
` ${ansis.cyan("zcf i")} Quick init / \u5FEB\u901F\u521D\u59CB\u5316`,
|
|
84
504
|
` ${ansis.cyan("zcf u")} Quick update / \u5FEB\u901F\u66F4\u65B0`
|
|
85
505
|
].join("\n")
|
|
86
506
|
});
|
|
87
507
|
sections.push({
|
|
88
508
|
title: ansis.yellow("Options / \u9009\u9879:"),
|
|
89
509
|
body: [
|
|
510
|
+
` ${ansis.green("--init")} Run full initialization directly / \u76F4\u63A5\u8FD0\u884C\u5B8C\u6574\u521D\u59CB\u5316`,
|
|
90
511
|
` ${ansis.green("--config-lang, -c")} <lang> Configuration language / \u914D\u7F6E\u8BED\u8A00 (zh-CN, en)`,
|
|
91
512
|
` ${ansis.green("--force, -f")} Force overwrite / \u5F3A\u5236\u8986\u76D6\u73B0\u6709\u914D\u7F6E`,
|
|
92
513
|
` ${ansis.green("--help, -h")} Display help / \u663E\u793A\u5E2E\u52A9`,
|
|
@@ -96,15 +517,20 @@ cli.help((sections) => {
|
|
|
96
517
|
sections.push({
|
|
97
518
|
title: ansis.yellow("Examples / \u793A\u4F8B:"),
|
|
98
519
|
body: [
|
|
99
|
-
ansis.gray(" #
|
|
520
|
+
ansis.gray(" # Show interactive menu / \u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355"),
|
|
100
521
|
` ${ansis.cyan("npx zcf")}`,
|
|
101
522
|
"",
|
|
523
|
+
ansis.gray(" # Run full initialization / \u8FD0\u884C\u5B8C\u6574\u521D\u59CB\u5316"),
|
|
524
|
+
` ${ansis.cyan("npx zcf init")}`,
|
|
525
|
+
` ${ansis.cyan("npx zcf i")}`,
|
|
526
|
+
` ${ansis.cyan("npx zcf --init")}`,
|
|
527
|
+
"",
|
|
102
528
|
ansis.gray(" # Update workflow-related md files only / \u4EC5\u66F4\u65B0\u5DE5\u4F5C\u6D41\u76F8\u5173md\u6587\u4EF6"),
|
|
103
529
|
` ${ansis.cyan("npx zcf u")}`,
|
|
104
530
|
"",
|
|
105
531
|
ansis.gray(" # Force overwrite with Chinese config / \u5F3A\u5236\u4F7F\u7528\u4E2D\u6587\u914D\u7F6E\u8986\u76D6"),
|
|
106
|
-
` ${ansis.cyan("npx zcf -c zh-CN -f")}`,
|
|
107
|
-
` ${ansis.cyan("npx zcf --config-lang zh-CN --force")}`
|
|
532
|
+
` ${ansis.cyan("npx zcf --init -c zh-CN -f")}`,
|
|
533
|
+
` ${ansis.cyan("npx zcf --init --config-lang zh-CN --force")}`
|
|
108
534
|
].join("\n")
|
|
109
535
|
});
|
|
110
536
|
return sections;
|