diff --git a/CHANGELOG.md b/CHANGELOG.md index 9eee4f5..c7b0ae5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,55 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- +## [1.7.10] - 2026-01-09 + +### 🐛 Bug 修复 + +**Windows 兼容性与升级体验优化** + +#### 核心修复 + +1. **修复 Windows 路径兼容性问题** + - ✅ 新增 `convertToGitBashPath` 函数,将 Windows 路径转换为 Git Bash 兼容格式 + - ✅ 修复路径从 `C:\Users\zlb\.claude\bin` 变形为 `C:Userszlb/.claude/bin` 的问题 + - ✅ 支持所有驱动器盘符(C:, D:, E: 等)自动转换为 `/c/`, `/d/`, `/e/` + - ✅ 影响所有调用 codeagent-wrapper 的命令(backend、frontend、workflow、analyze 等) + - 📝 修改文件:`src/utils/installer.ts` + +2. **修复配置迁移问题** + - ✅ `update` 命令现在会自动检测并执行从 `~/.ccg` 到 `~/.claude/.ccg` 的迁移 + - ✅ 从 v1.3.x 升级到 v1.7.x 时自动迁移配置文件和 prompts + - ✅ 显示详细的迁移日志(已迁移文件、已跳过文件、错误信息) + - 📝 修改文件:`src/commands/update.ts` + +3. **修复 Windows npx 缓存问题** + - ✅ `update` 命令在 Windows 上自动清理 npx 缓存 + - ✅ 确保更新时拉取最新版本,而不是使用缓存的旧版本 + - ✅ 先尝试 `npx clear-npx-cache`,失败则手动删除 `~/.npm/_npx` + - 📝 修改文件:`src/commands/update.ts` + +### 📝 文档改进 + +1. **完善卸载与更新文档** + - ✅ README 中增加完整的卸载说明(交互式 + 手动清理) + - ✅ **新增 npx 缓存清理说明**,解决更新后仍使用旧版本的问题 + - ✅ 提供手动清理 MCP 配置的指引 + - 📝 修改文件:`README.md` + +### 🧪 测试验证 + +- ✅ Windows 路径转换测试(6 个测试用例全部通过) +- ✅ 所有平台二进制文件已重新编译(macOS、Linux、Windows × amd64/arm64) +- ✅ TypeScript 类型检查通过 +- ✅ 构建测试通过 + +### 💡 用户价值 + +- **Windows 用户**:彻底解决路径兼容性问题,codeagent-wrapper 正常调用 +- **升级用户**:自动迁移配置 + npx 缓存清理指引,确保使用最新版本 + +--- + ## [1.6.0] - 2026-01-07 ### ✨ 功能增强 diff --git a/CLAUDE.md b/CLAUDE.md index 04fc446..7eb57c2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,12 +2,23 @@ > [根目录](../CLAUDE.md) > **skills-v2** -**Last Updated**: 2026-01-08 (v1.7.2) +**Last Updated**: 2026-01-09 (v1.7.10) --- ## 变更记录 (Changelog) +### 2026-01-09 (v1.7.10) +- 🐛 **修复 Windows 路径兼容性问题**:新增 `convertToGitBashPath` 函数,支持 Windows 路径转换(`C:\Users\...` → `/c/Users/...`) +- 🐛 **修复配置迁移问题**:update 命令现在会自动检测并执行从 `~/.ccg` 到 `~/.claude/.ccg` 的迁移 +- 🐛 **修复 Windows npx 缓存问题**:update 命令在 Windows 上自动清理 npx 缓存,确保拉取最新版本 +- 📝 **完善卸载与更新文档**:README 中新增 npx 缓存清理说明 +- 🔧 **涉及文件**: + - `src/utils/installer.ts` - 添加路径转换函数 + - `src/commands/update.ts` - 添加迁移逻辑 + Windows npx 缓存清理 + - `README.md` - 完善卸载说明 + npx 缓存清理指引 +- 🧪 **测试验证**:所有平台二进制文件已重新编译 + ### 2026-01-08 (v1.7.2) - 🐛 **修复单独调用语法**:backend/frontend 的单独调用示例现在使用正确的参数 - 📝 **使用 ROLE_FILE**:改用 ROLE_FILE 引用角色提示词,而不是硬编码 diff --git a/README.md b/README.md index 559f9b9..c9f9759 100644 --- a/README.md +++ b/README.md @@ -307,6 +307,8 @@ Windows:
Q6: 如何卸载? +**方式 1:交互式卸载** + ```bash npx ccg-workflow # 选择 "卸载工作流" @@ -316,9 +318,37 @@ npx ccg-workflow - `~/.claude/commands/ccg/` - 命令文件 - `~/.claude/agents/ccg/` - 子智能体 - `~/.claude/skills/` - skills -- `~/.claude/bin/codeagent-wrapper` - 二进制文件 +- `~/.claude/bin/codeagent-wrapper*` - 二进制文件 - `~/.claude/.ccg/` - 配置目录(可选保留) +**方式 2:手动清理** + +```bash +# 删除所有安装文件 +rm -rf ~/.claude/commands/ccg +rm -rf ~/.claude/agents/ccg +rm -rf ~/.claude/skills/multi-model-collaboration +rm -rf ~/.claude/bin/codeagent-wrapper* +rm -rf ~/.claude/.ccg + +# 清理 MCP 配置(如果安装了 ace-tool) +# 手动编辑 ~/.claude.json 删除 ace-tool 相关配置 +``` + +**⚠️ 注意:npx 缓存问题** + +`ccg-workflow` 通过 npx 运行,npx 会缓存已下载的包。如果卸载后重新安装仍使用旧版本,需要清理 npx 缓存: + +```bash +# 清理 npx 缓存(强制下载最新版本) +npx clear-npx-cache +# 或 +rm -rf ~/.npm/_npx + +# 然后重新安装 +npx ccg-workflow@latest +``` +
--- @@ -352,7 +382,7 @@ Copyright (c) 2025 fengshao1227
-**版本**: v1.7.3 | **最后更新**: 2026-01-09 +**版本**: v1.7.10 | **最后更新**: 2026-01-09 Made with ❤️ by the CCG Community diff --git a/package.json b/package.json index 915d5c1..7674be2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ccg-workflow", - "version": "1.7.9", + "version": "1.7.10", "description": "Claude-Codex-Gemini 多模型协作系统 - 智能路由多模型开发工作流", "type": "module", "packageManager": "pnpm@10.17.1", diff --git a/src/commands/update.ts b/src/commands/update.ts index 380e9bd..cf9f809 100644 --- a/src/commands/update.ts +++ b/src/commands/update.ts @@ -9,6 +9,7 @@ import { join } from 'pathe' import { checkForUpdates } from '../utils/version' import { installWorkflows } from '../utils/installer' import { readCcgConfig, writeCcgConfig } from '../utils/config' +import { migrateToV1_4_0, needsMigration } from '../utils/migration' import { i18n } from '../i18n' const execAsync = promisify(exec) @@ -155,10 +156,32 @@ async function performUpdate(fromVersion: string, toVersion: string, isNewVersio console.log(ansis.yellow.bold('⚙️ 开始更新...')) console.log() - // Step 1: Download latest package + // Step 1: Download latest package (force fresh download) let spinner = ora('正在下载最新版本...').start() try { + // Clear npx cache first to ensure we get the latest version + // This is especially important on Windows where npx caching can be aggressive + if (process.platform === 'win32') { + spinner.text = '正在清理 npx 缓存...' + try { + // Try to clear npx cache on Windows + await execAsync('npx clear-npx-cache', { timeout: 10000 }) + } + catch { + // If clear-npx-cache doesn't work, manually remove cache directory + const npxCachePath = join(homedir(), '.npm', '_npx') + try { + const fs = await import('fs-extra') + await fs.remove(npxCachePath) + } + catch { + // Cache clearing failed, but continue anyway + } + } + } + + spinner.text = '正在下载最新版本...' // Download latest package using npx with --yes flag await execAsync(`npx --yes ccg-workflow@latest --version`, { timeout: 60000 }) spinner.succeed('最新版本下载完成') @@ -169,10 +192,40 @@ async function performUpdate(fromVersion: string, toVersion: string, isNewVersio return } - // Step 2: Read current config (no reconfiguration needed - routing is fixed since v1.7.0) + // Step 2: Auto-migrate from old directory structure (if needed) + if (await needsMigration()) { + spinner = ora('检测到旧版本配置,正在迁移...').start() + const migrationResult = await migrateToV1_4_0() + + if (migrationResult.migratedFiles.length > 0) { + spinner.info(ansis.cyan('配置迁移完成:')) + console.log() + for (const file of migrationResult.migratedFiles) { + console.log(` ${ansis.green('✓')} ${file}`) + } + if (migrationResult.skipped.length > 0) { + console.log() + console.log(ansis.gray(' 已跳过:')) + for (const file of migrationResult.skipped) { + console.log(` ${ansis.gray('○')} ${file}`) + } + } + console.log() + } + + if (migrationResult.errors.length > 0) { + spinner.warn(ansis.yellow('迁移完成,但有部分错误:')) + for (const error of migrationResult.errors) { + console.log(` ${ansis.red('✗')} ${error}`) + } + console.log() + } + } + + // Step 3: Read current config (no reconfiguration needed - routing is fixed since v1.7.0) const config = await readCcgConfig() - // Step 3: Delete old workflows and install new ones + // Step 4: Delete old workflows and install new ones spinner = ora('正在更新工作流和 codeagent-wrapper 二进制...').start() try { diff --git a/src/utils/installer.ts b/src/utils/installer.ts index 2a8428d..be3506a 100644 --- a/src/utils/installer.ts +++ b/src/utils/installer.ts @@ -287,6 +287,26 @@ function injectConfigVariables(content: string, config: { return processed } +/** + * Convert Windows path to Git Bash compatible format + * C:\Users\zlb → /c/Users/zlb + * D:\code → /d/code + */ +function convertToGitBashPath(windowsPath: string): string { + if (!isWindows()) { + return windowsPath + } + + // Normalize to forward slashes first + let path = windowsPath.replace(/\\/g, '/') + + // Convert drive letter: C:/Users/... → /c/Users/... + // Match pattern: [A-Z]:/ at the start + path = path.replace(/^([A-Z]):/i, (_, drive) => `/${drive.toLowerCase()}`) + + return path +} + /** * Replace ~ paths in template content with absolute paths * This fixes Windows multi-user path resolution issues @@ -295,12 +315,21 @@ function replaceHomePathsInTemplate(content: string, installDir: string): string // Get absolute paths for replacement const userHome = homedir() const ccgDir = join(installDir, '.ccg') + const binDir = join(installDir, 'bin') + + // Convert paths to Git Bash format on Windows + const userHomePath = convertToGitBashPath(userHome) + const ccgDirPath = convertToGitBashPath(ccgDir) + const binDirPath = convertToGitBashPath(binDir) // Replace all instances of ~/.claude/.ccg with absolute path - let processed = content.replace(/~\/\.claude\/\.ccg/g, ccgDir) + let processed = content.replace(/~\/\.claude\/\.ccg/g, ccgDirPath) + + // Replace ~/.claude/bin with absolute path (for codeagent-wrapper) + processed = processed.replace(/~\/\.claude\/bin/g, binDirPath) // Replace other ~/ patterns with user home (if any) - processed = processed.replace(/~\//g, `${userHome}/`) + processed = processed.replace(/~\//g, `${userHomePath}/`) return processed }