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/README.md +500 -483
- package/dist/cli.mjs +67 -2
- package/dist/index.mjs +1 -1
- package/dist/shared/{ccg-workflow.DaI-Qubz.mjs → ccg-workflow.DrRf2eRd.mjs} +152 -42
- package/package.json +1 -1
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
|
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 (
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
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
|
-
|
|
921
|
-
|
|
1019
|
+
const args = ["-y", "ace-tool@latest"];
|
|
1020
|
+
if (baseUrl) {
|
|
1021
|
+
args.push("--base-url", baseUrl);
|
|
922
1022
|
}
|
|
923
|
-
|
|
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
|
-
|
|
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
|
|
932
|
-
configPath:
|
|
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 };
|