fix: v2.2.1 - Top5 鲁棒化修复 (F-09/F-12/F-17/F-19/F-22)

F-22: Phase 4 解密成功后调用 Save-SecretsToCache, 下次免授权码
F-12: 解密结果写入 env 前校验白名单 + 长度 < 512
F-19: 冲突检测改逐行匹配, 修复 Out-String 多行正则失效
F-09: boot 仓库 clone 始终弹凭证对话框, 不依赖 $cred 残留
F-17: uvx tool install 参数顺序修正 (包名在前 --python 在后)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
bookworm 2026-04-10 22:29:04 +08:00
parent 50d3ef0377
commit edee7b777e

View File

@ -16,7 +16,7 @@ param(
$ErrorActionPreference = "Stop"
# ─── 版本号 (每次更新递增, build.ps1 自动读取) ──────
$BWVersion = "2.2.0"
$BWVersion = "2.2.1"
# ─── B4: 单实例保护 (防止双击两次导致竞态) ─────────
$mutexCreated = $false
@ -964,7 +964,8 @@ if (Test-Path (Join-Path $BootDir ".git")) {
} catch { Log-Warn "boot 仓库更新失败, 使用本地版本" }
} else {
Log-Info "克隆 boot 仓库 (含解密工具与凭证)..."
if (-not $cred) { $cred = Show-GiteaCredentialDialog }
# F-09 fix: 始终弹凭证对话框, 不依赖 config 分支的 $cred 残留值
$cred = Show-GiteaCredentialDialog
$bootCloneUrl = if ($cred) { $BootUrl -replace '://', "://$([System.Uri]::EscapeDataString($cred.User)):$([System.Uri]::EscapeDataString($cred.Pass))@" } else { $BootUrl }
$r = Run-CmdWithUI "git" @("clone", "--depth", "1", $bootCloneUrl, $BootDir) "克隆 boot 仓库" 180000
if (-not (Test-Path (Join-Path $BootDir "crypto-helper.js"))) {
@ -973,6 +974,7 @@ if (Test-Path (Join-Path $BootDir ".git")) {
exit 1
}
Log-OK "boot 仓库克隆成功 → $BootDir"
Cache-GitCredentials $cred # F-09 fix: 缓存 boot 仓库凭证
}
# ========================================================================
@ -1059,16 +1061,19 @@ elseif ((Test-Path $SecretsEnc) -or (Get-ChildItem $BootDir -Filter "secrets-*.e
if (-not $line -or $line -notmatch '=') { continue }
$key = ($line -split '=', 2)[0].Trim()
$value = ($line -split '=', 2)[1].Trim()
if ($key -and $value) {
# 写入 Process (当前进程立即生效) + User (永久, 新终端也可用)
# F-12 fix: 白名单 + 长度校验, 防止 secrets.enc 被污染注入恶意 env
if ($key -and $value -and ($key -in $CacheAllowedKeys) -and ($value.Length -lt 512)) {
[System.Environment]::SetEnvironmentVariable($key, $value, "Process")
[System.Environment]::SetEnvironmentVariable($key, $value, "User")
Log-OK "已注入: $key (永久)"
$count++
} elseif ($key -and ($key -notin $CacheAllowedKeys)) {
Bw-Log "WARN" "跳过未知 key: $key (不在白名单)"
}
}
$decrypted = $null
$secretsDecrypted = $true
Save-SecretsToCache # F-22 fix: 写入 DPAPI 缓存, 下次免授权码
Show-MsgBox "授权码验证成功!`n`n$count 个凭证已写入系统环境变量 (永久生效)。`n任何终端输入 claude 即可启动,无需再次输入授权码。" "验证成功" "OK" "Information"
break
@ -1307,14 +1312,15 @@ try {
if (Test-Cmd "uvx") {
Log-Info "Python MCP 验证 (uvx)..."
$uvxPackages = @(
@{ Name = "windows-mcp"; Args = @("--python", "3.13", "windows-mcp") }
@{ Name = "atlassian"; Args = @("mcp-atlassian") }
# F-17 fix: uv tool install 参数顺序 = 包名在前, --python 在后
@{ Name = "windows-mcp"; Args = @("tool", "install", "windows-mcp", "--python", "3.13") }
@{ Name = "atlassian"; Args = @("tool", "install", "mcp-atlassian") }
)
foreach ($pkg in $uvxPackages) {
try {
$outTmp = Join-Path $env:TEMP "bw-uvx-$($pkg.Name).tmp"
$errTmp = Join-Path $env:TEMP "bw-uvx-$($pkg.Name)-err.tmp"
$installArgs = @("tool", "install") + $pkg.Args
$installArgs = $pkg.Args
$proc = Start-Process uv -ArgumentList $installArgs `
-NoNewWindow -PassThru `
-RedirectStandardOutput $outTmp `
@ -1387,8 +1393,10 @@ try {
try {
$claudeGit = Join-Path $ClaudeDir ".git"
if (Test-Path $claudeGit) {
$gitStatus = & git -C $ClaudeDir status --porcelain 2>&1 | Out-String
if ($gitStatus -match '^U|^.U') {
# F-19 fix: 逐行匹配冲突状态 (Out-String 合并后 ^ 不匹配行内)
$gitLines = & git -C $ClaudeDir status --porcelain 2>&1
$hasConflict = $gitLines | Where-Object { $_ -match '^U|^.U' }
if ($hasConflict) {
& git -C $ClaudeDir checkout --theirs . 2>&1 | Out-Null
& git -C $ClaudeDir add -A 2>&1 | Out-Null
& git -C $ClaudeDir commit -m "auto-resolve merge conflicts" 2>&1 | Out-Null