From 6168279f78a101e894043ce63b09920381bb127d Mon Sep 17 00:00:00 2001 From: bookworm Date: Fri, 10 Apr 2026 20:27:59 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20v2.0.2=20-=20Node.js=20=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E5=90=88=E5=B9=B6=20.claude.json=20(=E4=BF=9D?= =?UTF-8?q?=E7=95=99=E7=8E=B0=E6=9C=89=E5=AD=97=E6=AE=B5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2.0.1 的 PowerShell 合并会覆盖 .claude.json 现有字段 (installMethod/isLoggedIn), 导致 Claude Code 重新登录后又把 mcpServers 覆盖掉。 改用 Node.js JSON.parse/stringify 做精确字段合并: - 读取现有 .claude.json 全部字段 - 只注入/更新 mcpServers 键 - 过滤 __comment 键 - 保留 installMethod, isLoggedIn, completedOnboarding 等 Co-Authored-By: Claude Opus 4.6 (1M context) --- auto-setup.ps1 | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/auto-setup.ps1 b/auto-setup.ps1 index 66e83c1..bf0a926 100644 --- a/auto-setup.ps1 +++ b/auto-setup.ps1 @@ -16,7 +16,7 @@ param( $ErrorActionPreference = "Stop" # ─── 版本号 (每次更新递增, build.ps1 自动读取) ────── -$BWVersion = "2.0.1" +$BWVersion = "2.0.2" # ─── B4: 单实例保护 (防止双击两次导致竞态) ───────── $mutexCreated = $false @@ -1104,27 +1104,35 @@ if (Test-Path $templateFile) { # ── ~/.claude.json (Claude Code v2.1+ MCP 服务器配置的正确位置) ── # Claude Code 不再从 settings.json 读取 mcpServers, 必须写入 ~/.claude.json + # 用 Node.js 做 JSON 合并 (避免 PowerShell ConvertTo-Json 深度/类型陷阱) $claudeJsonFile = Join-Path $env:USERPROFILE ".claude.json" + $mcpTmpFile = Join-Path $env:TEMP "bw-mcp-servers.json" try { + # 从渲染后的 settings.json 提取 mcpServers 写入临时文件 $settingsObj = ConvertFrom-Json $content if ($settingsObj.mcpServers) { - $mcpOnly = @{ mcpServers = $settingsObj.mcpServers } - # 如果已有 .claude.json, 合并 mcpServers (保留用户自定义项) - if (Test-Path $claudeJsonFile) { - try { - $existing = Get-Content $claudeJsonFile -Raw -ErrorAction SilentlyContinue | ConvertFrom-Json - if ($existing.mcpServers) { - # 以模板为基础, 保留用户新增的 server - $merged = @{} - foreach ($prop in $existing.mcpServers.PSObject.Properties) { $merged[$prop.Name] = $prop.Value } - foreach ($prop in $settingsObj.mcpServers.PSObject.Properties) { $merged[$prop.Name] = $prop.Value } - $mcpOnly.mcpServers = [PSCustomObject]$merged - } - } catch { <# 解析失败则覆盖 #> } + # 过滤掉 __comment 键 + $cleanMcp = @{} + foreach ($prop in $settingsObj.mcpServers.PSObject.Properties) { + if ($prop.Name -notlike '__*') { $cleanMcp[$prop.Name] = $prop.Value } } - $mcpJson = $mcpOnly | ConvertTo-Json -Depth 10 - Set-Content $claudeJsonFile -Value $mcpJson -Encoding UTF8 - $mcpCount = ($settingsObj.mcpServers.PSObject.Properties | Where-Object { $_.Name -notlike '__*' }).Count + [PSCustomObject]$cleanMcp | ConvertTo-Json -Depth 10 | Set-Content $mcpTmpFile -Encoding UTF8 + + # Node.js 安全合并: 保留 .claude.json 所有现有字段, 只注入 mcpServers + $mergeJs = @' +const fs=require("fs"); +const target=process.argv[2], src=process.argv[3]; +let data={}; +try{data=JSON.parse(fs.readFileSync(target,"utf8"))}catch(e){} +const mcp=JSON.parse(fs.readFileSync(src,"utf8")); +data.mcpServers=mcp; +fs.writeFileSync(target,JSON.stringify(data,null,2),"utf8"); +const n=Object.keys(mcp).length; +console.log(n); +'@ + $nodeOut = & node -e $mergeJs -- $claudeJsonFile $mcpTmpFile 2>&1 + $mcpCount = ($nodeOut | Select-Object -First 1).ToString().Trim() + Remove-Item $mcpTmpFile -Force -ErrorAction SilentlyContinue Log-OK ".claude.json 已写入 ($mcpCount 个 MCP 服务器)" } } catch {