返回 CodeWhale
page.tsx
根目录 / web / app / [locale] / install / page.tsx
1 import Link from "next/link";
2 import { Seal } from "@/components/seal";
3 import { InstallCodeBlock } from "@/components/install-code-block";
4 import { InstallBinary } from "@/components/install-binary";
5 import { GETTING_STARTED_STEPS } from "@/lib/content/getting-started";
6 import { getFacts } from "@/lib/facts";
7 import { buildPageMetadata } from "@/lib/page-meta";
8
9 export const revalidate = 300;
10
11 export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
12 const { locale } = await params;
13 const isZh = locale === "zh";
14 return buildPageMetadata({
15 path: "/install",
16 locale,
17 title: isZh ? "安装 · Codewhale" : "Install · Codewhale",
18 description: isZh
19 ? "一行 curl -fsSL https://codewhale.net/install.sh | sh 安装或更新 Codewhale,也支持 npm、Cargo、GitHub Releases、CNB 镜像、Homebrew、预编译二进制、Docker 和源码编译。"
20 : "Install or update Codewhale with curl -fsSL https://codewhale.net/install.sh | sh, or via npm, cargo, GitHub Releases, the CNB mirror, Homebrew, prebuilt binaries, Docker, or from source.",
21 });
22 }
23
24 const SHELL_INSTALL = `curl -fsSL https://codewhale.net/install.sh | sh`;
25 const SHELL_INSPECT = `curl -fsSL https://codewhale.net/install.sh`;
26 const NPM_INSTALL = `npm install -g codewhale`;
27 const CARGO_INSTALL = `cargo install codewhale-cli --locked
28 cargo install codewhale-tui --locked`;
29 const FIRST_RUN = `codewhale`;
30 const UPDATE = `codewhale update`;
31
32 const RELEASE_DOWNLOAD = `# Download your platform archive:
33 https://github.com/Hmbown/CodeWhale/releases/latest`;
34 const cnbInstall = (tag: string) => `cargo install --git https://cnb.cool/codewhale.net/codewhale --tag ${tag} codewhale-cli --locked --force
35 cargo install --git https://cnb.cool/codewhale.net/codewhale --tag ${tag} codewhale-tui --locked --force`;
36 const TUNA_CONFIG = `# ~/.cargo/config.toml
37 [source.crates-io]
38 replace-with = "tuna"
39
40 [source.tuna]
41 registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"`;
42 const TUNA_INSTALL = `cargo install codewhale-cli --locked
43 cargo install codewhale-tui --locked`;
44
45 const BREW = `brew tap Hmbown/deepseek-tui
46 brew install deepseek-tui`;
47
48 const DOCKER = `docker volume create codewhale-home
49 docker run --rm -it \\
50 -e DEEPSEEK_API_KEY=$DEEPSEEK_API_KEY \\
51 -v codewhale-home:/home/codewhale/.codewhale \\
52 -v "$PWD:/workspace" -w /workspace \\
53 ghcr.io/hmbown/codewhale:latest`;
54
55 const FROM_SOURCE = `git clone https://github.com/Hmbown/CodeWhale
56 cd CodeWhale
57 cargo build --release --locked
58
59 # Install two Cargo packages; together they provide three commands
60 cargo install --path crates/cli --locked # codewhale + codew
61 cargo install --path crates/tui --locked # codewhale-tui`;
62
63 const CONFIG_TREE = `$CODEWHALE_HOME/ (default: ~/.codewhale/)
64 ├── config.toml api keys, model, hooks, profiles
65 ├── mcp.json MCP server definitions
66 ├── skills/ user skills (each with SKILL.md)
67 ├── sessions/ checkpoints + offline queue
68 ├── tasks/ background task store
69 └── audit.log best-effort credential / approval / elevation events
70
71 ./.codewhale/ project-scoped config (optional, per-repo)`;
72
73 const CONFIG_TREE_ZH = `$CODEWHALE_HOME/(默认:~/.codewhale/)
74 ├── config.toml API 密钥、模型、钩子、配置集
75 ├── mcp.json MCP 服务器定义
76 ├── skills/ 用户技能(每个含 SKILL.md)
77 ├── sessions/ 检查点 + 离线队列
78 ├── tasks/ 后台任务存储
79 └── audit.log 尽力写入的凭证 / 审批 / 提权事件
80
81 ./.codewhale/ 项目级配置(可选,每个仓库)`;
82
83 export default async function InstallPage({ params }: { params: Promise<{ locale: string }> }) {
84 const { locale } = await params;
85 const isZh = locale === "zh";
86 const facts = await getFacts();
87 const publishedRelease = facts.latestPublishedRelease;
88 const sourceIsPublished = publishedRelease?.version === facts.version;
89 const firstSession = GETTING_STARTED_STEPS.find((step) => step.id === "first-session")!;
90 const connectProvider = GETTING_STARTED_STEPS.find((step) => step.id === "connect-provider")!;
91 const verify = `codewhale --version${
92 publishedRelease ? ` # latest published: ${publishedRelease.version}` : ""
93 }
94 codewhale doctor`;
95
96 const copyLabel = isZh ? "复制" : "Copy";
97 const copiedLabel = isZh ? "已复制 ✓" : "Copied ✓";
98
99 return (
100 <>
101 {/* ① INSTALL */}
102 <section className="mx-auto max-w-[1100px] px-6 pt-12 pb-10">
103 <div className="flex items-baseline gap-4 mb-3">
104 <Seal char="装" />
105 <div className="eyebrow">{isZh ? "01 · 安装" : "01 · Install"}</div>
106 </div>
107 <h1 className="font-display tracking-crisp mb-6">
108 {isZh ? (
109 <>安装 <span className="font-cjk text-indigo text-5xl ml-2">Install</span></>
110 ) : (
111 <>Install <span className="font-cjk text-indigo text-5xl ml-2">安装</span></>
112 )}
113 </h1>
114
115 <div className="space-y-3">
116 <InstallCodeBlock cmd={SHELL_INSTALL} copyLabel={copyLabel} copiedLabel={copiedLabel} />
117 <InstallCodeBlock cmd={FIRST_RUN} copyLabel={copyLabel} copiedLabel={copiedLabel} />
118 </div>
119
120 <p className="mt-4 text-sm text-ink-soft leading-relaxed max-w-2xl">
121 {isZh ? (
122 <>
123 macOS / Linux 安装脚本会从 GitHub Releases 下载经 SHA-256 校验的二进制,
124 默认安装到 <code className="inline">~/.local/bin</code>,并安装{" "}
125 <code className="inline">codewhale</code>、<code className="inline">codew</code> 和{" "}
126 <code className="inline">codewhale-tui</code>。先审阅脚本可运行{" "}
127 <code className="inline">{SHELL_INSPECT}</code>。下方「其他安装方式」列出 npm、Cargo、GitHub Releases、
128 CNB、国内镜像、Homebrew、预编译二进制和 Docker。
129 </>
130 ) : (
131 <>
132 The macOS / Linux installer downloads SHA-256-verified binaries from GitHub Releases,
133 installs to <code className="inline">~/.local/bin</code> by default, and exposes{" "}
134 <code className="inline">codewhale</code>, <code className="inline">codew</code>, and{" "}
135 <code className="inline">codewhale-tui</code>. To inspect it first, run{" "}
136 <code className="inline">{SHELL_INSPECT}</code>. See{" "}
137 <a href="#other-ways" className="body-link">Other ways to install</a> below for
138 npm, cargo, GitHub Releases, CNB, Homebrew, prebuilt binaries, Docker, or mainland
139 China mirrors.
140 </>
141 )}
142 </p>
143 </section>
144
145 {/* ② VERIFY */}
146 <section className="mx-auto max-w-[1100px] px-6 py-10 hairline-t">
147 <div className="flex items-baseline gap-4 mb-5">
148 <Seal char="验" />
149 <div className="eyebrow">{isZh ? "02 · 验证" : "02 · Verify"}</div>
150 </div>
151
152 <InstallCodeBlock cmd={verify} copyLabel={copyLabel} copiedLabel={copiedLabel} />
153
154 <p className="mt-4 text-sm text-ink-soft leading-relaxed max-w-2xl">
155 {isZh ? (
156 <>
157 <code className="inline">codewhale doctor</code> 检查 API 密钥、网络、沙箱可用性、
158 MCP 服务器,并在终端输出修复建议;需要结构化输出时可加{" "}
159 <code className="inline">--json</code>。
160 </>
161 ) : (
162 <>
163 <code className="inline">codewhale doctor</code> checks your API key, network,
164 sandbox availability, and MCP servers, then prints remediation guidance. Add{" "}
165 <code className="inline">--json</code> when you need structured output.
166 </>
167 )}
168 </p>
169 </section>
170
171 {/* ③ UPDATE */}
172 <section className="mx-auto max-w-[1100px] px-6 py-10 hairline-t">
173 <div className="flex items-baseline gap-4 mb-5">
174 <Seal char="新" />
175 <div className="eyebrow">{isZh ? "03 · 更新" : "03 · Update"}</div>
176 </div>
177
178 <InstallCodeBlock cmd={UPDATE} copyLabel={copyLabel} copiedLabel={copiedLabel} />
179 <div className="mt-3">
180 <InstallCodeBlock cmd={SHELL_INSTALL} copyLabel={copyLabel} copiedLabel={copiedLabel} />
181 </div>
182
183 <p className="mt-4 text-sm text-ink-soft leading-relaxed max-w-2xl">
184 {isZh ? (
185 <>
186 检查 GitHub Releases 是否有新版本并就地替换二进制。
187 通过 <code className="inline">install.sh</code> 安装的用户也可以重跑同一条{" "}
188 <code className="inline">curl</code> 命令覆盖更新。
189 通过包管理器安装的话,用包管理器升级更稳:npm 安装的运行{" "}
190 <code className="inline">npm update -g codewhale</code>;
191 Cargo 安装的重跑两个 package 的 <code className="inline">cargo install</code> 命令并加{" "}
192 <code className="inline">--force</code>(<code className="inline">codewhale-cli</code> 提供
193 <code className="inline">codewhale</code> 与 <code className="inline">codew</code>,
194 <code className="inline">codewhale-tui</code> 提供同名命令);
195 旧版 Homebrew tap 用 <code className="inline">brew upgrade deepseek-tui</code>。
196 </>
197 ) : (
198 <>
199 Checks GitHub Releases for a newer version and replaces the binary in place. If you
200 installed with <code className="inline">install.sh</code>, re-run the same{" "}
201 <code className="inline">curl</code> command to overwrite the binaries.
202 If you installed via a package manager, prefer it instead: npm users run{" "}
203 <code className="inline">npm update -g codewhale</code>; cargo users re-run the two
204 package <code className="inline">cargo install</code> commands with{" "}
205 <code className="inline">--force</code> (<code className="inline">codewhale-cli</code>
206 provides <code className="inline">codewhale</code> and <code className="inline">codew</code>;
207 <code className="inline">codewhale-tui</code> provides the command of the same name);
208 the legacy Homebrew tap updates with{" "}
209 <code className="inline">brew upgrade deepseek-tui</code>.
210 </>
211 )}
212 </p>
213 </section>
214
215 {/* ④ FIRST RUN */}
216 <section className="mx-auto max-w-[1100px] px-6 py-10 hairline-t">
217 <div className="flex items-baseline gap-4 mb-5">
218 <Seal char="始" />
219 <div className="eyebrow">{isZh ? "04 · 首次运行" : "04 · First run"}</div>
220 </div>
221
222 <ol className="space-y-6 max-w-2xl">
223 <li>
224 <div className="font-display text-lg mb-2">
225 {isZh ? `① ${firstSession.title.zh}` : `① ${firstSession.title.en}`}
226 </div>
227 <p className="text-sm text-ink-soft leading-relaxed">
228 {isZh ? firstSession.body.zh : firstSession.body.en}
229 </p>
230 <div className="mt-2">
231 <InstallCodeBlock
232 cmd={firstSession.commands.join("\n")}
233 copyLabel={copyLabel}
234 copiedLabel={copiedLabel}
235 />
236 </div>
237 </li>
238
239 <li>
240 <div className="font-display text-lg mb-2">
241 {isZh ? `② ${connectProvider.title.zh}` : `② ${connectProvider.title.en}`}
242 </div>
243 <p className="text-sm text-ink-soft leading-relaxed">
244 {isZh ? connectProvider.body.zh : connectProvider.body.en}
245 </p>
246 <div className="mt-2">
247 <InstallCodeBlock
248 cmd={connectProvider.commands.join("\n")}
249 copyLabel={copyLabel}
250 copiedLabel={copiedLabel}
251 />
252 </div>
253 <Link
254 href={`/${locale}${connectProvider.link.href}`}
255 className="body-link mt-2 inline-block text-sm"
256 >
257 {isZh ? connectProvider.link.label.zh : connectProvider.link.label.en} →
258 </Link>
259 </li>
260
261 <li>
262 <div className="font-display text-lg mb-2">
263 {isZh ? "③ 在项目目录中运行" : "③ Run it in a project"}
264 </div>
265 <InstallCodeBlock cmd={`cd path/to/project\ncodewhale`} copyLabel={copyLabel} copiedLabel={copiedLabel} />
266 <p className="mt-3 text-sm text-ink-soft leading-relaxed">
267 {isZh ? (
268 <>
269 新会话使用你选择的默认模式(未修改则为 Act)。输入区空闲时,按{" "}
270 <kbd className="font-mono text-xs px-1 hairline-t hairline-b hairline-l hairline-r">Tab</kbd>{" "}
271 循环 Plan → Act → Operate;按{" "}
272 <kbd className="font-mono text-xs px-1 hairline-t hairline-b hairline-l hairline-r">Shift+Tab</kbd>{" "}
273 循环 Ask → Auto-Review → Full Access 权限姿态。也可以运行{" "}
274 <code className="inline">/mode</code> 选择模式或运行 <code className="inline">/config</code>{" "}
275 查看权限。Plan 始终只读;Full Access 仅应用于你信任的工作区。
276 </>
277 ) : (
278 <>
279 New sessions use your selected default mode (Act unless you changed it). When the composer is idle, press{" "}
280 <kbd className="font-mono text-xs px-1 hairline-t hairline-b hairline-l hairline-r">Tab</kbd>{" "}
281 to cycle Plan → Act → Operate; press{" "}
282 <kbd className="font-mono text-xs px-1 hairline-t hairline-b hairline-l hairline-r">Shift+Tab</kbd>{" "}
283 to cycle Ask → Auto-Review → Full Access permission postures. You can also run{" "}
284 <code className="inline">/mode</code> to choose a mode or <code className="inline">/config</code>{" "}
285 to inspect permissions. Plan stays read-only; use Full Access only in a workspace you trust.
286 </>
287 )}
288 </p>
289 </li>
290 </ol>
291 </section>
292
293 {/* ⑤ OTHER WAYS TO INSTALL */}
294 <section id="other-ways" className="bg-paper-deep hairline-t hairline-b">
295 <div className="mx-auto max-w-[1100px] px-6 py-12">
296 <div className="flex items-baseline gap-4 mb-5">
297 <Seal char="备" />
298 <div className="eyebrow">{isZh ? "05 · 其他安装方式" : "05 · Other ways to install"}</div>
299 </div>
300 <h2 className="font-display text-3xl mb-2">
301 {isZh ? "其他安装方式" : "Other ways to install"}
302 </h2>
303 <p className="text-sm text-ink-soft max-w-2xl mb-4">
304 {isZh
305 ? "如果上面的脚本路径不适合你,请从下面选择匹配你环境的方式。各渠道的命令和打包形式有所不同,说明会明确列出安装内容。"
306 : "If the script above doesn't fit your setup, choose the channel that matches your environment. Command availability and packaging differ by channel, and each description states exactly what it installs."}
307 </p>
308
309 <p className="text-sm text-ink-soft max-w-2xl mb-10">
310 {publishedRelease
311 ? isZh
312 ? `下方的发布命令以 ${publishedRelease.tag} 为准;它是 GitHub 上最新的已发布版本。${sourceIsPublished ? "当前源码与该发布版一致。" : `当前源码候选版为 v${facts.version},发布前不会被安装命令当作正式版本。`}`
313 : `Release-backed commands below use ${publishedRelease.tag}, the latest version published on GitHub. ${sourceIsPublished ? "The current source matches that release." : `The current source candidate is v${facts.version}; install commands do not advertise it before publication.`}`
314 : isZh
315 ? "暂时无法验证最新的 GitHub 发布标签;请先查看 Releases,再运行需要固定标签的命令。"
316 : "The latest GitHub release tag could not be verified. Check Releases before running a command that requires a pinned tag."}
317 </p>
318
319 <div className="space-y-10">
320 {/* npm */}
321 <div>
322 <div className="eyebrow mb-2 text-indigo">
323 npm{" "}
324 <span className="text-ink-mute font-mono normal-case tracking-normal">
325 {isZh ? "· Node 18+" : "· Node 18+"}
326 </span>
327 </div>
328 <InstallCodeBlock cmd={NPM_INSTALL} copyLabel={copyLabel} copiedLabel={copiedLabel} />
329 <p className="mt-3 text-sm text-ink-soft leading-relaxed max-w-2xl">
330 {isZh ? (
331 <>
332 npm wrapper 会从 GitHub Releases 下载经 SHA-256 校验的二进制,并安装{" "}
333 <code className="inline">codewhale</code>、<code className="inline">codew</code> 和{" "}
334 <code className="inline">codewhale-tui</code> 三个命令。
335 </>
336 ) : (
337 <>
338 The npm wrapper downloads SHA-256-verified binaries from GitHub Releases and
339 installs <code className="inline">codewhale</code>,{" "}
340 <code className="inline">codew</code>, and{" "}
341 <code className="inline">codewhale-tui</code>.
342 </>
343 )}
344 </p>
345 </div>
346
347 {/* Cargo */}
348 <div>
349 <div className="eyebrow mb-2 text-indigo">
350 {isZh ? "Rust 工具链" : "Rust toolchain"}
351 </div>
352 <InstallCodeBlock cmd={CARGO_INSTALL} copyLabel={copyLabel} copiedLabel={copiedLabel} />
353 <p className="mt-3 text-sm text-ink-soft leading-relaxed max-w-2xl">
354 {isZh ? (
355 <>
356 两个 Cargo package 会把 <code className="inline">codewhale</code>、
357 <code className="inline">codew</code> 和 <code className="inline">codewhale-tui</code>
358 三个命令安装到 <code className="inline">~/.cargo/bin</code>。
359 需要 Rust 1.88+;Linux 用户先安装 <code className="inline">pkg-config</code> 和{" "}
360 <code className="inline">libdbus-1-dev</code> 等构建依赖。如未安装 Rust,可访问{" "}
361 <a href="https://rustup.rs" className="body-link">rustup.rs</a>。
362 </>
363 ) : (
364 <>
365 The two Cargo packages install three commands—
366 <code className="inline">codewhale</code>, <code className="inline">codew</code>, and{" "}
367 <code className="inline">codewhale-tui</code>—to <code className="inline">~/.cargo/bin</code>.
368 Requires Rust 1.88+; install via{" "}
369 <a href="https://rustup.rs" className="body-link">rustup.rs</a> if you don&apos;t have it.
370 On Linux, install build dependencies such as{" "}
371 <code className="inline">pkg-config</code> and{" "}
372 <code className="inline">libdbus-1-dev</code> first.
373 </>
374 )}
375 </p>
376 </div>
377
378 {/* GitHub Release */}
379 <div className="rounded-lg border border-ink/12 bg-white/70 p-5">
380 <div className="font-display text-lg mb-3">{isZh ? "GitHub Releases" : "GitHub Releases"}</div>
381 <InstallCodeBlock cmd={RELEASE_DOWNLOAD} copyLabel={copyLabel} copiedLabel={copiedLabel} />
382 </div>
383
384 {/* CNB */}
385 <div className="rounded-lg border border-ink/12 bg-white/70 p-5">
386 <div className="font-display text-lg mb-3">{isZh ? "CNB 镜像" : "CNB mirror"}</div>
387 {publishedRelease ? (
388 <InstallCodeBlock
389 cmd={cnbInstall(publishedRelease.tag)}
390 copyLabel={copyLabel}
391 copiedLabel={copiedLabel}
392 />
393 ) : (
394 <a
395 href="https://github.com/Hmbown/CodeWhale/releases/latest"
396 className="body-link"
397 >
398 {isZh ? "查看最新 GitHub 发布" : "Check the latest GitHub release"}
399 </a>
400 )}
401 </div>
402
403 {/* Mainland China network */}
404 <div>
405 <div className="eyebrow mb-2 text-indigo">
406 {isZh ? "中国大陆网络" : "Mainland China network"}
407 </div>
408 <p className="text-sm text-ink-soft leading-relaxed max-w-2xl mb-3">
409 {isZh ? (
410 <>
411 <strong className="text-indigo">官方源:</strong>
412 GitHub Releases 为唯一官方发布源。Cargo 经清华 Tuna 镜像——添加到 <code className="inline">~/.cargo/config.toml</code>:
413 </>
414 ) : (
415 <>
416 <strong className="text-indigo">Official source:</strong>{" "}
417 GitHub Releases is the sole canonical release source. Cargo via Tsinghua Tuna mirror — add to{" "}
418 <code className="inline">~/.cargo/config.toml</code>:
419 </>
420 )}
421 </p>
422 <InstallCodeBlock cmd={TUNA_CONFIG} copyLabel={copyLabel} copiedLabel={copiedLabel} />
423 <div className="mt-3">
424 <InstallCodeBlock cmd={TUNA_INSTALL} copyLabel={copyLabel} copiedLabel={copiedLabel} />
425 </div>
426
427 <p className="mt-4 text-sm text-ink-soft leading-relaxed max-w-2xl">
428 {isZh ? (
429 <>
430 npm 安装时设置 <code className="inline">CODEWHALE_USE_CNB_MIRROR=1</code>,
431 wrapper 会改从 CNB 镜像下载二进制而不是 GitHub。Cargo + Tuna 或 CNB
432 路径同样可以绕开 GitHub 下载瓶颈。
433 DeepSeek API(<code className="inline">api.deepseek.com</code>)在国内直连,无需代理。
434 </>
435 ) : (
436 <>
437 For the npm path, set{" "}
438 <code className="inline">CODEWHALE_USE_CNB_MIRROR=1</code> and the wrapper
439 downloads binaries from the CNB mirror instead of GitHub. Cargo + Tuna or the
440 CNB path also routes around GitHub download bottlenecks. The DeepSeek API at{" "}
441 <code className="inline">api.deepseek.com</code> is reachable from mainland China
442 without a proxy.
443 </>
444 )}
445 </p>
446 </div>
447
448 {/* Homebrew */}
449 <div>
450 <div className="eyebrow mb-2 text-indigo">
451 Homebrew{" "}
452 <span className="text-ink-mute font-mono normal-case tracking-normal">
453 {isZh ? "· macOS / Linux · 旧版 tap" : "· macOS / Linux · legacy tap"}
454 </span>
455 </div>
456 <InstallCodeBlock cmd={BREW} copyLabel={copyLabel} copiedLabel={copiedLabel} />
457 <p className="mt-3 text-sm text-ink-soft leading-relaxed max-w-2xl">
458 {isZh
459 ? "这是旧版 deepseek-tui tap,在 formula 重命名为 codewhale 期间保留以保证兼容,安装的同样是当前版本的二进制。"
460 : "This is the legacy deepseek-tui tap, kept for compatibility while the formula is renamed to codewhale. It installs the same current-release binaries."}
461 </p>
462 </div>
463
464 {/* Prebuilt binary */}
465 <div>
466 <div className="eyebrow mb-2 text-indigo">
467 {isZh ? "预编译二进制" : "Prebuilt binary"}{" "}
468 <span className="text-ink-mute font-mono normal-case tracking-normal">
469 {isZh ? "· 已自动检测" : "· auto-detected"}
470 </span>
471 </div>
472 <InstallBinary
473 copyLabel={copyLabel}
474 copiedLabel={copiedLabel}
475 verifyHeading={isZh ? "校验 SHA256" : "Verify checksum"}
476 />
477 </div>
478
479 {/* Docker */}
480 <div>
481 <div className="eyebrow mb-2 text-indigo">Docker</div>
482 <InstallCodeBlock cmd={DOCKER} copyLabel={copyLabel} copiedLabel={copiedLabel} />
483 <p className="mt-3 text-sm text-ink-soft leading-relaxed max-w-2xl">
484 {isZh
485 ? "发布镜像位于 GHCR。需要固定版本时,把 latest 替换成具体的发布标签。"
486 : "The release image is published to GHCR. Replace latest with a release tag when you need a pinned version."}
487 </p>
488 </div>
489
490 {/* From source */}
491 <div>
492 <div className="eyebrow mb-2 text-indigo">
493 {isZh ? "从源码编译" : "From source"}
494 </div>
495 <InstallCodeBlock cmd={FROM_SOURCE} copyLabel={copyLabel} copiedLabel={copiedLabel} />
496 <p className="mt-3 text-sm text-ink-soft leading-relaxed max-w-2xl">
497 {isZh
498 ? "适合本地修改 workspace 或贡献补丁。"
499 : "Useful for working on the workspace itself or contributing patches."}
500 </p>
501 </div>
502 </div>
503 </div>
504 </section>
505
506 {/* ⑥ WHERE CONFIG LIVES */}
507 <section className="mx-auto max-w-[1100px] px-6 py-12">
508 <div className="flex items-baseline gap-4 mb-5">
509 <Seal char="件" />
510 <div className="eyebrow">{isZh ? "06 · 配置文件在哪" : "06 · Where config lives"}</div>
511 </div>
512 <InstallCodeBlock cmd={isZh ? CONFIG_TREE_ZH : CONFIG_TREE} copyLabel={copyLabel} copiedLabel={copiedLabel} />
513 <p className="mt-4 text-sm text-ink-soft leading-relaxed max-w-2xl">
514 {isZh ? (
515 <>
516 项目级 <code className="inline">./.codewhale/</code> 目录是可选的——每个仓库可有独立的 MCP 服务器、钩子、
517 技能和配置覆盖(例如提供商密钥)。
518 首次运行时,如果缺少配置文件,系统会询问是否交互式创建。旧版 <code className="inline">~/.deepseek</code> 和 <code className="inline">./.deepseek</code> 路径仍会作为兼容回退读取。
519 </>
520 ) : (
521 <>
522 The project-scoped <code className="inline">./.codewhale/</code> directory is optional —
523 each repo can carry its own MCP servers, hooks, skills, and config overrides (e.g.
524 provider keys). On first run the app asks whether to interactively create a config
525 file if one is missing. Legacy <code className="inline">~/.deepseek</code> and{" "}
526 <code className="inline">./.deepseek</code> paths are still read as compatibility fallbacks.
527 </>
528 )}
529 </p>
530 </section>
531
532 {/* ⑦ PROVENANCE */}
533 <section className="mx-auto max-w-[1100px] px-6 py-12 hairline-t">
534 <div className="flex items-baseline gap-4 mb-5">
535 <Seal char="源" />
536 <div className="eyebrow">{isZh ? "07 · 来源与镜像" : "07 · Provenance & mirrors"}</div>
537 </div>
538
539 <div className="space-y-4 text-sm text-ink-soft leading-relaxed max-w-2xl">
540 <p>
541 {isZh ? (
542 <>
543 <strong className="text-ink">codewhale.net</strong> 和{" "}
544 <strong className="text-ink">www.codewhale.net</strong> 是 Codewhale 的官方站点,
545 部署在 Cloudflare 上。网站源码位于{" "}
546 <code className="inline">Hmbown/CodeWhale</code> 仓库的{" "}
547 <code className="inline">web/</code> 目录下,任何人都可自行部署为镜像。
548 </>
549 ) : (
550 <>
551 <strong className="text-ink">codewhale.net</strong> and{" "}
552 <strong className="text-ink">www.codewhale.net</strong> are the official Codewhale
553 sites, deployed on Cloudflare. The website source lives under{" "}
554 <code className="inline">web/</code> in the{" "}
555 <code className="inline">Hmbown/CodeWhale</code> repository — anyone can
556 self-deploy it as a mirror.
557 </>
558 )}
559 </p>
560
561 <div className="grid sm:grid-cols-2 gap-4 mt-4">
562 <div>
563 <div className="eyebrow mb-1 text-indigo">{isZh ? "官方发布" : "Official releases"}</div>
564 <p>
565 {isZh
566 ? "所有正式发布和 SHA-256 校验文件仅通过 GitHub Releases 分发。npm 包从 GitHub Releases 下载经校验的二进制。"
567 : "All official releases and SHA-256 checksums are distributed exclusively through GitHub Releases. The npm package downloads verified binaries from GitHub Releases."}
568 </p>
569 </div>
570 <div>
571 <div className="eyebrow mb-1 text-indigo">{isZh ? "CNB 镜像" : "CNB mirror"}</div>
572 <p>
573 {isZh ? (
574 <>
575 面向无法稳定访问 GitHub 的用户,提供 CNB 镜像(
576 <a href="https://github.com/Hmbown/CodeWhale/blob/main/docs/CNB_MIRROR.md" className="body-link">docs/CNB_MIRROR.md</a>
577 )。镜像仓库由社区成员维护,发布延迟可能为几小时。
578 </>
579 ) : (
580 <>
581 A CNB mirror is available for users who cannot reliably reach GitHub (
582 <a href="https://github.com/Hmbown/CodeWhale/blob/main/docs/CNB_MIRROR.md" className="body-link">docs/CNB_MIRROR.md</a>
583 ). The mirror is maintained by community members; release latency may be a few hours.
584 </>
585 )}
586 </p>
587 </div>
588 <div>
589 <div className="eyebrow mb-1 text-indigo">{isZh ? "TUNA / 包镜像" : "TUNA / package mirrors"}</div>
590 <p>
591 {isZh
592 ? "Cargo 用户可通过 TUNA(清华大学开源镜像站)加速下载。这些镜像由第三方维护,Codewhale 项目不控制镜像内容。"
593 : "Cargo users can accelerate downloads via TUNA (Tsinghua University Open Source Mirror). These mirrors are maintained by third parties; the Codewhale project does not control mirror content."}
594 </p>
595 </div>
596 <div>
597 <div className="eyebrow mb-1 text-indigo">{isZh ? "自行部署" : "Self-deployed"}</div>
598 <p>
599 {isZh
600 ? "自行部署的网站副本、镜像站和第三方包不受 Codewhale 项目控制。请验证下载来源和校验和。"
601 : "Self-deployed website copies, mirror sites, and third-party packages are not controlled by the Codewhale project. Verify download sources and checksums."}
602 </p>
603 </div>
604 </div>
605 </div>
606 </section>
607
608 {/* ⑧ NEXT STEPS */}
609 <section className="bg-paper-deep hairline-t hairline-b">
610 <div className="mx-auto max-w-[1100px] px-6 py-12">
611 <div className="flex items-baseline gap-4 mb-5">
612 <Seal char="续" />
613 <div className="eyebrow">{isZh ? "08 · 下一步" : "08 · Next steps"}</div>
614 </div>
615 <div className="grid md:grid-cols-3 gap-0 col-rule hairline-t hairline-b">
616 <Link
617 href={isZh ? "/zh/docs" : "/en/docs"}
618 className="p-6 hover:bg-paper-deep transition-colors"
619 >
620 <div className="font-display text-xl mb-2">Docs</div>
621 <div className="text-sm text-ink-soft mb-3">
622 {isZh ? "模式、工具、配置、提供商、MCP" : "Modes, tools, config, providers, MCP"}
623 </div>
624 <span className="font-mono text-[0.7rem] uppercase tracking-widest text-indigo">
625 {isZh ? "阅读文档 →" : "Read docs →"}
626 </span>
627 </Link>
628 <Link
629 href={`/${locale}/faq`}
630 className="p-6 hover:bg-paper-deep transition-colors"
631 >
632 <div className="font-display text-xl mb-2">FAQ</div>
633 <div className="text-sm text-ink-soft mb-3">
634 {isZh ? "安装、配置、模型、提供商等常见问题" : "Common questions on install, config, models, providers"}
635 </div>
636 <span className="font-mono text-[0.7rem] uppercase tracking-widest text-indigo">
637 {isZh ? "查看 FAQ →" : "See FAQ →"}
638 </span>
639 </Link>
640 <Link
641 href={`/${locale}/roadmap`}
642 className="p-6 hover:bg-paper-deep transition-colors"
643 >
644 <div className="font-display text-xl mb-2">Roadmap</div>
645 <div className="text-sm text-ink-soft mb-3">
646 {isZh ? "已发布、进行中、考虑中、暂不考虑" : "Shipped, underway, considered, ruled out"}
647 </div>
648 <span className="font-mono text-[0.7rem] uppercase tracking-widest text-indigo">
649 {isZh ? "查看路线图 →" : "View roadmap →"}
650 </span>
651 </Link>
652 </div>
653 </div>
654 </section>
655 </>
656 );
657 }
658
658 lines Plain Text