ccg-workflow 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +434 -0
  3. package/bin/ccg.mjs +2 -0
  4. package/bin/codeagent-wrapper-darwin-amd64 +0 -0
  5. package/bin/codeagent-wrapper-darwin-arm64 +0 -0
  6. package/bin/codeagent-wrapper-linux-amd64 +0 -0
  7. package/bin/codeagent-wrapper-windows-amd64.exe +0 -0
  8. package/dist/cli.d.mts +1 -0
  9. package/dist/cli.d.ts +1 -0
  10. package/dist/cli.mjs +97 -0
  11. package/dist/index.d.mts +134 -0
  12. package/dist/index.d.ts +134 -0
  13. package/dist/index.mjs +10 -0
  14. package/dist/shared/ccg-workflow.D_RkPyZ0.mjs +1117 -0
  15. package/package.json +63 -0
  16. package/prompts/claude/analyzer.md +59 -0
  17. package/prompts/claude/architect.md +54 -0
  18. package/prompts/claude/debugger.md +71 -0
  19. package/prompts/claude/optimizer.md +73 -0
  20. package/prompts/claude/reviewer.md +63 -0
  21. package/prompts/claude/tester.md +69 -0
  22. package/prompts/codex/analyzer.md +50 -0
  23. package/prompts/codex/architect.md +46 -0
  24. package/prompts/codex/debugger.md +66 -0
  25. package/prompts/codex/optimizer.md +74 -0
  26. package/prompts/codex/reviewer.md +66 -0
  27. package/prompts/codex/tester.md +55 -0
  28. package/prompts/gemini/analyzer.md +53 -0
  29. package/prompts/gemini/debugger.md +70 -0
  30. package/prompts/gemini/frontend.md +56 -0
  31. package/prompts/gemini/optimizer.md +77 -0
  32. package/prompts/gemini/reviewer.md +73 -0
  33. package/prompts/gemini/tester.md +61 -0
  34. package/templates/commands/_config.md +85 -0
  35. package/templates/commands/analyze.md +73 -0
  36. package/templates/commands/backend.md +81 -0
  37. package/templates/commands/bugfix.md +55 -0
  38. package/templates/commands/clean-branches.md +102 -0
  39. package/templates/commands/code.md +169 -0
  40. package/templates/commands/commit.md +158 -0
  41. package/templates/commands/debug.md +104 -0
  42. package/templates/commands/dev.md +153 -0
  43. package/templates/commands/enhance.md +49 -0
  44. package/templates/commands/frontend.md +80 -0
  45. package/templates/commands/init.md +53 -0
  46. package/templates/commands/optimize.md +69 -0
  47. package/templates/commands/review.md +85 -0
  48. package/templates/commands/rollback.md +90 -0
  49. package/templates/commands/test.md +53 -0
  50. package/templates/commands/think.md +73 -0
  51. package/templates/commands/worktree.md +276 -0
  52. package/templates/prompts/claude/analyzer.md +59 -0
  53. package/templates/prompts/claude/architect.md +54 -0
  54. package/templates/prompts/claude/debugger.md +71 -0
  55. package/templates/prompts/claude/optimizer.md +73 -0
  56. package/templates/prompts/claude/reviewer.md +63 -0
  57. package/templates/prompts/claude/tester.md +69 -0
  58. package/templates/prompts/codex/analyzer.md +50 -0
  59. package/templates/prompts/codex/architect.md +46 -0
  60. package/templates/prompts/codex/debugger.md +66 -0
  61. package/templates/prompts/codex/optimizer.md +74 -0
  62. package/templates/prompts/codex/reviewer.md +66 -0
  63. package/templates/prompts/codex/tester.md +55 -0
  64. package/templates/prompts/gemini/analyzer.md +53 -0
  65. package/templates/prompts/gemini/debugger.md +70 -0
  66. package/templates/prompts/gemini/frontend.md +56 -0
  67. package/templates/prompts/gemini/optimizer.md +77 -0
  68. package/templates/prompts/gemini/reviewer.md +73 -0
  69. package/templates/prompts/gemini/tester.md +61 -0
@@ -0,0 +1,1117 @@
1
+ import ansis from 'ansis';
2
+ import inquirer from 'inquirer';
3
+ import { homedir } from 'node:os';
4
+ import { join, dirname } from 'pathe';
5
+ import i18next from 'i18next';
6
+ import fs from 'fs-extra';
7
+ import { fileURLToPath } from 'node:url';
8
+ import ora from 'ora';
9
+ import { parse, stringify } from 'smol-toml';
10
+
11
+ const i18n = i18next;
12
+ const zhCN = {
13
+ common: {
14
+ yes: "\u662F",
15
+ no: "\u5426",
16
+ confirm: "\u786E\u8BA4",
17
+ cancel: "\u53D6\u6D88",
18
+ back: "\u8FD4\u56DE",
19
+ exit: "\u9000\u51FA",
20
+ success: "\u6210\u529F",
21
+ error: "\u9519\u8BEF",
22
+ warning: "\u8B66\u544A",
23
+ info: "\u4FE1\u606F",
24
+ loading: "\u52A0\u8F7D\u4E2D...",
25
+ processing: "\u5904\u7406\u4E2D...",
26
+ completed: "\u5DF2\u5B8C\u6210",
27
+ failed: "\u5931\u8D25"
28
+ },
29
+ cli: {
30
+ help: {
31
+ commands: "\u547D\u4EE4",
32
+ commandDescriptions: {
33
+ showMenu: "\u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355\uFF08\u9ED8\u8BA4\uFF09",
34
+ initConfig: "\u521D\u59CB\u5316 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF"
35
+ },
36
+ shortcuts: "\u5FEB\u6377\u65B9\u5F0F:",
37
+ shortcutDescriptions: {
38
+ quickInit: "\u5FEB\u901F\u521D\u59CB\u5316"
39
+ },
40
+ options: "\u9009\u9879",
41
+ optionDescriptions: {
42
+ displayLanguage: "\u663E\u793A\u8BED\u8A00",
43
+ forceOverwrite: "\u5F3A\u5236\u8986\u76D6\u73B0\u6709\u914D\u7F6E",
44
+ displayHelp: "\u663E\u793A\u5E2E\u52A9\u4FE1\u606F",
45
+ displayVersion: "\u663E\u793A\u7248\u672C\u53F7",
46
+ skipAllPrompts: "\u8DF3\u8FC7\u6240\u6709\u4EA4\u4E92\u5F0F\u63D0\u793A\uFF08\u975E\u4EA4\u4E92\u6A21\u5F0F\uFF09",
47
+ frontendModels: "\u524D\u7AEF\u6A21\u578B\uFF08\u9017\u53F7\u5206\u9694\uFF09",
48
+ backendModels: "\u540E\u7AEF\u6A21\u578B\uFF08\u9017\u53F7\u5206\u9694\uFF09",
49
+ collaborationMode: "\u534F\u4F5C\u6A21\u5F0F (parallel/smart/sequential)",
50
+ workflows: "\u8981\u5B89\u88C5\u7684\u5DE5\u4F5C\u6D41",
51
+ installDir: "\u5B89\u88C5\u76EE\u5F55"
52
+ },
53
+ nonInteractiveMode: "\u975E\u4EA4\u4E92\u6A21\u5F0F:",
54
+ examples: "\u793A\u4F8B",
55
+ exampleDescriptions: {
56
+ showInteractiveMenu: "\u663E\u793A\u4EA4\u4E92\u5F0F\u83DC\u5355",
57
+ runFullInitialization: "\u8FD0\u884C\u5B8C\u6574\u521D\u59CB\u5316",
58
+ customModels: "\u81EA\u5B9A\u4E49\u6A21\u578B\u914D\u7F6E",
59
+ parallelMode: "\u4F7F\u7528\u5E76\u884C\u534F\u4F5C\u6A21\u5F0F"
60
+ }
61
+ }
62
+ },
63
+ init: {
64
+ welcome: "\u6B22\u8FCE\u4F7F\u7528 CCG \u591A\u6A21\u578B\u534F\u4F5C\u7CFB\u7EDF",
65
+ selectLanguage: "\u8BF7\u9009\u62E9\u8BED\u8A00",
66
+ selectFrontendModels: "\u9009\u62E9\u524D\u7AEF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u53EF\u591A\u9009\uFF09",
67
+ selectBackendModels: "\u9009\u62E9\u540E\u7AEF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u53EF\u591A\u9009\uFF09",
68
+ selectMode: "\u9009\u62E9\u534F\u4F5C\u6A21\u5F0F",
69
+ selectWorkflows: "\u9009\u62E9\u8981\u5B89\u88C5\u7684\u5DE5\u4F5C\u6D41\uFF08\u53EF\u591A\u9009\uFF09",
70
+ confirmInstall: "\u786E\u8BA4\u5B89\u88C5\u4EE5\u4E0A\u914D\u7F6E\uFF1F",
71
+ installing: "\u6B63\u5728\u5B89\u88C5...",
72
+ installSuccess: "\u5B89\u88C5\u6210\u529F\uFF01",
73
+ installFailed: "\u5B89\u88C5\u5931\u8D25",
74
+ installCancelled: "\u5B89\u88C5\u5DF2\u53D6\u6D88",
75
+ installedCommands: "\u5DF2\u5B89\u88C5\u547D\u4EE4:",
76
+ installedPrompts: "\u5DF2\u5B89\u88C5\u89D2\u8272\u63D0\u793A\u8BCD:",
77
+ configSavedTo: "\u914D\u7F6E\u5DF2\u4FDD\u5B58\u81F3:",
78
+ validation: {
79
+ selectAtLeastOne: "\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u6A21\u578B"
80
+ },
81
+ summary: {
82
+ title: "\u914D\u7F6E\u6458\u8981:",
83
+ frontendModels: "\u524D\u7AEF\u6A21\u578B:",
84
+ backendModels: "\u540E\u7AEF\u6A21\u578B:",
85
+ collaboration: "\u534F\u4F5C\u6A21\u5F0F:",
86
+ workflows: "\u5DE5\u4F5C\u6D41:",
87
+ selected: "\u4E2A\u5DF2\u9009\u62E9"
88
+ },
89
+ modes: {
90
+ parallel: "\u5E76\u884C\u6A21\u5F0F - \u540C\u65F6\u8C03\u7528\u591A\u4E2A\u6A21\u578B",
91
+ smart: "\u667A\u80FD\u6A21\u5F0F - \u6839\u636E\u4EFB\u52A1\u7C7B\u578B\u81EA\u52A8\u9009\u62E9",
92
+ sequential: "\u987A\u5E8F\u6A21\u5F0F - \u4F9D\u6B21\u8C03\u7528\u6A21\u578B"
93
+ },
94
+ models: {
95
+ codex: "Codex - \u64C5\u957F\u540E\u7AEF\u903B\u8F91\u3001\u7B97\u6CD5\u3001\u8C03\u8BD5",
96
+ gemini: "Gemini - \u64C5\u957F\u524D\u7AEFUI\u3001CSS\u3001\u7EC4\u4EF6\u8BBE\u8BA1",
97
+ claude: "Claude - \u64C5\u957F\u7F16\u6392\u3001\u91CD\u6784\u3001\u6587\u6863\u751F\u6210"
98
+ },
99
+ workflows: {
100
+ dev: "\u5B8C\u6574\u5F00\u53D1\u5DE5\u4F5C\u6D41 (/ccg:dev)",
101
+ frontend: "\u524D\u7AEF\u4EFB\u52A1 (/ccg:frontend)",
102
+ backend: "\u540E\u7AEF\u4EFB\u52A1 (/ccg:backend)",
103
+ review: "\u4EE3\u7801\u5BA1\u67E5 (/ccg:review)",
104
+ analyze: "\u6280\u672F\u5206\u6790 (/ccg:analyze)",
105
+ commit: "Git \u667A\u80FD\u63D0\u4EA4 (/ccg:commit)",
106
+ rollback: "Git \u56DE\u6EDA (/ccg:rollback)",
107
+ cleanBranches: "\u6E05\u7406\u5206\u652F (/ccg:clean-branches)",
108
+ worktree: "Worktree \u7BA1\u7406 (/ccg:worktree)",
109
+ init: "\u9879\u76EE\u521D\u59CB\u5316 (/ccg:init)"
110
+ },
111
+ aceTool: {
112
+ title: "ace-tool MCP \u914D\u7F6E",
113
+ description: "\u8F7B\u91CF\u7EA7\u4EE3\u7801\u68C0\u7D22\u548C Prompt \u589E\u5F3A\u5DE5\u5177",
114
+ getToken: "\u83B7\u53D6 Token",
115
+ configure: "\u662F\u5426\u914D\u7F6E ace-tool MCP\uFF1F",
116
+ baseUrl: "API Base URL:",
117
+ token: "API Token:",
118
+ installing: "\u6B63\u5728\u914D\u7F6E ace-tool MCP...",
119
+ failed: "ace-tool \u914D\u7F6E\u5931\u8D25\uFF08\u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\uFF09"
120
+ }
121
+ },
122
+ menu: {
123
+ title: "CCG \u4E3B\u83DC\u5355",
124
+ options: {
125
+ init: "\u521D\u59CB\u5316 CCG \u914D\u7F6E",
126
+ update: "\u66F4\u65B0\u5DE5\u4F5C\u6D41",
127
+ uninstall: "\u5378\u8F7D CCG",
128
+ help: "\u5E2E\u52A9",
129
+ exit: "\u9000\u51FA"
130
+ },
131
+ help: {
132
+ title: "CCG \u547D\u4EE4:",
133
+ hint: "\u66F4\u591A\u4FE1\u606F\u8BF7\u8FD0\u884C: npx ccg --help",
134
+ descriptions: {
135
+ dev: "\u5B8C\u6574\u516D\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41",
136
+ frontend: "\u524D\u7AEF\u4EFB\u52A1 \u2192 Gemini",
137
+ backend: "\u540E\u7AEF\u4EFB\u52A1 \u2192 Codex",
138
+ review: "\u53CC\u6A21\u578B\u4EE3\u7801\u5BA1\u67E5",
139
+ analyze: "\u53CC\u6A21\u578B\u6280\u672F\u5206\u6790",
140
+ commit: "Git \u667A\u80FD\u63D0\u4EA4",
141
+ rollback: "Git \u4EA4\u4E92\u5F0F\u56DE\u6EDA"
142
+ }
143
+ },
144
+ uninstall: {
145
+ 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",
146
+ alsoRemoveAceTool: "\u540C\u65F6\u79FB\u9664 ace-tool MCP \u914D\u7F6E\uFF1F",
147
+ uninstalling: "\u6B63\u5728\u5378\u8F7D...",
148
+ success: "\u5378\u8F7D\u6210\u529F\uFF01",
149
+ removedCommands: "\u5DF2\u79FB\u9664\u547D\u4EE4:",
150
+ removedAceTool: "ace-tool MCP \u914D\u7F6E\u5DF2\u79FB\u9664",
151
+ cancelled: "\u5378\u8F7D\u5DF2\u53D6\u6D88",
152
+ failed: "\u5378\u8F7D\u5931\u8D25"
153
+ }
154
+ }
155
+ };
156
+ const en = {
157
+ common: {
158
+ yes: "Yes",
159
+ no: "No",
160
+ confirm: "Confirm",
161
+ cancel: "Cancel",
162
+ back: "Back",
163
+ exit: "Exit",
164
+ success: "Success",
165
+ error: "Error",
166
+ warning: "Warning",
167
+ info: "Info",
168
+ loading: "Loading...",
169
+ processing: "Processing...",
170
+ completed: "Completed",
171
+ failed: "Failed"
172
+ },
173
+ cli: {
174
+ help: {
175
+ commands: "Commands",
176
+ commandDescriptions: {
177
+ showMenu: "Show interactive menu (default)",
178
+ initConfig: "Initialize CCG multi-model collaboration system"
179
+ },
180
+ shortcuts: "Shortcuts:",
181
+ shortcutDescriptions: {
182
+ quickInit: "Quick init"
183
+ },
184
+ options: "Options",
185
+ optionDescriptions: {
186
+ displayLanguage: "Display language",
187
+ forceOverwrite: "Force overwrite existing configuration",
188
+ displayHelp: "Display help",
189
+ displayVersion: "Display version",
190
+ skipAllPrompts: "Skip all interactive prompts (non-interactive mode)",
191
+ frontendModels: "Frontend models (comma-separated)",
192
+ backendModels: "Backend models (comma-separated)",
193
+ collaborationMode: "Collaboration mode (parallel/smart/sequential)",
194
+ workflows: "Workflows to install",
195
+ installDir: "Installation directory"
196
+ },
197
+ nonInteractiveMode: "Non-interactive mode:",
198
+ examples: "Examples",
199
+ exampleDescriptions: {
200
+ showInteractiveMenu: "Show interactive menu",
201
+ runFullInitialization: "Run full initialization",
202
+ customModels: "Custom model configuration",
203
+ parallelMode: "Use parallel collaboration mode"
204
+ }
205
+ }
206
+ },
207
+ init: {
208
+ welcome: "Welcome to CCG Multi-Model Collaboration System",
209
+ selectLanguage: "Select language",
210
+ selectFrontendModels: "Select models for frontend tasks (multi-select)",
211
+ selectBackendModels: "Select models for backend tasks (multi-select)",
212
+ selectMode: "Select collaboration mode",
213
+ selectWorkflows: "Select workflows to install (multi-select)",
214
+ confirmInstall: "Confirm installation with above configuration?",
215
+ installing: "Installing...",
216
+ installSuccess: "Installation successful!",
217
+ installFailed: "Installation failed",
218
+ installCancelled: "Installation cancelled",
219
+ installedCommands: "Installed Commands:",
220
+ installedPrompts: "Installed Role Prompts:",
221
+ configSavedTo: "Config saved to:",
222
+ validation: {
223
+ selectAtLeastOne: "Please select at least one model"
224
+ },
225
+ summary: {
226
+ title: "Configuration Summary:",
227
+ frontendModels: "Frontend Models:",
228
+ backendModels: "Backend Models:",
229
+ collaboration: "Collaboration:",
230
+ workflows: "Workflows:",
231
+ selected: "selected"
232
+ },
233
+ modes: {
234
+ parallel: "Parallel - Call multiple models simultaneously",
235
+ smart: "Smart - Auto-select based on task type",
236
+ sequential: "Sequential - Call models one by one"
237
+ },
238
+ models: {
239
+ codex: "Codex - Backend logic, algorithms, debugging",
240
+ gemini: "Gemini - Frontend UI, CSS, component design",
241
+ claude: "Claude - Orchestration, refactoring, documentation"
242
+ },
243
+ workflows: {
244
+ dev: "Full development workflow (/ccg:dev)",
245
+ frontend: "Frontend tasks (/ccg:frontend)",
246
+ backend: "Backend tasks (/ccg:backend)",
247
+ review: "Code review (/ccg:review)",
248
+ analyze: "Technical analysis (/ccg:analyze)",
249
+ commit: "Git smart commit (/ccg:commit)",
250
+ rollback: "Git rollback (/ccg:rollback)",
251
+ cleanBranches: "Clean branches (/ccg:clean-branches)",
252
+ worktree: "Worktree management (/ccg:worktree)",
253
+ init: "Project initialization (/ccg:init)"
254
+ },
255
+ aceTool: {
256
+ title: "ace-tool MCP Configuration",
257
+ description: "Lightweight codebase retrieval and prompt enhancement tool",
258
+ getToken: "Get Token",
259
+ configure: "Configure ace-tool MCP?",
260
+ baseUrl: "API Base URL:",
261
+ token: "API Token:",
262
+ installing: "Configuring ace-tool MCP...",
263
+ failed: "ace-tool configuration failed (can be configured manually later)"
264
+ }
265
+ },
266
+ menu: {
267
+ title: "CCG Main Menu",
268
+ options: {
269
+ init: "Initialize CCG configuration",
270
+ update: "Update workflows",
271
+ uninstall: "Uninstall CCG",
272
+ help: "Help",
273
+ exit: "Exit"
274
+ },
275
+ help: {
276
+ title: "CCG Commands:",
277
+ hint: "For more information, run: npx ccg --help",
278
+ descriptions: {
279
+ dev: "Complete 6-phase development workflow",
280
+ frontend: "Frontend tasks \u2192 Gemini",
281
+ backend: "Backend tasks \u2192 Codex",
282
+ review: "Dual-model code review",
283
+ analyze: "Dual-model technical analysis",
284
+ commit: "Git smart commit",
285
+ rollback: "Git interactive rollback"
286
+ }
287
+ },
288
+ uninstall: {
289
+ confirm: "Are you sure you want to uninstall CCG? This will remove all installed commands and configurations.",
290
+ alsoRemoveAceTool: "Also remove ace-tool MCP configuration?",
291
+ uninstalling: "Uninstalling...",
292
+ success: "Uninstallation successful!",
293
+ removedCommands: "Removed commands:",
294
+ removedAceTool: "ace-tool MCP configuration removed",
295
+ cancelled: "Uninstallation cancelled",
296
+ failed: "Uninstallation failed"
297
+ }
298
+ }
299
+ };
300
+ async function initI18n(lang = "en") {
301
+ if (!i18n.isInitialized) {
302
+ await i18n.init({
303
+ lng: lang,
304
+ fallbackLng: "en",
305
+ resources: {
306
+ "zh-CN": { translation: zhCN, ...zhCN },
307
+ en: { translation: en, ...en }
308
+ },
309
+ interpolation: {
310
+ escapeValue: false
311
+ }
312
+ });
313
+ } else if (i18n.language !== lang) {
314
+ await i18n.changeLanguage(lang);
315
+ }
316
+ }
317
+ async function changeLanguage(lang) {
318
+ await i18n.changeLanguage(lang);
319
+ }
320
+
321
+ const CCG_DIR = join(homedir(), ".ccg");
322
+ const CONFIG_FILE = join(CCG_DIR, "config.toml");
323
+ function getCcgDir() {
324
+ return CCG_DIR;
325
+ }
326
+ function getConfigPath() {
327
+ return CONFIG_FILE;
328
+ }
329
+ async function ensureCcgDir() {
330
+ await fs.ensureDir(CCG_DIR);
331
+ }
332
+ async function readCcgConfig() {
333
+ try {
334
+ if (await fs.pathExists(CONFIG_FILE)) {
335
+ const content = await fs.readFile(CONFIG_FILE, "utf-8");
336
+ return parse(content);
337
+ }
338
+ } catch {
339
+ }
340
+ return null;
341
+ }
342
+ async function writeCcgConfig(config) {
343
+ await ensureCcgDir();
344
+ const content = stringify(config);
345
+ await fs.writeFile(CONFIG_FILE, content, "utf-8");
346
+ }
347
+ function createDefaultConfig(options) {
348
+ return {
349
+ general: {
350
+ version: "1.0.0",
351
+ language: options.language,
352
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
353
+ },
354
+ routing: options.routing,
355
+ workflows: {
356
+ installed: options.installedWorkflows
357
+ },
358
+ paths: {
359
+ commands: join(homedir(), ".claude", "commands", "ccg"),
360
+ prompts: join(homedir(), ".claude", "prompts", "ccg"),
361
+ backup: join(CCG_DIR, "backup")
362
+ }
363
+ };
364
+ }
365
+ function createDefaultRouting() {
366
+ return {
367
+ frontend: {
368
+ models: ["gemini"],
369
+ primary: "gemini",
370
+ strategy: "parallel"
371
+ },
372
+ backend: {
373
+ models: ["codex"],
374
+ primary: "codex",
375
+ strategy: "parallel"
376
+ },
377
+ review: {
378
+ models: ["codex", "gemini"],
379
+ strategy: "parallel"
380
+ },
381
+ mode: "smart"
382
+ };
383
+ }
384
+
385
+ const __filename$1 = fileURLToPath(import.meta.url);
386
+ const __dirname$1 = dirname(__filename$1);
387
+ function findPackageRoot(startDir) {
388
+ let dir = startDir;
389
+ for (let i = 0; i < 5; i++) {
390
+ if (fs.existsSync(join(dir, "package.json"))) {
391
+ return dir;
392
+ }
393
+ dir = dirname(dir);
394
+ }
395
+ return startDir;
396
+ }
397
+ const PACKAGE_ROOT = findPackageRoot(__dirname$1);
398
+ const WORKFLOW_CONFIGS = [
399
+ {
400
+ id: "dev",
401
+ name: "\u5B8C\u6574\u5F00\u53D1\u5DE5\u4F5C\u6D41",
402
+ nameEn: "Full Development Workflow",
403
+ category: "development",
404
+ commands: ["dev"],
405
+ defaultSelected: true,
406
+ order: 1,
407
+ 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",
408
+ descriptionEn: "Full 6-phase development workflow (Prompt enhancement \u2192 Context retrieval \u2192 Multi-model analysis \u2192 Prototype \u2192 Implementation \u2192 Audit)"
409
+ },
410
+ {
411
+ id: "code",
412
+ name: "\u667A\u80FD\u4EE3\u7801\u751F\u6210",
413
+ nameEn: "Smart Code Generation",
414
+ category: "development",
415
+ commands: ["code"],
416
+ defaultSelected: true,
417
+ order: 2,
418
+ description: "\u591A\u6A21\u578B\u4EE3\u7801\u751F\u6210\uFF08\u667A\u80FD\u8DEF\u7531\uFF1A\u524D\u7AEF\u2192Gemini\uFF0C\u540E\u7AEF\u2192Codex\uFF09",
419
+ descriptionEn: "Multi-model code generation (smart routing: frontend\u2192Gemini, backend\u2192Codex)"
420
+ },
421
+ {
422
+ id: "frontend",
423
+ name: "\u524D\u7AEF\u4EFB\u52A1",
424
+ nameEn: "Frontend Tasks",
425
+ category: "development",
426
+ commands: ["frontend"],
427
+ defaultSelected: true,
428
+ order: 3,
429
+ description: "\u524D\u7AEF/UI/\u6837\u5F0F\u4EFB\u52A1\uFF0C\u81EA\u52A8\u8DEF\u7531\u5230 Gemini",
430
+ descriptionEn: "Frontend/UI/style tasks, auto-route to Gemini"
431
+ },
432
+ {
433
+ id: "backend",
434
+ name: "\u540E\u7AEF\u4EFB\u52A1",
435
+ nameEn: "Backend Tasks",
436
+ category: "development",
437
+ commands: ["backend"],
438
+ defaultSelected: true,
439
+ order: 4,
440
+ description: "\u540E\u7AEF/\u903B\u8F91/\u7B97\u6CD5\u4EFB\u52A1\uFF0C\u81EA\u52A8\u8DEF\u7531\u5230 Codex",
441
+ descriptionEn: "Backend/logic/algorithm tasks, auto-route to Codex"
442
+ },
443
+ {
444
+ id: "review",
445
+ name: "\u4EE3\u7801\u5BA1\u67E5",
446
+ nameEn: "Code Review",
447
+ category: "development",
448
+ commands: ["review"],
449
+ defaultSelected: true,
450
+ order: 5,
451
+ description: "\u53CC\u6A21\u578B\u4EE3\u7801\u5BA1\u67E5\uFF08Codex + Gemini \u5E76\u884C\uFF09\uFF0C\u65E0\u53C2\u6570\u65F6\u81EA\u52A8\u5BA1\u67E5 git diff",
452
+ descriptionEn: "Dual-model code review (Codex + Gemini parallel), auto-review git diff when no args"
453
+ },
454
+ {
455
+ id: "analyze",
456
+ name: "\u6280\u672F\u5206\u6790",
457
+ nameEn: "Technical Analysis",
458
+ category: "development",
459
+ commands: ["analyze"],
460
+ defaultSelected: true,
461
+ order: 6,
462
+ description: "\u53CC\u6A21\u578B\u6280\u672F\u5206\u6790\uFF08Codex + Gemini \u5E76\u884C\uFF09\uFF0C\u4EA4\u53C9\u9A8C\u8BC1\u540E\u7EFC\u5408\u89C1\u89E3",
463
+ descriptionEn: "Dual-model technical analysis (Codex + Gemini parallel), comprehensive insights after cross-validation"
464
+ },
465
+ {
466
+ id: "enhance",
467
+ name: "Prompt \u589E\u5F3A",
468
+ nameEn: "Prompt Enhancement",
469
+ category: "development",
470
+ commands: ["enhance"],
471
+ defaultSelected: true,
472
+ order: 7,
473
+ description: "\u4F7F\u7528 ace-tool enhance_prompt \u4F18\u5316 Prompt",
474
+ descriptionEn: "Optimize prompts using ace-tool enhance_prompt"
475
+ },
476
+ {
477
+ id: "debug",
478
+ name: "UltraThink \u8C03\u8BD5",
479
+ nameEn: "UltraThink Debug",
480
+ category: "development",
481
+ commands: ["debug"],
482
+ defaultSelected: false,
483
+ order: 8,
484
+ description: "UltraThink \u591A\u6A21\u578B\u8C03\u8BD5\uFF08Codex \u540E\u7AEF\u8BCA\u65AD + Gemini \u524D\u7AEF\u8BCA\u65AD\uFF09",
485
+ descriptionEn: "UltraThink multi-model debugging (Codex backend diagnosis + Gemini frontend diagnosis)"
486
+ },
487
+ {
488
+ id: "test",
489
+ name: "\u591A\u6A21\u578B\u6D4B\u8BD5\u751F\u6210",
490
+ nameEn: "Multi-Model Test Generation",
491
+ category: "development",
492
+ commands: ["test"],
493
+ defaultSelected: false,
494
+ order: 9,
495
+ description: "\u591A\u6A21\u578B\u6D4B\u8BD5\u751F\u6210\uFF08Codex \u540E\u7AEF\u6D4B\u8BD5 + Gemini \u524D\u7AEF\u6D4B\u8BD5\uFF09",
496
+ descriptionEn: "Multi-model test generation (Codex backend tests + Gemini frontend tests)"
497
+ },
498
+ {
499
+ id: "bugfix",
500
+ name: "\u8D28\u91CF\u95E8\u63A7\u4FEE\u590D",
501
+ nameEn: "Quality Gate Bugfix",
502
+ category: "development",
503
+ commands: ["bugfix"],
504
+ defaultSelected: false,
505
+ order: 10,
506
+ description: "\u8D28\u91CF\u95E8\u63A7\u4FEE\u590D\uFF08\u53CC\u6A21\u578B\u4EA4\u53C9\u9A8C\u8BC1\uFF0C90%+ \u901A\u8FC7\uFF09",
507
+ descriptionEn: "Quality gate bugfix (dual-model cross-validation, 90%+ pass)"
508
+ },
509
+ {
510
+ id: "think",
511
+ name: "UltraThink \u6DF1\u5EA6\u5206\u6790",
512
+ nameEn: "UltraThink Deep Analysis",
513
+ category: "development",
514
+ commands: ["think"],
515
+ defaultSelected: false,
516
+ order: 11,
517
+ description: "UltraThink \u6DF1\u5EA6\u5206\u6790\uFF08\u53CC\u6A21\u578B\u5E76\u884C\u5206\u6790 + \u7EFC\u5408\u89C1\u89E3\uFF09",
518
+ descriptionEn: "UltraThink deep analysis (dual-model parallel analysis + comprehensive insights)"
519
+ },
520
+ {
521
+ id: "optimize",
522
+ name: "\u591A\u6A21\u578B\u6027\u80FD\u4F18\u5316",
523
+ nameEn: "Multi-Model Optimization",
524
+ category: "development",
525
+ commands: ["optimize"],
526
+ defaultSelected: false,
527
+ order: 12,
528
+ description: "\u591A\u6A21\u578B\u6027\u80FD\u4F18\u5316\uFF08Codex \u540E\u7AEF\u4F18\u5316 + Gemini \u524D\u7AEF\u4F18\u5316\uFF09",
529
+ descriptionEn: "Multi-model performance optimization (Codex backend + Gemini frontend)"
530
+ },
531
+ {
532
+ id: "commit",
533
+ name: "Git \u667A\u80FD\u63D0\u4EA4",
534
+ nameEn: "Git Smart Commit",
535
+ category: "git",
536
+ commands: ["commit"],
537
+ defaultSelected: true,
538
+ order: 20,
539
+ description: "\u4EC5\u7528 Git \u5206\u6790\u6539\u52A8\u5E76\u81EA\u52A8\u751F\u6210 conventional commit \u4FE1\u606F\uFF08\u53EF\u9009 emoji\uFF09",
540
+ descriptionEn: "Git-only analysis to auto-generate conventional commit messages (optional emoji)"
541
+ },
542
+ {
543
+ id: "rollback",
544
+ name: "Git \u4EA4\u4E92\u5F0F\u56DE\u6EDA",
545
+ nameEn: "Git Interactive Rollback",
546
+ category: "git",
547
+ commands: ["rollback"],
548
+ defaultSelected: true,
549
+ order: 21,
550
+ 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",
551
+ descriptionEn: "Interactive Git branch rollback; list branches, versions, confirm before execution"
552
+ },
553
+ {
554
+ id: "clean-branches",
555
+ name: "\u6E05\u7406 Git \u5206\u652F",
556
+ nameEn: "Clean Git Branches",
557
+ category: "git",
558
+ commands: ["clean-branches"],
559
+ defaultSelected: true,
560
+ order: 22,
561
+ 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",
562
+ descriptionEn: "Safely find and clean merged or stale Git branches, supports dry-run mode"
563
+ },
564
+ {
565
+ id: "worktree",
566
+ name: "Git Worktree \u7BA1\u7406",
567
+ nameEn: "Git Worktree Management",
568
+ category: "git",
569
+ commands: ["worktree"],
570
+ defaultSelected: false,
571
+ order: 23,
572
+ description: "\u7BA1\u7406 Git worktree\uFF0C\u5728\u9879\u76EE\u5E73\u7EA7\u7684 ../.ccg/\u9879\u76EE\u540D/ \u76EE\u5F55\u4E0B\u521B\u5EFA",
573
+ descriptionEn: "Manage Git worktree, create in ../.ccg/project-name/ directory parallel to project"
574
+ },
575
+ {
576
+ id: "init-project",
577
+ name: "\u9879\u76EE AI \u4E0A\u4E0B\u6587\u521D\u59CB\u5316",
578
+ nameEn: "Project AI Context Init",
579
+ category: "init",
580
+ commands: ["init"],
581
+ defaultSelected: true,
582
+ order: 30,
583
+ 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",
584
+ descriptionEn: "Initialize project AI context, generate/update root and module level CLAUDE.md index"
585
+ }
586
+ ];
587
+ function getWorkflowConfigs() {
588
+ return WORKFLOW_CONFIGS.sort((a, b) => a.order - b.order);
589
+ }
590
+ function getWorkflowById(id) {
591
+ return WORKFLOW_CONFIGS.find((w) => w.id === id);
592
+ }
593
+ async function installWorkflows(workflowIds, installDir, force = false) {
594
+ const result = {
595
+ success: true,
596
+ installedCommands: [],
597
+ installedPrompts: [],
598
+ errors: [],
599
+ configPath: ""
600
+ };
601
+ const commandsDir = join(installDir, "commands", "ccg");
602
+ const promptsDir = join(installDir, "prompts", "ccg");
603
+ await fs.ensureDir(commandsDir);
604
+ await fs.ensureDir(promptsDir);
605
+ const templateDir = join(PACKAGE_ROOT, "templates");
606
+ for (const workflowId of workflowIds) {
607
+ const workflow = getWorkflowById(workflowId);
608
+ if (!workflow) {
609
+ result.errors.push(`Unknown workflow: ${workflowId}`);
610
+ continue;
611
+ }
612
+ for (const cmd of workflow.commands) {
613
+ const srcFile = join(templateDir, "commands", `${cmd}.md`);
614
+ const destFile = join(commandsDir, `${cmd}.md`);
615
+ try {
616
+ if (await fs.pathExists(srcFile)) {
617
+ if (force || !await fs.pathExists(destFile)) {
618
+ await fs.copy(srcFile, destFile);
619
+ result.installedCommands.push(cmd);
620
+ }
621
+ } else {
622
+ const placeholder = `---
623
+ description: "${workflow.descriptionEn}"
624
+ ---
625
+
626
+ # /ccg:${cmd}
627
+
628
+ ${workflow.description}
629
+
630
+ > This command is part of CCG multi-model collaboration system.
631
+ `;
632
+ await fs.writeFile(destFile, placeholder, "utf-8");
633
+ result.installedCommands.push(cmd);
634
+ }
635
+ } catch (error) {
636
+ result.errors.push(`Failed to install ${cmd}: ${error}`);
637
+ result.success = false;
638
+ }
639
+ }
640
+ }
641
+ const configSrcFile = join(templateDir, "commands", "_config.md");
642
+ const configDestFile = join(commandsDir, "_config.md");
643
+ if (await fs.pathExists(configSrcFile)) {
644
+ if (force || !await fs.pathExists(configDestFile)) {
645
+ await fs.copy(configSrcFile, configDestFile);
646
+ }
647
+ }
648
+ const promptsTemplateDir = join(templateDir, "prompts");
649
+ if (await fs.pathExists(promptsTemplateDir)) {
650
+ const modelDirs = ["codex", "gemini", "claude"];
651
+ for (const model of modelDirs) {
652
+ const srcModelDir = join(promptsTemplateDir, model);
653
+ const destModelDir = join(promptsDir, model);
654
+ if (await fs.pathExists(srcModelDir)) {
655
+ try {
656
+ await fs.ensureDir(destModelDir);
657
+ const files = await fs.readdir(srcModelDir);
658
+ for (const file of files) {
659
+ if (file.endsWith(".md")) {
660
+ const srcFile = join(srcModelDir, file);
661
+ const destFile = join(destModelDir, file);
662
+ if (force || !await fs.pathExists(destFile)) {
663
+ await fs.copy(srcFile, destFile);
664
+ result.installedPrompts.push(`${model}/${file.replace(".md", "")}`);
665
+ }
666
+ }
667
+ }
668
+ } catch (error) {
669
+ result.errors.push(`Failed to install ${model} prompts: ${error}`);
670
+ result.success = false;
671
+ }
672
+ }
673
+ }
674
+ }
675
+ result.configPath = commandsDir;
676
+ return result;
677
+ }
678
+ function getClaudeCodeConfigPath() {
679
+ return join(homedir(), ".claude.json");
680
+ }
681
+ async function uninstallWorkflows(installDir) {
682
+ const result = {
683
+ success: true,
684
+ removedCommands: [],
685
+ removedPrompts: [],
686
+ errors: []
687
+ };
688
+ const commandsDir = join(installDir, "commands", "ccg");
689
+ const promptsDir = join(installDir, "prompts", "ccg");
690
+ if (await fs.pathExists(commandsDir)) {
691
+ try {
692
+ const files = await fs.readdir(commandsDir);
693
+ for (const file of files) {
694
+ if (file.endsWith(".md")) {
695
+ await fs.remove(join(commandsDir, file));
696
+ result.removedCommands.push(file.replace(".md", ""));
697
+ }
698
+ }
699
+ const remaining = await fs.readdir(commandsDir);
700
+ if (remaining.length === 0) {
701
+ await fs.remove(commandsDir);
702
+ }
703
+ } catch (error) {
704
+ result.errors.push(`Failed to remove commands: ${error}`);
705
+ result.success = false;
706
+ }
707
+ }
708
+ if (await fs.pathExists(promptsDir)) {
709
+ try {
710
+ const files = await fs.readdir(promptsDir);
711
+ for (const file of files) {
712
+ await fs.remove(join(promptsDir, file));
713
+ result.removedPrompts.push(file);
714
+ }
715
+ const remaining = await fs.readdir(promptsDir);
716
+ if (remaining.length === 0) {
717
+ await fs.remove(promptsDir);
718
+ }
719
+ } catch (error) {
720
+ result.errors.push(`Failed to remove prompts: ${error}`);
721
+ result.success = false;
722
+ }
723
+ }
724
+ return result;
725
+ }
726
+ async function uninstallAceTool() {
727
+ const mcpConfigPath = getClaudeCodeConfigPath();
728
+ try {
729
+ if (!await fs.pathExists(mcpConfigPath)) {
730
+ return {
731
+ success: true,
732
+ message: "No ~/.claude.json found, nothing to remove"
733
+ };
734
+ }
735
+ const content = await fs.readFile(mcpConfigPath, "utf-8");
736
+ let existingConfig;
737
+ try {
738
+ existingConfig = JSON.parse(content);
739
+ } catch {
740
+ return {
741
+ success: false,
742
+ message: "Failed to parse ~/.claude.json"
743
+ };
744
+ }
745
+ if (!existingConfig.mcpServers || !existingConfig.mcpServers["ace-tool"]) {
746
+ return {
747
+ success: true,
748
+ message: "ace-tool MCP not found in config"
749
+ };
750
+ }
751
+ delete existingConfig.mcpServers["ace-tool"];
752
+ await fs.writeFile(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
753
+ return {
754
+ success: true,
755
+ message: "ace-tool MCP removed from ~/.claude.json"
756
+ };
757
+ } catch (error) {
758
+ return {
759
+ success: false,
760
+ message: `Failed to uninstall ace-tool: ${error}`
761
+ };
762
+ }
763
+ }
764
+ async function installAceTool(config) {
765
+ const { baseUrl, token } = config;
766
+ const mcpConfigPath = getClaudeCodeConfigPath();
767
+ try {
768
+ let existingConfig = {};
769
+ if (await fs.pathExists(mcpConfigPath)) {
770
+ try {
771
+ const content = await fs.readFile(mcpConfigPath, "utf-8");
772
+ existingConfig = JSON.parse(content);
773
+ } catch {
774
+ return {
775
+ success: false,
776
+ message: "Failed to parse existing ~/.claude.json - please check the file format"
777
+ };
778
+ }
779
+ }
780
+ if (!existingConfig.mcpServers) {
781
+ existingConfig.mcpServers = {};
782
+ }
783
+ existingConfig.mcpServers["ace-tool"] = {
784
+ type: "stdio",
785
+ command: "npx",
786
+ args: ["-y", "ace-tool@latest"],
787
+ env: {
788
+ ACE_BASE_URL: baseUrl || "https://api.augmentcode.com",
789
+ ACE_TOKEN: token || ""
790
+ }
791
+ };
792
+ await fs.writeFile(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
793
+ return {
794
+ success: true,
795
+ message: "ace-tool MCP configured successfully in ~/.claude.json",
796
+ configPath: mcpConfigPath
797
+ };
798
+ } catch (error) {
799
+ return {
800
+ success: false,
801
+ message: `Failed to configure ace-tool: ${error}`
802
+ };
803
+ }
804
+ }
805
+
806
+ async function init(options = {}) {
807
+ console.log();
808
+ console.log(ansis.cyan.bold(` CCG - Claude + Codex + Gemini`));
809
+ console.log(ansis.gray(` ${i18n.t("init:welcome")}`));
810
+ console.log();
811
+ let language = options.lang || "en";
812
+ if (!options.skipPrompt && !options.lang) {
813
+ const { selectedLang } = await inquirer.prompt([{
814
+ type: "list",
815
+ name: "selectedLang",
816
+ message: i18n.t("init:selectLanguage"),
817
+ choices: [
818
+ { name: "\u4E2D\u6587 (Chinese)", value: "zh-CN" },
819
+ { name: "English", value: "en" }
820
+ ],
821
+ default: "zh-CN"
822
+ }]);
823
+ language = selectedLang;
824
+ await i18n.changeLanguage(language);
825
+ }
826
+ let frontendModels = ["gemini"];
827
+ if (options.frontend) {
828
+ frontendModels = options.frontend.split(",").map((m) => m.trim());
829
+ } else if (!options.skipPrompt) {
830
+ const { selectedFrontend } = await inquirer.prompt([{
831
+ type: "checkbox",
832
+ name: "selectedFrontend",
833
+ message: i18n.t("init:selectFrontendModels"),
834
+ choices: [
835
+ { name: i18n.t("init:models.gemini"), value: "gemini", checked: true },
836
+ { name: i18n.t("init:models.codex"), value: "codex" },
837
+ { name: i18n.t("init:models.claude"), value: "claude" }
838
+ ],
839
+ validate: (answer) => answer.length > 0 || i18n.t("init:validation.selectAtLeastOne")
840
+ }]);
841
+ frontendModels = selectedFrontend;
842
+ }
843
+ let backendModels = ["codex"];
844
+ if (options.backend) {
845
+ backendModels = options.backend.split(",").map((m) => m.trim());
846
+ } else if (!options.skipPrompt) {
847
+ const { selectedBackend } = await inquirer.prompt([{
848
+ type: "checkbox",
849
+ name: "selectedBackend",
850
+ message: i18n.t("init:selectBackendModels"),
851
+ choices: [
852
+ { name: i18n.t("init:models.codex"), value: "codex", checked: true },
853
+ { name: i18n.t("init:models.gemini"), value: "gemini" },
854
+ { name: i18n.t("init:models.claude"), value: "claude" }
855
+ ],
856
+ validate: (answer) => answer.length > 0 || i18n.t("init:validation.selectAtLeastOne")
857
+ }]);
858
+ backendModels = selectedBackend;
859
+ }
860
+ let mode = "smart";
861
+ if (options.mode) {
862
+ mode = options.mode;
863
+ } else if (!options.skipPrompt) {
864
+ const { selectedMode } = await inquirer.prompt([{
865
+ type: "list",
866
+ name: "selectedMode",
867
+ message: i18n.t("init:selectMode"),
868
+ choices: [
869
+ { name: i18n.t("init:modes.smart"), value: "smart" },
870
+ { name: i18n.t("init:modes.parallel"), value: "parallel" },
871
+ { name: i18n.t("init:modes.sequential"), value: "sequential" }
872
+ ],
873
+ default: "smart"
874
+ }]);
875
+ mode = selectedMode;
876
+ }
877
+ const allWorkflows = getWorkflowConfigs();
878
+ let selectedWorkflows = allWorkflows.filter((w) => w.defaultSelected).map((w) => w.id);
879
+ if (options.workflows) {
880
+ if (options.workflows === "all") {
881
+ selectedWorkflows = allWorkflows.map((w) => w.id);
882
+ } else if (options.workflows !== "skip") {
883
+ selectedWorkflows = options.workflows.split(",").map((w) => w.trim());
884
+ }
885
+ } else if (!options.skipPrompt) {
886
+ const { selected } = await inquirer.prompt([{
887
+ type: "checkbox",
888
+ name: "selected",
889
+ message: i18n.t("init:selectWorkflows"),
890
+ choices: allWorkflows.map((w) => ({
891
+ name: `${language === "zh-CN" ? w.name : w.nameEn} ${ansis.gray(`\u2014 ${language === "zh-CN" ? w.description : w.descriptionEn}`)}`,
892
+ value: w.id,
893
+ checked: w.defaultSelected
894
+ }))
895
+ }]);
896
+ selectedWorkflows = selected;
897
+ }
898
+ let aceToolBaseUrl = "";
899
+ let aceToolToken = "";
900
+ if (!options.skipPrompt) {
901
+ console.log();
902
+ console.log(ansis.cyan.bold(` \u{1F527} ace-tool MCP`));
903
+ console.log(ansis.gray(` ${i18n.t("init:aceTool.description")}`));
904
+ console.log(ansis.gray(` ${i18n.t("init:aceTool.getToken")}: https://augmentcode.com/`));
905
+ console.log();
906
+ const aceAnswers = await inquirer.prompt([
907
+ {
908
+ type: "input",
909
+ name: "baseUrl",
910
+ message: `${i18n.t("init:aceTool.baseUrl")} ${ansis.gray("(Enter to skip)")}`,
911
+ default: ""
912
+ },
913
+ {
914
+ type: "password",
915
+ name: "token",
916
+ message: `${i18n.t("init:aceTool.token")} ${ansis.gray("(Enter to skip)")}`,
917
+ mask: "*"
918
+ }
919
+ ]);
920
+ aceToolBaseUrl = aceAnswers.baseUrl || "";
921
+ aceToolToken = aceAnswers.token || "";
922
+ }
923
+ const routing = {
924
+ frontend: {
925
+ models: frontendModels,
926
+ primary: frontendModels[0],
927
+ strategy: frontendModels.length > 1 ? "parallel" : "fallback"
928
+ },
929
+ backend: {
930
+ models: backendModels,
931
+ primary: backendModels[0],
932
+ strategy: backendModels.length > 1 ? "parallel" : "fallback"
933
+ },
934
+ review: {
935
+ models: [.../* @__PURE__ */ new Set([...frontendModels, ...backendModels])],
936
+ strategy: "parallel"
937
+ },
938
+ mode
939
+ };
940
+ console.log();
941
+ console.log(ansis.yellow("\u2501".repeat(50)));
942
+ console.log(ansis.bold(` ${i18n.t("init:summary.title")}`));
943
+ console.log();
944
+ console.log(` ${ansis.cyan(i18n.t("init:summary.frontendModels"))} ${frontendModels.map((m) => ansis.green(m)).join(", ")}`);
945
+ console.log(` ${ansis.cyan(i18n.t("init:summary.backendModels"))} ${backendModels.map((m) => ansis.blue(m)).join(", ")}`);
946
+ console.log(` ${ansis.cyan(i18n.t("init:summary.collaboration"))} ${ansis.yellow(mode)}`);
947
+ console.log(` ${ansis.cyan(i18n.t("init:summary.workflows"))} ${selectedWorkflows.length} ${i18n.t("init:summary.selected")}`);
948
+ console.log(ansis.yellow("\u2501".repeat(50)));
949
+ console.log();
950
+ if (!options.skipPrompt) {
951
+ const { confirmed } = await inquirer.prompt([{
952
+ type: "confirm",
953
+ name: "confirmed",
954
+ message: i18n.t("init:confirmInstall"),
955
+ default: true
956
+ }]);
957
+ if (!confirmed) {
958
+ console.log(ansis.yellow(i18n.t("init:installCancelled")));
959
+ return;
960
+ }
961
+ }
962
+ const spinner = ora(i18n.t("init:installing")).start();
963
+ try {
964
+ await ensureCcgDir();
965
+ const config = createDefaultConfig({
966
+ language,
967
+ routing,
968
+ installedWorkflows: selectedWorkflows
969
+ });
970
+ const installDir = options.installDir || join(homedir(), ".claude");
971
+ const result = await installWorkflows(selectedWorkflows, installDir, options.force);
972
+ await writeCcgConfig(config);
973
+ if (aceToolBaseUrl || aceToolToken) {
974
+ spinner.text = i18n.t("init:aceTool.installing");
975
+ const aceResult = await installAceTool({
976
+ baseUrl: aceToolBaseUrl,
977
+ token: aceToolToken
978
+ });
979
+ if (aceResult.success) {
980
+ spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
981
+ console.log();
982
+ console.log(` ${ansis.green("\u2713")} ace-tool MCP ${ansis.gray(`\u2192 ${aceResult.configPath}`)}`);
983
+ } else {
984
+ spinner.warn(ansis.yellow(i18n.t("init:aceTool.failed")));
985
+ console.log(ansis.gray(` ${aceResult.message}`));
986
+ }
987
+ } else {
988
+ spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
989
+ }
990
+ console.log();
991
+ console.log(ansis.cyan(` ${i18n.t("init:installedCommands")}`));
992
+ result.installedCommands.forEach((cmd) => {
993
+ console.log(` ${ansis.green("\u2713")} /ccg:${cmd}`);
994
+ });
995
+ if (result.installedPrompts.length > 0) {
996
+ console.log();
997
+ console.log(ansis.cyan(` ${i18n.t("init:installedPrompts")}`));
998
+ const grouped = {};
999
+ result.installedPrompts.forEach((p) => {
1000
+ const [model, role] = p.split("/");
1001
+ if (!grouped[model])
1002
+ grouped[model] = [];
1003
+ grouped[model].push(role);
1004
+ });
1005
+ Object.entries(grouped).forEach(([model, roles]) => {
1006
+ console.log(` ${ansis.green("\u2713")} ${model}: ${roles.join(", ")}`);
1007
+ });
1008
+ }
1009
+ console.log();
1010
+ console.log(ansis.gray(` ${i18n.t("init:configSavedTo")} ${getCcgDir()}/config.toml`));
1011
+ console.log();
1012
+ } catch (error) {
1013
+ spinner.fail(ansis.red(i18n.t("init:installFailed")));
1014
+ console.error(error);
1015
+ }
1016
+ }
1017
+
1018
+ async function showMainMenu() {
1019
+ console.log();
1020
+ console.log(ansis.cyan.bold(` CCG - Claude + Codex + Gemini`));
1021
+ console.log(ansis.gray(" Multi-Model Collaboration System"));
1022
+ console.log();
1023
+ const { action } = await inquirer.prompt([{
1024
+ type: "list",
1025
+ name: "action",
1026
+ message: i18n.t("menu:title"),
1027
+ choices: [
1028
+ { name: `${ansis.green("\u279C")} ${i18n.t("menu:options.init")}`, value: "init" },
1029
+ { name: `${ansis.blue("\u279C")} ${i18n.t("menu:options.update")}`, value: "update" },
1030
+ { name: `${ansis.magenta("\u279C")} ${i18n.t("menu:options.uninstall")}`, value: "uninstall" },
1031
+ { name: `${ansis.yellow("?")} ${i18n.t("menu:options.help")}`, value: "help" },
1032
+ new inquirer.Separator(),
1033
+ { name: `${ansis.red("\u2715")} ${i18n.t("menu:options.exit")}`, value: "exit" }
1034
+ ]
1035
+ }]);
1036
+ switch (action) {
1037
+ case "init":
1038
+ await init();
1039
+ break;
1040
+ case "update":
1041
+ console.log(ansis.yellow("Update functionality coming soon..."));
1042
+ break;
1043
+ case "uninstall":
1044
+ await uninstall();
1045
+ break;
1046
+ case "help":
1047
+ showHelp();
1048
+ break;
1049
+ case "exit":
1050
+ console.log(ansis.gray("Goodbye!"));
1051
+ break;
1052
+ }
1053
+ }
1054
+ function showHelp() {
1055
+ console.log();
1056
+ console.log(ansis.cyan.bold(i18n.t("menu:help.title")));
1057
+ console.log();
1058
+ console.log(` ${ansis.green("/ccg:dev")} ${i18n.t("menu:help.descriptions.dev")}`);
1059
+ console.log(` ${ansis.green("/ccg:frontend")} ${i18n.t("menu:help.descriptions.frontend")}`);
1060
+ console.log(` ${ansis.green("/ccg:backend")} ${i18n.t("menu:help.descriptions.backend")}`);
1061
+ console.log(` ${ansis.green("/ccg:review")} ${i18n.t("menu:help.descriptions.review")}`);
1062
+ console.log(` ${ansis.green("/ccg:analyze")} ${i18n.t("menu:help.descriptions.analyze")}`);
1063
+ console.log(` ${ansis.green("/ccg:commit")} ${i18n.t("menu:help.descriptions.commit")}`);
1064
+ console.log(` ${ansis.green("/ccg:rollback")} ${i18n.t("menu:help.descriptions.rollback")}`);
1065
+ console.log();
1066
+ console.log(ansis.gray(i18n.t("menu:help.hint")));
1067
+ console.log();
1068
+ }
1069
+ async function uninstall() {
1070
+ console.log();
1071
+ const { confirm } = await inquirer.prompt([{
1072
+ type: "confirm",
1073
+ name: "confirm",
1074
+ message: i18n.t("menu:uninstall.confirm"),
1075
+ default: false
1076
+ }]);
1077
+ if (!confirm) {
1078
+ console.log(ansis.gray(i18n.t("menu:uninstall.cancelled")));
1079
+ return;
1080
+ }
1081
+ const { removeAceTool } = await inquirer.prompt([{
1082
+ type: "confirm",
1083
+ name: "removeAceTool",
1084
+ message: i18n.t("menu:uninstall.alsoRemoveAceTool"),
1085
+ default: false
1086
+ }]);
1087
+ console.log();
1088
+ console.log(ansis.yellow(i18n.t("menu:uninstall.uninstalling")));
1089
+ const installDir = join(homedir(), ".claude");
1090
+ const result = await uninstallWorkflows(installDir);
1091
+ if (result.success) {
1092
+ console.log(ansis.green(i18n.t("menu:uninstall.success")));
1093
+ if (result.removedCommands.length > 0) {
1094
+ console.log();
1095
+ console.log(ansis.cyan(i18n.t("menu:uninstall.removedCommands")));
1096
+ for (const cmd of result.removedCommands) {
1097
+ console.log(` ${ansis.gray("\u2022")} /ccg:${cmd}`);
1098
+ }
1099
+ }
1100
+ } else {
1101
+ console.log(ansis.red(i18n.t("menu:uninstall.failed")));
1102
+ for (const error of result.errors) {
1103
+ console.log(ansis.red(` ${error}`));
1104
+ }
1105
+ }
1106
+ if (removeAceTool) {
1107
+ const aceResult = await uninstallAceTool();
1108
+ if (aceResult.success) {
1109
+ console.log(ansis.green(i18n.t("menu:uninstall.removedAceTool")));
1110
+ } else {
1111
+ console.log(ansis.red(aceResult.message));
1112
+ }
1113
+ }
1114
+ console.log();
1115
+ }
1116
+
1117
+ export { 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, uninstallAceTool as m, readCcgConfig as r, showMainMenu as s, uninstallWorkflows as u, writeCcgConfig as w };