bookworm-boot/guide-mac.html
bookworm d11b36f815 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>
2026-04-06 21:49:50 +08:00

789 lines
35 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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 for Mac - 保姆式安装手册</title>
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon-32.png">
<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, 'SF Pro Display', 'PingFang SC', 'Helvetica Neue', sans-serif;
line-height: 1.7;
padding: 0;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
.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 .platform-badge {
display: inline-flex; align-items: center; gap: 0.4rem;
background: rgba(88,166,255,0.15); border: 1px solid rgba(88,166,255,0.3);
border-radius: 20px; padding: 0.3rem 0.9rem; font-size: 0.9rem;
color: var(--accent); margin-bottom: 0.8rem;
}
.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); }
.platform-switch {
display: flex; gap: 0.6rem; justify-content: center; margin-top: 1.2rem;
}
.platform-switch a {
display: inline-flex; align-items: center; gap: 0.4rem;
padding: 0.5rem 1.2rem; border-radius: 8px; font-size: 0.9rem;
font-weight: 600; text-decoration: none; transition: all 0.2s;
}
.platform-switch .active {
background: var(--accent); color: #000;
}
.platform-switch .inactive {
background: var(--card); color: var(--text-dim);
border: 1px solid var(--border);
}
.platform-switch .inactive:hover {
border-color: var(--accent); color: var(--text); text-decoration: none;
}
.container { max-width: 900px; margin: 0 auto; padding: 2rem 1.5rem 4rem; }
.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-block {
background: #0d1117; border: 1px solid var(--border); border-radius: 8px;
padding: 1rem 1.2rem; margin: 0.8rem 0; overflow-x: auto; position: relative;
cursor: pointer; transition: border-color 0.2s;
}
.code-block:hover { border-color: var(--accent); }
.code-block::after {
content: "点击复制"; position: absolute; top: 0.4rem; right: 0.6rem;
font-size: 0.7rem; color: var(--text-dim); background: var(--card);
padding: 0.15rem 0.5rem; border-radius: 4px; border: 1px solid var(--border);
opacity: 0; transition: opacity 0.2s;
}
.code-block:hover::after { opacity: 1; }
.code-block.copied::after { content: "已复制!"; color: var(--green); opacity: 1; }
.code-block code {
font-family: 'SF Mono', 'Menlo', 'Monaco', 'Cascadia Code', monospace;
font-size: 0.9rem; line-height: 1.6; color: var(--text);
white-space: pre-wrap; word-break: break-all;
}
.code-block .label {
position: absolute; top: 0.4rem; left: 0.6rem;
font-size: 0.65rem; color: var(--text-dim); background: var(--card);
padding: 0.1rem 0.5rem; border-radius: 4px; border: 1px solid var(--border);
text-transform: uppercase; letter-spacing: 0.5px;
}
.code-block.has-label { padding-top: 2rem; }
.cmd { color: var(--green); }
.flag { color: var(--yellow); }
.url { color: var(--accent); }
.comment { color: var(--text-dim); }
.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; }
.step { display: flex; gap: 1rem; margin: 1.2rem 0; align-items: flex-start; }
.step-icon {
width: 40px; height: 40px; border-radius: 10px;
display: flex; align-items: center; justify-content: center;
font-size: 1.2rem; font-weight: 700; flex-shrink: 0; margin-top: 0.1rem;
}
.step-icon.green { background: rgba(63,185,80,0.15); border: 1px solid rgba(63,185,80,0.3); color: var(--green); }
.step-icon.blue { background: rgba(88,166,255,0.15); border: 1px solid rgba(88,166,255,0.3); color: var(--accent); }
.step-icon.yellow { background: rgba(210,153,34,0.15); border: 1px solid rgba(210,153,34,0.3); color: var(--yellow); }
.step-icon.red { background: rgba(248,81,73,0.15); border: 1px solid rgba(248,81,73,0.3); color: var(--red); }
.step-icon.purple { background: rgba(188,140,255,0.15); border: 1px solid rgba(188,140,255,0.3); color: var(--purple); }
.step-content { flex: 1; }
.step-content h4 { font-size: 1.05rem; margin-bottom: 0.3rem; }
.step-content p { color: var(--text-dim); font-size: 0.9rem; }
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 {
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; line-height: 1.5; }
.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); }
.checklist { list-style: none; padding: 0; }
.checklist li {
padding: 0.5rem 0; padding-left: 2rem; position: relative;
border-bottom: 1px solid rgba(48,54,61,0.5); color: var(--text-dim);
}
.checklist li::before {
content: ""; position: absolute; left: 0; top: 0.65rem;
width: 18px; height: 18px; border: 2px solid var(--border); border-radius: 4px;
}
.checklist li.done::before {
background: var(--green); border-color: var(--green);
content: ""; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
background-size: 14px; background-position: center; background-repeat: no-repeat;
}
.checklist li.done { color: var(--text); }
.checklist li strong { color: var(--text); }
.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; }
.screenshot-note {
background: var(--card); border: 1px solid var(--border); border-radius: 8px;
padding: 0.8rem 1rem; margin: 0.5rem 0; font-size: 0.85rem; color: var(--text-dim);
border-left: 3px solid var(--yellow);
}
.screenshot-note strong { color: var(--yellow); }
.footer {
text-align: center; padding: 2rem; color: var(--text-dim);
font-size: 0.8rem; border-top: 1px solid var(--border);
}
@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); }
.step { flex-direction: column; gap: 0.5rem; }
}
</style>
</head>
<body>
<div class="header">
<pre> ____ _
| __ ) ___ ___ | | ____ _____ _ __ _ __ ___
| _ \ / _ \ / _ \| |/ /\ \ /\ / / _ \| '__| '_ ` _ \
| |_) | (_) | (_) | < \ V V / (_) | | | | | | | |
|____/ \___/ \___/|_|\_\ \_/\_/ \___/|_| |_| |_| |_|
</pre>
<div class="platform-badge"> macOS Edition</div>
<h1>Bookworm <span>Portable</span> 保姆式安装手册</h1>
<p>从零开始,一步步教你在任意 Mac 电脑上激活 Bookworm</p>
<div class="badge-row">
<span class="badge"><strong>92</strong> Skills</span>
<span class="badge"><strong>18</strong> Agents</span>
<span class="badge"><strong>34</strong> Hooks</span>
<span class="badge"><strong>AES-256</strong> 加密</span>
<span class="badge"><strong>HTTPS</strong> 传输</span>
</div>
<div class="platform-switch">
<a href="/mac" class="active"> macOS</a>
<a href="/" class="inactive"> Windows</a>
</div>
<a href="/Bookworm-Setup.sh" download style="display:inline-block;margin-top:1.2rem;padding:0.7rem 2rem;background:var(--accent);color:#000;font-weight:700;border-radius:8px;font-size:1rem;text-decoration:none;transition:opacity 0.2s" onmouseover="this.style.opacity='0.85'" onmouseout="this.style.opacity='1'">&#11015; 下载一键安装脚本</a>
</div>
<div class="container">
<!-- 整体流程 -->
<div class="section">
<h2>整体流程概览</h2>
<div class="card" style="text-align:center;border-color:var(--green);margin-bottom:1.5rem">
<h3 style="color:var(--green);margin-bottom:0.5rem">最快方式:一键安装脚本</h3>
<p style="color:var(--text-dim);font-size:0.9rem;margin-bottom:0.8rem">下载 <strong>Bookworm-Setup.sh</strong> → 在终端运行 → 输入密码 → 完成</p>
<p style="font-size:0.8rem;color:var(--text-dim)">脚本自动检测依赖、安装 Homebrew/Node.js/Git、下载配置、启动 Claude Code</p>
</div>
<p style="text-align:center;color:var(--text-dim);font-size:0.85rem;margin-bottom:0.5rem">手动安装流程:</p>
<div class="flow">
<div class="flow-node">安装依赖<br><small style="color:var(--text-dim)">Homebrew + Node.js</small></div>
<span class="flow-arrow">&#10132;</span>
<div class="flow-node">安装 Claude Code<br><small style="color:var(--text-dim)">npm 全局安装</small></div>
<span class="flow-arrow">&#10132;</span>
<div class="flow-node">运行安装脚本<br><small style="color:var(--text-dim)">或 git clone</small></div>
<span class="flow-arrow">&#10132;</span>
<div class="flow-node">输入密码<br><small style="color:var(--text-dim)">主密码</small></div>
<span class="flow-arrow">&#10132;</span>
<div class="flow-node active">开始使用<br><small style="color:var(--green)">Bookworm 激活</small></div>
</div>
<p style="text-align:center;color:var(--text-dim);font-size:0.9rem">首次安装约 10 分钟(含依赖下载),之后每次启动约 5-15 秒</p>
</div>
<!-- ============================================================ -->
<!-- 第一步:安装依赖 -->
<!-- ============================================================ -->
<div class="section">
<h2><span class="num">1</span>安装依赖软件</h2>
<div class="alert danger">
<span class="alert-icon">&#9888;</span>
<div>
<strong>国内必须:代理/VPN 软件</strong><br>
Claude Code 启动时会检查 <code>api.anthropic.com</code>,国内无法直连。<br>
请先安装并启动代理软件ClashX / Surge / V2Ray / 任意 VPN安装脚本会<strong>自动检测</strong>系统代理。<br>
无代理 = Claude Code 无法启动。
</div>
</div>
<div class="alert info">
<span class="alert-icon">&#128161;</span>
<div>
<strong>中转站不走代理</strong><br>
API 中转站 <code>bww.letcareme.com</code> 部署在国内阿里云,<strong>不需要通过代理访问</strong><br>
安装脚本已自动设置 <code>NO_PROXY=bww.letcareme.com,code.letcareme.com</code>,无需手动配置。<br>
如果代理软件有"绕过规则"设置,建议把 <code>*.letcareme.com</code> 加入直连列表。
</div>
</div>
<p>需要安装以下软件。如果已装过可跳到下一步。</p>
<!-- Homebrew -->
<div class="step">
<div class="step-icon blue">A</div>
<div class="step-content">
<h4>安装 HomebrewmacOS 包管理器)</h4>
<p>Homebrew 是 macOS 上最常用的包管理器,后续用它安装 Node.js 和 Git。</p>
</div>
</div>
<p>打开 <strong>终端</strong>(按 <code>&#8984; + 空格</code> 搜索 "终端" 或 "Terminal"),执行:</p>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">/bin/bash</span> -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"</code>
</div>
<div class="alert info">
<span class="alert-icon">&#128161;</span>
<div>
<strong>国内加速</strong><br>
如果下载太慢,可以使用清华镜像:<br>
<code>export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git"</code><br>
<code>export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git"</code><br>
设置后重新执行上面的安装命令。
</div>
</div>
<div class="alert warning">
<span class="alert-icon">&#9888;</span>
<div>
<strong>Apple Silicon (M1/M2/M3/M4) 用户注意!</strong><br>
安装完成后,需要将 Homebrew 添加到 PATH。终端会提示你执行以下命令
</div>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="comment"># Apple Silicon Mac 需要执行Intel Mac 不需要)</span>
<span class="cmd">echo</span> 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
<span class="cmd">eval</span> "$(/opt/homebrew/bin/brew shellenv)"</code>
</div>
<p style="margin-top:0.8rem">验证安装成功:</p>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">brew</span> --version <span class="comment"># 应显示 Homebrew 4.x.x</span></code>
</div>
<!-- Node.js -->
<div class="step" style="margin-top:1.5rem">
<div class="step-icon blue">B</div>
<div class="step-content">
<h4>安装 Node.js必须</h4>
<p>用 Homebrew 一行命令安装。</p>
</div>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">brew</span> install node</code>
</div>
<p style="color:var(--text-dim);font-size:0.85rem">也可以从 <a href="https://nodejs.org/zh-cn" target="_blank">nodejs.org</a> 下载 .pkg 安装包。</p>
<p style="margin-top:0.5rem">验证安装成功:</p>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">node</span> -v <span class="comment"># 应显示 v22.x.x</span>
<span class="cmd">npm</span> -v <span class="comment"># 应显示 10.x.x</span></code>
</div>
<!-- Git -->
<div class="step" style="margin-top:1.5rem">
<div class="step-icon blue">C</div>
<div class="step-content">
<h4>安装 Git必须</h4>
<p>macOS 通常自带 Git如没有则用 Homebrew 安装。</p>
</div>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="comment"># 检查是否已安装</span>
<span class="cmd">git</span> --version
<span class="comment"># 如果提示安装 Xcode Command Line Tools点击"安装"即可</span>
<span class="comment"># 或者用 Homebrew 安装:</span>
<span class="cmd">brew</span> install git</code>
</div>
</div>
<!-- ============================================================ -->
<!-- 第二步:安装 Claude Code -->
<!-- ============================================================ -->
<div class="section">
<h2><span class="num">2</span>安装 Claude Code</h2>
<div class="step">
<div class="step-icon green">1</div>
<div class="step-content">
<h4>全局安装</h4>
<p>在终端中执行:</p>
</div>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">npm</span> i -g @anthropic-ai/claude-code</code>
</div>
<p style="color:var(--text-dim);font-size:0.85rem">安装过程需要几分钟,等待完成即可。如果报权限错误,在前面加 <code>sudo</code></p>
<div class="step">
<div class="step-icon green">2</div>
<div class="step-content">
<h4>验证安装</h4>
</div>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">claude</span> --version <span class="comment"># 应显示版本号</span></code>
</div>
<div class="alert info">
<span class="alert-icon">&#128161;</span>
<div>
<strong>不需要登录 Claude 账号!</strong><br>
Bookworm 使用中转站 API安装 Claude Code 后直接进入下一步,不用执行 <code>claude login</code>
</div>
</div>
</div>
<!-- ============================================================ -->
<!-- 第三步:安装 Bookworm -->
<!-- ============================================================ -->
<div class="section">
<h2><span class="num">3</span>安装 Bookworm核心步骤</h2>
<div class="step">
<div class="step-icon purple">1</div>
<div class="step-content">
<h4>克隆引导仓库</h4>
<p>在终端中执行以下命令。系统会提示输入用户名和密码。</p>
</div>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">git clone</span> <span class="url">https://code.letcareme.com/bookworm/bookworm-boot.git</span>
<span class="cmd">cd</span> bookworm-boot</code>
</div>
<div class="screenshot-note">
<strong>弹出用户名密码?</strong> 输入管理员提供给你的 Gitea 账号密码。这是 Gitea 的密码,不是主密码。
</div>
<div class="step">
<div class="step-icon purple">2</div>
<div class="step-content">
<h4>运行安装脚本</h4>
<p>在终端中执行安装脚本:</p>
</div>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">bash</span> Bookworm-Setup.sh</code>
</div>
<p style="color:var(--text-dim);font-size:0.85rem">如果提示权限不足:<code>chmod +x Bookworm-Setup.sh && ./Bookworm-Setup.sh</code></p>
<div class="step">
<div class="step-icon purple">3</div>
<div class="step-content">
<h4>输入主密码</h4>
<p>脚本会提示 <strong>"输入主密码解密凭证"</strong>,输入管理员提供的<strong>主密码</strong>(不是 Gitea 密码),按回车。</p>
<p>密码输入时不显示字符,这是正常的。<strong>输错了可以重试,最多 3 次。</strong></p>
</div>
</div>
<div class="screenshot-note">
<strong>两个密码不要搞混:</strong><br>
<strong>Gitea 密码</strong> = 克隆仓库时输入的,用于下载文件<br>
<strong>主密码</strong> = 解密 API 凭证时输入的,用于启动 Claude Code
</div>
<div class="step">
<div class="step-icon green">4</div>
<div class="step-content">
<h4>等待完成</h4>
<p>脚本会显示步骤进度 [1/8] 到 [8/8],自动完成:</p>
<ul style="color:var(--text-dim);font-size:0.9rem;padding-left:1.2rem;margin-top:0.3rem">
<li>[1/6] 检查依赖 (Homebrew / Node.js / Git / OpenSSL / Claude Code)</li>
<li>[2/6] 自动检测代理 + 设置 NO_PROXY</li>
<li>[3/6] 同步配置 (克隆/更新 92 个 Skills)</li>
<li>[4/6] 解密凭证 (输入主密码) + 渲染配置模板</li>
<li>[5/6] 配置终端别名 (bw / bw-update)</li>
<li>[6/6] 完成 — 可选立即启动</li>
</ul>
</div>
</div>
<div class="alert success">
<span class="alert-icon">&#10003;</span>
<div>
<strong>看到 "Bookworm 就绪" 绿色横幅就说明成功了!</strong><br>
Claude Code 启动后,脚本会验证 Skills/Hooks/配置 完整性,全部 [OK] 后进入 Bookworm 模式。<br>
所有 API 请求通过中转站转发,不需要自己的 Claude 账号。
</div>
</div>
<div class="alert warning">
<span class="alert-icon">&#9888;</span>
<div>
<strong>看到 "原生模式启动" 黄色横幅?</strong><br>
说明 Bookworm 配置不完整。请重新运行安装脚本,或联系管理员。
</div>
</div>
</div>
<!-- ============================================================ -->
<!-- 日常使用 -->
<!-- ============================================================ -->
<div class="section">
<h2><span class="num">4</span>日常使用</h2>
<div class="card">
<h3>方法一:终端别名(推荐,最简单)</h3>
<p>安装脚本已自动添加别名到 <code>~/.zshrc</code>,直接在终端输入:</p>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">bw</span> <span class="comment"># 快速启动</span>
<span class="cmd">bw-update</span> <span class="comment"># 同步更新</span></code>
</div>
<div class="card" style="margin-top:1rem">
<h3>方法二:脚本命令</h3>
<p>如果别名不可用,在终端中手动执行:</p>
</div>
<table>
<tr><th>操作</th><th>命令</th><th>说明</th></tr>
<tr>
<td><strong>快速启动</strong></td>
<td><code>bw</code></td>
<td>直接启动 Claude Code + Bookworm</td>
</tr>
<tr>
<td><strong>同步更新</strong></td>
<td><code>bw-update</code></td>
<td>更新 boot + 配置仓库</td>
</tr>
</table>
<div class="alert info">
<span class="alert-icon">&#128161;</span>
<div>
<strong>启动时显示 "有 N 个新更新可用"</strong><br>
说明管理员更新了 Skills 或 Hooks。执行 <code>bw-update</code> 即可同步。
</div>
</div>
</div>
<!-- ============================================================ -->
<!-- 密码说明 -->
<!-- ============================================================ -->
<div class="section">
<h2><span class="num">5</span>密码说明</h2>
<div class="card">
<h3>本系统有两个密码,不要搞混</h3>
<table>
<tr><th>名称</th><th>用途</th><th>何时输入</th></tr>
<tr><td><strong>Gitea 密码</strong></td><td>下载文件(克隆仓库)</td><td>首次安装时 git 弹出要求</td></tr>
<tr><td><strong>主密码</strong></td><td>解密 API 凭证</td><td>每次启动脚本提示输入</td></tr>
</table>
</div>
<div class="alert info">
<span class="alert-icon">&#128161;</span>
<div>
<strong>密码输错了?</strong> 最多可以重试 3 次不用紧张。3 次都错才会退出。
</div>
</div>
<div class="card" style="margin-top:0.8rem">
<h3>本日免密功能</h3>
<p>首次解密成功后,脚本会询问 <strong>"今日内免密启动? (y/n)"</strong></p>
<p><strong>y</strong> 后,当天再次启动无需输入主密码,次日自动过期。</p>
<p style="color:var(--text-dim);font-size:0.85rem;margin-top:0.3rem">凭证缓存在 macOS 钥匙串 (Keychain) 中,仅当前用户可读。</p>
</div>
<div class="alert warning" style="margin-top:0.8rem">
<span class="alert-icon">&#128274;</span>
<div><strong>主密码无法找回</strong> — 忘记后联系管理员重新生成 secrets.enc。</div>
</div>
</div>
<!-- ============================================================ -->
<!-- 使用完毕 -->
<!-- ============================================================ -->
<div class="section">
<h2><span class="num">6</span>使用完毕 — 清理 / 卸载</h2>
<p>在终端中执行清理命令:</p>
<table>
<tr><th>场景</th><th>命令</th><th>说明</th></tr>
<tr>
<td><strong>基础清理</strong></td>
<td><code>rm -rf ~/.claude</code></td>
<td>删除 Bookworm 配置,保留引导仓库供重新安装</td>
</tr>
<tr>
<td><strong>完整恢复</strong></td>
<td><code>rm -rf ~/.claude ~/bookworm-boot</code></td>
<td>删除所有 Bookworm 文件</td>
</tr>
<tr>
<td><strong>深度清理</strong></td>
<td><code>rm -rf ~/.claude ~/bookworm-boot && sed -i '' '/Bookworm Portable/,+2d' ~/.zshrc && git credential-osxkeychain erase &lt;&lt;&lt; "host=code.letcareme.com"</code></td>
<td>完整恢复 + 清除别名 + 清除 Git 凭证</td>
</tr>
</table>
<div class="alert danger">
<span class="alert-icon">&#9888;</span>
<div>
<strong>在他人电脑/公用电脑上务必清理:</strong><br>
执行深度清理命令,确保不留下任何凭证或配置
</div>
</div>
</div>
<!-- ============================================================ -->
<!-- 故障排查 -->
<!-- ============================================================ -->
<div class="section">
<h2><span class="num">!</span>常见问题排查</h2>
<div class="card">
<h3>&#10060; brew 命令找不到</h3>
<p><strong>原因:</strong>Homebrew 未添加到 PATHApple Silicon Mac 常见)。</p>
<p><strong>解决:</strong></p>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="comment"># Apple Silicon (M1/M2/M3/M4)</span>
<span class="cmd">eval</span> "$(/opt/homebrew/bin/brew shellenv)"
<span class="comment"># Intel Mac</span>
<span class="cmd">eval</span> "$(/usr/local/bin/brew shellenv)"</code>
</div>
<div class="card">
<h3>&#10060; npm 全局安装报 Permission denied</h3>
<p><strong>原因:</strong>macOS 默认目录权限限制。</p>
<p><strong>解决方式一(推荐):</strong>修改 npm 全局目录:</p>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">mkdir</span> -p ~/.npm-global
<span class="cmd">npm</span> config set prefix '~/.npm-global'
<span class="cmd">echo</span> 'export PATH=~/.npm-global/bin:$PATH' >> ~/.zshrc
<span class="cmd">source</span> ~/.zshrc
<span class="comment"># 然后重新安装</span>
<span class="cmd">npm</span> i -g @anthropic-ai/claude-code</code>
</div>
<p style="color:var(--text-dim);font-size:0.85rem">解决方式二:在命令前加 <code>sudo</code>(简单但不推荐长期使用)。</p>
<div class="card">
<h3>&#10060; git clone 失败 / 认证失败</h3>
<p><strong>解决步骤:</strong></p>
<ol style="color:var(--text-dim);padding-left:1.5rem;margin-top:0.3rem">
<li>浏览器打开 <code>https://code.letcareme.com</code> 确认网站可访问</li>
<li>确认用户名密码正确(区分大小写)</li>
<li>如果 macOS 弹出钥匙串对话框,点"始终允许"</li>
<li>检查网络是否需要代理</li>
</ol>
</div>
<div class="card">
<h3>&#10060; 解密凭证失败 / 主密码错误</h3>
<p><strong>原因:</strong>主密码区分大小写,且无法找回。</p>
<p><strong>解决:</strong>仔细检查密码是否正确。如确认忘记,联系管理员重新生成 <code>secrets.enc</code></p>
</div>
<div class="card">
<h3>&#10060; openssl 版本不兼容</h3>
<p><strong>原因:</strong>macOS 自带 LibreSSL部分加密参数可能不同。</p>
<p><strong>解决:</strong>安装 OpenSSL</p>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="cmd">brew</span> install openssl
<span class="comment"># 脚本会自动检测 Homebrew 安装的 openssl 路径</span></code>
</div>
<div class="card">
<h3>&#10060; ECONNRESET / "Unable to connect to API"</h3>
<p><strong>原因:</strong>代理软件把国内中转站 <code>bww.letcareme.com</code> 的流量也走了国际线路。</p>
<p><strong>解决:</strong>手动设置 NO_PROXY 后重试:</p>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="comment"># 设置中转站直连(不走代理)</span>
<span class="cmd">export</span> NO_PROXY="bww.letcareme.com,code.letcareme.com"
<span class="comment"># 重新启动</span>
<span class="cmd">bw</span></code>
</div>
<p style="color:var(--text-dim);font-size:0.85rem">或在代理软件中将 <code>*.letcareme.com</code> 加入直连规则。</p>
<div class="card">
<h3>&#10060; "Not logged in" / 直接运行 claude 报错</h3>
<p><strong>原因:</strong>API 凭证是进程级环境变量,只在安装脚本启动的进程中有效。</p>
<p><strong>解决:</strong><strong>不要直接运行 <code>claude</code></strong>,必须通过以下方式启动:</p>
<ul style="color:var(--text-dim);font-size:0.9rem;padding-left:1.2rem;margin-top:0.3rem">
<li>终端输入 <code>bw</code>(推荐)</li>
<li><code>cd ~/bookworm-boot && bash Bookworm-Setup.sh</code></li>
</ul>
</div>
<div class="card">
<h3>&#10060; 安装包下载太慢</h3>
<p><strong>解决:</strong>设置淘宝镜像:</p>
</div>
<div class="code-block" onclick="copyCode(this)">
<code><span class="comment"># npm 淘宝镜像</span>
<span class="cmd">npm</span> config set registry https://registry.npmmirror.com
<span class="comment"># Homebrew 清华镜像</span>
<span class="cmd">export</span> HOMEBREW_BREW_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git"
<span class="comment"># 然后重新安装</span>
<span class="cmd">npm</span> i -g @anthropic-ai/claude-code</code>
</div>
<div class="card">
<h3>&#10060; 需要自己的 Claude 账号吗?</h3>
<p><strong>不需要。</strong>所有 API 请求通过中转站转发,消耗中转站额度。目标机不需要任何 Anthropic 账号或订阅。</p>
</div>
</div>
<!-- ============================================================ -->
<!-- 安装检查清单 -->
<!-- ============================================================ -->
<div class="section">
<h2>安装检查清单</h2>
<p style="color:var(--text-dim);margin-bottom:0.5rem">逐项确认,全部打勾即可开始使用:</p>
<ul class="checklist">
<li><strong>Homebrew 已安装</strong><code>brew --version</code> 显示版本号</li>
<li><strong>Node.js 已安装</strong><code>node -v</code> 显示版本号</li>
<li><strong>Git 已安装</strong><code>git --version</code> 显示版本号</li>
<li><strong>npm 可用</strong><code>npm -v</code> 显示版本号</li>
<li><strong>Claude Code 已安装</strong><code>claude --version</code> 显示版本号</li>
<li><strong>已获取 Gitea 账号密码</strong> — 管理员提供</li>
<li><strong>已获取主密码</strong> — 管理员提供(用于解密 API 凭证)</li>
<li><strong>能访问 code.letcareme.com</strong> — 浏览器打开确认</li>
<li><strong>代理/VPN 已启动</strong> — 国内必须,脚本自动检测 (ClashX/Surge/V2Ray 等)</li>
</ul>
</div>
<!-- ============================================================ -->
<!-- 快速参考卡片 -->
<!-- ============================================================ -->
<div class="section">
<h2>快速参考</h2>
<table>
<tr><th>操作</th><th>快捷方式</th><th>完整命令</th></tr>
<tr><td>首次安装</td><td>git clone + <code>bash Bookworm-Setup.sh</code></td><td><code>cd ~/bookworm-boot && bash Bookworm-Setup.sh</code></td></tr>
<tr><td>快速启动</td><td><code>bw</code></td><td><code>NO_PROXY="bww.letcareme.com,code.letcareme.com,localhost,127.0.0.1" claude</code></td></tr>
<tr><td>同步更新</td><td><code>bw-update</code></td><td><code>cd ~/bookworm-boot && git pull && cd ~/.claude && git pull</code></td></tr>
<tr><td>基础清理</td><td colspan="2"><code>rm -rf ~/.claude</code></td></tr>
<tr><td>完整恢复</td><td colspan="2"><code>rm -rf ~/.claude ~/bookworm-boot</code></td></tr>
<tr><td>深度清理</td><td colspan="2"><code>rm -rf ~/.claude ~/bookworm-boot && sed -i '' '/Bookworm/,+2d' ~/.zshrc</code></td></tr>
</table>
</div>
<!-- ============================================================ -->
<!-- 安全须知 -->
<!-- ============================================================ -->
<div class="section">
<h2>安全须知</h2>
<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>进程级环境变量 + 可选本日缓存 (macOS Keychain, 当日 23:59 过期)</td></tr>
<tr><td>登录保护</td><td>fail2ban (5 次失败/小时 → 封禁 24 小时)</td></tr>
</table>
<div class="alert warning" style="margin-top:1rem">
<span class="alert-icon">&#128274;</span>
<div>
<strong>主密码无法找回</strong> — 请妥善保管。忘记后需管理员重新生成加密凭证。
</div>
</div>
</div>
</div>
<div class="footer">
Bookworm Portable v1.5 — macOS 保姆式安装手册<br>
&copy; 2026 Bookworm Smart Assistant
</div>
<script>
function copyCode(el) {
const code = el.querySelector('code').innerText;
navigator.clipboard.writeText(code).then(() => {
el.classList.add('copied');
setTimeout(() => el.classList.remove('copied'), 1500);
});
}
</script>
</body>
</html>