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.
- package/README.md +175 -408
- package/bin/codeagent-wrapper-linux-arm64 +0 -0
- package/bin/codeagent-wrapper-windows-arm64.exe +0 -0
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +1 -1
- package/dist/shared/{ccg-workflow.CjatSnB0.mjs → ccg-workflow._fNXxrRQ.mjs} +194 -286
- package/package.json +1 -1
- package/templates/commands/analyze.md +130 -57
- package/templates/commands/backend.md +92 -152
- package/templates/commands/clean-branches.md +81 -66
- package/templates/commands/commit.md +81 -117
- package/templates/commands/debug.md +117 -90
- package/templates/commands/feat.md +68 -282
- package/templates/commands/frontend.md +92 -154
- package/templates/commands/init.md +100 -36
- package/templates/commands/optimize.md +137 -70
- package/templates/commands/review.md +123 -63
- package/templates/commands/rollback.md +86 -60
- package/templates/commands/test.md +143 -54
- package/templates/commands/workflow.md +244 -0
- package/templates/commands/worktree.md +78 -226
- package/templates/commands/bugfix.md +0 -114
- package/templates/commands/code.md +0 -255
- package/templates/commands/dev.md +0 -179
- package/templates/commands/think.md +0 -102
|
@@ -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.
|
|
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: "
|
|
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: ["
|
|
155
|
+
commands: ["workflow"],
|
|
156
156
|
defaultSelected: true,
|
|
157
157
|
order: 1,
|
|
158
|
-
description: "\u5B8C\u65746\u9636\u6BB5\u5F00\u53D1\u5DE5\u4F5C\u6D41\
|
|
159
|
-
descriptionEn: "Full 6-phase development workflow
|
|
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\
|
|
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:
|
|
180
|
-
description: "\u524D\u7AEF
|
|
181
|
-
descriptionEn: "Frontend
|
|
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\
|
|
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:
|
|
191
|
-
description: "\u540E\u7AEF
|
|
192
|
-
descriptionEn: "Backend
|
|
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: "
|
|
196
|
-
name: "\
|
|
197
|
-
nameEn: "
|
|
184
|
+
id: "feat",
|
|
185
|
+
name: "\u667A\u80FD\u529F\u80FD\u5F00\u53D1",
|
|
186
|
+
nameEn: "Smart Feature Development",
|
|
198
187
|
category: "development",
|
|
199
|
-
commands: ["
|
|
188
|
+
commands: ["feat"],
|
|
200
189
|
defaultSelected: true,
|
|
201
|
-
order:
|
|
202
|
-
description: "\
|
|
203
|
-
descriptionEn: "
|
|
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:
|
|
213
|
-
description: "\u53CC\u6A21\u578B\u6280\u672F\u5206\u6790\
|
|
214
|
-
descriptionEn: "Dual-model technical analysis
|
|
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: "
|
|
218
|
-
name: "
|
|
219
|
-
nameEn: "
|
|
206
|
+
id: "debug",
|
|
207
|
+
name: "\u95EE\u9898\u8BCA\u65AD",
|
|
208
|
+
nameEn: "Debug",
|
|
220
209
|
category: "development",
|
|
221
|
-
commands: ["
|
|
210
|
+
commands: ["debug"],
|
|
222
211
|
defaultSelected: true,
|
|
223
|
-
order:
|
|
224
|
-
description: "\
|
|
225
|
-
descriptionEn: "
|
|
212
|
+
order: 6,
|
|
213
|
+
description: "\u591A\u6A21\u578B\u8BCA\u65AD + \u4FEE\u590D",
|
|
214
|
+
descriptionEn: "Multi-model diagnosis + fix"
|
|
226
215
|
},
|
|
227
216
|
{
|
|
228
|
-
id: "
|
|
229
|
-
name: "
|
|
230
|
-
nameEn: "
|
|
217
|
+
id: "optimize",
|
|
218
|
+
name: "\u6027\u80FD\u4F18\u5316",
|
|
219
|
+
nameEn: "Performance Optimization",
|
|
231
220
|
category: "development",
|
|
232
|
-
commands: ["
|
|
233
|
-
defaultSelected:
|
|
234
|
-
order:
|
|
235
|
-
description: "
|
|
236
|
-
descriptionEn: "
|
|
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: "\
|
|
241
|
-
nameEn: "
|
|
229
|
+
name: "\u6D4B\u8BD5\u751F\u6210",
|
|
230
|
+
nameEn: "Test Generation",
|
|
242
231
|
category: "development",
|
|
243
232
|
commands: ["test"],
|
|
244
|
-
defaultSelected:
|
|
245
|
-
order:
|
|
246
|
-
description: "\
|
|
247
|
-
descriptionEn: "
|
|
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: "
|
|
262
|
-
name: "
|
|
263
|
-
nameEn: "
|
|
239
|
+
id: "review",
|
|
240
|
+
name: "\u4EE3\u7801\u5BA1\u67E5",
|
|
241
|
+
nameEn: "Code Review",
|
|
264
242
|
category: "development",
|
|
265
|
-
commands: ["
|
|
266
|
-
defaultSelected:
|
|
267
|
-
order:
|
|
268
|
-
description: "
|
|
269
|
-
descriptionEn: "
|
|
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: "
|
|
273
|
-
name: "\
|
|
274
|
-
nameEn: "
|
|
275
|
-
category: "
|
|
276
|
-
commands: ["
|
|
277
|
-
defaultSelected:
|
|
278
|
-
order:
|
|
279
|
-
description: "\
|
|
280
|
-
descriptionEn: "
|
|
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 \
|
|
285
|
-
nameEn: "Git
|
|
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: "\
|
|
291
|
-
descriptionEn: "
|
|
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 \
|
|
296
|
-
nameEn: "Git
|
|
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
|
|
302
|
-
descriptionEn: "Interactive
|
|
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
|
|
307
|
-
nameEn: "Clean
|
|
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\
|
|
313
|
-
descriptionEn: "Safely
|
|
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
|
|
318
|
-
nameEn: "Git Worktree
|
|
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:
|
|
334
|
-
description: "\
|
|
335
|
-
descriptionEn: "
|
|
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
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
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, "
|
|
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(
|
|
567
|
+
if (await fs.pathExists(agentsDir)) {
|
|
591
568
|
try {
|
|
592
|
-
const files = await fs.readdir(
|
|
569
|
+
const files = await fs.readdir(agentsDir);
|
|
593
570
|
for (const file of files) {
|
|
594
|
-
await fs.remove(join(
|
|
595
|
-
result.
|
|
571
|
+
await fs.remove(join(agentsDir, file));
|
|
572
|
+
result.removedAgents.push(file.replace(".md", ""));
|
|
596
573
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
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(`
|
|
1275
|
+
console.log(ansis.gray(` \u591A\u6A21\u578B\u534F\u4F5C\u5F00\u53D1\u5DE5\u4F5C\u6D41`));
|
|
1268
1276
|
console.log();
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
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:
|
|
1469
|
-
strategy:
|
|
1362
|
+
primary: "gemini",
|
|
1363
|
+
strategy: "fallback"
|
|
1470
1364
|
},
|
|
1471
1365
|
backend: {
|
|
1472
1366
|
models: backendModels,
|
|
1473
|
-
primary:
|
|
1474
|
-
strategy:
|
|
1367
|
+
primary: "codex",
|
|
1368
|
+
strategy: "fallback"
|
|
1475
1369
|
},
|
|
1476
1370
|
review: {
|
|
1477
|
-
models: [
|
|
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(
|
|
1487
|
-
console.log(` ${ansis.cyan(
|
|
1488
|
-
console.log(` ${ansis.cyan(
|
|
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) {
|