ccg-workflow 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,14 +2,16 @@ import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
3
  import { homedir } from 'node:os';
4
4
  import { join, dirname } from 'pathe';
5
- import i18next from 'i18next';
6
5
  import fs from 'fs-extra';
7
6
  import { fileURLToPath } from 'node:url';
7
+ import i18next from 'i18next';
8
8
  import ora from 'ora';
9
9
  import { parse, stringify } from 'smol-toml';
10
10
  import { exec } from 'node:child_process';
11
11
  import { promisify } from 'node:util';
12
12
 
13
+ const version = "1.6.0";
14
+
13
15
  function isWindows() {
14
16
  return process.platform === "win32";
15
17
  }
@@ -131,460 +133,41 @@ async function diagnoseMcpConfig() {
131
133
  return issues;
132
134
  }
133
135
 
134
- const i18n = i18next;
135
- const zhCN = {
136
- common: {
137
- yes: "\u662F",
138
- no: "\u5426",
139
- confirm: "\u786E\u8BA4",
140
- cancel: "\u53D6\u6D88",
141
- back: "\u8FD4\u56DE",
142
- exit: "\u9000\u51FA",
143
- success: "\u6210\u529F",
144
- error: "\u9519\u8BEF",
145
- warning: "\u8B66\u544A",
146
- info: "\u4FE1\u606F",
147
- loading: "\u52A0\u8F7D\u4E2D...",
148
- processing: "\u5904\u7406\u4E2D...",
149
- completed: "\u5DF2\u5B8C\u6210",
150
- failed: "\u5931\u8D25"
151
- },
152
- cli: {
153
- help: {
154
- commands: "\u547D\u4EE4",
155
- commandDescriptions: {
156
- showMenu: "\u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355\uFF08\u9ED8\u8BA4\uFF09",
157
- initConfig: "\u521D\u59CB\u5316 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF"
158
- },
159
- shortcuts: "\u5FEB\u6377\u65B9\u5F0F:",
160
- shortcutDescriptions: {
161
- quickInit: "\u5FEB\u901F\u521D\u59CB\u5316"
162
- },
163
- options: "\u9009\u9879",
164
- optionDescriptions: {
165
- displayLanguage: "\u663E\u793A\u8BED\u8A00",
166
- forceOverwrite: "\u5F3A\u5236\u8986\u76D6\u73B0\u6709\u914D\u7F6E",
167
- displayHelp: "\u663E\u793A\u5E2E\u52A9\u4FE1\u606F",
168
- displayVersion: "\u663E\u793A\u7248\u672C\u53F7",
169
- skipAllPrompts: "\u8DF3\u8FC7\u6240\u6709\u4EA4\u4E92\u5F0F\u63D0\u793A\uFF08\u975E\u4EA4\u4E92\u6A21\u5F0F\uFF09",
170
- frontendModels: "\u524D\u7AEF\u6A21\u578B\uFF08\u9017\u53F7\u5206\u9694\uFF09",
171
- backendModels: "\u540E\u7AEF\u6A21\u578B\uFF08\u9017\u53F7\u5206\u9694\uFF09",
172
- collaborationMode: "\u534F\u4F5C\u6A21\u5F0F (parallel/smart/sequential)",
173
- workflows: "\u8981\u5B89\u88C5\u7684\u5DE5\u4F5C\u6D41",
174
- installDir: "\u5B89\u88C5\u76EE\u5F55"
175
- },
176
- nonInteractiveMode: "\u975E\u4EA4\u4E92\u6A21\u5F0F:",
177
- examples: "\u793A\u4F8B",
178
- exampleDescriptions: {
179
- showInteractiveMenu: "\u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355",
180
- runFullInitialization: "\u8FD0\u884C\u5B8C\u6574\u521D\u59CB\u5316",
181
- customModels: "\u81EA\u5B9A\u4E49\u6A21\u578B\u914D\u7F6E",
182
- parallelMode: "\u4F7F\u7528\u5E76\u884C\u534F\u4F5C\u6A21\u5F0F"
183
- }
184
- }
185
- },
186
- init: {
187
- welcome: "\u6B22\u8FCE\u4F7F\u7528 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF",
188
- selectLanguage: "\u8BF7\u9009\u62E9\u8BED\u8A00",
189
- selectFrontendModels: "\u9009\u62E9\u524D\u7AEF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u53EF\u591A\u9009\uFF09",
190
- selectBackendModels: "\u9009\u62E9\u540E\u7AEF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u53EF\u591A\u9009\uFF09",
191
- selectMode: "\u9009\u62E9\u534F\u4F5C\u6A21\u5F0F",
192
- selectWorkflows: "\u9009\u62E9\u8981\u5B89\u88C5\u7684\u5DE5\u4F5C\u6D41\uFF08\u53EF\u591A\u9009\uFF09",
193
- confirmInstall: "\u786E\u8BA4\u5B89\u88C5\u4EE5\u4E0A\u914D\u7F6E\uFF1F",
194
- installing: "\u6B63\u5728\u5B89\u88C5...",
195
- installSuccess: "\u5B89\u88C5\u6210\u529F\uFF01",
196
- installFailed: "\u5B89\u88C5\u5931\u8D25",
197
- installCancelled: "\u5B89\u88C5\u5DF2\u53D6\u6D88",
198
- installedCommands: "\u5DF2\u5B89\u88C5\u547D\u4EE4:",
199
- installedPrompts: "\u5DF2\u5B89\u88C5\u89D2\u8272\u63D0\u793A\u8BCD:",
200
- installedBinary: "\u5DF2\u5B89\u88C5\u4E8C\u8FDB\u5236\u6587\u4EF6:",
201
- installationErrors: "\u5B89\u88C5\u8FC7\u7A0B\u4E2D\u51FA\u73B0\u9519\u8BEF:",
202
- pathWarning: "\u9700\u8981\u5C06 codeagent-wrapper \u6DFB\u52A0\u5230 PATH \u624D\u80FD\u4F7F\u7528",
203
- autoConfigurePathPrompt: "\u662F\u5426\u81EA\u52A8\u914D\u7F6E PATH \u73AF\u5883\u53D8\u91CF\uFF1F",
204
- pathConfigured: "PATH \u5DF2\u6DFB\u52A0\u5230 {{file}}",
205
- pathAlreadyConfigured: "PATH \u5DF2\u914D\u7F6E\u5728 {{file}} \u4E2D",
206
- pathConfigFailed: "\u81EA\u52A8\u914D\u7F6E\u5931\u8D25",
207
- restartShellPrompt: "\u8BF7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u4F7F\u914D\u7F6E\u751F\u6548:",
208
- manualConfigInstructions: "\u8BF7\u624B\u52A8\u6DFB\u52A0\u4EE5\u4E0B\u547D\u4EE4\u5230 {{file}}:",
209
- windowsPathInstructions: "Windows \u7528\u6237 - \u624B\u52A8\u6DFB\u52A0\u5230\u7CFB\u7EDF\u73AF\u5883\u53D8\u91CF:",
210
- windowsStep1: '\u6309 Win+X\uFF0C\u9009\u62E9"\u7CFB\u7EDF"',
211
- windowsStep2: '\u70B9\u51FB"\u9AD8\u7EA7\u7CFB\u7EDF\u8BBE\u7F6E" \u2192 "\u73AF\u5883\u53D8\u91CF"',
212
- windowsStep3: '\u5728"\u7528\u6237\u53D8\u91CF"\u4E2D\u627E\u5230 Path\uFF0C\u70B9\u51FB"\u7F16\u8F91"\uFF0C\u6DFB\u52A0:',
213
- windowsStep4: '\u70B9\u51FB"\u786E\u5B9A"\u4FDD\u5B58\uFF0C\u91CD\u542F\u7EC8\u7AEF',
214
- orUsePowerShell: "\u6216\u5728 PowerShell (\u7BA1\u7406\u5458) \u4E2D\u8FD0\u884C:",
215
- addToShellConfig: "\u8BF7\u6DFB\u52A0\u4EE5\u4E0B\u547D\u4EE4\u5230 {{file}} \u5E76\u91CD\u542F\u7EC8\u7AEF",
216
- configSavedTo: "\u914D\u7F6E\u5DF2\u4FDD\u5B58\u81F3:",
217
- validation: {
218
- selectAtLeastOne: "\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u6A21\u578B"
219
- },
220
- summary: {
221
- title: "\u914D\u7F6E\u6458\u8981:",
222
- frontendModels: "\u524D\u7AEF\u6A21\u578B:",
223
- backendModels: "\u540E\u7AEF\u6A21\u578B:",
224
- collaboration: "\u534F\u4F5C\u6A21\u5F0F:",
225
- workflows: "\u5DE5\u4F5C\u6D41:",
226
- selected: "\u4E2A\u5DF2\u9009\u62E9"
227
- },
228
- modes: {
229
- parallel: "\u5E76\u884C\u6A21\u5F0F - \u540C\u65F6\u8C03\u7528\u591A\u4E2A\u6A21\u578B",
230
- smart: "\u667A\u80FD\u6A21\u5F0F - \u6839\u636E\u4EFB\u52A1\u7C7B\u578B\u81EA\u52A8\u9009\u62E9",
231
- sequential: "\u987A\u5E8F\u6A21\u5F0F - \u4F9D\u6B21\u8C03\u7528\u6A21\u578B"
232
- },
233
- models: {
234
- codex: "Codex - \u64C5\u957F\u540E\u7AEF\u903B\u8F91\u3001\u7B97\u6CD5\u3001\u8C03\u8BD5",
235
- gemini: "Gemini - \u64C5\u957F\u524D\u7AEFUI\u3001CSS\u3001\u7EC4\u4EF6\u8BBE\u8BA1",
236
- claude: "Claude - \u64C5\u957F\u7F16\u6392\u3001\u91CD\u6784\u3001\u6587\u6863\u751F\u6210"
237
- },
238
- workflows: {
239
- dev: "\u5B8C\u6574\u5F00\u53D1\u5DE5\u4F5C\u6D41 (/ccg:dev)",
240
- frontend: "\u524D\u7AEF\u4EFB\u52A1 (/ccg:frontend)",
241
- backend: "\u540E\u7AEF\u4EFB\u52A1 (/ccg:backend)",
242
- review: "\u4EE3\u7801\u5BA1\u67E5 (/ccg:review)",
243
- analyze: "\u6280\u672F\u5206\u6790 (/ccg:analyze)",
244
- commit: "Git \u667A\u80FD\u63D0\u4EA4 (/ccg:commit)",
245
- rollback: "Git \u56DE\u6EDA (/ccg:rollback)",
246
- cleanBranches: "\u6E05\u7406\u5206\u652F (/ccg:clean-branches)",
247
- worktree: "Worktree \u7BA1\u7406 (/ccg:worktree)",
248
- init: "\u9879\u76EE\u521D\u59CB\u5316 (/ccg:init)"
249
- },
250
- aceTool: {
251
- title: "ace-tool MCP \u914D\u7F6E",
252
- description: "\u8F7B\u91CF\u7EA7\u4EE3\u7801\u68C0\u7D22\u548C Prompt \u589E\u5F3A\u5DE5\u5177",
253
- getToken: "\u83B7\u53D6 Token",
254
- configure: "\u662F\u5426\u914D\u7F6E ace-tool MCP\uFF1F",
255
- baseUrl: "API Base URL:",
256
- token: "API Token:",
257
- installing: "\u6B63\u5728\u914D\u7F6E ace-tool MCP...",
258
- failed: "ace-tool \u914D\u7F6E\u5931\u8D25\uFF08\u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\uFF09"
259
- }
260
- },
261
- menu: {
262
- title: "CCG \u4E3B\u83DC\u5355",
263
- options: {
264
- init: "\u521D\u59CB\u5316 CCG \u914D\u7F6E",
265
- update: "\u66F4\u65B0\u5DE5\u4F5C\u6D41",
266
- uninstall: "\u5378\u8F7D CCG",
267
- help: "\u5E2E\u52A9",
268
- exit: "\u9000\u51FA"
269
- },
270
- help: {
271
- title: "CCG \u547D\u4EE4:",
272
- hint: "\u66F4\u591A\u4FE1\u606F\u8BF7\u8FD0\u884C: npx ccg --help",
273
- descriptions: {
274
- dev: "\u5B8C\u6574\u516D\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41",
275
- frontend: "\u524D\u7AEF\u4EFB\u52A1 \u2192 Gemini",
276
- backend: "\u540E\u7AEF\u4EFB\u52A1 \u2192 Codex",
277
- review: "\u53CC\u6A21\u578B\u4EE3\u7801\u5BA1\u67E5",
278
- analyze: "\u53CC\u6A21\u578B\u6280\u672F\u5206\u6790",
279
- commit: "Git \u667A\u80FD\u63D0\u4EA4",
280
- rollback: "Git \u4EA4\u4E92\u5F0F\u56DE\u6EDA"
281
- }
282
- },
283
- uninstall: {
284
- confirm: "\u786E\u5B9A\u8981\u5378\u8F7D CCG \u5417\uFF1F\u8FD9\u5C06\u79FB\u9664\u6240\u6709\u5DF2\u5B89\u88C5\u7684\u547D\u4EE4\u548C\u914D\u7F6E\u3002",
285
- alsoRemoveAceTool: "\u540C\u65F6\u79FB\u9664 ace-tool MCP \u914D\u7F6E\uFF1F",
286
- uninstalling: "\u6B63\u5728\u5378\u8F7D...",
287
- success: "\u5378\u8F7D\u6210\u529F\uFF01",
288
- removedCommands: "\u5DF2\u79FB\u9664\u547D\u4EE4:",
289
- removedAceTool: "ace-tool MCP \u914D\u7F6E\u5DF2\u79FB\u9664",
290
- cancelled: "\u5378\u8F7D\u5DF2\u53D6\u6D88",
291
- failed: "\u5378\u8F7D\u5931\u8D25"
136
+ const __filename$2 = fileURLToPath(import.meta.url);
137
+ const __dirname$2 = dirname(__filename$2);
138
+ function findPackageRoot$1(startDir) {
139
+ let dir = startDir;
140
+ for (let i = 0; i < 5; i++) {
141
+ if (fs.existsSync(join(dir, "package.json"))) {
142
+ return dir;
292
143
  }
144
+ dir = dirname(dir);
293
145
  }
294
- };
295
- const en = {
296
- common: {
297
- yes: "Yes",
298
- no: "No",
299
- confirm: "Confirm",
300
- cancel: "Cancel",
301
- back: "Back",
302
- exit: "Exit",
303
- success: "Success",
304
- error: "Error",
305
- warning: "Warning",
306
- info: "Info",
307
- loading: "Loading...",
308
- processing: "Processing...",
309
- completed: "Completed",
310
- failed: "Failed"
146
+ return startDir;
147
+ }
148
+ const PACKAGE_ROOT$1 = findPackageRoot$1(__dirname$2);
149
+ const WORKFLOW_CONFIGS = [
150
+ {
151
+ id: "dev",
152
+ name: "\u5B8C\u6574\u5F00\u53D1\u5DE5\u4F5C\u6D41",
153
+ nameEn: "Full Development Workflow",
154
+ category: "development",
155
+ commands: ["dev"],
156
+ defaultSelected: true,
157
+ order: 1,
158
+ description: "\u5B8C\u65746\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41\uFF08Prompt\u589E\u5F3A\u2192\u4E0A\u4E0B\u6587\u68C0\u7D22\u2192\u591A\u6A21\u578B\u5206\u6790\u2192\u539F\u578B\u751F\u6210\u2192\u4EE3\u7801\u5B9E\u65BD\u2192\u5BA1\u8BA1\u4EA4\u4ED8\uFF09",
159
+ descriptionEn: "Full 6-phase development workflow (Prompt enhancement \u2192 Context retrieval \u2192 Multi-model analysis \u2192 Prototype \u2192 Implementation \u2192 Audit)"
311
160
  },
312
- cli: {
313
- help: {
314
- commands: "Commands",
315
- commandDescriptions: {
316
- showMenu: "Show interactive menu (default)",
317
- initConfig: "Initialize CCG multi-model collaboration system"
318
- },
319
- shortcuts: "Shortcuts:",
320
- shortcutDescriptions: {
321
- quickInit: "Quick init"
322
- },
323
- options: "Options",
324
- optionDescriptions: {
325
- displayLanguage: "Display language",
326
- forceOverwrite: "Force overwrite existing configuration",
327
- displayHelp: "Display help",
328
- displayVersion: "Display version",
329
- skipAllPrompts: "Skip all interactive prompts (non-interactive mode)",
330
- frontendModels: "Frontend models (comma-separated)",
331
- backendModels: "Backend models (comma-separated)",
332
- collaborationMode: "Collaboration mode (parallel/smart/sequential)",
333
- workflows: "Workflows to install",
334
- installDir: "Installation directory"
335
- },
336
- nonInteractiveMode: "Non-interactive mode:",
337
- examples: "Examples",
338
- exampleDescriptions: {
339
- showInteractiveMenu: "Show interactive menu",
340
- runFullInitialization: "Run full initialization",
341
- customModels: "Custom model configuration",
342
- parallelMode: "Use parallel collaboration mode"
343
- }
344
- }
345
- },
346
- init: {
347
- welcome: "Welcome to CCG Multi-Model Collaboration System",
348
- selectLanguage: "Select language",
349
- selectFrontendModels: "Select models for frontend tasks (multi-select)",
350
- selectBackendModels: "Select models for backend tasks (multi-select)",
351
- selectMode: "Select collaboration mode",
352
- selectWorkflows: "Select workflows to install (multi-select)",
353
- confirmInstall: "Confirm installation with above configuration?",
354
- installing: "Installing...",
355
- installSuccess: "Installation successful!",
356
- installFailed: "Installation failed",
357
- installCancelled: "Installation cancelled",
358
- installedCommands: "Installed Commands:",
359
- installedPrompts: "Installed Role Prompts:",
360
- installedBinary: "Installed Binary:",
361
- installationErrors: "Installation Errors:",
362
- pathWarning: "codeagent-wrapper needs to be added to PATH",
363
- autoConfigurePathPrompt: "Automatically configure PATH environment variable?",
364
- pathConfigured: "PATH has been added to {{file}}",
365
- pathAlreadyConfigured: "PATH is already configured in {{file}}",
366
- pathConfigFailed: "Auto-configuration failed",
367
- restartShellPrompt: "Run the following command to apply changes:",
368
- manualConfigInstructions: "Please manually add the following to {{file}}:",
369
- windowsPathInstructions: "Windows Users - Manually add to System Environment Variables:",
370
- windowsStep1: 'Press Win+X, select "System"',
371
- windowsStep2: 'Click "Advanced system settings" \u2192 "Environment Variables"',
372
- windowsStep3: 'Find "Path" in User variables, click "Edit", add:',
373
- windowsStep4: 'Click "OK" to save, restart terminal',
374
- orUsePowerShell: "Or run in PowerShell (Admin):",
375
- addToShellConfig: "Add the following command to {{file}} and restart your terminal",
376
- configSavedTo: "Config saved to:",
377
- validation: {
378
- selectAtLeastOne: "Please select at least one model"
379
- },
380
- summary: {
381
- title: "Configuration Summary:",
382
- frontendModels: "Frontend Models:",
383
- backendModels: "Backend Models:",
384
- collaboration: "Collaboration:",
385
- workflows: "Workflows:",
386
- selected: "selected"
387
- },
388
- modes: {
389
- parallel: "Parallel - Call multiple models simultaneously",
390
- smart: "Smart - Auto-select based on task type",
391
- sequential: "Sequential - Call models one by one"
392
- },
393
- models: {
394
- codex: "Codex - Backend logic, algorithms, debugging",
395
- gemini: "Gemini - Frontend UI, CSS, component design",
396
- claude: "Claude - Orchestration, refactoring, documentation"
397
- },
398
- workflows: {
399
- dev: "Full development workflow (/ccg:dev)",
400
- frontend: "Frontend tasks (/ccg:frontend)",
401
- backend: "Backend tasks (/ccg:backend)",
402
- review: "Code review (/ccg:review)",
403
- analyze: "Technical analysis (/ccg:analyze)",
404
- commit: "Git smart commit (/ccg:commit)",
405
- rollback: "Git rollback (/ccg:rollback)",
406
- cleanBranches: "Clean branches (/ccg:clean-branches)",
407
- worktree: "Worktree management (/ccg:worktree)",
408
- init: "Project initialization (/ccg:init)"
409
- },
410
- aceTool: {
411
- title: "ace-tool MCP Configuration",
412
- description: "Lightweight codebase retrieval and prompt enhancement tool",
413
- getToken: "Get Token",
414
- configure: "Configure ace-tool MCP?",
415
- baseUrl: "API Base URL:",
416
- token: "API Token:",
417
- installing: "Configuring ace-tool MCP...",
418
- failed: "ace-tool configuration failed (can be configured manually later)"
419
- }
420
- },
421
- menu: {
422
- title: "CCG Main Menu",
423
- options: {
424
- init: "Initialize CCG configuration",
425
- update: "Update workflows",
426
- uninstall: "Uninstall CCG",
427
- help: "Help",
428
- exit: "Exit"
429
- },
430
- help: {
431
- title: "CCG Commands:",
432
- hint: "For more information, run: npx ccg --help",
433
- descriptions: {
434
- dev: "Complete 6-phase development workflow",
435
- frontend: "Frontend tasks \u2192 Gemini",
436
- backend: "Backend tasks \u2192 Codex",
437
- review: "Dual-model code review",
438
- analyze: "Dual-model technical analysis",
439
- commit: "Git smart commit",
440
- rollback: "Git interactive rollback"
441
- }
442
- },
443
- uninstall: {
444
- confirm: "Are you sure you want to uninstall CCG? This will remove all installed commands and configurations.",
445
- alsoRemoveAceTool: "Also remove ace-tool MCP configuration?",
446
- uninstalling: "Uninstalling...",
447
- success: "Uninstallation successful!",
448
- removedCommands: "Removed commands:",
449
- removedAceTool: "ace-tool MCP configuration removed",
450
- cancelled: "Uninstallation cancelled",
451
- failed: "Uninstallation failed"
452
- }
453
- }
454
- };
455
- async function initI18n(lang = "zh-CN") {
456
- if (!i18n.isInitialized) {
457
- await i18n.init({
458
- lng: lang,
459
- fallbackLng: "en",
460
- resources: {
461
- "zh-CN": { translation: zhCN, ...zhCN },
462
- en: { translation: en, ...en }
463
- },
464
- interpolation: {
465
- escapeValue: false
466
- }
467
- });
468
- } else if (i18n.language !== lang) {
469
- await i18n.changeLanguage(lang);
470
- }
471
- }
472
- async function changeLanguage(lang) {
473
- await i18n.changeLanguage(lang);
474
- }
475
-
476
- const CCG_DIR = join(homedir(), ".claude", ".ccg");
477
- const CONFIG_FILE = join(CCG_DIR, "config.toml");
478
- function getCcgDir() {
479
- return CCG_DIR;
480
- }
481
- function getConfigPath() {
482
- return CONFIG_FILE;
483
- }
484
- async function ensureCcgDir() {
485
- await fs.ensureDir(CCG_DIR);
486
- }
487
- async function readCcgConfig() {
488
- try {
489
- if (await fs.pathExists(CONFIG_FILE)) {
490
- const content = await fs.readFile(CONFIG_FILE, "utf-8");
491
- return parse(content);
492
- }
493
- } catch {
494
- }
495
- return null;
496
- }
497
- async function writeCcgConfig(config) {
498
- await ensureCcgDir();
499
- const content = stringify(config);
500
- await fs.writeFile(CONFIG_FILE, content, "utf-8");
501
- }
502
- function createDefaultConfig(options) {
503
- return {
504
- general: {
505
- version: "1.4.0",
506
- language: options.language,
507
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
508
- },
509
- routing: options.routing,
510
- workflows: {
511
- installed: options.installedWorkflows
512
- },
513
- paths: {
514
- commands: join(homedir(), ".claude", "commands", "ccg"),
515
- prompts: join(CCG_DIR, "prompts"),
516
- // v1.4.0: 移到配置目录
517
- backup: join(CCG_DIR, "backup")
518
- },
519
- mcp: {
520
- provider: options.mcpProvider || "ace-tool",
521
- setup_url: "https://linux.do/t/topic/284963",
522
- tools: {
523
- code_search_ace: "mcp__ace-tool__search_context",
524
- code_search_auggie: "mcp__auggie-mcp__codebase-retrieval",
525
- prompt_enhance_ace: "mcp__ace-tool__enhance_prompt",
526
- prompt_enhance_auggie: "mcp__auggie-mcp__enhance_prompt",
527
- query_param_ace: "query",
528
- query_param_auggie: "information_request"
529
- }
530
- }
531
- };
532
- }
533
- function createDefaultRouting() {
534
- return {
535
- frontend: {
536
- models: ["gemini"],
537
- primary: "gemini",
538
- strategy: "parallel"
539
- },
540
- backend: {
541
- models: ["codex"],
542
- primary: "codex",
543
- strategy: "parallel"
544
- },
545
- review: {
546
- models: ["codex", "gemini"],
547
- strategy: "parallel"
548
- },
549
- mode: "smart"
550
- };
551
- }
552
-
553
- const __filename$2 = fileURLToPath(import.meta.url);
554
- const __dirname$2 = dirname(__filename$2);
555
- function findPackageRoot$1(startDir) {
556
- let dir = startDir;
557
- for (let i = 0; i < 5; i++) {
558
- if (fs.existsSync(join(dir, "package.json"))) {
559
- return dir;
560
- }
561
- dir = dirname(dir);
562
- }
563
- return startDir;
564
- }
565
- const PACKAGE_ROOT$1 = findPackageRoot$1(__dirname$2);
566
- const WORKFLOW_CONFIGS = [
567
- {
568
- id: "dev",
569
- name: "\u5B8C\u6574\u5F00\u53D1\u5DE5\u4F5C\u6D41",
570
- nameEn: "Full Development Workflow",
571
- category: "development",
572
- commands: ["dev"],
573
- defaultSelected: true,
574
- order: 1,
575
- description: "\u5B8C\u65746\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41\uFF08Prompt\u589E\u5F3A\u2192\u4E0A\u4E0B\u6587\u68C0\u7D22\u2192\u591A\u6A21\u578B\u5206\u6790\u2192\u539F\u578B\u751F\u6210\u2192\u4EE3\u7801\u5B9E\u65BD\u2192\u5BA1\u8BA1\u4EA4\u4ED8\uFF09",
576
- descriptionEn: "Full 6-phase development workflow (Prompt enhancement \u2192 Context retrieval \u2192 Multi-model analysis \u2192 Prototype \u2192 Implementation \u2192 Audit)"
577
- },
578
- {
579
- id: "code",
580
- name: "\u667A\u80FD\u4EE3\u7801\u751F\u6210",
581
- nameEn: "Smart Code Generation",
582
- category: "development",
583
- commands: ["code"],
584
- defaultSelected: true,
585
- order: 2,
586
- description: "\u591A\u6A21\u578B\u4EE3\u7801\u751F\u6210\uFF08\u667A\u80FD\u8DEF\u7531\uFF1A\u524D\u7AEF\u2192Gemini\uFF0C\u540E\u7AEF\u2192Codex\uFF09",
587
- descriptionEn: "Multi-model code generation (smart routing: frontend\u2192Gemini, backend\u2192Codex)"
161
+ {
162
+ id: "code",
163
+ name: "\u667A\u80FD\u4EE3\u7801\u751F\u6210",
164
+ nameEn: "Smart Code Generation",
165
+ category: "development",
166
+ commands: ["code"],
167
+ defaultSelected: true,
168
+ order: 2,
169
+ description: "\u591A\u6A21\u578B\u4EE3\u7801\u751F\u6210\uFF08\u667A\u80FD\u8DEF\u7531\uFF1A\u524D\u7AEF\u2192Gemini\uFF0C\u540E\u7AEF\u2192Codex\uFF09",
170
+ descriptionEn: "Multi-model code generation (smart routing: frontend\u2192Gemini, backend\u2192Codex)"
588
171
  },
589
172
  {
590
173
  id: "frontend",
@@ -769,19 +352,34 @@ function getWorkflowConfigs() {
769
352
  function getWorkflowById(id) {
770
353
  return WORKFLOW_CONFIGS.find((w) => w.id === id);
771
354
  }
355
+ const WORKFLOW_PRESETS = {
356
+ minimal: {
357
+ name: "\u6700\u5C0F\u5316",
358
+ nameEn: "Minimal",
359
+ description: "\u6838\u5FC3\u5F00\u53D1\u547D\u4EE4\uFF083\u4E2A\uFF09",
360
+ descriptionEn: "Core development commands (3)",
361
+ workflows: ["dev", "code", "commit"]
362
+ },
363
+ standard: {
364
+ name: "\u6807\u51C6",
365
+ nameEn: "Standard",
366
+ description: "\u5E38\u7528\u5F00\u53D1 + Git \u547D\u4EE4\uFF0812\u4E2A\uFF09",
367
+ descriptionEn: "Common dev + Git commands (12)",
368
+ workflows: ["dev", "code", "frontend", "backend", "review", "analyze", "debug", "test", "commit", "rollback", "clean-branches", "feat"]
369
+ },
370
+ full: {
371
+ name: "\u5B8C\u6574",
372
+ nameEn: "Full",
373
+ description: "\u5168\u90E8\u547D\u4EE4\uFF0817\u4E2A\uFF09",
374
+ descriptionEn: "All commands (17)",
375
+ workflows: WORKFLOW_CONFIGS.map((w) => w.id)
376
+ }
377
+ };
378
+ function getWorkflowPreset(preset) {
379
+ return [...WORKFLOW_PRESETS[preset].workflows];
380
+ }
772
381
  function injectConfigVariables(content, config) {
773
382
  let processed = content;
774
- if (config.mcpProvider === "ace-tool") {
775
- processed = processed.replace(/\{\{MCP_SEARCH_TOOL\}\}/g, "mcp__ace-tool__search_context");
776
- processed = processed.replace(/\{\{MCP_ENHANCE_TOOL\}\}/g, "mcp__ace-tool__enhance_prompt");
777
- processed = processed.replace(/\{\{MCP_SEARCH_PARAM\}\}/g, "query");
778
- processed = processed.replace(/\{\{MCP_ENHANCE_PARAM\}\}/g, "prompt");
779
- } else {
780
- processed = processed.replace(/\{\{MCP_SEARCH_TOOL\}\}/g, "mcp__auggie-mcp__codebase-retrieval");
781
- processed = processed.replace(/\{\{MCP_ENHANCE_TOOL\}\}/g, "mcp__auggie-mcp__enhance_prompt");
782
- processed = processed.replace(/\{\{MCP_SEARCH_PARAM\}\}/g, "information_request");
783
- processed = processed.replace(/\{\{MCP_ENHANCE_PARAM\}\}/g, "prompt");
784
- }
785
383
  const routing = config.routing || {};
786
384
  const frontendModels = routing.frontend?.models || ["gemini"];
787
385
  const frontendPrimary = routing.frontend?.primary || "gemini";
@@ -806,7 +404,6 @@ function replaceHomePathsInTemplate(content, installDir) {
806
404
  }
807
405
  async function installWorkflows(workflowIds, installDir, force = false, config) {
808
406
  const installConfig = {
809
- mcpProvider: config?.mcpProvider || "auggie",
810
407
  routing: config?.routing || {
811
408
  mode: "smart",
812
409
  frontend: { models: ["gemini"], primary: "gemini" },
@@ -866,16 +463,6 @@ ${workflow.description}
866
463
  }
867
464
  }
868
465
  }
869
- const sharedConfigSrcFile = join(templateDir, "config", "shared-config.md");
870
- const sharedConfigDestFile = join(ccgConfigDir, "shared-config.md");
871
- if (await fs.pathExists(sharedConfigSrcFile)) {
872
- if (force || !await fs.pathExists(sharedConfigDestFile)) {
873
- let templateContent = await fs.readFile(sharedConfigSrcFile, "utf-8");
874
- templateContent = injectConfigVariables(templateContent, installConfig);
875
- const processedContent = replaceHomePathsInTemplate(templateContent, installDir);
876
- await fs.writeFile(sharedConfigDestFile, processedContent, "utf-8");
877
- }
878
- }
879
466
  const agentsSrcDir = join(templateDir, "commands", "agents");
880
467
  const agentsDestDir = join(installDir, "agents", "ccg");
881
468
  if (await fs.pathExists(agentsSrcDir)) {
@@ -1000,97 +587,595 @@ async function uninstallWorkflows(installDir) {
1000
587
  result.success = false;
1001
588
  }
1002
589
  }
1003
- if (await fs.pathExists(promptsDir)) {
1004
- try {
1005
- const files = await fs.readdir(promptsDir);
1006
- for (const file of files) {
1007
- await fs.remove(join(promptsDir, file));
1008
- result.removedPrompts.push(file);
1009
- }
1010
- const remaining = await fs.readdir(promptsDir);
1011
- if (remaining.length === 0) {
1012
- await fs.remove(promptsDir);
590
+ if (await fs.pathExists(promptsDir)) {
591
+ try {
592
+ const files = await fs.readdir(promptsDir);
593
+ for (const file of files) {
594
+ await fs.remove(join(promptsDir, file));
595
+ result.removedPrompts.push(file);
596
+ }
597
+ const remaining = await fs.readdir(promptsDir);
598
+ if (remaining.length === 0) {
599
+ await fs.remove(promptsDir);
600
+ }
601
+ } catch (error) {
602
+ result.errors.push(`Failed to remove prompts: ${error}`);
603
+ result.success = false;
604
+ }
605
+ }
606
+ return result;
607
+ }
608
+ async function uninstallAceTool() {
609
+ try {
610
+ const existingConfig = await readClaudeCodeConfig();
611
+ if (!existingConfig) {
612
+ return {
613
+ success: true,
614
+ message: "No ~/.claude.json found, nothing to remove"
615
+ };
616
+ }
617
+ if (!existingConfig.mcpServers || !existingConfig.mcpServers["ace-tool"]) {
618
+ return {
619
+ success: true,
620
+ message: "ace-tool MCP not found in config"
621
+ };
622
+ }
623
+ await backupClaudeCodeConfig();
624
+ delete existingConfig.mcpServers["ace-tool"];
625
+ await writeClaudeCodeConfig(existingConfig);
626
+ return {
627
+ success: true,
628
+ message: "ace-tool MCP removed from ~/.claude.json"
629
+ };
630
+ } catch (error) {
631
+ return {
632
+ success: false,
633
+ message: `Failed to uninstall ace-tool: ${error}`
634
+ };
635
+ }
636
+ }
637
+ async function installAceTool(config) {
638
+ const { baseUrl, token } = config;
639
+ try {
640
+ let existingConfig = await readClaudeCodeConfig();
641
+ if (!existingConfig) {
642
+ existingConfig = { mcpServers: {} };
643
+ }
644
+ if (existingConfig.mcpServers && Object.keys(existingConfig.mcpServers).length > 0) {
645
+ const backupPath = await backupClaudeCodeConfig();
646
+ if (backupPath) {
647
+ console.log(` \u2713 Backup created: ${backupPath}`);
648
+ }
649
+ }
650
+ const args = ["-y", "ace-tool@latest"];
651
+ if (baseUrl) {
652
+ args.push("--base-url", baseUrl);
653
+ }
654
+ if (token) {
655
+ args.push("--token", token);
656
+ }
657
+ const aceToolConfig = buildMcpServerConfig({
658
+ type: "stdio",
659
+ command: "npx",
660
+ args
661
+ });
662
+ let mergedConfig = mergeMcpServers(existingConfig, {
663
+ "ace-tool": aceToolConfig
664
+ });
665
+ if (isWindows()) {
666
+ mergedConfig = fixWindowsMcpConfig(mergedConfig);
667
+ console.log(" \u2713 Applied Windows MCP configuration fixes");
668
+ }
669
+ await writeClaudeCodeConfig(mergedConfig);
670
+ return {
671
+ success: true,
672
+ message: isWindows() ? "ace-tool MCP configured successfully with Windows compatibility" : "ace-tool MCP configured successfully",
673
+ configPath: join(homedir(), ".claude.json")
674
+ };
675
+ } catch (error) {
676
+ return {
677
+ success: false,
678
+ message: `Failed to configure ace-tool: ${error}`
679
+ };
680
+ }
681
+ }
682
+
683
+ async function configMcp() {
684
+ console.log();
685
+ console.log(ansis.cyan.bold(` \u914D\u7F6E ace-tool MCP`));
686
+ console.log();
687
+ const { action } = await inquirer.prompt([{
688
+ type: "list",
689
+ name: "action",
690
+ message: "\u9009\u62E9\u64CD\u4F5C",
691
+ choices: [
692
+ { name: `${ansis.green("\u279C")} \u5B89\u88C5/\u66F4\u65B0 ace-tool MCP`, value: "install" },
693
+ { name: `${ansis.red("\u2715")} \u5378\u8F7D ace-tool MCP`, value: "uninstall" },
694
+ new inquirer.Separator(),
695
+ { name: `${ansis.gray("\u8FD4\u56DE")}`, value: "cancel" }
696
+ ]
697
+ }]);
698
+ if (action === "cancel") {
699
+ return;
700
+ }
701
+ if (action === "uninstall") {
702
+ await handleUninstall();
703
+ return;
704
+ }
705
+ console.log();
706
+ console.log(ansis.cyan(`\u{1F4D6} \u83B7\u53D6 ace-tool \u8BBF\u95EE\u65B9\u5F0F\uFF1A`));
707
+ console.log(` ${ansis.gray("\u2022")} ${ansis.cyan("\u5B98\u65B9\u670D\u52A1")}: ${ansis.underline("https://augmentcode.com/")}`);
708
+ 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")}`);
709
+ console.log();
710
+ const aceAnswers = await inquirer.prompt([
711
+ {
712
+ type: "input",
713
+ name: "baseUrl",
714
+ message: `Base URL ${ansis.gray("(\u4F7F\u7528\u4E2D\u8F6C\u670D\u52A1\u65F6\u5FC5\u586B\uFF0C\u5B98\u65B9\u670D\u52A1\u7559\u7A7A)")}`
715
+ },
716
+ {
717
+ type: "password",
718
+ name: "token",
719
+ message: `Token ${ansis.gray("(\u5FC5\u586B)")}`,
720
+ validate: (input) => input.trim() !== "" || "\u8BF7\u8F93\u5165 Token"
721
+ }
722
+ ]);
723
+ console.log();
724
+ console.log(ansis.yellow("\u23F3 \u6B63\u5728\u914D\u7F6E ace-tool MCP..."));
725
+ console.log();
726
+ const result = await installAceTool({
727
+ baseUrl: aceAnswers.baseUrl?.trim() || void 0,
728
+ token: aceAnswers.token.trim()
729
+ });
730
+ if (result.success) {
731
+ console.log(ansis.green("\u2713 ace-tool MCP \u914D\u7F6E\u6210\u529F\uFF01"));
732
+ if (result.configPath) {
733
+ console.log(ansis.gray(` \u914D\u7F6E\u6587\u4EF6: ${result.configPath}`));
734
+ }
735
+ console.log();
736
+ console.log(ansis.cyan("\u{1F4A1} \u63D0\u793A\uFF1A"));
737
+ console.log(ansis.gray(" 1. \u91CD\u542F Claude Code CLI \u4F7F\u914D\u7F6E\u751F\u6548"));
738
+ console.log(ansis.gray(" 2. \u8FD0\u884C /ccg:dev \u547D\u4EE4\u6D4B\u8BD5 MCP \u529F\u80FD"));
739
+ } else {
740
+ console.log(ansis.red("\u2717 ace-tool MCP \u914D\u7F6E\u5931\u8D25"));
741
+ console.log(ansis.gray(` \u9519\u8BEF\u4FE1\u606F: ${result.message}`));
742
+ }
743
+ console.log();
744
+ }
745
+ async function handleUninstall() {
746
+ console.log();
747
+ const { confirm } = await inquirer.prompt([{
748
+ type: "confirm",
749
+ name: "confirm",
750
+ message: "\u786E\u5B9A\u8981\u5378\u8F7D ace-tool MCP \u5417\uFF1F",
751
+ default: false
752
+ }]);
753
+ if (!confirm) {
754
+ console.log(ansis.gray("\u5DF2\u53D6\u6D88"));
755
+ return;
756
+ }
757
+ console.log();
758
+ console.log(ansis.yellow("\u23F3 \u6B63\u5728\u5378\u8F7D ace-tool MCP..."));
759
+ const result = await uninstallAceTool();
760
+ if (result.success) {
761
+ console.log(ansis.green("\u2713 ace-tool MCP \u5DF2\u5378\u8F7D"));
762
+ console.log();
763
+ } else {
764
+ console.log(ansis.red("\u2717 \u5378\u8F7D\u5931\u8D25"));
765
+ console.log(ansis.gray(` \u9519\u8BEF\u4FE1\u606F: ${result.message}`));
766
+ console.log();
767
+ }
768
+ }
769
+
770
+ const i18n = i18next;
771
+ const zhCN = {
772
+ common: {
773
+ yes: "\u662F",
774
+ no: "\u5426",
775
+ confirm: "\u786E\u8BA4",
776
+ cancel: "\u53D6\u6D88",
777
+ back: "\u8FD4\u56DE",
778
+ exit: "\u9000\u51FA",
779
+ success: "\u6210\u529F",
780
+ error: "\u9519\u8BEF",
781
+ warning: "\u8B66\u544A",
782
+ info: "\u4FE1\u606F",
783
+ loading: "\u52A0\u8F7D\u4E2D...",
784
+ processing: "\u5904\u7406\u4E2D...",
785
+ completed: "\u5DF2\u5B8C\u6210",
786
+ failed: "\u5931\u8D25"
787
+ },
788
+ cli: {
789
+ help: {
790
+ commands: "\u547D\u4EE4",
791
+ commandDescriptions: {
792
+ showMenu: "\u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355\uFF08\u9ED8\u8BA4\uFF09",
793
+ initConfig: "\u521D\u59CB\u5316 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF"
794
+ },
795
+ shortcuts: "\u5FEB\u6377\u65B9\u5F0F:",
796
+ shortcutDescriptions: {
797
+ quickInit: "\u5FEB\u901F\u521D\u59CB\u5316"
798
+ },
799
+ options: "\u9009\u9879",
800
+ optionDescriptions: {
801
+ displayLanguage: "\u663E\u793A\u8BED\u8A00",
802
+ forceOverwrite: "\u5F3A\u5236\u8986\u76D6\u73B0\u6709\u914D\u7F6E",
803
+ displayHelp: "\u663E\u793A\u5E2E\u52A9\u4FE1\u606F",
804
+ displayVersion: "\u663E\u793A\u7248\u672C\u53F7",
805
+ skipAllPrompts: "\u8DF3\u8FC7\u6240\u6709\u4EA4\u4E92\u5F0F\u63D0\u793A\uFF08\u975E\u4EA4\u4E92\u6A21\u5F0F\uFF09",
806
+ frontendModels: "\u524D\u7AEF\u6A21\u578B\uFF08\u9017\u53F7\u5206\u9694\uFF09",
807
+ backendModels: "\u540E\u7AEF\u6A21\u578B\uFF08\u9017\u53F7\u5206\u9694\uFF09",
808
+ collaborationMode: "\u534F\u4F5C\u6A21\u5F0F (parallel/smart/sequential)",
809
+ workflows: "\u8981\u5B89\u88C5\u7684\u5DE5\u4F5C\u6D41",
810
+ installDir: "\u5B89\u88C5\u76EE\u5F55"
811
+ },
812
+ nonInteractiveMode: "\u975E\u4EA4\u4E92\u6A21\u5F0F:",
813
+ examples: "\u793A\u4F8B",
814
+ exampleDescriptions: {
815
+ showInteractiveMenu: "\u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355",
816
+ runFullInitialization: "\u8FD0\u884C\u5B8C\u6574\u521D\u59CB\u5316",
817
+ customModels: "\u81EA\u5B9A\u4E49\u6A21\u578B\u914D\u7F6E",
818
+ parallelMode: "\u4F7F\u7528\u5E76\u884C\u534F\u4F5C\u6A21\u5F0F"
819
+ }
820
+ }
821
+ },
822
+ init: {
823
+ welcome: "\u6B22\u8FCE\u4F7F\u7528 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF",
824
+ selectLanguage: "\u8BF7\u9009\u62E9\u8BED\u8A00",
825
+ selectFrontendModels: "\u9009\u62E9\u524D\u7AEF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u53EF\u591A\u9009\uFF09",
826
+ selectBackendModels: "\u9009\u62E9\u540E\u7AEF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u53EF\u591A\u9009\uFF09",
827
+ selectMode: "\u9009\u62E9\u534F\u4F5C\u6A21\u5F0F",
828
+ selectWorkflows: "\u9009\u62E9\u8981\u5B89\u88C5\u7684\u5DE5\u4F5C\u6D41\uFF08\u53EF\u591A\u9009\uFF09",
829
+ confirmInstall: "\u786E\u8BA4\u5B89\u88C5\u4EE5\u4E0A\u914D\u7F6E\uFF1F",
830
+ installing: "\u6B63\u5728\u5B89\u88C5...",
831
+ installSuccess: "\u5B89\u88C5\u6210\u529F\uFF01",
832
+ installFailed: "\u5B89\u88C5\u5931\u8D25",
833
+ installCancelled: "\u5B89\u88C5\u5DF2\u53D6\u6D88",
834
+ installedCommands: "\u5DF2\u5B89\u88C5\u547D\u4EE4:",
835
+ installedPrompts: "\u5DF2\u5B89\u88C5\u89D2\u8272\u63D0\u793A\u8BCD:",
836
+ installedBinary: "\u5DF2\u5B89\u88C5\u4E8C\u8FDB\u5236\u6587\u4EF6:",
837
+ installationErrors: "\u5B89\u88C5\u8FC7\u7A0B\u4E2D\u51FA\u73B0\u9519\u8BEF:",
838
+ pathWarning: "\u9700\u8981\u5C06 codeagent-wrapper \u6DFB\u52A0\u5230 PATH \u624D\u80FD\u4F7F\u7528",
839
+ autoConfigurePathPrompt: "\u662F\u5426\u81EA\u52A8\u914D\u7F6E PATH \u73AF\u5883\u53D8\u91CF\uFF1F",
840
+ pathConfigured: "PATH \u5DF2\u6DFB\u52A0\u5230 {{file}}",
841
+ pathAlreadyConfigured: "PATH \u5DF2\u914D\u7F6E\u5728 {{file}} \u4E2D",
842
+ pathConfigFailed: "\u81EA\u52A8\u914D\u7F6E\u5931\u8D25",
843
+ restartShellPrompt: "\u8BF7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u4F7F\u914D\u7F6E\u751F\u6548:",
844
+ manualConfigInstructions: "\u8BF7\u624B\u52A8\u6DFB\u52A0\u4EE5\u4E0B\u547D\u4EE4\u5230 {{file}}:",
845
+ windowsPathInstructions: "Windows \u7528\u6237 - \u624B\u52A8\u6DFB\u52A0\u5230\u7CFB\u7EDF\u73AF\u5883\u53D8\u91CF:",
846
+ windowsStep1: '\u6309 Win+X\uFF0C\u9009\u62E9"\u7CFB\u7EDF"',
847
+ windowsStep2: '\u70B9\u51FB"\u9AD8\u7EA7\u7CFB\u7EDF\u8BBE\u7F6E" \u2192 "\u73AF\u5883\u53D8\u91CF"',
848
+ windowsStep3: '\u5728"\u7528\u6237\u53D8\u91CF"\u4E2D\u627E\u5230 Path\uFF0C\u70B9\u51FB"\u7F16\u8F91"\uFF0C\u6DFB\u52A0:',
849
+ windowsStep4: '\u70B9\u51FB"\u786E\u5B9A"\u4FDD\u5B58\uFF0C\u91CD\u542F\u7EC8\u7AEF',
850
+ orUsePowerShell: "\u6216\u5728 PowerShell (\u7BA1\u7406\u5458) \u4E2D\u8FD0\u884C:",
851
+ addToShellConfig: "\u8BF7\u6DFB\u52A0\u4EE5\u4E0B\u547D\u4EE4\u5230 {{file}} \u5E76\u91CD\u542F\u7EC8\u7AEF",
852
+ configSavedTo: "\u914D\u7F6E\u5DF2\u4FDD\u5B58\u81F3:",
853
+ validation: {
854
+ selectAtLeastOne: "\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u6A21\u578B"
855
+ },
856
+ summary: {
857
+ title: "\u914D\u7F6E\u6458\u8981:",
858
+ frontendModels: "\u524D\u7AEF\u6A21\u578B:",
859
+ backendModels: "\u540E\u7AEF\u6A21\u578B:",
860
+ collaboration: "\u534F\u4F5C\u6A21\u5F0F:",
861
+ workflows: "\u5DE5\u4F5C\u6D41:",
862
+ selected: "\u4E2A\u5DF2\u9009\u62E9"
863
+ },
864
+ modes: {
865
+ parallel: "\u5E76\u884C\u6A21\u5F0F - \u540C\u65F6\u8C03\u7528\u591A\u4E2A\u6A21\u578B",
866
+ smart: "\u667A\u80FD\u6A21\u5F0F - \u6839\u636E\u4EFB\u52A1\u7C7B\u578B\u81EA\u52A8\u9009\u62E9",
867
+ sequential: "\u987A\u5E8F\u6A21\u5F0F - \u4F9D\u6B21\u8C03\u7528\u6A21\u578B"
868
+ },
869
+ models: {
870
+ codex: "Codex - \u64C5\u957F\u540E\u7AEF\u903B\u8F91\u3001\u7B97\u6CD5\u3001\u8C03\u8BD5",
871
+ gemini: "Gemini - \u64C5\u957F\u524D\u7AEFUI\u3001CSS\u3001\u7EC4\u4EF6\u8BBE\u8BA1",
872
+ claude: "Claude - \u64C5\u957F\u7F16\u6392\u3001\u91CD\u6784\u3001\u6587\u6863\u751F\u6210"
873
+ },
874
+ workflows: {
875
+ dev: "\u5B8C\u6574\u5F00\u53D1\u5DE5\u4F5C\u6D41 (/ccg:dev)",
876
+ frontend: "\u524D\u7AEF\u4EFB\u52A1 (/ccg:frontend)",
877
+ backend: "\u540E\u7AEF\u4EFB\u52A1 (/ccg:backend)",
878
+ review: "\u4EE3\u7801\u5BA1\u67E5 (/ccg:review)",
879
+ analyze: "\u6280\u672F\u5206\u6790 (/ccg:analyze)",
880
+ commit: "Git \u667A\u80FD\u63D0\u4EA4 (/ccg:commit)",
881
+ rollback: "Git \u56DE\u6EDA (/ccg:rollback)",
882
+ cleanBranches: "\u6E05\u7406\u5206\u652F (/ccg:clean-branches)",
883
+ worktree: "Worktree \u7BA1\u7406 (/ccg:worktree)",
884
+ init: "\u9879\u76EE\u521D\u59CB\u5316 (/ccg:init)"
885
+ },
886
+ aceTool: {
887
+ title: "ace-tool MCP \u914D\u7F6E",
888
+ description: "\u8F7B\u91CF\u7EA7\u4EE3\u7801\u68C0\u7D22\u548C Prompt \u589E\u5F3A\u5DE5\u5177",
889
+ getToken: "\u83B7\u53D6 Token",
890
+ configure: "\u662F\u5426\u914D\u7F6E ace-tool MCP\uFF1F",
891
+ baseUrl: "API Base URL:",
892
+ token: "API Token:",
893
+ installing: "\u6B63\u5728\u914D\u7F6E ace-tool MCP...",
894
+ failed: "ace-tool \u914D\u7F6E\u5931\u8D25\uFF08\u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\uFF09"
895
+ }
896
+ },
897
+ menu: {
898
+ title: "CCG \u4E3B\u83DC\u5355",
899
+ options: {
900
+ init: "\u521D\u59CB\u5316 CCG \u914D\u7F6E",
901
+ update: "\u66F4\u65B0\u5DE5\u4F5C\u6D41",
902
+ uninstall: "\u5378\u8F7D CCG",
903
+ help: "\u5E2E\u52A9",
904
+ exit: "\u9000\u51FA"
905
+ },
906
+ help: {
907
+ title: "CCG \u547D\u4EE4:",
908
+ hint: "\u66F4\u591A\u4FE1\u606F\u8BF7\u8FD0\u884C: npx ccg --help",
909
+ descriptions: {
910
+ dev: "\u5B8C\u6574\u516D\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41",
911
+ frontend: "\u524D\u7AEF\u4EFB\u52A1 \u2192 Gemini",
912
+ backend: "\u540E\u7AEF\u4EFB\u52A1 \u2192 Codex",
913
+ review: "\u53CC\u6A21\u578B\u4EE3\u7801\u5BA1\u67E5",
914
+ analyze: "\u53CC\u6A21\u578B\u6280\u672F\u5206\u6790",
915
+ commit: "Git \u667A\u80FD\u63D0\u4EA4",
916
+ rollback: "Git \u4EA4\u4E92\u5F0F\u56DE\u6EDA"
917
+ }
918
+ },
919
+ uninstall: {
920
+ confirm: "\u786E\u5B9A\u8981\u5378\u8F7D CCG \u5417\uFF1F\u8FD9\u5C06\u79FB\u9664\u6240\u6709\u5DF2\u5B89\u88C5\u7684\u547D\u4EE4\u548C\u914D\u7F6E\u3002",
921
+ alsoRemoveAceTool: "\u540C\u65F6\u79FB\u9664 ace-tool MCP \u914D\u7F6E\uFF1F",
922
+ uninstalling: "\u6B63\u5728\u5378\u8F7D...",
923
+ success: "\u5378\u8F7D\u6210\u529F\uFF01",
924
+ removedCommands: "\u5DF2\u79FB\u9664\u547D\u4EE4:",
925
+ removedAceTool: "ace-tool MCP \u914D\u7F6E\u5DF2\u79FB\u9664",
926
+ cancelled: "\u5378\u8F7D\u5DF2\u53D6\u6D88",
927
+ failed: "\u5378\u8F7D\u5931\u8D25"
928
+ }
929
+ }
930
+ };
931
+ const en = {
932
+ common: {
933
+ yes: "Yes",
934
+ no: "No",
935
+ confirm: "Confirm",
936
+ cancel: "Cancel",
937
+ back: "Back",
938
+ exit: "Exit",
939
+ success: "Success",
940
+ error: "Error",
941
+ warning: "Warning",
942
+ info: "Info",
943
+ loading: "Loading...",
944
+ processing: "Processing...",
945
+ completed: "Completed",
946
+ failed: "Failed"
947
+ },
948
+ cli: {
949
+ help: {
950
+ commands: "Commands",
951
+ commandDescriptions: {
952
+ showMenu: "Show interactive menu (default)",
953
+ initConfig: "Initialize CCG multi-model collaboration system"
954
+ },
955
+ shortcuts: "Shortcuts:",
956
+ shortcutDescriptions: {
957
+ quickInit: "Quick init"
958
+ },
959
+ options: "Options",
960
+ optionDescriptions: {
961
+ displayLanguage: "Display language",
962
+ forceOverwrite: "Force overwrite existing configuration",
963
+ displayHelp: "Display help",
964
+ displayVersion: "Display version",
965
+ skipAllPrompts: "Skip all interactive prompts (non-interactive mode)",
966
+ frontendModels: "Frontend models (comma-separated)",
967
+ backendModels: "Backend models (comma-separated)",
968
+ collaborationMode: "Collaboration mode (parallel/smart/sequential)",
969
+ workflows: "Workflows to install",
970
+ installDir: "Installation directory"
971
+ },
972
+ nonInteractiveMode: "Non-interactive mode:",
973
+ examples: "Examples",
974
+ exampleDescriptions: {
975
+ showInteractiveMenu: "Show interactive menu",
976
+ runFullInitialization: "Run full initialization",
977
+ customModels: "Custom model configuration",
978
+ parallelMode: "Use parallel collaboration mode"
979
+ }
980
+ }
981
+ },
982
+ init: {
983
+ welcome: "Welcome to CCG Multi-Model Collaboration System",
984
+ selectLanguage: "Select language",
985
+ selectFrontendModels: "Select models for frontend tasks (multi-select)",
986
+ selectBackendModels: "Select models for backend tasks (multi-select)",
987
+ selectMode: "Select collaboration mode",
988
+ selectWorkflows: "Select workflows to install (multi-select)",
989
+ confirmInstall: "Confirm installation with above configuration?",
990
+ installing: "Installing...",
991
+ installSuccess: "Installation successful!",
992
+ installFailed: "Installation failed",
993
+ installCancelled: "Installation cancelled",
994
+ installedCommands: "Installed Commands:",
995
+ installedPrompts: "Installed Role Prompts:",
996
+ installedBinary: "Installed Binary:",
997
+ installationErrors: "Installation Errors:",
998
+ pathWarning: "codeagent-wrapper needs to be added to PATH",
999
+ autoConfigurePathPrompt: "Automatically configure PATH environment variable?",
1000
+ pathConfigured: "PATH has been added to {{file}}",
1001
+ pathAlreadyConfigured: "PATH is already configured in {{file}}",
1002
+ pathConfigFailed: "Auto-configuration failed",
1003
+ restartShellPrompt: "Run the following command to apply changes:",
1004
+ manualConfigInstructions: "Please manually add the following to {{file}}:",
1005
+ windowsPathInstructions: "Windows Users - Manually add to System Environment Variables:",
1006
+ windowsStep1: 'Press Win+X, select "System"',
1007
+ windowsStep2: 'Click "Advanced system settings" \u2192 "Environment Variables"',
1008
+ windowsStep3: 'Find "Path" in User variables, click "Edit", add:',
1009
+ windowsStep4: 'Click "OK" to save, restart terminal',
1010
+ orUsePowerShell: "Or run in PowerShell (Admin):",
1011
+ addToShellConfig: "Add the following command to {{file}} and restart your terminal",
1012
+ configSavedTo: "Config saved to:",
1013
+ validation: {
1014
+ selectAtLeastOne: "Please select at least one model"
1015
+ },
1016
+ summary: {
1017
+ title: "Configuration Summary:",
1018
+ frontendModels: "Frontend Models:",
1019
+ backendModels: "Backend Models:",
1020
+ collaboration: "Collaboration:",
1021
+ workflows: "Workflows:",
1022
+ selected: "selected"
1023
+ },
1024
+ modes: {
1025
+ parallel: "Parallel - Call multiple models simultaneously",
1026
+ smart: "Smart - Auto-select based on task type",
1027
+ sequential: "Sequential - Call models one by one"
1028
+ },
1029
+ models: {
1030
+ codex: "Codex - Backend logic, algorithms, debugging",
1031
+ gemini: "Gemini - Frontend UI, CSS, component design",
1032
+ claude: "Claude - Orchestration, refactoring, documentation"
1033
+ },
1034
+ workflows: {
1035
+ dev: "Full development workflow (/ccg:dev)",
1036
+ frontend: "Frontend tasks (/ccg:frontend)",
1037
+ backend: "Backend tasks (/ccg:backend)",
1038
+ review: "Code review (/ccg:review)",
1039
+ analyze: "Technical analysis (/ccg:analyze)",
1040
+ commit: "Git smart commit (/ccg:commit)",
1041
+ rollback: "Git rollback (/ccg:rollback)",
1042
+ cleanBranches: "Clean branches (/ccg:clean-branches)",
1043
+ worktree: "Worktree management (/ccg:worktree)",
1044
+ init: "Project initialization (/ccg:init)"
1045
+ },
1046
+ aceTool: {
1047
+ title: "ace-tool MCP Configuration",
1048
+ description: "Lightweight codebase retrieval and prompt enhancement tool",
1049
+ getToken: "Get Token",
1050
+ configure: "Configure ace-tool MCP?",
1051
+ baseUrl: "API Base URL:",
1052
+ token: "API Token:",
1053
+ installing: "Configuring ace-tool MCP...",
1054
+ failed: "ace-tool configuration failed (can be configured manually later)"
1055
+ }
1056
+ },
1057
+ menu: {
1058
+ title: "CCG Main Menu",
1059
+ options: {
1060
+ init: "Initialize CCG configuration",
1061
+ update: "Update workflows",
1062
+ uninstall: "Uninstall CCG",
1063
+ help: "Help",
1064
+ exit: "Exit"
1065
+ },
1066
+ help: {
1067
+ title: "CCG Commands:",
1068
+ hint: "For more information, run: npx ccg --help",
1069
+ descriptions: {
1070
+ dev: "Complete 6-phase development workflow",
1071
+ frontend: "Frontend tasks \u2192 Gemini",
1072
+ backend: "Backend tasks \u2192 Codex",
1073
+ review: "Dual-model code review",
1074
+ analyze: "Dual-model technical analysis",
1075
+ commit: "Git smart commit",
1076
+ rollback: "Git interactive rollback"
1077
+ }
1078
+ },
1079
+ uninstall: {
1080
+ confirm: "Are you sure you want to uninstall CCG? This will remove all installed commands and configurations.",
1081
+ alsoRemoveAceTool: "Also remove ace-tool MCP configuration?",
1082
+ uninstalling: "Uninstalling...",
1083
+ success: "Uninstallation successful!",
1084
+ removedCommands: "Removed commands:",
1085
+ removedAceTool: "ace-tool MCP configuration removed",
1086
+ cancelled: "Uninstallation cancelled",
1087
+ failed: "Uninstallation failed"
1088
+ }
1089
+ }
1090
+ };
1091
+ async function initI18n(lang = "zh-CN") {
1092
+ if (!i18n.isInitialized) {
1093
+ await i18n.init({
1094
+ lng: lang,
1095
+ fallbackLng: "en",
1096
+ resources: {
1097
+ "zh-CN": { translation: zhCN, ...zhCN },
1098
+ en: { translation: en, ...en }
1099
+ },
1100
+ interpolation: {
1101
+ escapeValue: false
1013
1102
  }
1014
- } catch (error) {
1015
- result.errors.push(`Failed to remove prompts: ${error}`);
1016
- result.success = false;
1017
- }
1103
+ });
1104
+ } else if (i18n.language !== lang) {
1105
+ await i18n.changeLanguage(lang);
1018
1106
  }
1019
- return result;
1020
1107
  }
1021
- async function uninstallAceTool() {
1108
+ async function changeLanguage(lang) {
1109
+ await i18n.changeLanguage(lang);
1110
+ }
1111
+
1112
+ const CCG_DIR = join(homedir(), ".claude", ".ccg");
1113
+ const CONFIG_FILE = join(CCG_DIR, "config.toml");
1114
+ function getCcgDir() {
1115
+ return CCG_DIR;
1116
+ }
1117
+ function getConfigPath() {
1118
+ return CONFIG_FILE;
1119
+ }
1120
+ async function ensureCcgDir() {
1121
+ await fs.ensureDir(CCG_DIR);
1122
+ }
1123
+ async function readCcgConfig() {
1022
1124
  try {
1023
- const existingConfig = await readClaudeCodeConfig();
1024
- if (!existingConfig) {
1025
- return {
1026
- success: true,
1027
- message: "No ~/.claude.json found, nothing to remove"
1028
- };
1029
- }
1030
- if (!existingConfig.mcpServers || !existingConfig.mcpServers["ace-tool"]) {
1031
- return {
1032
- success: true,
1033
- message: "ace-tool MCP not found in config"
1034
- };
1125
+ if (await fs.pathExists(CONFIG_FILE)) {
1126
+ const content = await fs.readFile(CONFIG_FILE, "utf-8");
1127
+ return parse(content);
1035
1128
  }
1036
- await backupClaudeCodeConfig();
1037
- delete existingConfig.mcpServers["ace-tool"];
1038
- await writeClaudeCodeConfig(existingConfig);
1039
- return {
1040
- success: true,
1041
- message: "ace-tool MCP removed from ~/.claude.json"
1042
- };
1043
- } catch (error) {
1044
- return {
1045
- success: false,
1046
- message: `Failed to uninstall ace-tool: ${error}`
1047
- };
1129
+ } catch {
1048
1130
  }
1131
+ return null;
1049
1132
  }
1050
- async function installAceTool(config) {
1051
- const { baseUrl, token } = config;
1052
- try {
1053
- let existingConfig = await readClaudeCodeConfig();
1054
- if (!existingConfig) {
1055
- existingConfig = { mcpServers: {} };
1056
- }
1057
- if (existingConfig.mcpServers && Object.keys(existingConfig.mcpServers).length > 0) {
1058
- const backupPath = await backupClaudeCodeConfig();
1059
- if (backupPath) {
1060
- console.log(` \u2713 Backup created: ${backupPath}`);
1061
- }
1062
- }
1063
- const args = ["-y", "ace-tool@latest"];
1064
- if (baseUrl) {
1065
- args.push("--base-url", baseUrl);
1066
- }
1067
- if (token) {
1068
- args.push("--token", token);
1069
- }
1070
- const aceToolConfig = buildMcpServerConfig({
1071
- type: "stdio",
1072
- command: "npx",
1073
- args
1074
- });
1075
- let mergedConfig = mergeMcpServers(existingConfig, {
1076
- "ace-tool": aceToolConfig
1077
- });
1078
- if (isWindows()) {
1079
- mergedConfig = fixWindowsMcpConfig(mergedConfig);
1080
- console.log(" \u2713 Applied Windows MCP configuration fixes");
1133
+ async function writeCcgConfig(config) {
1134
+ await ensureCcgDir();
1135
+ const content = stringify(config);
1136
+ await fs.writeFile(CONFIG_FILE, content, "utf-8");
1137
+ }
1138
+ function createDefaultConfig(options) {
1139
+ return {
1140
+ general: {
1141
+ version: version,
1142
+ language: options.language,
1143
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
1144
+ },
1145
+ routing: options.routing,
1146
+ workflows: {
1147
+ installed: options.installedWorkflows
1148
+ },
1149
+ paths: {
1150
+ commands: join(homedir(), ".claude", "commands", "ccg"),
1151
+ prompts: join(CCG_DIR, "prompts"),
1152
+ // v1.4.0: 移到配置目录
1153
+ backup: join(CCG_DIR, "backup")
1154
+ },
1155
+ mcp: {
1156
+ provider: options.mcpProvider || "ace-tool",
1157
+ setup_url: "https://augmentcode.com/"
1081
1158
  }
1082
- await writeClaudeCodeConfig(mergedConfig);
1083
- return {
1084
- success: true,
1085
- message: isWindows() ? "ace-tool MCP configured successfully with Windows compatibility" : "ace-tool MCP configured successfully",
1086
- configPath: join(homedir(), ".claude.json")
1087
- };
1088
- } catch (error) {
1089
- return {
1090
- success: false,
1091
- message: `Failed to configure ace-tool: ${error}`
1092
- };
1093
- }
1159
+ };
1160
+ }
1161
+ function createDefaultRouting() {
1162
+ return {
1163
+ frontend: {
1164
+ models: ["gemini"],
1165
+ primary: "gemini",
1166
+ strategy: "parallel"
1167
+ },
1168
+ backend: {
1169
+ models: ["codex"],
1170
+ primary: "codex",
1171
+ strategy: "parallel"
1172
+ },
1173
+ review: {
1174
+ models: ["codex", "gemini"],
1175
+ strategy: "parallel"
1176
+ },
1177
+ mode: "smart"
1178
+ };
1094
1179
  }
1095
1180
 
1096
1181
  async function migrateToV1_4_0() {
@@ -1104,8 +1189,6 @@ async function migrateToV1_4_0() {
1104
1189
  const newCcgDir = join(homedir(), ".claude", ".ccg");
1105
1190
  const oldPromptsDir = join(homedir(), ".claude", "prompts", "ccg");
1106
1191
  const newPromptsDir = join(newCcgDir, "prompts");
1107
- const oldConfigFile = join(homedir(), ".claude", "commands", "ccg", "_config.md");
1108
- const newConfigFile = join(newCcgDir, "shared-config.md");
1109
1192
  try {
1110
1193
  await fs.ensureDir(newCcgDir);
1111
1194
  if (await fs.pathExists(oldCcgDir)) {
@@ -1162,23 +1245,6 @@ async function migrateToV1_4_0() {
1162
1245
  } else {
1163
1246
  result.skipped.push("~/.claude/prompts/ccg/ (does not exist, nothing to migrate)");
1164
1247
  }
1165
- if (await fs.pathExists(oldConfigFile)) {
1166
- try {
1167
- if (await fs.pathExists(newConfigFile)) {
1168
- result.skipped.push("_config.md (already exists in new location)");
1169
- } else {
1170
- await fs.copy(oldConfigFile, newConfigFile);
1171
- result.migratedFiles.push("~/.claude/commands/ccg/_config.md \u2192 ~/.claude/.ccg/shared-config.md");
1172
- await fs.remove(oldConfigFile);
1173
- result.migratedFiles.push("Removed old _config.md from commands directory");
1174
- }
1175
- } catch (error) {
1176
- result.errors.push(`Failed to migrate _config.md: ${error}`);
1177
- result.success = false;
1178
- }
1179
- } else {
1180
- result.skipped.push("_config.md (does not exist, nothing to migrate)");
1181
- }
1182
1248
  } catch (error) {
1183
1249
  result.errors.push(`Migration failed: ${error}`);
1184
1250
  result.success = false;
@@ -1275,40 +1341,68 @@ async function init(options = {}) {
1275
1341
  selectedWorkflows = options.workflows.split(",").map((w) => w.trim());
1276
1342
  }
1277
1343
  } else if (!options.skipPrompt) {
1278
- const { selected } = await inquirer.prompt([{
1279
- type: "checkbox",
1280
- name: "selected",
1281
- message: i18n.t("init:selectWorkflows"),
1282
- choices: allWorkflows.map((w) => ({
1283
- name: `${language === "zh-CN" ? w.name : w.nameEn} ${ansis.gray(`\u2014 ${language === "zh-CN" ? w.description : w.descriptionEn}`)}`,
1284
- value: w.id,
1285
- checked: w.defaultSelected
1286
- }))
1344
+ const { workflowMode } = await inquirer.prompt([{
1345
+ type: "list",
1346
+ name: "workflowMode",
1347
+ message: "\u9009\u62E9\u547D\u4EE4\u5B89\u88C5\u6A21\u5F0F",
1348
+ choices: [
1349
+ {
1350
+ name: `${WORKFLOW_PRESETS.minimal.name} ${ansis.gray(`\u2014 ${WORKFLOW_PRESETS.minimal.description}`)} ${ansis.green("(\u63A8\u8350\u65B0\u624B)")}`,
1351
+ value: "minimal"
1352
+ },
1353
+ {
1354
+ name: `${WORKFLOW_PRESETS.standard.name} ${ansis.gray(`\u2014 ${WORKFLOW_PRESETS.standard.description}`)} ${ansis.green("(\u63A8\u8350)")}`,
1355
+ value: "standard"
1356
+ },
1357
+ {
1358
+ name: `${WORKFLOW_PRESETS.full.name} ${ansis.gray(`\u2014 ${WORKFLOW_PRESETS.full.description}`)}`,
1359
+ value: "full"
1360
+ },
1361
+ new inquirer.Separator(),
1362
+ {
1363
+ name: `\u81EA\u5B9A\u4E49 ${ansis.gray("\u2014 \u624B\u52A8\u9009\u62E9\u547D\u4EE4")}`,
1364
+ value: "custom"
1365
+ }
1366
+ ],
1367
+ default: "standard"
1287
1368
  }]);
1288
- selectedWorkflows = selected;
1369
+ if (workflowMode === "custom") {
1370
+ const { selected } = await inquirer.prompt([{
1371
+ type: "checkbox",
1372
+ name: "selected",
1373
+ message: i18n.t("init:selectWorkflows"),
1374
+ choices: allWorkflows.map((w) => ({
1375
+ name: `${language === "zh-CN" ? w.name : w.nameEn} ${ansis.gray(`\u2014 ${language === "zh-CN" ? w.description : w.descriptionEn}`)}`,
1376
+ value: w.id,
1377
+ checked: w.defaultSelected
1378
+ }))
1379
+ }]);
1380
+ selectedWorkflows = selected;
1381
+ } else {
1382
+ selectedWorkflows = getWorkflowPreset(workflowMode);
1383
+ const preset = WORKFLOW_PRESETS[workflowMode];
1384
+ console.log();
1385
+ console.log(ansis.gray(` \u5DF2\u9009\u62E9 ${ansis.cyan(preset.name)} \u6A21\u5F0F (${selectedWorkflows.length} \u4E2A\u547D\u4EE4)`));
1386
+ }
1289
1387
  }
1290
1388
  let mcpProvider = "ace-tool";
1291
1389
  let aceToolBaseUrl = "";
1292
1390
  let aceToolToken = "";
1293
1391
  if (!options.skipPrompt) {
1294
1392
  console.log();
1295
- console.log(ansis.cyan.bold(` \u{1F527} MCP \u5DE5\u5177\u9009\u62E9`));
1393
+ console.log(ansis.cyan.bold(` \u{1F527} MCP \u5DE5\u5177\u914D\u7F6E`));
1296
1394
  console.log();
1297
1395
  const { selectedMcp } = await inquirer.prompt([{
1298
1396
  type: "list",
1299
1397
  name: "selectedMcp",
1300
- message: "\u9009\u62E9 MCP \u4EE3\u7801\u68C0\u7D22\u5DE5\u5177",
1398
+ message: "\u662F\u5426\u5B89\u88C5 ace-tool MCP\uFF1F",
1301
1399
  choices: [
1302
1400
  {
1303
- name: `ace-tool ${ansis.gray("(\u63A8\u8350) - \u5F00\u7BB1\u5373\u7528\uFF0C\u542B Prompt \u589E\u5F3A + \u4EE3\u7801\u68C0\u7D22")}`,
1401
+ name: `\u5B89\u88C5 ace-tool ${ansis.gray("(\u63A8\u8350) - \u4E00\u952E\u5B89\u88C5\uFF0C\u542B Prompt \u589E\u5F3A + \u4EE3\u7801\u68C0\u7D22")}`,
1304
1402
  value: "ace-tool"
1305
1403
  },
1306
1404
  {
1307
- name: `auggie ${ansis.gray("(\u5B98\u65B9) - \u4EE3\u7801\u68C0\u7D22 + \u53EF\u9009 Prompt \u589E\u5F3A\uFF08\u9700\u989D\u5916\u914D\u7F6E\uFF09")}`,
1308
- value: "auggie"
1309
- },
1310
- {
1311
- name: `\u8DF3\u8FC7 ${ansis.gray("- \u7A0D\u540E\u624B\u52A8\u914D\u7F6E")}`,
1405
+ name: `\u8DF3\u8FC7 ${ansis.gray("- \u7A0D\u540E\u624B\u52A8\u914D\u7F6E\uFF08\u53EF\u9009 auggie \u7B49\u5176\u4ED6 MCP\uFF09")}`,
1312
1406
  value: "skip"
1313
1407
  }
1314
1408
  ],
@@ -1319,33 +1413,52 @@ async function init(options = {}) {
1319
1413
  console.log();
1320
1414
  console.log(ansis.cyan.bold(` \u{1F527} ace-tool MCP \u914D\u7F6E`));
1321
1415
  console.log(ansis.gray(` ${i18n.t("init:aceTool.description")}`));
1322
- console.log(ansis.gray(` ${i18n.t("init:aceTool.getToken")}: https://augmentcode.com/`));
1323
- console.log();
1324
- const aceAnswers = await inquirer.prompt([
1325
- {
1326
- type: "input",
1327
- name: "baseUrl",
1328
- message: `${i18n.t("init:aceTool.baseUrl")} ${ansis.gray("(Enter to skip)")}`,
1329
- default: ""
1330
- },
1331
- {
1332
- type: "password",
1333
- name: "token",
1334
- message: `${i18n.t("init:aceTool.token")} ${ansis.gray("(Enter to skip)")}`,
1335
- mask: "*"
1336
- }
1337
- ]);
1338
- aceToolBaseUrl = aceAnswers.baseUrl || "";
1339
- aceToolToken = aceAnswers.token || "";
1340
- } else if (selectedMcp === "auggie") {
1341
- console.log();
1342
- console.log(ansis.yellow(` \u2139\uFE0F auggie \u5DF2\u9009\u62E9`));
1343
- console.log(ansis.gray(` \u4EE3\u7801\u68C0\u7D22\u529F\u80FD\u5F00\u7BB1\u5373\u7528`));
1344
- console.log(ansis.gray(` Prompt \u589E\u5F3A\u9700\u989D\u5916\u914D\u7F6E: https://linux.do/t/topic/1280612`));
1345
1416
  console.log();
1417
+ const { skipToken } = await inquirer.prompt([{
1418
+ type: "confirm",
1419
+ name: "skipToken",
1420
+ message: "\u662F\u5426\u8DF3\u8FC7 Token \u914D\u7F6E\uFF1F\uFF08\u53EF\u7A0D\u540E\u8FD0\u884C npx ccg config mcp \u914D\u7F6E\uFF09",
1421
+ default: false
1422
+ }]);
1423
+ if (!skipToken) {
1424
+ console.log();
1425
+ console.log(ansis.cyan(` \u{1F4D6} \u83B7\u53D6 ace-tool \u8BBF\u95EE\u65B9\u5F0F\uFF1A`));
1426
+ console.log();
1427
+ console.log(` ${ansis.gray("\u2022")} ${ansis.cyan("\u5B98\u65B9\u670D\u52A1")}: ${ansis.underline("https://augmentcode.com/")}`);
1428
+ console.log(` ${ansis.gray("\u6CE8\u518C\u8D26\u53F7\u540E\u83B7\u53D6 Token")}`);
1429
+ console.log();
1430
+ 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")}`);
1431
+ console.log(` ${ansis.gray("linux.do \u793E\u533A\u63D0\u4F9B\u7684\u514D\u8D39\u4E2D\u8F6C\u670D\u52A1")}`);
1432
+ console.log();
1433
+ const aceAnswers = await inquirer.prompt([
1434
+ {
1435
+ type: "input",
1436
+ name: "baseUrl",
1437
+ message: `Base URL ${ansis.gray("(\u4F7F\u7528\u4E2D\u8F6C\u670D\u52A1\u65F6\u5FC5\u586B\uFF0C\u5B98\u65B9\u670D\u52A1\u7559\u7A7A)")}`,
1438
+ default: ""
1439
+ },
1440
+ {
1441
+ type: "password",
1442
+ name: "token",
1443
+ message: `Token ${ansis.gray("(\u5FC5\u586B)")}`,
1444
+ mask: "*",
1445
+ validate: (input) => input.trim() !== "" || "\u8BF7\u8F93\u5165 Token"
1446
+ }
1447
+ ]);
1448
+ aceToolBaseUrl = aceAnswers.baseUrl || "";
1449
+ aceToolToken = aceAnswers.token || "";
1450
+ } else {
1451
+ console.log();
1452
+ console.log(ansis.yellow(` \u2139\uFE0F \u5DF2\u8DF3\u8FC7 Token \u914D\u7F6E`));
1453
+ console.log(ansis.gray(` \u2022 ace-tool MCP \u5C06\u4E0D\u4F1A\u81EA\u52A8\u5B89\u88C5`));
1454
+ console.log(ansis.gray(` \u2022 \u53EF\u7A0D\u540E\u8FD0\u884C ${ansis.cyan("npx ccg config mcp")} \u914D\u7F6E Token`));
1455
+ console.log(ansis.gray(` \u2022 \u83B7\u53D6 Token: ${ansis.cyan("https://augmentcode.com/")}`));
1456
+ console.log();
1457
+ }
1346
1458
  } else {
1347
1459
  console.log();
1348
- console.log(ansis.yellow(` \u2139\uFE0F \u5DF2\u8DF3\u8FC7 MCP \u914D\u7F6E\uFF0C\u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E`));
1460
+ console.log(ansis.yellow(` \u2139\uFE0F \u5DF2\u8DF3\u8FC7 MCP \u914D\u7F6E`));
1461
+ console.log(ansis.gray(` \u2022 \u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1`));
1349
1462
  console.log();
1350
1463
  }
1351
1464
  }
@@ -1428,10 +1541,9 @@ async function init(options = {}) {
1428
1541
  await writeCcgConfig(config);
1429
1542
  const installDir = options.installDir || join(homedir(), ".claude");
1430
1543
  const result = await installWorkflows(selectedWorkflows, installDir, options.force, {
1431
- mcpProvider,
1432
1544
  routing
1433
1545
  });
1434
- if (aceToolBaseUrl || aceToolToken) {
1546
+ if (mcpProvider === "ace-tool" && aceToolToken) {
1435
1547
  spinner.text = i18n.t("init:aceTool.installing");
1436
1548
  const aceResult = await installAceTool({
1437
1549
  baseUrl: aceToolBaseUrl,
@@ -1445,6 +1557,11 @@ async function init(options = {}) {
1445
1557
  spinner.warn(ansis.yellow(i18n.t("init:aceTool.failed")));
1446
1558
  console.log(ansis.gray(` ${aceResult.message}`));
1447
1559
  }
1560
+ } else if (mcpProvider === "ace-tool" && !aceToolToken) {
1561
+ spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
1562
+ console.log();
1563
+ console.log(` ${ansis.yellow("\u26A0")} ace-tool MCP \u672A\u5B89\u88C5 ${ansis.gray("(Token \u672A\u63D0\u4F9B)")}`);
1564
+ console.log(` ${ansis.gray("\u2192")} \u7A0D\u540E\u8FD0\u884C ${ansis.cyan("npx ccg config mcp")} \u5B8C\u6210\u914D\u7F6E`);
1448
1565
  } else {
1449
1566
  spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
1450
1567
  }
@@ -1550,6 +1667,19 @@ ${exportCommand}
1550
1667
  }
1551
1668
  }
1552
1669
  }
1670
+ if (mcpProvider === "skip" || mcpProvider === "ace-tool" && !aceToolToken) {
1671
+ console.log();
1672
+ console.log(ansis.cyan.bold(` \u{1F4D6} MCP \u670D\u52A1\u9009\u9879`));
1673
+ console.log();
1674
+ console.log(ansis.gray(` \u5982\u9700\u4F7F\u7528\u4EE3\u7801\u68C0\u7D22\u548C Prompt \u589E\u5F3A\u529F\u80FD\uFF0C\u53EF\u9009\u62E9\u4EE5\u4E0B MCP \u670D\u52A1\uFF1A`));
1675
+ console.log();
1676
+ console.log(` ${ansis.green("1.")} ${ansis.cyan("ace-tool")} ${ansis.gray("(\u63A8\u8350)")}: ${ansis.underline("https://augmentcode.com/")}`);
1677
+ console.log(` ${ansis.gray("\u4E00\u952E\u5B89\u88C5\uFF0C\u542B Prompt \u589E\u5F3A + \u4EE3\u7801\u68C0\u7D22")}`);
1678
+ console.log();
1679
+ 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")}`);
1680
+ console.log(` ${ansis.gray("linux.do \u793E\u533A\u63D0\u4F9B\u7684\u514D\u8D39\u4E2D\u8F6C\u670D\u52A1")}`);
1681
+ console.log();
1682
+ }
1553
1683
  console.log();
1554
1684
  console.log(ansis.gray(` ${i18n.t("init:configSavedTo")} ${getCcgDir()}/config.toml`));
1555
1685
  console.log();
@@ -1666,18 +1796,86 @@ async function update() {
1666
1796
  console.log(ansis.red(`\u274C \u66F4\u65B0\u5931\u8D25: ${error}`));
1667
1797
  }
1668
1798
  }
1799
+ async function askReconfigureRouting(currentRouting) {
1800
+ console.log();
1801
+ console.log(ansis.cyan.bold("\u{1F527} \u6A21\u578B\u8DEF\u7531\u914D\u7F6E"));
1802
+ console.log();
1803
+ if (currentRouting) {
1804
+ console.log(ansis.gray("\u5F53\u524D\u914D\u7F6E:"));
1805
+ console.log(` ${ansis.cyan("\u524D\u7AEF\u6A21\u578B:")} ${currentRouting.frontend.models.map((m) => ansis.green(m)).join(", ")}`);
1806
+ console.log(` ${ansis.cyan("\u540E\u7AEF\u6A21\u578B:")} ${currentRouting.backend.models.map((m) => ansis.blue(m)).join(", ")}`);
1807
+ console.log();
1808
+ }
1809
+ const { reconfigure } = await inquirer.prompt([{
1810
+ type: "confirm",
1811
+ name: "reconfigure",
1812
+ message: "\u662F\u5426\u91CD\u65B0\u914D\u7F6E\u524D\u7AEF\u548C\u540E\u7AEF\u6A21\u578B\uFF1F",
1813
+ default: false
1814
+ }]);
1815
+ if (!reconfigure) {
1816
+ return null;
1817
+ }
1818
+ console.log();
1819
+ const { selectedFrontend } = await inquirer.prompt([{
1820
+ type: "checkbox",
1821
+ name: "selectedFrontend",
1822
+ message: i18n.t("init:selectFrontendModels"),
1823
+ choices: [
1824
+ { name: "Gemini", value: "gemini", checked: currentRouting?.frontend.models.includes("gemini") ?? true },
1825
+ { name: "Claude", value: "claude", checked: currentRouting?.frontend.models.includes("claude") ?? false },
1826
+ { name: "Codex", value: "codex", checked: currentRouting?.frontend.models.includes("codex") ?? false }
1827
+ ],
1828
+ validate: (answer) => answer.length > 0 || i18n.t("init:validation.selectAtLeastOne")
1829
+ }]);
1830
+ const { selectedBackend } = await inquirer.prompt([{
1831
+ type: "checkbox",
1832
+ name: "selectedBackend",
1833
+ message: i18n.t("init:selectBackendModels"),
1834
+ choices: [
1835
+ { name: "Codex", value: "codex", checked: currentRouting?.backend.models.includes("codex") ?? true },
1836
+ { name: "Gemini", value: "gemini", checked: currentRouting?.backend.models.includes("gemini") ?? false },
1837
+ { name: "Claude", value: "claude", checked: currentRouting?.backend.models.includes("claude") ?? false }
1838
+ ],
1839
+ validate: (answer) => answer.length > 0 || i18n.t("init:validation.selectAtLeastOne")
1840
+ }]);
1841
+ const frontendModels = selectedFrontend;
1842
+ const backendModels = selectedBackend;
1843
+ const newRouting = {
1844
+ frontend: {
1845
+ models: frontendModels,
1846
+ primary: frontendModels[0],
1847
+ strategy: frontendModels.length > 1 ? "parallel" : "fallback"
1848
+ },
1849
+ backend: {
1850
+ models: backendModels,
1851
+ primary: backendModels[0],
1852
+ strategy: backendModels.length > 1 ? "parallel" : "fallback"
1853
+ },
1854
+ review: {
1855
+ models: [.../* @__PURE__ */ new Set([...frontendModels, ...backendModels])],
1856
+ strategy: "parallel"
1857
+ },
1858
+ mode: currentRouting?.mode || "smart"
1859
+ };
1860
+ console.log();
1861
+ console.log(ansis.green("\u2713 \u65B0\u914D\u7F6E:"));
1862
+ console.log(` ${ansis.cyan("\u524D\u7AEF\u6A21\u578B:")} ${frontendModels.map((m) => ansis.green(m)).join(", ")}`);
1863
+ console.log(` ${ansis.cyan("\u540E\u7AEF\u6A21\u578B:")} ${backendModels.map((m) => ansis.blue(m)).join(", ")}`);
1864
+ console.log();
1865
+ return newRouting;
1866
+ }
1669
1867
  async function performUpdate(fromVersion, toVersion) {
1670
1868
  console.log();
1671
1869
  console.log(ansis.yellow.bold("\u2699\uFE0F \u5F00\u59CB\u66F4\u65B0..."));
1672
1870
  console.log();
1871
+ const config = await readCcgConfig();
1872
+ const newRouting = await askReconfigureRouting(config?.routing);
1673
1873
  const spinner = ora("\u66F4\u65B0\u547D\u4EE4\u6A21\u677F\u548C\u63D0\u793A\u8BCD...").start();
1674
1874
  try {
1675
- const config = await readCcgConfig();
1676
1875
  const workflows = config?.workflows?.installed || [];
1677
1876
  const installDir = join(homedir(), ".claude");
1678
1877
  const result = await installWorkflows(workflows, installDir, true, {
1679
- mcpProvider: config?.mcp?.provider || "auggie",
1680
- routing: config?.routing
1878
+ routing: newRouting || config?.routing
1681
1879
  });
1682
1880
  if (result.success) {
1683
1881
  spinner.succeed("\u547D\u4EE4\u6A21\u677F\u548C\u63D0\u793A\u8BCD\u66F4\u65B0\u6210\u529F");
@@ -1688,8 +1886,15 @@ async function performUpdate(fromVersion, toVersion) {
1688
1886
  }
1689
1887
  if (config) {
1690
1888
  config.general.version = toVersion;
1889
+ if (newRouting) {
1890
+ config.routing = newRouting;
1891
+ }
1691
1892
  await writeCcgConfig(config);
1692
1893
  }
1894
+ if (newRouting) {
1895
+ console.log();
1896
+ console.log(ansis.green("\u2713 \u6A21\u578B\u8DEF\u7531\u914D\u7F6E\u5DF2\u66F4\u65B0"));
1897
+ }
1693
1898
  } else {
1694
1899
  spinner.fail("\u66F4\u65B0\u5931\u8D25");
1695
1900
  console.log(ansis.red("\u90E8\u5206\u6587\u4EF6\u66F4\u65B0\u5931\u8D25:"));
@@ -1722,6 +1927,7 @@ async function showMainMenu() {
1722
1927
  choices: [
1723
1928
  { name: `${ansis.green("\u279C")} ${i18n.t("menu:options.init")}`, value: "init" },
1724
1929
  { name: `${ansis.blue("\u279C")} ${i18n.t("menu:options.update")}`, value: "update" },
1930
+ { name: `${ansis.cyan("\u2699")} \u914D\u7F6E MCP`, value: "config-mcp" },
1725
1931
  { name: `${ansis.magenta("\u279C")} ${i18n.t("menu:options.uninstall")}`, value: "uninstall" },
1726
1932
  { name: `${ansis.yellow("?")} ${i18n.t("menu:options.help")}`, value: "help" },
1727
1933
  new inquirer.Separator(),
@@ -1735,6 +1941,9 @@ async function showMainMenu() {
1735
1941
  case "update":
1736
1942
  await update();
1737
1943
  break;
1944
+ case "config-mcp":
1945
+ await configMcp();
1946
+ break;
1738
1947
  case "uninstall":
1739
1948
  await uninstall();
1740
1949
  break;
@@ -1809,4 +2018,4 @@ async function uninstall() {
1809
2018
  console.log();
1810
2019
  }
1811
2020
 
1812
- export { readClaudeCodeConfig as A, fixWindowsMcpConfig as B, writeClaudeCodeConfig as C, i18n as a, initI18n as b, changeLanguage as c, createDefaultConfig as d, createDefaultRouting as e, getConfigPath as f, getCcgDir as g, getWorkflowConfigs as h, init as i, getWorkflowById as j, installWorkflows as k, installAceTool as l, uninstallWorkflows as m, uninstallAceTool as n, migrateToV1_4_0 as o, needsMigration as p, getCurrentVersion as q, readCcgConfig as r, showMainMenu as s, getLatestVersion as t, update as u, checkForUpdates as v, writeCcgConfig as w, compareVersions as x, diagnoseMcpConfig as y, isWindows as z };
2021
+ export { readClaudeCodeConfig as A, fixWindowsMcpConfig as B, writeClaudeCodeConfig as C, configMcp as D, version as E, i18n as a, initI18n as b, changeLanguage as c, createDefaultConfig as d, createDefaultRouting as e, getConfigPath as f, getCcgDir as g, getWorkflowConfigs as h, init as i, getWorkflowById as j, installWorkflows as k, installAceTool as l, uninstallWorkflows as m, uninstallAceTool as n, migrateToV1_4_0 as o, needsMigration as p, getCurrentVersion as q, readCcgConfig as r, showMainMenu as s, getLatestVersion as t, update as u, checkForUpdates as v, writeCcgConfig as w, compareVersions as x, diagnoseMcpConfig as y, isWindows as z };