From 0b4402d417a072d966315899f060c9d4cf1e89df Mon Sep 17 00:00:00 2001 From: bookworm Date: Sun, 26 Apr 2026 17:05:38 +0800 Subject: [PATCH] =?UTF-8?q?hotfix(v3.1.3):=20=E5=8D=B8=E8=BD=BD=E7=B2=BE?= =?UTF-8?q?=E5=87=86=E5=88=A0=E9=99=A4=20+=20=E4=BD=93=E6=A3=80=E5=87=AD?= =?UTF-8?q?=E8=AF=81=E9=93=BE=E8=B7=AF=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit W1: 卸载脚本改为只删 Bookworm 注入的 7 目录+3 文件, 保留用户自有 CLAUDE.md/memory/projects (防误杀) W2: bw-doctor [9] 改检 DPAPI→profile 注入链路, 不再检查 User 持久环境变量 (逻辑反转修正) Co-Authored-By: Claude Opus 4.6 (1M context) --- auto-setup.ps1 | 2 +- bw-doctor.ps1 | 63 ++++++++++++++++++++++++----------------- 卸载Bookworm-impl.ps1 | 31 +++++++++++++++----- 卸载Bookworm.bat | 2 +- 4 files changed, 63 insertions(+), 35 deletions(-) diff --git a/auto-setup.ps1 b/auto-setup.ps1 index fe94200..afef95c 100644 --- a/auto-setup.ps1 +++ b/auto-setup.ps1 @@ -48,7 +48,7 @@ trap { } # ─── 版本号 (每次更新递增, build.ps1 自动读取) ────── -$BWVersion = "3.1.2" # 完整生命周期: 卸载脚本 + 体检工具 + nvm探测 + 镜像fallback + log rotation + 4桌面lnk (闭合 L9/L10/L11/L12) +$BWVersion = "3.1.3" # hotfix: 卸载精准删除 (不删用户自有 ~/.claude) + 体检凭证链路检测修正 # DryRun 模式日志标记 if ($DryRun) { $global:BWDryRun = $DryRun } else { $global:BWDryRun = $null } diff --git a/bw-doctor.ps1 b/bw-doctor.ps1 index ea6fc38..5be5fff 100644 --- a/bw-doctor.ps1 +++ b/bw-doctor.ps1 @@ -1,6 +1,6 @@ <# .SYNOPSIS - Bookworm Portable 体检工具 (v3.1.2) + Bookworm Portable 体检工具 (v3.1.3) .DESCRIPTION 13 维度自检, 覆盖 auto-setup.ps1 7 阶段所有安装产物. @@ -59,11 +59,11 @@ function Test-Cmd($name) { return [bool](Get-Command $name -EA SilentlyContinue) # ── Banner ── Write-Host "" Write-Host " +------------------------------------------+" -ForegroundColor Cyan -Write-Host " | Bookworm Doctor v3.1.2 |" -ForegroundColor Cyan +Write-Host " | Bookworm Doctor v3.1.3 |" -ForegroundColor Cyan Write-Host " | 13 维度健康体检 |" -ForegroundColor Cyan Write-Host " +------------------------------------------+" -ForegroundColor Cyan Write-Host "" -Log-Doctor "=== Bookworm Doctor v3.1.2 START ===" +Log-Doctor "=== Bookworm Doctor v3.1.3 START ===" # ══════════════════════════════════════════════════════ # [1/13] PowerShell 7 @@ -275,32 +275,43 @@ if (Test-Path $clipProfile) { } # ══════════════════════════════════════════════════════ -# [9/13] 环境变量 +# [9/13] 凭证注入链路 (DPAPI → profile → 运行时 Key) # ══════════════════════════════════════════════════════ -Write-Host " [9/13] 环境变量" -ForegroundColor Cyan -$envChecks = @( - @{ Name = "ANTHROPIC_API_KEY"; Required = $true } - @{ Name = "ANTHROPIC_BASE_URL"; Required = $false } - @{ Name = "ANTHROPIC_MODEL"; Required = $false } -) -$envOK = @(); $envMissing = @(); $envOptMissing = @() -foreach ($e in $envChecks) { - $val = [Environment]::GetEnvironmentVariable($e.Name, 'User') - if ($val) { - $masked = if ($e.Name -eq 'ANTHROPIC_API_KEY') { $val.Substring(0, [Math]::Min(7, $val.Length)) + '...' } else { $val } - $envOK += "$($e.Name)=$masked" - } elseif ($e.Required) { - $envMissing += $e.Name - } else { - $envOptMissing += $e.Name - } +Write-Host " [9/13] 凭证注入链路" -ForegroundColor Cyan +# Bookworm 的设计: DPAPI 加密存 HKCU → profile.ps1 启动时解密 export → 运行时 env 可用 +# 不应检查 User 持久环境变量 (Key 明文存 User env 反而不安全) +$chainOK = $true; $chainDetail = @() + +# 环节 1: DPAPI 存储有 Key +$regPath = "HKCU:\Software\Bookworm\CachedEnv" +$dpapiHasKey = $false +if (Test-Path $regPath) { + try { + $props = Get-ItemProperty $regPath -EA SilentlyContinue + $apiKeyProp = $props.PSObject.Properties | Where-Object { $_.Name -eq 'ANTHROPIC_API_KEY' } + if ($apiKeyProp) { $dpapiHasKey = $true; $chainDetail += "DPAPI=OK" } + } catch {} } -if ($envMissing.Count -eq 0) { - $detail = ($envOK -join '; ') - if ($envOptMissing.Count -gt 0) { $detail += " (可选未设: $($envOptMissing -join ', '))" } - Report "[9] 环境变量" "PASS" $detail +if (-not $dpapiHasKey) { $chainOK = $false; $chainDetail += "DPAPI=MISSING" } + +# 环节 2: profile 有 BW_CRED 块 +$ps7Profile = Join-Path $env:USERPROFILE "Documents\PowerShell\profile.ps1" +$profileHasCred = $false +if (Test-Path $ps7Profile) { + $c = Get-Content $ps7Profile -Raw -EA SilentlyContinue + if ($c -match 'BW_CRED_START') { $profileHasCred = $true; $chainDetail += "Profile=OK" } +} +if (-not $profileHasCred) { $chainOK = $false; $chainDetail += "Profile=MISSING" } + +# 环节 3: BASE_URL (可选但推荐) +$baseUrl = [Environment]::GetEnvironmentVariable('ANTHROPIC_BASE_URL', 'User') +if (-not $baseUrl) { $baseUrl = $env:ANTHROPIC_BASE_URL } +if ($baseUrl) { $chainDetail += "BaseURL=$baseUrl" } else { $chainDetail += "BaseURL=default" } + +if ($chainOK) { + Report "[9] 凭证注入链路" "PASS" ($chainDetail -join ' → ') } else { - Report "[9] 环境变量" "FAIL" "缺失: $($envMissing -join ', ')" + Report "[9] 凭证注入链路" "FAIL" ($chainDetail -join ' → ') + " — 重跑 Bookworm-Setup.exe" } # ══════════════════════════════════════════════════════ diff --git a/卸载Bookworm-impl.ps1 b/卸载Bookworm-impl.ps1 index 7d3cc1b..ea07ea0 100644 --- a/卸载Bookworm-impl.ps1 +++ b/卸载Bookworm-impl.ps1 @@ -1,6 +1,6 @@ <# .SYNOPSIS - v3.1.2: Bookworm 完整卸载实现脚本 + v3.1.3: Bookworm 完整卸载实��脚本 .DESCRIPTION 由 卸载Bookworm.bat 调用. 集中所有 PS 清理逻辑, 避免 cmd 多行 PS 转义. @@ -25,12 +25,13 @@ Add-Type -AssemblyName System.Windows.Forms -EA SilentlyContinue $msg = "确定要卸载 Bookworm 吗?`n`n" $msg += "将删除:`n" $msg += " - 桌面 4-5 个快捷方式`n" -$msg += " - ~/.claude 配置目录 (skills/hooks/agents)`n" +$msg += " - ~/.claude 中 Bookworm 注入的内容 (skills/hooks/agents/scripts)`n" $msg += " - HKCU DPAPI 凭证缓存`n" $msg += " - PowerShell profile (PS7+PS5.1) 中的 BW_* 块`n" $msg += " - 还原截图 Toast 默认设置`n" $msg += " - ANTHROPIC_* User 环境变量`n`n" -$msg += "保留 (公共依赖, 不主动卸):`n" +$msg += "保留:`n" +$msg += " - ~/.claude/CLAUDE.md, memory/, projects/ (用户自有内容)`n" $msg += " - Node.js / Git / PowerShell 7 / Claude Code" $confirm = [System.Windows.Forms.MessageBox]::Show($msg, 'Bookworm 卸载二次确认', 'YesNo', 'Warning') @@ -53,12 +54,28 @@ foreach ($n in @('启动Bookworm.lnk','更新Bookworm.lnk','体检Bookworm.lnk', } } -# ── [2/7] ~/.claude 目录 ── -Log "[2/7] 删 ~/.claude/ (配置 + 凭证 + skills/hooks/agents)" +# ── [2/7] ~/.claude Bookworm 注入内容 (精准删除, 保留用户自有配置) ── +Log "[2/7] 清 ~/.claude/ 中 Bookworm 注入的文件" $claudeDir = Join-Path $env:USERPROFILE '.claude' if (Test-Path $claudeDir) { - try { Remove-Item $claudeDir -Recurse -Force -EA Stop; Log " ✓ 已删 $claudeDir" } - catch { Log " [!] 删除失败 (可能 claude 进程占用): $_" } + # 只删 Bookworm 管理的子目录和文件, 不删用户自己的 CLAUDE.md / memory / projects + $bwManagedDirs = @('skills', 'hooks', 'agents', 'scripts', 'constitution', 'patches', 'session-state') + foreach ($d in $bwManagedDirs) { + $dp = Join-Path $claudeDir $d + if (Test-Path $dp) { + try { Remove-Item $dp -Recurse -Force -EA Stop; Log " ✓ 删 $d/" } + catch { Log " [!] 删 $d/ 失败: $_" } + } + } + # 删 Bookworm 的配置文件 (settings.json 含 hooks 注册) + foreach ($f in @('settings.json', 'settings.local.json', 'stats-compiled.json')) { + $fp = Join-Path $claudeDir $f + if (Test-Path $fp) { + try { Remove-Item $fp -Force -EA Stop; Log " ✓ 删 $f" } + catch { Log " [!] 删 $f 失败: $_" } + } + } + Log " · 保留 ~/.claude/CLAUDE.md, memory/, projects/ (用户自有内容)" } # ── [3/7] HKCU DPAPI 凭证 + Toast 备份元数据 ── diff --git a/卸载Bookworm.bat b/卸载Bookworm.bat index d070236..1c83a2b 100644 --- a/卸载Bookworm.bat +++ b/卸载Bookworm.bat @@ -1,6 +1,6 @@ @echo off chcp 65001 > nul -:: v3.1.2: Bookworm 完整卸载脚本 +:: v3.1.3: Bookworm 完整卸载脚本 :: 删除: 桌面 .lnk × 4 / ~/.claude / DPAPI HKCU 凭证 / :: 双 profile (PS7+PS5.1) 的 BW_CRED + BW_CLIP 块 / Toast 备份还原 / :: ANTHROPIC_* User 环境变量