ccg-workflow 1.5.1 → 1.7.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.7.0";
14
+
13
15
  function isWindows() {
14
16
  return process.platform === "win32";
15
17
  }
@@ -131,482 +133,107 @@ 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
- }
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;
184
143
  }
144
+ dir = dirname(dir);
145
+ }
146
+ return startDir;
147
+ }
148
+ const PACKAGE_ROOT$1 = findPackageRoot$1(__dirname$2);
149
+ const WORKFLOW_CONFIGS = [
150
+ {
151
+ id: "workflow",
152
+ name: "\u5B8C\u6574\u5F00\u53D1\u5DE5\u4F5C\u6D41",
153
+ nameEn: "Full Development Workflow",
154
+ category: "development",
155
+ commands: ["workflow"],
156
+ defaultSelected: true,
157
+ order: 1,
158
+ description: "\u5B8C\u65746\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41\uFF08\u7814\u7A76\u2192\u6784\u601D\u2192\u8BA1\u5212\u2192\u6267\u884C\u2192\u4F18\u5316\u2192\u8BC4\u5BA1\uFF09",
159
+ descriptionEn: "Full 6-phase development workflow"
185
160
  },
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
- }
161
+ {
162
+ id: "frontend",
163
+ name: "\u524D\u7AEF\u4E13\u9879",
164
+ nameEn: "Frontend Tasks",
165
+ category: "development",
166
+ commands: ["frontend"],
167
+ defaultSelected: true,
168
+ order: 2,
169
+ description: "\u524D\u7AEF\u4E13\u9879\u4EFB\u52A1\uFF08Gemini\u4E3B\u5BFC\uFF0C\u66F4\u5FEB\u66F4\u7CBE\u51C6\uFF09",
170
+ descriptionEn: "Frontend tasks (Gemini-led, faster)"
260
171
  },
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"
292
- }
293
- }
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"
172
+ {
173
+ id: "backend",
174
+ name: "\u540E\u7AEF\u4E13\u9879",
175
+ nameEn: "Backend Tasks",
176
+ category: "development",
177
+ commands: ["backend"],
178
+ defaultSelected: true,
179
+ order: 3,
180
+ description: "\u540E\u7AEF\u4E13\u9879\u4EFB\u52A1\uFF08Codex\u4E3B\u5BFC\uFF0C\u66F4\u5FEB\u66F4\u7CBE\u51C6\uFF09",
181
+ descriptionEn: "Backend tasks (Codex-led, faster)"
311
182
  },
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
- }
183
+ {
184
+ id: "feat",
185
+ name: "\u667A\u80FD\u529F\u80FD\u5F00\u53D1",
186
+ nameEn: "Smart Feature Development",
187
+ category: "development",
188
+ commands: ["feat"],
189
+ defaultSelected: true,
190
+ order: 4,
191
+ description: "\u667A\u80FD\u529F\u80FD\u5F00\u53D1 - \u81EA\u52A8\u89C4\u5212\u3001\u8BBE\u8BA1\u3001\u5B9E\u65BD",
192
+ descriptionEn: "Smart feature development - auto plan, design, implement"
345
193
  },
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
194
  {
568
- id: "dev",
569
- name: "\u5B8C\u6574\u5F00\u53D1\u5DE5\u4F5C\u6D41",
570
- nameEn: "Full Development Workflow",
195
+ id: "analyze",
196
+ name: "\u6280\u672F\u5206\u6790",
197
+ nameEn: "Technical Analysis",
571
198
  category: "development",
572
- commands: ["dev"],
199
+ commands: ["analyze"],
573
200
  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)"
201
+ order: 5,
202
+ description: "\u53CC\u6A21\u578B\u6280\u672F\u5206\u6790\uFF0C\u4EC5\u5206\u6790\u4E0D\u4FEE\u6539\u4EE3\u7801",
203
+ descriptionEn: "Dual-model technical analysis, analysis only"
577
204
  },
578
205
  {
579
- id: "code",
580
- name: "\u667A\u80FD\u4EE3\u7801\u751F\u6210",
581
- nameEn: "Smart Code Generation",
206
+ id: "debug",
207
+ name: "\u95EE\u9898\u8BCA\u65AD",
208
+ nameEn: "Debug",
582
209
  category: "development",
583
- commands: ["code"],
210
+ commands: ["debug"],
584
211
  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)"
212
+ order: 6,
213
+ description: "\u591A\u6A21\u578B\u8BCA\u65AD + \u4FEE\u590D",
214
+ descriptionEn: "Multi-model diagnosis + fix"
588
215
  },
589
216
  {
590
- id: "frontend",
591
- name: "\u524D\u7AEF\u4EFB\u52A1",
592
- nameEn: "Frontend Tasks",
217
+ id: "optimize",
218
+ name: "\u6027\u80FD\u4F18\u5316",
219
+ nameEn: "Performance Optimization",
593
220
  category: "development",
594
- commands: ["frontend"],
221
+ commands: ["optimize"],
595
222
  defaultSelected: true,
596
- order: 3,
597
- description: "\u524D\u7AEF/UI/\u6837\u5F0F\u4EFB\u52A1\uFF0C\u81EA\u52A8\u8DEF\u7531\u5230 Gemini",
598
- descriptionEn: "Frontend/UI/style tasks, auto-route to Gemini"
223
+ order: 7,
224
+ description: "\u591A\u6A21\u578B\u6027\u80FD\u4F18\u5316",
225
+ descriptionEn: "Multi-model performance optimization"
599
226
  },
600
227
  {
601
- id: "backend",
602
- name: "\u540E\u7AEF\u4EFB\u52A1",
603
- nameEn: "Backend Tasks",
228
+ id: "test",
229
+ name: "\u6D4B\u8BD5\u751F\u6210",
230
+ nameEn: "Test Generation",
604
231
  category: "development",
605
- commands: ["backend"],
232
+ commands: ["test"],
606
233
  defaultSelected: true,
607
- order: 4,
608
- description: "\u540E\u7AEF/\u903B\u8F91/\u7B97\u6CD5\u4EFB\u52A1\uFF0C\u81EA\u52A8\u8DEF\u7531\u5230 Codex",
609
- descriptionEn: "Backend/logic/algorithm tasks, auto-route to Codex"
234
+ order: 8,
235
+ description: "\u667A\u80FD\u8DEF\u7531\u6D4B\u8BD5\u751F\u6210",
236
+ descriptionEn: "Smart routing test generation"
610
237
  },
611
238
  {
612
239
  id: "review",
@@ -615,152 +242,64 @@ const WORKFLOW_CONFIGS = [
615
242
  category: "development",
616
243
  commands: ["review"],
617
244
  defaultSelected: true,
618
- order: 5,
619
- description: "\u53CC\u6A21\u578B\u4EE3\u7801\u5BA1\u67E5\uFF08Codex + Gemini \u5E76\u884C\uFF09\uFF0C\u65E0\u53C2\u6570\u65F6\u81EA\u52A8\u5BA1\u67E5 git diff",
620
- descriptionEn: "Dual-model code review (Codex + Gemini parallel), auto-review git diff when no args"
245
+ order: 9,
246
+ description: "\u53CC\u6A21\u578B\u4EE3\u7801\u5BA1\u67E5\uFF0C\u65E0\u53C2\u6570\u65F6\u81EA\u52A8\u5BA1\u67E5 git diff",
247
+ descriptionEn: "Dual-model code review, auto-review git diff when no args"
621
248
  },
622
249
  {
623
- id: "analyze",
624
- name: "\u6280\u672F\u5206\u6790",
625
- nameEn: "Technical Analysis",
626
- category: "development",
627
- commands: ["analyze"],
250
+ id: "init-project",
251
+ name: "\u9879\u76EE\u521D\u59CB\u5316",
252
+ nameEn: "Project Init",
253
+ category: "init",
254
+ commands: ["init"],
628
255
  defaultSelected: true,
629
- order: 6,
630
- description: "\u53CC\u6A21\u578B\u6280\u672F\u5206\u6790\uFF08Codex + Gemini \u5E76\u884C\uFF09\uFF0C\u4EA4\u53C9\u9A8C\u8BC1\u540E\u7EFC\u5408\u89C1\u89E3",
631
- descriptionEn: "Dual-model technical analysis (Codex + Gemini parallel), comprehensive insights after cross-validation"
256
+ order: 10,
257
+ description: "\u521D\u59CB\u5316\u9879\u76EE AI \u4E0A\u4E0B\u6587\uFF0C\u751F\u6210 CLAUDE.md",
258
+ descriptionEn: "Initialize project AI context, generate CLAUDE.md"
632
259
  },
633
260
  {
634
- id: "enhance",
635
- name: "Prompt \u589E\u5F3A",
636
- nameEn: "Prompt Enhancement",
637
- category: "development",
638
- commands: ["enhance"],
261
+ id: "commit",
262
+ name: "Git \u63D0\u4EA4",
263
+ nameEn: "Git Commit",
264
+ category: "git",
265
+ commands: ["commit"],
639
266
  defaultSelected: true,
640
- order: 7,
641
- description: "\u4F7F\u7528 ace-tool enhance_prompt \u4F18\u5316 Prompt",
642
- descriptionEn: "Optimize prompts using ace-tool enhance_prompt"
643
- },
644
- {
645
- id: "debug",
646
- name: "UltraThink \u8C03\u8BD5",
647
- nameEn: "UltraThink Debug",
648
- category: "development",
649
- commands: ["debug"],
650
- defaultSelected: false,
651
- order: 8,
652
- description: "UltraThink \u591A\u6A21\u578B\u8C03\u8BD5\uFF08Codex \u540E\u7AEF\u8BCA\u65AD + Gemini \u524D\u7AEF\u8BCA\u65AD\uFF09",
653
- descriptionEn: "UltraThink multi-model debugging (Codex backend diagnosis + Gemini frontend diagnosis)"
654
- },
655
- {
656
- id: "test",
657
- name: "\u591A\u6A21\u578B\u6D4B\u8BD5\u751F\u6210",
658
- nameEn: "Multi-Model Test Generation",
659
- category: "development",
660
- commands: ["test"],
661
- defaultSelected: false,
662
- order: 9,
663
- description: "\u591A\u6A21\u578B\u6D4B\u8BD5\u751F\u6210\uFF08Codex \u540E\u7AEF\u6D4B\u8BD5 + Gemini \u524D\u7AEF\u6D4B\u8BD5\uFF09",
664
- descriptionEn: "Multi-model test generation (Codex backend tests + Gemini frontend tests)"
665
- },
666
- {
667
- id: "bugfix",
668
- name: "\u8D28\u91CF\u95E8\u63A7\u4FEE\u590D",
669
- nameEn: "Quality Gate Bugfix",
670
- category: "development",
671
- commands: ["bugfix"],
672
- defaultSelected: false,
673
- order: 10,
674
- description: "\u8D28\u91CF\u95E8\u63A7\u4FEE\u590D\uFF08\u53CC\u6A21\u578B\u4EA4\u53C9\u9A8C\u8BC1\uFF0C90%+ \u901A\u8FC7\uFF09",
675
- descriptionEn: "Quality gate bugfix (dual-model cross-validation, 90%+ pass)"
676
- },
677
- {
678
- id: "think",
679
- name: "UltraThink \u6DF1\u5EA6\u5206\u6790",
680
- nameEn: "UltraThink Deep Analysis",
681
- category: "development",
682
- commands: ["think"],
683
- defaultSelected: false,
684
- order: 11,
685
- description: "UltraThink \u6DF1\u5EA6\u5206\u6790\uFF08\u53CC\u6A21\u578B\u5E76\u884C\u5206\u6790 + \u7EFC\u5408\u89C1\u89E3\uFF09",
686
- descriptionEn: "UltraThink deep analysis (dual-model parallel analysis + comprehensive insights)"
687
- },
688
- {
689
- id: "optimize",
690
- name: "\u591A\u6A21\u578B\u6027\u80FD\u4F18\u5316",
691
- nameEn: "Multi-Model Optimization",
692
- category: "development",
693
- commands: ["optimize"],
694
- defaultSelected: false,
695
- order: 12,
696
- description: "\u591A\u6A21\u578B\u6027\u80FD\u4F18\u5316\uFF08Codex \u540E\u7AEF\u4F18\u5316 + Gemini \u524D\u7AEF\u4F18\u5316\uFF09",
697
- descriptionEn: "Multi-model performance optimization (Codex backend + Gemini frontend)"
698
- },
699
- {
700
- id: "commit",
701
- name: "Git \u667A\u80FD\u63D0\u4EA4",
702
- nameEn: "Git Smart Commit",
703
- category: "git",
704
- commands: ["commit"],
705
- defaultSelected: true,
706
- order: 20,
707
- description: "\u4EC5\u7528 Git \u5206\u6790\u6539\u52A8\u5E76\u81EA\u52A8\u751F\u6210 conventional commit \u4FE1\u606F\uFF08\u53EF\u9009 emoji\uFF09",
708
- descriptionEn: "Git-only analysis to auto-generate conventional commit messages (optional emoji)"
267
+ order: 20,
268
+ description: "\u667A\u80FD\u751F\u6210 conventional commit \u4FE1\u606F",
269
+ descriptionEn: "Smart conventional commit message generation"
709
270
  },
710
271
  {
711
272
  id: "rollback",
712
- name: "Git \u4EA4\u4E92\u5F0F\u56DE\u6EDA",
713
- nameEn: "Git Interactive Rollback",
273
+ name: "Git \u56DE\u6EDA",
274
+ nameEn: "Git Rollback",
714
275
  category: "git",
715
276
  commands: ["rollback"],
716
277
  defaultSelected: true,
717
278
  order: 21,
718
- description: "\u4EA4\u4E92\u5F0F\u56DE\u6EDA Git \u5206\u652F\u5230\u5386\u53F2\u7248\u672C\uFF1B\u5217\u5206\u652F\u3001\u5217\u7248\u672C\u3001\u4E8C\u6B21\u786E\u8BA4\u540E\u6267\u884C",
719
- descriptionEn: "Interactive Git branch rollback; list branches, versions, confirm before execution"
279
+ description: "\u4EA4\u4E92\u5F0F\u56DE\u6EDA\u5206\u652F\u5230\u5386\u53F2\u7248\u672C",
280
+ descriptionEn: "Interactive rollback to historical version"
720
281
  },
721
282
  {
722
283
  id: "clean-branches",
723
- name: "\u6E05\u7406 Git \u5206\u652F",
724
- nameEn: "Clean Git Branches",
284
+ name: "Git \u6E05\u7406\u5206\u652F",
285
+ nameEn: "Git Clean Branches",
725
286
  category: "git",
726
287
  commands: ["clean-branches"],
727
288
  defaultSelected: true,
728
289
  order: 22,
729
- description: "\u5B89\u5168\u67E5\u627E\u5E76\u6E05\u7406\u5DF2\u5408\u5E76\u6216\u8FC7\u671F\u7684 Git \u5206\u652F\uFF0C\u652F\u6301 dry-run \u6A21\u5F0F",
730
- descriptionEn: "Safely find and clean merged or stale Git branches, supports dry-run mode"
290
+ description: "\u5B89\u5168\u6E05\u7406\u5DF2\u5408\u5E76\u6216\u8FC7\u671F\u5206\u652F",
291
+ descriptionEn: "Safely clean merged or stale branches"
731
292
  },
732
293
  {
733
294
  id: "worktree",
734
- name: "Git Worktree \u7BA1\u7406",
735
- nameEn: "Git Worktree Management",
295
+ name: "Git Worktree",
296
+ nameEn: "Git Worktree",
736
297
  category: "git",
737
298
  commands: ["worktree"],
738
- defaultSelected: false,
739
- order: 23,
740
- description: "\u7BA1\u7406 Git worktree\uFF0C\u5728\u9879\u76EE\u5E73\u7EA7\u7684 ../.ccg/\u9879\u76EE\u540D/ \u76EE\u5F55\u4E0B\u521B\u5EFA",
741
- descriptionEn: "Manage Git worktree, create in ../.ccg/project-name/ directory parallel to project"
742
- },
743
- {
744
- id: "init-project",
745
- name: "\u9879\u76EE AI \u4E0A\u4E0B\u6587\u521D\u59CB\u5316",
746
- nameEn: "Project AI Context Init",
747
- category: "init",
748
- commands: ["init"],
749
299
  defaultSelected: true,
750
- order: 30,
751
- description: "\u521D\u59CB\u5316\u9879\u76EE AI \u4E0A\u4E0B\u6587\uFF0C\u751F\u6210/\u66F4\u65B0\u6839\u7EA7\u4E0E\u6A21\u5757\u7EA7 CLAUDE.md \u7D22\u5F15",
752
- descriptionEn: "Initialize project AI context, generate/update root and module level CLAUDE.md index"
753
- },
754
- {
755
- id: "feat",
756
- name: "\u667A\u80FD\u529F\u80FD\u5F00\u53D1",
757
- nameEn: "Smart Feature Development",
758
- category: "planning",
759
- commands: ["feat"],
760
- defaultSelected: true,
761
- order: 32,
762
- description: "\u667A\u80FD\u529F\u80FD\u5F00\u53D1 - \u81EA\u52A8\u89C4\u5212\u3001\u8BBE\u8BA1\u3001\u5B9E\u65BD\uFF08\u652F\u6301\u9700\u6C42\u89C4\u5212/\u8BA8\u8BBA\u8FED\u4EE3/\u6267\u884C\u5B9E\u65BD\uFF09",
763
- descriptionEn: "Smart feature development - auto plan, design, implement (supports planning/iteration/execution modes)"
300
+ order: 23,
301
+ description: "\u7BA1\u7406 Git worktree",
302
+ descriptionEn: "Manage Git worktree"
764
303
  }
765
304
  ];
766
305
  function getWorkflowConfigs() {
@@ -769,19 +308,16 @@ function getWorkflowConfigs() {
769
308
  function getWorkflowById(id) {
770
309
  return WORKFLOW_CONFIGS.find((w) => w.id === id);
771
310
  }
311
+ function getAllCommandIds() {
312
+ return WORKFLOW_CONFIGS.map((w) => w.id);
313
+ }
314
+ ({
315
+ full: {
316
+ workflows: WORKFLOW_CONFIGS.map((w) => w.id)
317
+ }
318
+ });
772
319
  function injectConfigVariables(content, config) {
773
320
  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
321
  const routing = config.routing || {};
786
322
  const frontendModels = routing.frontend?.models || ["gemini"];
787
323
  const frontendPrimary = routing.frontend?.primary || "gemini";
@@ -806,7 +342,6 @@ function replaceHomePathsInTemplate(content, installDir) {
806
342
  }
807
343
  async function installWorkflows(workflowIds, installDir, force = false, config) {
808
344
  const installConfig = {
809
- mcpProvider: config?.mcpProvider || "auggie",
810
345
  routing: config?.routing || {
811
346
  mode: "smart",
812
347
  frontend: { models: ["gemini"], primary: "gemini" },
@@ -866,16 +401,6 @@ ${workflow.description}
866
401
  }
867
402
  }
868
403
  }
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
404
  const agentsSrcDir = join(templateDir, "commands", "agents");
880
405
  const agentsDestDir = join(installDir, "agents", "ccg");
881
406
  if (await fs.pathExists(agentsSrcDir)) {
@@ -928,6 +453,34 @@ ${workflow.description}
928
453
  }
929
454
  }
930
455
  }
456
+ const skillsTemplateDir = join(templateDir, "skills");
457
+ const skillsDestDir = join(installDir, "skills");
458
+ if (await fs.pathExists(skillsTemplateDir)) {
459
+ try {
460
+ const skillDirs = await fs.readdir(skillsTemplateDir);
461
+ for (const skillName of skillDirs) {
462
+ const srcSkillDir = join(skillsTemplateDir, skillName);
463
+ const destSkillDir = join(skillsDestDir, skillName);
464
+ const stat = await fs.stat(srcSkillDir);
465
+ if (stat.isDirectory()) {
466
+ await fs.ensureDir(destSkillDir);
467
+ const files = await fs.readdir(srcSkillDir);
468
+ for (const file of files) {
469
+ const srcFile = join(srcSkillDir, file);
470
+ const destFile = join(destSkillDir, file);
471
+ if (force || !await fs.pathExists(destFile)) {
472
+ const templateContent = await fs.readFile(srcFile, "utf-8");
473
+ const processedContent = replaceHomePathsInTemplate(templateContent, installDir);
474
+ await fs.writeFile(destFile, processedContent, "utf-8");
475
+ }
476
+ }
477
+ }
478
+ }
479
+ } catch (error) {
480
+ result.errors.push(`Failed to install skills: ${error}`);
481
+ result.success = false;
482
+ }
483
+ }
931
484
  try {
932
485
  const binDir = join(installDir, "bin");
933
486
  await fs.ensureDir(binDir);
@@ -937,9 +490,9 @@ ${workflow.description}
937
490
  if (platform === "darwin") {
938
491
  binaryName = arch === "arm64" ? "codeagent-wrapper-darwin-arm64" : "codeagent-wrapper-darwin-amd64";
939
492
  } else if (platform === "linux") {
940
- binaryName = "codeagent-wrapper-linux-amd64";
493
+ binaryName = arch === "arm64" ? "codeagent-wrapper-linux-arm64" : "codeagent-wrapper-linux-amd64";
941
494
  } else if (platform === "win32") {
942
- binaryName = "codeagent-wrapper-windows-amd64.exe";
495
+ binaryName = arch === "arm64" ? "codeagent-wrapper-windows-arm64.exe" : "codeagent-wrapper-windows-amd64.exe";
943
496
  } else {
944
497
  result.errors.push(`Unsupported platform: ${platform}`);
945
498
  result.success = false;
@@ -978,10 +531,17 @@ async function uninstallWorkflows(installDir) {
978
531
  success: true,
979
532
  removedCommands: [],
980
533
  removedPrompts: [],
534
+ removedAgents: [],
535
+ removedSkills: [],
536
+ removedBin: false,
981
537
  errors: []
982
538
  };
983
539
  const commandsDir = join(installDir, "commands", "ccg");
984
- const promptsDir = join(installDir, "prompts", "ccg");
540
+ const promptsDir = join(installDir, ".ccg", "prompts");
541
+ const agentsDir = join(installDir, "agents", "ccg");
542
+ const skillsDir = join(installDir, "skills", "multi-model-collaboration");
543
+ const binDir = join(installDir, "bin");
544
+ join(installDir, ".ccg");
985
545
  if (await fs.pathExists(commandsDir)) {
986
546
  try {
987
547
  const files = await fs.readdir(commandsDir);
@@ -991,6 +551,10 @@ async function uninstallWorkflows(installDir) {
991
551
  result.removedCommands.push(file.replace(".md", ""));
992
552
  }
993
553
  }
554
+ const agentsSubDir = join(commandsDir, "agents");
555
+ if (await fs.pathExists(agentsSubDir)) {
556
+ await fs.remove(agentsSubDir);
557
+ }
994
558
  const remaining = await fs.readdir(commandsDir);
995
559
  if (remaining.length === 0) {
996
560
  await fs.remove(commandsDir);
@@ -1000,97 +564,626 @@ async function uninstallWorkflows(installDir) {
1000
564
  result.success = false;
1001
565
  }
1002
566
  }
1003
- if (await fs.pathExists(promptsDir)) {
567
+ if (await fs.pathExists(agentsDir)) {
1004
568
  try {
1005
- const files = await fs.readdir(promptsDir);
569
+ const files = await fs.readdir(agentsDir);
1006
570
  for (const file of files) {
1007
- await fs.remove(join(promptsDir, file));
1008
- result.removedPrompts.push(file);
571
+ await fs.remove(join(agentsDir, file));
572
+ result.removedAgents.push(file.replace(".md", ""));
1009
573
  }
1010
- const remaining = await fs.readdir(promptsDir);
1011
- if (remaining.length === 0) {
1012
- await fs.remove(promptsDir);
574
+ await fs.remove(agentsDir);
575
+ } catch (error) {
576
+ result.errors.push(`Failed to remove agents: ${error}`);
577
+ result.success = false;
578
+ }
579
+ }
580
+ if (await fs.pathExists(skillsDir)) {
581
+ try {
582
+ const files = await fs.readdir(skillsDir);
583
+ for (const file of files) {
584
+ result.removedSkills.push(file);
585
+ }
586
+ await fs.remove(skillsDir);
587
+ } catch (error) {
588
+ result.errors.push(`Failed to remove skills: ${error}`);
589
+ result.success = false;
590
+ }
591
+ }
592
+ if (await fs.pathExists(promptsDir)) {
593
+ try {
594
+ await fs.remove(promptsDir);
595
+ result.removedPrompts.push("codex", "gemini");
596
+ } catch (error) {
597
+ result.errors.push(`Failed to remove prompts: ${error}`);
598
+ result.success = false;
599
+ }
600
+ }
601
+ if (await fs.pathExists(binDir)) {
602
+ try {
603
+ const wrapperName = process.platform === "win32" ? "codeagent-wrapper.exe" : "codeagent-wrapper";
604
+ const wrapperPath = join(binDir, wrapperName);
605
+ if (await fs.pathExists(wrapperPath)) {
606
+ await fs.remove(wrapperPath);
607
+ result.removedBin = true;
608
+ }
609
+ } catch (error) {
610
+ result.errors.push(`Failed to remove binary: ${error}`);
611
+ result.success = false;
612
+ }
613
+ }
614
+ return result;
615
+ }
616
+ async function uninstallAceTool() {
617
+ try {
618
+ const existingConfig = await readClaudeCodeConfig();
619
+ if (!existingConfig) {
620
+ return {
621
+ success: true,
622
+ message: "No ~/.claude.json found, nothing to remove"
623
+ };
624
+ }
625
+ if (!existingConfig.mcpServers || !existingConfig.mcpServers["ace-tool"]) {
626
+ return {
627
+ success: true,
628
+ message: "ace-tool MCP not found in config"
629
+ };
630
+ }
631
+ await backupClaudeCodeConfig();
632
+ delete existingConfig.mcpServers["ace-tool"];
633
+ await writeClaudeCodeConfig(existingConfig);
634
+ return {
635
+ success: true,
636
+ message: "ace-tool MCP removed from ~/.claude.json"
637
+ };
638
+ } catch (error) {
639
+ return {
640
+ success: false,
641
+ message: `Failed to uninstall ace-tool: ${error}`
642
+ };
643
+ }
644
+ }
645
+ async function installAceTool(config) {
646
+ const { baseUrl, token } = config;
647
+ try {
648
+ let existingConfig = await readClaudeCodeConfig();
649
+ if (!existingConfig) {
650
+ existingConfig = { mcpServers: {} };
651
+ }
652
+ if (existingConfig.mcpServers && Object.keys(existingConfig.mcpServers).length > 0) {
653
+ const backupPath = await backupClaudeCodeConfig();
654
+ if (backupPath) {
655
+ console.log(` \u2713 Backup created: ${backupPath}`);
656
+ }
657
+ }
658
+ const args = ["-y", "ace-tool@latest"];
659
+ if (baseUrl) {
660
+ args.push("--base-url", baseUrl);
661
+ }
662
+ if (token) {
663
+ args.push("--token", token);
664
+ }
665
+ const aceToolConfig = buildMcpServerConfig({
666
+ type: "stdio",
667
+ command: "npx",
668
+ args
669
+ });
670
+ let mergedConfig = mergeMcpServers(existingConfig, {
671
+ "ace-tool": aceToolConfig
672
+ });
673
+ if (isWindows()) {
674
+ mergedConfig = fixWindowsMcpConfig(mergedConfig);
675
+ console.log(" \u2713 Applied Windows MCP configuration fixes");
676
+ }
677
+ await writeClaudeCodeConfig(mergedConfig);
678
+ return {
679
+ success: true,
680
+ message: isWindows() ? "ace-tool MCP configured successfully with Windows compatibility" : "ace-tool MCP configured successfully",
681
+ configPath: join(homedir(), ".claude.json")
682
+ };
683
+ } catch (error) {
684
+ return {
685
+ success: false,
686
+ message: `Failed to configure ace-tool: ${error}`
687
+ };
688
+ }
689
+ }
690
+
691
+ async function configMcp() {
692
+ console.log();
693
+ console.log(ansis.cyan.bold(` \u914D\u7F6E ace-tool MCP`));
694
+ console.log();
695
+ const { action } = await inquirer.prompt([{
696
+ type: "list",
697
+ name: "action",
698
+ message: "\u9009\u62E9\u64CD\u4F5C",
699
+ choices: [
700
+ { name: `${ansis.green("\u279C")} \u5B89\u88C5/\u66F4\u65B0 ace-tool MCP`, value: "install" },
701
+ { name: `${ansis.red("\u2715")} \u5378\u8F7D ace-tool MCP`, value: "uninstall" },
702
+ new inquirer.Separator(),
703
+ { name: `${ansis.gray("\u8FD4\u56DE")}`, value: "cancel" }
704
+ ]
705
+ }]);
706
+ if (action === "cancel") {
707
+ return;
708
+ }
709
+ if (action === "uninstall") {
710
+ await handleUninstall();
711
+ return;
712
+ }
713
+ console.log();
714
+ console.log(ansis.cyan(`\u{1F4D6} \u83B7\u53D6 ace-tool \u8BBF\u95EE\u65B9\u5F0F\uFF1A`));
715
+ console.log(` ${ansis.gray("\u2022")} ${ansis.cyan("\u5B98\u65B9\u670D\u52A1")}: ${ansis.underline("https://augmentcode.com/")}`);
716
+ 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")}`);
717
+ console.log();
718
+ const aceAnswers = await inquirer.prompt([
719
+ {
720
+ type: "input",
721
+ name: "baseUrl",
722
+ message: `Base URL ${ansis.gray("(\u4F7F\u7528\u4E2D\u8F6C\u670D\u52A1\u65F6\u5FC5\u586B\uFF0C\u5B98\u65B9\u670D\u52A1\u7559\u7A7A)")}`
723
+ },
724
+ {
725
+ type: "password",
726
+ name: "token",
727
+ message: `Token ${ansis.gray("(\u5FC5\u586B)")}`,
728
+ validate: (input) => input.trim() !== "" || "\u8BF7\u8F93\u5165 Token"
729
+ }
730
+ ]);
731
+ console.log();
732
+ console.log(ansis.yellow("\u23F3 \u6B63\u5728\u914D\u7F6E ace-tool MCP..."));
733
+ console.log();
734
+ const result = await installAceTool({
735
+ baseUrl: aceAnswers.baseUrl?.trim() || void 0,
736
+ token: aceAnswers.token.trim()
737
+ });
738
+ if (result.success) {
739
+ console.log(ansis.green("\u2713 ace-tool MCP \u914D\u7F6E\u6210\u529F\uFF01"));
740
+ if (result.configPath) {
741
+ console.log(ansis.gray(` \u914D\u7F6E\u6587\u4EF6: ${result.configPath}`));
742
+ }
743
+ console.log();
744
+ console.log(ansis.cyan("\u{1F4A1} \u63D0\u793A\uFF1A"));
745
+ console.log(ansis.gray(" 1. \u91CD\u542F Claude Code CLI \u4F7F\u914D\u7F6E\u751F\u6548"));
746
+ console.log(ansis.gray(" 2. \u8FD0\u884C /ccg:dev \u547D\u4EE4\u6D4B\u8BD5 MCP \u529F\u80FD"));
747
+ } else {
748
+ console.log(ansis.red("\u2717 ace-tool MCP \u914D\u7F6E\u5931\u8D25"));
749
+ console.log(ansis.gray(` \u9519\u8BEF\u4FE1\u606F: ${result.message}`));
750
+ }
751
+ console.log();
752
+ }
753
+ async function handleUninstall() {
754
+ console.log();
755
+ const { confirm } = await inquirer.prompt([{
756
+ type: "confirm",
757
+ name: "confirm",
758
+ message: "\u786E\u5B9A\u8981\u5378\u8F7D ace-tool MCP \u5417\uFF1F",
759
+ default: false
760
+ }]);
761
+ if (!confirm) {
762
+ console.log(ansis.gray("\u5DF2\u53D6\u6D88"));
763
+ return;
764
+ }
765
+ console.log();
766
+ console.log(ansis.yellow("\u23F3 \u6B63\u5728\u5378\u8F7D ace-tool MCP..."));
767
+ const result = await uninstallAceTool();
768
+ if (result.success) {
769
+ console.log(ansis.green("\u2713 ace-tool MCP \u5DF2\u5378\u8F7D"));
770
+ console.log();
771
+ } else {
772
+ console.log(ansis.red("\u2717 \u5378\u8F7D\u5931\u8D25"));
773
+ console.log(ansis.gray(` \u9519\u8BEF\u4FE1\u606F: ${result.message}`));
774
+ console.log();
775
+ }
776
+ }
777
+
778
+ const i18n = i18next;
779
+ const zhCN = {
780
+ common: {
781
+ yes: "\u662F",
782
+ no: "\u5426",
783
+ confirm: "\u786E\u8BA4",
784
+ cancel: "\u53D6\u6D88",
785
+ back: "\u8FD4\u56DE",
786
+ exit: "\u9000\u51FA",
787
+ success: "\u6210\u529F",
788
+ error: "\u9519\u8BEF",
789
+ warning: "\u8B66\u544A",
790
+ info: "\u4FE1\u606F",
791
+ loading: "\u52A0\u8F7D\u4E2D...",
792
+ processing: "\u5904\u7406\u4E2D...",
793
+ completed: "\u5DF2\u5B8C\u6210",
794
+ failed: "\u5931\u8D25"
795
+ },
796
+ cli: {
797
+ help: {
798
+ commands: "\u547D\u4EE4",
799
+ commandDescriptions: {
800
+ showMenu: "\u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355\uFF08\u9ED8\u8BA4\uFF09",
801
+ initConfig: "\u521D\u59CB\u5316 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF"
802
+ },
803
+ shortcuts: "\u5FEB\u6377\u65B9\u5F0F:",
804
+ shortcutDescriptions: {
805
+ quickInit: "\u5FEB\u901F\u521D\u59CB\u5316"
806
+ },
807
+ options: "\u9009\u9879",
808
+ optionDescriptions: {
809
+ displayLanguage: "\u663E\u793A\u8BED\u8A00",
810
+ forceOverwrite: "\u5F3A\u5236\u8986\u76D6\u73B0\u6709\u914D\u7F6E",
811
+ displayHelp: "\u663E\u793A\u5E2E\u52A9\u4FE1\u606F",
812
+ displayVersion: "\u663E\u793A\u7248\u672C\u53F7",
813
+ skipAllPrompts: "\u8DF3\u8FC7\u6240\u6709\u4EA4\u4E92\u5F0F\u63D0\u793A\uFF08\u975E\u4EA4\u4E92\u6A21\u5F0F\uFF09",
814
+ frontendModels: "\u524D\u7AEF\u6A21\u578B\uFF08\u9017\u53F7\u5206\u9694\uFF09",
815
+ backendModels: "\u540E\u7AEF\u6A21\u578B\uFF08\u9017\u53F7\u5206\u9694\uFF09",
816
+ collaborationMode: "\u534F\u4F5C\u6A21\u5F0F (parallel/smart/sequential)",
817
+ workflows: "\u8981\u5B89\u88C5\u7684\u5DE5\u4F5C\u6D41",
818
+ installDir: "\u5B89\u88C5\u76EE\u5F55"
819
+ },
820
+ nonInteractiveMode: "\u975E\u4EA4\u4E92\u6A21\u5F0F:",
821
+ examples: "\u793A\u4F8B",
822
+ exampleDescriptions: {
823
+ showInteractiveMenu: "\u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355",
824
+ runFullInitialization: "\u8FD0\u884C\u5B8C\u6574\u521D\u59CB\u5316",
825
+ customModels: "\u81EA\u5B9A\u4E49\u6A21\u578B\u914D\u7F6E",
826
+ parallelMode: "\u4F7F\u7528\u5E76\u884C\u534F\u4F5C\u6A21\u5F0F"
827
+ }
828
+ }
829
+ },
830
+ init: {
831
+ welcome: "\u6B22\u8FCE\u4F7F\u7528 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF",
832
+ selectLanguage: "\u8BF7\u9009\u62E9\u8BED\u8A00",
833
+ selectFrontendModels: "\u9009\u62E9\u524D\u7AEF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u53EF\u591A\u9009\uFF09",
834
+ selectBackendModels: "\u9009\u62E9\u540E\u7AEF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u53EF\u591A\u9009\uFF09",
835
+ selectMode: "\u9009\u62E9\u534F\u4F5C\u6A21\u5F0F",
836
+ selectWorkflows: "\u9009\u62E9\u8981\u5B89\u88C5\u7684\u5DE5\u4F5C\u6D41\uFF08\u53EF\u591A\u9009\uFF09",
837
+ confirmInstall: "\u786E\u8BA4\u5B89\u88C5\u4EE5\u4E0A\u914D\u7F6E\uFF1F",
838
+ installing: "\u6B63\u5728\u5B89\u88C5...",
839
+ installSuccess: "\u5B89\u88C5\u6210\u529F\uFF01",
840
+ installFailed: "\u5B89\u88C5\u5931\u8D25",
841
+ installCancelled: "\u5B89\u88C5\u5DF2\u53D6\u6D88",
842
+ installedCommands: "\u5DF2\u5B89\u88C5\u547D\u4EE4:",
843
+ installedPrompts: "\u5DF2\u5B89\u88C5\u89D2\u8272\u63D0\u793A\u8BCD:",
844
+ installedBinary: "\u5DF2\u5B89\u88C5\u4E8C\u8FDB\u5236\u6587\u4EF6:",
845
+ installationErrors: "\u5B89\u88C5\u8FC7\u7A0B\u4E2D\u51FA\u73B0\u9519\u8BEF:",
846
+ pathWarning: "\u9700\u8981\u5C06 codeagent-wrapper \u6DFB\u52A0\u5230 PATH \u624D\u80FD\u4F7F\u7528",
847
+ autoConfigurePathPrompt: "\u662F\u5426\u81EA\u52A8\u914D\u7F6E PATH \u73AF\u5883\u53D8\u91CF\uFF1F",
848
+ pathConfigured: "PATH \u5DF2\u6DFB\u52A0\u5230 {{file}}",
849
+ pathAlreadyConfigured: "PATH \u5DF2\u914D\u7F6E\u5728 {{file}} \u4E2D",
850
+ pathConfigFailed: "\u81EA\u52A8\u914D\u7F6E\u5931\u8D25",
851
+ restartShellPrompt: "\u8BF7\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u4F7F\u914D\u7F6E\u751F\u6548:",
852
+ manualConfigInstructions: "\u8BF7\u624B\u52A8\u6DFB\u52A0\u4EE5\u4E0B\u547D\u4EE4\u5230 {{file}}:",
853
+ windowsPathInstructions: "Windows \u7528\u6237 - \u624B\u52A8\u6DFB\u52A0\u5230\u7CFB\u7EDF\u73AF\u5883\u53D8\u91CF:",
854
+ windowsStep1: '\u6309 Win+X\uFF0C\u9009\u62E9"\u7CFB\u7EDF"',
855
+ windowsStep2: '\u70B9\u51FB"\u9AD8\u7EA7\u7CFB\u7EDF\u8BBE\u7F6E" \u2192 "\u73AF\u5883\u53D8\u91CF"',
856
+ windowsStep3: '\u5728"\u7528\u6237\u53D8\u91CF"\u4E2D\u627E\u5230 Path\uFF0C\u70B9\u51FB"\u7F16\u8F91"\uFF0C\u6DFB\u52A0:',
857
+ windowsStep4: '\u70B9\u51FB"\u786E\u5B9A"\u4FDD\u5B58\uFF0C\u91CD\u542F\u7EC8\u7AEF',
858
+ orUsePowerShell: "\u6216\u5728 PowerShell (\u7BA1\u7406\u5458) \u4E2D\u8FD0\u884C:",
859
+ addToShellConfig: "\u8BF7\u6DFB\u52A0\u4EE5\u4E0B\u547D\u4EE4\u5230 {{file}} \u5E76\u91CD\u542F\u7EC8\u7AEF",
860
+ configSavedTo: "\u914D\u7F6E\u5DF2\u4FDD\u5B58\u81F3:",
861
+ validation: {
862
+ selectAtLeastOne: "\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u6A21\u578B"
863
+ },
864
+ summary: {
865
+ title: "\u914D\u7F6E\u6458\u8981:",
866
+ frontendModels: "\u524D\u7AEF\u6A21\u578B:",
867
+ backendModels: "\u540E\u7AEF\u6A21\u578B:",
868
+ collaboration: "\u534F\u4F5C\u6A21\u5F0F:",
869
+ workflows: "\u5DE5\u4F5C\u6D41:",
870
+ selected: "\u4E2A\u5DF2\u9009\u62E9"
871
+ },
872
+ modes: {
873
+ parallel: "\u5E76\u884C\u6A21\u5F0F - \u540C\u65F6\u8C03\u7528\u591A\u4E2A\u6A21\u578B",
874
+ smart: "\u667A\u80FD\u6A21\u5F0F - \u6839\u636E\u4EFB\u52A1\u7C7B\u578B\u81EA\u52A8\u9009\u62E9",
875
+ sequential: "\u987A\u5E8F\u6A21\u5F0F - \u4F9D\u6B21\u8C03\u7528\u6A21\u578B"
876
+ },
877
+ models: {
878
+ codex: "Codex - \u64C5\u957F\u540E\u7AEF\u903B\u8F91\u3001\u7B97\u6CD5\u3001\u8C03\u8BD5",
879
+ gemini: "Gemini - \u64C5\u957F\u524D\u7AEFUI\u3001CSS\u3001\u7EC4\u4EF6\u8BBE\u8BA1",
880
+ claude: "Claude - \u64C5\u957F\u7F16\u6392\u3001\u91CD\u6784\u3001\u6587\u6863\u751F\u6210"
881
+ },
882
+ workflows: {
883
+ dev: "\u5B8C\u6574\u5F00\u53D1\u5DE5\u4F5C\u6D41 (/ccg:dev)",
884
+ frontend: "\u524D\u7AEF\u4EFB\u52A1 (/ccg:frontend)",
885
+ backend: "\u540E\u7AEF\u4EFB\u52A1 (/ccg:backend)",
886
+ review: "\u4EE3\u7801\u5BA1\u67E5 (/ccg:review)",
887
+ analyze: "\u6280\u672F\u5206\u6790 (/ccg:analyze)",
888
+ commit: "Git \u667A\u80FD\u63D0\u4EA4 (/ccg:commit)",
889
+ rollback: "Git \u56DE\u6EDA (/ccg:rollback)",
890
+ cleanBranches: "\u6E05\u7406\u5206\u652F (/ccg:clean-branches)",
891
+ worktree: "Worktree \u7BA1\u7406 (/ccg:worktree)",
892
+ init: "\u9879\u76EE\u521D\u59CB\u5316 (/ccg:init)"
893
+ },
894
+ aceTool: {
895
+ title: "ace-tool MCP \u914D\u7F6E",
896
+ description: "\u8F7B\u91CF\u7EA7\u4EE3\u7801\u68C0\u7D22\u548C Prompt \u589E\u5F3A\u5DE5\u5177",
897
+ getToken: "\u83B7\u53D6 Token",
898
+ configure: "\u662F\u5426\u914D\u7F6E ace-tool MCP\uFF1F",
899
+ baseUrl: "API Base URL:",
900
+ token: "API Token:",
901
+ installing: "\u6B63\u5728\u914D\u7F6E ace-tool MCP...",
902
+ failed: "ace-tool \u914D\u7F6E\u5931\u8D25\uFF08\u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\uFF09"
903
+ }
904
+ },
905
+ menu: {
906
+ title: "CCG \u4E3B\u83DC\u5355",
907
+ options: {
908
+ init: "\u521D\u59CB\u5316 CCG \u914D\u7F6E",
909
+ update: "\u66F4\u65B0\u5DE5\u4F5C\u6D41",
910
+ uninstall: "\u5378\u8F7D CCG",
911
+ help: "\u5E2E\u52A9",
912
+ exit: "\u9000\u51FA"
913
+ },
914
+ help: {
915
+ title: "CCG \u547D\u4EE4:",
916
+ hint: "\u66F4\u591A\u4FE1\u606F\u8BF7\u8FD0\u884C: npx ccg --help",
917
+ descriptions: {
918
+ dev: "\u5B8C\u6574\u516D\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41",
919
+ frontend: "\u524D\u7AEF\u4EFB\u52A1 \u2192 Gemini",
920
+ backend: "\u540E\u7AEF\u4EFB\u52A1 \u2192 Codex",
921
+ review: "\u53CC\u6A21\u578B\u4EE3\u7801\u5BA1\u67E5",
922
+ analyze: "\u53CC\u6A21\u578B\u6280\u672F\u5206\u6790",
923
+ commit: "Git \u667A\u80FD\u63D0\u4EA4",
924
+ rollback: "Git \u4EA4\u4E92\u5F0F\u56DE\u6EDA"
925
+ }
926
+ },
927
+ uninstall: {
928
+ 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",
929
+ alsoRemoveAceTool: "\u540C\u65F6\u79FB\u9664 ace-tool MCP \u914D\u7F6E\uFF1F",
930
+ uninstalling: "\u6B63\u5728\u5378\u8F7D...",
931
+ success: "\u5378\u8F7D\u6210\u529F\uFF01",
932
+ removedCommands: "\u5DF2\u79FB\u9664\u547D\u4EE4:",
933
+ removedAceTool: "ace-tool MCP \u914D\u7F6E\u5DF2\u79FB\u9664",
934
+ cancelled: "\u5378\u8F7D\u5DF2\u53D6\u6D88",
935
+ failed: "\u5378\u8F7D\u5931\u8D25"
936
+ }
937
+ }
938
+ };
939
+ const en = {
940
+ common: {
941
+ yes: "Yes",
942
+ no: "No",
943
+ confirm: "Confirm",
944
+ cancel: "Cancel",
945
+ back: "Back",
946
+ exit: "Exit",
947
+ success: "Success",
948
+ error: "Error",
949
+ warning: "Warning",
950
+ info: "Info",
951
+ loading: "Loading...",
952
+ processing: "Processing...",
953
+ completed: "Completed",
954
+ failed: "Failed"
955
+ },
956
+ cli: {
957
+ help: {
958
+ commands: "Commands",
959
+ commandDescriptions: {
960
+ showMenu: "Show interactive menu (default)",
961
+ initConfig: "Initialize CCG multi-model collaboration system"
962
+ },
963
+ shortcuts: "Shortcuts:",
964
+ shortcutDescriptions: {
965
+ quickInit: "Quick init"
966
+ },
967
+ options: "Options",
968
+ optionDescriptions: {
969
+ displayLanguage: "Display language",
970
+ forceOverwrite: "Force overwrite existing configuration",
971
+ displayHelp: "Display help",
972
+ displayVersion: "Display version",
973
+ skipAllPrompts: "Skip all interactive prompts (non-interactive mode)",
974
+ frontendModels: "Frontend models (comma-separated)",
975
+ backendModels: "Backend models (comma-separated)",
976
+ collaborationMode: "Collaboration mode (parallel/smart/sequential)",
977
+ workflows: "Workflows to install",
978
+ installDir: "Installation directory"
979
+ },
980
+ nonInteractiveMode: "Non-interactive mode:",
981
+ examples: "Examples",
982
+ exampleDescriptions: {
983
+ showInteractiveMenu: "Show interactive menu",
984
+ runFullInitialization: "Run full initialization",
985
+ customModels: "Custom model configuration",
986
+ parallelMode: "Use parallel collaboration mode"
987
+ }
988
+ }
989
+ },
990
+ init: {
991
+ welcome: "Welcome to CCG Multi-Model Collaboration System",
992
+ selectLanguage: "Select language",
993
+ selectFrontendModels: "Select models for frontend tasks (multi-select)",
994
+ selectBackendModels: "Select models for backend tasks (multi-select)",
995
+ selectMode: "Select collaboration mode",
996
+ selectWorkflows: "Select workflows to install (multi-select)",
997
+ confirmInstall: "Confirm installation with above configuration?",
998
+ installing: "Installing...",
999
+ installSuccess: "Installation successful!",
1000
+ installFailed: "Installation failed",
1001
+ installCancelled: "Installation cancelled",
1002
+ installedCommands: "Installed Commands:",
1003
+ installedPrompts: "Installed Role Prompts:",
1004
+ installedBinary: "Installed Binary:",
1005
+ installationErrors: "Installation Errors:",
1006
+ pathWarning: "codeagent-wrapper needs to be added to PATH",
1007
+ autoConfigurePathPrompt: "Automatically configure PATH environment variable?",
1008
+ pathConfigured: "PATH has been added to {{file}}",
1009
+ pathAlreadyConfigured: "PATH is already configured in {{file}}",
1010
+ pathConfigFailed: "Auto-configuration failed",
1011
+ restartShellPrompt: "Run the following command to apply changes:",
1012
+ manualConfigInstructions: "Please manually add the following to {{file}}:",
1013
+ windowsPathInstructions: "Windows Users - Manually add to System Environment Variables:",
1014
+ windowsStep1: 'Press Win+X, select "System"',
1015
+ windowsStep2: 'Click "Advanced system settings" \u2192 "Environment Variables"',
1016
+ windowsStep3: 'Find "Path" in User variables, click "Edit", add:',
1017
+ windowsStep4: 'Click "OK" to save, restart terminal',
1018
+ orUsePowerShell: "Or run in PowerShell (Admin):",
1019
+ addToShellConfig: "Add the following command to {{file}} and restart your terminal",
1020
+ configSavedTo: "Config saved to:",
1021
+ validation: {
1022
+ selectAtLeastOne: "Please select at least one model"
1023
+ },
1024
+ summary: {
1025
+ title: "Configuration Summary:",
1026
+ frontendModels: "Frontend Models:",
1027
+ backendModels: "Backend Models:",
1028
+ collaboration: "Collaboration:",
1029
+ workflows: "Workflows:",
1030
+ selected: "selected"
1031
+ },
1032
+ modes: {
1033
+ parallel: "Parallel - Call multiple models simultaneously",
1034
+ smart: "Smart - Auto-select based on task type",
1035
+ sequential: "Sequential - Call models one by one"
1036
+ },
1037
+ models: {
1038
+ codex: "Codex - Backend logic, algorithms, debugging",
1039
+ gemini: "Gemini - Frontend UI, CSS, component design",
1040
+ claude: "Claude - Orchestration, refactoring, documentation"
1041
+ },
1042
+ workflows: {
1043
+ dev: "Full development workflow (/ccg:dev)",
1044
+ frontend: "Frontend tasks (/ccg:frontend)",
1045
+ backend: "Backend tasks (/ccg:backend)",
1046
+ review: "Code review (/ccg:review)",
1047
+ analyze: "Technical analysis (/ccg:analyze)",
1048
+ commit: "Git smart commit (/ccg:commit)",
1049
+ rollback: "Git rollback (/ccg:rollback)",
1050
+ cleanBranches: "Clean branches (/ccg:clean-branches)",
1051
+ worktree: "Worktree management (/ccg:worktree)",
1052
+ init: "Project initialization (/ccg:init)"
1053
+ },
1054
+ aceTool: {
1055
+ title: "ace-tool MCP Configuration",
1056
+ description: "Lightweight codebase retrieval and prompt enhancement tool",
1057
+ getToken: "Get Token",
1058
+ configure: "Configure ace-tool MCP?",
1059
+ baseUrl: "API Base URL:",
1060
+ token: "API Token:",
1061
+ installing: "Configuring ace-tool MCP...",
1062
+ failed: "ace-tool configuration failed (can be configured manually later)"
1063
+ }
1064
+ },
1065
+ menu: {
1066
+ title: "CCG Main Menu",
1067
+ options: {
1068
+ init: "Initialize CCG configuration",
1069
+ update: "Update workflows",
1070
+ uninstall: "Uninstall CCG",
1071
+ help: "Help",
1072
+ exit: "Exit"
1073
+ },
1074
+ help: {
1075
+ title: "CCG Commands:",
1076
+ hint: "For more information, run: npx ccg --help",
1077
+ descriptions: {
1078
+ dev: "Complete 6-phase development workflow",
1079
+ frontend: "Frontend tasks \u2192 Gemini",
1080
+ backend: "Backend tasks \u2192 Codex",
1081
+ review: "Dual-model code review",
1082
+ analyze: "Dual-model technical analysis",
1083
+ commit: "Git smart commit",
1084
+ rollback: "Git interactive rollback"
1085
+ }
1086
+ },
1087
+ uninstall: {
1088
+ confirm: "Are you sure you want to uninstall CCG? This will remove all installed commands and configurations.",
1089
+ alsoRemoveAceTool: "Also remove ace-tool MCP configuration?",
1090
+ uninstalling: "Uninstalling...",
1091
+ success: "Uninstallation successful!",
1092
+ removedCommands: "Removed commands:",
1093
+ removedAceTool: "ace-tool MCP configuration removed",
1094
+ cancelled: "Uninstallation cancelled",
1095
+ failed: "Uninstallation failed"
1096
+ }
1097
+ }
1098
+ };
1099
+ async function initI18n(lang = "zh-CN") {
1100
+ if (!i18n.isInitialized) {
1101
+ await i18n.init({
1102
+ lng: lang,
1103
+ fallbackLng: "en",
1104
+ resources: {
1105
+ "zh-CN": { translation: zhCN, ...zhCN },
1106
+ en: { translation: en, ...en }
1107
+ },
1108
+ interpolation: {
1109
+ escapeValue: false
1013
1110
  }
1014
- } catch (error) {
1015
- result.errors.push(`Failed to remove prompts: ${error}`);
1016
- result.success = false;
1017
- }
1111
+ });
1112
+ } else if (i18n.language !== lang) {
1113
+ await i18n.changeLanguage(lang);
1018
1114
  }
1019
- return result;
1020
1115
  }
1021
- async function uninstallAceTool() {
1116
+ async function changeLanguage(lang) {
1117
+ await i18n.changeLanguage(lang);
1118
+ }
1119
+
1120
+ const CCG_DIR = join(homedir(), ".claude", ".ccg");
1121
+ const CONFIG_FILE = join(CCG_DIR, "config.toml");
1122
+ function getCcgDir() {
1123
+ return CCG_DIR;
1124
+ }
1125
+ function getConfigPath() {
1126
+ return CONFIG_FILE;
1127
+ }
1128
+ async function ensureCcgDir() {
1129
+ await fs.ensureDir(CCG_DIR);
1130
+ }
1131
+ async function readCcgConfig() {
1022
1132
  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
- };
1133
+ if (await fs.pathExists(CONFIG_FILE)) {
1134
+ const content = await fs.readFile(CONFIG_FILE, "utf-8");
1135
+ return parse(content);
1035
1136
  }
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
- };
1137
+ } catch {
1048
1138
  }
1139
+ return null;
1049
1140
  }
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");
1141
+ async function writeCcgConfig(config) {
1142
+ await ensureCcgDir();
1143
+ const content = stringify(config);
1144
+ await fs.writeFile(CONFIG_FILE, content, "utf-8");
1145
+ }
1146
+ function createDefaultConfig(options) {
1147
+ return {
1148
+ general: {
1149
+ version: version,
1150
+ language: options.language,
1151
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
1152
+ },
1153
+ routing: options.routing,
1154
+ workflows: {
1155
+ installed: options.installedWorkflows
1156
+ },
1157
+ paths: {
1158
+ commands: join(homedir(), ".claude", "commands", "ccg"),
1159
+ prompts: join(CCG_DIR, "prompts"),
1160
+ // v1.4.0: 移到配置目录
1161
+ backup: join(CCG_DIR, "backup")
1162
+ },
1163
+ mcp: {
1164
+ provider: options.mcpProvider || "ace-tool",
1165
+ setup_url: "https://augmentcode.com/"
1081
1166
  }
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
- }
1167
+ };
1168
+ }
1169
+ function createDefaultRouting() {
1170
+ return {
1171
+ frontend: {
1172
+ models: ["gemini"],
1173
+ primary: "gemini",
1174
+ strategy: "parallel"
1175
+ },
1176
+ backend: {
1177
+ models: ["codex"],
1178
+ primary: "codex",
1179
+ strategy: "parallel"
1180
+ },
1181
+ review: {
1182
+ models: ["codex", "gemini"],
1183
+ strategy: "parallel"
1184
+ },
1185
+ mode: "smart"
1186
+ };
1094
1187
  }
1095
1188
 
1096
1189
  async function migrateToV1_4_0() {
@@ -1104,8 +1197,6 @@ async function migrateToV1_4_0() {
1104
1197
  const newCcgDir = join(homedir(), ".claude", ".ccg");
1105
1198
  const oldPromptsDir = join(homedir(), ".claude", "prompts", "ccg");
1106
1199
  const newPromptsDir = join(newCcgDir, "prompts");
1107
- const oldConfigFile = join(homedir(), ".claude", "commands", "ccg", "_config.md");
1108
- const newConfigFile = join(newCcgDir, "shared-config.md");
1109
1200
  try {
1110
1201
  await fs.ensureDir(newCcgDir);
1111
1202
  if (await fs.pathExists(oldCcgDir)) {
@@ -1162,23 +1253,6 @@ async function migrateToV1_4_0() {
1162
1253
  } else {
1163
1254
  result.skipped.push("~/.claude/prompts/ccg/ (does not exist, nothing to migrate)");
1164
1255
  }
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
1256
  } catch (error) {
1183
1257
  result.errors.push(`Migration failed: ${error}`);
1184
1258
  result.success = false;
@@ -1198,117 +1272,31 @@ async function needsMigration() {
1198
1272
  async function init(options = {}) {
1199
1273
  console.log();
1200
1274
  console.log(ansis.cyan.bold(` CCG - Claude + Codex + Gemini`));
1201
- console.log(ansis.gray(` ${i18n.t("init:welcome")}`));
1275
+ console.log(ansis.gray(` \u591A\u6A21\u578B\u534F\u4F5C\u5F00\u53D1\u5DE5\u4F5C\u6D41`));
1202
1276
  console.log();
1203
- let language = options.lang || "en";
1204
- if (!options.skipPrompt && !options.lang) {
1205
- const { selectedLang } = await inquirer.prompt([{
1206
- type: "list",
1207
- name: "selectedLang",
1208
- message: i18n.t("init:selectLanguage"),
1209
- choices: [
1210
- { name: "\u4E2D\u6587 (Chinese)", value: "zh-CN" },
1211
- { name: "English", value: "en" }
1212
- ],
1213
- default: "zh-CN"
1214
- }]);
1215
- language = selectedLang;
1216
- await i18n.changeLanguage(language);
1217
- }
1218
- let frontendModels = ["gemini"];
1219
- if (options.frontend) {
1220
- frontendModels = options.frontend.split(",").map((m) => m.trim());
1221
- } else if (!options.skipPrompt) {
1222
- const { selectedFrontend } = await inquirer.prompt([{
1223
- type: "checkbox",
1224
- name: "selectedFrontend",
1225
- message: i18n.t("init:selectFrontendModels"),
1226
- choices: [
1227
- { name: i18n.t("init:models.gemini"), value: "gemini", checked: true },
1228
- { name: i18n.t("init:models.codex"), value: "codex" },
1229
- { name: i18n.t("init:models.claude"), value: "claude" }
1230
- ],
1231
- validate: (answer) => answer.length > 0 || i18n.t("init:validation.selectAtLeastOne")
1232
- }]);
1233
- frontendModels = selectedFrontend;
1234
- }
1235
- let backendModels = ["codex"];
1236
- if (options.backend) {
1237
- backendModels = options.backend.split(",").map((m) => m.trim());
1238
- } else if (!options.skipPrompt) {
1239
- const { selectedBackend } = await inquirer.prompt([{
1240
- type: "checkbox",
1241
- name: "selectedBackend",
1242
- message: i18n.t("init:selectBackendModels"),
1243
- choices: [
1244
- { name: i18n.t("init:models.codex"), value: "codex", checked: true },
1245
- { name: i18n.t("init:models.gemini"), value: "gemini" },
1246
- { name: i18n.t("init:models.claude"), value: "claude" }
1247
- ],
1248
- validate: (answer) => answer.length > 0 || i18n.t("init:validation.selectAtLeastOne")
1249
- }]);
1250
- backendModels = selectedBackend;
1251
- }
1252
- let mode = "smart";
1253
- if (options.mode) {
1254
- mode = options.mode;
1255
- } else if (!options.skipPrompt) {
1256
- const { selectedMode } = await inquirer.prompt([{
1257
- type: "list",
1258
- name: "selectedMode",
1259
- message: i18n.t("init:selectMode"),
1260
- choices: [
1261
- { name: i18n.t("init:modes.smart"), value: "smart" },
1262
- { name: i18n.t("init:modes.parallel"), value: "parallel" },
1263
- { name: i18n.t("init:modes.sequential"), value: "sequential" }
1264
- ],
1265
- default: "smart"
1266
- }]);
1267
- mode = selectedMode;
1268
- }
1269
- const allWorkflows = getWorkflowConfigs();
1270
- let selectedWorkflows = allWorkflows.filter((w) => w.defaultSelected).map((w) => w.id);
1271
- if (options.workflows) {
1272
- if (options.workflows === "all") {
1273
- selectedWorkflows = allWorkflows.map((w) => w.id);
1274
- } else if (options.workflows !== "skip") {
1275
- selectedWorkflows = options.workflows.split(",").map((w) => w.trim());
1276
- }
1277
- } 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
- }))
1287
- }]);
1288
- selectedWorkflows = selected;
1289
- }
1277
+ const language = "zh-CN";
1278
+ const frontendModels = ["gemini"];
1279
+ const backendModels = ["codex"];
1280
+ const mode = "smart";
1281
+ const selectedWorkflows = getAllCommandIds();
1290
1282
  let mcpProvider = "ace-tool";
1291
1283
  let aceToolBaseUrl = "";
1292
1284
  let aceToolToken = "";
1293
1285
  if (!options.skipPrompt) {
1294
1286
  console.log();
1295
- console.log(ansis.cyan.bold(` \u{1F527} MCP \u5DE5\u5177\u9009\u62E9`));
1287
+ console.log(ansis.cyan.bold(` \u{1F527} MCP \u5DE5\u5177\u914D\u7F6E`));
1296
1288
  console.log();
1297
1289
  const { selectedMcp } = await inquirer.prompt([{
1298
1290
  type: "list",
1299
1291
  name: "selectedMcp",
1300
- message: "\u9009\u62E9 MCP \u4EE3\u7801\u68C0\u7D22\u5DE5\u5177",
1292
+ message: "\u662F\u5426\u5B89\u88C5 ace-tool MCP\uFF1F",
1301
1293
  choices: [
1302
1294
  {
1303
- name: `ace-tool ${ansis.gray("(\u63A8\u8350) - \u5F00\u7BB1\u5373\u7528\uFF0C\u542B Prompt \u589E\u5F3A + \u4EE3\u7801\u68C0\u7D22")}`,
1295
+ name: `\u5B89\u88C5 ace-tool ${ansis.gray("(\u63A8\u8350) - \u4E00\u952E\u5B89\u88C5\uFF0C\u542B Prompt \u589E\u5F3A + \u4EE3\u7801\u68C0\u7D22")}`,
1304
1296
  value: "ace-tool"
1305
1297
  },
1306
1298
  {
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")}`,
1299
+ name: `\u8DF3\u8FC7 ${ansis.gray("- \u7A0D\u540E\u624B\u52A8\u914D\u7F6E\uFF08\u53EF\u9009 auggie \u7B49\u5176\u4ED6 MCP\uFF09")}`,
1312
1300
  value: "skip"
1313
1301
  }
1314
1302
  ],
@@ -1319,49 +1307,68 @@ async function init(options = {}) {
1319
1307
  console.log();
1320
1308
  console.log(ansis.cyan.bold(` \u{1F527} ace-tool MCP \u914D\u7F6E`));
1321
1309
  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
1310
  console.log();
1311
+ const { skipToken } = await inquirer.prompt([{
1312
+ type: "confirm",
1313
+ name: "skipToken",
1314
+ message: "\u662F\u5426\u8DF3\u8FC7 Token \u914D\u7F6E\uFF1F\uFF08\u53EF\u7A0D\u540E\u8FD0\u884C npx ccg config mcp \u914D\u7F6E\uFF09",
1315
+ default: false
1316
+ }]);
1317
+ if (!skipToken) {
1318
+ console.log();
1319
+ console.log(ansis.cyan(` \u{1F4D6} \u83B7\u53D6 ace-tool \u8BBF\u95EE\u65B9\u5F0F\uFF1A`));
1320
+ console.log();
1321
+ console.log(` ${ansis.gray("\u2022")} ${ansis.cyan("\u5B98\u65B9\u670D\u52A1")}: ${ansis.underline("https://augmentcode.com/")}`);
1322
+ console.log(` ${ansis.gray("\u6CE8\u518C\u8D26\u53F7\u540E\u83B7\u53D6 Token")}`);
1323
+ console.log();
1324
+ 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")}`);
1325
+ console.log(` ${ansis.gray("linux.do \u793E\u533A\u63D0\u4F9B\u7684\u514D\u8D39\u4E2D\u8F6C\u670D\u52A1")}`);
1326
+ console.log();
1327
+ const aceAnswers = await inquirer.prompt([
1328
+ {
1329
+ type: "input",
1330
+ name: "baseUrl",
1331
+ message: `Base URL ${ansis.gray("(\u4F7F\u7528\u4E2D\u8F6C\u670D\u52A1\u65F6\u5FC5\u586B\uFF0C\u5B98\u65B9\u670D\u52A1\u7559\u7A7A)")}`,
1332
+ default: ""
1333
+ },
1334
+ {
1335
+ type: "password",
1336
+ name: "token",
1337
+ message: `Token ${ansis.gray("(\u5FC5\u586B)")}`,
1338
+ mask: "*",
1339
+ validate: (input) => input.trim() !== "" || "\u8BF7\u8F93\u5165 Token"
1340
+ }
1341
+ ]);
1342
+ aceToolBaseUrl = aceAnswers.baseUrl || "";
1343
+ aceToolToken = aceAnswers.token || "";
1344
+ } else {
1345
+ console.log();
1346
+ console.log(ansis.yellow(` \u2139\uFE0F \u5DF2\u8DF3\u8FC7 Token \u914D\u7F6E`));
1347
+ console.log(ansis.gray(` \u2022 ace-tool MCP \u5C06\u4E0D\u4F1A\u81EA\u52A8\u5B89\u88C5`));
1348
+ console.log(ansis.gray(` \u2022 \u53EF\u7A0D\u540E\u8FD0\u884C ${ansis.cyan("npx ccg config mcp")} \u914D\u7F6E Token`));
1349
+ console.log(ansis.gray(` \u2022 \u83B7\u53D6 Token: ${ansis.cyan("https://augmentcode.com/")}`));
1350
+ console.log();
1351
+ }
1346
1352
  } else {
1347
1353
  console.log();
1348
- console.log(ansis.yellow(` \u2139\uFE0F \u5DF2\u8DF3\u8FC7 MCP \u914D\u7F6E\uFF0C\u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E`));
1354
+ console.log(ansis.yellow(` \u2139\uFE0F \u5DF2\u8DF3\u8FC7 MCP \u914D\u7F6E`));
1355
+ console.log(ansis.gray(` \u2022 \u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1`));
1349
1356
  console.log();
1350
1357
  }
1351
1358
  }
1352
1359
  const routing = {
1353
1360
  frontend: {
1354
1361
  models: frontendModels,
1355
- primary: frontendModels[0],
1356
- strategy: frontendModels.length > 1 ? "parallel" : "fallback"
1362
+ primary: "gemini",
1363
+ strategy: "fallback"
1357
1364
  },
1358
1365
  backend: {
1359
1366
  models: backendModels,
1360
- primary: backendModels[0],
1361
- strategy: backendModels.length > 1 ? "parallel" : "fallback"
1367
+ primary: "codex",
1368
+ strategy: "fallback"
1362
1369
  },
1363
1370
  review: {
1364
- models: [.../* @__PURE__ */ new Set([...frontendModels, ...backendModels])],
1371
+ models: ["codex", "gemini"],
1365
1372
  strategy: "parallel"
1366
1373
  },
1367
1374
  mode
@@ -1370,10 +1377,9 @@ async function init(options = {}) {
1370
1377
  console.log(ansis.yellow("\u2501".repeat(50)));
1371
1378
  console.log(ansis.bold(` ${i18n.t("init:summary.title")}`));
1372
1379
  console.log();
1373
- console.log(` ${ansis.cyan(i18n.t("init:summary.frontendModels"))} ${frontendModels.map((m) => ansis.green(m)).join(", ")}`);
1374
- console.log(` ${ansis.cyan(i18n.t("init:summary.backendModels"))} ${backendModels.map((m) => ansis.blue(m)).join(", ")}`);
1375
- console.log(` ${ansis.cyan(i18n.t("init:summary.collaboration"))} ${ansis.yellow(mode)}`);
1376
- console.log(` ${ansis.cyan(i18n.t("init:summary.workflows"))} ${selectedWorkflows.length} ${i18n.t("init:summary.selected")}`);
1380
+ console.log(` ${ansis.cyan("\u6A21\u578B\u8DEF\u7531")} ${ansis.green("Gemini")} (\u524D\u7AEF) + ${ansis.blue("Codex")} (\u540E\u7AEF)`);
1381
+ console.log(` ${ansis.cyan("\u547D\u4EE4\u6570\u91CF")} ${ansis.yellow(selectedWorkflows.length.toString())} \u4E2A`);
1382
+ console.log(` ${ansis.cyan("MCP \u5DE5\u5177")} ${mcpProvider === "ace-tool" ? aceToolToken ? ansis.green("ace-tool") : ansis.yellow("ace-tool (\u5F85\u914D\u7F6E)") : ansis.gray("\u8DF3\u8FC7")}`);
1377
1383
  console.log(ansis.yellow("\u2501".repeat(50)));
1378
1384
  console.log();
1379
1385
  if (!options.skipPrompt) {
@@ -1428,10 +1434,9 @@ async function init(options = {}) {
1428
1434
  await writeCcgConfig(config);
1429
1435
  const installDir = options.installDir || join(homedir(), ".claude");
1430
1436
  const result = await installWorkflows(selectedWorkflows, installDir, options.force, {
1431
- mcpProvider,
1432
1437
  routing
1433
1438
  });
1434
- if (aceToolBaseUrl || aceToolToken) {
1439
+ if (mcpProvider === "ace-tool" && aceToolToken) {
1435
1440
  spinner.text = i18n.t("init:aceTool.installing");
1436
1441
  const aceResult = await installAceTool({
1437
1442
  baseUrl: aceToolBaseUrl,
@@ -1445,6 +1450,11 @@ async function init(options = {}) {
1445
1450
  spinner.warn(ansis.yellow(i18n.t("init:aceTool.failed")));
1446
1451
  console.log(ansis.gray(` ${aceResult.message}`));
1447
1452
  }
1453
+ } else if (mcpProvider === "ace-tool" && !aceToolToken) {
1454
+ spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
1455
+ console.log();
1456
+ console.log(` ${ansis.yellow("\u26A0")} ace-tool MCP \u672A\u5B89\u88C5 ${ansis.gray("(Token \u672A\u63D0\u4F9B)")}`);
1457
+ console.log(` ${ansis.gray("\u2192")} \u7A0D\u540E\u8FD0\u884C ${ansis.cyan("npx ccg config mcp")} \u5B8C\u6210\u914D\u7F6E`);
1448
1458
  } else {
1449
1459
  spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
1450
1460
  }
@@ -1550,8 +1560,19 @@ ${exportCommand}
1550
1560
  }
1551
1561
  }
1552
1562
  }
1553
- console.log();
1554
- console.log(ansis.gray(` ${i18n.t("init:configSavedTo")} ${getCcgDir()}/config.toml`));
1563
+ if (mcpProvider === "skip" || mcpProvider === "ace-tool" && !aceToolToken) {
1564
+ console.log();
1565
+ console.log(ansis.cyan.bold(` \u{1F4D6} MCP \u670D\u52A1\u9009\u9879`));
1566
+ console.log();
1567
+ 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`));
1568
+ console.log();
1569
+ console.log(` ${ansis.green("1.")} ${ansis.cyan("ace-tool")} ${ansis.gray("(\u63A8\u8350)")}: ${ansis.underline("https://augmentcode.com/")}`);
1570
+ console.log(` ${ansis.gray("\u4E00\u952E\u5B89\u88C5\uFF0C\u542B Prompt \u589E\u5F3A + \u4EE3\u7801\u68C0\u7D22")}`);
1571
+ console.log();
1572
+ 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")}`);
1573
+ console.log(` ${ansis.gray("linux.do \u793E\u533A\u63D0\u4F9B\u7684\u514D\u8D39\u4E2D\u8F6C\u670D\u52A1")}`);
1574
+ console.log();
1575
+ }
1555
1576
  console.log();
1556
1577
  } catch (error) {
1557
1578
  spinner.fail(ansis.red(i18n.t("init:installFailed")));
@@ -1666,18 +1687,86 @@ async function update() {
1666
1687
  console.log(ansis.red(`\u274C \u66F4\u65B0\u5931\u8D25: ${error}`));
1667
1688
  }
1668
1689
  }
1690
+ async function askReconfigureRouting(currentRouting) {
1691
+ console.log();
1692
+ console.log(ansis.cyan.bold("\u{1F527} \u6A21\u578B\u8DEF\u7531\u914D\u7F6E"));
1693
+ console.log();
1694
+ if (currentRouting) {
1695
+ console.log(ansis.gray("\u5F53\u524D\u914D\u7F6E:"));
1696
+ console.log(` ${ansis.cyan("\u524D\u7AEF\u6A21\u578B:")} ${currentRouting.frontend.models.map((m) => ansis.green(m)).join(", ")}`);
1697
+ console.log(` ${ansis.cyan("\u540E\u7AEF\u6A21\u578B:")} ${currentRouting.backend.models.map((m) => ansis.blue(m)).join(", ")}`);
1698
+ console.log();
1699
+ }
1700
+ const { reconfigure } = await inquirer.prompt([{
1701
+ type: "confirm",
1702
+ name: "reconfigure",
1703
+ message: "\u662F\u5426\u91CD\u65B0\u914D\u7F6E\u524D\u7AEF\u548C\u540E\u7AEF\u6A21\u578B\uFF1F",
1704
+ default: false
1705
+ }]);
1706
+ if (!reconfigure) {
1707
+ return null;
1708
+ }
1709
+ console.log();
1710
+ const { selectedFrontend } = await inquirer.prompt([{
1711
+ type: "checkbox",
1712
+ name: "selectedFrontend",
1713
+ message: i18n.t("init:selectFrontendModels"),
1714
+ choices: [
1715
+ { name: "Gemini", value: "gemini", checked: currentRouting?.frontend.models.includes("gemini") ?? true },
1716
+ { name: "Claude", value: "claude", checked: currentRouting?.frontend.models.includes("claude") ?? false },
1717
+ { name: "Codex", value: "codex", checked: currentRouting?.frontend.models.includes("codex") ?? false }
1718
+ ],
1719
+ validate: (answer) => answer.length > 0 || i18n.t("init:validation.selectAtLeastOne")
1720
+ }]);
1721
+ const { selectedBackend } = await inquirer.prompt([{
1722
+ type: "checkbox",
1723
+ name: "selectedBackend",
1724
+ message: i18n.t("init:selectBackendModels"),
1725
+ choices: [
1726
+ { name: "Codex", value: "codex", checked: currentRouting?.backend.models.includes("codex") ?? true },
1727
+ { name: "Gemini", value: "gemini", checked: currentRouting?.backend.models.includes("gemini") ?? false },
1728
+ { name: "Claude", value: "claude", checked: currentRouting?.backend.models.includes("claude") ?? false }
1729
+ ],
1730
+ validate: (answer) => answer.length > 0 || i18n.t("init:validation.selectAtLeastOne")
1731
+ }]);
1732
+ const frontendModels = selectedFrontend;
1733
+ const backendModels = selectedBackend;
1734
+ const newRouting = {
1735
+ frontend: {
1736
+ models: frontendModels,
1737
+ primary: frontendModels[0],
1738
+ strategy: frontendModels.length > 1 ? "parallel" : "fallback"
1739
+ },
1740
+ backend: {
1741
+ models: backendModels,
1742
+ primary: backendModels[0],
1743
+ strategy: backendModels.length > 1 ? "parallel" : "fallback"
1744
+ },
1745
+ review: {
1746
+ models: [.../* @__PURE__ */ new Set([...frontendModels, ...backendModels])],
1747
+ strategy: "parallel"
1748
+ },
1749
+ mode: currentRouting?.mode || "smart"
1750
+ };
1751
+ console.log();
1752
+ console.log(ansis.green("\u2713 \u65B0\u914D\u7F6E:"));
1753
+ console.log(` ${ansis.cyan("\u524D\u7AEF\u6A21\u578B:")} ${frontendModels.map((m) => ansis.green(m)).join(", ")}`);
1754
+ console.log(` ${ansis.cyan("\u540E\u7AEF\u6A21\u578B:")} ${backendModels.map((m) => ansis.blue(m)).join(", ")}`);
1755
+ console.log();
1756
+ return newRouting;
1757
+ }
1669
1758
  async function performUpdate(fromVersion, toVersion) {
1670
1759
  console.log();
1671
1760
  console.log(ansis.yellow.bold("\u2699\uFE0F \u5F00\u59CB\u66F4\u65B0..."));
1672
1761
  console.log();
1762
+ const config = await readCcgConfig();
1763
+ const newRouting = await askReconfigureRouting(config?.routing);
1673
1764
  const spinner = ora("\u66F4\u65B0\u547D\u4EE4\u6A21\u677F\u548C\u63D0\u793A\u8BCD...").start();
1674
1765
  try {
1675
- const config = await readCcgConfig();
1676
1766
  const workflows = config?.workflows?.installed || [];
1677
1767
  const installDir = join(homedir(), ".claude");
1678
1768
  const result = await installWorkflows(workflows, installDir, true, {
1679
- mcpProvider: config?.mcp?.provider || "auggie",
1680
- routing: config?.routing
1769
+ routing: newRouting || config?.routing
1681
1770
  });
1682
1771
  if (result.success) {
1683
1772
  spinner.succeed("\u547D\u4EE4\u6A21\u677F\u548C\u63D0\u793A\u8BCD\u66F4\u65B0\u6210\u529F");
@@ -1688,8 +1777,15 @@ async function performUpdate(fromVersion, toVersion) {
1688
1777
  }
1689
1778
  if (config) {
1690
1779
  config.general.version = toVersion;
1780
+ if (newRouting) {
1781
+ config.routing = newRouting;
1782
+ }
1691
1783
  await writeCcgConfig(config);
1692
1784
  }
1785
+ if (newRouting) {
1786
+ console.log();
1787
+ console.log(ansis.green("\u2713 \u6A21\u578B\u8DEF\u7531\u914D\u7F6E\u5DF2\u66F4\u65B0"));
1788
+ }
1693
1789
  } else {
1694
1790
  spinner.fail("\u66F4\u65B0\u5931\u8D25");
1695
1791
  console.log(ansis.red("\u90E8\u5206\u6587\u4EF6\u66F4\u65B0\u5931\u8D25:"));
@@ -1722,6 +1818,7 @@ async function showMainMenu() {
1722
1818
  choices: [
1723
1819
  { name: `${ansis.green("\u279C")} ${i18n.t("menu:options.init")}`, value: "init" },
1724
1820
  { name: `${ansis.blue("\u279C")} ${i18n.t("menu:options.update")}`, value: "update" },
1821
+ { name: `${ansis.cyan("\u2699")} \u914D\u7F6E MCP`, value: "config-mcp" },
1725
1822
  { name: `${ansis.magenta("\u279C")} ${i18n.t("menu:options.uninstall")}`, value: "uninstall" },
1726
1823
  { name: `${ansis.yellow("?")} ${i18n.t("menu:options.help")}`, value: "help" },
1727
1824
  new inquirer.Separator(),
@@ -1735,6 +1832,9 @@ async function showMainMenu() {
1735
1832
  case "update":
1736
1833
  await update();
1737
1834
  break;
1835
+ case "config-mcp":
1836
+ await configMcp();
1837
+ break;
1738
1838
  case "uninstall":
1739
1839
  await uninstall();
1740
1840
  break;
@@ -1792,6 +1892,23 @@ async function uninstall() {
1792
1892
  console.log(` ${ansis.gray("\u2022")} /ccg:${cmd}`);
1793
1893
  }
1794
1894
  }
1895
+ if (result.removedAgents.length > 0) {
1896
+ console.log();
1897
+ console.log(ansis.cyan("\u5DF2\u79FB\u9664\u5B50\u667A\u80FD\u4F53:"));
1898
+ for (const agent of result.removedAgents) {
1899
+ console.log(` ${ansis.gray("\u2022")} ${agent}`);
1900
+ }
1901
+ }
1902
+ if (result.removedSkills.length > 0) {
1903
+ console.log();
1904
+ console.log(ansis.cyan("\u5DF2\u79FB\u9664 Skills:"));
1905
+ console.log(` ${ansis.gray("\u2022")} multi-model-collaboration`);
1906
+ }
1907
+ if (result.removedBin) {
1908
+ console.log();
1909
+ console.log(ansis.cyan("\u5DF2\u79FB\u9664\u4E8C\u8FDB\u5236\u6587\u4EF6:"));
1910
+ console.log(` ${ansis.gray("\u2022")} codeagent-wrapper`);
1911
+ }
1795
1912
  } else {
1796
1913
  console.log(ansis.red(i18n.t("menu:uninstall.failed")));
1797
1914
  for (const error of result.errors) {
@@ -1809,4 +1926,4 @@ async function uninstall() {
1809
1926
  console.log();
1810
1927
  }
1811
1928
 
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 };
1929
+ 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 };