feat(v3.0.11): 架构重构 — 启动链路 7 跳 → 1 跳直链
用户报障驱动 (v3.0.3-3.0.10 共 9 轮迭代后接受架构原罪). 旧架构: .lnk → bat → wt → pwsh → Base64 → DPAPI → claude (7 跳) 新架构: .lnk → pwsh → claude.ps1 (1 跳, 凭证由 profile 异步加载) ADR-001 桌面 .lnk 直调 pwsh + claude.ps1 绝对路径 - 安装时 Get-Command claude / npm config get prefix 定位 claude.ps1 - bake 进 .lnk Args, 运行时不依赖任何 PATH 重载 - 自验证: 创建后回读 .lnk 确认 Target/Args 完整, 失败立即删除拒绝交付 ADR-002 DPAPI 凭证加载迁移到 PowerShell profile sentinel - BW_CRED_START..END 块写入 ~/Documents/PowerShell/profile.ps1 - pwsh 启动自动 source, 与启动链路彻底解耦 - profile 编辑用 String.Replace 字面替换 (避开 -replace $ backreference) ADR-003 启动 / 更新功能拆分 - 启动Bookworm.lnk → 仅启动 (1 跳) - 更新Bookworm.lnk → 仅 git pull - 更新并启动Bookworm.bat → 重命名为 更新Bookworm.bat (仅同步) - tools/gen-launcher-bats.ps1 归档 (新架构不需要 Base64 生成器) 8 个失败模式中 7 个被架构性消除: ✅ F1 wt ; 切 tab (无 wt) ✅ F2 cmd 转义 (无 cmd 启动路径) ✅ F3 wt -d 引号 (无 wt -d) ✅ F4 Base64 解码语义错 (无 Base64) ✅ F5 PATH 时序 (绝对路径不依赖 PATH) ✅ F6 claude shim (直调 .ps1) ✅ F8 wt 自身 issue (无 wt) ⚠️ F7 DPAPI 跨用户 (设计限制, 跨用户需重激活) EXE 220672 → 227840 bytes (+7168, ADR-002 profile 注入函数)
This commit is contained in:
parent
609e82bac0
commit
1421338da3
173
auto-setup.ps1
173
auto-setup.ps1
@ -48,7 +48,7 @@ trap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ─── 版本号 (每次更新递增, build.ps1 自动读取) ──────
|
# ─── 版本号 (每次更新递增, build.ps1 自动读取) ──────
|
||||||
$BWVersion = "3.0.10" # hotfix: Base64 脚本 -or 括号导致 Test-Path 参数错 (gen-launcher-bats 加实跑 dry-run 防护)
|
$BWVersion = "3.0.11" # 架构重构: 桌面 .lnk 直调 pwsh+claude.ps1 (1跳直链), 凭证迁移 profile sentinel, 启动/更新拆分
|
||||||
|
|
||||||
# DryRun 模式日志标记
|
# DryRun 模式日志标记
|
||||||
if ($DryRun) { $global:BWDryRun = $DryRun } else { $global:BWDryRun = $null }
|
if ($DryRun) { $global:BWDryRun = $DryRun } else { $global:BWDryRun = $null }
|
||||||
@ -742,51 +742,172 @@ function Save-SecretsToCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Set-ItemProperty $regPath -Name "_expiry" -Value (Get-Date).Date.AddDays(1).ToUniversalTime().ToString("o") -Force
|
Set-ItemProperty $regPath -Name "_expiry" -Value (Get-Date).Date.AddDays(1).ToUniversalTime().ToString("o") -Force
|
||||||
|
# v3.0.11: 同步注入 profile.ps1 sentinel 块 (pwsh 启动时自动加载凭证, 与启动链路解耦)
|
||||||
|
try { Inject-CredentialLoaderProfile } catch { Bw-Log "WARN" "profile 凭证块注入失败: $_" }
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# v3.0.11 ADR-002: DPAPI 凭证加载迁移到 PowerShell profile
|
||||||
|
# 桌面 .lnk 直调 pwsh + claude.ps1 后, 凭证由 pwsh profile 启动 hook 自动加载,
|
||||||
|
# 完全脱离 bat/Base64 链路. profile 编辑用 String.Replace 字面替换 (不走 -replace
|
||||||
|
# 的 $ backreference 语义, 避免 v3.0.5 BW_CLIP 块踩过的同类 bug)
|
||||||
|
function Inject-CredentialLoaderProfile {
|
||||||
|
$psProfileDir = Join-Path $env:USERPROFILE "Documents\PowerShell"
|
||||||
|
if (-not (Test-Path $psProfileDir)) { New-Item -ItemType Directory -Path $psProfileDir -Force | Out-Null }
|
||||||
|
$psProfilePath = Join-Path $psProfileDir "profile.ps1"
|
||||||
|
|
||||||
|
$sentinelStart = "# BW_CRED_START v3.0.11 — 不要手动修改 (Bookworm 启动凭证 DPAPI 自动加载)"
|
||||||
|
$sentinelEnd = "# BW_CRED_END"
|
||||||
|
|
||||||
|
# 注: here-string 内 PS 变量用反引号 ` 转义保留为字面量, 由 profile 加载时再求值
|
||||||
|
$block = @"
|
||||||
|
$sentinelStart
|
||||||
|
# pwsh 启动时自动从 HKCU:\Software\Bookworm\CachedEnv 解密凭证
|
||||||
|
# 写入 Process 作用域 env, claude.ps1 启动后能直接读到 ANTHROPIC_API_KEY 等
|
||||||
|
try {
|
||||||
|
`$bwReg = 'HKCU:\Software\Bookworm\CachedEnv'
|
||||||
|
if (Test-Path `$bwReg) {
|
||||||
|
Add-Type -AssemblyName System.Security -ErrorAction Stop
|
||||||
|
(Get-ItemProperty `$bwReg -ErrorAction 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 {}
|
||||||
|
$sentinelEnd
|
||||||
|
"@
|
||||||
|
|
||||||
|
$existing = if (Test-Path $psProfilePath) { Get-Content $psProfilePath -Raw -Encoding UTF8 } else { "" }
|
||||||
|
$pattern = [regex]::Escape($sentinelStart) + "[\s\S]*?" + [regex]::Escape($sentinelEnd)
|
||||||
|
$regex = [regex]::new($pattern)
|
||||||
|
$match = $regex.Match($existing)
|
||||||
|
if ($match.Success) {
|
||||||
|
# 字面替换 — 绕过 -replace 的 $ backreference 语义
|
||||||
|
$updated = $existing.Replace($match.Value, $block)
|
||||||
|
} else {
|
||||||
|
$updated = if ($existing) { $existing.TrimEnd() + "`n`n" + $block + "`n" } else { $block + "`n" }
|
||||||
|
}
|
||||||
|
[System.IO.File]::WriteAllText($psProfilePath, $updated, [System.Text.UTF8Encoding]::new($false))
|
||||||
|
Bw-Log "OK" "BW_CRED 块已注入 PowerShell profile: $psProfilePath"
|
||||||
|
}
|
||||||
|
|
||||||
# ─── 桌面快捷方式 ──────────────────────────────────
|
# ─── 桌面快捷方式 ──────────────────────────────────
|
||||||
function New-DesktopShortcuts {
|
function New-DesktopShortcuts {
|
||||||
|
# v3.0.11 架构重构: 桌面 .lnk 直调 pwsh + claude.ps1 绝对路径
|
||||||
|
# 不再走 bat → wt → Base64 → DPAPI 7 跳链路, 消除 F1-F8 大部分失败模式
|
||||||
|
# 启动 lnk: Target=pwsh.exe, Args=-NoLogo -NoExit -File "<claude.ps1 绝对路径>" --dangerously-skip-permissions
|
||||||
|
# 更新 lnk: Target=cmd.exe, Args=/c "git pull..." (失败也不影响启动 lnk)
|
||||||
try {
|
try {
|
||||||
$shell = New-Object -ComObject WScript.Shell
|
$shell = New-Object -ComObject WScript.Shell
|
||||||
$desktop = $shell.SpecialFolders("Desktop")
|
$desktop = $shell.SpecialFolders("Desktop")
|
||||||
|
|
||||||
# 桌面专用图标 (Bookworm 蓝紫渐变 B 圆, 多尺寸 ICO)
|
# ── 1. 定位 pwsh.exe 绝对路径 ─────────────────────────
|
||||||
$iconPath = Join-Path $BootDir "bookworm-desktop.ico"
|
$pwshExe = (Get-Command pwsh -ErrorAction SilentlyContinue).Source
|
||||||
if (-not (Test-Path $iconPath)) {
|
if (-not $pwshExe -or -not (Test-Path $pwshExe)) {
|
||||||
# 回退到 EXE 图标 (bookworm.ico)
|
# 兜底候选 (winget 默认 / MSI 默认)
|
||||||
$iconPath = Join-Path $BootDir "bookworm.ico"
|
foreach ($p in @("$env:ProgramFiles\PowerShell\7\pwsh.exe", "${env:ProgramFiles(x86)}\PowerShell\7\pwsh.exe", "$env:LOCALAPPDATA\Microsoft\PowerShell\pwsh.exe")) {
|
||||||
|
if (Test-Path $p) { $pwshExe = $p; break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (-not $pwshExe -or -not (Test-Path $pwshExe)) {
|
||||||
|
Log-Fail "找不到 pwsh.exe 绝对路径, 拒绝创建桌面快捷方式 (v3.0.11 架构强依赖 pwsh)"
|
||||||
|
Show-MsgBox "无法定位 pwsh.exe 绝对路径.`n`nPowerShell 7 可能未正确安装. 请先解决 PS7 安装问题再重跑安装器." "v3.0.11 桌面快捷方式创建失败" "OK" "Error"
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
# 步骤 1: 快速启动 (bat 文件位于 bookworm-boot 仓库内)
|
# ── 2. 定位 claude.ps1 绝对路径 ───────────────────────
|
||||||
|
# 优先 Get-Command claude (运行时 PATH 里的)
|
||||||
|
$claudePs1 = $null
|
||||||
|
$claudeCmd = Get-Command claude -ErrorAction SilentlyContinue
|
||||||
|
if ($claudeCmd) {
|
||||||
|
$src = $claudeCmd.Source
|
||||||
|
if ($src -and $src.EndsWith('.ps1') -and (Test-Path $src)) { $claudePs1 = $src }
|
||||||
|
}
|
||||||
|
# 兜底 npm config get prefix
|
||||||
|
if (-not $claudePs1) {
|
||||||
|
try {
|
||||||
|
$npmPrefix = (& npm config get prefix 2>$null | Select-Object -First 1).Trim()
|
||||||
|
$candidate = Join-Path $npmPrefix "claude.ps1"
|
||||||
|
if (Test-Path $candidate) { $claudePs1 = $candidate }
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
# 最终硬编码兜底
|
||||||
|
if (-not $claudePs1) {
|
||||||
|
foreach ($p in @("$env:APPDATA\npm\claude.ps1", "$env:ProgramFiles\nodejs\claude.ps1", "$env:LOCALAPPDATA\npm\claude.ps1")) {
|
||||||
|
if (Test-Path $p) { $claudePs1 = $p; break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (-not $claudePs1 -or -not (Test-Path $claudePs1)) {
|
||||||
|
Log-Fail "找不到 claude.ps1 绝对路径, 拒绝创建桌面快捷方式"
|
||||||
|
Show-MsgBox "无法定位 claude.ps1 文件.`n`nClaude Code 可能未正确安装. 请先解决 Claude Code 安装问题 (npm i -g @anthropic-ai/claude-code) 再重跑安装器." "v3.0.11 桌面快捷方式创建失败" "OK" "Error"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Log-OK "v3.0.11 启动路径已锁定: pwsh=$pwshExe; claude.ps1=$claudePs1"
|
||||||
|
|
||||||
|
# ── 3. 桌面图标 ───────────────────────────────────────
|
||||||
|
$iconPath = Join-Path $BootDir "bookworm-desktop.ico"
|
||||||
|
if (-not (Test-Path $iconPath)) { $iconPath = Join-Path $BootDir "bookworm.ico" }
|
||||||
|
|
||||||
|
# ── 4. 启动 .lnk: 直调 pwsh + claude.ps1 (1 跳链路) ──
|
||||||
$newLnk = "$desktop\启动Bookworm.lnk"
|
$newLnk = "$desktop\启动Bookworm.lnk"
|
||||||
$shortcut = $shell.CreateShortcut($newLnk)
|
$shortcut = $shell.CreateShortcut($newLnk)
|
||||||
$batPath = Join-Path $BootDir "启动Bookworm.bat"
|
$shortcut.TargetPath = $pwshExe
|
||||||
if (-not (Test-Path $batPath)) { $batPath = Join-Path $BootDir "Bookworm-OneClick.bat" }
|
$shortcut.Arguments = "-NoLogo -NoExit -File `"$claudePs1`" --dangerously-skip-permissions"
|
||||||
$shortcut.TargetPath = $batPath
|
$shortcut.WorkingDirectory = $env:USERPROFILE
|
||||||
$shortcut.WorkingDirectory = $BootDir
|
$shortcut.Description = "Bookworm Smart Assistant (v3.0.11 直调架构)"
|
||||||
$shortcut.Description = "Bookworm Smart Assistant - 智能助手"
|
|
||||||
if (Test-Path $iconPath) { $shortcut.IconLocation = "$iconPath,0" }
|
if (Test-Path $iconPath) { $shortcut.IconLocation = "$iconPath,0" }
|
||||||
$shortcut.Save()
|
$shortcut.Save()
|
||||||
|
|
||||||
# 步骤 2: 迁移清理老 Bookworm.lnk (v3.0.3 及以前命名), 必须在新 lnk 确认存在后, 防空窗
|
# ── 5. 自验证: 读回 .lnk 确认 Target/Args 写入完整 ──
|
||||||
|
$verify = $shell.CreateShortcut($newLnk)
|
||||||
|
if ($verify.TargetPath -ne $pwshExe) {
|
||||||
|
Log-Fail "启动.lnk 自验证失败: TargetPath 不匹配 ($($verify.TargetPath) vs $pwshExe)"
|
||||||
|
Remove-Item $newLnk -Force -EA SilentlyContinue
|
||||||
|
Show-MsgBox "桌面快捷方式自验证失败 (Target 不匹配). 已删除避免坏快捷方式. 请重跑安装器." "v3.0.11 自验证失败" "OK" "Error"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ($verify.Arguments -notmatch [regex]::Escape("-File `"$claudePs1`"")) {
|
||||||
|
Log-Fail "启动.lnk 自验证失败: Arguments 不含 claude.ps1 路径"
|
||||||
|
Remove-Item $newLnk -Force -EA SilentlyContinue
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Log-OK "启动Bookworm.lnk 创建并自验证通过"
|
||||||
|
|
||||||
|
# ── 6. 迁移清理老 lnk (v3.0.3 及以前的 Bookworm.lnk) ──
|
||||||
$oldLnk = "$desktop\Bookworm.lnk"
|
$oldLnk = "$desktop\Bookworm.lnk"
|
||||||
if ((Test-Path $oldLnk) -and (Test-Path $newLnk)) {
|
if (Test-Path $oldLnk) {
|
||||||
try { Remove-Item -LiteralPath $oldLnk -Force -ErrorAction Stop; Log-OK "已清理旧快捷方式 Bookworm.lnk (迁移到「启动Bookworm」)" }
|
try { Remove-Item -LiteralPath $oldLnk -Force -ErrorAction Stop; Log-Info "已清理旧 Bookworm.lnk (迁移到 v3.0.11 架构)" } catch {}
|
||||||
catch { Log-Warn "无法清理旧 Bookworm.lnk: $_" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 更新启动
|
# ── 7. 更新 .lnk: 仅 git pull, 失败不影响启动 lnk ────
|
||||||
$shortcut2 = $shell.CreateShortcut("$desktop\更新Bookworm.lnk")
|
$updateLnk = "$desktop\更新Bookworm.lnk"
|
||||||
$updateBat = Join-Path $BootDir "更新并启动Bookworm.bat"
|
$updateBat = Join-Path $BootDir "更新Bookworm.bat"
|
||||||
if (Test-Path $updateBat) {
|
# 兼容旧名 (gen-launcher-bats 之前生成的)
|
||||||
$shortcut2.TargetPath = $updateBat
|
if (-not (Test-Path $updateBat)) {
|
||||||
$shortcut2.WorkingDirectory = $BootDir
|
$oldUpdateBat = Join-Path $BootDir "更新并启动Bookworm.bat"
|
||||||
$shortcut2.Description = "更新并启动 Bookworm"
|
if (Test-Path $oldUpdateBat) { $updateBat = $oldUpdateBat }
|
||||||
if (Test-Path $iconPath) { $shortcut2.IconLocation = "$iconPath,0" }
|
|
||||||
$shortcut2.Save()
|
|
||||||
}
|
}
|
||||||
Log-OK "桌面快捷方式已创建 (含 Bookworm 图标)"
|
if (Test-Path $updateBat) {
|
||||||
|
$u = $shell.CreateShortcut($updateLnk)
|
||||||
|
$u.TargetPath = $updateBat
|
||||||
|
$u.WorkingDirectory = $BootDir
|
||||||
|
$u.Description = "更新 Bookworm 配置 (git pull)"
|
||||||
|
if (Test-Path $iconPath) { $u.IconLocation = "$iconPath,0" }
|
||||||
|
$u.Save()
|
||||||
|
Log-OK "更新Bookworm.lnk 创建"
|
||||||
|
} else {
|
||||||
|
Log-Info "更新.bat 未找到, 跳过更新 lnk (启动 lnk 已就绪, 不影响使用)"
|
||||||
|
}
|
||||||
|
|
||||||
|
Log-OK "v3.0.11 桌面快捷方式架构 (1 跳直调) 创建完成"
|
||||||
} catch { Log-Warn "快捷方式创建失败: $_" }
|
} catch { Log-Warn "快捷方式创建失败: $_" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
85
install.ps1
85
install.ps1
@ -172,39 +172,74 @@ function Install-MissingDeps {
|
|||||||
|
|
||||||
# ─── 桌面快捷方式 ────────────────────────────────────
|
# ─── 桌面快捷方式 ────────────────────────────────────
|
||||||
function New-DesktopShortcuts {
|
function New-DesktopShortcuts {
|
||||||
|
# v3.0.11 架构重构: .lnk 直调 pwsh + claude.ps1 绝对路径 (1 跳直链)
|
||||||
$desktop = [System.Environment]::GetFolderPath("Desktop")
|
$desktop = [System.Environment]::GetFolderPath("Desktop")
|
||||||
$bootDir = $ScriptDir
|
$bootDir = $ScriptDir
|
||||||
|
|
||||||
# 步骤 1: 确保新「启动Bookworm.lnk」存在 (缺失时创建)
|
|
||||||
$lnkPath = Join-Path $desktop "启动Bookworm.lnk"
|
$lnkPath = Join-Path $desktop "启动Bookworm.lnk"
|
||||||
if (-not (Test-Path $lnkPath)) {
|
|
||||||
try {
|
# 定位 pwsh.exe
|
||||||
$shell = New-Object -ComObject WScript.Shell
|
$pwshExe = (Get-Command pwsh -ErrorAction SilentlyContinue).Source
|
||||||
$shortcut = $shell.CreateShortcut($lnkPath)
|
if (-not $pwshExe) {
|
||||||
$scriptPath = Join-Path $bootDir "install.ps1"
|
foreach ($p in @("$env:ProgramFiles\PowerShell\7\pwsh.exe", "${env:ProgramFiles(x86)}\PowerShell\7\pwsh.exe")) {
|
||||||
$hasPwsh = [bool](Get-Command pwsh -ErrorAction SilentlyContinue)
|
if (Test-Path $p) { $pwshExe = $p; break }
|
||||||
$psExe = if ($hasPwsh) { (Get-Command pwsh).Source } else { "powershell.exe" }
|
|
||||||
$shortcut.TargetPath = $psExe
|
|
||||||
$shortcut.Arguments = "-NoLogo -ExecutionPolicy Bypass -Command `"Set-Item Env:NO_PROXY 'bww.letcareme.com,code.letcareme.com,letcareme.com,localhost,127.0.0.1'; & '$scriptPath' -StartOnly -AutoAccept`""
|
|
||||||
$shortcut.WorkingDirectory = $bootDir
|
|
||||||
$shortcut.Description = "Bookworm Smart Assistant"
|
|
||||||
$shortcut.Save()
|
|
||||||
$psVer = if ($hasPwsh) { "PowerShell 7" } else { "PowerShell 5.1" }
|
|
||||||
Write-Host " [OK] 桌面快捷方式已创建: 启动Bookworm ($psVer)" -ForegroundColor Green
|
|
||||||
} catch {
|
|
||||||
Write-Host " [!] 桌面快捷方式创建失败 (不影响使用)" -ForegroundColor Gray
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (-not $pwshExe) {
|
||||||
|
Write-Host " [!] pwsh.exe 未找到, 跳过桌面快捷方式 (建议先装 PS7)" -ForegroundColor Yellow
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
# 步骤 2: 迁移清理老 Bookworm.lnk (v3.0.3 及以前命名), 必须在新 lnk 确认存在后, 防空窗
|
# 定位 claude.ps1
|
||||||
|
$claudePs1 = $null
|
||||||
|
$claudeCmd = Get-Command claude -ErrorAction SilentlyContinue
|
||||||
|
if ($claudeCmd -and $claudeCmd.Source -and $claudeCmd.Source.EndsWith('.ps1') -and (Test-Path $claudeCmd.Source)) {
|
||||||
|
$claudePs1 = $claudeCmd.Source
|
||||||
|
}
|
||||||
|
if (-not $claudePs1) {
|
||||||
|
try {
|
||||||
|
$npmPrefix = (& npm config get prefix 2>$null | Select-Object -First 1).Trim()
|
||||||
|
$candidate = Join-Path $npmPrefix "claude.ps1"
|
||||||
|
if (Test-Path $candidate) { $claudePs1 = $candidate }
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
if (-not $claudePs1) {
|
||||||
|
foreach ($p in @("$env:APPDATA\npm\claude.ps1", "$env:ProgramFiles\nodejs\claude.ps1")) {
|
||||||
|
if (Test-Path $p) { $claudePs1 = $p; break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (-not $claudePs1) {
|
||||||
|
Write-Host " [!] claude.ps1 未找到, 跳过桌面快捷方式 (Claude Code 装好后重跑可补)" -ForegroundColor Yellow
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$shell = New-Object -ComObject WScript.Shell
|
||||||
|
$shortcut = $shell.CreateShortcut($lnkPath)
|
||||||
|
$shortcut.TargetPath = $pwshExe
|
||||||
|
$shortcut.Arguments = "-NoLogo -NoExit -File `"$claudePs1`" --dangerously-skip-permissions"
|
||||||
|
$shortcut.WorkingDirectory = $env:USERPROFILE
|
||||||
|
$shortcut.Description = "Bookworm Smart Assistant (v3.0.11 直调)"
|
||||||
|
$iconPath = Join-Path $bootDir "bookworm-desktop.ico"
|
||||||
|
if (-not (Test-Path $iconPath)) { $iconPath = Join-Path $bootDir "bookworm.ico" }
|
||||||
|
if (Test-Path $iconPath) { $shortcut.IconLocation = "$iconPath,0" }
|
||||||
|
$shortcut.Save()
|
||||||
|
|
||||||
|
# 自验证
|
||||||
|
$verify = $shell.CreateShortcut($lnkPath)
|
||||||
|
if ($verify.TargetPath -eq $pwshExe -and $verify.Arguments -match [regex]::Escape($claudePs1)) {
|
||||||
|
Write-Host " [OK] 桌面快捷方式已创建: 启动Bookworm.lnk → pwsh + claude.ps1" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host " [!] 桌面快捷方式自验证失败" -ForegroundColor Yellow
|
||||||
|
Remove-Item $lnkPath -Force -EA SilentlyContinue
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host " [!] 桌面快捷方式创建失败: $_" -ForegroundColor Gray
|
||||||
|
}
|
||||||
|
|
||||||
|
# 迁移清理老 Bookworm.lnk
|
||||||
$oldLnk = Join-Path $desktop "Bookworm.lnk"
|
$oldLnk = Join-Path $desktop "Bookworm.lnk"
|
||||||
if ((Test-Path $oldLnk) -and (Test-Path $lnkPath)) {
|
if ((Test-Path $oldLnk) -and (Test-Path $lnkPath)) {
|
||||||
try {
|
try { Remove-Item -LiteralPath $oldLnk -Force -ErrorAction Stop } catch {}
|
||||||
Remove-Item -LiteralPath $oldLnk -Force -ErrorAction Stop
|
|
||||||
Write-Host " [MIGRATE] 已清理旧快捷方式 Bookworm.lnk (已替换为启动Bookworm)" -ForegroundColor DarkGray
|
|
||||||
} catch {
|
|
||||||
Write-Host " [!] 无法清理旧 Bookworm.lnk (不影响使用)" -ForegroundColor Gray
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
33
更新Bookworm.bat
Normal file
33
更新Bookworm.bat
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 > nul
|
||||||
|
cd /d "%~dp0"
|
||||||
|
:: v3.0.11 架构重构: 更新 .bat 仅做 git pull, 不启动 claude.
|
||||||
|
:: 启动 claude 由独立的 启动Bookworm.lnk → pwsh + claude.ps1 完成 (1 跳直链)
|
||||||
|
:: 这样 git pull 失败也不会拖累启动, 解耦关键
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Bookworm 配置同步
|
||||||
|
echo ============================================
|
||||||
|
echo.
|
||||||
|
|
||||||
|
:: 同步 bookworm-boot 仓库 (本目录)
|
||||||
|
echo [1/2] 同步启动器目录 (bookworm-boot)...
|
||||||
|
git pull --rebase 2>&1
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo [!] bookworm-boot git pull 失败 ^(不影响启动 lnk^)
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 同步 ~/.claude 配置仓库 (Skill/hook/agents)
|
||||||
|
echo.
|
||||||
|
echo [2/2] 同步 Claude 配置 (.claude/)...
|
||||||
|
git -C "%USERPROFILE%\.claude" pull --rebase 2>&1
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo [!] .claude git pull 失败 ^(不影响启动 lnk^)
|
||||||
|
)
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ============================================
|
||||||
|
echo 完成. 双击桌面「启动Bookworm」启动 Claude.
|
||||||
|
echo ============================================
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user