update: BOM fix, code.letcareme.com domain, guide.html, openssl path fix

This commit is contained in:
leesu 2026-04-01 14:30:05 +08:00
parent 5c005e8850
commit 816c19f673
4 changed files with 536 additions and 5 deletions

View File

@ -1,4 +1,4 @@
Bookworm Portable v1.1 - 纯云端便携部署工具包
Bookworm Portable v1.1 - 纯云端便携部署工具包
================================================
=== 文件说明 ===

531
guide.html Normal file
View File

@ -0,0 +1,531 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bookworm Portable - 使用教程</title>
<style>
:root {
--bg: #0d1117;
--card: #161b22;
--border: #30363d;
--text: #e6edf3;
--text-dim: #8b949e;
--accent: #58a6ff;
--green: #3fb950;
--yellow: #d29922;
--red: #f85149;
--purple: #bc8cff;
--cyan: #39d2c0;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: var(--bg);
color: var(--text);
font-family: -apple-system, 'Segoe UI', 'Microsoft YaHei', sans-serif;
line-height: 1.7;
padding: 0;
}
/* Header */
.header {
background: linear-gradient(135deg, #1a1f35 0%, #0d1117 100%);
border-bottom: 1px solid var(--border);
padding: 3rem 2rem;
text-align: center;
}
.header pre {
color: var(--cyan);
font-size: 0.65rem;
line-height: 1.2;
margin-bottom: 1rem;
display: inline-block;
text-align: left;
}
.header h1 {
font-size: 2rem;
font-weight: 700;
margin-bottom: 0.5rem;
}
.header h1 span { color: var(--accent); }
.header p { color: var(--text-dim); font-size: 1.05rem; }
.badge-row {
display: flex;
gap: 0.8rem;
justify-content: center;
margin-top: 1rem;
flex-wrap: wrap;
}
.badge {
display: inline-flex;
align-items: center;
gap: 0.4rem;
background: var(--card);
border: 1px solid var(--border);
border-radius: 20px;
padding: 0.3rem 0.9rem;
font-size: 0.85rem;
color: var(--text-dim);
}
.badge strong { color: var(--text); }
/* Container */
.container {
max-width: 860px;
margin: 0 auto;
padding: 2rem 1.5rem 4rem;
}
/* Section */
.section {
margin-bottom: 2.5rem;
}
.section h2 {
font-size: 1.4rem;
margin-bottom: 1rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 0.6rem;
}
.section h2 .num {
background: var(--accent);
color: #000;
width: 28px;
height: 28px;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 0.85rem;
font-weight: 700;
flex-shrink: 0;
}
/* Code blocks */
.code-block {
background: #0d1117;
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem 1.2rem;
margin: 0.8rem 0;
overflow-x: auto;
position: relative;
}
.code-block code {
font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
font-size: 0.9rem;
line-height: 1.6;
color: var(--text);
}
.code-block .comment { color: var(--text-dim); }
.code-block .cmd { color: var(--green); }
.code-block .flag { color: var(--yellow); }
.code-block .url { color: var(--accent); }
.code-block .label {
position: absolute;
top: 0.4rem;
right: 0.6rem;
font-size: 0.7rem;
color: var(--text-dim);
background: var(--card);
padding: 0.1rem 0.5rem;
border-radius: 4px;
border: 1px solid var(--border);
}
/* Cards */
.card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 10px;
padding: 1.2rem 1.5rem;
margin: 0.8rem 0;
}
.card h3 {
font-size: 1rem;
margin-bottom: 0.5rem;
color: var(--accent);
}
.card p { color: var(--text-dim); font-size: 0.95rem; }
/* Steps */
.step {
display: flex;
gap: 1rem;
margin: 1rem 0;
align-items: flex-start;
}
.step-icon {
width: 36px;
height: 36px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.1rem;
flex-shrink: 0;
margin-top: 0.2rem;
}
.step-icon.green { background: rgba(63,185,80,0.15); border: 1px solid rgba(63,185,80,0.3); }
.step-icon.blue { background: rgba(88,166,255,0.15); border: 1px solid rgba(88,166,255,0.3); }
.step-icon.yellow { background: rgba(210,153,34,0.15); border: 1px solid rgba(210,153,34,0.3); }
.step-icon.red { background: rgba(248,81,73,0.15); border: 1px solid rgba(248,81,73,0.3); }
.step-content h4 { font-size: 1rem; margin-bottom: 0.3rem; }
.step-content p { color: var(--text-dim); font-size: 0.9rem; }
/* Table */
table {
width: 100%;
border-collapse: collapse;
margin: 0.8rem 0;
font-size: 0.9rem;
}
th, td {
padding: 0.6rem 1rem;
text-align: left;
border-bottom: 1px solid var(--border);
}
th {
color: var(--text-dim);
font-weight: 600;
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.5px;
}
td code {
background: var(--bg);
padding: 0.15rem 0.4rem;
border-radius: 4px;
font-size: 0.85rem;
border: 1px solid var(--border);
}
/* Alert boxes */
.alert {
border-radius: 8px;
padding: 1rem 1.2rem;
margin: 1rem 0;
font-size: 0.9rem;
display: flex;
gap: 0.8rem;
align-items: flex-start;
}
.alert-icon { font-size: 1.2rem; flex-shrink: 0; }
.alert.warning {
background: rgba(210,153,34,0.08);
border: 1px solid rgba(210,153,34,0.3);
}
.alert.danger {
background: rgba(248,81,73,0.08);
border: 1px solid rgba(248,81,73,0.3);
}
.alert.info {
background: rgba(88,166,255,0.08);
border: 1px solid rgba(88,166,255,0.3);
}
.alert.success {
background: rgba(63,185,80,0.08);
border: 1px solid rgba(63,185,80,0.3);
}
/* Flow diagram */
.flow {
display: flex;
align-items: center;
justify-content: center;
gap: 0;
margin: 1.5rem 0;
flex-wrap: wrap;
}
.flow-node {
background: var(--card);
border: 1px solid var(--border);
border-radius: 8px;
padding: 0.6rem 1rem;
font-size: 0.85rem;
text-align: center;
min-width: 100px;
}
.flow-node.active {
border-color: var(--green);
box-shadow: 0 0 8px rgba(63,185,80,0.2);
}
.flow-arrow {
color: var(--text-dim);
font-size: 1.2rem;
padding: 0 0.3rem;
}
/* Footer */
.footer {
text-align: center;
padding: 2rem;
color: var(--text-dim);
font-size: 0.8rem;
border-top: 1px solid var(--border);
}
/* Responsive */
@media (max-width: 600px) {
.header { padding: 2rem 1rem; }
.header pre { font-size: 0.5rem; }
.header h1 { font-size: 1.5rem; }
.container { padding: 1.5rem 1rem; }
.flow { flex-direction: column; }
.flow-arrow { transform: rotate(90deg); }
}
</style>
</head>
<body>
<!-- Header -->
<div class="header">
<pre>
____ _
| __ ) ___ ___ | | ____ _____ _ __ _ __ ___
| _ \ / _ \ / _ \| |/ /\ \ /\ / / _ \| '__| '_ ` _ \
| |_) | (_) | (_) | < \ V V / (_) | | | | | | | |
|____/ \___/ \___/|_|\_\ \_/\_/ \___/|_| |_| |_| |_|
</pre>
<h1>Bookworm <span>Portable</span> 使用教程</h1>
<p>纯云端便携部署 — 任意电脑一行命令激活 Bookworm 全套能力</p>
<div class="badge-row">
<span class="badge"><strong>97</strong> Skills</span>
<span class="badge"><strong>18</strong> Agents</span>
<span class="badge"><strong>28</strong> Hooks</span>
<span class="badge"><strong>AES-256</strong> 加密</span>
<span class="badge"><strong>HTTPS</strong> 传输</span>
</div>
</div>
<div class="container">
<!-- 工作原理 -->
<div class="section">
<h2>工作原理</h2>
<p>Bookworm 配置存储在私有 Gitea 服务器上,目标机通过 HTTPS 克隆并自动渲染为本地配置,凭证全程加密,不落盘。</p>
<div class="flow">
<div class="flow-node">Gitea 私有仓<br><small style="color:var(--text-dim)">code.letcareme.com</small></div>
<span class="flow-arrow"></span>
<div class="flow-node">git clone<br><small style="color:var(--text-dim)">HTTPS 加密</small></div>
<span class="flow-arrow"></span>
<div class="flow-node">渲染模板<br><small style="color:var(--text-dim)">settings.json</small></div>
<span class="flow-arrow"></span>
<div class="flow-node">解密凭证<br><small style="color:var(--text-dim)">AES-256</small></div>
<span class="flow-arrow"></span>
<div class="flow-node active">Claude Code<br><small style="color:var(--green)">Bookworm 激活</small></div>
</div>
</div>
<!-- 前置要求 -->
<div class="section">
<h2><span class="num">0</span>前置要求</h2>
<p>目标电脑需要预先安装以下软件:</p>
<table>
<tr><th>软件</th><th>必须</th><th>安装方式</th></tr>
<tr><td><strong>Claude Code</strong></td><td></td><td><code>npm i -g @anthropic-ai/claude-code</code></td></tr>
<tr><td><strong>Node.js</strong> ≥ 18</td><td></td><td><a href="https://nodejs.org" style="color:var(--accent)">nodejs.org</a></td></tr>
<tr><td><strong>Git</strong></td><td></td><td><a href="https://git-scm.com" style="color:var(--accent)">git-scm.com</a></td></tr>
<tr><td><strong>PowerShell 7</strong></td><td>推荐</td><td><code>winget install Microsoft.PowerShell</code></td></tr>
<tr><td>Python 3.x</td><td>可选</td><td>缺失则 3 个 MCP 服务降级</td></tr>
</table>
</div>
<!-- 安装步骤 -->
<div class="section">
<h2><span class="num">1</span>安装 Bookworm首次</h2>
<div class="step">
<div class="step-icon blue">1</div>
<div class="step-content">
<h4>克隆引导仓库</h4>
<p>打开 PowerShell运行</p>
</div>
</div>
<div class="code-block">
<span class="label">PowerShell</span>
<code>
<span class="cmd">git clone</span> <span class="url">https://code.letcareme.com/leesu/bookworm-boot.git</span><br>
<span class="cmd">cd</span> bookworm-boot
</code>
</div>
<p style="color:var(--text-dim);font-size:0.9rem;margin:0.5rem 0">系统会提示输入 Gitea 用户名和密码。</p>
<div class="step">
<div class="step-icon blue">2</div>
<div class="step-content">
<h4>运行安装脚本</h4>
<p>执行安装,自动克隆配置 + 解密凭证 + 渲染模板 + 启动 Claude Code</p>
</div>
</div>
<div class="code-block">
<span class="label">PowerShell</span>
<code>
<span class="cmd">pwsh</span> <span class="flag">-ExecutionPolicy Bypass</span> -File install.ps1
</code>
</div>
<div class="step">
<div class="step-icon green">3</div>
<div class="step-content">
<h4>输入主密码</h4>
<p>脚本会提示输入主密码来解密 API 凭证。输入后自动完成配置并启动 Claude Code。</p>
</div>
</div>
<div class="alert success">
<span class="alert-icon">&#10003;</span>
<div>完成Claude Code 启动后即进入 Bookworm 模式97 个 Skills、18 个 Agents、28 个 Hooks 全部激活。所有 API 请求通过中转站转发。</div>
</div>
</div>
<!-- 后续使用 -->
<div class="section">
<h2><span class="num">2</span>后续使用(已安装过)</h2>
<p>已安装过的电脑,再次使用时只需:</p>
<div class="code-block">
<span class="label">PowerShell</span>
<code>
<span class="cmd">cd</span> bookworm-boot<br>
<span class="cmd">pwsh</span> <span class="flag">-ExecutionPolicy Bypass</span> -File install.ps1 <span class="flag">-StartOnly</span>
</code>
</div>
<p style="color:var(--text-dim);font-size:0.9rem;margin-top:0.5rem"><code>-StartOnly</code> 跳过 git clone直接解密凭证并启动。</p>
<p style="margin-top:1rem">如需同步最新配置更新:</p>
<div class="code-block">
<span class="label">PowerShell</span>
<code>
<span class="cmd">cd</span> bookworm-boot<br>
<span class="cmd">pwsh</span> <span class="flag">-ExecutionPolicy Bypass</span> -File install.ps1
</code>
</div>
<p style="color:var(--text-dim);font-size:0.9rem;margin-top:0.5rem">不加 <code>-StartOnly</code> 会自动 <code>git pull</code> 拉取最新 Skills/Hooks 更新。</p>
</div>
<!-- 使用完毕 -->
<div class="section">
<h2><span class="num">3</span>使用完毕 — 清理</h2>
<p>离开电脑前,清理环境变量和凭证痕迹:</p>
<div class="card">
<h3>基础清理(保留配置,下次可快速启动)</h3>
<div class="code-block" style="border:none;padding:0.5rem 0">
<code><span class="cmd">pwsh</span> <span class="flag">-ExecutionPolicy Bypass</span> -File stop.ps1</code>
</div>
</div>
<div class="card">
<h3>完整恢复(删除 Bookworm恢复电脑原始状态</h3>
<div class="code-block" style="border:none;padding:0.5rem 0">
<code><span class="cmd">pwsh</span> <span class="flag">-ExecutionPolicy Bypass</span> -File stop.ps1 <span class="flag">-Restore</span></code>
</div>
</div>
<div class="card">
<h3>深度清理(含 PowerShell 历史 + Git 凭证缓存)</h3>
<div class="code-block" style="border:none;padding:0.5rem 0">
<code><span class="cmd">pwsh</span> <span class="flag">-ExecutionPolicy Bypass</span> -File stop.ps1 <span class="flag">-Restore -Deep</span></code>
</div>
</div>
</div>
<!-- 安全须知 -->
<div class="section">
<h2><span class="num">!</span>安全须知</h2>
<div class="alert warning">
<span class="alert-icon">&#9888;</span>
<div>
<strong>主密码无法找回</strong><br>
主密码用于解密 API 凭证,没有重置机制。请牢记或存入密码管理器。
</div>
</div>
<div class="alert info">
<span class="alert-icon">&#128274;</span>
<div>
<strong>凭证不落盘</strong><br>
API Key 仅存在于当前进程的环境变量中。关闭终端或运行 stop.ps1 后自动消失,不会写入磁盘或注册表。
</div>
</div>
<div class="alert danger">
<span class="alert-icon">&#9888;</span>
<div>
<strong>在他人电脑上使用后务必清理</strong><br>
运行 <code>stop.ps1 -Restore -Deep</code> 确保不留痕迹。尤其注意公用电脑。
</div>
</div>
<table>
<tr><th>安全特性</th><th>规格</th></tr>
<tr><td>凭证加密</td><td>AES-256-CBC + PBKDF2 (600,000 迭代)</td></tr>
<tr><td>传输加密</td><td>HTTPS (TLS 1.2+, Let's Encrypt 证书)</td></tr>
<tr><td>凭证存储</td><td>进程级环境变量,不写磁盘</td></tr>
<tr><td>登录保护</td><td>fail2ban (5次失败/小时 → 封禁24h)</td></tr>
<tr><td>完整性校验</td><td>SHA-256 文件哈希验证</td></tr>
</table>
</div>
<!-- 常见问题 -->
<div class="section">
<h2><span class="num">?</span>常见问题</h2>
<div class="card">
<h3>Q: 提示 "openssl 未找到"</h3>
<p>确认 Git for Windows 已安装。脚本会自动搜索 <code>C:\Program Files\Git</code><code>D:\Git</code> 下的 openssl。</p>
</div>
<div class="card">
<h3>Q: 提示 "执行策略" 错误</h3>
<p>使用 <code>pwsh -ExecutionPolicy Bypass -File install.ps1</code> 运行,或以管理员身份执行 <code>Set-ExecutionPolicy RemoteSigned</code></p>
</div>
<div class="card">
<h3>Q: 克隆失败 / Gitea 不可达</h3>
<p>检查网络是否能访问 <code>https://code.letcareme.com</code>。如在内网环境,可能需要配置代理。</p>
</div>
<div class="card">
<h3>Q: 解密失败</h3>
<p>确认主密码正确(区分大小写)。如忘记密码,需要管理员重新运行 <code>encrypt-secrets.ps1</code> 生成新的 secrets.enc。</p>
</div>
<div class="card">
<h3>Q: Claude Code 启动后没有 Bookworm 横幅</h3>
<p>检查 <code>~/.claude/CLAUDE.md</code> 是否存在。运行 <code>install.ps1</code>(不加 -StartOnly重新同步。</p>
</div>
<div class="card">
<h3>Q: 目标机需要自己的 Claude 订阅吗?</h3>
<p><strong>不需要。</strong>所有 API 请求通过中转站转发,消耗中转站额度,目标机无需任何 Anthropic 账号。</p>
</div>
</div>
<!-- 快速参考 -->
<div class="section">
<h2>快速参考卡片</h2>
<table>
<tr><th>场景</th><th>命令</th></tr>
<tr><td>首次安装</td><td><code>git clone ... && pwsh -File install.ps1</code></td></tr>
<tr><td>快速启动</td><td><code>pwsh -File install.ps1 -StartOnly</code></td></tr>
<tr><td>同步更新</td><td><code>pwsh -File install.ps1</code></td></tr>
<tr><td>基础清理</td><td><code>pwsh -File stop.ps1</code></td></tr>
<tr><td>完整恢复</td><td><code>pwsh -File stop.ps1 -Restore</code></td></tr>
<tr><td>深度清理</td><td><code>pwsh -File stop.ps1 -Restore -Deep</code></td></tr>
</table>
</div>
</div>
<div class="footer">
Bookworm Portable v1.1 &mdash; Powered by Gitea + Claude Code<br>
&copy; 2026 Bookworm Smart Assistant
</div>
</body>
</html>

View File

@ -1,4 +1,4 @@
<#
<#
.SYNOPSIS
Bookworm Portable - 安装/启动脚本
.DESCRIPTION
@ -39,8 +39,8 @@ $DebugDir = Join-Path $ClaudeTarget "debug"
# ─── openssl 检测 ────────────────────────────────────
$opensslCmd = (Get-Command openssl -ErrorAction SilentlyContinue)?.Source
if (-not $opensslCmd) {
$gitOpenssl = "C:\Program Files\Git\usr\bin\openssl.exe"
if (Test-Path $gitOpenssl) { $opensslCmd = $gitOpenssl }
$searchPaths = @("C:\Program Files\Git\usr\bin\openssl.exe", "D:\Git\usr\bin\openssl.exe", "D:\Git\mingw64\bin\openssl.exe", "C:\Program Files\Git\mingw64\bin\openssl.exe")
$opensslCmd = $searchPaths | Where-Object { Test-Path $_ } | Select-Object -First 1
}
# ─── 辅助函数 ────────────────────────────────────────

View File

@ -1,4 +1,4 @@
<#
<#
.SYNOPSIS
Bookworm Portable - 清理/卸载脚本
.DESCRIPTION