feat: UX v1.3 - bat launchers + password retry + update detection
This commit is contained in:
parent
dc05d25230
commit
2a6bb08abb
90
install.ps1
90
install.ps1
@ -68,18 +68,25 @@ function Decrypt-Secrets {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
$password = Read-Host " 输入主密码解密凭证" -AsSecureString
|
$maxRetries = 3
|
||||||
|
for ($attempt = 1; $attempt -le $maxRetries; $attempt++) {
|
||||||
|
$label = if ($attempt -gt 1) { " 重新输入主密码 (第 $attempt/$maxRetries 次)" } else { " 输入主密码解密凭证" }
|
||||||
|
$password = Read-Host $label -AsSecureString
|
||||||
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
|
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
|
||||||
$plainPwd = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)
|
$plainPwd = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)
|
||||||
|
|
||||||
try {
|
$prevEAP = $ErrorActionPreference
|
||||||
# 通过 stdin 传入密码,避免进程列表泄露
|
$ErrorActionPreference = "Continue"
|
||||||
$decrypted = $plainPwd | & $opensslCmd enc -aes-256-cbc -d -pbkdf2 -iter 600000 -in $SecretsEnc -pass stdin 2>&1
|
$decrypted = $plainPwd | & $opensslCmd enc -aes-256-cbc -d -pbkdf2 -iter 600000 -in $SecretsEnc -pass stdin 2>&1
|
||||||
if ($LASTEXITCODE -ne 0) {
|
$decExit = $LASTEXITCODE
|
||||||
throw "解密失败,密码错误?"
|
$ErrorActionPreference = $prevEAP
|
||||||
}
|
|
||||||
|
|
||||||
# 使用 IndexOf 正确分割 key=value (value 中可能含 = 号)
|
# 清除内存中的密码
|
||||||
|
$plainPwd = $null
|
||||||
|
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
|
||||||
|
|
||||||
|
if ($decExit -eq 0 -and $decrypted) {
|
||||||
|
# 解密成功,注入环境变量
|
||||||
$decrypted -split "`n" | ForEach-Object {
|
$decrypted -split "`n" | ForEach-Object {
|
||||||
$line = $_.Trim()
|
$line = $_.Trim()
|
||||||
if ($line -and $line.Contains('=')) {
|
if ($line -and $line.Contains('=')) {
|
||||||
@ -90,20 +97,22 @@ function Decrypt-Secrets {
|
|||||||
Write-Host " [OK] 已注入: $key" -ForegroundColor Green
|
Write-Host " [OK] 已注入: $key" -ForegroundColor Green
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
catch {
|
|
||||||
Write-Host " [ERROR] 凭证解密失败: $_" -ForegroundColor Red
|
# 解密失败
|
||||||
# 检查关键凭证是否存在
|
$remaining = $maxRetries - $attempt
|
||||||
if (-not $env:ANTHROPIC_API_KEY) {
|
if ($remaining -gt 0) {
|
||||||
Write-Host " [WARN] ANTHROPIC_API_KEY 未设置,Claude Code 可能无法使用中转站" -ForegroundColor Yellow
|
Write-Host " [!!] 密码错误,剩余重试: $remaining 次" -ForegroundColor Red
|
||||||
$continue = Read-Host " 继续启动? (y/n)"
|
|
||||||
if ($continue -ne 'y') { exit 1 }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
$plainPwd = $null
|
# 3次全部失败
|
||||||
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
|
Write-Host ""
|
||||||
}
|
Write-Host " [ABORT] 3 次密码均错误" -ForegroundColor Red
|
||||||
|
Write-Host " 请确认主密码是否正确 (区分大小写,至少12位)" -ForegroundColor Yellow
|
||||||
|
Write-Host " 如忘记密码,请联系管理员重新生成 secrets.enc" -ForegroundColor Yellow
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function Render-SettingsTemplate {
|
function Render-SettingsTemplate {
|
||||||
@ -202,7 +211,7 @@ function Detect-SystemProxy {
|
|||||||
Write-Banner
|
Write-Banner
|
||||||
|
|
||||||
# 步骤 0: 前置检查
|
# 步骤 0: 前置检查
|
||||||
Write-Host "[0/7] 前置检查..." -ForegroundColor White
|
Write-Host "[1/6] 前置检查..." -ForegroundColor White
|
||||||
$checks = @(
|
$checks = @(
|
||||||
@{ Name = "Claude Code"; OK = (Test-Command "claude") }
|
@{ Name = "Claude Code"; OK = (Test-Command "claude") }
|
||||||
@{ Name = "Node.js"; OK = (Test-Command "node") }
|
@{ Name = "Node.js"; OK = (Test-Command "node") }
|
||||||
@ -222,17 +231,23 @@ if (-not (Test-Command "node")) {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# 步骤 0.5: 代理检测 (国内必须)
|
# 步骤 2: 代理检测 (国内必须)
|
||||||
Write-Host "`n[0.5/7] 代理检测..." -ForegroundColor White
|
Write-Host "`n[2/6] 代理检测..." -ForegroundColor White
|
||||||
Detect-SystemProxy
|
Detect-SystemProxy
|
||||||
|
|
||||||
# 步骤 1: 解密凭证 (进程级环境变量,不写磁盘)
|
# 步骤 3: 解密凭证 (进程级环境变量,不写磁盘)
|
||||||
Write-Host "`n[1/7] 解密凭证..." -ForegroundColor White
|
Write-Host "`n[3/6] 解密凭证..." -ForegroundColor White
|
||||||
Decrypt-Secrets
|
Decrypt-Secrets
|
||||||
|
|
||||||
|
# 自动配置 git credential helper (避免 clone 时反复要密码)
|
||||||
|
$prevEAP = $ErrorActionPreference
|
||||||
|
$ErrorActionPreference = "Continue"
|
||||||
|
git config --global credential.helper store 2>$null
|
||||||
|
$ErrorActionPreference = $prevEAP
|
||||||
|
|
||||||
# 步骤 2: 克隆/更新仓库
|
# 步骤 2: 克隆/更新仓库
|
||||||
if (-not $StartOnly) {
|
if (-not $StartOnly) {
|
||||||
Write-Host "`n[2/7] 同步 Bookworm 配置..." -ForegroundColor White
|
Write-Host "`n[4/6] 同步 Bookworm 配置..." -ForegroundColor White
|
||||||
|
|
||||||
if (Test-Path $ClaudeTarget) {
|
if (Test-Path $ClaudeTarget) {
|
||||||
$isGit = Test-Path (Join-Path $ClaudeTarget ".git")
|
$isGit = Test-Path (Join-Path $ClaudeTarget ".git")
|
||||||
@ -303,13 +318,26 @@ if (-not $StartOnly) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Host "`n[2/7] StartOnly 模式,跳过同步" -ForegroundColor Gray
|
Write-Host "`n[4/6] StartOnly 模式,跳过同步" -ForegroundColor Gray
|
||||||
|
# 静默检测远程更新
|
||||||
|
$configDir = Join-Path $env:USERPROFILE ".claude"
|
||||||
|
if (Test-Path (Join-Path $configDir ".git")) {
|
||||||
|
$prevEAP2 = $ErrorActionPreference
|
||||||
|
$ErrorActionPreference = "Continue"
|
||||||
|
git -C $configDir fetch --quiet 2>$null
|
||||||
|
$behind = git -C $configDir rev-list "HEAD..origin/main" --count 2>$null
|
||||||
|
$ErrorActionPreference = $prevEAP2
|
||||||
|
if ($behind -and [int]$behind -gt 0) {
|
||||||
|
Write-Host " [!] Bookworm 有 $behind 个新更新可用" -ForegroundColor Yellow
|
||||||
|
Write-Host " 双击 '更新并启动Bookworm.bat' 可同步最新版本" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# 步骤 3: 完整性校验
|
# 步骤 3: 完整性校验
|
||||||
$integrityFile = Join-Path $ClaudeTarget "integrity.sha256"
|
$integrityFile = Join-Path $ClaudeTarget "integrity.sha256"
|
||||||
if (Test-Path $integrityFile) {
|
if (Test-Path $integrityFile) {
|
||||||
Write-Host "`n[4/7] 完整性校验..." -ForegroundColor White
|
Write-Host "`n[5/6] 完整性校验..." -ForegroundColor White
|
||||||
$failures = @()
|
$failures = @()
|
||||||
Get-Content $integrityFile | ForEach-Object {
|
Get-Content $integrityFile | ForEach-Object {
|
||||||
if ($_ -match '^([a-f0-9]{64})\s+(.+)$') {
|
if ($_ -match '^([a-f0-9]{64})\s+(.+)$') {
|
||||||
@ -333,15 +361,15 @@ if (Test-Path $integrityFile) {
|
|||||||
Write-Host " [OK] 所有文件完整性校验通过" -ForegroundColor Green
|
Write-Host " [OK] 所有文件完整性校验通过" -ForegroundColor Green
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Write-Host "`n[4/7] 跳过完整性校验 (无 integrity.sha256)" -ForegroundColor Gray
|
Write-Host "`n[5/6] 跳过完整性校验 (无 integrity.sha256)" -ForegroundColor Gray
|
||||||
}
|
}
|
||||||
|
|
||||||
# 步骤 4: 渲染 settings.json
|
# 步骤 4: 渲染 settings.json
|
||||||
Write-Host "`n[5/7] 渲染配置模板..." -ForegroundColor White
|
Write-Host "`n[5/6] 渲染配置模板..." -ForegroundColor White
|
||||||
Render-SettingsTemplate
|
Render-SettingsTemplate
|
||||||
|
|
||||||
# 步骤 5: 确保必要目录存在
|
# 步骤 5: 确保必要目录存在
|
||||||
Write-Host "`n[6/7] 初始化本地目录..." -ForegroundColor White
|
Write-Host "`n[5/6] 初始化本地目录..." -ForegroundColor White
|
||||||
$localDirs = @("debug", "sessions", "cache", "backups", "telemetry", "shell-snapshots", "projects", "memory")
|
$localDirs = @("debug", "sessions", "cache", "backups", "telemetry", "shell-snapshots", "projects", "memory")
|
||||||
foreach ($d in $localDirs) {
|
foreach ($d in $localDirs) {
|
||||||
$dirPath = Join-Path $ClaudeTarget $d
|
$dirPath = Join-Path $ClaudeTarget $d
|
||||||
@ -364,7 +392,7 @@ if ($nodeCheck -eq $ClaudeTarget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 步骤 6: Bookworm 完整性验证 + MCP 检查
|
# 步骤 6: Bookworm 完整性验证 + MCP 检查
|
||||||
Write-Host "`n[7/8] Bookworm 系统验证..." -ForegroundColor White
|
Write-Host "`n[5/6] Bookworm 系统验证..." -ForegroundColor White
|
||||||
|
|
||||||
# --- Bookworm vs 原生 Claude Code 检测 ---
|
# --- Bookworm vs 原生 Claude Code 检测 ---
|
||||||
$bwChecks = @()
|
$bwChecks = @()
|
||||||
@ -495,7 +523,7 @@ if ($mcpWarnings.Count -eq 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 步骤 7: 启动 Claude Code
|
# 步骤 7: 启动 Claude Code
|
||||||
Write-Host "`n[8/8] 启动 Claude Code..." -ForegroundColor White
|
Write-Host "`n[6/6] 启动 Claude Code..." -ForegroundColor White
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
if ($allOK) {
|
if ($allOK) {
|
||||||
Write-Host " ╔══════════════════════════════════════════╗" -ForegroundColor Green
|
Write-Host " ╔══════════════════════════════════════════╗" -ForegroundColor Green
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
Gitea 地址: https://code.letcareme.com
|
Gitea 地址: https://code.letcareme.com
|
||||||
管理员账号: bookworm
|
管理员账号: [由管理员提供]
|
||||||
管理员密码: [REDACTED_OLD_PASSWORD]
|
管理员密码: [由管理员提供]
|
||||||
中转站地址: https://bww.letcareme.com/v1
|
中转站地址: [由管理员提供]
|
||||||
ECS 服务器: 8.138.11.105 (Gitea 端口 3300, 仅本地)
|
ECS 服务器: [由管理员提供]
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
一、首次安装 (目标机)
|
一、首次安装 (目标机)
|
||||||
@ -109,7 +109,7 @@
|
|||||||
---- 5.1 部署 Gitea (仅首次) ----
|
---- 5.1 部署 Gitea (仅首次) ----
|
||||||
|
|
||||||
scp C:\Users\leesu\Desktop\bookworm-portable\deploy-gitea.sh root@8.138.11.105:/tmp/
|
scp C:\Users\leesu\Desktop\bookworm-portable\deploy-gitea.sh root@8.138.11.105:/tmp/
|
||||||
ssh root@8.138.11.105 "GITEA_ADMIN_PASS='[REDACTED_OLD_PASSWORD]' bash /tmp/deploy-gitea.sh"
|
ssh root@8.138.11.105 "GITEA_ADMIN_PASS='[密码]' bash /tmp/deploy-gitea.sh"
|
||||||
|
|
||||||
---- 5.2 配置 HTTPS (仅首次) ----
|
---- 5.2 配置 HTTPS (仅首次) ----
|
||||||
|
|
||||||
@ -126,7 +126,7 @@
|
|||||||
cd C:\Users\leesu\.claude
|
cd C:\Users\leesu\.claude
|
||||||
git add -A
|
git add -A
|
||||||
git commit -m "update bookworm config"
|
git commit -m "update bookworm config"
|
||||||
git push https://bookworm:[REDACTED_OLD_PASSWORD]@code.letcareme.com/bookworm/bookworm-config.git main
|
git push https://bookworm:[密码]@code.letcareme.com/bookworm/bookworm-config.git main
|
||||||
|
|
||||||
---- 5.5 更新 boot 仓库脚本 ----
|
---- 5.5 更新 boot 仓库脚本 ----
|
||||||
|
|
||||||
@ -137,7 +137,7 @@
|
|||||||
cp C:\Users\leesu\Desktop\bookworm-portable\secrets.enc .
|
cp C:\Users\leesu\Desktop\bookworm-portable\secrets.enc .
|
||||||
git add -A
|
git add -A
|
||||||
git commit -m "update boot scripts"
|
git commit -m "update boot scripts"
|
||||||
git push https://bookworm:[REDACTED_OLD_PASSWORD]@code.letcareme.com/bookworm/bookworm-boot.git main
|
git push https://bookworm:[密码]@code.letcareme.com/bookworm/bookworm-boot.git main
|
||||||
|
|
||||||
---- 5.6 重新加密凭证 (更换 API Key 后) ----
|
---- 5.6 重新加密凭证 (更换 API Key 后) ----
|
||||||
|
|
||||||
|
|||||||
23
启动Bookworm.bat
Normal file
23
启动Bookworm.bat
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 > nul
|
||||||
|
title Bookworm Portable - 启动
|
||||||
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ====================================
|
||||||
|
echo Bookworm Portable - 快速启动
|
||||||
|
echo ====================================
|
||||||
|
echo.
|
||||||
|
|
||||||
|
where pwsh >nul 2>nul
|
||||||
|
if %errorlevel% equ 0 (
|
||||||
|
pwsh -ExecutionPolicy Bypass -File install.ps1 -StartOnly
|
||||||
|
) else (
|
||||||
|
powershell -ExecutionPolicy Bypass -File install.ps1 -StartOnly
|
||||||
|
)
|
||||||
|
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo 启动失败,按任意键退出...
|
||||||
|
pause > nul
|
||||||
|
)
|
||||||
24
更新并启动Bookworm.bat
Normal file
24
更新并启动Bookworm.bat
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 > nul
|
||||||
|
title Bookworm Portable - 更新并启动
|
||||||
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ====================================
|
||||||
|
echo Bookworm Portable - 更新并启动
|
||||||
|
echo (同步最新 Skills/Hooks 后启动)
|
||||||
|
echo ====================================
|
||||||
|
echo.
|
||||||
|
|
||||||
|
where pwsh >nul 2>nul
|
||||||
|
if %errorlevel% equ 0 (
|
||||||
|
pwsh -ExecutionPolicy Bypass -File install.ps1
|
||||||
|
) else (
|
||||||
|
powershell -ExecutionPolicy Bypass -File install.ps1
|
||||||
|
)
|
||||||
|
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo 启动失败,按任意键退出...
|
||||||
|
pause > nul
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue
Block a user