ccg-workflow 1.7.72 → 1.7.74

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 (32) hide show
  1. package/README.md +7 -2
  2. package/README.zh-CN.md +7 -2
  3. package/bin/codeagent-wrapper-darwin-amd64 +0 -0
  4. package/bin/codeagent-wrapper-darwin-arm64 +0 -0
  5. package/bin/codeagent-wrapper-linux-amd64 +0 -0
  6. package/bin/codeagent-wrapper-linux-arm64 +0 -0
  7. package/bin/codeagent-wrapper-windows-amd64.exe +0 -0
  8. package/bin/codeagent-wrapper-windows-arm64.exe +0 -0
  9. package/dist/cli.mjs +1 -1
  10. package/dist/index.d.mts +1 -0
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.mjs +1 -1
  13. package/dist/shared/{ccg-workflow.HQWqy5Tx.mjs → ccg-workflow.Cj1gMkci.mjs} +167 -22
  14. package/package.json +4 -2
  15. package/templates/commands/codex-exec.md +413 -0
  16. package/templates/commands/spec-impl.md +6 -2
  17. package/templates/commands/spec-plan.md +5 -2
  18. package/templates/commands/spec-research.md +4 -2
  19. package/templates/skills/SKILL.md +92 -0
  20. package/templates/skills/orchestration/multi-agent/SKILL.md +493 -0
  21. package/templates/skills/run_skill.js +129 -0
  22. package/templates/skills/tools/gen-docs/SKILL.md +116 -0
  23. package/templates/skills/tools/gen-docs/scripts/doc_generator.js +435 -0
  24. package/templates/skills/tools/lib/shared.js +98 -0
  25. package/templates/skills/tools/verify-change/SKILL.md +140 -0
  26. package/templates/skills/tools/verify-change/scripts/change_analyzer.js +289 -0
  27. package/templates/skills/tools/verify-module/SKILL.md +127 -0
  28. package/templates/skills/tools/verify-module/scripts/module_scanner.js +171 -0
  29. package/templates/skills/tools/verify-quality/SKILL.md +160 -0
  30. package/templates/skills/tools/verify-quality/scripts/quality_checker.js +337 -0
  31. package/templates/skills/tools/verify-security/SKILL.md +143 -0
  32. package/templates/skills/tools/verify-security/scripts/security_scanner.js +283 -0
package/README.md CHANGED
@@ -58,6 +58,7 @@ On first run, CCG will prompt you to select your preferred language (English or
58
58
  | `/ccg:team-plan` | Agent Teams constraints → parallel plan |
59
59
  | `/ccg:team-exec` | Agent Teams parallel execution |
60
60
  | `/ccg:team-review` | Agent Teams dual-model review |
61
+ | `/ccg:codex-exec` | Codex full execution (plan → code → review) |
61
62
 
62
63
  ### OPSX Spec-Driven (v1.7.52+)
63
64
 
@@ -113,8 +114,11 @@ Leverage Claude Code Agent Teams experimental feature to spawn multiple Builder
113
114
  # 2. Review the plan (editable)
114
115
  # Plan saved to .claude/plan/user-auth.md
115
116
 
116
- # 3. Execute the plan (works in new sessions too)
117
+ # 3a. Execute (Claude refactors) fine-grained control
117
118
  /ccg:execute .claude/plan/user-auth.md
119
+
120
+ # 3b. Execute (Codex does everything) — efficient, low Claude token usage
121
+ /ccg:codex-exec .claude/plan/user-auth.md
118
122
  ```
119
123
 
120
124
  ## Configuration
@@ -125,6 +129,7 @@ Leverage Claude Code Agent Teams experimental feature to spawn multiple Builder
125
129
  ~/.claude/
126
130
  ├── commands/ccg/ # Slash commands
127
131
  ├── agents/ccg/ # Sub-agents
132
+ ├── skills/ # Quality gates + multi-agent orchestration
128
133
  ├── bin/codeagent-wrapper
129
134
  └── .ccg/
130
135
  ├── config.toml
@@ -288,4 +293,4 @@ MIT
288
293
 
289
294
  ---
290
295
 
291
- v1.7.72 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
296
+ v1.7.74 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
package/README.zh-CN.md CHANGED
@@ -58,6 +58,7 @@ npx ccg-workflow
58
58
  | `/ccg:team-plan` | Agent Teams 约束 → 并行计划 |
59
59
  | `/ccg:team-exec` | Agent Teams 并行实施 |
60
60
  | `/ccg:team-review` | Agent Teams 双模型审查 |
61
+ | `/ccg:codex-exec` | Codex 全权执行(计划 → 代码 → 审核) |
61
62
 
62
63
  ### OPSX 规范驱动(v1.7.52+)
63
64
 
@@ -115,8 +116,11 @@ v1.7.39 新增 `/ccg:plan` 和 `/ccg:execute` 命令,将规划与执行解耦
115
116
  # 2. 审查计划(可修改)
116
117
  # 计划保存至 .claude/plan/user-auth.md
117
118
 
118
- # 3. 执行计划(新会话也可执行)
119
+ # 3a. 执行计划(Claude 重构)— 精细控制
119
120
  /ccg:execute .claude/plan/user-auth.md
121
+
122
+ # 3b. 执行计划(Codex 全权)— 高效执行,Claude token 极低
123
+ /ccg:codex-exec .claude/plan/user-auth.md
120
124
  ```
121
125
 
122
126
  ## 配置
@@ -127,6 +131,7 @@ v1.7.39 新增 `/ccg:plan` 和 `/ccg:execute` 命令,将规划与执行解耦
127
131
  ~/.claude/
128
132
  ├── commands/ccg/ # 斜杠命令
129
133
  ├── agents/ccg/ # 子智能体
134
+ ├── skills/ # 质量关卡 + 多 Agent 协同
130
135
  ├── bin/codeagent-wrapper
131
136
  └── .ccg/
132
137
  ├── config.toml
@@ -290,4 +295,4 @@ MIT
290
295
 
291
296
  ---
292
297
 
293
- v1.7.72 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
298
+ v1.7.74 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
Binary file
Binary file
Binary file
Binary file
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import cac from 'cac';
3
3
  import ansis from 'ansis';
4
- import { z as diagnoseMcpConfig, A as isWindows, B as readClaudeCodeConfig, C as fixWindowsMcpConfig, D as writeClaudeCodeConfig, r as readCcgConfig, b as initI18n, a as i18n, s as showMainMenu, i as init, E as configMcp, F as version } from './shared/ccg-workflow.HQWqy5Tx.mjs';
4
+ import { z as diagnoseMcpConfig, A as isWindows, B as readClaudeCodeConfig, C as fixWindowsMcpConfig, D as writeClaudeCodeConfig, r as readCcgConfig, b as initI18n, a as i18n, s as showMainMenu, i as init, E as configMcp, F as version } from './shared/ccg-workflow.Cj1gMkci.mjs';
5
5
  import 'inquirer';
6
6
  import 'node:child_process';
7
7
  import 'node:util';
package/dist/index.d.mts CHANGED
@@ -82,6 +82,7 @@ interface InstallResult {
82
82
  success: boolean;
83
83
  installedCommands: string[];
84
84
  installedPrompts: string[];
85
+ installedSkills?: number;
85
86
  errors: string[];
86
87
  configPath: string;
87
88
  binPath?: string;
package/dist/index.d.ts CHANGED
@@ -82,6 +82,7 @@ interface InstallResult {
82
82
  success: boolean;
83
83
  installedCommands: string[];
84
84
  installedPrompts: string[];
85
+ installedSkills?: number;
85
86
  errors: string[];
86
87
  configPath: string;
87
88
  binPath?: string;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { c as changeLanguage, x as checkForUpdates, y as compareVersions, d as createDefaultConfig, e as createDefaultRouting, g as getCcgDir, f as getConfigPath, t as getCurrentVersion, v as getLatestVersion, j as getWorkflowById, h as getWorkflowConfigs, a as i18n, i as init, b as initI18n, l as installAceTool, m as installAceToolRs, k as installWorkflows, p as migrateToV1_4_0, q as needsMigration, r as readCcgConfig, s as showMainMenu, o as uninstallAceTool, n as uninstallWorkflows, u as update, w as writeCcgConfig } from './shared/ccg-workflow.HQWqy5Tx.mjs';
1
+ export { c as changeLanguage, x as checkForUpdates, y as compareVersions, d as createDefaultConfig, e as createDefaultRouting, g as getCcgDir, f as getConfigPath, t as getCurrentVersion, v as getLatestVersion, j as getWorkflowById, h as getWorkflowConfigs, a as i18n, i as init, b as initI18n, l as installAceTool, m as installAceToolRs, k as installWorkflows, p as migrateToV1_4_0, q as needsMigration, r as readCcgConfig, s as showMainMenu, o as uninstallAceTool, n as uninstallWorkflows, u as update, w as writeCcgConfig } from './shared/ccg-workflow.Cj1gMkci.mjs';
2
2
  import 'ansis';
3
3
  import 'inquirer';
4
4
  import 'node:child_process';
@@ -10,7 +10,7 @@ import { parse, stringify } from 'smol-toml';
10
10
  import i18next from 'i18next';
11
11
  import ora from 'ora';
12
12
 
13
- const version = "1.7.72";
13
+ const version = "1.7.74";
14
14
 
15
15
  function isWindows() {
16
16
  return process.platform === "win32";
@@ -455,6 +455,17 @@ const WORKFLOW_CONFIGS = [
455
455
  order: 3,
456
456
  description: "\u53CC\u6A21\u578B\u4EA4\u53C9\u5BA1\u67E5\u5E76\u884C\u5B9E\u65BD\u4EA7\u51FA\uFF0C\u5206\u7EA7\u5904\u7406 Critical/Warning/Info",
457
457
  descriptionEn: "Dual-model cross-review with severity classification"
458
+ },
459
+ {
460
+ id: "codex-exec",
461
+ name: "Codex \u6267\u884C\u8BA1\u5212",
462
+ nameEn: "Codex Plan Executor",
463
+ category: "development",
464
+ commands: ["codex-exec"],
465
+ defaultSelected: true,
466
+ order: 3,
467
+ description: "\u8BFB\u53D6 /ccg:plan \u8BA1\u5212\u6587\u4EF6\uFF0CCodex \u5168\u6743\u6267\u884C + \u591A\u6A21\u578B\u5BA1\u6838",
468
+ descriptionEn: "Read plan file from /ccg:plan, Codex executes + multi-model review"
458
469
  }
459
470
  ];
460
471
  function getWorkflowConfigs() {
@@ -526,6 +537,22 @@ function replaceHomePathsInTemplate(content, installDir) {
526
537
  processed = processed.replace(/~\//g, `${normalizePath2(userHome)}/`);
527
538
  return processed;
528
539
  }
540
+ async function countInstalledSkills(skillsDir, depth = 0) {
541
+ let count = 0;
542
+ try {
543
+ const entries = await fs.readdir(skillsDir, { withFileTypes: true });
544
+ for (const entry of entries) {
545
+ const fullPath = join(skillsDir, entry.name);
546
+ if (entry.isDirectory()) {
547
+ count += await countInstalledSkills(fullPath, depth + 1);
548
+ } else if (entry.name === "SKILL.md" && depth > 0) {
549
+ count++;
550
+ }
551
+ }
552
+ } catch {
553
+ }
554
+ return count;
555
+ }
529
556
  async function installWorkflows(workflowIds, installDir, force = false, config) {
530
557
  const installConfig = {
531
558
  routing: config?.routing || {
@@ -645,25 +672,27 @@ ${workflow.description}
645
672
  const skillsDestDir = join(installDir, "skills");
646
673
  if (await fs.pathExists(skillsTemplateDir)) {
647
674
  try {
648
- const skillDirs = await fs.readdir(skillsTemplateDir);
649
- for (const skillName of skillDirs) {
650
- const srcSkillDir = join(skillsTemplateDir, skillName);
651
- const destSkillDir = join(skillsDestDir, skillName);
652
- const stat = await fs.stat(srcSkillDir);
653
- if (stat.isDirectory()) {
654
- await fs.ensureDir(destSkillDir);
655
- const files = await fs.readdir(srcSkillDir);
656
- for (const file of files) {
657
- const srcFile = join(srcSkillDir, file);
658
- const destFile = join(destSkillDir, file);
659
- if (force || !await fs.pathExists(destFile)) {
660
- const templateContent = await fs.readFile(srcFile, "utf-8");
661
- const processedContent = replaceHomePathsInTemplate(templateContent, installDir);
662
- await fs.writeFile(destFile, processedContent, "utf-8");
675
+ await fs.copy(skillsTemplateDir, skillsDestDir, {
676
+ overwrite: force,
677
+ errorOnExist: false
678
+ });
679
+ const replacePathsInDir = async (dir) => {
680
+ const entries = await fs.readdir(dir, { withFileTypes: true });
681
+ for (const entry of entries) {
682
+ const fullPath = join(dir, entry.name);
683
+ if (entry.isDirectory()) {
684
+ await replacePathsInDir(fullPath);
685
+ } else if (entry.name.endsWith(".md")) {
686
+ const content = await fs.readFile(fullPath, "utf-8");
687
+ const processed = replaceHomePathsInTemplate(content, installDir);
688
+ if (processed !== content) {
689
+ await fs.writeFile(fullPath, processed, "utf-8");
663
690
  }
664
691
  }
665
692
  }
666
- }
693
+ };
694
+ await replacePathsInDir(skillsDestDir);
695
+ result.installedSkills = await countInstalledSkills(skillsDestDir);
667
696
  } catch (error) {
668
697
  result.errors.push(`Failed to install skills: ${error}`);
669
698
  result.success = false;
@@ -727,7 +756,7 @@ async function uninstallWorkflows(installDir) {
727
756
  const commandsDir = join(installDir, "commands", "ccg");
728
757
  join(installDir, ".ccg", "prompts");
729
758
  const agentsDir = join(installDir, "agents", "ccg");
730
- const skillsDir = join(installDir, "skills", "multi-model-collaboration");
759
+ const skillsDir = join(installDir, "skills");
731
760
  const binDir = join(installDir, "bin");
732
761
  const ccgConfigDir = join(installDir, ".ccg");
733
762
  if (await fs.pathExists(commandsDir)) {
@@ -758,10 +787,20 @@ async function uninstallWorkflows(installDir) {
758
787
  }
759
788
  if (await fs.pathExists(skillsDir)) {
760
789
  try {
761
- const files = await fs.readdir(skillsDir);
762
- for (const file of files) {
763
- result.removedSkills.push(file);
764
- }
790
+ const collectSkillNames = async (dir, depth) => {
791
+ const names = [];
792
+ const entries = await fs.readdir(dir, { withFileTypes: true });
793
+ for (const entry of entries) {
794
+ if (entry.isDirectory()) {
795
+ names.push(...await collectSkillNames(join(dir, entry.name), depth + 1));
796
+ } else if (entry.name === "SKILL.md" && depth > 0) {
797
+ const parts = dir.split("/");
798
+ names.push(parts[parts.length - 1]);
799
+ }
800
+ }
801
+ return names;
802
+ };
803
+ result.removedSkills = await collectSkillNames(skillsDir, 0);
765
804
  await fs.remove(skillsDir);
766
805
  } catch (error) {
767
806
  result.errors.push(`Failed to remove skills: ${error}`);
@@ -1030,6 +1069,82 @@ async function uninstallMcpServer(id) {
1030
1069
  return { success: false, message: `Failed to uninstall ${id}: ${error}` };
1031
1070
  }
1032
1071
  }
1072
+ const CCG_MCP_IDS = /* @__PURE__ */ new Set([
1073
+ "grok-search",
1074
+ "context7",
1075
+ "ace-tool",
1076
+ "ace-tool-rs",
1077
+ "contextweaver"
1078
+ ]);
1079
+ async function syncMcpToCodex() {
1080
+ const synced = [];
1081
+ const removed = [];
1082
+ try {
1083
+ const claudeConfig = await readClaudeCodeConfig();
1084
+ const claudeMcpServers = claudeConfig?.mcpServers || {};
1085
+ const serversToSync = {};
1086
+ for (const [id, config] of Object.entries(claudeMcpServers)) {
1087
+ if (CCG_MCP_IDS.has(id) && config) {
1088
+ serversToSync[id] = config;
1089
+ }
1090
+ }
1091
+ const codexConfigDir = join(homedir(), ".codex");
1092
+ const codexConfigPath = join(codexConfigDir, "config.toml");
1093
+ await fs.ensureDir(codexConfigDir);
1094
+ let codexConfig = {};
1095
+ if (await fs.pathExists(codexConfigPath)) {
1096
+ const content = await fs.readFile(codexConfigPath, "utf-8");
1097
+ codexConfig = parse(content);
1098
+ }
1099
+ if (!codexConfig.mcp_servers) {
1100
+ codexConfig.mcp_servers = {};
1101
+ }
1102
+ for (const [id, claudeServer] of Object.entries(serversToSync)) {
1103
+ const server = claudeServer;
1104
+ const codexEntry = {};
1105
+ for (const [key, value] of Object.entries(server)) {
1106
+ if (value !== null && value !== void 0) {
1107
+ codexEntry[key] = value;
1108
+ }
1109
+ }
1110
+ codexConfig.mcp_servers[id] = codexEntry;
1111
+ synced.push(id);
1112
+ }
1113
+ for (const id of CCG_MCP_IDS) {
1114
+ if (!serversToSync[id] && codexConfig.mcp_servers[id]) {
1115
+ delete codexConfig.mcp_servers[id];
1116
+ removed.push(id);
1117
+ }
1118
+ }
1119
+ if (synced.length === 0 && removed.length === 0) {
1120
+ return {
1121
+ success: true,
1122
+ message: "No CCG MCP servers to sync or remove",
1123
+ synced: [],
1124
+ removed: []
1125
+ };
1126
+ }
1127
+ const tmpPath = `${codexConfigPath}.tmp`;
1128
+ await fs.writeFile(tmpPath, stringify(codexConfig), "utf-8");
1129
+ await fs.rename(tmpPath, codexConfigPath);
1130
+ const parts = [];
1131
+ if (synced.length > 0) parts.push(`synced: ${synced.join(", ")}`);
1132
+ if (removed.length > 0) parts.push(`removed: ${removed.join(", ")}`);
1133
+ return {
1134
+ success: true,
1135
+ message: `Codex MCP mirror complete (${parts.join("; ")})`,
1136
+ synced,
1137
+ removed
1138
+ };
1139
+ } catch (error) {
1140
+ return {
1141
+ success: false,
1142
+ message: `Failed to sync MCP to Codex: ${error}`,
1143
+ synced,
1144
+ removed
1145
+ };
1146
+ }
1147
+ }
1033
1148
 
1034
1149
  async function configMcp() {
1035
1150
  console.log();
@@ -2867,6 +2982,30 @@ async function init(options = {}) {
2867
2982
  console.log(ansis.gray(` ${grokResult.message}`));
2868
2983
  }
2869
2984
  }
2985
+ if (!options.skipMcp) {
2986
+ const context7Result = await installMcpServer(
2987
+ "context7",
2988
+ "npx",
2989
+ ["-y", "@upstash/context7-mcp@latest"]
2990
+ );
2991
+ if (context7Result.success) {
2992
+ console.log();
2993
+ console.log(` ${ansis.green("\u2713")} context7 MCP ${ansis.gray("\u2192 ~/.claude.json")}`);
2994
+ } else {
2995
+ console.log();
2996
+ console.log(` ${ansis.yellow("\u26A0")} context7 MCP install failed`);
2997
+ console.log(ansis.gray(` ${context7Result.message}`));
2998
+ }
2999
+ const codexSyncResult = await syncMcpToCodex();
3000
+ if (codexSyncResult.success && codexSyncResult.synced.length > 0) {
3001
+ console.log();
3002
+ console.log(` ${ansis.green("\u2713")} Codex MCP sync: ${codexSyncResult.synced.join(", ")} ${ansis.gray("\u2192 ~/.codex/config.toml")}`);
3003
+ } else if (!codexSyncResult.success) {
3004
+ console.log();
3005
+ console.log(` ${ansis.yellow("\u26A0")} Codex MCP sync failed`);
3006
+ console.log(ansis.gray(` ${codexSyncResult.message}`));
3007
+ }
3008
+ }
2870
3009
  const hasJq = await checkJqAvailable();
2871
3010
  if (!hasJq) {
2872
3011
  console.log();
@@ -2896,6 +3035,12 @@ async function init(options = {}) {
2896
3035
  console.log(` ${ansis.green("\u2713")} ${model}: ${roles.join(", ")}`);
2897
3036
  });
2898
3037
  }
3038
+ if (result.installedSkills && result.installedSkills > 0) {
3039
+ console.log();
3040
+ console.log(ansis.cyan(" Skills:"));
3041
+ console.log(` ${ansis.green("\u2713")} ${result.installedSkills} skills installed (quality gates + multi-agent)`);
3042
+ console.log(ansis.gray(" \u2192 ~/.claude/skills/"));
3043
+ }
2899
3044
  if (result.errors.length > 0) {
2900
3045
  console.log();
2901
3046
  console.log(ansis.red(` \u26A0 ${i18n.t("init:installationErrors")}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccg-workflow",
3
- "version": "1.7.72",
3
+ "version": "1.7.74",
4
4
  "description": "Claude + Codex + Gemini multi-model collaboration system - smart routing development workflow",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.17.1",
@@ -53,6 +53,7 @@
53
53
  "templates/commands/team-plan.md",
54
54
  "templates/commands/team-exec.md",
55
55
  "templates/commands/team-review.md",
56
+ "templates/commands/codex-exec.md",
56
57
  "templates/commands/agents/",
57
58
  "templates/prompts/codex/",
58
59
  "templates/prompts/gemini/analyzer.md",
@@ -63,7 +64,8 @@
63
64
  "templates/prompts/gemini/reviewer.md",
64
65
  "templates/prompts/gemini/tester.md",
65
66
  "templates/prompts/claude/",
66
- "templates/output-styles/"
67
+ "templates/output-styles/",
68
+ "templates/skills/"
67
69
  ],
68
70
  "scripts": {
69
71
  "dev": "tsx src/cli.ts",