ccg-workflow 1.6.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@ import { parse, stringify } from 'smol-toml';
10
10
  import { exec } from 'node:child_process';
11
11
  import { promisify } from 'node:util';
12
12
 
13
- const version = "1.6.0";
13
+ const version = "1.7.1";
14
14
 
15
15
  function isWindows() {
16
16
  return process.platform === "win32";
@@ -148,59 +148,48 @@ function findPackageRoot$1(startDir) {
148
148
  const PACKAGE_ROOT$1 = findPackageRoot$1(__dirname$2);
149
149
  const WORKFLOW_CONFIGS = [
150
150
  {
151
- id: "dev",
151
+ id: "workflow",
152
152
  name: "\u5B8C\u6574\u5F00\u53D1\u5DE5\u4F5C\u6D41",
153
153
  nameEn: "Full Development Workflow",
154
154
  category: "development",
155
- commands: ["dev"],
155
+ commands: ["workflow"],
156
156
  defaultSelected: true,
157
157
  order: 1,
158
- description: "\u5B8C\u65746\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41\uFF08Prompt\u589E\u5F3A\u2192\u4E0A\u4E0B\u6587\u68C0\u7D22\u2192\u591A\u6A21\u578B\u5206\u6790\u2192\u539F\u578B\u751F\u6210\u2192\u4EE3\u7801\u5B9E\u65BD\u2192\u5BA1\u8BA1\u4EA4\u4ED8\uFF09",
159
- descriptionEn: "Full 6-phase development workflow (Prompt enhancement \u2192 Context retrieval \u2192 Multi-model analysis \u2192 Prototype \u2192 Implementation \u2192 Audit)"
160
- },
161
- {
162
- id: "code",
163
- name: "\u667A\u80FD\u4EE3\u7801\u751F\u6210",
164
- nameEn: "Smart Code Generation",
165
- category: "development",
166
- commands: ["code"],
167
- defaultSelected: true,
168
- order: 2,
169
- description: "\u591A\u6A21\u578B\u4EE3\u7801\u751F\u6210\uFF08\u667A\u80FD\u8DEF\u7531\uFF1A\u524D\u7AEF\u2192Gemini\uFF0C\u540E\u7AEF\u2192Codex\uFF09",
170
- descriptionEn: "Multi-model code generation (smart routing: frontend\u2192Gemini, backend\u2192Codex)"
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"
171
160
  },
172
161
  {
173
162
  id: "frontend",
174
- name: "\u524D\u7AEF\u4EFB\u52A1",
163
+ name: "\u524D\u7AEF\u4E13\u9879",
175
164
  nameEn: "Frontend Tasks",
176
165
  category: "development",
177
166
  commands: ["frontend"],
178
167
  defaultSelected: true,
179
- order: 3,
180
- description: "\u524D\u7AEF/UI/\u6837\u5F0F\u4EFB\u52A1\uFF0C\u81EA\u52A8\u8DEF\u7531\u5230 Gemini",
181
- descriptionEn: "Frontend/UI/style tasks, auto-route to Gemini"
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)"
182
171
  },
183
172
  {
184
173
  id: "backend",
185
- name: "\u540E\u7AEF\u4EFB\u52A1",
174
+ name: "\u540E\u7AEF\u4E13\u9879",
186
175
  nameEn: "Backend Tasks",
187
176
  category: "development",
188
177
  commands: ["backend"],
189
178
  defaultSelected: true,
190
- order: 4,
191
- description: "\u540E\u7AEF/\u903B\u8F91/\u7B97\u6CD5\u4EFB\u52A1\uFF0C\u81EA\u52A8\u8DEF\u7531\u5230 Codex",
192
- descriptionEn: "Backend/logic/algorithm tasks, auto-route to Codex"
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)"
193
182
  },
194
183
  {
195
- id: "review",
196
- name: "\u4EE3\u7801\u5BA1\u67E5",
197
- nameEn: "Code Review",
184
+ id: "feat",
185
+ name: "\u667A\u80FD\u529F\u80FD\u5F00\u53D1",
186
+ nameEn: "Smart Feature Development",
198
187
  category: "development",
199
- commands: ["review"],
188
+ commands: ["feat"],
200
189
  defaultSelected: true,
201
- order: 5,
202
- description: "\u53CC\u6A21\u578B\u4EE3\u7801\u5BA1\u67E5\uFF08Codex + Gemini \u5E76\u884C\uFF09\uFF0C\u65E0\u53C2\u6570\u65F6\u81EA\u52A8\u5BA1\u67E5 git diff",
203
- descriptionEn: "Dual-model code review (Codex + Gemini parallel), auto-review git diff when no args"
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"
204
193
  },
205
194
  {
206
195
  id: "analyze",
@@ -209,141 +198,108 @@ const WORKFLOW_CONFIGS = [
209
198
  category: "development",
210
199
  commands: ["analyze"],
211
200
  defaultSelected: true,
212
- order: 6,
213
- description: "\u53CC\u6A21\u578B\u6280\u672F\u5206\u6790\uFF08Codex + Gemini \u5E76\u884C\uFF09\uFF0C\u4EA4\u53C9\u9A8C\u8BC1\u540E\u7EFC\u5408\u89C1\u89E3",
214
- descriptionEn: "Dual-model technical analysis (Codex + Gemini parallel), comprehensive insights after cross-validation"
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"
215
204
  },
216
205
  {
217
- id: "enhance",
218
- name: "Prompt \u589E\u5F3A",
219
- nameEn: "Prompt Enhancement",
206
+ id: "debug",
207
+ name: "\u95EE\u9898\u8BCA\u65AD",
208
+ nameEn: "Debug",
220
209
  category: "development",
221
- commands: ["enhance"],
210
+ commands: ["debug"],
222
211
  defaultSelected: true,
223
- order: 7,
224
- description: "\u4F7F\u7528 ace-tool enhance_prompt \u4F18\u5316 Prompt",
225
- descriptionEn: "Optimize prompts using ace-tool enhance_prompt"
212
+ order: 6,
213
+ description: "\u591A\u6A21\u578B\u8BCA\u65AD + \u4FEE\u590D",
214
+ descriptionEn: "Multi-model diagnosis + fix"
226
215
  },
227
216
  {
228
- id: "debug",
229
- name: "UltraThink \u8C03\u8BD5",
230
- nameEn: "UltraThink Debug",
217
+ id: "optimize",
218
+ name: "\u6027\u80FD\u4F18\u5316",
219
+ nameEn: "Performance Optimization",
231
220
  category: "development",
232
- commands: ["debug"],
233
- defaultSelected: false,
234
- order: 8,
235
- description: "UltraThink \u591A\u6A21\u578B\u8C03\u8BD5\uFF08Codex \u540E\u7AEF\u8BCA\u65AD + Gemini \u524D\u7AEF\u8BCA\u65AD\uFF09",
236
- descriptionEn: "UltraThink multi-model debugging (Codex backend diagnosis + Gemini frontend diagnosis)"
221
+ commands: ["optimize"],
222
+ defaultSelected: true,
223
+ order: 7,
224
+ description: "\u591A\u6A21\u578B\u6027\u80FD\u4F18\u5316",
225
+ descriptionEn: "Multi-model performance optimization"
237
226
  },
238
227
  {
239
228
  id: "test",
240
- name: "\u591A\u6A21\u578B\u6D4B\u8BD5\u751F\u6210",
241
- nameEn: "Multi-Model Test Generation",
229
+ name: "\u6D4B\u8BD5\u751F\u6210",
230
+ nameEn: "Test Generation",
242
231
  category: "development",
243
232
  commands: ["test"],
244
- defaultSelected: false,
245
- order: 9,
246
- description: "\u591A\u6A21\u578B\u6D4B\u8BD5\u751F\u6210\uFF08Codex \u540E\u7AEF\u6D4B\u8BD5 + Gemini \u524D\u7AEF\u6D4B\u8BD5\uFF09",
247
- descriptionEn: "Multi-model test generation (Codex backend tests + Gemini frontend tests)"
248
- },
249
- {
250
- id: "bugfix",
251
- name: "\u8D28\u91CF\u95E8\u63A7\u4FEE\u590D",
252
- nameEn: "Quality Gate Bugfix",
253
- category: "development",
254
- commands: ["bugfix"],
255
- defaultSelected: false,
256
- order: 10,
257
- description: "\u8D28\u91CF\u95E8\u63A7\u4FEE\u590D\uFF08\u53CC\u6A21\u578B\u4EA4\u53C9\u9A8C\u8BC1\uFF0C90%+ \u901A\u8FC7\uFF09",
258
- descriptionEn: "Quality gate bugfix (dual-model cross-validation, 90%+ pass)"
233
+ defaultSelected: true,
234
+ order: 8,
235
+ description: "\u667A\u80FD\u8DEF\u7531\u6D4B\u8BD5\u751F\u6210",
236
+ descriptionEn: "Smart routing test generation"
259
237
  },
260
238
  {
261
- id: "think",
262
- name: "UltraThink \u6DF1\u5EA6\u5206\u6790",
263
- nameEn: "UltraThink Deep Analysis",
239
+ id: "review",
240
+ name: "\u4EE3\u7801\u5BA1\u67E5",
241
+ nameEn: "Code Review",
264
242
  category: "development",
265
- commands: ["think"],
266
- defaultSelected: false,
267
- order: 11,
268
- description: "UltraThink \u6DF1\u5EA6\u5206\u6790\uFF08\u53CC\u6A21\u578B\u5E76\u884C\u5206\u6790 + \u7EFC\u5408\u89C1\u89E3\uFF09",
269
- descriptionEn: "UltraThink deep analysis (dual-model parallel analysis + comprehensive insights)"
243
+ commands: ["review"],
244
+ defaultSelected: true,
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"
270
248
  },
271
249
  {
272
- id: "optimize",
273
- name: "\u591A\u6A21\u578B\u6027\u80FD\u4F18\u5316",
274
- nameEn: "Multi-Model Optimization",
275
- category: "development",
276
- commands: ["optimize"],
277
- defaultSelected: false,
278
- order: 12,
279
- description: "\u591A\u6A21\u578B\u6027\u80FD\u4F18\u5316\uFF08Codex \u540E\u7AEF\u4F18\u5316 + Gemini \u524D\u7AEF\u4F18\u5316\uFF09",
280
- descriptionEn: "Multi-model performance optimization (Codex backend + Gemini frontend)"
250
+ id: "init-project",
251
+ name: "\u9879\u76EE\u521D\u59CB\u5316",
252
+ nameEn: "Project Init",
253
+ category: "init",
254
+ commands: ["init"],
255
+ defaultSelected: true,
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"
281
259
  },
282
260
  {
283
261
  id: "commit",
284
- name: "Git \u667A\u80FD\u63D0\u4EA4",
285
- nameEn: "Git Smart Commit",
262
+ name: "Git \u63D0\u4EA4",
263
+ nameEn: "Git Commit",
286
264
  category: "git",
287
265
  commands: ["commit"],
288
266
  defaultSelected: true,
289
267
  order: 20,
290
- description: "\u4EC5\u7528 Git \u5206\u6790\u6539\u52A8\u5E76\u81EA\u52A8\u751F\u6210 conventional commit \u4FE1\u606F\uFF08\u53EF\u9009 emoji\uFF09",
291
- descriptionEn: "Git-only analysis to auto-generate conventional commit messages (optional emoji)"
268
+ description: "\u667A\u80FD\u751F\u6210 conventional commit \u4FE1\u606F",
269
+ descriptionEn: "Smart conventional commit message generation"
292
270
  },
293
271
  {
294
272
  id: "rollback",
295
- name: "Git \u4EA4\u4E92\u5F0F\u56DE\u6EDA",
296
- nameEn: "Git Interactive Rollback",
273
+ name: "Git \u56DE\u6EDA",
274
+ nameEn: "Git Rollback",
297
275
  category: "git",
298
276
  commands: ["rollback"],
299
277
  defaultSelected: true,
300
278
  order: 21,
301
- 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",
302
- 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"
303
281
  },
304
282
  {
305
283
  id: "clean-branches",
306
- name: "\u6E05\u7406 Git \u5206\u652F",
307
- nameEn: "Clean Git Branches",
284
+ name: "Git \u6E05\u7406\u5206\u652F",
285
+ nameEn: "Git Clean Branches",
308
286
  category: "git",
309
287
  commands: ["clean-branches"],
310
288
  defaultSelected: true,
311
289
  order: 22,
312
- 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",
313
- 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"
314
292
  },
315
293
  {
316
294
  id: "worktree",
317
- name: "Git Worktree \u7BA1\u7406",
318
- nameEn: "Git Worktree Management",
295
+ name: "Git Worktree",
296
+ nameEn: "Git Worktree",
319
297
  category: "git",
320
298
  commands: ["worktree"],
321
- defaultSelected: false,
322
- order: 23,
323
- description: "\u7BA1\u7406 Git worktree\uFF0C\u5728\u9879\u76EE\u5E73\u7EA7\u7684 ../.ccg/\u9879\u76EE\u540D/ \u76EE\u5F55\u4E0B\u521B\u5EFA",
324
- descriptionEn: "Manage Git worktree, create in ../.ccg/project-name/ directory parallel to project"
325
- },
326
- {
327
- id: "init-project",
328
- name: "\u9879\u76EE AI \u4E0A\u4E0B\u6587\u521D\u59CB\u5316",
329
- nameEn: "Project AI Context Init",
330
- category: "init",
331
- commands: ["init"],
332
299
  defaultSelected: true,
333
- order: 30,
334
- 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",
335
- descriptionEn: "Initialize project AI context, generate/update root and module level CLAUDE.md index"
336
- },
337
- {
338
- id: "feat",
339
- name: "\u667A\u80FD\u529F\u80FD\u5F00\u53D1",
340
- nameEn: "Smart Feature Development",
341
- category: "planning",
342
- commands: ["feat"],
343
- defaultSelected: true,
344
- order: 32,
345
- 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",
346
- 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"
347
303
  }
348
304
  ];
349
305
  function getWorkflowConfigs() {
@@ -352,32 +308,14 @@ function getWorkflowConfigs() {
352
308
  function getWorkflowById(id) {
353
309
  return WORKFLOW_CONFIGS.find((w) => w.id === id);
354
310
  }
355
- const WORKFLOW_PRESETS = {
356
- minimal: {
357
- name: "\u6700\u5C0F\u5316",
358
- nameEn: "Minimal",
359
- description: "\u6838\u5FC3\u5F00\u53D1\u547D\u4EE4\uFF083\u4E2A\uFF09",
360
- descriptionEn: "Core development commands (3)",
361
- workflows: ["dev", "code", "commit"]
362
- },
363
- standard: {
364
- name: "\u6807\u51C6",
365
- nameEn: "Standard",
366
- description: "\u5E38\u7528\u5F00\u53D1 + Git \u547D\u4EE4\uFF0812\u4E2A\uFF09",
367
- descriptionEn: "Common dev + Git commands (12)",
368
- workflows: ["dev", "code", "frontend", "backend", "review", "analyze", "debug", "test", "commit", "rollback", "clean-branches", "feat"]
369
- },
311
+ function getAllCommandIds() {
312
+ return WORKFLOW_CONFIGS.map((w) => w.id);
313
+ }
314
+ ({
370
315
  full: {
371
- name: "\u5B8C\u6574",
372
- nameEn: "Full",
373
- description: "\u5168\u90E8\u547D\u4EE4\uFF0817\u4E2A\uFF09",
374
- descriptionEn: "All commands (17)",
375
316
  workflows: WORKFLOW_CONFIGS.map((w) => w.id)
376
317
  }
377
- };
378
- function getWorkflowPreset(preset) {
379
- return [...WORKFLOW_PRESETS[preset].workflows];
380
- }
318
+ });
381
319
  function injectConfigVariables(content, config) {
382
320
  let processed = content;
383
321
  const routing = config.routing || {};
@@ -515,6 +453,34 @@ ${workflow.description}
515
453
  }
516
454
  }
517
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
+ }
518
484
  try {
519
485
  const binDir = join(installDir, "bin");
520
486
  await fs.ensureDir(binDir);
@@ -524,9 +490,9 @@ ${workflow.description}
524
490
  if (platform === "darwin") {
525
491
  binaryName = arch === "arm64" ? "codeagent-wrapper-darwin-arm64" : "codeagent-wrapper-darwin-amd64";
526
492
  } else if (platform === "linux") {
527
- binaryName = "codeagent-wrapper-linux-amd64";
493
+ binaryName = arch === "arm64" ? "codeagent-wrapper-linux-arm64" : "codeagent-wrapper-linux-amd64";
528
494
  } else if (platform === "win32") {
529
- binaryName = "codeagent-wrapper-windows-amd64.exe";
495
+ binaryName = arch === "arm64" ? "codeagent-wrapper-windows-arm64.exe" : "codeagent-wrapper-windows-amd64.exe";
530
496
  } else {
531
497
  result.errors.push(`Unsupported platform: ${platform}`);
532
498
  result.success = false;
@@ -565,10 +531,17 @@ async function uninstallWorkflows(installDir) {
565
531
  success: true,
566
532
  removedCommands: [],
567
533
  removedPrompts: [],
534
+ removedAgents: [],
535
+ removedSkills: [],
536
+ removedBin: false,
568
537
  errors: []
569
538
  };
570
539
  const commandsDir = join(installDir, "commands", "ccg");
571
- 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");
572
545
  if (await fs.pathExists(commandsDir)) {
573
546
  try {
574
547
  const files = await fs.readdir(commandsDir);
@@ -578,6 +551,10 @@ async function uninstallWorkflows(installDir) {
578
551
  result.removedCommands.push(file.replace(".md", ""));
579
552
  }
580
553
  }
554
+ const agentsSubDir = join(commandsDir, "agents");
555
+ if (await fs.pathExists(agentsSubDir)) {
556
+ await fs.remove(agentsSubDir);
557
+ }
581
558
  const remaining = await fs.readdir(commandsDir);
582
559
  if (remaining.length === 0) {
583
560
  await fs.remove(commandsDir);
@@ -587,22 +564,53 @@ async function uninstallWorkflows(installDir) {
587
564
  result.success = false;
588
565
  }
589
566
  }
590
- if (await fs.pathExists(promptsDir)) {
567
+ if (await fs.pathExists(agentsDir)) {
591
568
  try {
592
- const files = await fs.readdir(promptsDir);
569
+ const files = await fs.readdir(agentsDir);
593
570
  for (const file of files) {
594
- await fs.remove(join(promptsDir, file));
595
- result.removedPrompts.push(file);
571
+ await fs.remove(join(agentsDir, file));
572
+ result.removedAgents.push(file.replace(".md", ""));
596
573
  }
597
- const remaining = await fs.readdir(promptsDir);
598
- if (remaining.length === 0) {
599
- 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);
600
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");
601
596
  } catch (error) {
602
597
  result.errors.push(`Failed to remove prompts: ${error}`);
603
598
  result.success = false;
604
599
  }
605
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
+ }
606
614
  return result;
607
615
  }
608
616
  async function uninstallAceTool() {
@@ -1264,127 +1272,13 @@ async function needsMigration() {
1264
1272
  async function init(options = {}) {
1265
1273
  console.log();
1266
1274
  console.log(ansis.cyan.bold(` CCG - Claude + Codex + Gemini`));
1267
- console.log(ansis.gray(` ${i18n.t("init:welcome")}`));
1275
+ console.log(ansis.gray(` \u591A\u6A21\u578B\u534F\u4F5C\u5F00\u53D1\u5DE5\u4F5C\u6D41`));
1268
1276
  console.log();
1269
- let language = options.lang || "en";
1270
- if (!options.skipPrompt && !options.lang) {
1271
- const { selectedLang } = await inquirer.prompt([{
1272
- type: "list",
1273
- name: "selectedLang",
1274
- message: i18n.t("init:selectLanguage"),
1275
- choices: [
1276
- { name: "\u4E2D\u6587 (Chinese)", value: "zh-CN" },
1277
- { name: "English", value: "en" }
1278
- ],
1279
- default: "zh-CN"
1280
- }]);
1281
- language = selectedLang;
1282
- await i18n.changeLanguage(language);
1283
- }
1284
- let frontendModels = ["gemini"];
1285
- if (options.frontend) {
1286
- frontendModels = options.frontend.split(",").map((m) => m.trim());
1287
- } else if (!options.skipPrompt) {
1288
- const { selectedFrontend } = await inquirer.prompt([{
1289
- type: "checkbox",
1290
- name: "selectedFrontend",
1291
- message: i18n.t("init:selectFrontendModels"),
1292
- choices: [
1293
- { name: i18n.t("init:models.gemini"), value: "gemini", checked: true },
1294
- { name: i18n.t("init:models.codex"), value: "codex" },
1295
- { name: i18n.t("init:models.claude"), value: "claude" }
1296
- ],
1297
- validate: (answer) => answer.length > 0 || i18n.t("init:validation.selectAtLeastOne")
1298
- }]);
1299
- frontendModels = selectedFrontend;
1300
- }
1301
- let backendModels = ["codex"];
1302
- if (options.backend) {
1303
- backendModels = options.backend.split(",").map((m) => m.trim());
1304
- } else if (!options.skipPrompt) {
1305
- const { selectedBackend } = await inquirer.prompt([{
1306
- type: "checkbox",
1307
- name: "selectedBackend",
1308
- message: i18n.t("init:selectBackendModels"),
1309
- choices: [
1310
- { name: i18n.t("init:models.codex"), value: "codex", checked: true },
1311
- { name: i18n.t("init:models.gemini"), value: "gemini" },
1312
- { name: i18n.t("init:models.claude"), value: "claude" }
1313
- ],
1314
- validate: (answer) => answer.length > 0 || i18n.t("init:validation.selectAtLeastOne")
1315
- }]);
1316
- backendModels = selectedBackend;
1317
- }
1318
- let mode = "smart";
1319
- if (options.mode) {
1320
- mode = options.mode;
1321
- } else if (!options.skipPrompt) {
1322
- const { selectedMode } = await inquirer.prompt([{
1323
- type: "list",
1324
- name: "selectedMode",
1325
- message: i18n.t("init:selectMode"),
1326
- choices: [
1327
- { name: i18n.t("init:modes.smart"), value: "smart" },
1328
- { name: i18n.t("init:modes.parallel"), value: "parallel" },
1329
- { name: i18n.t("init:modes.sequential"), value: "sequential" }
1330
- ],
1331
- default: "smart"
1332
- }]);
1333
- mode = selectedMode;
1334
- }
1335
- const allWorkflows = getWorkflowConfigs();
1336
- let selectedWorkflows = allWorkflows.filter((w) => w.defaultSelected).map((w) => w.id);
1337
- if (options.workflows) {
1338
- if (options.workflows === "all") {
1339
- selectedWorkflows = allWorkflows.map((w) => w.id);
1340
- } else if (options.workflows !== "skip") {
1341
- selectedWorkflows = options.workflows.split(",").map((w) => w.trim());
1342
- }
1343
- } else if (!options.skipPrompt) {
1344
- const { workflowMode } = await inquirer.prompt([{
1345
- type: "list",
1346
- name: "workflowMode",
1347
- message: "\u9009\u62E9\u547D\u4EE4\u5B89\u88C5\u6A21\u5F0F",
1348
- choices: [
1349
- {
1350
- name: `${WORKFLOW_PRESETS.minimal.name} ${ansis.gray(`\u2014 ${WORKFLOW_PRESETS.minimal.description}`)} ${ansis.green("(\u63A8\u8350\u65B0\u624B)")}`,
1351
- value: "minimal"
1352
- },
1353
- {
1354
- name: `${WORKFLOW_PRESETS.standard.name} ${ansis.gray(`\u2014 ${WORKFLOW_PRESETS.standard.description}`)} ${ansis.green("(\u63A8\u8350)")}`,
1355
- value: "standard"
1356
- },
1357
- {
1358
- name: `${WORKFLOW_PRESETS.full.name} ${ansis.gray(`\u2014 ${WORKFLOW_PRESETS.full.description}`)}`,
1359
- value: "full"
1360
- },
1361
- new inquirer.Separator(),
1362
- {
1363
- name: `\u81EA\u5B9A\u4E49 ${ansis.gray("\u2014 \u624B\u52A8\u9009\u62E9\u547D\u4EE4")}`,
1364
- value: "custom"
1365
- }
1366
- ],
1367
- default: "standard"
1368
- }]);
1369
- if (workflowMode === "custom") {
1370
- const { selected } = await inquirer.prompt([{
1371
- type: "checkbox",
1372
- name: "selected",
1373
- message: i18n.t("init:selectWorkflows"),
1374
- choices: allWorkflows.map((w) => ({
1375
- name: `${language === "zh-CN" ? w.name : w.nameEn} ${ansis.gray(`\u2014 ${language === "zh-CN" ? w.description : w.descriptionEn}`)}`,
1376
- value: w.id,
1377
- checked: w.defaultSelected
1378
- }))
1379
- }]);
1380
- selectedWorkflows = selected;
1381
- } else {
1382
- selectedWorkflows = getWorkflowPreset(workflowMode);
1383
- const preset = WORKFLOW_PRESETS[workflowMode];
1384
- console.log();
1385
- console.log(ansis.gray(` \u5DF2\u9009\u62E9 ${ansis.cyan(preset.name)} \u6A21\u5F0F (${selectedWorkflows.length} \u4E2A\u547D\u4EE4)`));
1386
- }
1387
- }
1277
+ const language = "zh-CN";
1278
+ const frontendModels = ["gemini"];
1279
+ const backendModels = ["codex"];
1280
+ const mode = "smart";
1281
+ const selectedWorkflows = getAllCommandIds();
1388
1282
  let mcpProvider = "ace-tool";
1389
1283
  let aceToolBaseUrl = "";
1390
1284
  let aceToolToken = "";
@@ -1465,16 +1359,16 @@ async function init(options = {}) {
1465
1359
  const routing = {
1466
1360
  frontend: {
1467
1361
  models: frontendModels,
1468
- primary: frontendModels[0],
1469
- strategy: frontendModels.length > 1 ? "parallel" : "fallback"
1362
+ primary: "gemini",
1363
+ strategy: "fallback"
1470
1364
  },
1471
1365
  backend: {
1472
1366
  models: backendModels,
1473
- primary: backendModels[0],
1474
- strategy: backendModels.length > 1 ? "parallel" : "fallback"
1367
+ primary: "codex",
1368
+ strategy: "fallback"
1475
1369
  },
1476
1370
  review: {
1477
- models: [.../* @__PURE__ */ new Set([...frontendModels, ...backendModels])],
1371
+ models: ["codex", "gemini"],
1478
1372
  strategy: "parallel"
1479
1373
  },
1480
1374
  mode
@@ -1483,10 +1377,9 @@ async function init(options = {}) {
1483
1377
  console.log(ansis.yellow("\u2501".repeat(50)));
1484
1378
  console.log(ansis.bold(` ${i18n.t("init:summary.title")}`));
1485
1379
  console.log();
1486
- console.log(` ${ansis.cyan(i18n.t("init:summary.frontendModels"))} ${frontendModels.map((m) => ansis.green(m)).join(", ")}`);
1487
- console.log(` ${ansis.cyan(i18n.t("init:summary.backendModels"))} ${backendModels.map((m) => ansis.blue(m)).join(", ")}`);
1488
- console.log(` ${ansis.cyan(i18n.t("init:summary.collaboration"))} ${ansis.yellow(mode)}`);
1489
- 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")}`);
1490
1383
  console.log(ansis.yellow("\u2501".repeat(50)));
1491
1384
  console.log();
1492
1385
  if (!options.skipPrompt) {
@@ -1681,8 +1574,6 @@ ${exportCommand}
1681
1574
  console.log();
1682
1575
  }
1683
1576
  console.log();
1684
- console.log(ansis.gray(` ${i18n.t("init:configSavedTo")} ${getCcgDir()}/config.toml`));
1685
- console.log();
1686
1577
  } catch (error) {
1687
1578
  spinner.fail(ansis.red(i18n.t("init:installFailed")));
1688
1579
  console.error(error);
@@ -2001,6 +1892,23 @@ async function uninstall() {
2001
1892
  console.log(` ${ansis.gray("\u2022")} /ccg:${cmd}`);
2002
1893
  }
2003
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
+ }
2004
1912
  } else {
2005
1913
  console.log(ansis.red(i18n.t("menu:uninstall.failed")));
2006
1914
  for (const error of result.errors) {