Files
codewhale/web/app/[locale]/install/page.tsx
T
Hunter Bown 9e45780ba0 feat(web): community site for deepseek-tui.com (mobile + color refresh) (#1108)
First commit of the Next.js community site that powers
deepseek-tui.com, deployed via Cloudflare Workers / OpenNext.

This commit lands the scaffold and applies the visual + correctness
pass requested by community feedback:

- Palette: drop the cream/Anthropic-feel paper (#F4F1E8) for a
  DeepSeek-aligned cool white + soft gray (#FFFFFF / #F4F6FB), with
  indigo accents kept. Soften default hairlines so a pure-white
  background reads clean instead of harsh.
- Mobile: add a hamburger menu (mobile-menu.tsx) so phones can reach
  Install / Docs / Activity / Roadmap / Contribute — previously the
  link list was hidden on phones with no replacement. Tighter hero,
  flexible button row, viewport-safe code blocks, columnar grids
  collapse cleanly under 768px, and the printed-almanac center rule
  is desktop-only now (it sliced through narrow viewports).
- "How it works" diagram: replace the hand-rolled ASCII art (which
  misaligned under CJK monospace because Han characters take 2
  columns vs Latin's 1, per dhh's note in WeChat) with a real
  mermaid diagram rendered client-side via dynamic import. Uses the
  mermaid.live standard syntax 庄表伟 recommended.
- Issue #1104: the docs listed a `deepseek-cn` provider that the
  v0.8.16 binary doesn't accept (`ProviderArg` in crates/cli only
  has 9 variants; the 10th lives only in the legacy tui/config.rs).
  derive-facts.mjs now omits `deepseek-cn` until that variant is
  wired through the shared ProviderKind, and the install page's
  China-network recipe uses `base_url` / `DEEPSEEK_BASE_URL` (which
  actually works on v0.8.16) instead of the unsupported provider.

Auto-deploys via .github/workflows/deploy-web.yml on push to main.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 21:00:06 -05:00

296 lines
15 KiB
TypeScript
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.
import Link from "next/link";
import { GITEE_ENABLED } from "@/lib/i18n/config";
import { Seal } from "@/components/seal";
import { InstallTabs } from "@/components/install-tabs";
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
const { locale } = await params;
const isZh = locale === "zh";
return {
title: isZh ? "安装 · DeepSeek TUI" : "Install · DeepSeek TUI",
description: isZh
? "在 macOS、Linux 或 Windows 上通过 Cargo、npm、Homebrew tap 或预编译二进制安装 deepseek-tui。"
: "Install deepseek-tui on macOS, Linux, or Windows via Cargo, npm, the Homebrew tap, or pre-built binaries.",
};
}
export default async function InstallPage({ params }: { params: Promise<{ locale: string }> }) {
const { locale } = await params;
const isZh = locale === "zh";
return (
<>
{isZh ? (
<>
<section className="mx-auto max-w-[1400px] px-6 pt-12 pb-8">
<div className="flex items-baseline gap-4 mb-3">
<Seal char="装" />
<div className="eyebrow">Section 01 · </div>
</div>
<h1 className="font-display tracking-crisp">
<span className="font-cjk text-indigo text-5xl ml-2">Install</span>
</h1>
<p className="mt-5 max-w-3xl text-ink-soft text-lg leading-[1.9] tracking-wide">
<code className="inline">deepseek</code> 使 TUI
<code className="inline">doctor</code><code className="inline">mcp</code>
<code className="inline">serve</code><code className="inline">eval</code>
</p>
</section>
<InstallTabs />
{/* 国内镜像安装 */}
<section className="mx-auto max-w-[1400px] px-6 py-16">
<div className="flex items-baseline gap-4 mb-8 hairline-b pb-4">
<Seal char="镜" />
<h2 className="font-display">
<span className="font-cjk text-ink-mute text-xl ml-2"></span>
</h2>
</div>
<div className="grid md:grid-cols-2 gap-0 col-rule hairline-t hairline-b min-w-0">
{/* npmmirror */}
<div className="p-6 min-w-0">
<h3 className="font-display text-lg mb-2">npmmirror </h3>
<p className="text-sm text-ink-soft leading-[1.9] tracking-wide mb-3">
npm
</p>
<pre className="code-block text-[0.78rem]">
{`npm config set registry https://registry.npmmirror.com
npm install -g deepseek-tui`}
</pre>
</div>
{/* Tuna Cargo */}
<div className="p-6 min-w-0">
<h3 className="font-display text-lg mb-2">Tuna Cargo </h3>
<p className="text-sm text-ink-soft leading-[1.9] tracking-wide mb-3">
<code className="inline">~/.cargo/config.toml</code> 使 Tuna
</p>
<pre className="code-block text-[0.78rem]">
{`[source.crates-io]
replace-with = "tuna"
[source.tuna]
registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"`}
</pre>
<p className="text-sm text-ink-soft leading-[1.9] tracking-wide mt-3">
<code className="inline">cargo install deepseek-tui-cli --locked</code> <code className="inline">deepseek</code>
</p>
</div>
{/* Gitee 二进制 */}
{GITEE_ENABLED && <div className="p-6 min-w-0">
<h3 className="font-display text-lg mb-2">Gitee </h3>
<p className="text-sm text-ink-soft leading-[1.9] tracking-wide mb-3">
Gitee 使
</p>
<Link href="https://gitee.com/Hmbown/deepseek-tui/releases" className="font-mono text-[0.78rem] text-indigo hover:underline">
gitee.com/Hmbown/deepseek-tui/releases
</Link>
</div>}
{/* API 端点 */}
<div className="p-6 min-w-0">
<h3 className="font-display text-lg mb-2"> API 访</h3>
<p className="text-sm text-ink-soft leading-[1.9] tracking-wide mb-3">
<code className="inline">https://api.deepseek.com</code> 在国内通常可直连。
<code className="inline">base_url</code>
<code className="inline">DEEPSEEK_BASE_URL</code>
</p>
<pre className="code-block text-[0.78rem]">
{`# ~/.deepseek/config.toml
[api]
base_url = "https://<你的节点>"
# 或环境变量(推荐,便于临时切换):
# export DEEPSEEK_BASE_URL=https://<你的节点>`}
</pre>
<p className="text-sm text-ink-soft leading-[1.9] tracking-wide mt-3">
API key <code className="inline">deepseek auth set --provider deepseek</code>{" "}
<code className="inline">DEEPSEEK_API_KEY</code>
</p>
</div>
</div>
{GITEE_ENABLED && <div className="mt-6">
<Link href="https://gitee.com/Hmbown/deepseek-tui" className="body-link">
Gitee
</Link>
</div>}
</section>
{/* 安装后 */}
<section className="mx-auto max-w-[1400px] px-6 py-16">
<div className="flex items-baseline gap-4 mb-8 hairline-b pb-4">
<Seal char="后" />
<h2 className="font-display">
<span className="font-cjk text-ink-mute text-xl ml-2"></span>
</h2>
</div>
<ol className="grid md:grid-cols-3 gap-0 col-rule hairline-t hairline-b">
<li className="p-6">
<div className="font-display text-3xl text-indigo mb-2"></div>
<div className="eyebrow mb-2"></div>
<h3 className="font-display text-lg mb-2"> platform.deepseek.com </h3>
<p className="text-sm text-ink-soft leading-[1.9] tracking-wide">
<code className="inline">sk-...</code> API
<code className="inline"> deepseek auth</code>
<code className="inline"> ~/.deepseek/config.toml</code>
</p>
</li>
<li className="p-6">
<div className="font-display text-3xl text-indigo mb-2"></div>
<div className="eyebrow mb-2"></div>
<h3 className="font-display text-lg mb-2"></h3>
<p className="text-sm text-ink-soft leading-[1.9] tracking-wide">
<code className="inline">deepseek doctor</code>
MCP <code className="inline">~/.deepseek/doctor.log</code>
</p>
</li>
<li className="p-6">
<div className="font-display text-3xl text-indigo mb-2"></div>
<div className="eyebrow mb-2"></div>
<h3 className="font-display text-lg mb-2"></h3>
<p className="text-sm text-ink-soft leading-[1.9] tracking-wide">
<code className="inline">cd</code> <code className="inline">deepseek</code>
<em>"这个代码库是做什么的?"</em> Plan
<kbd className="font-mono text-xs px-1 hairline-t hairline-b hairline-l hairline-r">Tab</kbd> Agent
</p>
</li>
</ol>
</section>
{/* 配置 */}
<section className="bg-paper-deep hairline-t hairline-b">
<div className="mx-auto max-w-[1400px] px-6 py-16 grid lg:grid-cols-12 gap-10 min-w-0">
<div className="lg:col-span-5 min-w-0">
<div className="eyebrow mb-3"> · Config</div>
<h2 className="font-display text-3xl"></h2>
<p className="mt-4 text-ink-soft leading-[1.9] tracking-wide">
<code className="inline">~/.deepseek/</code>
<code className="inline">.deepseek/</code>
</p>
<div className="mt-6 space-y-3">
<Link href="/zh/docs" className="body-link inline-block"> </Link>
</div>
</div>
<div className="lg:col-span-7 min-w-0">
<pre className="code-block text-[0.78rem]">
{`~/.deepseek/
├── config.toml # API 密钥、模型、钩子、配置集
├── mcp.json # MCP 服务器定义
├── skills/ # 用户技能(每个含 SKILL.md
├── sessions/ # 检查点 + 离线队列
├── tasks/ # 后台任务存储
└── audit.log # 凭证 / 审批 / 提权审计日志
# 项目级别
./.deepseek/ # 项目级配置(可选)`}
</pre>
</div>
</div>
</section>
</>
) : (
<>
<section className="mx-auto max-w-[1400px] px-6 pt-12 pb-8">
<div className="flex items-baseline gap-4 mb-3">
<Seal char="装" />
<div className="eyebrow">Section 01 · </div>
</div>
<h1 className="font-display tracking-crisp">
Install <span className="font-cjk text-indigo text-5xl ml-2"></span>
</h1>
<p className="mt-5 max-w-3xl text-ink-soft text-lg leading-relaxed">
Pick your platform below we auto-detect on first load. Every method gives you the same
binary: a single static <code className="inline">deepseek</code> executable that
dispatches to the TUI for interactive use and exposes subcommands like
<code className="inline">doctor</code>, <code className="inline">mcp</code>,
<code className="inline">serve</code>, <code className="inline">eval</code>.
</p>
</section>
<InstallTabs />
{/* AFTER INSTALL */}
<section className="mx-auto max-w-[1400px] px-6 py-16">
<div className="flex items-baseline gap-4 mb-8 hairline-b pb-4">
<Seal char="后" />
<h2 className="font-display">
After install <span className="font-cjk text-ink-mute text-xl ml-2"></span>
</h2>
</div>
<ol className="grid md:grid-cols-3 gap-0 col-rule hairline-t hairline-b">
<li className="p-6">
<div className="font-display text-3xl text-indigo mb-2"></div>
<div className="eyebrow mb-2">Get a key</div>
<h3 className="font-display text-lg mb-2">Sign up at platform.deepseek.com</h3>
<p className="text-sm text-ink-soft leading-relaxed">
You'll get an <code className="inline">sk-...</code> API key. Paste it once and
<code className="inline"> deepseek auth</code> will store it in
<code className="inline"> ~/.deepseek/config.toml</code>.
</p>
</li>
<li className="p-6">
<div className="font-display text-3xl text-indigo mb-2"></div>
<div className="eyebrow mb-2">Run doctor</div>
<h3 className="font-display text-lg mb-2">Verify your setup</h3>
<p className="text-sm text-ink-soft leading-relaxed">
<code className="inline">deepseek doctor</code> checks your key, network,
sandbox availability, MCP servers, and writes a report to{" "}
<code className="inline">~/.deepseek/doctor.log</code>.
</p>
</li>
<li className="p-6">
<div className="font-display text-3xl text-indigo mb-2"></div>
<div className="eyebrow mb-2">Try it out</div>
<h3 className="font-display text-lg mb-2">First prompt</h3>
<p className="text-sm text-ink-soft leading-relaxed">
<code className="inline">cd</code> into a project, run <code className="inline">deepseek</code>,
and ask: <em>"What does this codebase do?"</em> Plan mode is read-only by default
press <kbd className="font-mono text-xs px-1 hairline-t hairline-b hairline-l hairline-r">Tab</kbd> to switch to Agent mode.
</p>
</li>
</ol>
</section>
{/* CONFIG */}
<section className="bg-paper-deep hairline-t hairline-b">
<div className="mx-auto max-w-[1400px] px-6 py-16 grid lg:grid-cols-12 gap-10 min-w-0">
<div className="lg:col-span-5 min-w-0">
<div className="eyebrow mb-3">Config files · </div>
<h2 className="font-display text-3xl">Where things live</h2>
<p className="mt-4 text-ink-soft leading-relaxed">
All configuration goes under <code className="inline">~/.deepseek/</code>. Per-project
overrides via project-scoped <code className="inline">.deepseek/</code> config at the repo root.
</p>
<div className="mt-6 space-y-3">
<Link href="/docs" className="body-link inline-block">Full configuration reference </Link>
</div>
</div>
<div className="lg:col-span-7 min-w-0">
<pre className="code-block text-[0.78rem]">
{`~/.deepseek/
├── config.toml # api keys, model, hooks, profiles
├── mcp.json # MCP server definitions
├── skills/ # user skills (each with SKILL.md)
├── sessions/ # checkpoints + offline queue
├── tasks/ # background task store
└── audit.log # credential / approval / elevation audit trail
# project-local
./.deepseek/ # project-scoped config (optional)`}
</pre>
</div>
</div>
</section>
</>
)}
</>
);
}