fix: DPAPI凭证加密 + pwsh7路径凭证注入 + PS5.1双调用优化 + assets追踪

- install.ps1: Save-SecretsToCache 改用真正 DPAPI 加密 (System.Security.ProtectedData)
  增加 GEMINI_API_KEY 到缓存键列表
- install.ps1: Get-CachedSecrets DPAPI 解密 + 旧版明文缓存向后兼容
- 启动Bookworm.bat: pwsh7路径启动 claude 前从注册表加载 DPAPI 加密凭证
- 更新并启动Bookworm.bat: 同上 + PS5.1 回退路径从2次调用精简为1次
- assets/: 纳入版本管理 (favicon-32.png / logo-200x200.png / logo-dark.svg)
- HTML: 同步 download/guide-mac/guide-unified/guide 页面更新

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
bookworm 2026-04-06 21:49:50 +08:00
parent 2d4dea242b
commit d11b36f815
10 changed files with 153 additions and 22 deletions

BIN
assets/favicon-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

BIN
assets/logo-200x200.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

118
assets/logo-dark.svg Normal file
View File

@ -0,0 +1,118 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<defs>
<!-- ── FILTER: Center Glow ── -->
<filter id="center-glow" x="-60%" y="-60%" width="220%" height="220%">
<feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="center-glow-sm" x="-80%" y="-80%" width="260%" height="260%">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="dot-glow" x="-100%" y="-100%" width="300%" height="300%">
<feGaussianBlur in="SourceGraphic" stdDeviation="2.5" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<!-- ── RADIAL BG ── -->
<radialGradient id="bg-gradient" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#141420"/>
<stop offset="100%" stop-color="#0C0C14"/>
</radialGradient>
<!-- ── CENTER GLOW GRADIENT ── -->
<radialGradient id="center-gradient" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/>
<stop offset="30%" stop-color="#FFFFFF" stop-opacity="0.9"/>
<stop offset="60%" stop-color="#C8D8FF" stop-opacity="0.4"/>
<stop offset="100%" stop-color="#A0C0FF" stop-opacity="0"/>
</radialGradient>
<!-- ── MONOCHROME GRADIENT ── -->
<radialGradient id="mono-center" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#FFFFFF"/>
<stop offset="30%" stop-color="#FFE88A" stop-opacity="0.9"/>
<stop offset="100%" stop-color="#C8A050" stop-opacity="0"/>
</radialGradient>
<!-- ════════════════════════════════════════════
FULL QUANTUM ROTATION SYMBOL (512×512 viewBox)
Fibonacci Spiral: r = 18 × e^(bθ), b = ln(φ)/(π/2)
32 dots from outermost to center
════════════════════════════════════════════ -->
</defs>
<!-- Background -->
<rect width="512" height="512" fill="url(#bg-gradient)"/>
<!-- Golden spiral path — r(θ)=3.5×e^(0.3063θ), θ∈[0,13.5], ~2.15 turns -->
<path d="M 259.5,256 L 259.6,255.8 L 259.6,255.5 L 259.6,255.3 L 259.7,255 L 259.7,254.7 L 259.6,254.4 L 259.6,254.2 L 259.5,253.9 L 259.5,253.6 L 259.4,253.3 L 259.2,253 L 259.1,252.8 L 258.9,252.5 L 258.7,252.2 L 258.5,252 L 258.3,251.7 L 258,251.5 L 257.8,251.2 L 257.5,251 L 257.2,250.8 L 256.8,250.7 L 256.5,250.5 L 256.1,250.4 L 255.7,250.3 L 255.3,250.2 L 254.9,250.1 L 254.5,250.1 L 254,250.1 L 253.6,250.1 L 253.1,250.2 L 252.7,250.2 L 252.2,250.4 L 251.8,250.5 L 251.3,250.7 L 250.9,250.9 L 250.4,251.2 L 250,251.5 L 249.6,251.8 L 249.2,252.2 L 248.8,252.6 L 248.4,253 L 248,253.5 L 247.7,254 L 247.4,254.5 L 247.2,255.1 L 246.9,255.7 L 246.8,256.3 L 246.6,256.9 L 246.5,257.6 L 246.4,258.3 L 246.4,259 L 246.4,259.7 L 246.5,260.4 L 246.6,261.2 L 246.8,261.9 L 247.1,262.6 L 247.3,263.4 L 247.7,264.1 L 248.1,264.8 L 248.6,265.5 L 249.1,266.2 L 249.7,266.9 L 250.3,267.5 L 251,268.1 L 251.7,268.7 L 252.5,269.3 L 253.4,269.7 L 254.3,270.2 L 255.2,270.6 L 256.2,270.9 L 257.2,271.1 L 258.3,271.3 L 259.4,271.5 L 260.5,271.5 L 261.7,271.5 L 262.8,271.4 L 264,271.2 L 265.2,270.9 L 266.4,270.6 L 267.6,270.1 L 268.8,269.6 L 270,269 L 271.1,268.3 L 272.3,267.4 L 273.3,266.5 L 274.4,265.5 L 275.4,264.4 L 276.3,263.3 L 277.2,262 L 278,260.7 L 278.8,259.2 L 279.4,257.7 L 279.9,256.1 L 280.4,254.5 L 280.8,252.8 L 281,251 L 281.1,249.2 L 281.1,247.3 L 281,245.5 L 280.7,243.5 L 280.3,241.6 L 279.8,239.7 L 279.1,237.7 L 278.3,235.8 L 277.3,233.9 L 276.2,232 L 274.9,230.2 L 273.5,228.4 L 271.9,226.7 L 270.2,225 L 268.3,223.5 L 266.3,222 L 264.1,220.7 L 261.9,219.5 L 259.4,218.4 L 256.9,217.5 L 254.3,216.7 L 251.6,216.1 L 248.7,215.7 L 245.8,215.4 L 242.8,215.4 L 239.8,215.5 L 236.7,215.9 L 233.6,216.5 L 230.4,217.3 L 227.3,218.3 L 224.2,219.6 L 221.1,221.1 L 218,222.9 L 215,224.9 L 212.1,227.1 L 209.3,229.6 L 206.6,232.3 L 204.1,235.3 L 201.7,238.5 L 199.5,241.9 L 197.4,245.5 L 195.6,249.3 L 194.1,253.4 L 192.7,257.6 L 191.7,262 L 190.9,266.5 L 190.4,271.2 L 190.2,276 L 190.4,280.9 L 190.9,285.9 L 191.7,290.9 L 192.9,296 L 194.5,301.1 L 196.5,306.2 L 198.8,311.2 L 201.6,316.1 L 204.7,321 L 208.2,325.7 L 212.1,330.3 L 216.4,334.7 L 221.1,338.9 L 226.2,342.9 L 231.6,346.5 L 237.4,349.9 L 243.5,352.9 L 250,355.6 L 256.7,357.8 L 263.7,359.7 L 271,361.1 L 278.5,362 L 286.2,362.4 L 294.1,362.3 L 302.2,361.6 L 310.3,360.4 L 318.5,358.6 L 326.7,356.2 L 334.9,353.2 L 343.1,349.6 L 351.2,345.3 L 359.1,340.4 L 366.8,334.9 L 374.3,328.7 L 381.5,322 L 388.4,314.5 L 394.9,306.5 L 400.9,297.9 L 406.5,288.7 L 411.5,278.9 L 416,268.6 L 419.8,257.9 L 423,246.6 L 425.5,234.9 L 427.2,222.9 L 428.1,210.5 L 428.1,197.8 L 427.3,184.9 L 425.6,171.7 L 422.9,158.5 L 419.3,145.2 L 414.7,131.9 L 409.1,118.6 L 402.5,105.6 L 394.9,92.7 L 386.2,80.1"
fill="none" stroke="rgba(255,255,255,0.08)" stroke-width="1.5" stroke-linecap="round"/>
<!-- 48 quantum dots — mathematically placed along golden spiral -->
<!-- OUTER → teal/cyan (small dots) -->
<circle cx="386.2" cy="80.1" r="3" fill="#20E0C0" opacity="0.75"/>
<circle cx="416" cy="135.3" r="3.2" fill="#20E0C0" opacity="0.76"/>
<circle cx="427.8" cy="191.5" r="3.5" fill="#20E0C0" opacity="0.76"/>
<circle cx="423.7" cy="243.9" r="3.7" fill="#28D0D0" opacity="0.77"/>
<circle cx="406.4" cy="288.9" r="3.9" fill="#30C8E8" opacity="0.77"/>
<!-- BLUE band -->
<circle cx="379.5" cy="323.9" r="4.2" fill="#4080FF" opacity="0.78"/>
<circle cx="346.9" cy="347.7" r="4.4" fill="#4080FF" opacity="0.78"/>
<circle cx="312" cy="360.1" r="4.6" fill="#4080FF" opacity="0.79"/>
<circle cx="278.2" cy="362" r="4.9" fill="#4888FF" opacity="0.79"/>
<circle cx="248" cy="354.8" r="5.1" fill="#5070FF" opacity="0.8"/>
<!-- INDIGO band -->
<circle cx="223.3" cy="340.7" r="5.3" fill="#6060F0" opacity="0.8" filter="url(#dot-glow)"/>
<circle cx="205.3" cy="321.9" r="5.6" fill="#6060F0" opacity="0.81" filter="url(#dot-glow)"/>
<circle cx="194.4" cy="300.8" r="5.8" fill="#7050EC" opacity="0.81" filter="url(#dot-glow)"/>
<circle cx="190.3" cy="279.3" r="6" fill="#7848E8" opacity="0.82" filter="url(#dot-glow)"/>
<!-- PURPLE band -->
<circle cx="192.2" cy="259.4" r="6.3" fill="#8838E4" opacity="0.82" filter="url(#dot-glow)"/>
<circle cx="199.1" cy="242.5" r="6.5" fill="#A020E0" opacity="0.83" filter="url(#dot-glow)"/>
<circle cx="209.5" cy="229.4" r="6.7" fill="#A820E0" opacity="0.83" filter="url(#dot-glow)"/>
<circle cx="222.1" cy="220.6" r="7" fill="#B018D8" opacity="0.84" filter="url(#dot-glow)"/>
<circle cx="235.4" cy="216.1" r="7.2" fill="#B818D0" opacity="0.84" filter="url(#dot-glow)"/>
<!-- MAGENTA band -->
<circle cx="248.3" cy="215.6" r="7.4" fill="#C828C0" opacity="0.85" filter="url(#dot-glow)"/>
<circle cx="259.7" cy="218.5" r="7.7" fill="#D030A8" opacity="0.85" filter="url(#dot-glow)"/>
<circle cx="269" cy="224" r="7.9" fill="#D83898" opacity="0.86" filter="url(#dot-glow)"/>
<circle cx="275.7" cy="231.3" r="8.1" fill="#E03888" opacity="0.86" filter="url(#dot-glow)"/>
<circle cx="279.7" cy="239.4" r="8.4" fill="#E84078" opacity="0.87" filter="url(#dot-glow)"/>
<!-- HOT PINK → ORANGE transition -->
<circle cx="281.1" cy="247.6" r="8.6" fill="#F04878" opacity="0.87" filter="url(#dot-glow)"/>
<circle cx="280.2" cy="255.1" r="8.9" fill="#F05068" opacity="0.88" filter="url(#dot-glow)"/>
<circle cx="277.5" cy="261.5" r="9.1" fill="#F05858" opacity="0.88" filter="url(#dot-glow)"/>
<circle cx="273.5" cy="266.4" r="9.3" fill="#F06048" opacity="0.89" filter="url(#dot-glow)"/>
<circle cx="268.6" cy="269.7" r="9.6" fill="#F06838" opacity="0.89" filter="url(#dot-glow)"/>
<!-- ORANGE band -->
<circle cx="263.5" cy="271.3" r="9.8" fill="#FF7818" opacity="0.9" filter="url(#dot-glow)"/>
<circle cx="258.7" cy="271.4" r="10" fill="#FF8418" opacity="0.9" filter="url(#dot-glow)"/>
<circle cx="254.3" cy="270.2" r="10.3" fill="#FF9018" opacity="0.91" filter="url(#dot-glow)"/>
<circle cx="250.9" cy="268" r="10.5" fill="#FF9C18" opacity="0.91" filter="url(#dot-glow)"/>
<circle cx="248.4" cy="265.2" r="10.7" fill="#FFA820" opacity="0.92" filter="url(#dot-glow)"/>
<circle cx="246.9" cy="262.1" r="11" fill="#FFB420" opacity="0.92" filter="url(#dot-glow)"/>
<!-- GOLD band (innermost dots) -->
<circle cx="246.4" cy="259" r="11.2" fill="#FFC028" opacity="0.93" filter="url(#dot-glow)"/>
<circle cx="246.8" cy="256.2" r="11.4" fill="#FFC830" opacity="0.93" filter="url(#dot-glow)"/>
<circle cx="247.9" cy="253.8" r="11.7" fill="#FFD038" opacity="0.94" filter="url(#dot-glow)"/>
<circle cx="249.4" cy="251.9" r="11.9" fill="#FFD840" opacity="0.94" filter="url(#dot-glow)"/>
<circle cx="251.3" cy="250.7" r="12.1" fill="#FFE040" opacity="0.95" filter="url(#dot-glow)"/>
<circle cx="253.2" cy="250.1" r="12.4" fill="#FFE448" opacity="0.95" filter="url(#dot-glow)"/>
<circle cx="255.1" cy="250.1" r="12.6" fill="#FFE850" opacity="0.96" filter="url(#dot-glow)"/>
<circle cx="256.7" cy="250.6" r="12.8" fill="#FFE858" opacity="0.96" filter="url(#dot-glow)"/>
<circle cx="258" cy="251.5" r="13.1" fill="#FFE860" opacity="0.97" filter="url(#dot-glow)"/>
<circle cx="259" cy="252.5" r="13.3" fill="#FFE860" opacity="0.97" filter="url(#dot-glow)"/>
<circle cx="259.5" cy="253.7" r="13.5" fill="#FFE860" opacity="0.98" filter="url(#dot-glow)"/>
<circle cx="259.7" cy="254.9" r="13.8" fill="#FFE860" opacity="0.98" filter="url(#dot-glow)"/>
<circle cx="259.5" cy="256" r="14" fill="#FFE860" opacity="0.99" filter="url(#dot-glow)"/>
<!-- CENTER — white core with glow -->
<circle cx="256" cy="256" r="50" fill="url(#center-gradient)" filter="url(#center-glow)"/>
<circle cx="256" cy="256" r="18" fill="#FFFFFF" filter="url(#center-glow)"/>
<circle cx="256" cy="256" r="10" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -4,6 +4,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bookworm - 下载安装</title> <title>Bookworm - 下载安装</title>
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon-32.png">
<style> <style>
* { margin: 0; padding: 0; box-sizing: border-box; } * { margin: 0; padding: 0; box-sizing: border-box; }
body { body {
@ -92,7 +93,7 @@
</head> </head>
<body> <body>
<div class="card"> <div class="card">
<div class="logo">&#128218;</div> <div class="logo"><img src="assets/logo-200x200.png" alt="Bookworm" style="width:80px;height:80px;border-radius:18%;"></div>
<h1>Bookworm <span>Portable</span></h1> <h1>Bookworm <span>Portable</span></h1>
<p class="subtitle">AI 编程助手 — 一键安装,即刻使用</p> <p class="subtitle">AI 编程助手 — 一键安装,即刻使用</p>
<div class="badges"> <div class="badges">

View File

@ -4,6 +4,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bookworm Portable for Mac - 保姆式安装手册</title> <title>Bookworm Portable for Mac - 保姆式安装手册</title>
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon-32.png">
<style> <style>
:root { :root {
--bg: #0d1117; --bg: #0d1117;

View File

@ -4,6 +4,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bookworm Portable - 保姆式安装手册 (Windows + macOS)</title> <title>Bookworm Portable - 保姆式安装手册 (Windows + macOS)</title>
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon-32.png">
<style> <style>
:root { :root {
--bg: #0d1117; --bg: #0d1117;

View File

@ -4,6 +4,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bookworm Portable - 保姆式安装手册</title> <title>Bookworm Portable - 保姆式安装手册</title>
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon-32.png">
<style> <style>
:root { :root {
--bg: #0d1117; --bg: #0d1117;

View File

@ -65,14 +65,24 @@ function Get-CachedSecrets {
try { try {
$cred = cmdkey /list 2>$null | Select-String "bookworm-secrets" $cred = cmdkey /list 2>$null | Select-String "bookworm-secrets"
if ($cred) { if ($cred) {
# 从 Credential Manager 读取缓存的环境变量
$regPath = "HKCU:\Software\Bookworm\CachedEnv" $regPath = "HKCU:\Software\Bookworm\CachedEnv"
if (Test-Path $regPath) { if (Test-Path $regPath) {
Add-Type -AssemblyName System.Security
$props = Get-ItemProperty $regPath -ErrorAction SilentlyContinue $props = Get-ItemProperty $regPath -ErrorAction SilentlyContinue
$loaded = 0 $loaded = 0
foreach ($p in $props.PSObject.Properties) { foreach ($p in $props.PSObject.Properties) {
if ($p.Name -match '^[A-Z_]+$') { if ($p.Name -match '^[A-Z_]+$') {
[System.Environment]::SetEnvironmentVariable($p.Name, $p.Value, "Process") $val = $p.Value
try {
# DPAPI 解密 (Base64 → byte[] → 明文)
$bytes = [Security.Cryptography.ProtectedData]::Unprotect(
[Convert]::FromBase64String($val), $null,
[Security.Cryptography.DataProtectionScope]::CurrentUser)
$val = [Text.Encoding]::UTF8.GetString($bytes)
} catch {
# 回退: 旧版明文缓存兼容
}
[System.Environment]::SetEnvironmentVariable($p.Name, $val, "Process")
$loaded++ $loaded++
} }
} }
@ -88,21 +98,26 @@ function Get-CachedSecrets {
function Save-SecretsToCache { function Save-SecretsToCache {
try { try {
# 用 Credential Manager 标记缓存存在
cmdkey /generic:bookworm-secrets /user:bw /pass:cached 2>$null | Out-Null cmdkey /generic:bookworm-secrets /user:bw /pass:cached 2>$null | Out-Null
# 用 HKCU 注册表存凭证值 (DPAPI 保护, 仅当前用户可读)
$regPath = "HKCU:\Software\Bookworm\CachedEnv" $regPath = "HKCU:\Software\Bookworm\CachedEnv"
if (-not (Test-Path $regPath)) { New-Item $regPath -Force | Out-Null } if (-not (Test-Path $regPath)) { New-Item $regPath -Force | Out-Null }
Add-Type -AssemblyName System.Security
$envKeys = @("ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "GITHUB_PERSONAL_ACCESS_TOKEN", $envKeys = @("ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "GITHUB_PERSONAL_ACCESS_TOKEN",
"SLACK_BOT_TOKEN", "ATLASSIAN_API_TOKEN", "BROWSERBASE_API_KEY", "FIRECRAWL_API_KEY") "SLACK_BOT_TOKEN", "ATLASSIAN_API_TOKEN", "BROWSERBASE_API_KEY",
"FIRECRAWL_API_KEY", "GEMINI_API_KEY")
foreach ($k in $envKeys) { foreach ($k in $envKeys) {
$v = [System.Environment]::GetEnvironmentVariable($k, "Process") $v = [System.Environment]::GetEnvironmentVariable($k, "Process")
if ($v) { Set-ItemProperty $regPath -Name $k -Value $v -Force } if ($v) {
# DPAPI 加密: 明文 → byte[] → ProtectedData → Base64 存入注册表
$bytes = [Text.Encoding]::UTF8.GetBytes($v)
$enc = [Security.Cryptography.ProtectedData]::Protect(
$bytes, $null, [Security.Cryptography.DataProtectionScope]::CurrentUser)
Set-ItemProperty $regPath -Name $k -Value ([Convert]::ToBase64String($enc)) -Force
}
} }
# 设置过期时间 (今日 23:59:59)
$expiry = (Get-Date).Date.AddDays(1).ToString("o") $expiry = (Get-Date).Date.AddDays(1).ToString("o")
Set-ItemProperty $regPath -Name "_expiry" -Value $expiry -Force Set-ItemProperty $regPath -Name "_expiry" -Value $expiry -Force
Write-Host " [OK] 凭证已缓存至今日 23:59 (下次免密)" -ForegroundColor Green Write-Host " [OK] 凭证已缓存至今日 23:59 (DPAPI 加密, 下次免密)" -ForegroundColor Green
} catch {} } catch {}
} }

View File

@ -6,10 +6,10 @@ cd /d "%~dp0"
set NO_PROXY=bww.letcareme.com,code.letcareme.com,letcareme.com,localhost,127.0.0.1 set NO_PROXY=bww.letcareme.com,code.letcareme.com,letcareme.com,localhost,127.0.0.1
set no_proxy=%NO_PROXY% set no_proxy=%NO_PROXY%
:: 优先 pwsh7: 直接在 pwsh7 窗口运行 claude :: 优先 pwsh7: 新窗口启动 claude, 先从注册表缓存加载凭证 (DPAPI 解密)
where pwsh >nul 2>nul where pwsh >nul 2>nul
if %errorlevel% equ 0 ( if %errorlevel% equ 0 (
start "Bookworm Smart Assistant" pwsh -NoLogo -NoExit -Command "& claude --dangerously-skip-permissions" start "Bookworm Smart Assistant" pwsh -NoLogo -NoExit -Command "Add-Type -AssemblyName System.Security;$r='HKCU:\Software\Bookworm\CachedEnv';try{(Get-ItemProperty $r -EA Stop).PSObject.Properties|Where-Object{$_.Name-match'^[A-Z_]+$'}|ForEach-Object{$v=$_.Value;try{$b=[Security.Cryptography.ProtectedData]::Unprotect([Convert]::FromBase64String($v),$null,[Security.Cryptography.DataProtectionScope]::CurrentUser);$v=[Text.Encoding]::UTF8.GetString($b)}catch{};[Environment]::SetEnvironmentVariable($_.Name,$v,'Process')}}catch{};& claude --dangerously-skip-permissions"
exit exit
) )

View File

@ -6,24 +6,18 @@ cd /d "%~dp0"
set NO_PROXY=bww.letcareme.com,code.letcareme.com,letcareme.com,localhost,127.0.0.1 set NO_PROXY=bww.letcareme.com,code.letcareme.com,letcareme.com,localhost,127.0.0.1
set no_proxy=%NO_PROXY% set no_proxy=%NO_PROXY%
:: 先更新配置 (在 cmd 中完成) :: 检测 pwsh7 可用性
where pwsh >nul 2>nul where pwsh >nul 2>nul
if %errorlevel% equ 0 ( if %errorlevel% equ 0 (
:: pwsh7: 先同步配置, 再在新窗口启动 claude (从注册表缓存加载 DPAPI 凭证)
pwsh -NoLogo -ExecutionPolicy Bypass -File "%~dp0install.ps1" -AutoAccept -SkipLaunch pwsh -NoLogo -ExecutionPolicy Bypass -File "%~dp0install.ps1" -AutoAccept -SkipLaunch
) else ( start "Bookworm Smart Assistant" pwsh -NoLogo -NoExit -Command "Add-Type -AssemblyName System.Security;$r='HKCU:\Software\Bookworm\CachedEnv';try{(Get-ItemProperty $r -EA Stop).PSObject.Properties|Where-Object{$_.Name-match'^[A-Z_]+$'}|ForEach-Object{$v=$_.Value;try{$b=[Security.Cryptography.ProtectedData]::Unprotect([Convert]::FromBase64String($v),$null,[Security.Cryptography.DataProtectionScope]::CurrentUser);$v=[Text.Encoding]::UTF8.GetString($b)}catch{};[Environment]::SetEnvironmentVariable($_.Name,$v,'Process')}}catch{};& claude --dangerously-skip-permissions"
powershell -ExecutionPolicy Bypass -File "%~dp0install.ps1" -AutoAccept -SkipLaunch
)
:: 更新后在 pwsh7 新窗口启动 claude
where pwsh >nul 2>nul
if %errorlevel% equ 0 (
start "Bookworm Smart Assistant" pwsh -NoLogo -NoExit -Command "& claude --dangerously-skip-permissions"
exit exit
) )
:: 回退 PowerShell 5.1 :: 回退 PowerShell 5.1: 一次调用完成更新+加载凭证+启动 (消除双次调用)
title Bookworm Portable title Bookworm Portable
powershell -ExecutionPolicy Bypass -File "%~dp0install.ps1" -StartOnly -AutoAccept powershell -ExecutionPolicy Bypass -File "%~dp0install.ps1" -AutoAccept
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
echo. echo.
echo 启动失败,按任意键退出... echo 启动失败,按任意键退出...