fix: v2.0.2 - Node.js 安全合并 .claude.json (保留现有字段)
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) <noreply@anthropic.com>
This commit is contained in:
parent
f262f1bd21
commit
6168279f78
@ -16,7 +16,7 @@ param(
|
|||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
# ─── 版本号 (每次更新递增, build.ps1 自动读取) ──────
|
# ─── 版本号 (每次更新递增, build.ps1 自动读取) ──────
|
||||||
$BWVersion = "2.0.1"
|
$BWVersion = "2.0.2"
|
||||||
|
|
||||||
# ─── B4: 单实例保护 (防止双击两次导致竞态) ─────────
|
# ─── B4: 单实例保护 (防止双击两次导致竞态) ─────────
|
||||||
$mutexCreated = $false
|
$mutexCreated = $false
|
||||||
@ -1104,27 +1104,35 @@ if (Test-Path $templateFile) {
|
|||||||
|
|
||||||
# ── ~/.claude.json (Claude Code v2.1+ MCP 服务器配置的正确位置) ──
|
# ── ~/.claude.json (Claude Code v2.1+ MCP 服务器配置的正确位置) ──
|
||||||
# Claude Code 不再从 settings.json 读取 mcpServers, 必须写入 ~/.claude.json
|
# Claude Code 不再从 settings.json 读取 mcpServers, 必须写入 ~/.claude.json
|
||||||
|
# 用 Node.js 做 JSON 合并 (避免 PowerShell ConvertTo-Json 深度/类型陷阱)
|
||||||
$claudeJsonFile = Join-Path $env:USERPROFILE ".claude.json"
|
$claudeJsonFile = Join-Path $env:USERPROFILE ".claude.json"
|
||||||
|
$mcpTmpFile = Join-Path $env:TEMP "bw-mcp-servers.json"
|
||||||
try {
|
try {
|
||||||
|
# 从渲染后的 settings.json 提取 mcpServers 写入临时文件
|
||||||
$settingsObj = ConvertFrom-Json $content
|
$settingsObj = ConvertFrom-Json $content
|
||||||
if ($settingsObj.mcpServers) {
|
if ($settingsObj.mcpServers) {
|
||||||
$mcpOnly = @{ mcpServers = $settingsObj.mcpServers }
|
# 过滤掉 __comment 键
|
||||||
# 如果已有 .claude.json, 合并 mcpServers (保留用户自定义项)
|
$cleanMcp = @{}
|
||||||
if (Test-Path $claudeJsonFile) {
|
foreach ($prop in $settingsObj.mcpServers.PSObject.Properties) {
|
||||||
try {
|
if ($prop.Name -notlike '__*') { $cleanMcp[$prop.Name] = $prop.Value }
|
||||||
$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 { <# 解析失败则覆盖 #> }
|
[PSCustomObject]$cleanMcp | ConvertTo-Json -Depth 10 | Set-Content $mcpTmpFile -Encoding UTF8
|
||||||
}
|
|
||||||
$mcpJson = $mcpOnly | ConvertTo-Json -Depth 10
|
# Node.js 安全合并: 保留 .claude.json 所有现有字段, 只注入 mcpServers
|
||||||
Set-Content $claudeJsonFile -Value $mcpJson -Encoding UTF8
|
$mergeJs = @'
|
||||||
$mcpCount = ($settingsObj.mcpServers.PSObject.Properties | Where-Object { $_.Name -notlike '__*' }).Count
|
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 服务器)"
|
Log-OK ".claude.json 已写入 ($mcpCount 个 MCP 服务器)"
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user