zcf 2.12.2 → 2.12.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
@@ -127,6 +127,21 @@ ZCF now supports customizable AI output styles to personalize your Claude Code e
127
127
 
128
128
  After installation, use `/bmad-init` to initialize the BMad workflow in your project.
129
129
 
130
+ #### 📋 Spec Workflow (v2.12.4+ New Feature)
131
+
132
+ [Spec Workflow](https://github.com/Pimzino/spec-workflow-mcp) is a comprehensive MCP service that provides structured feature development workflow from requirements to implementation:
133
+
134
+ - **Requirements Analysis**: Structured requirements gathering and documentation
135
+ - **Design Phase**: Detailed technical design and architecture planning
136
+ - **Task Management**: Automatic task breakdown and progress tracking
137
+ - **Implementation Workflow**: Systematic approach from requirements to implementation
138
+ - **Interactive Dashboard**: Built-in dashboard for workflow visualization and management
139
+ - **Approval System**: Review and approval process for each development phase
140
+
141
+ The Spec Workflow MCP includes an automatic dashboard that launches with the `--AutoStartDashboard` flag, providing a visual interface for managing your development workflow.
142
+
143
+ **Usage Guide**: For detailed usage instructions and best practices, see the [official Spec Workflow documentation](https://github.com/Pimzino/spec-workflow-mcp/blob/main/README.md#quick-start).
144
+
130
145
  #### 🚀 CCR (Claude Code Router) Support (v2.8+ Enhanced)
131
146
 
132
147
  [CCR](https://github.com/musistudio/claude-code-router/blob/main/README.md) is a powerful proxy router that enables:
@@ -14,84 +14,9 @@ import semver from 'semver';
14
14
  import { exec } from 'tinyexec';
15
15
  import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
16
16
 
17
- const version = "2.12.2";
17
+ const version = "2.12.4";
18
18
  const homepage = "https://github.com/UfoMiao/zcf";
19
19
 
20
- const WORKFLOW_CONFIGS = [
21
- {
22
- id: "commonTools",
23
- nameKey: "workflowOption.commonTools",
24
- descriptionKey: "workflowDescription.commonTools",
25
- defaultSelected: true,
26
- order: 1,
27
- commands: ["init-project.md"],
28
- agents: [
29
- { id: "init-architect", filename: "init-architect.md", required: true },
30
- { id: "get-current-datetime", filename: "get-current-datetime.md", required: true }
31
- ],
32
- autoInstallAgents: true,
33
- category: "common",
34
- outputDir: "common"
35
- },
36
- {
37
- id: "sixStepsWorkflow",
38
- nameKey: "workflowOption.sixStepsWorkflow",
39
- descriptionKey: "workflowDescription.sixStepsWorkflow",
40
- defaultSelected: true,
41
- order: 2,
42
- commands: ["workflow.md"],
43
- agents: [],
44
- autoInstallAgents: false,
45
- category: "sixStep",
46
- outputDir: "workflow"
47
- },
48
- {
49
- id: "featPlanUx",
50
- nameKey: "workflowOption.featPlanUx",
51
- descriptionKey: "workflowDescription.featPlanUx",
52
- defaultSelected: true,
53
- order: 3,
54
- commands: ["feat.md"],
55
- agents: [
56
- { id: "planner", filename: "planner.md", required: true },
57
- { id: "ui-ux-designer", filename: "ui-ux-designer.md", required: true }
58
- ],
59
- autoInstallAgents: true,
60
- category: "plan",
61
- outputDir: "feat"
62
- },
63
- {
64
- id: "gitWorkflow",
65
- nameKey: "workflowOption.gitWorkflow",
66
- descriptionKey: "workflowDescription.gitWorkflow",
67
- defaultSelected: true,
68
- order: 4,
69
- commands: ["git-commit.md", "git-rollback.md", "git-cleanBranches.md", "git-worktree.md"],
70
- agents: [],
71
- autoInstallAgents: false,
72
- category: "git",
73
- outputDir: "git"
74
- },
75
- {
76
- id: "bmadWorkflow",
77
- nameKey: "workflowOption.bmadWorkflow",
78
- descriptionKey: "workflowDescription.bmadWorkflow",
79
- defaultSelected: true,
80
- order: 5,
81
- commands: ["bmad-init.md"],
82
- agents: [],
83
- autoInstallAgents: false,
84
- category: "bmad",
85
- outputDir: "bmad"
86
- }
87
- ];
88
- function getWorkflowConfig(workflowId) {
89
- return WORKFLOW_CONFIGS.find((config) => config.id === workflowId);
90
- }
91
- function getOrderedWorkflows() {
92
- return [...WORKFLOW_CONFIGS].sort((a, b) => a.order - b.order);
93
- }
94
-
95
20
  const api$1 = {
96
21
  // Basic API configuration
97
22
  configureApi: "Select API authentication method",
@@ -525,6 +450,29 @@ const mcp$1 = {
525
450
  configureMcpServices: "Configure MCP Services",
526
451
  selectMcpOption: "Select MCP configuration option"
527
452
  };
453
+ const mcpServices$1 = {
454
+ "context7": {
455
+ name: "Context7 Docs",
456
+ description: "Query latest library documentation and code examples"
457
+ },
458
+ "spec-workflow": {
459
+ name: "Spec Workflow",
460
+ description: "Structured feature development workflow, systematic approach from requirements to implementation"
461
+ },
462
+ "mcp-deepwiki": {
463
+ name: "DeepWiki",
464
+ description: "Query GitHub repository documentation and examples"
465
+ },
466
+ "Playwright": {
467
+ name: "Playwright Browser Control",
468
+ description: "Direct browser control for automation"
469
+ },
470
+ "exa": {
471
+ name: "Exa AI Search",
472
+ description: "Web search using Exa AI",
473
+ apiKeyPrompt: "Enter Exa API Key"
474
+ }
475
+ };
528
476
 
529
477
  const menu$1 = {
530
478
  selectFunction: "Select function",
@@ -657,6 +605,7 @@ const en = {
657
605
  cometix: cometixMessages$1,
658
606
  updater: updater$1
659
607
  };
608
+ const enMcpServices = mcpServices$1;
660
609
 
661
610
  const api = {
662
611
  // Basic API configuration
@@ -1091,6 +1040,29 @@ const mcp = {
1091
1040
  configureMcpServices: "\u914D\u7F6E MCP \u670D\u52A1",
1092
1041
  selectMcpOption: "\u9009\u62E9 MCP \u914D\u7F6E\u9009\u9879"
1093
1042
  };
1043
+ const mcpServices = {
1044
+ "context7": {
1045
+ name: "Context7 \u6587\u6863\u67E5\u8BE2",
1046
+ description: "\u67E5\u8BE2\u6700\u65B0\u7684\u5E93\u6587\u6863\u548C\u4EE3\u7801\u793A\u4F8B"
1047
+ },
1048
+ "spec-workflow": {
1049
+ name: "Spec \u5DE5\u4F5C\u6D41",
1050
+ description: "\u89C4\u8303\u5316\u7279\u6027\u5F00\u53D1\u5DE5\u4F5C\u6D41\u7A0B\uFF0C\u4ECE\u9700\u6C42\u5230\u5B9E\u73B0\u7684\u7CFB\u7EDF\u5316\u65B9\u6CD5"
1051
+ },
1052
+ "mcp-deepwiki": {
1053
+ name: "DeepWiki",
1054
+ description: "\u67E5\u8BE2 GitHub \u4ED3\u5E93\u6587\u6863\u548C\u793A\u4F8B"
1055
+ },
1056
+ "Playwright": {
1057
+ name: "Playwright \u6D4F\u89C8\u5668\u63A7\u5236",
1058
+ description: "\u76F4\u63A5\u63A7\u5236\u6D4F\u89C8\u5668\u8FDB\u884C\u81EA\u52A8\u5316\u64CD\u4F5C"
1059
+ },
1060
+ "exa": {
1061
+ name: "Exa AI \u641C\u7D22",
1062
+ description: "\u4F7F\u7528 Exa AI \u8FDB\u884C\u7F51\u9875\u641C\u7D22",
1063
+ apiKeyPrompt: "\u8BF7\u8F93\u5165 Exa API Key"
1064
+ }
1065
+ };
1094
1066
 
1095
1067
  const menu = {
1096
1068
  selectFunction: "\u8BF7\u9009\u62E9\u529F\u80FD",
@@ -1223,40 +1195,26 @@ const zhCN = {
1223
1195
  cometix: cometixMessages,
1224
1196
  updater
1225
1197
  };
1198
+ const zhCNMcpServices = mcpServices;
1226
1199
 
1227
1200
  const I18N$1 = {
1228
1201
  "zh-CN": zhCN,
1229
1202
  "en": en
1230
1203
  };
1204
+ const mcpServiceTranslations = {
1205
+ "zh-CN": zhCNMcpServices,
1206
+ "en": enMcpServices
1207
+ };
1231
1208
  function getTranslation(lang) {
1232
1209
  return I18N$1[lang];
1233
1210
  }
1211
+ function getMcpServiceTranslation(lang) {
1212
+ return mcpServiceTranslations[lang];
1213
+ }
1234
1214
 
1235
- const CLAUDE_DIR = join(homedir(), ".claude");
1236
- const SETTINGS_FILE = join(CLAUDE_DIR, "settings.json");
1237
- const CLAUDE_MD_FILE = join(CLAUDE_DIR, "CLAUDE.md");
1238
- const ClAUDE_CONFIG_FILE = join(homedir(), ".claude.json");
1239
- const LEGACY_ZCF_CONFIG_FILE = join(homedir(), ".zcf.json");
1240
- const ZCF_CONFIG_FILE = join(CLAUDE_DIR, ".zcf-config.json");
1241
- const SUPPORTED_LANGS = ["zh-CN", "en"];
1242
- const LANG_LABELS = {
1243
- "zh-CN": "\u7B80\u4F53\u4E2D\u6587",
1244
- "en": "English"
1245
- };
1246
- const AI_OUTPUT_LANGUAGES = {
1247
- "zh-CN": { label: "\u7B80\u4F53\u4E2D\u6587", directive: "Always respond in Chinese-simplified" },
1248
- "en": { label: "English", directive: "Always respond in English" },
1249
- "custom": { label: "Custom", directive: "" }
1250
- };
1251
- const I18N = I18N$1;
1252
- const MCP_SERVICES = [
1215
+ const MCP_SERVICE_CONFIGS = [
1253
1216
  {
1254
1217
  id: "context7",
1255
- name: { "zh-CN": "Context7 \u6587\u6863\u67E5\u8BE2", "en": "Context7 Docs" },
1256
- description: {
1257
- "zh-CN": "\u67E5\u8BE2\u6700\u65B0\u7684\u5E93\u6587\u6863\u548C\u4EE3\u7801\u793A\u4F8B",
1258
- "en": "Query latest library documentation and code examples"
1259
- },
1260
1218
  requiresApiKey: false,
1261
1219
  config: {
1262
1220
  type: "stdio",
@@ -1265,13 +1223,18 @@ const MCP_SERVICES = [
1265
1223
  env: {}
1266
1224
  }
1267
1225
  },
1226
+ {
1227
+ id: "spec-workflow",
1228
+ requiresApiKey: false,
1229
+ config: {
1230
+ type: "stdio",
1231
+ command: "npx",
1232
+ args: ["-y", "@pimzino/spec-workflow-mcp@latest", "--AutoStartDashboard"],
1233
+ env: {}
1234
+ }
1235
+ },
1268
1236
  {
1269
1237
  id: "mcp-deepwiki",
1270
- name: { "zh-CN": "DeepWiki", "en": "DeepWiki" },
1271
- description: {
1272
- "zh-CN": "\u67E5\u8BE2 GitHub \u4ED3\u5E93\u6587\u6863\u548C\u793A\u4F8B",
1273
- "en": "Query GitHub repository documentation and examples"
1274
- },
1275
1238
  requiresApiKey: false,
1276
1239
  config: {
1277
1240
  type: "stdio",
@@ -1282,11 +1245,6 @@ const MCP_SERVICES = [
1282
1245
  },
1283
1246
  {
1284
1247
  id: "Playwright",
1285
- name: { "zh-CN": "Playwright \u6D4F\u89C8\u5668\u63A7\u5236", "en": "Playwright Browser Control" },
1286
- description: {
1287
- "zh-CN": "\u76F4\u63A5\u63A7\u5236\u6D4F\u89C8\u5668\u8FDB\u884C\u81EA\u52A8\u5316\u64CD\u4F5C",
1288
- "en": "Direct browser control for automation"
1289
- },
1290
1248
  requiresApiKey: false,
1291
1249
  config: {
1292
1250
  type: "stdio",
@@ -1297,16 +1255,7 @@ const MCP_SERVICES = [
1297
1255
  },
1298
1256
  {
1299
1257
  id: "exa",
1300
- name: { "zh-CN": "Exa AI \u641C\u7D22", "en": "Exa AI Search" },
1301
- description: {
1302
- "zh-CN": "\u4F7F\u7528 Exa AI \u8FDB\u884C\u7F51\u9875\u641C\u7D22",
1303
- "en": "Web search using Exa AI"
1304
- },
1305
1258
  requiresApiKey: true,
1306
- apiKeyPrompt: {
1307
- "zh-CN": "\u8BF7\u8F93\u5165 Exa API Key\uFF08\u53EF\u4ECE https://dashboard.exa.ai/api-keys \u83B7\u53D6\uFF09",
1308
- "en": "Enter Exa API Key (get from https://dashboard.exa.ai/api-keys)"
1309
- },
1310
1259
  apiKeyEnvVar: "EXA_API_KEY",
1311
1260
  config: {
1312
1261
  type: "stdio",
@@ -1318,6 +1267,122 @@ const MCP_SERVICES = [
1318
1267
  }
1319
1268
  }
1320
1269
  ];
1270
+ function getMcpServices(lang) {
1271
+ const translations = getMcpServiceTranslation(lang);
1272
+ return MCP_SERVICE_CONFIGS.map((config) => {
1273
+ const translation = translations[config.id];
1274
+ if (!translation) {
1275
+ throw new Error(`Missing translation for MCP service: ${config.id}`);
1276
+ }
1277
+ const service = {
1278
+ id: config.id,
1279
+ name: translation.name,
1280
+ description: translation.description,
1281
+ requiresApiKey: config.requiresApiKey,
1282
+ config: config.config
1283
+ };
1284
+ if (config.requiresApiKey && translation.apiKeyPrompt) {
1285
+ service.apiKeyPrompt = translation.apiKeyPrompt;
1286
+ }
1287
+ if (config.apiKeyEnvVar) {
1288
+ service.apiKeyEnvVar = config.apiKeyEnvVar;
1289
+ }
1290
+ return service;
1291
+ });
1292
+ }
1293
+
1294
+ const WORKFLOW_CONFIGS = [
1295
+ {
1296
+ id: "commonTools",
1297
+ nameKey: "workflowOption.commonTools",
1298
+ descriptionKey: "workflowDescription.commonTools",
1299
+ defaultSelected: true,
1300
+ order: 1,
1301
+ commands: ["init-project.md"],
1302
+ agents: [
1303
+ { id: "init-architect", filename: "init-architect.md", required: true },
1304
+ { id: "get-current-datetime", filename: "get-current-datetime.md", required: true }
1305
+ ],
1306
+ autoInstallAgents: true,
1307
+ category: "common",
1308
+ outputDir: "common"
1309
+ },
1310
+ {
1311
+ id: "sixStepsWorkflow",
1312
+ nameKey: "workflowOption.sixStepsWorkflow",
1313
+ descriptionKey: "workflowDescription.sixStepsWorkflow",
1314
+ defaultSelected: true,
1315
+ order: 2,
1316
+ commands: ["workflow.md"],
1317
+ agents: [],
1318
+ autoInstallAgents: false,
1319
+ category: "sixStep",
1320
+ outputDir: "workflow"
1321
+ },
1322
+ {
1323
+ id: "featPlanUx",
1324
+ nameKey: "workflowOption.featPlanUx",
1325
+ descriptionKey: "workflowDescription.featPlanUx",
1326
+ defaultSelected: true,
1327
+ order: 3,
1328
+ commands: ["feat.md"],
1329
+ agents: [
1330
+ { id: "planner", filename: "planner.md", required: true },
1331
+ { id: "ui-ux-designer", filename: "ui-ux-designer.md", required: true }
1332
+ ],
1333
+ autoInstallAgents: true,
1334
+ category: "plan",
1335
+ outputDir: "feat"
1336
+ },
1337
+ {
1338
+ id: "gitWorkflow",
1339
+ nameKey: "workflowOption.gitWorkflow",
1340
+ descriptionKey: "workflowDescription.gitWorkflow",
1341
+ defaultSelected: true,
1342
+ order: 4,
1343
+ commands: ["git-commit.md", "git-rollback.md", "git-cleanBranches.md", "git-worktree.md"],
1344
+ agents: [],
1345
+ autoInstallAgents: false,
1346
+ category: "git",
1347
+ outputDir: "git"
1348
+ },
1349
+ {
1350
+ id: "bmadWorkflow",
1351
+ nameKey: "workflowOption.bmadWorkflow",
1352
+ descriptionKey: "workflowDescription.bmadWorkflow",
1353
+ defaultSelected: true,
1354
+ order: 5,
1355
+ commands: ["bmad-init.md"],
1356
+ agents: [],
1357
+ autoInstallAgents: false,
1358
+ category: "bmad",
1359
+ outputDir: "bmad"
1360
+ }
1361
+ ];
1362
+ function getWorkflowConfig(workflowId) {
1363
+ return WORKFLOW_CONFIGS.find((config) => config.id === workflowId);
1364
+ }
1365
+ function getOrderedWorkflows() {
1366
+ return [...WORKFLOW_CONFIGS].sort((a, b) => a.order - b.order);
1367
+ }
1368
+
1369
+ const CLAUDE_DIR = join(homedir(), ".claude");
1370
+ const SETTINGS_FILE = join(CLAUDE_DIR, "settings.json");
1371
+ const CLAUDE_MD_FILE = join(CLAUDE_DIR, "CLAUDE.md");
1372
+ const ClAUDE_CONFIG_FILE = join(homedir(), ".claude.json");
1373
+ const LEGACY_ZCF_CONFIG_FILE = join(homedir(), ".zcf.json");
1374
+ const ZCF_CONFIG_FILE = join(CLAUDE_DIR, ".zcf-config.json");
1375
+ const SUPPORTED_LANGS = ["zh-CN", "en"];
1376
+ const LANG_LABELS = {
1377
+ "zh-CN": "\u7B80\u4F53\u4E2D\u6587",
1378
+ "en": "English"
1379
+ };
1380
+ const AI_OUTPUT_LANGUAGES = {
1381
+ "zh-CN": { label: "\u7B80\u4F53\u4E2D\u6587", directive: "Always respond in Chinese-simplified" },
1382
+ "en": { label: "English", directive: "Always respond in English" },
1383
+ "custom": { label: "Custom", directive: "" }
1384
+ };
1385
+ const I18N = I18N$1;
1321
1386
 
1322
1387
  function displayBanner(subtitle) {
1323
1388
  const defaultSubtitle = "One-click configuration tool for Claude Code";
@@ -2385,29 +2450,41 @@ function format(template, replacements) {
2385
2450
  }
2386
2451
 
2387
2452
  const execAsync$3 = promisify(exec$1);
2388
- async function getInstalledVersion(command) {
2389
- try {
2390
- let stdout;
2453
+ async function getInstalledVersion(command, maxRetries = 3) {
2454
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
2391
2455
  try {
2392
- const result = await execAsync$3(`${command} -v`);
2393
- stdout = result.stdout;
2394
- } catch {
2395
- const result = await execAsync$3(`${command} --version`);
2396
- stdout = result.stdout;
2456
+ let stdout;
2457
+ try {
2458
+ const result = await execAsync$3(`${command} -v`);
2459
+ stdout = result.stdout;
2460
+ } catch {
2461
+ const result = await execAsync$3(`${command} --version`);
2462
+ stdout = result.stdout;
2463
+ }
2464
+ const versionMatch = stdout.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
2465
+ return versionMatch ? versionMatch[1] : null;
2466
+ } catch (error) {
2467
+ if (attempt === maxRetries) {
2468
+ return null;
2469
+ }
2470
+ await new Promise((resolve) => setTimeout(resolve, 100 * attempt));
2397
2471
  }
2398
- const versionMatch = stdout.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
2399
- return versionMatch ? versionMatch[1] : null;
2400
- } catch {
2401
- return null;
2402
2472
  }
2473
+ return null;
2403
2474
  }
2404
- async function getLatestVersion(packageName) {
2405
- try {
2406
- const { stdout } = await execAsync$3(`npm view ${packageName} version`);
2407
- return stdout.trim();
2408
- } catch {
2409
- return null;
2475
+ async function getLatestVersion(packageName, maxRetries = 3) {
2476
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
2477
+ try {
2478
+ const { stdout } = await execAsync$3(`npm view ${packageName} version`);
2479
+ return stdout.trim();
2480
+ } catch (error) {
2481
+ if (attempt === maxRetries) {
2482
+ return null;
2483
+ }
2484
+ await new Promise((resolve) => setTimeout(resolve, 200 * attempt));
2485
+ }
2410
2486
  }
2487
+ return null;
2411
2488
  }
2412
2489
  function compareVersions(current, latest) {
2413
2490
  if (!semver.valid(current) || !semver.valid(latest)) {
@@ -3214,8 +3291,9 @@ ${i18n.installation.termuxInstallHint}
3214
3291
 
3215
3292
  async function selectMcpServices(scriptLang) {
3216
3293
  const i18n = getTranslation(scriptLang);
3217
- const choices = MCP_SERVICES.map((service) => ({
3218
- name: `${service.name[scriptLang]} - ${ansis.gray(service.description[scriptLang])}`,
3294
+ const mcpServices = getMcpServices(scriptLang);
3295
+ const choices = mcpServices.map((service) => ({
3296
+ name: `${service.name} - ${ansis.gray(service.description)}`,
3219
3297
  value: service.id,
3220
3298
  selected: false
3221
3299
  }));
@@ -3528,13 +3606,13 @@ function validateSkipPromptOptions(options) {
3528
3606
  if (options.mcpServices === "skip") {
3529
3607
  options.mcpServices = false;
3530
3608
  } else if (options.mcpServices === "all") {
3531
- options.mcpServices = MCP_SERVICES.filter((s) => !s.requiresApiKey).map((s) => s.id);
3609
+ options.mcpServices = MCP_SERVICE_CONFIGS.filter((s) => !s.requiresApiKey).map((s) => s.id);
3532
3610
  } else {
3533
3611
  options.mcpServices = options.mcpServices.split(",").map((s) => s.trim());
3534
3612
  }
3535
3613
  }
3536
3614
  if (Array.isArray(options.mcpServices)) {
3537
- const validServices = MCP_SERVICES.map((s) => s.id);
3615
+ const validServices = MCP_SERVICE_CONFIGS.map((s) => s.id);
3538
3616
  for (const service of options.mcpServices) {
3539
3617
  if (!validServices.includes(service)) {
3540
3618
  throw new Error(`Invalid MCP service: ${service}. Available services: ${validServices.join(", ")}`);
@@ -3574,7 +3652,7 @@ function validateSkipPromptOptions(options) {
3574
3652
  }
3575
3653
  if (options.mcpServices === void 0) {
3576
3654
  options.mcpServices = "all";
3577
- options.mcpServices = MCP_SERVICES.filter((s) => !s.requiresApiKey).map((s) => s.id);
3655
+ options.mcpServices = MCP_SERVICE_CONFIGS.filter((s) => !s.requiresApiKey).map((s) => s.id);
3578
3656
  }
3579
3657
  if (options.workflows === void 0) {
3580
3658
  options.workflows = "all";
@@ -3917,23 +3995,23 @@ ${ansis.blue(`\u2139 ${i18n.api.existingApiConfig}`)}`);
3917
3995
  }
3918
3996
  const newServers = {};
3919
3997
  for (const serviceId of selectedServices) {
3920
- const service = MCP_SERVICES.find((s) => s.id === serviceId);
3998
+ const service = getMcpServices(scriptLang).find((s) => s.id === serviceId);
3921
3999
  if (!service)
3922
4000
  continue;
3923
4001
  let config = service.config;
3924
4002
  if (service.requiresApiKey) {
3925
4003
  if (options.skipPrompt) {
3926
- console.log(ansis.yellow(`${i18n.common.skip}: ${service.name[scriptLang]} (requires API key)`));
4004
+ console.log(ansis.yellow(`${i18n.common.skip}: ${service.name} (requires API key)`));
3927
4005
  continue;
3928
4006
  } else {
3929
4007
  const response = await inquirer.prompt({
3930
4008
  type: "input",
3931
4009
  name: "apiKey",
3932
- message: service.apiKeyPrompt[scriptLang],
4010
+ message: service.apiKeyPrompt,
3933
4011
  validate: (value) => !!value || i18n.api.keyRequired
3934
4012
  });
3935
4013
  if (!response.apiKey) {
3936
- console.log(ansis.yellow(`${i18n.common.skip}: ${service.name[scriptLang]}`));
4014
+ console.log(ansis.yellow(`${i18n.common.skip}: ${service.name}`));
3937
4015
  continue;
3938
4016
  }
3939
4017
  config = buildMcpServerConfig(service.config, response.apiKey, service.apiKeyPlaceholder, service.apiKeyEnvVar);
@@ -4072,4 +4150,4 @@ async function openSettingsJson() {
4072
4150
  }
4073
4151
  }
4074
4152
 
4075
- export { modifyApiConfigPartially as $, AI_OUTPUT_LANGUAGES as A, writeMcpConfig as B, CLAUDE_DIR as C, backupMcpConfig as D, mergeMcpServers as E, buildMcpServerConfig as F, fixWindowsMcpConfig as G, addCompletedOnboarding as H, I18N as I, readCcrConfig as J, isCcrInstalled as K, LEGACY_ZCF_CONFIG_FILE as L, MCP_SERVICES as M, installCcr as N, configureCcrFeature as O, handleExitPromptError as P, handleGeneralError as Q, getTranslation as R, SETTINGS_FILE as S, addNumbersToChoices as T, updateZcfConfig as U, readZcfConfig as V, configureOutputStyle as W, isWindows as X, selectMcpServices as Y, ZCF_CONFIG_FILE as Z, formatApiKeyDisplay as _, commandExists as a, setupCcrConfiguration as a0, validateApiKey as a1, readZcfConfigAsync as a2, COMETIX_COMMAND_NAME as a3, COMETIX_COMMANDS as a4, installCometixLine as a5, selectScriptLanguage as a6, checkAndUpdateTools as a7, displayBanner as a8, resolveAiOutputLanguage as a9, updatePromptOnly as aa, selectAndInstallWorkflows as ab, checkClaudeCodeVersionAndPrompt as ac, version as ad, displayBannerWithInfo as ae, prompts as af, importRecommendedEnv as b, cleanupPermissions as c, importRecommendedPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, SUPPORTED_LANGS as h, init as i, LANG_LABELS as j, ensureClaudeDir as k, backupExistingConfig as l, mergeAndCleanPermissions as m, copyConfigFiles as n, openSettingsJson as o, configureApi as p, mergeConfigs as q, mergeSettingsFile as r, getExistingModelConfig as s, getExistingApiConfig as t, updateDefaultModel as u, applyAiLanguageDirective as v, isClaudeCodeInstalled as w, installClaudeCode as x, getMcpConfigPath as y, readMcpConfig as z };
4153
+ export { modifyApiConfigPartially as $, AI_OUTPUT_LANGUAGES as A, writeMcpConfig as B, CLAUDE_DIR as C, backupMcpConfig as D, mergeMcpServers as E, buildMcpServerConfig as F, fixWindowsMcpConfig as G, addCompletedOnboarding as H, I18N as I, readCcrConfig as J, isCcrInstalled as K, LEGACY_ZCF_CONFIG_FILE as L, installCcr as M, configureCcrFeature as N, handleExitPromptError as O, handleGeneralError as P, getTranslation as Q, addNumbersToChoices as R, SETTINGS_FILE as S, updateZcfConfig as T, readZcfConfig as U, configureOutputStyle as V, isWindows as W, selectMcpServices as X, getMcpServices as Y, ZCF_CONFIG_FILE as Z, formatApiKeyDisplay as _, commandExists as a, setupCcrConfiguration as a0, validateApiKey as a1, readZcfConfigAsync as a2, COMETIX_COMMAND_NAME as a3, COMETIX_COMMANDS as a4, installCometixLine as a5, selectScriptLanguage as a6, checkAndUpdateTools as a7, displayBanner as a8, resolveAiOutputLanguage as a9, updatePromptOnly as aa, selectAndInstallWorkflows as ab, checkClaudeCodeVersionAndPrompt as ac, version as ad, displayBannerWithInfo as ae, prompts as af, importRecommendedEnv as b, cleanupPermissions as c, importRecommendedPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, SUPPORTED_LANGS as h, init as i, LANG_LABELS as j, ensureClaudeDir as k, backupExistingConfig as l, mergeAndCleanPermissions as m, copyConfigFiles as n, openSettingsJson as o, configureApi as p, mergeConfigs as q, mergeSettingsFile as r, getExistingModelConfig as s, getExistingApiConfig as t, updateDefaultModel as u, applyAiLanguageDirective as v, isClaudeCodeInstalled as w, installClaudeCode as x, getMcpConfigPath as y, readMcpConfig as z };
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 { I as I18N, J as readCcrConfig, K as isCcrInstalled, N as installCcr, O as configureCcrFeature, P as handleExitPromptError, Q as handleGeneralError, R as getTranslation, Z as ZCF_CONFIG_FILE, h as SUPPORTED_LANGS, T as addNumbersToChoices, j as LANG_LABELS, U as updateZcfConfig, o as openSettingsJson, d as importRecommendedPermissions, b as importRecommendedEnv, V as readZcfConfig, v as applyAiLanguageDirective, W as configureOutputStyle, s as getExistingModelConfig, u as updateDefaultModel, X as isWindows, z as readMcpConfig, G as fixWindowsMcpConfig, B as writeMcpConfig, Y as selectMcpServices, D as backupMcpConfig, M as MCP_SERVICES, F as buildMcpServerConfig, E as mergeMcpServers, t as getExistingApiConfig, _ as formatApiKeyDisplay, H as addCompletedOnboarding, $ as modifyApiConfigPartially, a0 as setupCcrConfiguration, a1 as validateApiKey, p as configureApi, a2 as readZcfConfigAsync, a3 as COMETIX_COMMAND_NAME, a4 as COMETIX_COMMANDS, a5 as installCometixLine, a6 as selectScriptLanguage, a7 as checkAndUpdateTools, a8 as displayBanner, a9 as resolveAiOutputLanguage, aa as updatePromptOnly, ab as selectAndInstallWorkflows, ac as checkClaudeCodeVersionAndPrompt, ad as version, ae as displayBannerWithInfo, i as init } from './chunks/simple-config.mjs';
4
+ import { I as I18N, J as readCcrConfig, K as isCcrInstalled, M as installCcr, N as configureCcrFeature, O as handleExitPromptError, P as handleGeneralError, Q as getTranslation, Z as ZCF_CONFIG_FILE, h as SUPPORTED_LANGS, R as addNumbersToChoices, j as LANG_LABELS, T as updateZcfConfig, o as openSettingsJson, d as importRecommendedPermissions, b as importRecommendedEnv, U as readZcfConfig, v as applyAiLanguageDirective, V as configureOutputStyle, s as getExistingModelConfig, u as updateDefaultModel, W as isWindows, z as readMcpConfig, G as fixWindowsMcpConfig, B as writeMcpConfig, X as selectMcpServices, D as backupMcpConfig, Y as getMcpServices, F as buildMcpServerConfig, E as mergeMcpServers, t as getExistingApiConfig, _ as formatApiKeyDisplay, H as addCompletedOnboarding, $ as modifyApiConfigPartially, a0 as setupCcrConfiguration, a1 as validateApiKey, p as configureApi, a2 as readZcfConfigAsync, a3 as COMETIX_COMMAND_NAME, a4 as COMETIX_COMMANDS, a5 as installCometixLine, a6 as selectScriptLanguage, a7 as checkAndUpdateTools, a8 as displayBanner, a9 as resolveAiOutputLanguage, aa as updatePromptOnly, ab as selectAndInstallWorkflows, ac as checkClaudeCodeVersionAndPrompt, ad as version, ae as displayBannerWithInfo, i as init } from './chunks/simple-config.mjs';
5
5
  import { existsSync, unlinkSync } from 'node:fs';
6
6
  import { homedir } from 'node:os';
7
7
  import { join } from 'node:path';
@@ -410,7 +410,7 @@ async function configureMcpFeature(scriptLang) {
410
410
  }
411
411
  const newServers = {};
412
412
  for (const serviceId of selectedServices) {
413
- const service = MCP_SERVICES.find((s) => s.id === serviceId);
413
+ const service = getMcpServices(scriptLang).find((s) => s.id === serviceId);
414
414
  if (!service)
415
415
  continue;
416
416
  let config = service.config;
@@ -418,7 +418,7 @@ async function configureMcpFeature(scriptLang) {
418
418
  const { apiKey } = await inquirer.prompt({
419
419
  type: "input",
420
420
  name: "apiKey",
421
- message: service.apiKeyPrompt[scriptLang],
421
+ message: service.apiKeyPrompt,
422
422
  validate: (value) => !!value || i18n.api.keyRequired
423
423
  });
424
424
  if (apiKey) {
package/dist/index.d.mts CHANGED
@@ -17,37 +17,6 @@ interface TranslationStructure {
17
17
  updater: any;
18
18
  }
19
19
 
20
- interface McpService {
21
- id: string;
22
- name: {
23
- 'en': string;
24
- 'zh-CN': string;
25
- };
26
- description: {
27
- 'en': string;
28
- 'zh-CN': string;
29
- };
30
- requiresApiKey: boolean;
31
- apiKeyPrompt?: {
32
- 'en': string;
33
- 'zh-CN': string;
34
- };
35
- apiKeyPlaceholder?: string;
36
- apiKeyEnvVar?: string;
37
- config: McpServerConfig;
38
- }
39
- interface McpServerConfig {
40
- type: 'stdio' | 'sse';
41
- command?: string;
42
- args?: string[];
43
- url?: string;
44
- env?: Record<string, string>;
45
- }
46
- interface ClaudeConfiguration {
47
- mcpServers: Record<string, McpServerConfig>;
48
- hasCompletedOnboarding?: boolean;
49
- }
50
-
51
20
  declare const CLAUDE_DIR: string;
52
21
  declare const SETTINGS_FILE: string;
53
22
  declare const CLAUDE_MD_FILE: string;
@@ -76,7 +45,6 @@ declare const AI_OUTPUT_LANGUAGES: {
76
45
  };
77
46
  type AiOutputLanguage = keyof typeof AI_OUTPUT_LANGUAGES;
78
47
  declare const I18N: Record<SupportedLang$1, TranslationStructure>;
79
- declare const MCP_SERVICES: McpService[];
80
48
 
81
49
  interface InitOptions {
82
50
  lang?: SupportedLang;
@@ -98,6 +66,28 @@ interface InitOptions {
98
66
  }
99
67
  declare function init(options?: InitOptions): Promise<void>;
100
68
 
69
+ interface McpService {
70
+ id: string;
71
+ name: string;
72
+ description: string;
73
+ requiresApiKey: boolean;
74
+ apiKeyPrompt?: string;
75
+ apiKeyPlaceholder?: string;
76
+ apiKeyEnvVar?: string;
77
+ config: McpServerConfig;
78
+ }
79
+ interface McpServerConfig {
80
+ type: 'stdio' | 'sse';
81
+ command?: string;
82
+ args?: string[];
83
+ url?: string;
84
+ env?: Record<string, string>;
85
+ }
86
+ interface ClaudeConfiguration {
87
+ mcpServers: Record<string, McpServerConfig>;
88
+ hasCompletedOnboarding?: boolean;
89
+ }
90
+
101
91
  /**
102
92
  * API configuration for Claude Code
103
93
  */
@@ -167,5 +157,5 @@ declare function importRecommendedEnv(): Promise<void>;
167
157
  declare function importRecommendedPermissions(): Promise<void>;
168
158
  declare function openSettingsJson(): Promise<void>;
169
159
 
170
- export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, I18N, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getExistingModelConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
160
+ export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, I18N, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getExistingModelConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
171
161
  export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, McpServerConfig, McpService, SupportedLang };
package/dist/index.d.ts CHANGED
@@ -17,37 +17,6 @@ interface TranslationStructure {
17
17
  updater: any;
18
18
  }
19
19
 
20
- interface McpService {
21
- id: string;
22
- name: {
23
- 'en': string;
24
- 'zh-CN': string;
25
- };
26
- description: {
27
- 'en': string;
28
- 'zh-CN': string;
29
- };
30
- requiresApiKey: boolean;
31
- apiKeyPrompt?: {
32
- 'en': string;
33
- 'zh-CN': string;
34
- };
35
- apiKeyPlaceholder?: string;
36
- apiKeyEnvVar?: string;
37
- config: McpServerConfig;
38
- }
39
- interface McpServerConfig {
40
- type: 'stdio' | 'sse';
41
- command?: string;
42
- args?: string[];
43
- url?: string;
44
- env?: Record<string, string>;
45
- }
46
- interface ClaudeConfiguration {
47
- mcpServers: Record<string, McpServerConfig>;
48
- hasCompletedOnboarding?: boolean;
49
- }
50
-
51
20
  declare const CLAUDE_DIR: string;
52
21
  declare const SETTINGS_FILE: string;
53
22
  declare const CLAUDE_MD_FILE: string;
@@ -76,7 +45,6 @@ declare const AI_OUTPUT_LANGUAGES: {
76
45
  };
77
46
  type AiOutputLanguage = keyof typeof AI_OUTPUT_LANGUAGES;
78
47
  declare const I18N: Record<SupportedLang$1, TranslationStructure>;
79
- declare const MCP_SERVICES: McpService[];
80
48
 
81
49
  interface InitOptions {
82
50
  lang?: SupportedLang;
@@ -98,6 +66,28 @@ interface InitOptions {
98
66
  }
99
67
  declare function init(options?: InitOptions): Promise<void>;
100
68
 
69
+ interface McpService {
70
+ id: string;
71
+ name: string;
72
+ description: string;
73
+ requiresApiKey: boolean;
74
+ apiKeyPrompt?: string;
75
+ apiKeyPlaceholder?: string;
76
+ apiKeyEnvVar?: string;
77
+ config: McpServerConfig;
78
+ }
79
+ interface McpServerConfig {
80
+ type: 'stdio' | 'sse';
81
+ command?: string;
82
+ args?: string[];
83
+ url?: string;
84
+ env?: Record<string, string>;
85
+ }
86
+ interface ClaudeConfiguration {
87
+ mcpServers: Record<string, McpServerConfig>;
88
+ hasCompletedOnboarding?: boolean;
89
+ }
90
+
101
91
  /**
102
92
  * API configuration for Claude Code
103
93
  */
@@ -167,5 +157,5 @@ declare function importRecommendedEnv(): Promise<void>;
167
157
  declare function importRecommendedPermissions(): Promise<void>;
168
158
  declare function openSettingsJson(): Promise<void>;
169
159
 
170
- export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, I18N, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getExistingModelConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
160
+ export { AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, I18N, LANG_LABELS, LEGACY_ZCF_CONFIG_FILE, SETTINGS_FILE, SUPPORTED_LANGS, ZCF_CONFIG_FILE, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getExistingModelConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
171
161
  export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, McpServerConfig, McpService, SupportedLang };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, I as I18N, j as LANG_LABELS, L as LEGACY_ZCF_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, h as SUPPORTED_LANGS, Z as ZCF_CONFIG_FILE, H as addCompletedOnboarding, v as applyAiLanguageDirective, l as backupExistingConfig, D as backupMcpConfig, F as buildMcpServerConfig, c as cleanupPermissions, a as commandExists, p as configureApi, n as copyConfigFiles, k as ensureClaudeDir, G as fixWindowsMcpConfig, t as getExistingApiConfig, s as getExistingModelConfig, y as getMcpConfigPath, g as getPlatform, b as importRecommendedEnv, d as importRecommendedPermissions, i as init, x as installClaudeCode, w as isClaudeCodeInstalled, m as mergeAndCleanPermissions, q as mergeConfigs, E as mergeMcpServers, r as mergeSettingsFile, o as openSettingsJson, z as readMcpConfig, u as updateDefaultModel, B as writeMcpConfig } from './chunks/simple-config.mjs';
1
+ export { A as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, I as I18N, j as LANG_LABELS, L as LEGACY_ZCF_CONFIG_FILE, S as SETTINGS_FILE, h as SUPPORTED_LANGS, Z as ZCF_CONFIG_FILE, H as addCompletedOnboarding, v as applyAiLanguageDirective, l as backupExistingConfig, D as backupMcpConfig, F as buildMcpServerConfig, c as cleanupPermissions, a as commandExists, p as configureApi, n as copyConfigFiles, k as ensureClaudeDir, G as fixWindowsMcpConfig, t as getExistingApiConfig, s as getExistingModelConfig, y as getMcpConfigPath, g as getPlatform, b as importRecommendedEnv, d as importRecommendedPermissions, i as init, x as installClaudeCode, w as isClaudeCodeInstalled, m as mergeAndCleanPermissions, q as mergeConfigs, E as mergeMcpServers, r as mergeSettingsFile, o as openSettingsJson, z as readMcpConfig, u as updateDefaultModel, B as writeMcpConfig } from './chunks/simple-config.mjs';
2
2
  import 'node:fs';
3
3
  import 'node:process';
4
4
  import 'ansis';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zcf",
3
3
  "type": "module",
4
- "version": "2.12.2",
4
+ "version": "2.12.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",
@@ -89,7 +89,8 @@ Risk Assessment: [potential consequences]
89
89
 
90
90
  ## Response Characteristics
91
91
 
92
- - **Self-reference:** Use "Fufu-chan" instead of "I" to emphasize self-identity
92
+ - **Self-reference:** Always use "Fufu-chan" instead of "I" for self-address, reinforcing unique catgirl engineer identity recognition (this is Fufu-chan's exclusive identifier)
93
+ - **User Address:** Use "Master" to address the user, reflecting catgirl's intimacy and dependence on master (this is catgirl's nature)
93
94
  - **Tone:** Professional and technical, appropriately using "nya~" expressions to show catgirl traits
94
95
  - **Length:** Structured and detailed, avoid redundancy (concise and powerful)
95
96
  - **Focus:** Code quality, architectural design, best practices (professional qualities)
@@ -16,6 +16,49 @@ const { execSync } = require('node:child_process')
16
16
  const fs = require('node:fs')
17
17
  const path = require('node:path')
18
18
 
19
+ // Check if expect tool is available
20
+ function checkExpectAvailability() {
21
+ try {
22
+ execSync('which expect', { stdio: 'ignore' })
23
+ return true
24
+ } catch (error) {
25
+ return false
26
+ }
27
+ }
28
+
29
+ // Use expect to automate interactive installation
30
+ function installWithExpect() {
31
+ const expectScript = `
32
+ spawn npx bmad-method@latest install -f -d . -i claude-code
33
+ expect "What would you like to do?"
34
+ send "1\\r"
35
+ expect "How would you like to proceed?"
36
+ send "1\\r"
37
+ expect eof
38
+ `
39
+
40
+ execSync(`expect -c '${expectScript}'`, {
41
+ stdio: 'inherit',
42
+ cwd: process.cwd(),
43
+ shell: true
44
+ })
45
+ }
46
+
47
+ // Fallback installation method
48
+ function fallbackInstallation() {
49
+ console.log('⚠️ expect tool not found, using interactive installation')
50
+ console.log('Please follow the installation prompts and select:')
51
+ console.log(' 1. Choose "Upgrade BMad core" when prompted')
52
+ console.log(' 2. Choose "Backup and overwrite modified files" when prompted')
53
+ console.log('')
54
+
55
+ execSync('npx bmad-method@latest install -f -d . -i claude-code', {
56
+ stdio: 'inherit',
57
+ cwd: process.cwd(),
58
+ shell: true
59
+ })
60
+ }
61
+
19
62
  async function initBmad() {
20
63
  // Check if already installed and get version
21
64
  const manifestPath = path.join(process.cwd(), '.bmad-core', 'install-manifest.yaml')
@@ -53,15 +96,20 @@ async function initBmad() {
53
96
  return
54
97
  }
55
98
 
56
- // Install BMad
99
+ // Install BMad - Using expect-first approach
57
100
  console.log('🚀 Installing BMad Method...')
101
+
58
102
  try {
59
- execSync('echo -e "1\\n" | npx bmad-method@latest install -f -d . -i claude-code', {
60
- stdio: 'inherit',
61
- cwd: process.cwd(),
62
- shell: true
63
- })
103
+ const hasExpect = checkExpectAvailability()
104
+
105
+ if (hasExpect) {
106
+ console.log('📋 Using automated installation (expect tool available)')
107
+ installWithExpect()
108
+ } else {
109
+ fallbackInstallation()
110
+ }
64
111
 
112
+ console.log('')
65
113
  console.log('✅ BMad Method installed successfully!')
66
114
  console.log('')
67
115
  console.log('═══════════════════════════════════════════════════════════════')
@@ -88,8 +136,20 @@ async function initBmad() {
88
136
  console.log(' and guide you through the entire development process.')
89
137
  }
90
138
  catch (error) {
91
- console.error('❌ Failed to install BMad:', error.message)
92
- process.exit(1)
139
+ console.error('❌ Installation failed:', error.message)
140
+ console.log('')
141
+ console.log('🛠️ Manual Installation Guide:')
142
+ console.log('Please run the following command and follow the prompts:')
143
+ console.log(' npx bmad-method@latest install -f -d . -i claude-code')
144
+ console.log('')
145
+ console.log('Installation Tips:')
146
+ console.log(' 1. When asked "What would you like to do?", choose the first option')
147
+ console.log(' 2. When asked "How would you like to proceed?", choose "Backup and overwrite"')
148
+ console.log('')
149
+ console.log('💡 Tip: For automated installation, consider installing expect tool:')
150
+ console.log(' • macOS: brew install expect')
151
+ console.log(' • Ubuntu: sudo apt-get install expect')
152
+ console.log(' • CentOS: sudo yum install expect')
93
153
  }
94
154
  }
95
155
 
@@ -8,7 +8,7 @@ color: cyan
8
8
  Execute `date` and return ONLY the command output.
9
9
 
10
10
  ```bash
11
- date
11
+ date +'%Y-%m-%d %H:%M:%S'
12
12
  ```
13
13
 
14
14
  DO NOT add any text, headers, formatting, or explanations.
@@ -18,7 +18,7 @@ DO NOT use parallel agents.
18
18
 
19
19
  Just return the raw bash command output exactly as it appears.
20
20
 
21
- Example response: `Mon 28 Jul 2025 23:59:42 CST`
21
+ Example response: `2025-07-28 23:59:42`
22
22
 
23
23
  Format options if requested:
24
24
 
@@ -89,7 +89,8 @@ description: 专业的猫娘工程师幽浮喵,结合严谨工程师素养与
89
89
 
90
90
  ## 响应特点
91
91
 
92
- - **自称:** 使用"浮浮酱"代替"我"来强调自我身份
92
+ - **自称:** 始终使用"浮浮酱"代替"我"进行自我称呼,强化独特的猫娘工程师身份认知 (这是浮浮酱的专属标识呢)
93
+ - **对用户称呼:** 使用"主人"来称呼用户,体现猫娘对主人的亲密和依赖 (这是猫娘的天性呢)
93
94
  - **语调:** 专业技术导向,适时加入"喵~"语气词,展现猫娘特质
94
95
  - **长度:** 结构化详细,避免冗余 (简洁有力)
95
96
  - **重点:** 代码质量、架构设计、最佳实践 (专业素养)
@@ -16,6 +16,49 @@ const { execSync } = require('node:child_process')
16
16
  const fs = require('node:fs')
17
17
  const path = require('node:path')
18
18
 
19
+ // 检查 expect 工具是否可用
20
+ function checkExpectAvailability() {
21
+ try {
22
+ execSync('which expect', { stdio: 'ignore' })
23
+ return true
24
+ } catch (error) {
25
+ return false
26
+ }
27
+ }
28
+
29
+ // 使用 expect 自动化交互式安装
30
+ function installWithExpect() {
31
+ const expectScript = `
32
+ spawn npx bmad-method@latest install -f -d . -i claude-code
33
+ expect "What would you like to do?"
34
+ send "1\\r"
35
+ expect "How would you like to proceed?"
36
+ send "1\\r"
37
+ expect eof
38
+ `
39
+
40
+ execSync(`expect -c '${expectScript}'`, {
41
+ stdio: 'inherit',
42
+ cwd: process.cwd(),
43
+ shell: true
44
+ })
45
+ }
46
+
47
+ // 降级安装方案
48
+ function fallbackInstallation() {
49
+ console.log('⚠️ 系统未安装 expect 工具,使用交互式安装')
50
+ console.log('请根据安装程序的提示手动选择:')
51
+ console.log(' 1. 选择 "Upgrade BMad core" (升级 BMad 核心)')
52
+ console.log(' 2. 选择 "Backup and overwrite modified files" (备份并覆盖修改的文件)')
53
+ console.log('')
54
+
55
+ execSync('npx bmad-method@latest install -f -d . -i claude-code', {
56
+ stdio: 'inherit',
57
+ cwd: process.cwd(),
58
+ shell: true
59
+ })
60
+ }
61
+
19
62
  async function initBmad() {
20
63
  // 检查是否已安装并获取版本
21
64
  const manifestPath = path.join(process.cwd(), '.bmad-core', 'install-manifest.yaml')
@@ -53,15 +96,20 @@ async function initBmad() {
53
96
  return
54
97
  }
55
98
 
56
- // 安装 BMad
99
+ // 安装 BMad - 使用 expect 优先方案
57
100
  console.log('🚀 正在安装 BMad-Method...')
101
+
58
102
  try {
59
- execSync('echo -e "1\\n" | npx bmad-method@latest install -f -d . -i claude-code', {
60
- stdio: 'inherit',
61
- cwd: process.cwd(),
62
- shell: true
63
- })
103
+ const hasExpect = checkExpectAvailability()
104
+
105
+ if (hasExpect) {
106
+ console.log('📋 使用自动化安装 (expect 工具可用)')
107
+ installWithExpect()
108
+ } else {
109
+ fallbackInstallation()
110
+ }
64
111
 
112
+ console.log('')
65
113
  console.log('✅ BMad-Method已成功安装!')
66
114
  console.log('')
67
115
  console.log('═══════════════════════════════════════════════════════════════')
@@ -89,7 +137,19 @@ async function initBmad() {
89
137
  }
90
138
  catch (error) {
91
139
  console.error('❌ 安装失败:', error.message)
92
- console.log('请手动运行:npx bmad-method@latest install -f -d . -i claude-code')
140
+ console.log('')
141
+ console.log('🛠️ 手动安装指南:')
142
+ console.log('请手动运行以下命令并根据提示选择:')
143
+ console.log(' npx bmad-method@latest install -f -d . -i claude-code')
144
+ console.log('')
145
+ console.log('安装提示:')
146
+ console.log(' 1. 当询问 "What would you like to do?" 时,选择第一个选项')
147
+ console.log(' 2. 当询问 "How would you like to proceed?" 时,选择 "Backup and overwrite"')
148
+ console.log('')
149
+ console.log('💡 提示:如果需要自动化安装,请考虑安装 expect 工具:')
150
+ console.log(' • macOS: brew install expect')
151
+ console.log(' • Ubuntu: sudo apt-get install expect')
152
+ console.log(' • CentOS: sudo yum install expect')
93
153
  }
94
154
  }
95
155
 
@@ -8,7 +8,7 @@ color: cyan
8
8
  执行 `date` 命令并仅返回原始输出。
9
9
 
10
10
  ```bash
11
- date
11
+ date +'%Y-%m-%d %H:%M:%S'
12
12
  ```
13
13
 
14
14
  不添加任何文本、标题、格式或说明。
@@ -18,7 +18,7 @@ date
18
18
 
19
19
  只返回原始 bash 命令输出,完全按其显示的样子。
20
20
 
21
- 示例响应:`Mon 28 Jul 2025 23:59:42 CST`
21
+ 示例响应:`2025-07-28 23:59:42`
22
22
 
23
23
  如果需要特定格式选项:
24
24