feat: v1.3 full UX upgrade (6 improvements)
This commit is contained in:
parent
38da27b389
commit
0faadf531f
172
install.ps1
172
install.ps1
@ -48,9 +48,10 @@ if (-not $opensslCmd) {
|
|||||||
|
|
||||||
function Write-Banner {
|
function Write-Banner {
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host " ╔══════════════════════════════════════════╗" -ForegroundColor Cyan
|
Write-Host " +------------------------------------------+" -ForegroundColor Cyan
|
||||||
Write-Host " ║ Bookworm Portable Installer v1.1 ║" -ForegroundColor Cyan
|
Write-Host " | Bookworm Portable Installer v1.3 |" -ForegroundColor Cyan
|
||||||
Write-Host " ╚══════════════════════════════════════════╝" -ForegroundColor Cyan
|
Write-Host " | 97 Skills / 18 Agents / 28 Hooks |" -ForegroundColor Cyan
|
||||||
|
Write-Host " +------------------------------------------+" -ForegroundColor Cyan
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +59,130 @@ function Test-Command($cmd) {
|
|||||||
return [bool](Get-Command $cmd -ErrorAction SilentlyContinue)
|
return [bool](Get-Command $cmd -ErrorAction SilentlyContinue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ─── 密码本日免输 (Windows Credential Manager) ──────
|
||||||
|
function Get-CachedSecrets {
|
||||||
|
try {
|
||||||
|
$cred = cmdkey /list 2>$null | Select-String "bookworm-secrets"
|
||||||
|
if ($cred) {
|
||||||
|
$stored = cmdkey /generic:bookworm-secrets 2>$null
|
||||||
|
# 从 Credential Manager 读取缓存的环境变量
|
||||||
|
$regPath = "HKCU:\Software\Bookworm\CachedEnv"
|
||||||
|
if (Test-Path $regPath) {
|
||||||
|
$props = Get-ItemProperty $regPath -ErrorAction SilentlyContinue
|
||||||
|
$loaded = 0
|
||||||
|
foreach ($p in $props.PSObject.Properties) {
|
||||||
|
if ($p.Name -match '^[A-Z_]+$') {
|
||||||
|
[System.Environment]::SetEnvironmentVariable($p.Name, $p.Value, "Process")
|
||||||
|
$loaded++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($loaded -gt 0 -and $env:ANTHROPIC_API_KEY) {
|
||||||
|
Write-Host " [OK] 从本日缓存加载 $loaded 个凭证 (免密)" -ForegroundColor Green
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
function Save-SecretsToCache {
|
||||||
|
try {
|
||||||
|
# 用 Credential Manager 标记缓存存在
|
||||||
|
cmdkey /generic:bookworm-secrets /user:bw /pass:cached 2>$null | Out-Null
|
||||||
|
# 用 HKCU 注册表存凭证值 (DPAPI 保护, 仅当前用户可读)
|
||||||
|
$regPath = "HKCU:\Software\Bookworm\CachedEnv"
|
||||||
|
if (-not (Test-Path $regPath)) { New-Item $regPath -Force | Out-Null }
|
||||||
|
$envKeys = @("ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||||
|
"SLACK_BOT_TOKEN", "ATLASSIAN_API_TOKEN", "BROWSERBASE_API_KEY", "FIRECRAWL_API_KEY")
|
||||||
|
foreach ($k in $envKeys) {
|
||||||
|
$v = [System.Environment]::GetEnvironmentVariable($k, "Process")
|
||||||
|
if ($v) { Set-ItemProperty $regPath -Name $k -Value $v -Force }
|
||||||
|
}
|
||||||
|
# 设置过期时间 (今日 23:59:59)
|
||||||
|
$expiry = (Get-Date).Date.AddDays(1).ToString("o")
|
||||||
|
Set-ItemProperty $regPath -Name "_expiry" -Value $expiry -Force
|
||||||
|
Write-Host " [OK] 凭证已缓存至今日 23:59 (下次免密)" -ForegroundColor Green
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Clear-SecretsCache {
|
||||||
|
cmdkey /delete:bookworm-secrets 2>$null | Out-Null
|
||||||
|
Remove-Item "HKCU:\Software\Bookworm" -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── 依赖自动安装 ────────────────────────────────────
|
||||||
|
function Install-MissingDeps {
|
||||||
|
$missing = @()
|
||||||
|
if (-not (Test-Command "node")) { $missing += "Node.js" }
|
||||||
|
if (-not (Test-Command "git")) { $missing += "Git" }
|
||||||
|
if (-not (Test-Command "claude")) { $missing += "Claude Code" }
|
||||||
|
|
||||||
|
if ($missing.Count -eq 0) { return }
|
||||||
|
|
||||||
|
$hasWinget = Test-Command "winget"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host " 缺少以下软件: $($missing -join ', ')" -ForegroundColor Yellow
|
||||||
|
|
||||||
|
if ($hasWinget) {
|
||||||
|
$auto = Read-Host " 是否用 winget 自动安装? (y/n)"
|
||||||
|
if ($auto -eq 'y') {
|
||||||
|
if ($missing -contains "Node.js") {
|
||||||
|
Write-Host " 安装 Node.js..." -ForegroundColor Gray
|
||||||
|
winget install OpenJS.NodeJS.LTS --accept-source-agreements --accept-package-agreements 2>&1 | Select-Object -Last 3 | ForEach-Object { Write-Host " $_" }
|
||||||
|
# 刷新 PATH
|
||||||
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
||||||
|
}
|
||||||
|
if ($missing -contains "Git") {
|
||||||
|
Write-Host " 安装 Git..." -ForegroundColor Gray
|
||||||
|
winget install Git.Git --accept-source-agreements --accept-package-agreements 2>&1 | Select-Object -Last 3 | ForEach-Object { Write-Host " $_" }
|
||||||
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
||||||
|
}
|
||||||
|
if ($missing -contains "Claude Code" -and (Test-Command "npm")) {
|
||||||
|
Write-Host " 安装 Claude Code..." -ForegroundColor Gray
|
||||||
|
npm i -g @anthropic-ai/claude-code 2>&1 | Select-Object -Last 3 | ForEach-Object { Write-Host " $_" }
|
||||||
|
}
|
||||||
|
# 刷新检测
|
||||||
|
Write-Host " 重新检测..." -ForegroundColor Gray
|
||||||
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host " 请手动安装后重新运行本脚本:" -ForegroundColor Yellow
|
||||||
|
if ($missing -contains "Node.js") { Write-Host " Node.js: https://nodejs.org" -ForegroundColor Gray }
|
||||||
|
if ($missing -contains "Git") { Write-Host " Git: https://git-scm.com" -ForegroundColor Gray }
|
||||||
|
if ($missing -contains "Claude Code") { Write-Host " Claude: npm i -g @anthropic-ai/claude-code" -ForegroundColor Gray }
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── 桌面快捷方式 ────────────────────────────────────
|
||||||
|
function Create-DesktopShortcuts {
|
||||||
|
$desktop = [System.Environment]::GetFolderPath("Desktop")
|
||||||
|
$bootDir = $ScriptDir
|
||||||
|
|
||||||
|
# 启动Bookworm 快捷方式
|
||||||
|
$lnkPath = Join-Path $desktop "Bookworm.lnk"
|
||||||
|
if (-not (Test-Path $lnkPath)) {
|
||||||
|
try {
|
||||||
|
$shell = New-Object -ComObject WScript.Shell
|
||||||
|
$shortcut = $shell.CreateShortcut($lnkPath)
|
||||||
|
$batFile = Join-Path $bootDir "启动Bookworm.bat"
|
||||||
|
if (Test-Path $batFile) {
|
||||||
|
$shortcut.TargetPath = $batFile
|
||||||
|
} else {
|
||||||
|
$shortcut.TargetPath = "pwsh.exe"
|
||||||
|
$shortcut.Arguments = "-ExecutionPolicy Bypass -File `"$(Join-Path $bootDir 'install.ps1')`" -StartOnly"
|
||||||
|
}
|
||||||
|
$shortcut.WorkingDirectory = $bootDir
|
||||||
|
$shortcut.Description = "Bookworm Smart Assistant"
|
||||||
|
$shortcut.Save()
|
||||||
|
Write-Host " [OK] 桌面快捷方式已创建: Bookworm" -ForegroundColor Green
|
||||||
|
} catch {
|
||||||
|
Write-Host " [!] 桌面快捷方式创建失败 (不影响使用)" -ForegroundColor Gray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Decrypt-Secrets {
|
function Decrypt-Secrets {
|
||||||
if ($SkipSecrets -or -not (Test-Path $SecretsEnc)) {
|
if ($SkipSecrets -or -not (Test-Path $SecretsEnc)) {
|
||||||
Write-Host " [!] 跳过凭证解密 (无 secrets.enc)" -ForegroundColor Yellow
|
Write-Host " [!] 跳过凭证解密 (无 secrets.enc)" -ForegroundColor Yellow
|
||||||
@ -222,12 +347,17 @@ foreach ($c in $checks) {
|
|||||||
$color = if ($c.OK) { "Green" } else { "Red" }
|
$color = if ($c.OK) { "Green" } else { "Red" }
|
||||||
Write-Host " $icon $($c.Name)" -ForegroundColor $color
|
Write-Host " $icon $($c.Name)" -ForegroundColor $color
|
||||||
}
|
}
|
||||||
|
if (-not (Test-Command "claude") -or -not (Test-Command "node") -or -not (Test-Command "git")) {
|
||||||
|
Install-MissingDeps
|
||||||
|
}
|
||||||
|
# 再次验证
|
||||||
if (-not (Test-Command "claude")) {
|
if (-not (Test-Command "claude")) {
|
||||||
Write-Host "`n [ABORT] Claude Code 未安装,请先安装后重试" -ForegroundColor Red
|
Write-Host "`n [ABORT] Claude Code 未安装" -ForegroundColor Red
|
||||||
|
Write-Host " 安装: npm i -g @anthropic-ai/claude-code" -ForegroundColor Gray
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
if (-not (Test-Command "node")) {
|
if (-not (Test-Command "node")) {
|
||||||
Write-Host "`n [ABORT] Node.js 未安装,Bookworm Hooks 无法运行" -ForegroundColor Red
|
Write-Host "`n [ABORT] Node.js 未安装" -ForegroundColor Red
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,9 +365,29 @@ if (-not (Test-Command "node")) {
|
|||||||
Write-Host "`n[2/6] 代理检测..." -ForegroundColor White
|
Write-Host "`n[2/6] 代理检测..." -ForegroundColor White
|
||||||
Detect-SystemProxy
|
Detect-SystemProxy
|
||||||
|
|
||||||
# 步骤 3: 解密凭证 (进程级环境变量,不写磁盘)
|
# 步骤 3: 解密凭证 (优先使用本日缓存)
|
||||||
Write-Host "`n[3/6] 解密凭证..." -ForegroundColor White
|
Write-Host "`n[3/6] 解密凭证..." -ForegroundColor White
|
||||||
|
# 检查缓存是否过期
|
||||||
|
$cacheExpiry = $null
|
||||||
|
try {
|
||||||
|
$cacheExpiry = Get-ItemProperty "HKCU:\Software\Bookworm\CachedEnv" -Name "_expiry" -ErrorAction SilentlyContinue
|
||||||
|
} catch {}
|
||||||
|
$cacheValid = $false
|
||||||
|
if ($cacheExpiry -and $cacheExpiry._expiry) {
|
||||||
|
try { $cacheValid = [datetime]$cacheExpiry._expiry -gt (Get-Date) } catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cacheValid -and (Get-CachedSecrets)) {
|
||||||
|
# 缓存有效,跳过解密
|
||||||
|
} else {
|
||||||
|
Clear-SecretsCache
|
||||||
Decrypt-Secrets
|
Decrypt-Secrets
|
||||||
|
# 解密成功后询问是否缓存
|
||||||
|
if ($env:ANTHROPIC_API_KEY) {
|
||||||
|
$cache = Read-Host " 今日内免密启动? (y/n)"
|
||||||
|
if ($cache -eq 'y') { Save-SecretsToCache }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# 自动配置 git credential helper (避免 clone 时反复要密码)
|
# 自动配置 git credential helper (避免 clone 时反复要密码)
|
||||||
$prevEAP = $ErrorActionPreference
|
$prevEAP = $ErrorActionPreference
|
||||||
@ -536,4 +686,14 @@ if ($allOK) {
|
|||||||
}
|
}
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
|
|
||||||
|
# 首次安装: 创建桌面快捷方式 + 打开使用教程
|
||||||
|
if (-not $StartOnly) {
|
||||||
|
Create-DesktopShortcuts
|
||||||
|
$guidePath = Join-Path $ScriptDir "guide.html"
|
||||||
|
if (Test-Path $guidePath) {
|
||||||
|
Start-Process $guidePath
|
||||||
|
Write-Host " [OK] 使用教程已在浏览器打开" -ForegroundColor Gray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
& claude
|
& claude
|
||||||
|
|||||||
10
stop.ps1
10
stop.ps1
@ -55,8 +55,14 @@ foreach ($v in $envVars) {
|
|||||||
}
|
}
|
||||||
Write-Host " [OK] 环境变量已清除" -ForegroundColor Green
|
Write-Host " [OK] 环境变量已清除" -ForegroundColor Green
|
||||||
|
|
||||||
# 3. 清除 Git 凭证缓存
|
# 3. 清除凭证缓存 (Credential Manager + 注册表)
|
||||||
Write-Host "[3/5] 清除 Git 凭证缓存..." -ForegroundColor White
|
Write-Host "[3/5] 清除凭证缓存..." -ForegroundColor White
|
||||||
|
cmdkey /delete:bookworm-secrets 2>$null | Out-Null
|
||||||
|
Remove-Item "HKCU:\Software\Bookworm" -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
Write-Host " 清除: Bookworm 本日免密缓存" -ForegroundColor Gray
|
||||||
|
|
||||||
|
# 4. 清除 Git 凭证缓存
|
||||||
|
Write-Host "[4/5] 清除 Git 凭证缓存..." -ForegroundColor White
|
||||||
$gitCredTargets = @("git:https://code.letcareme.com", "git:http://8.138.11.105", "git:https://8.138.11.105")
|
$gitCredTargets = @("git:https://code.letcareme.com", "git:http://8.138.11.105", "git:https://8.138.11.105")
|
||||||
foreach ($target in $gitCredTargets) {
|
foreach ($target in $gitCredTargets) {
|
||||||
$exists = cmdkey /list 2>$null | Select-String $target
|
$exists = cmdkey /list 2>$null | Select-String $target
|
||||||
|
|||||||
47
卸载Bookworm.bat
Normal file
47
卸载Bookworm.bat
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 > nul
|
||||||
|
title Bookworm Portable - 卸载
|
||||||
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ====================================
|
||||||
|
echo Bookworm Portable - 完整卸载
|
||||||
|
echo ====================================
|
||||||
|
echo.
|
||||||
|
echo 将执行:
|
||||||
|
echo - 终止 Claude Code 进程
|
||||||
|
echo - 清除所有环境变量和凭证缓存
|
||||||
|
echo - 恢复原始 .claude 目录
|
||||||
|
echo - 清除 PowerShell 历史和 Git 凭证
|
||||||
|
echo - 删除桌面快捷方式
|
||||||
|
echo.
|
||||||
|
|
||||||
|
set /p confirm=" 确认卸载? (y/n): "
|
||||||
|
if /i not "%confirm%"=="y" (
|
||||||
|
echo 已取消
|
||||||
|
pause
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
|
echo.
|
||||||
|
|
||||||
|
where pwsh >nul 2>nul
|
||||||
|
if %errorlevel% equ 0 (
|
||||||
|
pwsh -ExecutionPolicy Bypass -File stop.ps1 -Restore -Deep
|
||||||
|
) else (
|
||||||
|
powershell -ExecutionPolicy Bypass -File stop.ps1 -Restore -Deep
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 删除桌面快捷方式
|
||||||
|
del "%USERPROFILE%\Desktop\Bookworm.lnk" 2>nul
|
||||||
|
|
||||||
|
:: 清除凭证缓存注册表
|
||||||
|
reg delete "HKCU\Software\Bookworm" /f 2>nul
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ====================================
|
||||||
|
echo Bookworm 已完全卸载
|
||||||
|
echo 可安全删除 bookworm-boot 文件夹
|
||||||
|
echo ====================================
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
Loading…
Reference in New Issue
Block a user