ccg-workflow 1.4.1 → 1.4.2

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/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 { r as readCcgConfig, b as initI18n, s as showMainMenu, i as init, a as i18n } from './shared/ccg-workflow.DaI-Qubz.mjs';
4
+ import { y as diagnoseMcpConfig, z as isWindows, A as readClaudeCodeConfig, B as fixWindowsMcpConfig, C as writeClaudeCodeConfig, r as readCcgConfig, b as initI18n, s as showMainMenu, i as init, a as i18n } from './shared/ccg-workflow.DrRf2eRd.mjs';
5
5
  import 'inquirer';
6
6
  import 'node:os';
7
7
  import 'pathe';
@@ -13,7 +13,66 @@ import 'smol-toml';
13
13
  import 'node:child_process';
14
14
  import 'node:util';
15
15
 
16
- const version = "1.4.1";
16
+ const version = "1.4.2";
17
+
18
+ async function diagnoseMcp() {
19
+ console.log();
20
+ console.log(ansis.cyan.bold(" \u{1F50D} MCP Configuration Diagnostics"));
21
+ console.log();
22
+ const issues = await diagnoseMcpConfig();
23
+ console.log(ansis.bold(" Diagnostic Results:"));
24
+ console.log();
25
+ for (const issue of issues) {
26
+ if (issue.startsWith("\u2705")) {
27
+ console.log(ansis.green(` ${issue}`));
28
+ } else if (issue.startsWith("\u26A0\uFE0F")) {
29
+ console.log(ansis.yellow(` ${issue}`));
30
+ } else if (issue.startsWith("\u274C")) {
31
+ console.log(ansis.red(` ${issue}`));
32
+ } else {
33
+ console.log(` ${issue}`);
34
+ }
35
+ }
36
+ if (isWindows() && issues.some((i) => i.includes("not properly wrapped"))) {
37
+ console.log();
38
+ console.log(ansis.yellow(" \u{1F4A1} Tip: Run the following command to fix Windows MCP configuration:"));
39
+ console.log(ansis.gray(" npx ccg fix-mcp"));
40
+ }
41
+ console.log();
42
+ }
43
+ async function fixMcp() {
44
+ console.log();
45
+ console.log(ansis.cyan.bold(" \u{1F527} Fixing MCP Configuration"));
46
+ console.log();
47
+ if (!isWindows()) {
48
+ console.log(ansis.yellow(" \u26A0\uFE0F This command is only needed on Windows"));
49
+ console.log();
50
+ return;
51
+ }
52
+ try {
53
+ const config = await readClaudeCodeConfig();
54
+ if (!config) {
55
+ console.log(ansis.red(" \u274C No ~/.claude.json found"));
56
+ console.log();
57
+ return;
58
+ }
59
+ if (!config.mcpServers || Object.keys(config.mcpServers).length === 0) {
60
+ console.log(ansis.yellow(" \u26A0\uFE0F No MCP servers configured"));
61
+ console.log();
62
+ return;
63
+ }
64
+ const fixedConfig = fixWindowsMcpConfig(config);
65
+ await writeClaudeCodeConfig(fixedConfig);
66
+ console.log(ansis.green(" \u2705 Windows MCP configuration fixed"));
67
+ console.log();
68
+ console.log(ansis.gray(" Run diagnostics again to verify:"));
69
+ console.log(ansis.gray(" npx ccg diagnose-mcp"));
70
+ console.log();
71
+ } catch (error) {
72
+ console.log(ansis.red(` \u274C Failed to fix MCP configuration: ${error}`));
73
+ console.log();
74
+ }
75
+ }
17
76
 
18
77
  function customizeHelp(sections) {
19
78
  sections.unshift({
@@ -87,6 +146,12 @@ async function setupCommands(cli) {
87
146
  }
88
147
  await init(options);
89
148
  });
149
+ cli.command("diagnose-mcp", "Diagnose MCP configuration issues").action(async () => {
150
+ await diagnoseMcp();
151
+ });
152
+ cli.command("fix-mcp", "Fix Windows MCP configuration issues").action(async () => {
153
+ await fixMcp();
154
+ });
90
155
  cli.help((sections) => customizeHelp(sections));
91
156
  cli.version(version);
92
157
  }
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { c as changeLanguage, v as checkForUpdates, x as compareVersions, d as createDefaultConfig, e as createDefaultRouting, g as getCcgDir, f as getConfigPath, q as getCurrentVersion, t as getLatestVersion, j as getWorkflowById, h as getWorkflowConfigs, a as i18n, i as init, b as initI18n, l as installAceTool, k as installWorkflows, o as migrateToV1_4_0, p as needsMigration, r as readCcgConfig, s as showMainMenu, n as uninstallAceTool, m as uninstallWorkflows, u as update, w as writeCcgConfig } from './shared/ccg-workflow.DaI-Qubz.mjs';
1
+ export { c as changeLanguage, v as checkForUpdates, x as compareVersions, d as createDefaultConfig, e as createDefaultRouting, g as getCcgDir, f as getConfigPath, q as getCurrentVersion, t as getLatestVersion, j as getWorkflowById, h as getWorkflowConfigs, a as i18n, i as init, b as initI18n, l as installAceTool, k as installWorkflows, o as migrateToV1_4_0, p as needsMigration, r as readCcgConfig, s as showMainMenu, n as uninstallAceTool, m as uninstallWorkflows, u as update, w as writeCcgConfig } from './shared/ccg-workflow.DrRf2eRd.mjs';
2
2
  import 'ansis';
3
3
  import 'inquirer';
4
4
  import 'node:os';
@@ -10,6 +10,127 @@ import { parse, stringify } from 'smol-toml';
10
10
  import { exec } from 'node:child_process';
11
11
  import { promisify } from 'node:util';
12
12
 
13
+ function isWindows() {
14
+ return process.platform === "win32";
15
+ }
16
+ function getMcpCommand(command) {
17
+ const needsWrapping = ["npx", "uvx", "node", "npm", "pnpm", "yarn"];
18
+ if (isWindows() && needsWrapping.includes(command)) {
19
+ return ["cmd", "/c", command];
20
+ }
21
+ return [command];
22
+ }
23
+
24
+ function getClaudeCodeConfigPath() {
25
+ return join(homedir(), ".claude.json");
26
+ }
27
+ async function readClaudeCodeConfig() {
28
+ const configPath = getClaudeCodeConfigPath();
29
+ try {
30
+ if (!await fs.pathExists(configPath)) {
31
+ return null;
32
+ }
33
+ const content = await fs.readFile(configPath, "utf-8");
34
+ return JSON.parse(content);
35
+ } catch (error) {
36
+ console.error("Failed to read Claude Code config:", error);
37
+ return null;
38
+ }
39
+ }
40
+ async function writeClaudeCodeConfig(config) {
41
+ const configPath = getClaudeCodeConfigPath();
42
+ try {
43
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
44
+ } catch (error) {
45
+ throw new Error(`Failed to write Claude Code config: ${error}`);
46
+ }
47
+ }
48
+ function applyPlatformCommand(config) {
49
+ if (isWindows() && config.command) {
50
+ const mcpCmd = getMcpCommand(config.command);
51
+ if (mcpCmd[0] === "cmd") {
52
+ const originalCommand = config.command;
53
+ const originalArgs = config.args || [];
54
+ config.command = mcpCmd[0];
55
+ config.args = [...mcpCmd.slice(1), originalCommand, ...originalArgs];
56
+ }
57
+ }
58
+ }
59
+ function buildMcpServerConfig(baseConfig, apiKey, placeholder = "YOUR_API_KEY", envVarName) {
60
+ const config = JSON.parse(JSON.stringify(baseConfig));
61
+ applyPlatformCommand(config);
62
+ {
63
+ return config;
64
+ }
65
+ }
66
+ function fixWindowsMcpConfig(config) {
67
+ if (!isWindows() || !config.mcpServers) {
68
+ return config;
69
+ }
70
+ const fixed = JSON.parse(JSON.stringify(config));
71
+ for (const [serverName, serverConfig] of Object.entries(fixed.mcpServers || {})) {
72
+ if (serverConfig && typeof serverConfig === "object" && "command" in serverConfig) {
73
+ applyPlatformCommand(serverConfig);
74
+ }
75
+ }
76
+ return fixed;
77
+ }
78
+ function mergeMcpServers(existing, newServers) {
79
+ const config = existing || { mcpServers: {} };
80
+ if (!config.mcpServers) {
81
+ config.mcpServers = {};
82
+ }
83
+ Object.assign(config.mcpServers, newServers);
84
+ return config;
85
+ }
86
+ async function backupClaudeCodeConfig() {
87
+ const configPath = getClaudeCodeConfigPath();
88
+ try {
89
+ if (!await fs.pathExists(configPath)) {
90
+ return null;
91
+ }
92
+ const backupDir = join(homedir(), ".claude", "backup");
93
+ await fs.ensureDir(backupDir);
94
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
95
+ const backupPath = join(backupDir, `claude-config-${timestamp}.json`);
96
+ await fs.copy(configPath, backupPath);
97
+ return backupPath;
98
+ } catch (error) {
99
+ console.error("Failed to backup Claude Code config:", error);
100
+ return null;
101
+ }
102
+ }
103
+ async function diagnoseMcpConfig() {
104
+ const issues = [];
105
+ const configPath = getClaudeCodeConfigPath();
106
+ if (!await fs.pathExists(configPath)) {
107
+ issues.push("\u274C ~/.claude.json does not exist");
108
+ return issues;
109
+ }
110
+ const config = await readClaudeCodeConfig();
111
+ if (!config) {
112
+ issues.push("\u274C Failed to parse ~/.claude.json");
113
+ return issues;
114
+ }
115
+ if (!config.mcpServers || Object.keys(config.mcpServers).length === 0) {
116
+ issues.push("\u26A0\uFE0F No MCP servers configured");
117
+ return issues;
118
+ }
119
+ if (isWindows()) {
120
+ for (const [name, server] of Object.entries(config.mcpServers)) {
121
+ if (server.command && ["npx", "uvx", "node"].includes(server.command)) {
122
+ if (server.command !== "cmd") {
123
+ issues.push(`\u274C ${name}: Command not properly wrapped for Windows (should use cmd /c)`);
124
+ }
125
+ }
126
+ }
127
+ }
128
+ if (issues.length === 0) {
129
+ issues.push("\u2705 MCP configuration looks good");
130
+ }
131
+ return issues;
132
+ }
133
+
13
134
  const i18n = i18next;
14
135
  const zhCN = {
15
136
  common: {
@@ -808,9 +929,6 @@ ${workflow.description}
808
929
  result.configPath = commandsDir;
809
930
  return result;
810
931
  }
811
- function getClaudeCodeConfigPath() {
812
- return join(homedir(), ".claude.json");
813
- }
814
932
  async function uninstallWorkflows(installDir) {
815
933
  const result = {
816
934
  success: true,
@@ -857,32 +975,23 @@ async function uninstallWorkflows(installDir) {
857
975
  return result;
858
976
  }
859
977
  async function uninstallAceTool() {
860
- const mcpConfigPath = getClaudeCodeConfigPath();
861
978
  try {
862
- if (!await fs.pathExists(mcpConfigPath)) {
979
+ const existingConfig = await readClaudeCodeConfig();
980
+ if (!existingConfig) {
863
981
  return {
864
982
  success: true,
865
983
  message: "No ~/.claude.json found, nothing to remove"
866
984
  };
867
985
  }
868
- const content = await fs.readFile(mcpConfigPath, "utf-8");
869
- let existingConfig;
870
- try {
871
- existingConfig = JSON.parse(content);
872
- } catch {
873
- return {
874
- success: false,
875
- message: "Failed to parse ~/.claude.json"
876
- };
877
- }
878
986
  if (!existingConfig.mcpServers || !existingConfig.mcpServers["ace-tool"]) {
879
987
  return {
880
988
  success: true,
881
989
  message: "ace-tool MCP not found in config"
882
990
  };
883
991
  }
992
+ await backupClaudeCodeConfig();
884
993
  delete existingConfig.mcpServers["ace-tool"];
885
- await fs.writeFile(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
994
+ await writeClaudeCodeConfig(existingConfig);
886
995
  return {
887
996
  success: true,
888
997
  message: "ace-tool MCP removed from ~/.claude.json"
@@ -896,40 +1005,41 @@ async function uninstallAceTool() {
896
1005
  }
897
1006
  async function installAceTool(config) {
898
1007
  const { baseUrl, token } = config;
899
- const args = ["-y", "ace-tool@latest"];
900
- if (baseUrl) {
901
- args.push("--base-url", baseUrl);
902
- }
903
- if (token) {
904
- args.push("--token", token);
905
- }
906
- const mcpConfigPath = getClaudeCodeConfigPath();
907
1008
  try {
908
- let existingConfig = {};
909
- if (await fs.pathExists(mcpConfigPath)) {
910
- try {
911
- const content = await fs.readFile(mcpConfigPath, "utf-8");
912
- existingConfig = JSON.parse(content);
913
- } catch {
914
- return {
915
- success: false,
916
- message: "Failed to parse existing ~/.claude.json - please check the file format"
917
- };
1009
+ let existingConfig = await readClaudeCodeConfig();
1010
+ if (!existingConfig) {
1011
+ existingConfig = { mcpServers: {} };
1012
+ }
1013
+ if (existingConfig.mcpServers && Object.keys(existingConfig.mcpServers).length > 0) {
1014
+ const backupPath = await backupClaudeCodeConfig();
1015
+ if (backupPath) {
1016
+ console.log(` \u2713 Backup created: ${backupPath}`);
918
1017
  }
919
1018
  }
920
- if (!existingConfig.mcpServers) {
921
- existingConfig.mcpServers = {};
1019
+ const args = ["-y", "ace-tool@latest"];
1020
+ if (baseUrl) {
1021
+ args.push("--base-url", baseUrl);
922
1022
  }
923
- existingConfig.mcpServers["ace-tool"] = {
1023
+ if (token) {
1024
+ args.push("--token", token);
1025
+ }
1026
+ const aceToolConfig = buildMcpServerConfig({
924
1027
  type: "stdio",
925
1028
  command: "npx",
926
1029
  args
927
- };
928
- await fs.writeFile(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
1030
+ });
1031
+ let mergedConfig = mergeMcpServers(existingConfig, {
1032
+ "ace-tool": aceToolConfig
1033
+ });
1034
+ if (isWindows()) {
1035
+ mergedConfig = fixWindowsMcpConfig(mergedConfig);
1036
+ console.log(" \u2713 Applied Windows MCP configuration fixes");
1037
+ }
1038
+ await writeClaudeCodeConfig(mergedConfig);
929
1039
  return {
930
1040
  success: true,
931
- message: "ace-tool MCP configured successfully in ~/.claude.json",
932
- configPath: mcpConfigPath
1041
+ message: isWindows() ? "ace-tool MCP configured successfully with Windows compatibility" : "ace-tool MCP configured successfully",
1042
+ configPath: join(homedir(), ".claude.json")
933
1043
  };
934
1044
  } catch (error) {
935
1045
  return {
@@ -1649,4 +1759,4 @@ async function uninstall() {
1649
1759
  console.log();
1650
1760
  }
1651
1761
 
1652
- 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, uninstallWorkflows as m, uninstallAceTool as n, migrateToV1_4_0 as o, needsMigration as p, getCurrentVersion as q, readCcgConfig as r, showMainMenu as s, getLatestVersion as t, update as u, checkForUpdates as v, writeCcgConfig as w, compareVersions as x };
1762
+ export { readClaudeCodeConfig as A, fixWindowsMcpConfig as B, writeClaudeCodeConfig as C, i18n as a, initI18n as b, changeLanguage as c, createDefaultConfig as d, createDefaultRouting as e, getConfigPath as f, getCcgDir as g, getWorkflowConfigs as h, init as i, getWorkflowById as j, installWorkflows as k, installAceTool as l, uninstallWorkflows as m, uninstallAceTool as n, migrateToV1_4_0 as o, needsMigration as p, getCurrentVersion as q, readCcgConfig as r, showMainMenu as s, getLatestVersion as t, update as u, checkForUpdates as v, writeCcgConfig as w, compareVersions as x, diagnoseMcpConfig as y, isWindows as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccg-workflow",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "Claude-Codex-Gemini 多模型协作系统 - 智能路由多模型开发工作流",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.17.1",