ccg-workflow 1.7.67 → 1.7.69

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.
@@ -10,7 +10,7 @@ import i18next from 'i18next';
10
10
  import ora from 'ora';
11
11
  import { parse, stringify } from 'smol-toml';
12
12
 
13
- const version = "1.7.67";
13
+ const version = "1.7.69";
14
14
 
15
15
  function isWindows() {
16
16
  return process.platform === "win32";
@@ -1231,14 +1231,26 @@ const zhCN = {
1231
1231
  loading: "\u52A0\u8F7D\u4E2D...",
1232
1232
  processing: "\u5904\u7406\u4E2D...",
1233
1233
  completed: "\u5DF2\u5B8C\u6210",
1234
- failed: "\u5931\u8D25"
1234
+ failed: "\u5931\u8D25",
1235
+ goodbye: "\u518D\u89C1\uFF01",
1236
+ pressEnterToReturn: "\u6309 Enter \u8FD4\u56DE\u4E3B\u83DC\u5355...",
1237
+ cancelled: "\u5DF2\u53D6\u6D88",
1238
+ configNotModified: "\u672A\u4FEE\u6539\u914D\u7F6E",
1239
+ configSaved: "\u914D\u7F6E\u5DF2\u4FDD\u5B58",
1240
+ configFile: "\u914D\u7F6E\u6587\u4EF6",
1241
+ restartToApply: "\u91CD\u542F Claude Code CLI \u4F7F\u914D\u7F6E\u751F\u6548",
1242
+ unknownSubcommand: "\u672A\u77E5\u5B50\u547D\u4EE4: {{subcommand}}",
1243
+ availableSubcommands: "\u53EF\u7528\u5B50\u547D\u4EE4: {{list}}"
1235
1244
  },
1236
1245
  cli: {
1237
1246
  help: {
1238
1247
  commands: "\u547D\u4EE4",
1239
1248
  commandDescriptions: {
1240
1249
  showMenu: "\u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355\uFF08\u9ED8\u8BA4\uFF09",
1241
- initConfig: "\u521D\u59CB\u5316 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF"
1250
+ initConfig: "\u521D\u59CB\u5316 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF",
1251
+ configMcp: "\u914D\u7F6E MCP Token",
1252
+ diagnoseMcp: "\u8BCA\u65AD MCP \u914D\u7F6E\u95EE\u9898",
1253
+ fixMcp: "\u4FEE\u590D Windows MCP \u914D\u7F6E"
1242
1254
  },
1243
1255
  shortcuts: "\u5FEB\u6377\u65B9\u5F0F:",
1244
1256
  shortcutDescriptions: {
@@ -1269,7 +1281,8 @@ const zhCN = {
1269
1281
  },
1270
1282
  init: {
1271
1283
  welcome: "\u6B22\u8FCE\u4F7F\u7528 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF",
1272
- selectLanguage: "\u8BF7\u9009\u62E9\u8BED\u8A00",
1284
+ subtitle: "\u591A\u6A21\u578B\u534F\u4F5C\u5F00\u53D1\u5DE5\u4F5C\u6D41",
1285
+ selectLanguage: "\u9009\u62E9\u8BED\u8A00 / Select language",
1273
1286
  selectFrontendModels: "\u9009\u62E9\u524D\u7AEF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u53EF\u591A\u9009\uFF09",
1274
1287
  selectBackendModels: "\u9009\u62E9\u540E\u7AEF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u53EF\u591A\u9009\uFF09",
1275
1288
  selectMode: "\u9009\u62E9\u534F\u4F5C\u6A21\u5F0F",
@@ -1307,8 +1320,86 @@ const zhCN = {
1307
1320
  backendModels: "\u540E\u7AEF\u6A21\u578B:",
1308
1321
  collaboration: "\u534F\u4F5C\u6A21\u5F0F:",
1309
1322
  workflows: "\u5DE5\u4F5C\u6D41:",
1310
- selected: "\u4E2A\u5DF2\u9009\u62E9"
1323
+ selected: "\u4E2A\u5DF2\u9009\u62E9",
1324
+ modelRouting: "\u6A21\u578B\u8DEF\u7531",
1325
+ commandCount: "\u547D\u4EE4\u6570\u91CF",
1326
+ mcpTool: "MCP \u5DE5\u5177",
1327
+ webUI: "Web UI",
1328
+ pendingConfig: "\u5F85\u914D\u7F6E",
1329
+ skipped: "\u8DF3\u8FC7",
1330
+ enabled: "\u542F\u7528",
1331
+ disabled: "\u7981\u7528"
1311
1332
  },
1333
+ mcp: {
1334
+ title: "MCP \u4EE3\u7801\u68C0\u7D22\u5DE5\u5177\u914D\u7F6E",
1335
+ selectProvider: "\u9009\u62E9\u4EE3\u7801\u68C0\u7D22 MCP \u5DE5\u5177",
1336
+ contextweaver: "\u672C\u5730\u5411\u91CF\u5E93\uFF0C\u6DF7\u5408\u641C\u7D22 + Rerank",
1337
+ aceToolPaid: "Augment \u5B98\u65B9",
1338
+ aceToolRsPaid: "\u66F4\u8F7B\u91CF",
1339
+ skipLater: "\u7A0D\u540E\u624B\u52A8\u914D\u7F6E",
1340
+ skipTokenPrompt: "\u662F\u5426\u8DF3\u8FC7 Token \u914D\u7F6E\uFF1F\uFF08\u53EF\u7A0D\u540E\u8FD0\u884C npx ccg config mcp \u914D\u7F6E\uFF09",
1341
+ skipKeyPrompt: "\u662F\u5426\u8DF3\u8FC7 API Key \u914D\u7F6E\uFF1F\uFF08\u53EF\u7A0D\u540E\u8FD0\u884C npx ccg config mcp \u914D\u7F6E\uFF09",
1342
+ tokenSkipped: "\u5DF2\u8DF3\u8FC7 Token \u914D\u7F6E",
1343
+ keySkipped: "\u5DF2\u8DF3\u8FC7 API Key \u914D\u7F6E",
1344
+ notInstalled: "\u672A\u5B89\u88C5",
1345
+ keyNotProvided: "API Key \u672A\u63D0\u4F9B",
1346
+ tokenNotProvided: "Token \u672A\u63D0\u4F9B",
1347
+ configLater: "\u53EF\u7A0D\u540E\u8FD0\u884C {{cmd}} \u914D\u7F6E",
1348
+ getAccess: "\u83B7\u53D6 ace-tool \u8BBF\u95EE\u65B9\u5F0F\uFF1A",
1349
+ officialService: "\u5B98\u65B9\u670D\u52A1",
1350
+ proxyService: "\u4E2D\u8F6C\u670D\u52A1",
1351
+ noSignup: "\u65E0\u9700\u6CE8\u518C",
1352
+ registerForToken: "\u6CE8\u518C\u8D26\u53F7\u540E\u83B7\u53D6 Token",
1353
+ communityProxy: "\u793E\u533A\u63D0\u4F9B\u7684\u514D\u8D39\u4E2D\u8F6C\u670D\u52A1",
1354
+ getApiKey: "\u83B7\u53D6\u7845\u57FA\u6D41\u52A8 API Key\uFF1A",
1355
+ siliconflowStep1: "\u8BBF\u95EE {{url}} \u6CE8\u518C\u8D26\u53F7",
1356
+ siliconflowStep2: "\u8FDB\u5165\u63A7\u5236\u53F0 \u2192 API \u5BC6\u94A5 \u2192 \u521B\u5EFA\u5BC6\u94A5",
1357
+ siliconflowStep3: "\u65B0\u7528\u6237\u6709\u514D\u8D39\u989D\u5EA6\uFF0CEmbedding + Rerank \u5B8C\u5168\u591F\u7528",
1358
+ baseUrlHint: "\u4F7F\u7528\u4E2D\u8F6C\u670D\u52A1\u65F6\u5FC5\u586B\uFF0C\u5B98\u65B9\u670D\u52A1\u7559\u7A7A",
1359
+ tokenRequired: "\u5FC5\u586B",
1360
+ enterToken: "\u8BF7\u8F93\u5165 Token",
1361
+ enterApiKey: "\u8BF7\u8F93\u5165 API Key",
1362
+ mcpSkipped: "\u5DF2\u8DF3\u8FC7 MCP \u914D\u7F6E",
1363
+ configManually: "\u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1",
1364
+ mcpOptions: "MCP \u670D\u52A1\u9009\u9879",
1365
+ mcpOptionsHint: "\u5982\u9700\u4F7F\u7528\u4EE3\u7801\u68C0\u7D22\u529F\u80FD\uFF0C\u53EF\u9009\u62E9\u4EE5\u4E0B MCP \u670D\u52A1\uFF1A",
1366
+ promptEnhancement: "Prompt \u589E\u5F3A + \u4EE3\u7801\u68C0\u7D22",
1367
+ localEngine: "\u672C\u5730\u8BED\u4E49\u4EE3\u7801\u68C0\u7D22\u5F15\u64CE\uFF0C\u6DF7\u5408\u641C\u7D22 + Rerank",
1368
+ freeQuota: "\u6709\u514D\u8D39\u989D\u5EA6",
1369
+ cwConfiguring: "\u6B63\u5728\u914D\u7F6E ContextWeaver MCP...",
1370
+ cwFailed: "ContextWeaver MCP \u914D\u7F6E\u5931\u8D25",
1371
+ cwConfigFile: "\u914D\u7F6E\u6587\u4EF6",
1372
+ cwIndexHint: "\u9996\u6B21\u4F7F\u7528\u9700\u8981\u7D22\u5F15\u4EE3\u7801\u5E93\uFF1A"
1373
+ },
1374
+ api: {
1375
+ title: "Claude Code API \u914D\u7F6E",
1376
+ configurePrompt: "\u662F\u5426\u914D\u7F6E\u81EA\u5B9A\u4E49 API\uFF1F\uFF08\u4F7F\u7528\u5B98\u65B9\u8D26\u53F7\u53EF\u8DF3\u8FC7\uFF09",
1377
+ urlPrompt: "API URL",
1378
+ urlRequired: "\u5FC5\u586B",
1379
+ keyPrompt: "API Key",
1380
+ keyRequired: "\u5FC5\u586B",
1381
+ enterUrl: "\u8BF7\u8F93\u5165 API URL",
1382
+ enterKey: "\u8BF7\u8F93\u5165 API Key",
1383
+ useOfficialHint: "\u4F7F\u7528\u5B98\u65B9\u8D26\u53F7\u53EF\u8DF3\u8FC7",
1384
+ leaveEmptyForOfficial: "\u7559\u7A7A\u4F7F\u7528\u5B98\u65B9",
1385
+ leaveEmptyToSkip: "\u7559\u7A7A\u8DF3\u8FC7"
1386
+ },
1387
+ webui: {
1388
+ prompt: "\u542F\u7528 Web UI \u5B9E\u65F6\u8F93\u51FA\uFF1F",
1389
+ disableHint: "\u7981\u7528\u53EF\u52A0\u901F\u54CD\u5E94"
1390
+ },
1391
+ hooks: {
1392
+ title: "codeagent-wrapper \u81EA\u52A8\u6388\u6743",
1393
+ description: "\u4F7F\u7528 Hook \u81EA\u52A8\u6388\u6743 codeagent-wrapper \u547D\u4EE4",
1394
+ installed: "Hook \u5DF2\u914D\u7F6E\uFF08\u81EA\u52A8\u6388\u6743 codeagent-wrapper\uFF09",
1395
+ jqRequired: "\u81EA\u52A8\u6388\u6743\u9700\u8981 jq \u547D\u4EE4",
1396
+ jqInstallHint: "\u5B89\u88C5\u65B9\u6CD5",
1397
+ jqMac: "macOS: brew install jq",
1398
+ jqLinux: "Linux: sudo apt install jq / sudo yum install jq",
1399
+ jqWindows: "Windows: choco install jq / scoop install jq",
1400
+ jqNotFound: "\u672A\u68C0\u6D4B\u5230 jq\uFF0CHook \u5DF2\u5199\u5165\u4F46\u9700\u5B89\u88C5 jq \u540E\u751F\u6548"
1401
+ },
1402
+ addToPathManually: "\u8BF7\u624B\u52A8\u6DFB\u52A0\u5230 shell \u914D\u7F6E:",
1312
1403
  modes: {
1313
1404
  parallel: "\u5E76\u884C\u6A21\u5F0F - \u540C\u65F6\u8C03\u7528\u591A\u4E2A\u6A21\u578B",
1314
1405
  smart: "\u667A\u80FD\u6A21\u5F0F - \u6839\u636E\u4EFB\u52A1\u7C7B\u578B\u81EA\u52A8\u9009\u62E9",
@@ -1352,11 +1443,60 @@ const zhCN = {
1352
1443
  failed: "ace-tool-rs \u914D\u7F6E\u5931\u8D25\uFF08\u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\uFF09"
1353
1444
  }
1354
1445
  },
1446
+ update: {
1447
+ checking: "\u68C0\u67E5\u66F4\u65B0...",
1448
+ checkingLatest: "\u6B63\u5728\u68C0\u67E5\u6700\u65B0\u7248\u672C...",
1449
+ cannotConnect: "\u65E0\u6CD5\u8FDE\u63A5\u5230 npm registry\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5",
1450
+ currentVersion: "\u5F53\u524D\u7248\u672C",
1451
+ latestVersion: "\u6700\u65B0\u7248\u672C",
1452
+ localWorkflow: "\u672C\u5730\u5DE5\u4F5C\u6D41",
1453
+ newVersionFound: "\u53D1\u73B0\u65B0\u7248\u672C v{{latest}} (\u5F53\u524D: v{{current}})\uFF0C\u662F\u5426\u66F4\u65B0\uFF1F",
1454
+ localOutdated: "\u68C0\u6D4B\u5230\u672C\u5730\u5DE5\u4F5C\u6D41\u7248\u672C (v{{local}}) \u4F4E\u4E8E\u5F53\u524D\u7248\u672C (v{{current}})\uFF0C\u662F\u5426\u66F4\u65B0\uFF1F",
1455
+ alreadyLatest: "\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C (v{{current}})\u3002\u662F\u5426\u5F3A\u5236\u91CD\u65B0\u5B89\u88C5/\u4FEE\u590D\u5DE5\u4F5C\u6D41\uFF1F",
1456
+ cancelled: "\u5DF2\u53D6\u6D88\u66F4\u65B0",
1457
+ starting: "\u5F00\u59CB\u66F4\u65B0...",
1458
+ globalDetected: "\u68C0\u6D4B\u5230\u4F60\u662F\u901A\u8FC7 npm \u5168\u5C40\u5B89\u88C5\u7684",
1459
+ packageLatest: "\u5F53\u524D\u5305\u7248\u672C\u5DF2\u662F\u6700\u65B0",
1460
+ workflowOnly: "\u4EC5\u9700\u66F4\u65B0\u5DE5\u4F5C\u6D41\u6587\u4EF6",
1461
+ recommendNpm: "\u63A8\u8350\u7684\u66F4\u65B0\u65B9\u5F0F\uFF1A",
1462
+ willUpdateBoth: "\u8FD9\u5C06\u540C\u65F6\u66F4\u65B0\u547D\u4EE4\u548C\u5DE5\u4F5C\u6D41\u6587\u4EF6",
1463
+ useNpmUpdate: "\u6539\u7528 npm \u66F4\u65B0\uFF08\u63A8\u8350\uFF09\uFF1F",
1464
+ runInNewTerminal: "\u8BF7\u5728\u65B0\u7684\u7EC8\u7AEF\u7A97\u53E3\u4E2D\u8FD0\u884C\uFF1A",
1465
+ autoUpdateAfter: "\u8FD0\u884C\u5B8C\u6210\u540E\uFF0C\u5F53\u524D\u7248\u672C\u5C06\u81EA\u52A8\u66F4\u65B0",
1466
+ continueBuiltin: "\u7EE7\u7EED\u4F7F\u7528\u5185\u7F6E\u66F4\u65B0\uFF08\u4EC5\u66F4\u65B0\u5DE5\u4F5C\u6D41\u6587\u4EF6\uFF09",
1467
+ willNotUpdateCli: "\u6CE8\u610F\uFF1A\u8FD9\u4E0D\u4F1A\u66F4\u65B0 ccg \u547D\u4EE4\u672C\u8EAB",
1468
+ downloading: "\u6B63\u5728\u4E0B\u8F7D\u6700\u65B0\u7248\u672C...",
1469
+ downloadDone: "\u6700\u65B0\u7248\u672C\u4E0B\u8F7D\u5B8C\u6210",
1470
+ downloadFailed: "\u4E0B\u8F7D\u6700\u65B0\u7248\u672C\u5931\u8D25",
1471
+ clearingCache: "\u6B63\u5728\u6E05\u7406 npx \u7F13\u5B58...",
1472
+ migrating: "\u68C0\u6D4B\u5230\u65E7\u7248\u672C\u914D\u7F6E\uFF0C\u6B63\u5728\u8FC1\u79FB...",
1473
+ migrationDone: "\u914D\u7F6E\u8FC1\u79FB\u5B8C\u6210:",
1474
+ migrationSkipped: "\u5DF2\u8DF3\u8FC7:",
1475
+ migrationErrors: "\u8FC1\u79FB\u5B8C\u6210\uFF0C\u4F46\u6709\u90E8\u5206\u9519\u8BEF:",
1476
+ removingOld: "\u6B63\u5728\u5220\u9664\u65E7\u5DE5\u4F5C\u6D41...",
1477
+ oldRemoved: "\u65E7\u5DE5\u4F5C\u6D41\u5DF2\u5220\u9664",
1478
+ partialRemoveFailed: "\u90E8\u5206\u6587\u4EF6\u5220\u9664\u5931\u8D25\uFF0C\u7EE7\u7EED\u5B89\u88C5...",
1479
+ removeFailed: "\u5220\u9664\u65E7\u5DE5\u4F5C\u6D41\u65F6\u51FA\u9519: {{error}}\uFF0C\u7EE7\u7EED\u5B89\u88C5...",
1480
+ installingNew: "\u6B63\u5728\u5B89\u88C5\u65B0\u7248\u672C\u5DE5\u4F5C\u6D41\u548C\u4E8C\u8FDB\u5236...",
1481
+ installDone: "\u65B0\u7248\u672C\u5B89\u88C5\u6210\u529F",
1482
+ installFailed: "\u5B89\u88C5\u65B0\u7248\u672C\u5931\u8D25",
1483
+ installed: "\u5DF2\u5B89\u88C5 {{count}} \u4E2A\u547D\u4EE4:",
1484
+ manualRetry: "\u8BF7\u5C1D\u8BD5\u624B\u52A8\u8FD0\u884C:",
1485
+ updateDone: "\u66F4\u65B0\u5B8C\u6210\uFF01",
1486
+ upgradedFromTo: "\u4ECE v{{from}} \u5347\u7EA7\u5230 v{{to}}",
1487
+ reinstalled: "\u91CD\u65B0\u5B89\u88C5\u4E86 v{{version}}",
1488
+ error: "\u66F4\u65B0\u5931\u8D25: {{error}}"
1489
+ },
1355
1490
  menu: {
1356
1491
  title: "CCG \u4E3B\u83DC\u5355",
1357
1492
  options: {
1358
1493
  init: "\u521D\u59CB\u5316 CCG \u914D\u7F6E",
1359
1494
  update: "\u66F4\u65B0\u5DE5\u4F5C\u6D41",
1495
+ configMcp: "\u914D\u7F6E MCP",
1496
+ configApi: "\u914D\u7F6E API",
1497
+ configStyle: "\u914D\u7F6E\u8F93\u51FA\u98CE\u683C",
1498
+ tools: "\u5B9E\u7528\u5DE5\u5177",
1499
+ installClaude: "\u5B89\u88C5 Claude Code",
1360
1500
  uninstall: "\u5378\u8F7D CCG",
1361
1501
  help: "\u5E2E\u52A9",
1362
1502
  exit: "\u9000\u51FA"
@@ -1364,25 +1504,119 @@ const zhCN = {
1364
1504
  help: {
1365
1505
  title: "CCG \u547D\u4EE4:",
1366
1506
  hint: "\u66F4\u591A\u4FE1\u606F\u8BF7\u8FD0\u884C: npx ccg --help",
1507
+ sections: {
1508
+ devWorkflow: "\u5F00\u53D1\u5DE5\u4F5C\u6D41:",
1509
+ opsx: "OpenSpec \u89C4\u8303\u9A71\u52A8:",
1510
+ gitTools: "Git \u5DE5\u5177:",
1511
+ projectMgmt: "\u9879\u76EE\u7BA1\u7406:"
1512
+ },
1367
1513
  descriptions: {
1514
+ workflow: "\u5B8C\u65746\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41",
1515
+ plan: "\u591A\u6A21\u578B\u534F\u4F5C\u89C4\u5212\uFF08Phase 1-2\uFF09",
1516
+ execute: "\u591A\u6A21\u578B\u534F\u4F5C\u6267\u884C\uFF08Phase 3-5\uFF09",
1368
1517
  dev: "\u5B8C\u6574\u516D\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41",
1369
1518
  frontend: "\u524D\u7AEF\u4EFB\u52A1 \u2192 Gemini",
1370
1519
  backend: "\u540E\u7AEF\u4EFB\u52A1 \u2192 Codex",
1520
+ feat: "\u667A\u80FD\u529F\u80FD\u5F00\u53D1",
1371
1521
  review: "\u53CC\u6A21\u578B\u4EE3\u7801\u5BA1\u67E5",
1372
1522
  analyze: "\u53CC\u6A21\u578B\u6280\u672F\u5206\u6790",
1523
+ debug: "\u95EE\u9898\u8BCA\u65AD + \u4FEE\u590D",
1524
+ optimize: "\u6027\u80FD\u4F18\u5316",
1525
+ test: "\u6D4B\u8BD5\u751F\u6210",
1526
+ specInit: "\u521D\u59CB\u5316 OpenSpec \u73AF\u5883",
1527
+ specResearch: "\u9700\u6C42\u7814\u7A76 \u2192 \u7EA6\u675F\u96C6",
1528
+ specPlan: "\u591A\u6A21\u578B\u5206\u6790 \u2192 \u96F6\u51B3\u7B56\u8BA1\u5212",
1529
+ specImpl: "\u89C4\u8303\u9A71\u52A8\u5B9E\u73B0",
1530
+ specReview: "\u5F52\u6863\u524D\u53CC\u6A21\u578B\u5BA1\u67E5",
1373
1531
  commit: "Git \u667A\u80FD\u63D0\u4EA4",
1374
- rollback: "Git \u4EA4\u4E92\u5F0F\u56DE\u6EDA"
1532
+ rollback: "Git \u4EA4\u4E92\u5F0F\u56DE\u6EDA",
1533
+ cleanBranches: "\u6E05\u7406\u5DF2\u5408\u5E76\u5206\u652F",
1534
+ worktree: "Git Worktree \u7BA1\u7406",
1535
+ init: "\u521D\u59CB\u5316\u9879\u76EE CLAUDE.md"
1375
1536
  }
1376
1537
  },
1538
+ api: {
1539
+ title: "\u914D\u7F6E Claude Code API",
1540
+ currentConfig: "\u5F53\u524D\u914D\u7F6E:",
1541
+ urlPrompt: "API URL",
1542
+ keyPrompt: "API Key",
1543
+ leaveEmptyOfficial: "\u7559\u7A7A\u4F7F\u7528\u5B98\u65B9",
1544
+ leaveEmptySkip: "\u7559\u7A7A\u8DF3\u8FC7",
1545
+ saved: "API \u914D\u7F6E\u5DF2\u4FDD\u5B58"
1546
+ },
1547
+ style: {
1548
+ title: "\u914D\u7F6E\u8F93\u51FA\u98CE\u683C",
1549
+ currentStyle: "\u5F53\u524D\u98CE\u683C",
1550
+ selectStyle: "\u9009\u62E9\u8F93\u51FA\u98CE\u683C",
1551
+ notChanged: "\u98CE\u683C\u672A\u53D8\u66F4",
1552
+ installed: "\u5DF2\u5B89\u88C5\u98CE\u683C\u6587\u4EF6: {{style}}",
1553
+ set: "\u8F93\u51FA\u98CE\u683C\u5DF2\u8BBE\u7F6E\u4E3A: {{style}}",
1554
+ default: "\u9ED8\u8BA4",
1555
+ defaultDesc: "Claude Code \u539F\u751F\u98CE\u683C",
1556
+ engineerPro: "\u4E13\u4E1A\u5DE5\u7A0B\u5E08",
1557
+ engineerProDesc: "\u7B80\u6D01\u4E13\u4E1A\u7684\u6280\u672F\u98CE\u683C",
1558
+ nekomata: "\u732B\u5A18\u5DE5\u7A0B\u5E08",
1559
+ nekomataDesc: "\u53EF\u7231\u732B\u5A18\u8BED\u6C14",
1560
+ laowang: "\u8001\u738B\u5DE5\u7A0B\u5E08",
1561
+ laowangDesc: "\u63A5\u5730\u6C14\u7684\u8001\u738B\u98CE\u683C",
1562
+ ojousama: "\u5927\u5C0F\u59D0\u5DE5\u7A0B\u5E08",
1563
+ ojousamaDesc: "\u4F18\u96C5\u5927\u5C0F\u59D0\u8BED\u6C14",
1564
+ abyss: "\u90AA\u4FEE\u98CE\u683C",
1565
+ abyssDesc: "\u5BBF\u547D\u6DF1\u6E0A \xB7 \u9053\u8BED\u6807\u7B7E"
1566
+ },
1567
+ claude: {
1568
+ title: "\u5B89\u88C5/\u91CD\u88C5 Claude Code",
1569
+ alreadyInstalled: "\u68C0\u6D4B\u5230\u5DF2\u5B89\u88C5 Claude Code",
1570
+ reinstallPrompt: "\u662F\u5426\u5378\u8F7D\u540E\u91CD\u65B0\u5B89\u88C5\uFF1F",
1571
+ uninstalling: "\u6B63\u5728\u5378\u8F7D Claude Code...",
1572
+ uninstallSuccess: "\u5378\u8F7D\u6210\u529F",
1573
+ uninstallFailed: "\u5378\u8F7D\u5931\u8D25: {{error}}",
1574
+ selectMethod: "\u9009\u62E9\u5B89\u88C5\u65B9\u5F0F",
1575
+ npmRecommended: "\u5168\u5C40\u5B89\u88C5",
1576
+ installing: "\u6B63\u5728\u5B89\u88C5 Claude Code...",
1577
+ installSuccess: "Claude Code \u5B89\u88C5\u6210\u529F",
1578
+ installFailed: "\u5B89\u88C5\u5931\u8D25: {{error}}",
1579
+ runHint: "\u8FD0\u884C claude \u547D\u4EE4\u542F\u52A8"
1580
+ },
1581
+ tools: {
1582
+ title: "\u9009\u62E9\u5DE5\u5177",
1583
+ ccusage: "Claude Code \u7528\u91CF\u5206\u6790",
1584
+ ccline: "\u72B6\u6001\u680F\u5DE5\u5177\uFF08Git + \u7528\u91CF\uFF09",
1585
+ runningCcusage: "\u8FD0\u884C ccusage...",
1586
+ cclineAction: "CCometixLine \u64CD\u4F5C",
1587
+ cclineInstall: "\u5B89\u88C5/\u66F4\u65B0",
1588
+ cclineUninstall: "\u5378\u8F7D",
1589
+ cclineInstalling: "\u6B63\u5728\u5B89\u88C5 CCometixLine...",
1590
+ cclineInstallSuccess: "@cometix/ccline \u5B89\u88C5\u6210\u529F",
1591
+ cclineConfigured: "Claude Code statusLine \u5DF2\u914D\u7F6E",
1592
+ cclineInstallFailed: "\u5B89\u88C5\u5931\u8D25: {{error}}",
1593
+ cclineUninstalling: "\u6B63\u5728\u5378\u8F7D CCometixLine...",
1594
+ cclineConfigRemoved: "statusLine \u914D\u7F6E\u5DF2\u79FB\u9664",
1595
+ cclineUninstalled: "@cometix/ccline \u5DF2\u5378\u8F7D",
1596
+ cclineUninstallFailed: "\u5378\u8F7D\u5931\u8D25: {{error}}"
1597
+ },
1377
1598
  uninstall: {
1599
+ globalDetected: "\u68C0\u6D4B\u5230\u4F60\u662F\u901A\u8FC7 npm \u5168\u5C40\u5B89\u88C5\u7684",
1600
+ twoSteps: "\u5B8C\u6574\u5378\u8F7D\u9700\u8981\u4E24\u6B65\uFF1A",
1601
+ step1: "\u79FB\u9664\u5DE5\u4F5C\u6D41\u6587\u4EF6",
1602
+ step1Hint: "\u5373\u5C06\u6267\u884C",
1603
+ step2: "\u5378\u8F7D npm \u5168\u5C40\u5305",
1604
+ step2Hint: "\u9700\u8981\u624B\u52A8\u6267\u884C",
1605
+ continuePrompt: "\u7EE7\u7EED\u5378\u8F7D\u5DE5\u4F5C\u6D41\u6587\u4EF6\uFF1F",
1378
1606
  confirm: "\u786E\u5B9A\u8981\u5378\u8F7D CCG \u5417\uFF1F\u8FD9\u5C06\u5F3A\u5236\u79FB\u9664\u6240\u6709\u547D\u4EE4\u76EE\u5F55\u3001\u914D\u7F6E\u6587\u4EF6\u548C\u6570\u636E\u3002",
1379
1607
  alsoRemoveAceTool: "\u540C\u65F6\u79FB\u9664 ace-tool MCP \u914D\u7F6E\uFF1F",
1380
1608
  uninstalling: "\u6B63\u5728\u5378\u8F7D...",
1381
- success: "\u5378\u8F7D\u6210\u529F\uFF01",
1609
+ success: "\u5DE5\u4F5C\u6D41\u6587\u4EF6\u5DF2\u79FB\u9664",
1382
1610
  removedCommands: "\u5DF2\u79FB\u9664\u547D\u4EE4:",
1611
+ removedAgents: "\u5DF2\u79FB\u9664\u5B50\u667A\u80FD\u4F53:",
1612
+ removedSkills: "\u5DF2\u79FB\u9664 Skills:",
1613
+ removedBin: "\u5DF2\u79FB\u9664\u4E8C\u8FDB\u5236\u6587\u4EF6:",
1383
1614
  removedAceTool: "ace-tool MCP \u914D\u7F6E\u5DF2\u79FB\u9664",
1384
1615
  cancelled: "\u5378\u8F7D\u5DF2\u53D6\u6D88",
1385
- failed: "\u5378\u8F7D\u5931\u8D25"
1616
+ failed: "\u5378\u8F7D\u5931\u8D25",
1617
+ lastStep: "\u6700\u540E\u4E00\u6B65\uFF1A\u5378\u8F7D npm \u5168\u5C40\u5305",
1618
+ runInNewTerminal: "\u8BF7\u5728\u65B0\u7684\u7EC8\u7AEF\u7A97\u53E3\u4E2D\u8FD0\u884C\uFF1A",
1619
+ afterDone: "\u5B8C\u6210\u540E ccg \u547D\u4EE4\u5C06\u5F7B\u5E95\u79FB\u9664"
1386
1620
  }
1387
1621
  }
1388
1622
  };
@@ -1401,14 +1635,26 @@ const en = {
1401
1635
  loading: "Loading...",
1402
1636
  processing: "Processing...",
1403
1637
  completed: "Completed",
1404
- failed: "Failed"
1638
+ failed: "Failed",
1639
+ goodbye: "Goodbye!",
1640
+ pressEnterToReturn: "Press Enter to return to main menu...",
1641
+ cancelled: "Cancelled",
1642
+ configNotModified: "Configuration not modified",
1643
+ configSaved: "Configuration saved",
1644
+ configFile: "Config file",
1645
+ restartToApply: "Restart Claude Code CLI to apply changes",
1646
+ unknownSubcommand: "Unknown subcommand: {{subcommand}}",
1647
+ availableSubcommands: "Available subcommands: {{list}}"
1405
1648
  },
1406
1649
  cli: {
1407
1650
  help: {
1408
1651
  commands: "Commands",
1409
1652
  commandDescriptions: {
1410
1653
  showMenu: "Show interactive menu (default)",
1411
- initConfig: "Initialize CCG multi-model collaboration system"
1654
+ initConfig: "Initialize CCG multi-model collaboration system",
1655
+ configMcp: "Configure MCP Token",
1656
+ diagnoseMcp: "Diagnose MCP configuration issues",
1657
+ fixMcp: "Fix Windows MCP configuration"
1412
1658
  },
1413
1659
  shortcuts: "Shortcuts:",
1414
1660
  shortcutDescriptions: {
@@ -1439,7 +1685,8 @@ const en = {
1439
1685
  },
1440
1686
  init: {
1441
1687
  welcome: "Welcome to CCG Multi-Model Collaboration System",
1442
- selectLanguage: "Select language",
1688
+ subtitle: "Multi-Model Collaboration Workflow",
1689
+ selectLanguage: "Select language / \u9009\u62E9\u8BED\u8A00",
1443
1690
  selectFrontendModels: "Select models for frontend tasks (multi-select)",
1444
1691
  selectBackendModels: "Select models for backend tasks (multi-select)",
1445
1692
  selectMode: "Select collaboration mode",
@@ -1449,10 +1696,10 @@ const en = {
1449
1696
  installSuccess: "Installation successful!",
1450
1697
  installFailed: "Installation failed",
1451
1698
  installCancelled: "Installation cancelled",
1452
- installedCommands: "Installed Commands:",
1453
- installedPrompts: "Installed Role Prompts:",
1454
- installedBinary: "Installed Binary:",
1455
- installationErrors: "Installation Errors:",
1699
+ installedCommands: "Installed commands:",
1700
+ installedPrompts: "Installed role prompts:",
1701
+ installedBinary: "Installed binary:",
1702
+ installationErrors: "Installation errors:",
1456
1703
  pathWarning: "codeagent-wrapper needs to be added to PATH",
1457
1704
  autoConfigurePathPrompt: "Automatically configure PATH environment variable?",
1458
1705
  pathConfigured: "PATH has been added to {{file}}",
@@ -1477,8 +1724,86 @@ const en = {
1477
1724
  backendModels: "Backend Models:",
1478
1725
  collaboration: "Collaboration:",
1479
1726
  workflows: "Workflows:",
1480
- selected: "selected"
1727
+ selected: "selected",
1728
+ modelRouting: "Model Routing",
1729
+ commandCount: "Commands",
1730
+ mcpTool: "MCP Tool",
1731
+ webUI: "Web UI",
1732
+ pendingConfig: "pending",
1733
+ skipped: "skipped",
1734
+ enabled: "Enabled",
1735
+ disabled: "Disabled"
1736
+ },
1737
+ mcp: {
1738
+ title: "MCP Code Retrieval Tool",
1739
+ selectProvider: "Select code retrieval MCP tool",
1740
+ contextweaver: "Local vector DB, hybrid search + Rerank",
1741
+ aceToolPaid: "Augment official",
1742
+ aceToolRsPaid: "Lighter weight",
1743
+ skipLater: "Configure later",
1744
+ skipTokenPrompt: "Skip Token configuration? (run npx ccg config mcp later)",
1745
+ skipKeyPrompt: "Skip API Key configuration? (run npx ccg config mcp later)",
1746
+ tokenSkipped: "Token configuration skipped",
1747
+ keySkipped: "API Key configuration skipped",
1748
+ notInstalled: "not installed",
1749
+ keyNotProvided: "API Key not provided",
1750
+ tokenNotProvided: "Token not provided",
1751
+ configLater: "Run {{cmd}} to configure later",
1752
+ getAccess: "Get ace-tool access:",
1753
+ officialService: "Official service",
1754
+ proxyService: "Proxy service",
1755
+ noSignup: "No signup required",
1756
+ registerForToken: "Register to get Token",
1757
+ communityProxy: "Free community proxy service",
1758
+ getApiKey: "Get SiliconFlow API Key:",
1759
+ siliconflowStep1: "Visit {{url}} to register",
1760
+ siliconflowStep2: "Go to Console \u2192 API Keys \u2192 Create Key",
1761
+ siliconflowStep3: "New users get free quota, enough for Embedding + Rerank",
1762
+ baseUrlHint: "Required for proxy, leave empty for official",
1763
+ tokenRequired: "Required",
1764
+ enterToken: "Please enter Token",
1765
+ enterApiKey: "Please enter API Key",
1766
+ mcpSkipped: "MCP configuration skipped",
1767
+ configManually: "You can configure any MCP service later",
1768
+ mcpOptions: "MCP Service Options",
1769
+ mcpOptionsHint: "To use code retrieval, choose from these MCP services:",
1770
+ promptEnhancement: "Prompt enhancement + code retrieval",
1771
+ localEngine: "Local semantic code search engine, hybrid search + Rerank",
1772
+ freeQuota: "Free quota available",
1773
+ cwConfiguring: "Configuring ContextWeaver MCP...",
1774
+ cwFailed: "ContextWeaver MCP configuration failed",
1775
+ cwConfigFile: "Config file",
1776
+ cwIndexHint: "First use requires indexing your codebase:"
1777
+ },
1778
+ api: {
1779
+ title: "Claude Code API Configuration",
1780
+ configurePrompt: "Configure custom API? (skip if using official account)",
1781
+ urlPrompt: "API URL",
1782
+ urlRequired: "Required",
1783
+ keyPrompt: "API Key",
1784
+ keyRequired: "Required",
1785
+ enterUrl: "Please enter API URL",
1786
+ enterKey: "Please enter API Key",
1787
+ useOfficialHint: "Skip if using official account",
1788
+ leaveEmptyForOfficial: "Leave empty for official",
1789
+ leaveEmptyToSkip: "Leave empty to skip"
1790
+ },
1791
+ webui: {
1792
+ prompt: "Enable Web UI real-time output?",
1793
+ disableHint: "Disabling can speed up response"
1481
1794
  },
1795
+ hooks: {
1796
+ title: "codeagent-wrapper auto-authorization",
1797
+ description: "Use Hook to auto-authorize codeagent-wrapper commands",
1798
+ installed: "Hook configured (auto-authorize codeagent-wrapper)",
1799
+ jqRequired: "Auto-authorization requires jq command",
1800
+ jqInstallHint: "Install method",
1801
+ jqMac: "macOS: brew install jq",
1802
+ jqLinux: "Linux: sudo apt install jq / sudo yum install jq",
1803
+ jqWindows: "Windows: choco install jq / scoop install jq",
1804
+ jqNotFound: "jq not detected. Hook written but requires jq to work"
1805
+ },
1806
+ addToPathManually: "Please add to shell config manually:",
1482
1807
  modes: {
1483
1808
  parallel: "Parallel - Call multiple models simultaneously",
1484
1809
  smart: "Smart - Auto-select based on task type",
@@ -1522,11 +1847,60 @@ const en = {
1522
1847
  failed: "ace-tool-rs configuration failed (can be configured manually later)"
1523
1848
  }
1524
1849
  },
1850
+ update: {
1851
+ checking: "Checking for updates...",
1852
+ checkingLatest: "Checking latest version...",
1853
+ cannotConnect: "Cannot connect to npm registry, please check your network",
1854
+ currentVersion: "Current version",
1855
+ latestVersion: "Latest version",
1856
+ localWorkflow: "Local workflows",
1857
+ newVersionFound: "New version v{{latest}} available (current: v{{current}}). Update?",
1858
+ localOutdated: "Local workflow version (v{{local}}) is older than current (v{{current}}). Update?",
1859
+ alreadyLatest: "Already on latest version (v{{current}}). Force reinstall/repair workflows?",
1860
+ cancelled: "Update cancelled",
1861
+ starting: "Starting update...",
1862
+ globalDetected: "Detected npm global installation",
1863
+ packageLatest: "Package version is already latest",
1864
+ workflowOnly: "Only workflow files need updating",
1865
+ recommendNpm: "Recommended update method:",
1866
+ willUpdateBoth: "This will update both commands and workflow files",
1867
+ useNpmUpdate: "Use npm update instead (recommended)?",
1868
+ runInNewTerminal: "Please run in a new terminal window:",
1869
+ autoUpdateAfter: "After completion, the current version will be automatically updated",
1870
+ continueBuiltin: "Continue with built-in update (workflow files only)",
1871
+ willNotUpdateCli: "Note: This will not update the ccg command itself",
1872
+ downloading: "Downloading latest version...",
1873
+ downloadDone: "Latest version downloaded",
1874
+ downloadFailed: "Failed to download latest version",
1875
+ clearingCache: "Clearing npx cache...",
1876
+ migrating: "Old version config detected, migrating...",
1877
+ migrationDone: "Migration completed:",
1878
+ migrationSkipped: "Skipped:",
1879
+ migrationErrors: "Migration completed with errors:",
1880
+ removingOld: "Removing old workflows...",
1881
+ oldRemoved: "Old workflows removed",
1882
+ partialRemoveFailed: "Some files failed to remove, continuing...",
1883
+ removeFailed: "Error removing old workflows: {{error}}, continuing...",
1884
+ installingNew: "Installing new workflows and binaries...",
1885
+ installDone: "New version installed successfully",
1886
+ installFailed: "Failed to install new version",
1887
+ installed: "Installed {{count}} commands:",
1888
+ manualRetry: "Please try running manually:",
1889
+ updateDone: "Update complete!",
1890
+ upgradedFromTo: "Upgraded from v{{from}} to v{{to}}",
1891
+ reinstalled: "Reinstalled v{{version}}",
1892
+ error: "Update failed: {{error}}"
1893
+ },
1525
1894
  menu: {
1526
1895
  title: "CCG Main Menu",
1527
1896
  options: {
1528
1897
  init: "Initialize CCG configuration",
1529
1898
  update: "Update workflows",
1899
+ configMcp: "Configure MCP",
1900
+ configApi: "Configure API",
1901
+ configStyle: "Configure output style",
1902
+ tools: "Tools",
1903
+ installClaude: "Install Claude Code",
1530
1904
  uninstall: "Uninstall CCG",
1531
1905
  help: "Help",
1532
1906
  exit: "Exit"
@@ -1534,25 +1908,119 @@ const en = {
1534
1908
  help: {
1535
1909
  title: "CCG Commands:",
1536
1910
  hint: "For more information, run: npx ccg --help",
1911
+ sections: {
1912
+ devWorkflow: "Development Workflow:",
1913
+ opsx: "OpenSpec Spec-Driven:",
1914
+ gitTools: "Git Tools:",
1915
+ projectMgmt: "Project Management:"
1916
+ },
1537
1917
  descriptions: {
1918
+ workflow: "Full 6-phase development workflow",
1919
+ plan: "Multi-model planning (Phase 1-2)",
1920
+ execute: "Multi-model execution (Phase 3-5)",
1538
1921
  dev: "Complete 6-phase development workflow",
1539
1922
  frontend: "Frontend tasks \u2192 Gemini",
1540
1923
  backend: "Backend tasks \u2192 Codex",
1924
+ feat: "Smart feature development",
1541
1925
  review: "Dual-model code review",
1542
1926
  analyze: "Dual-model technical analysis",
1927
+ debug: "Diagnosis + fix",
1928
+ optimize: "Performance optimization",
1929
+ test: "Test generation",
1930
+ specInit: "Initialize OpenSpec environment",
1931
+ specResearch: "Requirements \u2192 Constraint set",
1932
+ specPlan: "Multi-model analysis \u2192 Zero-decision plan",
1933
+ specImpl: "Spec-driven implementation",
1934
+ specReview: "Pre-archive dual-model review",
1543
1935
  commit: "Git smart commit",
1544
- rollback: "Git interactive rollback"
1936
+ rollback: "Git interactive rollback",
1937
+ cleanBranches: "Clean merged branches",
1938
+ worktree: "Git Worktree management",
1939
+ init: "Initialize project CLAUDE.md"
1545
1940
  }
1546
1941
  },
1942
+ api: {
1943
+ title: "Configure Claude Code API",
1944
+ currentConfig: "Current config:",
1945
+ urlPrompt: "API URL",
1946
+ keyPrompt: "API Key",
1947
+ leaveEmptyOfficial: "Leave empty for official",
1948
+ leaveEmptySkip: "Leave empty to skip",
1949
+ saved: "API configuration saved"
1950
+ },
1951
+ style: {
1952
+ title: "Configure Output Style",
1953
+ currentStyle: "Current style",
1954
+ selectStyle: "Select output style",
1955
+ notChanged: "Style not changed",
1956
+ installed: "Style file installed: {{style}}",
1957
+ set: "Output style set to: {{style}}",
1958
+ default: "Default",
1959
+ defaultDesc: "Claude Code native style",
1960
+ engineerPro: "Professional Engineer",
1961
+ engineerProDesc: "Clean, professional technical style",
1962
+ nekomata: "Nekomata Engineer",
1963
+ nekomataDesc: "Cute cat-girl tone",
1964
+ laowang: "Laowang Engineer",
1965
+ laowangDesc: "Down-to-earth Chinese uncle style",
1966
+ ojousama: "Ojou-sama Engineer",
1967
+ ojousamaDesc: "Elegant lady tone",
1968
+ abyss: "Abyss Cultivator",
1969
+ abyssDesc: "Dark cultivator style"
1970
+ },
1971
+ claude: {
1972
+ title: "Install/Reinstall Claude Code",
1973
+ alreadyInstalled: "Claude Code is already installed",
1974
+ reinstallPrompt: "Uninstall and reinstall?",
1975
+ uninstalling: "Uninstalling Claude Code...",
1976
+ uninstallSuccess: "Uninstall successful",
1977
+ uninstallFailed: "Uninstall failed: {{error}}",
1978
+ selectMethod: "Select installation method",
1979
+ npmRecommended: "Global install",
1980
+ installing: "Installing Claude Code...",
1981
+ installSuccess: "Claude Code installed successfully",
1982
+ installFailed: "Installation failed: {{error}}",
1983
+ runHint: "Run the claude command to start"
1984
+ },
1985
+ tools: {
1986
+ title: "Select tool",
1987
+ ccusage: "Claude Code usage analytics",
1988
+ ccline: "Status bar tool (Git + usage)",
1989
+ runningCcusage: "Running ccusage...",
1990
+ cclineAction: "CCometixLine action",
1991
+ cclineInstall: "Install/Update",
1992
+ cclineUninstall: "Uninstall",
1993
+ cclineInstalling: "Installing CCometixLine...",
1994
+ cclineInstallSuccess: "@cometix/ccline installed successfully",
1995
+ cclineConfigured: "Claude Code statusLine configured",
1996
+ cclineInstallFailed: "Installation failed: {{error}}",
1997
+ cclineUninstalling: "Uninstalling CCometixLine...",
1998
+ cclineConfigRemoved: "statusLine config removed",
1999
+ cclineUninstalled: "@cometix/ccline uninstalled",
2000
+ cclineUninstallFailed: "Uninstall failed: {{error}}"
2001
+ },
1547
2002
  uninstall: {
2003
+ globalDetected: "Detected npm global installation",
2004
+ twoSteps: "Full uninstall requires two steps:",
2005
+ step1: "Remove workflow files",
2006
+ step1Hint: "about to execute",
2007
+ step2: "Uninstall npm global package",
2008
+ step2Hint: "requires manual execution",
2009
+ continuePrompt: "Continue removing workflow files?",
1548
2010
  confirm: "Are you sure you want to uninstall CCG? This will force remove all command directories, config files and data.",
1549
2011
  alsoRemoveAceTool: "Also remove ace-tool MCP configuration?",
1550
2012
  uninstalling: "Uninstalling...",
1551
- success: "Uninstallation successful!",
2013
+ success: "Workflow files removed",
1552
2014
  removedCommands: "Removed commands:",
2015
+ removedAgents: "Removed agents:",
2016
+ removedSkills: "Removed skills:",
2017
+ removedBin: "Removed binary:",
1553
2018
  removedAceTool: "ace-tool MCP configuration removed",
1554
2019
  cancelled: "Uninstallation cancelled",
1555
- failed: "Uninstallation failed"
2020
+ failed: "Uninstallation failed",
2021
+ lastStep: "Last step: Uninstall npm global package",
2022
+ runInNewTerminal: "Please run in a new terminal window:",
2023
+ afterDone: "After completion, the ccg command will be fully removed"
1556
2024
  }
1557
2025
  }
1558
2026
  };
@@ -1732,12 +2200,71 @@ async function needsMigration() {
1732
2200
  return hasOldCcgDir || hasOldPromptsDir || hasOldConfigFile;
1733
2201
  }
1734
2202
 
2203
+ async function checkJqAvailable() {
2204
+ try {
2205
+ const { execSync } = await import('node:child_process');
2206
+ execSync("jq --version", { stdio: "pipe" });
2207
+ return true;
2208
+ } catch {
2209
+ return false;
2210
+ }
2211
+ }
2212
+ async function installHook(settingsPath) {
2213
+ let settings = {};
2214
+ if (await fs.pathExists(settingsPath)) {
2215
+ settings = await fs.readJSON(settingsPath);
2216
+ }
2217
+ if (!settings.hooks)
2218
+ settings.hooks = {};
2219
+ if (!settings.hooks.PreToolUse)
2220
+ settings.hooks.PreToolUse = [];
2221
+ const existingHook = settings.hooks.PreToolUse.find(
2222
+ (h) => h.matcher === "Bash" && h.hooks?.some((hh) => hh.command?.includes("codeagent-wrapper"))
2223
+ );
2224
+ if (!existingHook) {
2225
+ settings.hooks.PreToolUse.push({
2226
+ matcher: "Bash",
2227
+ hooks: [
2228
+ {
2229
+ type: "command",
2230
+ command: `jq -r '.tool_input.command' | grep -q 'codeagent-wrapper' && echo '{"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": "allow", "permissionDecisionReason": "codeagent-wrapper auto-approved"}}' || exit 1`,
2231
+ timeout: 1
2232
+ }
2233
+ ]
2234
+ });
2235
+ await fs.writeJSON(settingsPath, settings, { spaces: 2 });
2236
+ }
2237
+ }
1735
2238
  async function init(options = {}) {
1736
2239
  console.log();
1737
2240
  console.log(ansis.cyan.bold(` CCG - Claude + Codex + Gemini`));
1738
- console.log(ansis.gray(` \u591A\u6A21\u578B\u534F\u4F5C\u5F00\u53D1\u5DE5\u4F5C\u6D41`));
2241
+ console.log(ansis.gray(` Multi-Model Collaboration Workflow`));
1739
2242
  console.log();
1740
- const language = "zh-CN";
2243
+ let language = "zh-CN";
2244
+ if (!options.skipPrompt) {
2245
+ const existingConfig = await readCcgConfig();
2246
+ const savedLang = existingConfig?.general?.language;
2247
+ if (savedLang) {
2248
+ language = savedLang;
2249
+ await initI18n(language);
2250
+ } else {
2251
+ const { selectedLang } = await inquirer.prompt([{
2252
+ type: "list",
2253
+ name: "selectedLang",
2254
+ message: "\u9009\u62E9\u8BED\u8A00 / Select language",
2255
+ choices: [
2256
+ { name: `\u7B80\u4F53\u4E2D\u6587`, value: "zh-CN" },
2257
+ { name: `English`, value: "en" }
2258
+ ],
2259
+ default: "zh-CN"
2260
+ }]);
2261
+ language = selectedLang;
2262
+ await initI18n(language);
2263
+ }
2264
+ } else if (options.lang) {
2265
+ language = options.lang;
2266
+ await initI18n(language);
2267
+ }
1741
2268
  const frontendModels = ["gemini"];
1742
2269
  const backendModels = ["codex"];
1743
2270
  const mode = "smart";
@@ -1751,27 +2278,27 @@ async function init(options = {}) {
1751
2278
  mcpProvider = "skip";
1752
2279
  } else if (!options.skipPrompt) {
1753
2280
  console.log();
1754
- console.log(ansis.cyan.bold(` \u{1F527} MCP \u4EE3\u7801\u68C0\u7D22\u5DE5\u5177\u914D\u7F6E`));
2281
+ console.log(ansis.cyan.bold(` \u{1F527} ${i18n.t("init:mcp.title")}`));
1755
2282
  console.log();
1756
2283
  const { selectedMcp } = await inquirer.prompt([{
1757
2284
  type: "list",
1758
2285
  name: "selectedMcp",
1759
- message: "\u9009\u62E9\u4EE3\u7801\u68C0\u7D22 MCP \u5DE5\u5177",
2286
+ message: i18n.t("init:mcp.selectProvider"),
1760
2287
  choices: [
1761
2288
  {
1762
- name: `contextweaver ${ansis.green("(\u63A8\u8350)")} ${ansis.gray("- \u672C\u5730\u5411\u91CF\u5E93\uFF0C\u6DF7\u5408\u641C\u7D22 + Rerank")}`,
2289
+ name: `contextweaver ${ansis.green(`(${i18n.t("common:info")})`)} ${ansis.gray(`- ${i18n.t("init:mcp.contextweaver")}`)}`,
1763
2290
  value: "contextweaver"
1764
2291
  },
1765
2292
  {
1766
- name: `ace-tool ${ansis.red("(\u6536\u8D39)")} ${ansis.gray("(Node.js) - Augment \u5B98\u65B9")}`,
2293
+ name: `ace-tool ${ansis.red(`(${i18n.t("init:mcp.aceToolPaid")})`)} ${ansis.gray("(Node.js) - Augment")}`,
1767
2294
  value: "ace-tool"
1768
2295
  },
1769
2296
  {
1770
- name: `ace-tool-rs ${ansis.red("(\u6536\u8D39)")} ${ansis.gray("(Rust) - \u66F4\u8F7B\u91CF")}`,
2297
+ name: `ace-tool-rs ${ansis.red(`(${i18n.t("init:mcp.aceToolRsPaid")})`)} ${ansis.gray("(Rust) - " + i18n.t("init:mcp.aceToolRsPaid"))}`,
1771
2298
  value: "ace-tool-rs"
1772
2299
  },
1773
2300
  {
1774
- name: `\u8DF3\u8FC7 ${ansis.gray("- \u7A0D\u540E\u624B\u52A8\u914D\u7F6E")}`,
2301
+ name: `${i18n.t("init:mcp.skipLater")} ${ansis.gray(`- ${i18n.t("init:mcp.configManually")}`)}`,
1775
2302
  value: "skip"
1776
2303
  }
1777
2304
  ],
@@ -1782,89 +2309,87 @@ async function init(options = {}) {
1782
2309
  const toolName = selectedMcp === "ace-tool-rs" ? "ace-tool-rs" : "ace-tool";
1783
2310
  const toolDesc = selectedMcp === "ace-tool-rs" ? i18n.t("init:aceToolRs.description") : i18n.t("init:aceTool.description");
1784
2311
  console.log();
1785
- console.log(ansis.cyan.bold(` \u{1F527} ${toolName} MCP \u914D\u7F6E`));
2312
+ console.log(ansis.cyan.bold(` \u{1F527} ${toolName} MCP`));
1786
2313
  console.log(ansis.gray(` ${toolDesc}`));
1787
2314
  console.log();
1788
2315
  const { skipToken } = await inquirer.prompt([{
1789
2316
  type: "confirm",
1790
2317
  name: "skipToken",
1791
- message: "\u662F\u5426\u8DF3\u8FC7 Token \u914D\u7F6E\uFF1F\uFF08\u53EF\u7A0D\u540E\u8FD0\u884C npx ccg config mcp \u914D\u7F6E\uFF09",
2318
+ message: i18n.t("init:mcp.skipTokenPrompt"),
1792
2319
  default: false
1793
2320
  }]);
1794
2321
  if (!skipToken) {
1795
2322
  console.log();
1796
- console.log(ansis.cyan(` \u{1F4D6} \u83B7\u53D6 ace-tool \u8BBF\u95EE\u65B9\u5F0F\uFF1A`));
2323
+ console.log(ansis.cyan(` \u{1F4D6} ${i18n.t("init:mcp.getAccess")}`));
1797
2324
  console.log();
1798
- console.log(` ${ansis.gray("\u2022")} ${ansis.cyan("\u5B98\u65B9\u670D\u52A1")}: ${ansis.underline("https://augmentcode.com/")}`);
1799
- console.log(` ${ansis.gray("\u6CE8\u518C\u8D26\u53F7\u540E\u83B7\u53D6 Token")}`);
2325
+ console.log(` ${ansis.gray("\u2022")} ${ansis.cyan(i18n.t("init:mcp.officialService"))}: ${ansis.underline("https://augmentcode.com/")}`);
2326
+ console.log(` ${ansis.gray(i18n.t("init:mcp.registerForToken"))}`);
1800
2327
  console.log();
1801
- console.log(` ${ansis.gray("\u2022")} ${ansis.cyan("\u4E2D\u8F6C\u670D\u52A1")} ${ansis.yellow("(\u65E0\u9700\u6CE8\u518C)")}: ${ansis.underline("https://linux.do/t/topic/1291730")}`);
1802
- console.log(` ${ansis.gray("linux.do \u793E\u533A\u63D0\u4F9B\u7684\u514D\u8D39\u4E2D\u8F6C\u670D\u52A1")}`);
2328
+ console.log(` ${ansis.gray("\u2022")} ${ansis.cyan(i18n.t("init:mcp.proxyService"))} ${ansis.yellow(`(${i18n.t("init:mcp.noSignup")})`)}: ${ansis.underline("https://linux.do/t/topic/1291730")}`);
2329
+ console.log(` ${ansis.gray(i18n.t("init:mcp.communityProxy"))}`);
1803
2330
  console.log();
1804
2331
  const aceAnswers = await inquirer.prompt([
1805
2332
  {
1806
2333
  type: "input",
1807
2334
  name: "baseUrl",
1808
- message: `Base URL ${ansis.gray("(\u4F7F\u7528\u4E2D\u8F6C\u670D\u52A1\u65F6\u5FC5\u586B\uFF0C\u5B98\u65B9\u670D\u52A1\u7559\u7A7A)")}`,
2335
+ message: `Base URL ${ansis.gray(`(${i18n.t("init:mcp.baseUrlHint")})`)}`,
1809
2336
  default: ""
1810
2337
  },
1811
2338
  {
1812
2339
  type: "password",
1813
2340
  name: "token",
1814
- message: `Token ${ansis.gray("(\u5FC5\u586B)")}`,
2341
+ message: `Token ${ansis.gray(`(${i18n.t("init:mcp.tokenRequired")})`)}`,
1815
2342
  mask: "*",
1816
- validate: (input) => input.trim() !== "" || "\u8BF7\u8F93\u5165 Token"
2343
+ validate: (input) => input.trim() !== "" || i18n.t("init:mcp.enterToken")
1817
2344
  }
1818
2345
  ]);
1819
2346
  aceToolBaseUrl = aceAnswers.baseUrl || "";
1820
2347
  aceToolToken = aceAnswers.token || "";
1821
2348
  } else {
1822
2349
  console.log();
1823
- console.log(ansis.yellow(` \u2139\uFE0F \u5DF2\u8DF3\u8FC7 Token \u914D\u7F6E`));
1824
- console.log(ansis.gray(` \u2022 ace-tool MCP \u5C06\u4E0D\u4F1A\u81EA\u52A8\u5B89\u88C5`));
1825
- console.log(ansis.gray(` \u2022 \u53EF\u7A0D\u540E\u8FD0\u884C ${ansis.cyan("npx ccg config mcp")} \u914D\u7F6E Token`));
1826
- console.log(ansis.gray(` \u2022 \u83B7\u53D6 Token: ${ansis.cyan("https://augmentcode.com/")}`));
2350
+ console.log(ansis.yellow(` \u2139\uFE0F ${i18n.t("init:mcp.tokenSkipped")}`));
2351
+ console.log(ansis.gray(` \u2022 ${toolName} MCP ${i18n.t("init:mcp.notInstalled")}`));
2352
+ console.log(ansis.gray(` \u2022 ${i18n.t("init:mcp.configLater", { cmd: ansis.cyan("npx ccg config mcp") })}`));
1827
2353
  console.log();
1828
2354
  }
1829
2355
  } else if (selectedMcp === "contextweaver") {
1830
2356
  console.log();
1831
- console.log(ansis.cyan.bold(` \u{1F527} ContextWeaver MCP \u914D\u7F6E`));
1832
- console.log(ansis.gray(` \u672C\u5730\u8BED\u4E49\u4EE3\u7801\u68C0\u7D22\u5F15\u64CE\uFF0C\u6DF7\u5408\u641C\u7D22 + Rerank`));
2357
+ console.log(ansis.cyan.bold(` \u{1F527} ContextWeaver MCP`));
2358
+ console.log(ansis.gray(` ${i18n.t("init:mcp.localEngine")}`));
1833
2359
  console.log();
1834
2360
  const { skipKey } = await inquirer.prompt([{
1835
2361
  type: "confirm",
1836
2362
  name: "skipKey",
1837
- message: "\u662F\u5426\u8DF3\u8FC7 API Key \u914D\u7F6E\uFF1F\uFF08\u53EF\u7A0D\u540E\u8FD0\u884C npx ccg config mcp \u914D\u7F6E\uFF09",
2363
+ message: i18n.t("init:mcp.skipKeyPrompt"),
1838
2364
  default: false
1839
2365
  }]);
1840
2366
  if (!skipKey) {
1841
2367
  console.log();
1842
- console.log(ansis.cyan(` \u{1F4D6} \u83B7\u53D6\u7845\u57FA\u6D41\u52A8 API Key\uFF1A`));
2368
+ console.log(ansis.cyan(` \u{1F4D6} ${i18n.t("init:mcp.getApiKey")}`));
1843
2369
  console.log();
1844
- console.log(` ${ansis.gray("1.")} \u8BBF\u95EE ${ansis.underline("https://siliconflow.cn/")} \u6CE8\u518C\u8D26\u53F7`);
1845
- console.log(` ${ansis.gray("2.")} \u8FDB\u5165\u63A7\u5236\u53F0 \u2192 API \u5BC6\u94A5 \u2192 \u521B\u5EFA\u5BC6\u94A5`);
1846
- console.log(` ${ansis.gray("3.")} \u65B0\u7528\u6237\u6709\u514D\u8D39\u989D\u5EA6\uFF0CEmbedding + Rerank \u5B8C\u5168\u591F\u7528`);
2370
+ console.log(` ${ansis.gray("1.")} ${i18n.t("init:mcp.siliconflowStep1", { url: ansis.underline("https://siliconflow.cn/") })}`);
2371
+ console.log(` ${ansis.gray("2.")} ${i18n.t("init:mcp.siliconflowStep2")}`);
2372
+ console.log(` ${ansis.gray("3.")} ${i18n.t("init:mcp.siliconflowStep3")}`);
1847
2373
  console.log();
1848
2374
  const cwAnswers = await inquirer.prompt([{
1849
2375
  type: "password",
1850
2376
  name: "apiKey",
1851
- message: `\u7845\u57FA\u6D41\u52A8 API Key ${ansis.gray("(sk-xxx)")}`,
2377
+ message: `SiliconFlow API Key ${ansis.gray("(sk-xxx)")}`,
1852
2378
  mask: "*",
1853
- validate: (input) => input.trim() !== "" || "\u8BF7\u8F93\u5165 API Key"
2379
+ validate: (input) => input.trim() !== "" || i18n.t("init:mcp.enterApiKey")
1854
2380
  }]);
1855
2381
  contextWeaverApiKey = cwAnswers.apiKey || "";
1856
2382
  } else {
1857
2383
  console.log();
1858
- console.log(ansis.yellow(` \u2139\uFE0F \u5DF2\u8DF3\u8FC7 API Key \u914D\u7F6E`));
1859
- console.log(ansis.gray(` \u2022 ContextWeaver MCP \u5C06\u4E0D\u4F1A\u81EA\u52A8\u5B89\u88C5`));
1860
- console.log(ansis.gray(` \u2022 \u53EF\u7A0D\u540E\u8FD0\u884C ${ansis.cyan("npx ccg config mcp")} \u914D\u7F6E`));
1861
- console.log(ansis.gray(` \u2022 \u83B7\u53D6 Key: ${ansis.cyan("https://siliconflow.cn/")}`));
2384
+ console.log(ansis.yellow(` \u2139\uFE0F ${i18n.t("init:mcp.keySkipped")}`));
2385
+ console.log(ansis.gray(` \u2022 ContextWeaver MCP ${i18n.t("init:mcp.notInstalled")}`));
2386
+ console.log(ansis.gray(` \u2022 ${i18n.t("init:mcp.configLater", { cmd: ansis.cyan("npx ccg config mcp") })}`));
1862
2387
  console.log();
1863
2388
  }
1864
2389
  } else {
1865
2390
  console.log();
1866
- console.log(ansis.yellow(` \u2139\uFE0F \u5DF2\u8DF3\u8FC7 MCP \u914D\u7F6E`));
1867
- console.log(ansis.gray(` \u2022 \u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1`));
2391
+ console.log(ansis.yellow(` \u2139\uFE0F ${i18n.t("init:mcp.mcpSkipped")}`));
2392
+ console.log(ansis.gray(` \u2022 ${i18n.t("init:mcp.configManually")}`));
1868
2393
  console.log();
1869
2394
  }
1870
2395
  }
@@ -1872,12 +2397,12 @@ async function init(options = {}) {
1872
2397
  let apiKey = "";
1873
2398
  if (!options.skipPrompt) {
1874
2399
  console.log();
1875
- console.log(ansis.cyan.bold(` \u{1F511} Claude Code API \u914D\u7F6E`));
2400
+ console.log(ansis.cyan.bold(` \u{1F511} ${i18n.t("init:api.title")}`));
1876
2401
  console.log();
1877
2402
  const { configureApi } = await inquirer.prompt([{
1878
2403
  type: "confirm",
1879
2404
  name: "configureApi",
1880
- message: "\u662F\u5426\u914D\u7F6E\u81EA\u5B9A\u4E49 API\uFF1F\uFF08\u4F7F\u7528\u5B98\u65B9\u8D26\u53F7\u53EF\u8DF3\u8FC7\uFF09",
2405
+ message: i18n.t("init:api.configurePrompt"),
1881
2406
  default: false
1882
2407
  }]);
1883
2408
  if (configureApi) {
@@ -1885,15 +2410,15 @@ async function init(options = {}) {
1885
2410
  {
1886
2411
  type: "input",
1887
2412
  name: "url",
1888
- message: `API URL ${ansis.gray("(\u5FC5\u586B)")}`,
1889
- validate: (v) => v.trim() !== "" || "\u8BF7\u8F93\u5165 API URL"
2413
+ message: `API URL ${ansis.gray(`(${i18n.t("init:api.urlRequired")})`)}`,
2414
+ validate: (v) => v.trim() !== "" || i18n.t("init:api.enterUrl")
1890
2415
  },
1891
2416
  {
1892
2417
  type: "password",
1893
2418
  name: "key",
1894
- message: `API Key ${ansis.gray("(\u5FC5\u586B)")}`,
2419
+ message: `API Key ${ansis.gray(`(${i18n.t("init:api.keyRequired")})`)}`,
1895
2420
  mask: "*",
1896
- validate: (v) => v.trim() !== "" || "\u8BF7\u8F93\u5165 API Key"
2421
+ validate: (v) => v.trim() !== "" || i18n.t("init:api.enterKey")
1897
2422
  }
1898
2423
  ]);
1899
2424
  apiUrl = apiAnswers.url?.trim() || "";
@@ -1907,9 +2432,8 @@ async function init(options = {}) {
1907
2432
  const { enableWebUI } = await inquirer.prompt([{
1908
2433
  type: "confirm",
1909
2434
  name: "enableWebUI",
1910
- message: `\u542F\u7528 Web UI \u5B9E\u65F6\u8F93\u51FA\uFF1F${ansis.gray("(\u7981\u7528\u53EF\u52A0\u901F\u54CD\u5E94)")}`,
2435
+ message: `${i18n.t("init:webui.prompt")} ${ansis.gray(`(${i18n.t("init:webui.disableHint")})`)}`,
1911
2436
  default: !currentLiteMode
1912
- // Default to current setting (inverted)
1913
2437
  }]);
1914
2438
  liteMode = !enableWebUI;
1915
2439
  } else {
@@ -1939,10 +2463,10 @@ async function init(options = {}) {
1939
2463
  console.log(ansis.yellow("\u2501".repeat(50)));
1940
2464
  console.log(ansis.bold(` ${i18n.t("init:summary.title")}`));
1941
2465
  console.log();
1942
- console.log(` ${ansis.cyan("\u6A21\u578B\u8DEF\u7531")} ${ansis.green("Gemini")} (\u524D\u7AEF) + ${ansis.blue("Codex")} (\u540E\u7AEF)`);
1943
- console.log(` ${ansis.cyan("\u547D\u4EE4\u6570\u91CF")} ${ansis.yellow(selectedWorkflows.length.toString())} \u4E2A`);
1944
- console.log(` ${ansis.cyan("MCP \u5DE5\u5177")} ${mcpProvider === "ace-tool" || mcpProvider === "ace-tool-rs" ? aceToolToken ? ansis.green(mcpProvider) : ansis.yellow(`${mcpProvider} (\u5F85\u914D\u7F6E)`) : ansis.gray("\u8DF3\u8FC7")}`);
1945
- console.log(` ${ansis.cyan("Web UI")} ${liteMode ? ansis.gray("\u7981\u7528") : ansis.green("\u542F\u7528")}`);
2466
+ console.log(` ${ansis.cyan(i18n.t("init:summary.modelRouting"))} ${ansis.green("Gemini")} (Frontend) + ${ansis.blue("Codex")} (Backend)`);
2467
+ console.log(` ${ansis.cyan(i18n.t("init:summary.commandCount"))} ${ansis.yellow(selectedWorkflows.length.toString())}`);
2468
+ console.log(` ${ansis.cyan(i18n.t("init:summary.mcpTool"))} ${mcpProvider === "ace-tool" || mcpProvider === "ace-tool-rs" ? aceToolToken ? ansis.green(mcpProvider) : ansis.yellow(`${mcpProvider} (${i18n.t("init:summary.pendingConfig")})`) : mcpProvider === "contextweaver" ? contextWeaverApiKey ? ansis.green("contextweaver") : ansis.yellow(`contextweaver (${i18n.t("init:summary.pendingConfig")})`) : ansis.gray(i18n.t("init:summary.skipped"))}`);
2469
+ console.log(` ${ansis.cyan(i18n.t("init:summary.webUI"))} ${liteMode ? ansis.gray(i18n.t("init:summary.disabled")) : ansis.green(i18n.t("init:summary.enabled"))}`);
1946
2470
  console.log(ansis.yellow("\u2501".repeat(50)));
1947
2471
  console.log();
1948
2472
  if (!options.skipPrompt && !options.force) {
@@ -2019,7 +2543,7 @@ async function init(options = {}) {
2019
2543
  console.log(ansis.gray(` ${aceResult.message}`));
2020
2544
  }
2021
2545
  } else if (mcpProvider === "contextweaver" && contextWeaverApiKey) {
2022
- spinner.text = "\u6B63\u5728\u914D\u7F6E ContextWeaver MCP...";
2546
+ spinner.text = i18n.t("init:mcp.cwConfiguring");
2023
2547
  const cwResult = await installContextWeaver({
2024
2548
  siliconflowApiKey: contextWeaverApiKey
2025
2549
  });
@@ -2027,30 +2551,30 @@ async function init(options = {}) {
2027
2551
  spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
2028
2552
  console.log();
2029
2553
  console.log(` ${ansis.green("\u2713")} ContextWeaver MCP ${ansis.gray(`\u2192 ${cwResult.configPath}`)}`);
2030
- console.log(` ${ansis.green("\u2713")} \u914D\u7F6E\u6587\u4EF6 ${ansis.gray("\u2192 ~/.contextweaver/.env")}`);
2554
+ console.log(` ${ansis.green("\u2713")} ${i18n.t("init:mcp.cwConfigFile")} ${ansis.gray("\u2192 ~/.contextweaver/.env")}`);
2031
2555
  console.log();
2032
- console.log(ansis.cyan(` \u{1F4D6} \u9996\u6B21\u4F7F\u7528\u9700\u8981\u7D22\u5F15\u4EE3\u7801\u5E93\uFF1A`));
2556
+ console.log(ansis.cyan(` \u{1F4D6} ${i18n.t("init:mcp.cwIndexHint")}`));
2033
2557
  console.log(ansis.gray(` cd your-project && cw index`));
2034
2558
  } else {
2035
- spinner.warn(ansis.yellow("ContextWeaver MCP \u914D\u7F6E\u5931\u8D25"));
2559
+ spinner.warn(ansis.yellow(i18n.t("init:mcp.cwFailed")));
2036
2560
  console.log(ansis.gray(` ${cwResult.message}`));
2037
2561
  }
2038
2562
  } else if (mcpProvider === "contextweaver" && !contextWeaverApiKey) {
2039
2563
  spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
2040
2564
  console.log();
2041
- console.log(` ${ansis.yellow("\u26A0")} ContextWeaver MCP \u672A\u5B89\u88C5 ${ansis.gray("(API Key \u672A\u63D0\u4F9B)")}`);
2042
- console.log(` ${ansis.gray("\u2192")} \u7A0D\u540E\u8FD0\u884C ${ansis.cyan("npx ccg config mcp")} \u5B8C\u6210\u914D\u7F6E`);
2565
+ console.log(` ${ansis.yellow("\u26A0")} ContextWeaver MCP ${i18n.t("init:mcp.notInstalled")} ${ansis.gray(`(${i18n.t("init:mcp.keyNotProvided")})`)}`);
2566
+ console.log(` ${ansis.gray("\u2192")} ${i18n.t("init:mcp.configLater", { cmd: ansis.cyan("npx ccg config mcp") })}`);
2043
2567
  } else if ((mcpProvider === "ace-tool" || mcpProvider === "ace-tool-rs") && !aceToolToken) {
2044
2568
  const toolName = mcpProvider === "ace-tool-rs" ? "ace-tool-rs" : "ace-tool";
2045
2569
  spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
2046
2570
  console.log();
2047
- console.log(` ${ansis.yellow("\u26A0")} ${toolName} MCP \u672A\u5B89\u88C5 ${ansis.gray("(Token \u672A\u63D0\u4F9B)")}`);
2048
- console.log(` ${ansis.gray("\u2192")} \u7A0D\u540E\u8FD0\u884C ${ansis.cyan("npx ccg config mcp")} \u5B8C\u6210\u914D\u7F6E`);
2571
+ console.log(` ${ansis.yellow("\u26A0")} ${toolName} MCP ${i18n.t("init:mcp.notInstalled")} ${ansis.gray(`(${i18n.t("init:mcp.tokenNotProvided")})`)}`);
2572
+ console.log(` ${ansis.gray("\u2192")} ${i18n.t("init:mcp.configLater", { cmd: ansis.cyan("npx ccg config mcp") })}`);
2049
2573
  } else {
2050
2574
  spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
2051
2575
  }
2576
+ const settingsPath = join(installDir, "settings.json");
2052
2577
  if (apiUrl && apiKey) {
2053
- const settingsPath = join(installDir, "settings.json");
2054
2578
  let settings = {};
2055
2579
  if (await fs.pathExists(settingsPath)) {
2056
2580
  settings = await fs.readJSON(settingsPath);
@@ -2079,7 +2603,20 @@ async function init(options = {}) {
2079
2603
  }
2080
2604
  await fs.writeJSON(settingsPath, settings, { spaces: 2 });
2081
2605
  console.log();
2082
- console.log(` ${ansis.green("\u2713")} API \u914D\u7F6E ${ansis.gray(`\u2192 ${settingsPath}`)}`);
2606
+ console.log(` ${ansis.green("\u2713")} API ${ansis.gray(`\u2192 ${settingsPath}`)}`);
2607
+ }
2608
+ await installHook(settingsPath);
2609
+ console.log();
2610
+ console.log(` ${ansis.green("\u2713")} ${i18n.t("init:hooks.installed")}`);
2611
+ const hasJq = await checkJqAvailable();
2612
+ if (!hasJq) {
2613
+ console.log();
2614
+ console.log(ansis.yellow(` \u26A0 ${i18n.t("init:hooks.jqNotFound")}`));
2615
+ console.log();
2616
+ console.log(ansis.cyan(` \u{1F4D6} ${i18n.t("init:hooks.jqInstallHint")}:`));
2617
+ console.log(ansis.gray(` ${i18n.t("init:hooks.jqMac")}`));
2618
+ console.log(ansis.gray(` ${i18n.t("init:hooks.jqLinux")}`));
2619
+ console.log(ansis.gray(` ${i18n.t("init:hooks.jqWindows")}`));
2083
2620
  }
2084
2621
  console.log();
2085
2622
  console.log(ansis.cyan(` ${i18n.t("init:installedCommands")}`));
@@ -2124,7 +2661,7 @@ async function init(options = {}) {
2124
2661
  const escapedPath = windowsPath.replace(/'/g, "''");
2125
2662
  const psScript = currentPath ? `$p=[System.Environment]::GetEnvironmentVariable('PATH','User');[System.Environment]::SetEnvironmentVariable('PATH',($p+';'+'${escapedPath}'),'User')` : `[System.Environment]::SetEnvironmentVariable('PATH','${escapedPath}','User')`;
2126
2663
  execSync(`powershell ${psFlags} -Command "${psScript}"`, { stdio: "pipe" });
2127
- console.log(` ${ansis.green("\u2713")} PATH ${ansis.gray("\u2192 \u7528\u6237\u73AF\u5883\u53D8\u91CF")}`);
2664
+ console.log(` ${ansis.green("\u2713")} PATH ${ansis.gray("\u2192 User env")}`);
2128
2665
  }
2129
2666
  } catch {
2130
2667
  }
@@ -2143,7 +2680,7 @@ async function init(options = {}) {
2143
2680
  rcContent = await fs.readFile(shellRc, "utf-8");
2144
2681
  }
2145
2682
  if (rcContent.includes(result.binPath) || rcContent.includes("/.claude/bin")) {
2146
- console.log(` ${ansis.green("\u2713")} PATH ${ansis.gray(`\u2192 ${shellRcDisplay} (\u5DF2\u914D\u7F6E)`)}`);
2683
+ console.log(` ${ansis.green("\u2713")} PATH ${ansis.gray(`\u2192 ${shellRcDisplay} (${i18n.t("init:pathAlreadyConfigured", { file: shellRcDisplay })})`)}`);
2147
2684
  } else {
2148
2685
  const configLine = `
2149
2686
  # CCG multi-model collaboration system
@@ -2155,25 +2692,25 @@ ${exportCommand}
2155
2692
  } catch {
2156
2693
  }
2157
2694
  } else {
2158
- console.log(` ${ansis.yellow("\u26A0")} PATH ${ansis.gray("\u2192 \u8BF7\u624B\u52A8\u6DFB\u52A0\u5230 shell \u914D\u7F6E:")}`);
2695
+ console.log(` ${ansis.yellow("\u26A0")} PATH ${ansis.gray(`\u2192 ${i18n.t("init:addToPathManually")}`)}`);
2159
2696
  console.log(` ${ansis.cyan(exportCommand)}`);
2160
2697
  }
2161
2698
  }
2162
2699
  }
2163
2700
  if (mcpProvider === "skip" || (mcpProvider === "ace-tool" || mcpProvider === "ace-tool-rs") && !aceToolToken || mcpProvider === "contextweaver" && !contextWeaverApiKey) {
2164
2701
  console.log();
2165
- console.log(ansis.cyan.bold(` \u{1F4D6} MCP \u670D\u52A1\u9009\u9879`));
2702
+ console.log(ansis.cyan.bold(` \u{1F4D6} ${i18n.t("init:mcp.mcpOptions")}`));
2166
2703
  console.log();
2167
- console.log(ansis.gray(` \u5982\u9700\u4F7F\u7528\u4EE3\u7801\u68C0\u7D22\u529F\u80FD\uFF0C\u53EF\u9009\u62E9\u4EE5\u4E0B MCP \u670D\u52A1\uFF1A`));
2704
+ console.log(ansis.gray(` ${i18n.t("init:mcp.mcpOptionsHint")}`));
2168
2705
  console.log();
2169
2706
  console.log(` ${ansis.green("1.")} ${ansis.cyan("ace-tool / ace-tool-rs")}: ${ansis.underline("https://augmentcode.com/")}`);
2170
- console.log(` ${ansis.gray("Augment \u5B98\u65B9\uFF0C\u542B Prompt \u589E\u5F3A + \u4EE3\u7801\u68C0\u7D22")}`);
2707
+ console.log(` ${ansis.gray(i18n.t("init:mcp.promptEnhancement"))}`);
2171
2708
  console.log();
2172
- console.log(` ${ansis.green("2.")} ${ansis.cyan("ace-tool \u4E2D\u8F6C\u670D\u52A1")} ${ansis.yellow("(\u65E0\u9700\u6CE8\u518C)")}: ${ansis.underline("https://linux.do/t/topic/1291730")}`);
2173
- console.log(` ${ansis.gray("linux.do \u793E\u533A\u63D0\u4F9B\u7684\u514D\u8D39\u4E2D\u8F6C\u670D\u52A1")}`);
2709
+ console.log(` ${ansis.green("2.")} ${ansis.cyan("ace-tool " + i18n.t("init:mcp.proxyService"))} ${ansis.yellow(`(${i18n.t("init:mcp.noSignup")})`)}: ${ansis.underline("https://linux.do/t/topic/1291730")}`);
2710
+ console.log(` ${ansis.gray(i18n.t("init:mcp.communityProxy"))}`);
2174
2711
  console.log();
2175
- console.log(` ${ansis.green("3.")} ${ansis.cyan("ContextWeaver")} ${ansis.yellow("(\u672C\u5730)")}: ${ansis.underline("https://siliconflow.cn/")}`);
2176
- console.log(` ${ansis.gray("\u672C\u5730\u5411\u91CF\u5E93\uFF0C\u9700\u8981\u7845\u57FA\u6D41\u52A8 API Key\uFF08\u6709\u514D\u8D39\u989D\u5EA6\uFF09")}`);
2712
+ console.log(` ${ansis.green("3.")} ${ansis.cyan("ContextWeaver")} ${ansis.yellow(`(${i18n.t("init:mcp.freeQuota")})`)}: ${ansis.underline("https://siliconflow.cn/")}`);
2713
+ console.log(` ${ansis.gray(i18n.t("init:mcp.localEngine"))}`);
2177
2714
  console.log();
2178
2715
  }
2179
2716
  console.log();
@@ -2248,9 +2785,9 @@ async function checkForUpdates() {
2248
2785
  const execAsync$1 = promisify(exec);
2249
2786
  async function update() {
2250
2787
  console.log();
2251
- console.log(ansis.cyan.bold("\u{1F504} \u68C0\u67E5\u66F4\u65B0..."));
2788
+ console.log(ansis.cyan.bold(`\u{1F504} ${i18n.t("update:checking")}`));
2252
2789
  console.log();
2253
- const spinner = ora("\u6B63\u5728\u68C0\u67E5\u6700\u65B0\u7248\u672C...").start();
2790
+ const spinner = ora(i18n.t("update:checkingLatest")).start();
2254
2791
  try {
2255
2792
  const { hasUpdate, currentVersion, latestVersion } = await checkForUpdates();
2256
2793
  const config = await readCcgConfig();
@@ -2258,26 +2795,26 @@ async function update() {
2258
2795
  const needsWorkflowUpdate = compareVersions(currentVersion, localVersion) > 0;
2259
2796
  spinner.stop();
2260
2797
  if (!latestVersion) {
2261
- console.log(ansis.red("\u274C \u65E0\u6CD5\u8FDE\u63A5\u5230 npm registry\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5"));
2798
+ console.log(ansis.red(`\u274C ${i18n.t("update:cannotConnect")}`));
2262
2799
  return;
2263
2800
  }
2264
- console.log(`\u5F53\u524D\u7248\u672C: ${ansis.yellow(`v${currentVersion}`)}`);
2265
- console.log(`\u6700\u65B0\u7248\u672C: ${ansis.green(`v${latestVersion}`)}`);
2801
+ console.log(`${i18n.t("update:currentVersion")}: ${ansis.yellow(`v${currentVersion}`)}`);
2802
+ console.log(`${i18n.t("update:latestVersion")}: ${ansis.green(`v${latestVersion}`)}`);
2266
2803
  if (localVersion !== "0.0.0") {
2267
- console.log(`\u672C\u5730\u5DE5\u4F5C\u6D41: ${ansis.gray(`v${localVersion}`)}`);
2804
+ console.log(`${i18n.t("update:localWorkflow")}: ${ansis.gray(`v${localVersion}`)}`);
2268
2805
  }
2269
2806
  console.log();
2270
2807
  const effectiveNeedsUpdate = hasUpdate || needsWorkflowUpdate;
2271
2808
  let defaultConfirm = effectiveNeedsUpdate;
2272
2809
  let message;
2273
2810
  if (hasUpdate) {
2274
- message = `\u53D1\u73B0\u65B0\u7248\u672C v${latestVersion} (\u5F53\u524D: v${currentVersion})\uFF0C\u662F\u5426\u66F4\u65B0\uFF1F`;
2811
+ message = i18n.t("update:newVersionFound", { latest: latestVersion, current: currentVersion });
2275
2812
  defaultConfirm = true;
2276
2813
  } else if (needsWorkflowUpdate) {
2277
- message = `\u68C0\u6D4B\u5230\u672C\u5730\u5DE5\u4F5C\u6D41\u7248\u672C (v${localVersion}) \u4F4E\u4E8E\u5F53\u524D\u7248\u672C (v${currentVersion})\uFF0C\u662F\u5426\u66F4\u65B0\uFF1F`;
2814
+ message = i18n.t("update:localOutdated", { local: localVersion, current: currentVersion });
2278
2815
  defaultConfirm = true;
2279
2816
  } else {
2280
- message = `\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C (v${currentVersion})\u3002\u662F\u5426\u5F3A\u5236\u91CD\u65B0\u5B89\u88C5/\u4FEE\u590D\u5DE5\u4F5C\u6D41\uFF1F`;
2817
+ message = i18n.t("update:alreadyLatest", { current: currentVersion });
2281
2818
  defaultConfirm = false;
2282
2819
  }
2283
2820
  const { confirmUpdate } = await inquirer.prompt([{
@@ -2287,14 +2824,14 @@ async function update() {
2287
2824
  default: defaultConfirm
2288
2825
  }]);
2289
2826
  if (!confirmUpdate) {
2290
- console.log(ansis.gray("\u5DF2\u53D6\u6D88\u66F4\u65B0"));
2827
+ console.log(ansis.gray(i18n.t("update:cancelled")));
2291
2828
  return;
2292
2829
  }
2293
2830
  const fromVersion = needsWorkflowUpdate ? localVersion : currentVersion;
2294
- await performUpdate(fromVersion, latestVersion || currentVersion, hasUpdate || needsWorkflowUpdate);
2831
+ await performUpdate(fromVersion, latestVersion || currentVersion, hasUpdate);
2295
2832
  } catch (error) {
2296
2833
  spinner.stop();
2297
- console.log(ansis.red(`\u274C \u66F4\u65B0\u5931\u8D25: ${error}`));
2834
+ console.log(ansis.red(`\u274C ${i18n.t("update:error", { error: String(error) })}`));
2298
2835
  }
2299
2836
  }
2300
2837
  async function checkIfGlobalInstall$1() {
@@ -2307,49 +2844,49 @@ async function checkIfGlobalInstall$1() {
2307
2844
  }
2308
2845
  async function performUpdate(fromVersion, toVersion, isNewVersion) {
2309
2846
  console.log();
2310
- console.log(ansis.yellow.bold("\u2699\uFE0F \u5F00\u59CB\u66F4\u65B0..."));
2847
+ console.log(ansis.yellow.bold(`\u2699\uFE0F ${i18n.t("update:starting")}`));
2311
2848
  console.log();
2312
2849
  const isGlobalInstall = await checkIfGlobalInstall$1();
2313
2850
  if (isGlobalInstall && !isNewVersion) {
2314
- console.log(ansis.cyan("\u2139\uFE0F \u68C0\u6D4B\u5230\u4F60\u662F\u901A\u8FC7 npm \u5168\u5C40\u5B89\u88C5\u7684"));
2851
+ console.log(ansis.cyan(`\u2139\uFE0F ${i18n.t("update:globalDetected")}`));
2315
2852
  console.log();
2316
- console.log(ansis.green("\u2713 \u5F53\u524D\u5305\u7248\u672C\u5DF2\u662F\u6700\u65B0 (v" + toVersion + ")"));
2317
- console.log(ansis.yellow("\u2699\uFE0F \u4EC5\u9700\u66F4\u65B0\u5DE5\u4F5C\u6D41\u6587\u4EF6"));
2853
+ console.log(ansis.green(`\u2713 ${i18n.t("update:packageLatest")} (v${toVersion})`));
2854
+ console.log(ansis.yellow(`\u2699\uFE0F ${i18n.t("update:workflowOnly")}`));
2318
2855
  console.log();
2319
2856
  } else if (isGlobalInstall && isNewVersion) {
2320
- console.log(ansis.yellow("\u26A0\uFE0F \u68C0\u6D4B\u5230\u4F60\u662F\u901A\u8FC7 npm \u5168\u5C40\u5B89\u88C5\u7684"));
2857
+ console.log(ansis.yellow(`\u26A0\uFE0F ${i18n.t("update:globalDetected")}`));
2321
2858
  console.log();
2322
- console.log("\u63A8\u8350\u7684\u66F4\u65B0\u65B9\u5F0F\uFF1A");
2859
+ console.log(`${i18n.t("update:recommendNpm")}`);
2323
2860
  console.log();
2324
2861
  console.log(ansis.cyan(" npm install -g ccg-workflow@latest"));
2325
2862
  console.log();
2326
- console.log(ansis.gray("\u8FD9\u5C06\u540C\u65F6\u66F4\u65B0\u547D\u4EE4\u548C\u5DE5\u4F5C\u6D41\u6587\u4EF6"));
2863
+ console.log(ansis.gray(i18n.t("update:willUpdateBoth")));
2327
2864
  console.log();
2328
2865
  const { useNpmUpdate } = await inquirer.prompt([{
2329
2866
  type: "confirm",
2330
2867
  name: "useNpmUpdate",
2331
- message: "\u6539\u7528 npm \u66F4\u65B0\uFF08\u63A8\u8350\uFF09\uFF1F",
2868
+ message: i18n.t("update:useNpmUpdate"),
2332
2869
  default: true
2333
2870
  }]);
2334
2871
  if (useNpmUpdate) {
2335
2872
  console.log();
2336
- console.log(ansis.cyan("\u8BF7\u5728\u65B0\u7684\u7EC8\u7AEF\u7A97\u53E3\u4E2D\u8FD0\u884C\uFF1A"));
2873
+ console.log(ansis.cyan(i18n.t("update:runInNewTerminal")));
2337
2874
  console.log();
2338
2875
  console.log(ansis.cyan.bold(" npm install -g ccg-workflow@latest"));
2339
2876
  console.log();
2340
- console.log(ansis.gray("(\u8FD0\u884C\u5B8C\u6210\u540E\uFF0C\u5F53\u524D\u7248\u672C\u5C06\u81EA\u52A8\u66F4\u65B0)"));
2877
+ console.log(ansis.gray(`(${i18n.t("update:autoUpdateAfter")})`));
2341
2878
  console.log();
2342
2879
  return;
2343
2880
  }
2344
2881
  console.log();
2345
- console.log(ansis.yellow("\u26A0\uFE0F \u7EE7\u7EED\u4F7F\u7528\u5185\u7F6E\u66F4\u65B0\uFF08\u4EC5\u66F4\u65B0\u5DE5\u4F5C\u6D41\u6587\u4EF6\uFF09"));
2346
- console.log(ansis.gray("\u6CE8\u610F\uFF1A\u8FD9\u4E0D\u4F1A\u66F4\u65B0 ccg \u547D\u4EE4\u672C\u8EAB"));
2882
+ console.log(ansis.yellow(`\u26A0\uFE0F ${i18n.t("update:continueBuiltin")}`));
2883
+ console.log(ansis.gray(i18n.t("update:willNotUpdateCli")));
2347
2884
  console.log();
2348
2885
  }
2349
- let spinner = ora("\u6B63\u5728\u4E0B\u8F7D\u6700\u65B0\u7248\u672C...").start();
2886
+ let spinner = ora(i18n.t("update:downloading")).start();
2350
2887
  try {
2351
2888
  if (process.platform === "win32") {
2352
- spinner.text = "\u6B63\u5728\u6E05\u7406 npx \u7F13\u5B58...";
2889
+ spinner.text = i18n.t("update:clearingCache");
2353
2890
  try {
2354
2891
  await execAsync$1("npx clear-npx-cache", { timeout: 1e4 });
2355
2892
  } catch {
@@ -2361,26 +2898,26 @@ async function performUpdate(fromVersion, toVersion, isNewVersion) {
2361
2898
  }
2362
2899
  }
2363
2900
  }
2364
- spinner.text = "\u6B63\u5728\u4E0B\u8F7D\u6700\u65B0\u7248\u672C...";
2901
+ spinner.text = i18n.t("update:downloading");
2365
2902
  await execAsync$1(`npx --yes ccg-workflow@latest --version`, { timeout: 6e4 });
2366
- spinner.succeed("\u6700\u65B0\u7248\u672C\u4E0B\u8F7D\u5B8C\u6210");
2903
+ spinner.succeed(i18n.t("update:downloadDone"));
2367
2904
  } catch (error) {
2368
- spinner.fail("\u4E0B\u8F7D\u6700\u65B0\u7248\u672C\u5931\u8D25");
2369
- console.log(ansis.red(`\u9519\u8BEF: ${error}`));
2905
+ spinner.fail(i18n.t("update:downloadFailed"));
2906
+ console.log(ansis.red(`${i18n.t("common:error")}: ${error}`));
2370
2907
  return;
2371
2908
  }
2372
2909
  if (await needsMigration()) {
2373
- spinner = ora("\u68C0\u6D4B\u5230\u65E7\u7248\u672C\u914D\u7F6E\uFF0C\u6B63\u5728\u8FC1\u79FB...").start();
2910
+ spinner = ora(i18n.t("update:migrating")).start();
2374
2911
  const migrationResult = await migrateToV1_4_0();
2375
2912
  if (migrationResult.migratedFiles.length > 0) {
2376
- spinner.info(ansis.cyan("\u914D\u7F6E\u8FC1\u79FB\u5B8C\u6210:"));
2913
+ spinner.info(ansis.cyan(i18n.t("update:migrationDone")));
2377
2914
  console.log();
2378
2915
  for (const file of migrationResult.migratedFiles) {
2379
2916
  console.log(` ${ansis.green("\u2713")} ${file}`);
2380
2917
  }
2381
2918
  if (migrationResult.skipped.length > 0) {
2382
2919
  console.log();
2383
- console.log(ansis.gray(" \u5DF2\u8DF3\u8FC7:"));
2920
+ console.log(ansis.gray(` ${i18n.t("update:migrationSkipped")}`));
2384
2921
  for (const file of migrationResult.skipped) {
2385
2922
  console.log(` ${ansis.gray("\u25CB")} ${file}`);
2386
2923
  }
@@ -2388,62 +2925,61 @@ async function performUpdate(fromVersion, toVersion, isNewVersion) {
2388
2925
  console.log();
2389
2926
  }
2390
2927
  if (migrationResult.errors.length > 0) {
2391
- spinner.warn(ansis.yellow("\u8FC1\u79FB\u5B8C\u6210\uFF0C\u4F46\u6709\u90E8\u5206\u9519\u8BEF:"));
2928
+ spinner.warn(ansis.yellow(i18n.t("update:migrationErrors")));
2392
2929
  for (const error of migrationResult.errors) {
2393
2930
  console.log(` ${ansis.red("\u2717")} ${error}`);
2394
2931
  }
2395
2932
  console.log();
2396
2933
  }
2397
2934
  }
2398
- spinner = ora("\u6B63\u5728\u5220\u9664\u65E7\u5DE5\u4F5C\u6D41...").start();
2935
+ spinner = ora(i18n.t("update:removingOld")).start();
2399
2936
  try {
2400
2937
  const installDir = join(homedir(), ".claude");
2401
2938
  const uninstallResult = await uninstallWorkflows(installDir);
2402
2939
  if (uninstallResult.success) {
2403
- spinner.succeed("\u65E7\u5DE5\u4F5C\u6D41\u5DF2\u5220\u9664");
2940
+ spinner.succeed(i18n.t("update:oldRemoved"));
2404
2941
  } else {
2405
- spinner.warn("\u90E8\u5206\u6587\u4EF6\u5220\u9664\u5931\u8D25\uFF0C\u7EE7\u7EED\u5B89\u88C5...");
2942
+ spinner.warn(i18n.t("update:partialRemoveFailed"));
2406
2943
  for (const error of uninstallResult.errors) {
2407
2944
  console.log(ansis.yellow(` \u2022 ${error}`));
2408
2945
  }
2409
2946
  }
2410
2947
  } catch (error) {
2411
- spinner.warn(`\u5220\u9664\u65E7\u5DE5\u4F5C\u6D41\u65F6\u51FA\u9519: ${error}\uFF0C\u7EE7\u7EED\u5B89\u88C5...`);
2948
+ spinner.warn(i18n.t("update:removeFailed", { error: String(error) }));
2412
2949
  }
2413
- spinner = ora("\u6B63\u5728\u5B89\u88C5\u65B0\u7248\u672C\u5DE5\u4F5C\u6D41\u548C\u4E8C\u8FDB\u5236...").start();
2950
+ spinner = ora(i18n.t("update:installingNew")).start();
2414
2951
  try {
2415
2952
  await execAsync$1(`npx --yes ccg-workflow@latest init --force --skip-mcp --skip-prompt`, {
2416
2953
  timeout: 12e4,
2417
2954
  env: {
2418
2955
  ...process.env,
2419
2956
  CCG_UPDATE_MODE: "true"
2420
- // Signal to init that this is an update
2421
2957
  }
2422
2958
  });
2423
- spinner.succeed("\u65B0\u7248\u672C\u5B89\u88C5\u6210\u529F");
2959
+ spinner.succeed(i18n.t("update:installDone"));
2424
2960
  const config = await readCcgConfig();
2425
2961
  if (config?.workflows?.installed) {
2426
2962
  console.log();
2427
- console.log(ansis.cyan(`\u5DF2\u5B89\u88C5 ${config.workflows.installed.length} \u4E2A\u547D\u4EE4:`));
2963
+ console.log(ansis.cyan(i18n.t("update:installed", { count: config.workflows.installed.length })));
2428
2964
  for (const cmd of config.workflows.installed) {
2429
2965
  console.log(` ${ansis.gray("\u2022")} /ccg:${cmd}`);
2430
2966
  }
2431
2967
  }
2432
2968
  } catch (error) {
2433
- spinner.fail("\u5B89\u88C5\u65B0\u7248\u672C\u5931\u8D25");
2434
- console.log(ansis.red(`\u9519\u8BEF: ${error}`));
2969
+ spinner.fail(i18n.t("update:installFailed"));
2970
+ console.log(ansis.red(`${i18n.t("common:error")}: ${error}`));
2435
2971
  console.log();
2436
- console.log(ansis.yellow("\u8BF7\u5C1D\u8BD5\u624B\u52A8\u8FD0\u884C:"));
2972
+ console.log(ansis.yellow(i18n.t("update:manualRetry")));
2437
2973
  console.log(ansis.cyan(" npx ccg-workflow@latest"));
2438
2974
  return;
2439
2975
  }
2440
2976
  console.log();
2441
- console.log(ansis.green.bold("\u2705 \u66F4\u65B0\u5B8C\u6210\uFF01"));
2977
+ console.log(ansis.green.bold(`\u2705 ${i18n.t("update:updateDone")}`));
2442
2978
  console.log();
2443
2979
  if (isNewVersion) {
2444
- console.log(ansis.gray(`\u4ECE v${fromVersion} \u5347\u7EA7\u5230 v${toVersion}`));
2980
+ console.log(ansis.gray(i18n.t("update:upgradedFromTo", { from: fromVersion, to: toVersion })));
2445
2981
  } else {
2446
- console.log(ansis.gray(`\u91CD\u65B0\u5B89\u88C5\u4E86 v${toVersion}`));
2982
+ console.log(ansis.gray(i18n.t("update:reinstalled", { version: toVersion })));
2447
2983
  }
2448
2984
  console.log();
2449
2985
  }
@@ -2462,11 +2998,11 @@ async function showMainMenu() {
2462
2998
  choices: [
2463
2999
  { name: `${ansis.green("\u279C")} ${i18n.t("menu:options.init")}`, value: "init" },
2464
3000
  { name: `${ansis.blue("\u279C")} ${i18n.t("menu:options.update")}`, value: "update" },
2465
- { name: `${ansis.cyan("\u2699")} \u914D\u7F6E MCP`, value: "config-mcp" },
2466
- { name: `${ansis.cyan("\u{1F511}")} \u914D\u7F6E API`, value: "config-api" },
2467
- { name: `${ansis.magenta("\u{1F3AD}")} \u914D\u7F6E\u8F93\u51FA\u98CE\u683C`, value: "config-style" },
2468
- { name: `${ansis.yellow("\u{1F527}")} \u5B9E\u7528\u5DE5\u5177`, value: "tools" },
2469
- { name: `${ansis.blue("\u{1F4E6}")} \u5B89\u88C5 Claude Code`, value: "install-claude" },
3001
+ { name: `${ansis.cyan("\u2699")} ${i18n.t("menu:options.configMcp")}`, value: "config-mcp" },
3002
+ { name: `${ansis.cyan("\u{1F511}")} ${i18n.t("menu:options.configApi")}`, value: "config-api" },
3003
+ { name: `${ansis.magenta("\u{1F3AD}")} ${i18n.t("menu:options.configStyle")}`, value: "config-style" },
3004
+ { name: `${ansis.yellow("\u{1F527}")} ${i18n.t("menu:options.tools")}`, value: "tools" },
3005
+ { name: `${ansis.blue("\u{1F4E6}")} ${i18n.t("menu:options.installClaude")}`, value: "install-claude" },
2470
3006
  { name: `${ansis.magenta("\u279C")} ${i18n.t("menu:options.uninstall")}`, value: "uninstall" },
2471
3007
  { name: `${ansis.yellow("?")} ${i18n.t("menu:options.help")}`, value: "help" },
2472
3008
  new inquirer.Separator(),
@@ -2502,14 +3038,14 @@ async function showMainMenu() {
2502
3038
  showHelp();
2503
3039
  break;
2504
3040
  case "exit":
2505
- console.log(ansis.gray("\u518D\u89C1\uFF01"));
3041
+ console.log(ansis.gray(i18n.t("common:goodbye")));
2506
3042
  return;
2507
3043
  }
2508
3044
  console.log();
2509
3045
  await inquirer.prompt([{
2510
3046
  type: "input",
2511
3047
  name: "continue",
2512
- message: ansis.gray("\u6309 Enter \u8FD4\u56DE\u4E3B\u83DC\u5355...")
3048
+ message: ansis.gray(i18n.t("common:pressEnterToReturn"))
2513
3049
  }]);
2514
3050
  }
2515
3051
  }
@@ -2517,41 +3053,41 @@ function showHelp() {
2517
3053
  console.log();
2518
3054
  console.log(ansis.cyan.bold(i18n.t("menu:help.title")));
2519
3055
  console.log();
2520
- console.log(ansis.yellow.bold(" \u5F00\u53D1\u5DE5\u4F5C\u6D41:"));
2521
- console.log(` ${ansis.green("/ccg:workflow")} \u5B8C\u65746\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41`);
2522
- console.log(` ${ansis.green("/ccg:plan")} \u591A\u6A21\u578B\u534F\u4F5C\u89C4\u5212\uFF08Phase 1-2\uFF09`);
2523
- console.log(` ${ansis.green("/ccg:execute")} \u591A\u6A21\u578B\u534F\u4F5C\u6267\u884C\uFF08Phase 3-5\uFF09`);
3056
+ console.log(ansis.yellow.bold(` ${i18n.t("menu:help.sections.devWorkflow")}`));
3057
+ console.log(` ${ansis.green("/ccg:workflow")} ${i18n.t("menu:help.descriptions.workflow")}`);
3058
+ console.log(` ${ansis.green("/ccg:plan")} ${i18n.t("menu:help.descriptions.plan")}`);
3059
+ console.log(` ${ansis.green("/ccg:execute")} ${i18n.t("menu:help.descriptions.execute")}`);
2524
3060
  console.log(` ${ansis.green("/ccg:frontend")} ${i18n.t("menu:help.descriptions.frontend")}`);
2525
3061
  console.log(` ${ansis.green("/ccg:backend")} ${i18n.t("menu:help.descriptions.backend")}`);
2526
- console.log(` ${ansis.green("/ccg:feat")} \u667A\u80FD\u529F\u80FD\u5F00\u53D1`);
3062
+ console.log(` ${ansis.green("/ccg:feat")} ${i18n.t("menu:help.descriptions.feat")}`);
2527
3063
  console.log(` ${ansis.green("/ccg:analyze")} ${i18n.t("menu:help.descriptions.analyze")}`);
2528
- console.log(` ${ansis.green("/ccg:debug")} \u95EE\u9898\u8BCA\u65AD + \u4FEE\u590D`);
2529
- console.log(` ${ansis.green("/ccg:optimize")} \u6027\u80FD\u4F18\u5316`);
2530
- console.log(` ${ansis.green("/ccg:test")} \u6D4B\u8BD5\u751F\u6210`);
3064
+ console.log(` ${ansis.green("/ccg:debug")} ${i18n.t("menu:help.descriptions.debug")}`);
3065
+ console.log(` ${ansis.green("/ccg:optimize")} ${i18n.t("menu:help.descriptions.optimize")}`);
3066
+ console.log(` ${ansis.green("/ccg:test")} ${i18n.t("menu:help.descriptions.test")}`);
2531
3067
  console.log(` ${ansis.green("/ccg:review")} ${i18n.t("menu:help.descriptions.review")}`);
2532
3068
  console.log();
2533
- console.log(ansis.yellow.bold(" OpenSpec \u89C4\u8303\u9A71\u52A8:"));
2534
- console.log(` ${ansis.green("/ccg:spec-init")} \u521D\u59CB\u5316 OpenSpec \u73AF\u5883`);
2535
- console.log(` ${ansis.green("/ccg:spec-research")} \u9700\u6C42\u7814\u7A76 \u2192 \u7EA6\u675F\u96C6`);
2536
- console.log(` ${ansis.green("/ccg:spec-plan")} \u591A\u6A21\u578B\u5206\u6790 \u2192 \u96F6\u51B3\u7B56\u8BA1\u5212`);
2537
- console.log(` ${ansis.green("/ccg:spec-impl")} \u89C4\u8303\u9A71\u52A8\u5B9E\u73B0`);
2538
- console.log(` ${ansis.green("/ccg:spec-review")} \u5F52\u6863\u524D\u53CC\u6A21\u578B\u5BA1\u67E5`);
3069
+ console.log(ansis.yellow.bold(` ${i18n.t("menu:help.sections.opsx")}`));
3070
+ console.log(` ${ansis.green("/ccg:spec-init")} ${i18n.t("menu:help.descriptions.specInit")}`);
3071
+ console.log(` ${ansis.green("/ccg:spec-research")} ${i18n.t("menu:help.descriptions.specResearch")}`);
3072
+ console.log(` ${ansis.green("/ccg:spec-plan")} ${i18n.t("menu:help.descriptions.specPlan")}`);
3073
+ console.log(` ${ansis.green("/ccg:spec-impl")} ${i18n.t("menu:help.descriptions.specImpl")}`);
3074
+ console.log(` ${ansis.green("/ccg:spec-review")} ${i18n.t("menu:help.descriptions.specReview")}`);
2539
3075
  console.log();
2540
- console.log(ansis.yellow.bold(" Git \u5DE5\u5177:"));
3076
+ console.log(ansis.yellow.bold(` ${i18n.t("menu:help.sections.gitTools")}`));
2541
3077
  console.log(` ${ansis.green("/ccg:commit")} ${i18n.t("menu:help.descriptions.commit")}`);
2542
3078
  console.log(` ${ansis.green("/ccg:rollback")} ${i18n.t("menu:help.descriptions.rollback")}`);
2543
- console.log(` ${ansis.green("/ccg:clean-branches")} \u6E05\u7406\u5DF2\u5408\u5E76\u5206\u652F`);
2544
- console.log(` ${ansis.green("/ccg:worktree")} Git Worktree \u7BA1\u7406`);
3079
+ console.log(` ${ansis.green("/ccg:clean-branches")} ${i18n.t("menu:help.descriptions.cleanBranches")}`);
3080
+ console.log(` ${ansis.green("/ccg:worktree")} ${i18n.t("menu:help.descriptions.worktree")}`);
2545
3081
  console.log();
2546
- console.log(ansis.yellow.bold(" \u9879\u76EE\u7BA1\u7406:"));
2547
- console.log(` ${ansis.green("/ccg:init")} \u521D\u59CB\u5316\u9879\u76EE CLAUDE.md`);
3082
+ console.log(ansis.yellow.bold(` ${i18n.t("menu:help.sections.projectMgmt")}`));
3083
+ console.log(` ${ansis.green("/ccg:init")} ${i18n.t("menu:help.descriptions.init")}`);
2548
3084
  console.log();
2549
3085
  console.log(ansis.gray(i18n.t("menu:help.hint")));
2550
3086
  console.log();
2551
3087
  }
2552
3088
  async function configApi() {
2553
3089
  console.log();
2554
- console.log(ansis.cyan.bold(" \u914D\u7F6E Claude Code API"));
3090
+ console.log(ansis.cyan.bold(` ${i18n.t("menu:api.title")}`));
2555
3091
  console.log();
2556
3092
  const settingsPath = join(homedir(), ".claude", "settings.json");
2557
3093
  let settings = {};
@@ -2561,7 +3097,7 @@ async function configApi() {
2561
3097
  const currentUrl = settings.env?.ANTHROPIC_BASE_URL;
2562
3098
  const currentKey = settings.env?.ANTHROPIC_API_KEY || settings.env?.ANTHROPIC_AUTH_TOKEN;
2563
3099
  if (currentUrl || currentKey) {
2564
- console.log(ansis.gray(" \u5F53\u524D\u914D\u7F6E:"));
3100
+ console.log(ansis.gray(` ${i18n.t("menu:api.currentConfig")}`));
2565
3101
  if (currentUrl)
2566
3102
  console.log(ansis.gray(` URL: ${currentUrl}`));
2567
3103
  if (currentKey)
@@ -2572,18 +3108,18 @@ async function configApi() {
2572
3108
  {
2573
3109
  type: "input",
2574
3110
  name: "url",
2575
- message: `API URL ${ansis.gray("(\u7559\u7A7A\u4F7F\u7528\u5B98\u65B9)")}`,
3111
+ message: `${i18n.t("menu:api.urlPrompt")} ${ansis.gray(`(${i18n.t("menu:api.leaveEmptyOfficial")})`)}`,
2576
3112
  default: currentUrl || ""
2577
3113
  },
2578
3114
  {
2579
3115
  type: "password",
2580
3116
  name: "key",
2581
- message: `API Key ${ansis.gray("(\u7559\u7A7A\u8DF3\u8FC7)")}`,
3117
+ message: `${i18n.t("menu:api.keyPrompt")} ${ansis.gray(`(${i18n.t("menu:api.leaveEmptySkip")})`)}`,
2582
3118
  mask: "*"
2583
3119
  }
2584
3120
  ]);
2585
3121
  if (!answers.url && !answers.key) {
2586
- console.log(ansis.gray("\u672A\u4FEE\u6539\u914D\u7F6E"));
3122
+ console.log(ansis.gray(i18n.t("common:configNotModified")));
2587
3123
  return;
2588
3124
  }
2589
3125
  if (!settings.env)
@@ -2615,20 +3151,20 @@ async function configApi() {
2615
3151
  await fs.ensureDir(join(homedir(), ".claude"));
2616
3152
  await fs.writeJson(settingsPath, settings, { spaces: 2 });
2617
3153
  console.log();
2618
- console.log(ansis.green("\u2713 API \u914D\u7F6E\u5DF2\u4FDD\u5B58"));
2619
- console.log(ansis.gray(` \u914D\u7F6E\u6587\u4EF6: ${settingsPath}`));
3154
+ console.log(ansis.green(`\u2713 ${i18n.t("menu:api.saved")}`));
3155
+ console.log(ansis.gray(` ${i18n.t("common:configFile")}: ${settingsPath}`));
2620
3156
  }
2621
3157
  const OUTPUT_STYLES = [
2622
- { id: "default", name: "\u9ED8\u8BA4", desc: "Claude Code \u539F\u751F\u98CE\u683C" },
2623
- { id: "engineer-professional", name: "\u4E13\u4E1A\u5DE5\u7A0B\u5E08", desc: "\u7B80\u6D01\u4E13\u4E1A\u7684\u6280\u672F\u98CE\u683C" },
2624
- { id: "nekomata-engineer", name: "\u732B\u5A18\u5DE5\u7A0B\u5E08", desc: "\u53EF\u7231\u732B\u5A18\u8BED\u6C14\u55B5~" },
2625
- { id: "laowang-engineer", name: "\u8001\u738B\u5DE5\u7A0B\u5E08", desc: "\u63A5\u5730\u6C14\u7684\u8001\u738B\u98CE\u683C" },
2626
- { id: "ojousama-engineer", name: "\u5927\u5C0F\u59D0\u5DE5\u7A0B\u5E08", desc: "\u4F18\u96C5\u5927\u5C0F\u59D0\u8BED\u6C14" },
2627
- { id: "abyss-cultivator", name: "\u90AA\u4FEE\u98CE\u683C", desc: "\u5BBF\u547D\u6DF1\u6E0A\xB7\u9053\u8BED\u6807\u7B7E" }
3158
+ { id: "default", nameKey: "menu:style.default", descKey: "menu:style.defaultDesc" },
3159
+ { id: "engineer-professional", nameKey: "menu:style.engineerPro", descKey: "menu:style.engineerProDesc" },
3160
+ { id: "nekomata-engineer", nameKey: "menu:style.nekomata", descKey: "menu:style.nekomataDesc" },
3161
+ { id: "laowang-engineer", nameKey: "menu:style.laowang", descKey: "menu:style.laowangDesc" },
3162
+ { id: "ojousama-engineer", nameKey: "menu:style.ojousama", descKey: "menu:style.ojousamaDesc" },
3163
+ { id: "abyss-cultivator", nameKey: "menu:style.abyss", descKey: "menu:style.abyssDesc" }
2628
3164
  ];
2629
3165
  async function configOutputStyle() {
2630
3166
  console.log();
2631
- console.log(ansis.cyan.bold(" \u914D\u7F6E\u8F93\u51FA\u98CE\u683C"));
3167
+ console.log(ansis.cyan.bold(` ${i18n.t("menu:style.title")}`));
2632
3168
  console.log();
2633
3169
  const settingsPath = join(homedir(), ".claude", "settings.json");
2634
3170
  let settings = {};
@@ -2636,20 +3172,20 @@ async function configOutputStyle() {
2636
3172
  settings = await fs.readJson(settingsPath);
2637
3173
  }
2638
3174
  const currentStyle = settings.outputStyle || "default";
2639
- console.log(ansis.gray(` \u5F53\u524D\u98CE\u683C: ${currentStyle}`));
3175
+ console.log(ansis.gray(` ${i18n.t("menu:style.currentStyle")}: ${currentStyle}`));
2640
3176
  console.log();
2641
3177
  const { style } = await inquirer.prompt([{
2642
3178
  type: "list",
2643
3179
  name: "style",
2644
- message: "\u9009\u62E9\u8F93\u51FA\u98CE\u683C",
3180
+ message: i18n.t("menu:style.selectStyle"),
2645
3181
  choices: OUTPUT_STYLES.map((s) => ({
2646
- name: `${s.name} ${ansis.gray(`- ${s.desc}`)}`,
3182
+ name: `${i18n.t(s.nameKey)} ${ansis.gray(`- ${i18n.t(s.descKey)}`)}`,
2647
3183
  value: s.id
2648
3184
  })),
2649
3185
  default: currentStyle
2650
3186
  }]);
2651
3187
  if (style === currentStyle) {
2652
- console.log(ansis.gray("\u98CE\u683C\u672A\u53D8\u66F4"));
3188
+ console.log(ansis.gray(i18n.t("menu:style.notChanged")));
2653
3189
  return;
2654
3190
  }
2655
3191
  if (style !== "default") {
@@ -2665,7 +3201,7 @@ async function configOutputStyle() {
2665
3201
  const destPath = join(outputStylesDir, `${style}.md`);
2666
3202
  if (await fs.pathExists(templatePath)) {
2667
3203
  await fs.copy(templatePath, destPath);
2668
- console.log(ansis.green(`\u2713 \u5DF2\u5B89\u88C5\u98CE\u683C\u6587\u4EF6: ${style}.md`));
3204
+ console.log(ansis.green(`\u2713 ${i18n.t("menu:style.installed", { style })}`));
2669
3205
  }
2670
3206
  }
2671
3207
  if (style === "default") {
@@ -2675,12 +3211,12 @@ async function configOutputStyle() {
2675
3211
  }
2676
3212
  await fs.writeJson(settingsPath, settings, { spaces: 2 });
2677
3213
  console.log();
2678
- console.log(ansis.green(`\u2713 \u8F93\u51FA\u98CE\u683C\u5DF2\u8BBE\u7F6E\u4E3A: ${style}`));
2679
- console.log(ansis.gray(" \u91CD\u542F Claude Code CLI \u4F7F\u914D\u7F6E\u751F\u6548"));
3214
+ console.log(ansis.green(`\u2713 ${i18n.t("menu:style.set", { style })}`));
3215
+ console.log(ansis.gray(` ${i18n.t("common:restartToApply")}`));
2680
3216
  }
2681
3217
  async function handleInstallClaude() {
2682
3218
  console.log();
2683
- console.log(ansis.cyan.bold(" \u5B89\u88C5/\u91CD\u88C5 Claude Code"));
3219
+ console.log(ansis.cyan.bold(` ${i18n.t("menu:claude.title")}`));
2684
3220
  console.log();
2685
3221
  let isInstalled = false;
2686
3222
  try {
@@ -2690,25 +3226,25 @@ async function handleInstallClaude() {
2690
3226
  isInstalled = false;
2691
3227
  }
2692
3228
  if (isInstalled) {
2693
- console.log(ansis.yellow("\u26A0 \u68C0\u6D4B\u5230\u5DF2\u5B89\u88C5 Claude Code"));
3229
+ console.log(ansis.yellow(`\u26A0 ${i18n.t("menu:claude.alreadyInstalled")}`));
2694
3230
  const { confirm } = await inquirer.prompt([{
2695
3231
  type: "confirm",
2696
3232
  name: "confirm",
2697
- message: "\u662F\u5426\u5378\u8F7D\u540E\u91CD\u65B0\u5B89\u88C5\uFF1F",
3233
+ message: i18n.t("menu:claude.reinstallPrompt"),
2698
3234
  default: false
2699
3235
  }]);
2700
3236
  if (!confirm) {
2701
- console.log(ansis.gray("\u5DF2\u53D6\u6D88"));
3237
+ console.log(ansis.gray(i18n.t("common:cancelled")));
2702
3238
  return;
2703
3239
  }
2704
3240
  console.log();
2705
- console.log(ansis.yellow("\u23F3 \u6B63\u5728\u5378\u8F7D Claude Code..."));
3241
+ console.log(ansis.yellow(`\u23F3 ${i18n.t("menu:claude.uninstalling")}`));
2706
3242
  try {
2707
3243
  const uninstallCmd = isWindows() ? "npm uninstall -g @anthropic-ai/claude-code" : "sudo npm uninstall -g @anthropic-ai/claude-code";
2708
3244
  await execAsync(uninstallCmd, { timeout: 6e4 });
2709
- console.log(ansis.green("\u2713 \u5378\u8F7D\u6210\u529F"));
3245
+ console.log(ansis.green(`\u2713 ${i18n.t("menu:claude.uninstallSuccess")}`));
2710
3246
  } catch (e) {
2711
- console.log(ansis.red(`\u2717 \u5378\u8F7D\u5931\u8D25: ${e}`));
3247
+ console.log(ansis.red(`\u2717 ${i18n.t("menu:claude.uninstallFailed", { error: String(e) })}`));
2712
3248
  return;
2713
3249
  }
2714
3250
  }
@@ -2717,23 +3253,23 @@ async function handleInstallClaude() {
2717
3253
  const { method } = await inquirer.prompt([{
2718
3254
  type: "list",
2719
3255
  name: "method",
2720
- message: "\u9009\u62E9\u5B89\u88C5\u65B9\u5F0F",
3256
+ message: i18n.t("menu:claude.selectMethod"),
2721
3257
  choices: [
2722
- { name: `npm ${ansis.green("(\u63A8\u8350)")} ${ansis.gray("- \u5168\u5C40\u5B89\u88C5")}`, value: "npm" },
3258
+ { name: `npm ${ansis.green(`(${i18n.t("menu:claude.npmRecommended")})`)} ${ansis.gray("- npm install -g")}`, value: "npm" },
2723
3259
  ...isMac || isLinux ? [{ name: `homebrew ${ansis.gray("- brew install")}`, value: "homebrew" }] : [],
2724
- ...isMac || isLinux ? [{ name: `curl ${ansis.gray("- \u5B98\u65B9\u811A\u672C")}`, value: "curl" }] : [],
3260
+ ...isMac || isLinux ? [{ name: `curl ${ansis.gray("- official script")}`, value: "curl" }] : [],
2725
3261
  ...isWindows() ? [
2726
- { name: `powershell ${ansis.gray("- Windows \u5B98\u65B9")}`, value: "powershell" },
2727
- { name: `cmd ${ansis.gray("- \u547D\u4EE4\u63D0\u793A\u7B26")}`, value: "cmd" }
3262
+ { name: `powershell ${ansis.gray("- Windows official")}`, value: "powershell" },
3263
+ { name: `cmd ${ansis.gray("- Command Prompt")}`, value: "cmd" }
2728
3264
  ] : [],
2729
3265
  new inquirer.Separator(),
2730
- { name: `${ansis.gray("\u53D6\u6D88")}`, value: "cancel" }
3266
+ { name: `${ansis.gray(i18n.t("common:cancel"))}`, value: "cancel" }
2731
3267
  ]
2732
3268
  }]);
2733
3269
  if (method === "cancel")
2734
3270
  return;
2735
3271
  console.log();
2736
- console.log(ansis.yellow("\u23F3 \u6B63\u5728\u5B89\u88C5 Claude Code..."));
3272
+ console.log(ansis.yellow(`\u23F3 ${i18n.t("menu:claude.installing")}`));
2737
3273
  try {
2738
3274
  if (method === "npm") {
2739
3275
  const installCmd = isWindows() ? "npm install -g @anthropic-ai/claude-code" : "sudo npm install -g @anthropic-ai/claude-code";
@@ -2747,11 +3283,11 @@ async function handleInstallClaude() {
2747
3283
  } else if (method === "cmd") {
2748
3284
  await execAsync('cmd /c "curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd"', { timeout: 3e5 });
2749
3285
  }
2750
- console.log(ansis.green("\u2713 Claude Code \u5B89\u88C5\u6210\u529F"));
3286
+ console.log(ansis.green(`\u2713 ${i18n.t("menu:claude.installSuccess")}`));
2751
3287
  console.log();
2752
- console.log(ansis.cyan("\u{1F4A1} \u63D0\u793A\uFF1A\u8FD0\u884C claude \u547D\u4EE4\u542F\u52A8"));
3288
+ console.log(ansis.cyan(`\u{1F4A1} ${i18n.t("menu:claude.runHint")}`));
2753
3289
  } catch (e) {
2754
- console.log(ansis.red(`\u2717 \u5B89\u88C5\u5931\u8D25: ${e}`));
3290
+ console.log(ansis.red(`\u2717 ${i18n.t("menu:claude.installFailed", { error: String(e) })}`));
2755
3291
  }
2756
3292
  }
2757
3293
  async function checkIfGlobalInstall() {
@@ -2766,17 +3302,17 @@ async function uninstall() {
2766
3302
  console.log();
2767
3303
  const isGlobalInstall = await checkIfGlobalInstall();
2768
3304
  if (isGlobalInstall) {
2769
- console.log(ansis.yellow("\u26A0\uFE0F \u68C0\u6D4B\u5230\u4F60\u662F\u901A\u8FC7 npm \u5168\u5C40\u5B89\u88C5\u7684"));
3305
+ console.log(ansis.yellow(`\u26A0\uFE0F ${i18n.t("menu:uninstall.globalDetected")}`));
2770
3306
  console.log();
2771
- console.log("\u5B8C\u6574\u5378\u8F7D\u9700\u8981\u4E24\u6B65\uFF1A");
2772
- console.log(` ${ansis.cyan("1. \u79FB\u9664\u5DE5\u4F5C\u6D41\u6587\u4EF6")} (\u5373\u5C06\u6267\u884C)`);
2773
- console.log(` ${ansis.cyan("2. \u5378\u8F7D npm \u5168\u5C40\u5305")} (\u9700\u8981\u624B\u52A8\u6267\u884C)`);
3307
+ console.log(i18n.t("menu:uninstall.twoSteps"));
3308
+ console.log(` ${ansis.cyan(`1. ${i18n.t("menu:uninstall.step1")}`)} (${i18n.t("menu:uninstall.step1Hint")})`);
3309
+ console.log(` ${ansis.cyan(`2. ${i18n.t("menu:uninstall.step2")}`)} (${i18n.t("menu:uninstall.step2Hint")})`);
2774
3310
  console.log();
2775
3311
  }
2776
3312
  const { confirm } = await inquirer.prompt([{
2777
3313
  type: "confirm",
2778
3314
  name: "confirm",
2779
- message: isGlobalInstall ? "\u7EE7\u7EED\u5378\u8F7D\u5DE5\u4F5C\u6D41\u6587\u4EF6\uFF1F" : i18n.t("menu:uninstall.confirm"),
3315
+ message: isGlobalInstall ? i18n.t("menu:uninstall.continuePrompt") : i18n.t("menu:uninstall.confirm"),
2780
3316
  default: false
2781
3317
  }]);
2782
3318
  if (!confirm) {
@@ -2788,7 +3324,7 @@ async function uninstall() {
2788
3324
  const installDir = join(homedir(), ".claude");
2789
3325
  const result = await uninstallWorkflows(installDir);
2790
3326
  if (result.success) {
2791
- console.log(ansis.green("\u2705 \u5DE5\u4F5C\u6D41\u6587\u4EF6\u5DF2\u79FB\u9664"));
3327
+ console.log(ansis.green(`\u2705 ${i18n.t("menu:uninstall.success")}`));
2792
3328
  if (result.removedCommands.length > 0) {
2793
3329
  console.log();
2794
3330
  console.log(ansis.cyan(i18n.t("menu:uninstall.removedCommands")));
@@ -2798,30 +3334,30 @@ async function uninstall() {
2798
3334
  }
2799
3335
  if (result.removedAgents.length > 0) {
2800
3336
  console.log();
2801
- console.log(ansis.cyan("\u5DF2\u79FB\u9664\u5B50\u667A\u80FD\u4F53:"));
3337
+ console.log(ansis.cyan(i18n.t("menu:uninstall.removedAgents")));
2802
3338
  for (const agent of result.removedAgents) {
2803
3339
  console.log(` ${ansis.gray("\u2022")} ${agent}`);
2804
3340
  }
2805
3341
  }
2806
3342
  if (result.removedSkills.length > 0) {
2807
3343
  console.log();
2808
- console.log(ansis.cyan("\u5DF2\u79FB\u9664 Skills:"));
3344
+ console.log(ansis.cyan(i18n.t("menu:uninstall.removedSkills")));
2809
3345
  console.log(` ${ansis.gray("\u2022")} multi-model-collaboration`);
2810
3346
  }
2811
3347
  if (result.removedBin) {
2812
3348
  console.log();
2813
- console.log(ansis.cyan("\u5DF2\u79FB\u9664\u4E8C\u8FDB\u5236\u6587\u4EF6:"));
3349
+ console.log(ansis.cyan(i18n.t("menu:uninstall.removedBin")));
2814
3350
  console.log(` ${ansis.gray("\u2022")} codeagent-wrapper`);
2815
3351
  }
2816
3352
  if (isGlobalInstall) {
2817
3353
  console.log();
2818
- console.log(ansis.yellow.bold("\u{1F538} \u6700\u540E\u4E00\u6B65\uFF1A\u5378\u8F7D npm \u5168\u5C40\u5305"));
3354
+ console.log(ansis.yellow.bold(`\u{1F538} ${i18n.t("menu:uninstall.lastStep")}`));
2819
3355
  console.log();
2820
- console.log("\u8BF7\u5728\u65B0\u7684\u7EC8\u7AEF\u7A97\u53E3\u4E2D\u8FD0\u884C\uFF1A");
3356
+ console.log(i18n.t("menu:uninstall.runInNewTerminal"));
2821
3357
  console.log();
2822
3358
  console.log(ansis.cyan.bold(" npm uninstall -g ccg-workflow"));
2823
3359
  console.log();
2824
- console.log(ansis.gray("(\u5B8C\u6210\u540E ccg \u547D\u4EE4\u5C06\u5F7B\u5E95\u79FB\u9664)"));
3360
+ console.log(ansis.gray(`(${i18n.t("menu:uninstall.afterDone")})`));
2825
3361
  }
2826
3362
  } else {
2827
3363
  console.log(ansis.red(i18n.t("menu:uninstall.failed")));
@@ -2836,12 +3372,12 @@ async function handleTools() {
2836
3372
  const { tool } = await inquirer.prompt([{
2837
3373
  type: "list",
2838
3374
  name: "tool",
2839
- message: "\u9009\u62E9\u5DE5\u5177",
3375
+ message: i18n.t("menu:tools.title"),
2840
3376
  choices: [
2841
- { name: `${ansis.green("\u{1F4CA}")} ccusage ${ansis.gray("- Claude Code \u7528\u91CF\u5206\u6790")}`, value: "ccusage" },
2842
- { name: `${ansis.blue("\u{1F4DF}")} CCometixLine ${ansis.gray("- \u72B6\u6001\u680F\u5DE5\u5177\uFF08Git + \u7528\u91CF\uFF09")}`, value: "ccline" },
3377
+ { name: `${ansis.green("\u{1F4CA}")} ccusage ${ansis.gray(`- ${i18n.t("menu:tools.ccusage")}`)}`, value: "ccusage" },
3378
+ { name: `${ansis.blue("\u{1F4DF}")} CCometixLine ${ansis.gray(`- ${i18n.t("menu:tools.ccline")}`)}`, value: "ccline" },
2843
3379
  new inquirer.Separator(),
2844
- { name: `${ansis.gray("\u8FD4\u56DE")}`, value: "cancel" }
3380
+ { name: `${ansis.gray(i18n.t("common:back"))}`, value: "cancel" }
2845
3381
  ]
2846
3382
  }]);
2847
3383
  if (tool === "cancel")
@@ -2854,7 +3390,7 @@ async function handleTools() {
2854
3390
  }
2855
3391
  async function runCcusage() {
2856
3392
  console.log();
2857
- console.log(ansis.cyan("\u{1F4CA} \u8FD0\u884C ccusage..."));
3393
+ console.log(ansis.cyan(`\u{1F4CA} ${i18n.t("menu:tools.runningCcusage")}`));
2858
3394
  console.log(ansis.gray("$ npx ccusage@latest"));
2859
3395
  console.log();
2860
3396
  return new Promise((resolve) => {
@@ -2871,12 +3407,12 @@ async function handleCCometixLine() {
2871
3407
  const { action } = await inquirer.prompt([{
2872
3408
  type: "list",
2873
3409
  name: "action",
2874
- message: "CCometixLine \u64CD\u4F5C",
3410
+ message: i18n.t("menu:tools.cclineAction"),
2875
3411
  choices: [
2876
- { name: `${ansis.green("\u279C")} \u5B89\u88C5/\u66F4\u65B0`, value: "install" },
2877
- { name: `${ansis.red("\u2715")} \u5378\u8F7D`, value: "uninstall" },
3412
+ { name: `${ansis.green("\u279C")} ${i18n.t("menu:tools.cclineInstall")}`, value: "install" },
3413
+ { name: `${ansis.red("\u2715")} ${i18n.t("menu:tools.cclineUninstall")}`, value: "uninstall" },
2878
3414
  new inquirer.Separator(),
2879
- { name: `${ansis.gray("\u8FD4\u56DE")}`, value: "cancel" }
3415
+ { name: `${ansis.gray(i18n.t("common:back"))}`, value: "cancel" }
2880
3416
  ]
2881
3417
  }]);
2882
3418
  if (action === "cancel")
@@ -2889,11 +3425,11 @@ async function handleCCometixLine() {
2889
3425
  }
2890
3426
  async function installCCometixLine() {
2891
3427
  console.log();
2892
- console.log(ansis.yellow("\u23F3 \u6B63\u5728\u5B89\u88C5 CCometixLine..."));
3428
+ console.log(ansis.yellow(`\u23F3 ${i18n.t("menu:tools.cclineInstalling")}`));
2893
3429
  try {
2894
3430
  const installCmd = isWindows() ? "npm install -g @cometix/ccline" : "sudo npm install -g @cometix/ccline";
2895
3431
  await execAsync(installCmd, { timeout: 12e4 });
2896
- console.log(ansis.green("\u2713 @cometix/ccline \u5B89\u88C5\u6210\u529F"));
3432
+ console.log(ansis.green(`\u2713 ${i18n.t("menu:tools.cclineInstallSuccess")}`));
2897
3433
  const settingsPath = join(homedir(), ".claude", "settings.json");
2898
3434
  let settings = {};
2899
3435
  if (await fs.pathExists(settingsPath)) {
@@ -2906,29 +3442,29 @@ async function installCCometixLine() {
2906
3442
  };
2907
3443
  await fs.ensureDir(join(homedir(), ".claude"));
2908
3444
  await fs.writeJson(settingsPath, settings, { spaces: 2 });
2909
- console.log(ansis.green("\u2713 Claude Code statusLine \u5DF2\u914D\u7F6E"));
3445
+ console.log(ansis.green(`\u2713 ${i18n.t("menu:tools.cclineConfigured")}`));
2910
3446
  console.log();
2911
- console.log(ansis.cyan("\u{1F4A1} \u63D0\u793A\uFF1A\u91CD\u542F Claude Code CLI \u4F7F\u914D\u7F6E\u751F\u6548"));
3447
+ console.log(ansis.cyan(`\u{1F4A1} ${i18n.t("common:restartToApply")}`));
2912
3448
  } catch (error) {
2913
- console.log(ansis.red(`\u2717 \u5B89\u88C5\u5931\u8D25: ${error}`));
3449
+ console.log(ansis.red(`\u2717 ${i18n.t("menu:tools.cclineInstallFailed", { error: String(error) })}`));
2914
3450
  }
2915
3451
  }
2916
3452
  async function uninstallCCometixLine() {
2917
3453
  console.log();
2918
- console.log(ansis.yellow("\u23F3 \u6B63\u5728\u5378\u8F7D CCometixLine..."));
3454
+ console.log(ansis.yellow(`\u23F3 ${i18n.t("menu:tools.cclineUninstalling")}`));
2919
3455
  try {
2920
3456
  const settingsPath = join(homedir(), ".claude", "settings.json");
2921
3457
  if (await fs.pathExists(settingsPath)) {
2922
3458
  const settings = await fs.readJson(settingsPath);
2923
3459
  delete settings.statusLine;
2924
3460
  await fs.writeJson(settingsPath, settings, { spaces: 2 });
2925
- console.log(ansis.green("\u2713 statusLine \u914D\u7F6E\u5DF2\u79FB\u9664"));
3461
+ console.log(ansis.green(`\u2713 ${i18n.t("menu:tools.cclineConfigRemoved")}`));
2926
3462
  }
2927
3463
  const uninstallCmd = isWindows() ? "npm uninstall -g @cometix/ccline" : "sudo npm uninstall -g @cometix/ccline";
2928
3464
  await execAsync(uninstallCmd, { timeout: 6e4 });
2929
- console.log(ansis.green("\u2713 @cometix/ccline \u5DF2\u5378\u8F7D"));
3465
+ console.log(ansis.green(`\u2713 ${i18n.t("menu:tools.cclineUninstalled")}`));
2930
3466
  } catch (error) {
2931
- console.log(ansis.red(`\u2717 \u5378\u8F7D\u5931\u8D25: ${error}`));
3467
+ console.log(ansis.red(`\u2717 ${i18n.t("menu:tools.cclineUninstallFailed", { error: String(error) })}`));
2932
3468
  }
2933
3469
  }
2934
3470