ccg-workflow 1.7.10 → 1.7.12

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 CHANGED
@@ -307,7 +307,9 @@ Windows:
307
307
  <details>
308
308
  <summary><strong>Q6: 如何卸载?</strong></summary>
309
309
 
310
- **方式 1:交互式卸载**
310
+ **⚠️ 重要:根据安装方式选择卸载方法**
311
+
312
+ #### 方式 1:npx 安装用户(推荐)
311
313
 
312
314
  ```bash
313
315
  npx ccg-workflow
@@ -321,26 +323,44 @@ npx ccg-workflow
321
323
  - `~/.claude/bin/codeagent-wrapper*` - 二进制文件
322
324
  - `~/.claude/.ccg/` - 配置目录(可选保留)
323
325
 
324
- **方式 2:手动清理**
326
+ #### 方式 2:npm 全局安装用户
327
+
328
+ **如果你曾经运行过 `npm install -g ccg-workflow`,需要两步卸载:**
325
329
 
326
330
  ```bash
327
- # 删除所有安装文件
331
+ # 第 1 步:卸载工作流文件
332
+ npx ccg-workflow
333
+ # 选择 "卸载工作流"
334
+
335
+ # 第 2 步:卸载 npm 全局包(必须执行,否则 ccg 命令仍可用)
336
+ npm uninstall -g ccg-workflow
337
+ ```
338
+
339
+ **v1.7.11 新增**:系统会自动检测全局安装并提示第 2 步操作。
340
+
341
+ #### 方式 3:手动清理
342
+
343
+ ```bash
344
+ # 删除所有工作流文件
328
345
  rm -rf ~/.claude/commands/ccg
329
346
  rm -rf ~/.claude/agents/ccg
330
347
  rm -rf ~/.claude/skills/multi-model-collaboration
331
348
  rm -rf ~/.claude/bin/codeagent-wrapper*
332
349
  rm -rf ~/.claude/.ccg
333
350
 
351
+ # 如果是全局安装,还需执行
352
+ npm uninstall -g ccg-workflow
353
+
334
354
  # 清理 MCP 配置(如果安装了 ace-tool)
335
355
  # 手动编辑 ~/.claude.json 删除 ace-tool 相关配置
336
356
  ```
337
357
 
338
358
  **⚠️ 注意:npx 缓存问题**
339
359
 
340
- `ccg-workflow` 通过 npx 运行,npx 会缓存已下载的包。如果卸载后重新安装仍使用旧版本,需要清理 npx 缓存:
360
+ 如果卸载后重新安装仍使用旧版本,清理 npx 缓存:
341
361
 
342
362
  ```bash
343
- # 清理 npx 缓存(强制下载最新版本)
363
+ # 清理 npx 缓存
344
364
  npx clear-npx-cache
345
365
  # 或
346
366
  rm -rf ~/.npm/_npx
package/dist/cli.mjs CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import cac from 'cac';
3
3
  import ansis from 'ansis';
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, D as configMcp, E as version, a as i18n } from './shared/ccg-workflow.PDaIyvrx.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, D as configMcp, E as version, a as i18n } from './shared/ccg-workflow.eccEe_a4.mjs';
5
5
  import 'inquirer';
6
+ import 'node:child_process';
7
+ import 'node:util';
6
8
  import 'node:os';
7
9
  import 'pathe';
8
10
  import 'fs-extra';
@@ -10,8 +12,6 @@ import 'node:url';
10
12
  import 'i18next';
11
13
  import 'ora';
12
14
  import 'smol-toml';
13
- import 'node:child_process';
14
- import 'node:util';
15
15
 
16
16
  async function diagnoseMcp() {
17
17
  console.log();
package/dist/index.mjs CHANGED
@@ -1,6 +1,8 @@
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.PDaIyvrx.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.eccEe_a4.mjs';
2
2
  import 'ansis';
3
3
  import 'inquirer';
4
+ import 'node:child_process';
5
+ import 'node:util';
4
6
  import 'node:os';
5
7
  import 'pathe';
6
8
  import 'fs-extra';
@@ -8,5 +10,3 @@ import 'node:url';
8
10
  import 'i18next';
9
11
  import 'ora';
10
12
  import 'smol-toml';
11
- import 'node:child_process';
12
- import 'node:util';
@@ -1,5 +1,7 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
+ import { exec } from 'node:child_process';
4
+ import { promisify } from 'node:util';
3
5
  import { homedir } from 'node:os';
4
6
  import { join, dirname } from 'pathe';
5
7
  import fs from 'fs-extra';
@@ -7,10 +9,8 @@ import { fileURLToPath } from 'node:url';
7
9
  import i18next from 'i18next';
8
10
  import ora from 'ora';
9
11
  import { parse, stringify } from 'smol-toml';
10
- import { exec } from 'node:child_process';
11
- import { promisify } from 'node:util';
12
12
 
13
- const version = "1.7.10";
13
+ const version = "1.7.12";
14
14
 
15
15
  function isWindows() {
16
16
  return process.platform === "win32";
@@ -344,24 +344,30 @@ function injectConfigVariables(content, config) {
344
344
  processed = processed.replace(/\{\{ROUTING_MODE\}\}/g, routingMode);
345
345
  return processed;
346
346
  }
347
- function convertToGitBashPath(windowsPath) {
348
- if (!isWindows()) {
349
- return windowsPath;
350
- }
351
- let path = windowsPath.replace(/\\/g, "/");
352
- path = path.replace(/^([A-Z]):/i, (_, drive) => `/${drive.toLowerCase()}`);
353
- return path;
354
- }
355
347
  function replaceHomePathsInTemplate(content, installDir) {
356
348
  const userHome = homedir();
357
349
  const ccgDir = join(installDir, ".ccg");
358
350
  const binDir = join(installDir, "bin");
359
- const userHomePath = convertToGitBashPath(userHome);
360
- const ccgDirPath = convertToGitBashPath(ccgDir);
361
- const binDirPath = convertToGitBashPath(binDir);
362
- let processed = content.replace(/~\/\.claude\/\.ccg/g, ccgDirPath);
363
- processed = processed.replace(/~\/\.claude\/bin/g, binDirPath);
364
- processed = processed.replace(/~\//g, `${userHomePath}/`);
351
+ const claudeDir = installDir;
352
+ let processed = content;
353
+ if (isWindows()) {
354
+ const ccgDirWin = ccgDir.replace(/\//g, "\\");
355
+ processed = processed.replace(/~\/\.claude\/\.ccg/g, ccgDirWin);
356
+ const binDirWin = binDir.replace(/\//g, "\\");
357
+ processed = processed.replace(/~\/\.claude\/bin/g, binDirWin);
358
+ const claudeDirWin = claudeDir.replace(/\//g, "\\");
359
+ processed = processed.replace(/~\/\.claude/g, claudeDirWin);
360
+ const userHomeWin = userHome.replace(/\//g, "\\");
361
+ processed = processed.replace(/~\//g, `${userHomeWin}\\`);
362
+ processed = processed.replace(/([A-Z]):([\\/][^\s"'<>|*?\n]+)/gi, (match, drive, rest) => {
363
+ return `${drive}:${rest.replace(/\//g, "\\")}`;
364
+ });
365
+ } else {
366
+ processed = processed.replace(/~\/\.claude\/\.ccg/g, ccgDir);
367
+ processed = processed.replace(/~\/\.claude\/bin/g, binDir);
368
+ processed = processed.replace(/~\/\.claude/g, claudeDir);
369
+ processed = processed.replace(/~\//g, `${userHome}/`);
370
+ }
365
371
  return processed;
366
372
  }
367
373
  async function installWorkflows(workflowIds, installDir, force = false, config) {
@@ -1605,7 +1611,7 @@ ${exportCommand}
1605
1611
  }
1606
1612
  }
1607
1613
 
1608
- const execAsync$1 = promisify(exec);
1614
+ const execAsync$2 = promisify(exec);
1609
1615
  const __filename$1 = fileURLToPath(import.meta.url);
1610
1616
  const __dirname$1 = dirname(__filename$1);
1611
1617
  function findPackageRoot(startDir) {
@@ -1630,7 +1636,7 @@ async function getCurrentVersion() {
1630
1636
  }
1631
1637
  async function getLatestVersion(packageName = "ccg-workflow") {
1632
1638
  try {
1633
- const { stdout } = await execAsync$1(`npm view ${packageName} version`);
1639
+ const { stdout } = await execAsync$2(`npm view ${packageName} version`);
1634
1640
  return stdout.trim();
1635
1641
  } catch {
1636
1642
  return null;
@@ -1667,7 +1673,7 @@ async function checkForUpdates() {
1667
1673
  };
1668
1674
  }
1669
1675
 
1670
- const execAsync = promisify(exec);
1676
+ const execAsync$1 = promisify(exec);
1671
1677
  async function update() {
1672
1678
  console.log();
1673
1679
  console.log(ansis.cyan.bold("\u{1F504} \u68C0\u67E5\u66F4\u65B0..."));
@@ -1700,16 +1706,55 @@ async function update() {
1700
1706
  console.log(ansis.red(`\u274C \u66F4\u65B0\u5931\u8D25: ${error}`));
1701
1707
  }
1702
1708
  }
1709
+ async function checkIfGlobalInstall$1() {
1710
+ try {
1711
+ const { stdout } = await execAsync$1("npm list -g ccg-workflow --depth=0", { timeout: 5e3 });
1712
+ return stdout.includes("ccg-workflow@");
1713
+ } catch {
1714
+ return false;
1715
+ }
1716
+ }
1703
1717
  async function performUpdate(fromVersion, toVersion, isNewVersion) {
1704
1718
  console.log();
1705
1719
  console.log(ansis.yellow.bold("\u2699\uFE0F \u5F00\u59CB\u66F4\u65B0..."));
1706
1720
  console.log();
1721
+ const isGlobalInstall = await checkIfGlobalInstall$1();
1722
+ if (isGlobalInstall) {
1723
+ console.log(ansis.yellow("\u26A0\uFE0F \u68C0\u6D4B\u5230\u4F60\u662F\u901A\u8FC7 npm \u5168\u5C40\u5B89\u88C5\u7684"));
1724
+ console.log();
1725
+ console.log("\u63A8\u8350\u7684\u66F4\u65B0\u65B9\u5F0F\uFF1A");
1726
+ console.log();
1727
+ console.log(ansis.cyan(" npm install -g ccg-workflow@latest"));
1728
+ console.log();
1729
+ console.log(ansis.gray("\u8FD9\u5C06\u540C\u65F6\u66F4\u65B0\u547D\u4EE4\u548C\u5DE5\u4F5C\u6D41\u6587\u4EF6"));
1730
+ console.log();
1731
+ const { useNpmUpdate } = await inquirer.prompt([{
1732
+ type: "confirm",
1733
+ name: "useNpmUpdate",
1734
+ message: "\u6539\u7528 npm \u66F4\u65B0\uFF08\u63A8\u8350\uFF09\uFF1F",
1735
+ default: true
1736
+ }]);
1737
+ if (useNpmUpdate) {
1738
+ console.log();
1739
+ console.log(ansis.cyan("\u8BF7\u5728\u65B0\u7684\u7EC8\u7AEF\u7A97\u53E3\u4E2D\u8FD0\u884C\uFF1A"));
1740
+ console.log();
1741
+ console.log(ansis.cyan.bold(" npm install -g ccg-workflow@latest"));
1742
+ console.log();
1743
+ console.log(ansis.gray("(\u8FD0\u884C\u5B8C\u6210\u540E\uFF0C\u5F53\u524D\u7248\u672C\u5C06\u81EA\u52A8\u66F4\u65B0)"));
1744
+ console.log();
1745
+ return;
1746
+ }
1747
+ console.log();
1748
+ console.log(ansis.yellow("\u26A0\uFE0F \u7EE7\u7EED\u4F7F\u7528\u5185\u7F6E\u66F4\u65B0\uFF08\u4EC5\u66F4\u65B0\u5DE5\u4F5C\u6D41\u6587\u4EF6\uFF09"));
1749
+ console.log(ansis.gray("\u6CE8\u610F\uFF1A\u8FD9\u4E0D\u4F1A\u66F4\u65B0 ccg \u547D\u4EE4\u672C\u8EAB"));
1750
+ console.log();
1751
+ }
1707
1752
  let spinner = ora("\u6B63\u5728\u4E0B\u8F7D\u6700\u65B0\u7248\u672C...").start();
1708
1753
  try {
1709
1754
  if (process.platform === "win32") {
1710
1755
  spinner.text = "\u6B63\u5728\u6E05\u7406 npx \u7F13\u5B58...";
1711
1756
  try {
1712
- await execAsync("npx clear-npx-cache", { timeout: 1e4 });
1757
+ await execAsync$1("npx clear-npx-cache", { timeout: 1e4 });
1713
1758
  } catch {
1714
1759
  const npxCachePath = join(homedir(), ".npm", "_npx");
1715
1760
  try {
@@ -1720,7 +1765,7 @@ async function performUpdate(fromVersion, toVersion, isNewVersion) {
1720
1765
  }
1721
1766
  }
1722
1767
  spinner.text = "\u6B63\u5728\u4E0B\u8F7D\u6700\u65B0\u7248\u672C...";
1723
- await execAsync(`npx --yes ccg-workflow@latest --version`, { timeout: 6e4 });
1768
+ await execAsync$1(`npx --yes ccg-workflow@latest --version`, { timeout: 6e4 });
1724
1769
  spinner.succeed("\u6700\u65B0\u7248\u672C\u4E0B\u8F7D\u5B8C\u6210");
1725
1770
  } catch (error) {
1726
1771
  spinner.fail("\u4E0B\u8F7D\u6700\u65B0\u7248\u672C\u5931\u8D25");
@@ -1802,6 +1847,7 @@ async function performUpdate(fromVersion, toVersion, isNewVersion) {
1802
1847
  console.log();
1803
1848
  }
1804
1849
 
1850
+ const execAsync = promisify(exec);
1805
1851
  async function showMainMenu() {
1806
1852
  console.log();
1807
1853
  console.log(ansis.cyan.bold(` CCG - Claude + Codex + Gemini`));
@@ -1857,12 +1903,29 @@ function showHelp() {
1857
1903
  console.log(ansis.gray(i18n.t("menu:help.hint")));
1858
1904
  console.log();
1859
1905
  }
1906
+ async function checkIfGlobalInstall() {
1907
+ try {
1908
+ const { stdout } = await execAsync("npm list -g ccg-workflow --depth=0", { timeout: 5e3 });
1909
+ return stdout.includes("ccg-workflow@");
1910
+ } catch {
1911
+ return false;
1912
+ }
1913
+ }
1860
1914
  async function uninstall() {
1861
1915
  console.log();
1916
+ const isGlobalInstall = await checkIfGlobalInstall();
1917
+ if (isGlobalInstall) {
1918
+ console.log(ansis.yellow("\u26A0\uFE0F \u68C0\u6D4B\u5230\u4F60\u662F\u901A\u8FC7 npm \u5168\u5C40\u5B89\u88C5\u7684"));
1919
+ console.log();
1920
+ console.log("\u5B8C\u6574\u5378\u8F7D\u9700\u8981\u4E24\u6B65\uFF1A");
1921
+ console.log(` ${ansis.cyan("1. \u79FB\u9664\u5DE5\u4F5C\u6D41\u6587\u4EF6")} (\u5373\u5C06\u6267\u884C)`);
1922
+ console.log(` ${ansis.cyan("2. \u5378\u8F7D npm \u5168\u5C40\u5305")} (\u9700\u8981\u624B\u52A8\u6267\u884C)`);
1923
+ console.log();
1924
+ }
1862
1925
  const { confirm } = await inquirer.prompt([{
1863
1926
  type: "confirm",
1864
1927
  name: "confirm",
1865
- message: i18n.t("menu:uninstall.confirm"),
1928
+ message: isGlobalInstall ? "\u7EE7\u7EED\u5378\u8F7D\u5DE5\u4F5C\u6D41\u6587\u4EF6\uFF1F" : i18n.t("menu:uninstall.confirm"),
1866
1929
  default: false
1867
1930
  }]);
1868
1931
  if (!confirm) {
@@ -1880,7 +1943,7 @@ async function uninstall() {
1880
1943
  const installDir = join(homedir(), ".claude");
1881
1944
  const result = await uninstallWorkflows(installDir);
1882
1945
  if (result.success) {
1883
- console.log(ansis.green(i18n.t("menu:uninstall.success")));
1946
+ console.log(ansis.green("\u2705 \u5DE5\u4F5C\u6D41\u6587\u4EF6\u5DF2\u79FB\u9664"));
1884
1947
  if (result.removedCommands.length > 0) {
1885
1948
  console.log();
1886
1949
  console.log(ansis.cyan(i18n.t("menu:uninstall.removedCommands")));
@@ -1905,6 +1968,16 @@ async function uninstall() {
1905
1968
  console.log(ansis.cyan("\u5DF2\u79FB\u9664\u4E8C\u8FDB\u5236\u6587\u4EF6:"));
1906
1969
  console.log(` ${ansis.gray("\u2022")} codeagent-wrapper`);
1907
1970
  }
1971
+ if (isGlobalInstall) {
1972
+ console.log();
1973
+ console.log(ansis.yellow.bold("\u{1F538} \u6700\u540E\u4E00\u6B65\uFF1A\u5378\u8F7D npm \u5168\u5C40\u5305"));
1974
+ console.log();
1975
+ console.log("\u8BF7\u5728\u65B0\u7684\u7EC8\u7AEF\u7A97\u53E3\u4E2D\u8FD0\u884C\uFF1A");
1976
+ console.log();
1977
+ console.log(ansis.cyan.bold(" npm uninstall -g ccg-workflow"));
1978
+ console.log();
1979
+ console.log(ansis.gray("(\u5B8C\u6210\u540E ccg \u547D\u4EE4\u5C06\u5F7B\u5E95\u79FB\u9664)"));
1980
+ }
1908
1981
  } else {
1909
1982
  console.log(ansis.red(i18n.t("menu:uninstall.failed")));
1910
1983
  for (const error of result.errors) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccg-workflow",
3
- "version": "1.7.10",
3
+ "version": "1.7.12",
4
4
  "description": "Claude-Codex-Gemini 多模型协作系统 - 智能路由多模型开发工作流",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.17.1",