| 1 | import Link from "next/link"; |
| 2 | import { GETTING_STARTED_STEPS } from "@/lib/content/getting-started"; |
| 3 | import { PageHeader } from "@/components/page-header"; |
| 4 | import { FaqSearch } from "@/components/faq-search"; |
| 5 | import { buildFaqPageJsonLd } from "@/lib/faq-schema"; |
| 6 | import { FACTS } from "@/lib/facts.generated"; |
| 7 | import { canonicalLocaleForPath } from "@/lib/i18n/content-locales"; |
| 8 | import { getFaq, pickTextLocale } from "@/lib/i18n/dictionaries"; |
| 9 | import { serializeJsonLd } from "@/lib/json-ld"; |
| 10 | import { buildPageMetadata } from "@/lib/page-meta"; |
| 11 | import { SITE_URL } from "@/lib/page-meta"; |
| 12 | |
| 13 | export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) { |
| 14 | const { locale } = await params; |
| 15 | const t = getFaq(locale); |
| 16 | return buildPageMetadata({ |
| 17 | path: "/faq", |
| 18 | locale, |
| 19 | title: t.metaTitle, |
| 20 | description: t.metaDescription, |
| 21 | }); |
| 22 | } |
| 23 | |
| 24 | interface FaqItem { |
| 25 | q: string; |
| 26 | a: React.ReactNode; |
| 27 | sources?: string[]; |
| 28 | } |
| 29 | |
| 30 | /** `p` prefixes a site path with the reader's locale. */ |
| 31 | type SitePath = (path: string) => string; |
| 32 | |
| 33 | const faqEn = (p: SitePath): FaqItem[] => [ |
| 34 | { |
| 35 | q: "What is Codewhale?", |
| 36 | a: ( |
| 37 | <> |
| 38 | Codewhale is a terminal-native coding agent that works across hosted and local models. It runs from the <code className="inline">codewhale</code> command, streams reasoning blocks, edits local workspaces with approval gates, and can route each turn to a configured model and thinking level. DeepSeek is the bundled default route, while OpenRouter, Anthropic, OpenAI-compatible services, and self-hosted runtimes use the same runtime and tools. |
| 39 | </> |
| 40 | ), |
| 41 | sources: ["README.md", "docs/ARCHITECTURE.md"], |
| 42 | }, |
| 43 | { |
| 44 | q: "How do I install Codewhale?", |
| 45 | a: ( |
| 46 | <> |
| 47 | <p className="mb-2">Published channels differ in timing and platform support:</p> |
| 48 | <pre tabIndex={0} className="code-block mb-2"> |
| 49 | {`# GitHub release binaries (recommended on macOS / Linux) |
| 50 | ${GETTING_STARTED_STEPS[0].commands[0]} |
| 51 | |
| 52 | # npm alternative — no Rust toolchain needed |
| 53 | npm install -g codewhale |
| 54 | |
| 55 | # Cargo (needs Rust 1.88+; installs the codewhale command) |
| 56 | cargo install codewhale-cli --locked |
| 57 | |
| 58 | # Homebrew on Linux (tap; tested on Ubuntu) |
| 59 | brew install Hmbown/deepseek-tui/codewhale |
| 60 | |
| 61 | # Direct download |
| 62 | # https://github.com/codewhale-hq/CodeWhale/releases`} |
| 63 | </pre> |
| 64 | <p> |
| 65 | Run <code className="inline">codewhale</code> to start. First run creates <code className="inline">~/.codewhale/</code> automatically. Legacy <code className="inline">~/.deepseek/</code> is still read as a compatibility fallback. |
| 66 | Android arm64 / Termux is preview support: npm works only when the |
| 67 | selected package version has matching Android assets in its GitHub Release. |
| 68 | See the <Link href={p("/install")} className="body-link">full install guide</Link> for China mirrors, Docker, and troubleshooting. |
| 69 | </p> |
| 70 | </> |
| 71 | ), |
| 72 | sources: ["README.md", "docs/INSTALL.md", "#1860", "#1914"], |
| 73 | }, |
| 74 | { |
| 75 | q: "Can I use Codewhale from VS Code?", |
| 76 | a: ( |
| 77 | <> |
| 78 | Yes. CodeWhale GUI (VS Code) is the community-maintained graphical frontend for the same engine: agent chat, threads, and file changes in a VS Code sidebar, over the local Runtime you already run. Install it from the <a href="https://marketplace.visualstudio.com/items?itemName=HengQuWorld.brotherwhale-vscode" className="body-link">VS Code Marketplace</a>; the source is on <a href="https://github.com/HengQuWorld/CodeWhale-VSCode" className="body-link">GitHub</a>. |
| 79 | </> |
| 80 | ), |
| 81 | sources: ["README.md"], |
| 82 | }, |
| 83 | { |
| 84 | q: "What's the difference between codewhale and codewhale-tui?", |
| 85 | a: ( |
| 86 | <> |
| 87 | Since v0.9.5 there is one compiled runtime: the <code className="inline">codewhale</code> command contains the terminal UI directly — there is no separate TUI executable to install. |
| 88 | Release installers also expose <code className="inline">codew</code> as a byte-identical short name, and <code className="inline">codewhale update</code> refreshes any legacy <code className="inline">codewhale-tui</code> command path from the same verified bytes. |
| 89 | <code className="inline">codewhale-tui</code> survives as the internal TUI crate compiled into the <code className="inline">codewhale-cli</code> Cargo package, so Cargo users install just <code className="inline">codewhale-cli</code>. |
| 90 | </> |
| 91 | ), |
| 92 | sources: ["README.md", "CHANGELOG.md"], |
| 93 | }, |
| 94 | { |
| 95 | q: "Is Codewhale the same as DeepSeek TUI? What about the rename?", |
| 96 | a: ( |
| 97 | <> |
| 98 | Yes. Codewhale is the new name for what was previously called DeepSeek TUI. |
| 99 | The canonical command is now <code className="inline">codewhale</code>. Legacy <code className="inline">deepseek</code> and <code className="inline">deepseek-tui</code> commands remain as compatibility shims — they still work. |
| 100 | Config lives at <code className="inline">~/.codewhale/</code>. Legacy <code className="inline">~/.deepseek/</code> config is still read as a compatibility fallback, and <code className="inline">DEEPSEEK_*</code> env vars continue to work. |
| 101 | DeepSeek is not deprecated. The rename reflects a mission idea put in this version: Codewhale as an agentic terminal for open models across providers, not a narrowing away from DeepSeek. |
| 102 | </> |
| 103 | ), |
| 104 | sources: ["docs/REBRAND.md", "README.md"], |
| 105 | }, |
| 106 | { |
| 107 | q: "How do I set my API key?", |
| 108 | a: ( |
| 109 | <> |
| 110 | <pre tabIndex={0} className="code-block mb-2"> |
| 111 | {`# Method 1: Environment variable |
| 112 | export DEEPSEEK_API_KEY=sk-... |
| 113 | |
| 114 | # Method 2: Saved key (recommended — survives shell restarts) |
| 115 | codewhale auth set --provider deepseek # prompts for the key |
| 116 | # scripted: pipe it in with --api-key-stdin |
| 117 | |
| 118 | # Check what's active: |
| 119 | codewhale auth status # shows config, keyring, and env-var state |
| 120 | codewhale doctor # full connectivity check`} |
| 121 | </pre> |
| 122 | <p> |
| 123 | Saved keys take precedence over environment variables. Avoid putting a key directly on the command line, where it lands in shell history. |
| 124 | Use <code className="inline">codewhale auth clear --provider deepseek</code> to remove a saved key. |
| 125 | </p> |
| 126 | </> |
| 127 | ), |
| 128 | sources: ["#907", "#1545", "docs/CONFIGURATION.md"], |
| 129 | }, |
| 130 | { |
| 131 | q: "Which providers does Codewhale support?", |
| 132 | a: ( |
| 133 | <> |
| 134 | <p className="mb-2">Codewhale ships with {FACTS.providers.length} built-in provider routes:</p> |
| 135 | <ul className="list-disc pl-5 space-y-1 text-sm text-ink-soft mb-3"> |
| 136 | <li><strong>DeepSeek</strong> — bundled default with a native API route, reasoning streaming, cache metrics, and thinking effort control.</li> |
| 137 | <li><strong>OpenRouter</strong> — unified API for DeepSeek models and other open-model routes.</li> |
| 138 | <li><strong>{FACTS.providers.length - 2} more routes</strong> — including OpenAI-compatible, Anthropic, Mistral AI, OpenAI Codex, xAI, Moonshot/Kimi, Z.ai, MiniMax, StepFun, Volcengine Ark, Baidu Qianfan, Model Studio, NVIDIA NIM, Fireworks AI, Together AI, DeepInfra, SiliconFlow, Novita AI, Hugging Face, Arcee AI, AtlasCloud, and the keyless local endpoints SGLang, vLLM, and Ollama. <Link href={p("/models")} className="body-link">The full list is generated from the provider registry</Link>.</li> |
| 139 | </ul> |
| 140 | <p> |
| 141 | Set the corresponding env var (e.g. <code className="inline">OPENROUTER_API_KEY</code>) and your provider in <code className="inline">~/.codewhale/config.toml</code>. |
| 142 | Self-hosted OpenAI-compatible endpoints are supported through the provider config. |
| 143 | </p> |
| 144 | </> |
| 145 | ), |
| 146 | sources: ["docs/CONFIGURATION.md", "#1978", "#1710"], |
| 147 | }, |
| 148 | { |
| 149 | q: "How do I use OpenRouter with Codewhale?", |
| 150 | a: ( |
| 151 | <> |
| 152 | <pre tabIndex={0} className="code-block mb-2"> |
| 153 | {`# 1. Set your OpenRouter key |
| 154 | export OPENROUTER_API_KEY=sk-or-v1-... |
| 155 | |
| 156 | # 2. In ~/.codewhale/config.toml: |
| 157 | [providers.openrouter] |
| 158 | api_key = "sk-or-v1-..." |
| 159 | |
| 160 | # 3. Run with the OpenRouter route: |
| 161 | codewhale --provider openrouter --model deepseek/deepseek-v4-pro |
| 162 | |
| 163 | # Or make it the default route in config.toml: |
| 164 | # provider = "openrouter" |
| 165 | # default_text_model = "deepseek/deepseek-v4-pro"`} |
| 166 | </pre> |
| 167 | <p> |
| 168 | OpenRouter uses the same reasoning/cache parser as the native DeepSeek provider. |
| 169 | Model IDs are OpenRouter's own slugs (e.g. <code className="inline">deepseek/deepseek-v4-flash</code>); pick the route with <code className="inline">--provider openrouter</code> or top-level <code className="inline">provider = "openrouter"</code>. |
| 170 | </p> |
| 171 | </> |
| 172 | ), |
| 173 | sources: ["docs/CONFIGURATION.md", "#1978"], |
| 174 | }, |
| 175 | { |
| 176 | q: "Can I use self-hosted or local models (vLLM, Ollama, llama.cpp)?", |
| 177 | a: ( |
| 178 | <> |
| 179 | Yes. Use the <code className="inline">vllm</code>, <code className="inline">sglang</code>, or <code className="inline">ollama</code> providers with your local endpoint. |
| 180 | For OpenAI-compatible endpoints (llama.cpp server, text-generation-webui, Aphrodite, etc.), you can use the <code className="inline">openai</code> provider with a custom <code className="inline">base_url</code>. |
| 181 | Codewhale also respects <code className="inline">DEEPSEEK_ALLOW_INSECURE_HTTP=true</code> for local HTTP endpoints. |
| 182 | Hugging Face Inference Providers are also available through the <code className="inline">huggingface</code> provider. Broader Hub discovery, model cards, datasets, and Jobs belong to Model Lab. |
| 183 | </> |
| 184 | ), |
| 185 | sources: ["#574", "#1303", "docs/CONFIGURATION.md"], |
| 186 | }, |
| 187 | { |
| 188 | q: "What are Plan, Work, and Operate modes?", |
| 189 | a: ( |
| 190 | <> |
| 191 | <ul className="list-disc pl-5 space-y-2 text-sm text-ink-soft"> |
| 192 | <li><strong>Plan</strong> — Read-only investigation. Can grep, read files, list directories, fetch URLs. Cannot write or execute shell.</li> |
| 193 | <li><strong>Work</strong> — Normal interactive coding. Tool availability and approval prompts follow the active configuration and permission posture.</li> |
| 194 | <li><strong>Operate</strong> — Direct tools follow the same permission, sandbox, shell, and safety rules as Work. Fleet workers are preferred for independent, parallel, background, or long-running work, but delegation is not mandatory. Workflow is optional for ordered phases and gates.</li> |
| 195 | </ul> |
| 196 | <p className="mt-2"> |
| 197 | When the composer is idle, press <kbd className="font-mono text-xs px-1.5 py-0.5 hairline-t hairline-b hairline-l hairline-r">Tab</kbd> to cycle modes. |
| 198 | Press <kbd className="font-mono text-xs px-1.5 py-0.5 hairline-t hairline-b hairline-l hairline-r">Shift+Tab</kbd> to cycle the independent Ask / Auto-Review / Full Access permission posture; Plan remains read-only. |
| 199 | </p> |
| 200 | </> |
| 201 | ), |
| 202 | sources: ["docs/MODES.md"], |
| 203 | }, |
| 204 | { |
| 205 | q: "What is model auto-routing? What is Fin?", |
| 206 | a: ( |
| 207 | <> |
| 208 | <p className="mb-2"> |
| 209 | Use <code className="inline">codewhale --model auto</code> or <code className="inline">/model auto</code> to let Codewhale decide how much model power each turn needs. |
| 210 | </p> |
| 211 | <p className="mb-2"> |
| 212 | <strong>Fin</strong> is the fast non-thinking path (<code className="inline">deepseek-v4-flash</code> with thinking off) used for routing decisions, summaries, RLM children, context maintenance, and other coordination work. Before the real turn is sent, Fin makes a small routing call to pick the concrete model and thinking level. |
| 213 | </p> |
| 214 | <p> |
| 215 | Short/simple turns can stay on Flash with thinking off. Coding, debugging, release work, architecture, or security review can move up to Pro and/or higher thinking. Fin is local to Codewhale — the upstream API never receives <code className="inline">model: "auto"</code>. |
| 216 | </p> |
| 217 | </> |
| 218 | ), |
| 219 | sources: ["README.md", "#1207"], |
| 220 | }, |
| 221 | { |
| 222 | q: "What does /goal do?", |
| 223 | a: ( |
| 224 | <> |
| 225 | <code className="inline">/goal</code> sets a goal for the current TUI session. |
| 226 | App-server clients can also persist a thread-scoped goal through the |
| 227 | <code className="inline">thread/goal/*</code> methods. It does not add another |
| 228 | app mode; the mode switcher remains Plan, Work, and Operate, while permission posture is selected independently. |
| 229 | Track progress in <a href="https://github.com/codewhale-hq/CodeWhale/issues/891" className="body-link">#891</a>. |
| 230 | </> |
| 231 | ), |
| 232 | sources: ["#891"], |
| 233 | }, |
| 234 | { |
| 235 | q: "Is my code safe? What sandboxing does Codewhale use?", |
| 236 | a: ( |
| 237 | <> |
| 238 | The Codewhale runtime, workspace state, and audit log stay on your machine. |
| 239 | Codewhale counts anonymous usage by default and says so at first launch. |
| 240 | Turning it off is a saved choice that later versions keep; showing the notice |
| 241 | never records any acceptance on your behalf. While on, a |
| 242 | session posts aggregate session, feature, and error counts |
| 243 | and closed enums to a first-party endpoint at telemetry.codewhale.net, |
| 244 | a Cloudflare Worker whose full source is in the repository. Its storage has no IP, |
| 245 | country, or geo column, records no request logs, |
| 246 | and retains records for three months. Optional PostHog forwarding requires |
| 247 | separate operator configuration and verified IP-safe egress; its retention |
| 248 | is a separate project setting. Source support does not establish activation. Set{" "} |
| 249 | <code className="inline">telemetry_endpoint = ""</code> to stay |
| 250 | enabled and contact nobody. It never carries conversations, code, prompts, |
| 251 | files, file/repo/branch names, model content, credentials, or a per-turn or |
| 252 | per-tool timeline (see the{" "} |
| 253 | <a href="https://github.com/codewhale-hq/CodeWhale/blob/main/docs/TELEMETRY.md" className="body-link">telemetry schema</a>; |
| 254 | off with <code className="inline">codewhale config set telemetry false</code> |
| 255 | or <code className="inline">CODEWHALE_TELEMETRY=0</code>). There is no |
| 256 | mandatory hosted relay. The hosted |
| 257 | provider you select receives the prompt, project context, tool definitions, |
| 258 | and tool results required for that turn. Use a loopback local-model route to |
| 259 | keep model inference local. |
| 260 | OS command sandboxing is platform-specific: Codewhale uses <strong>Seatbelt</strong> on macOS when available. On Linux it uses <strong>bubblewrap</strong> only when <code className="inline">prefer_bwrap = true</code> and <code className="inline">/usr/bin/bwrap</code> is executable; otherwise commands have no Codewhale OS wrapper. Windows currently reports no OS sandbox. |
| 261 | Workspace boundaries default to <code className="inline">--workspace</code>. <code className="inline">/trust</code> lifts them. |
| 262 | Permission posture is configurable per session. |
| 263 | </> |
| 264 | ), |
| 265 | sources: [".github/SECURITY.md", "docs/PROVIDERS.md", "docs/RUNTIME_API.md"], |
| 266 | }, |
| 267 | { |
| 268 | q: "How do MCP servers work?", |
| 269 | a: ( |
| 270 | <> |
| 271 | Codewhale is a bidirectional MCP client and server. Define servers in <code className="inline">~/.codewhale/mcp.json</code>. |
| 272 | Tools appear as <code className="inline">mcp_<server>_<tool></code>. You can also expose Codewhale as an MCP server with <code className="inline">codewhale mcp</code>. |
| 273 | See the <Link href={p("/docs/mcp")} className="body-link">docs page</Link> for configuration examples. |
| 274 | </> |
| 275 | ), |
| 276 | sources: ["docs/MCP.md"], |
| 277 | }, |
| 278 | { |
| 279 | q: "How do I contribute?", |
| 280 | a: ( |
| 281 | <> |
| 282 | No CLA required. Fork, branch with conventional commits (<code className="inline">feat:</code>, <code className="inline">fix:</code>, etc.), run the local checks, open a PR. |
| 283 | The maintainer reads everything personally. Start with issues labeled <code className="inline">good first issue</code>. |
| 284 | See the <Link href={p("/contribute")} className="body-link">contribute page</Link> and <a href="https://github.com/codewhale-hq/CodeWhale/blob/main/CONTRIBUTING.md" className="body-link">CONTRIBUTING.md</a>. |
| 285 | </> |
| 286 | ), |
| 287 | sources: ["CONTRIBUTING.md"], |
| 288 | }, |
| 289 | { |
| 290 | q: "I'm in China — how do I install? Downloads are slow.", |
| 291 | a: ( |
| 292 | <> |
| 293 | Use mirror registries: |
| 294 | <pre tabIndex={0} className="code-block my-2"> |
| 295 | {`# npm mirror |
| 296 | npm config set registry https://registry.npmmirror.com |
| 297 | npm install -g codewhale |
| 298 | |
| 299 | # Cargo mirror (Tsinghua TUNA) |
| 300 | # Add to ~/.cargo/config.toml: |
| 301 | [source.crates-io] |
| 302 | replace-with = "tuna" |
| 303 | [source.tuna] |
| 304 | registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"`} |
| 305 | </pre> |
| 306 | <p> |
| 307 | Prebuilt binaries are also available from <a href="https://github.com/codewhale-hq/CodeWhale/releases" className="body-link">GitHub Releases</a>. |
| 308 | A maintained CNB mirror covers its documented targets; no Gitee mirror is advertised until one exists. |
| 309 | </p> |
| 310 | </> |
| 311 | ), |
| 312 | sources: ["README.md", "#1914", "docs/CNB_MIRROR.md"], |
| 313 | }, |
| 314 | { |
| 315 | q: "Is codewhale.net the official site? What about mirrors?", |
| 316 | a: ( |
| 317 | <> |
| 318 | <p className="mb-2"> |
| 319 | <strong>codewhale.net</strong> and <strong>www.codewhale.net</strong> are the |
| 320 | official Codewhale sites, deployed on Cloudflare. The website source is open |
| 321 | and lives under <code className="inline">web/</code> in the{" "} |
| 322 | <code className="inline">codewhale-hq/CodeWhale</code> repository — anyone can |
| 323 | self-deploy it as a mirror. |
| 324 | </p> |
| 325 | <p className="mb-2"> |
| 326 | All official releases and SHA-256 checksums are distributed exclusively through{" "} |
| 327 | <a href="https://github.com/codewhale-hq/CodeWhale/releases" className="body-link">GitHub Releases</a>. |
| 328 | The npm package downloads verified binaries from GitHub Releases. |
| 329 | </p> |
| 330 | <p className="mb-2"> |
| 331 | A CNB mirror is maintained for users who cannot reliably reach GitHub |
| 332 | (<Link href={p("/install")} className="body-link">docs/CNB_MIRROR.md</Link>). |
| 333 | Cargo users can use the TUNA mirror for faster downloads in China. |
| 334 | </p> |
| 335 | <p> |
| 336 | Self-deployed website copies, mirror sites, and third-party packages are not |
| 337 | controlled by the Codewhale project. Verify download sources and checksums. |
| 338 | </p> |
| 339 | </> |
| 340 | ), |
| 341 | sources: ["#2624", "#3421", "docs/CNB_MIRROR.md"], |
| 342 | }, |
| 343 | { |
| 344 | q: "My API key was rejected or I get auth errors on first run.", |
| 345 | a: ( |
| 346 | <> |
| 347 | <p className="mb-2">Run <code className="inline">codewhale doctor</code> — it prints a diagnostic report to stdout: config paths, credential-store state (values are never read or printed), provider/local/MCP probes, and release checks.</p> |
| 348 | <p className="mb-2">Common causes:</p> |
| 349 | <ul className="list-disc pl-5 space-y-1 text-sm text-ink-soft"> |
| 350 | <li>Stale <code className="inline">DEEPSEEK_API_KEY</code> in shell startup file — open a fresh shell or use <code className="inline">codewhale auth set</code></li> |
| 351 | <li>Key from wrong provider — make sure the key matches the provider you're using</li> |
| 352 | <li>Network connectivity — check <code className="inline">curl https://api.deepseek.com/v1/models</code></li> |
| 353 | </ul> |
| 354 | </> |
| 355 | ), |
| 356 | sources: ["#907", "#1545"], |
| 357 | }, |
| 358 | { |
| 359 | q: "What is Model Lab? What Hugging Face pieces are available?", |
| 360 | a: ( |
| 361 | <> |
| 362 | The <code className="inline">huggingface</code> provider is the shipped OpenAI-compatible route for Hugging Face Inference Providers. |
| 363 | Model Lab is the planned open-model infrastructure layer for Hub discovery, model cards, datasets, safetensors adapters, and Jobs. |
| 364 | Track broader progress in <a href="https://github.com/codewhale-hq/CodeWhale/issues/1977" className="body-link">#1977</a>. |
| 365 | </> |
| 366 | ), |
| 367 | sources: ["#1977", "docs/MODEL_LAB.md"], |
| 368 | }, |
| 369 | { |
| 370 | q: "Why is token consumption so high? / Why is cache hit rate low?", |
| 371 | a: ( |
| 372 | <> |
| 373 | Codewhale sends substantial context (system prompt, project instructions, tool definitions) with each turn. |
| 374 | DeepSeek's prefix cache is used aggressively — the system prompt is layered to maximize cache hits. |
| 375 | If you see high token usage, check: are you using <code className="inline">deepseek-v4-pro</code> for simple queries better suited to Flash? |
| 376 | Model auto-routing (Fin) can help pick the right model per turn. |
| 377 | Cache hit rate depends on prompt stability — modifying the system prompt or switching models resets the cache. |
| 378 | </> |
| 379 | ), |
| 380 | sources: ["#1177", "#1818", "#743"], |
| 381 | }, |
| 382 | { |
| 383 | q: "How do I update Codewhale?", |
| 384 | a: ( |
| 385 | <> |
| 386 | <pre tabIndex={0} className="code-block mb-2"> |
| 387 | {`# Installer or release-binary installs |
| 388 | codewhale update |
| 389 | |
| 390 | # npm (codewhale update refuses npm installs) |
| 391 | npm install -g codewhale@latest |
| 392 | |
| 393 | # Cargo |
| 394 | cargo install codewhale-cli --locked --force |
| 395 | |
| 396 | # Homebrew tap |
| 397 | brew update && brew upgrade codewhale`} |
| 398 | </pre> |
| 399 | <p> |
| 400 | If you installed with npm or Homebrew, update through that package manager; <code className="inline">codewhale update</code> leaves package-managed installs unchanged. |
| 401 | If a mirror is lagging, download directly from <a href="https://github.com/codewhale-hq/CodeWhale/releases" className="body-link">GitHub Releases</a>. |
| 402 | </p> |
| 403 | </> |
| 404 | ), |
| 405 | sources: ["README.md", "#1869", "#1914"], |
| 406 | }, |
| 407 | ]; |
| 408 | |
| 409 | const faqZh = (p: SitePath): FaqItem[] => [ |
| 410 | { |
| 411 | q: "Codewhale 是什么?", |
| 412 | a: ( |
| 413 | <> |
| 414 | Codewhale 是一个可使用托管与本地模型的终端原生编程智能体。通过 <code className="inline">codewhale</code> 命令启动,流式输出推理块,在有审批门槛的情况下编辑本地工作区,并可为每个回合选择已配置的模型和推理深度。DeepSeek 是内置默认路由;OpenRouter、Anthropic、OpenAI 兼容服务与自托管运行时使用同一套运行时和工具。 |
| 415 | </> |
| 416 | ), |
| 417 | sources: ["README.md", "docs/ARCHITECTURE.md"], |
| 418 | }, |
| 419 | { |
| 420 | q: "如何安装 Codewhale?", |
| 421 | a: ( |
| 422 | <> |
| 423 | <p className="mb-2">已发布渠道的更新时间与平台覆盖各不相同:</p> |
| 424 | <pre tabIndex={0} className="code-block mb-2"> |
| 425 | {`# GitHub Releases 二进制(macOS / Linux 推荐方式) |
| 426 | ${GETTING_STARTED_STEPS[0].commands[0]} |
| 427 | |
| 428 | # npm 其他方式 — 无需 Rust 工具链 |
| 429 | npm install -g codewhale |
| 430 | |
| 431 | # Cargo(需要 Rust 1.88+;安装 codewhale 命令) |
| 432 | cargo install codewhale-cli --locked |
| 433 | |
| 434 | # Linux 上的 Homebrew(tap;已在 Ubuntu 上测试) |
| 435 | brew install Hmbown/deepseek-tui/codewhale |
| 436 | |
| 437 | # 直接下载 |
| 438 | # https://github.com/codewhale-hq/CodeWhale/releases`} |
| 439 | </pre> |
| 440 | <p> |
| 441 | 输入 <code className="inline">codewhale</code> 即可启动。首次运行会自动创建 <code className="inline">~/.codewhale/</code>。旧版 <code className="inline">~/.deepseek/</code> 仍会作为兼容回退读取。 |
| 442 | Android arm64 / Termux 仍是预览支持:只有当所选 npm 包版本对应的 GitHub Release 发布了匹配的 Android 资产时,npm 安装才可用。 |
| 443 | 查看 <Link href={p("/install")} className="body-link">完整安装指南</Link> 了解国内镜像、Docker 和故障排除。 |
| 444 | </p> |
| 445 | </> |
| 446 | ), |
| 447 | sources: ["README.md", "docs/INSTALL.md", "#1860", "#1914"], |
| 448 | }, |
| 449 | { |
| 450 | q: "可以在 VS Code 中使用 Codewhale 吗?", |
| 451 | a: ( |
| 452 | <> |
| 453 | 可以。CodeWhale GUI(VS Code)是社区维护的图形前端,运行同一个引擎:在 VS Code 侧边栏中对话、管理线程并查看文件变更,连接你本机已在运行的 Runtime。可从 <a href="https://marketplace.visualstudio.com/items?itemName=HengQuWorld.brotherwhale-vscode" className="body-link">VS Code Marketplace</a> 安装;源码见 <a href="https://github.com/HengQuWorld/CodeWhale-VSCode" className="body-link">GitHub</a>。 |
| 454 | </> |
| 455 | ), |
| 456 | sources: ["README.md"], |
| 457 | }, |
| 458 | { |
| 459 | q: "codewhale 和 codewhale-tui 有什么区别?", |
| 460 | a: ( |
| 461 | <> |
| 462 | 自 v0.9.5 起只有一个编译好的运行时:<code className="inline">codewhale</code> 命令直接内置终端 UI——不再有需要单独安装的 TUI 可执行文件。 |
| 463 | 发布安装器同时提供字节完全相同的 <code className="inline">codew</code> 短名称,<code className="inline">codewhale update</code> 会用同一份经过校验的字节刷新任何遗留的 <code className="inline">codewhale-tui</code> 命令路径。 |
| 464 | <code className="inline">codewhale-tui</code> 仅以内部 TUI crate 的形式存在,编译进 <code className="inline">codewhale-cli</code> Cargo 包,因此 Cargo 用户只需安装 <code className="inline">codewhale-cli</code>。 |
| 465 | </> |
| 466 | ), |
| 467 | sources: ["README.md", "CHANGELOG.md"], |
| 468 | }, |
| 469 | { |
| 470 | q: "Codewhale 和 DeepSeek TUI 是什么关系?改名是怎么回事?", |
| 471 | a: ( |
| 472 | <> |
| 473 | Codewhale 是 DeepSeek TUI 的新名称。当前的主命令是 <code className="inline">codewhale</code>。旧的 <code className="inline">deepseek</code> 和 <code className="inline">deepseek-tui</code> 命令作为兼容垫片继续有效。 |
| 474 | 配置存放在 <code className="inline">~/.codewhale/</code>。旧版 <code className="inline">~/.deepseek/</code> 配置仍会作为兼容回退读取,<code className="inline">DEEPSEEK_*</code> 环境变量继续有效。 |
| 475 | DeepSeek 并未被弃用。改名是为了体现 Codewhale 更广泛的使命——成为面向所有提供商的开放模型智能体终端,而非弱化 DeepSeek 的地位。 |
| 476 | </> |
| 477 | ), |
| 478 | sources: ["docs/REBRAND.md", "README.md"], |
| 479 | }, |
| 480 | { |
| 481 | q: "如何设置 API 密钥?", |
| 482 | a: ( |
| 483 | <> |
| 484 | <pre tabIndex={0} className="code-block mb-2"> |
| 485 | {`# 方法 1:环境变量 |
| 486 | export DEEPSEEK_API_KEY=sk-... |
| 487 | |
| 488 | # 方法 2:保存密钥(推荐 — 重启 Shell 后仍然有效) |
| 489 | codewhale auth set --provider deepseek # 会提示输入密钥 |
| 490 | # 脚本中:用 --api-key-stdin 通过管道传入 |
| 491 | |
| 492 | # 查看当前状态: |
| 493 | codewhale auth status # 显示配置、密钥环和环境变量状态 |
| 494 | codewhale doctor # 完整连接检查`} |
| 495 | </pre> |
| 496 | <p> |
| 497 | 已保存的密钥优先于环境变量。不要把密钥直接写在命令行里,否则会留在 Shell 历史中。 |
| 498 | 使用 <code className="inline">codewhale auth clear --provider deepseek</code> 移除已保存的密钥。 |
| 499 | </p> |
| 500 | </> |
| 501 | ), |
| 502 | sources: ["#907", "#1545", "docs/CONFIGURATION.md"], |
| 503 | }, |
| 504 | { |
| 505 | q: "Codewhale 支持哪些提供商?", |
| 506 | a: ( |
| 507 | <> |
| 508 | <p className="mb-2">Codewhale 内建 {FACTS.providers.length} 条提供商路由:</p> |
| 509 | <ul className="list-disc pl-5 space-y-1 text-sm text-ink-soft mb-3"> |
| 510 | <li><strong>DeepSeek</strong> — 内置默认原生 API 路由,支持推理流、缓存指标和思考力度控制。</li> |
| 511 | <li><strong>OpenRouter</strong> — 统一 API,可访问 DeepSeek 和其他开放模型路由。</li> |
| 512 | <li><strong>另外 {FACTS.providers.length - 2} 条路由</strong>——包括 OpenAI 兼容、Anthropic、Mistral AI、OpenAI Codex、xAI、Moonshot/Kimi、Z.ai、MiniMax、StepFun、Volcengine Ark、百度千帆、Model Studio、NVIDIA NIM、Fireworks、Together AI、DeepInfra、SiliconFlow、Novita、Hugging Face、Arcee AI、AtlasCloud,以及无需密钥的本地端点 SGLang、vLLM 和 Ollama。<Link href={p("/models")} className="body-link">完整列表由提供商注册表生成</Link>。</li> |
| 513 | </ul> |
| 514 | <p> |
| 515 | 设置对应的环境变量(如 <code className="inline">OPENROUTER_API_KEY</code>)并在 <code className="inline">~/.codewhale/config.toml</code> 中配置你的提供商。 |
| 516 | 自托管 OpenAI 兼容端点可通过 provider 配置接入。 |
| 517 | </p> |
| 518 | </> |
| 519 | ), |
| 520 | sources: ["docs/CONFIGURATION.md", "#1978", "#1710"], |
| 521 | }, |
| 522 | { |
| 523 | q: "如何使用 OpenRouter?", |
| 524 | a: ( |
| 525 | <> |
| 526 | <pre tabIndex={0} className="code-block mb-2"> |
| 527 | {`# 1. 设置 OpenRouter 密钥 |
| 528 | export OPENROUTER_API_KEY=sk-or-v1-... |
| 529 | |
| 530 | # 2. 在 ~/.codewhale/config.toml 中: |
| 531 | [providers.openrouter] |
| 532 | api_key = "sk-or-v1-..." |
| 533 | |
| 534 | # 3. 使用 OpenRouter 路由运行: |
| 535 | codewhale --provider openrouter --model deepseek/deepseek-v4-pro |
| 536 | |
| 537 | # 或在 config.toml 中设为默认路由: |
| 538 | # provider = "openrouter" |
| 539 | # default_text_model = "deepseek/deepseek-v4-pro"`} |
| 540 | </pre> |
| 541 | <p> |
| 542 | OpenRouter 使用与原生 DeepSeek 提供商相同的推理/缓存解析器。 |
| 543 | 模型 ID 使用 OpenRouter 自己的 slug(如 <code className="inline">deepseek/deepseek-v4-flash</code>);通过 <code className="inline">--provider openrouter</code> 或顶层 <code className="inline">provider = "openrouter"</code> 选择路由。 |
| 544 | </p> |
| 545 | </> |
| 546 | ), |
| 547 | sources: ["docs/CONFIGURATION.md", "#1978"], |
| 548 | }, |
| 549 | { |
| 550 | q: "可以使用自托管或本地模型吗(vLLM、Ollama、llama.cpp)?", |
| 551 | a: ( |
| 552 | <> |
| 553 | 可以。使用 <code className="inline">vllm</code>、<code className="inline">sglang</code> 或 <code className="inline">ollama</code> 提供商连接本地端点。 |
| 554 | 对于 OpenAI 兼容端点(llama.cpp server、text-generation-webui 等),可以使用 <code className="inline">openai</code> 提供商并设置自定义 <code className="inline">base_url</code>。 |
| 555 | Codewhale 也支持 <code className="inline">DEEPSEEK_ALLOW_INSECURE_HTTP=true</code> 用于本地 HTTP 端点。 |
| 556 | Hugging Face Inference Providers 也可以通过 <code className="inline">huggingface</code> provider 使用。更完整的 Hub 发现、模型卡片、数据集和 Jobs 属于 Model Lab。 |
| 557 | </> |
| 558 | ), |
| 559 | sources: ["#574", "#1303", "docs/CONFIGURATION.md"], |
| 560 | }, |
| 561 | { |
| 562 | q: "Plan、Work、Operate 三种模式有什么区别?", |
| 563 | a: ( |
| 564 | <> |
| 565 | <ul className="list-disc pl-5 space-y-2 text-sm text-ink-soft"> |
| 566 | <li><strong>Plan(计划)</strong> — 只读调查。可以 grep、读文件、列目录、抓取 URL。不能写入或执行 Shell。</li> |
| 567 | <li><strong>Work(执行)</strong> — 常规交互式编码。工具是否可用以及何时请求批准,取决于当前配置和权限姿态。</li> |
| 568 | <li><strong>Operate(编排)</strong> — 直接工具遵循与 Work 相同的权限、沙箱、Shell 和安全规则。独立、并行、后台或长时间工作会优先交给 fleet worker,但不强制委派;只有需要有序阶段和门禁时才需要 Workflow。</li> |
| 569 | </ul> |
| 570 | <p className="mt-2"> |
| 571 | 输入区空闲时,按 <kbd className="font-mono text-xs px-1.5 py-0.5 hairline-t hairline-b hairline-l hairline-r">Tab</kbd> 切换模式。 |
| 572 | 按 <kbd className="font-mono text-xs px-1.5 py-0.5 hairline-t hairline-b hairline-l hairline-r">Shift+Tab</kbd> 循环独立的 Ask / Auto-Review / Full Access 权限姿态;Plan 始终只读。 |
| 573 | </p> |
| 574 | </> |
| 575 | ), |
| 576 | sources: ["docs/MODES.md"], |
| 577 | }, |
| 578 | { |
| 579 | q: "什么是模型自动路由?Fin 是什么?", |
| 580 | a: ( |
| 581 | <> |
| 582 | <p className="mb-2"> |
| 583 | 使用 <code className="inline">codewhale --model auto</code> 或 <code className="inline">/model auto</code> 让 Codewhale 为每个回合自动选择最合适的模型和推理深度。 |
| 584 | </p> |
| 585 | <p className="mb-2"> |
| 586 | <strong>Fin</strong> 是快速非推理路径(<code className="inline">deepseek-v4-flash</code>,推理关闭),用于路由决策、摘要、RLM 子任务、上下文维护等协调工作。在真实请求发送前,Fin 会做一个小的路由调用来选择具体的模型和推理级别。 |
| 587 | </p> |
| 588 | <p> |
| 589 | 简短简单的请求可以留在 Flash + 推理关闭的状态。编码、调试、发布工作、架构设计或安全审查则会提升到 Pro 和/或更高的推理级别。Fin 是 Codewhale 本地逻辑——上游 API 永远不会收到 <code className="inline">model: "auto"</code>。 |
| 590 | </p> |
| 591 | </> |
| 592 | ), |
| 593 | sources: ["README.md", "#1207"], |
| 594 | }, |
| 595 | { |
| 596 | q: "什么是 Goal 模式?现在可用吗?", |
| 597 | a: ( |
| 598 | <> |
| 599 | <code className="inline">/goal</code> 为当前 TUI 会话设置目标,支持 <code className="inline">pause</code>、<code className="inline">resume</code>、<code className="inline">complete</code>、<code className="inline">blocked</code> 和 <code className="inline">clear</code> 控制。 |
| 600 | App-server 客户端也可以通过 <code className="inline">thread/goal/*</code> 方法持久化线程范围的目标,支持 <code className="inline">set</code>、<code className="inline">get</code> 和 <code className="inline">clear</code>。 |
| 601 | 它不会新增一个应用模式;模式切换器仍然是 Plan、Work 和 Operate,权限姿态独立选择。 |
| 602 | 跟踪进展:<a href="https://github.com/codewhale-hq/CodeWhale/issues/891" className="body-link">#891</a>。 |
| 603 | </> |
| 604 | ), |
| 605 | sources: ["#891"], |
| 606 | }, |
| 607 | { |
| 608 | q: "我的代码安全吗?Codewhale 使用什么沙箱机制?", |
| 609 | a: ( |
| 610 | <> |
| 611 | Codewhale 运行时、工作区状态与审计日志保留在你的机器上。Codewhale 默认统计匿名使用量,并在首次启动时告知你。 |
| 612 | 关闭是会被后续版本保留的选择;显示告知绝不会代你记录任何同意。开启时,会话只会把聚合的会话、功能与错误计数以及封闭枚举 POST 到 telemetry.codewhale.net 上的第一方端点, |
| 613 | 那是一个 Cloudflare Worker,完整源码就在仓库里。 |
| 614 | 它的存储中没有 IP、国家或地理位置列,不记录请求日志,保留期固定为三个月。 |
| 615 | 可选的 PostHog 转发需要运营方单独配置,并验证出口不会转发客户端 IP;其保留期由项目另行设置。源码支持不代表已启用。 |
| 616 | 若想保持启用但不联系任何服务器,设置 <code className="inline">telemetry_endpoint = ""</code>。 |
| 617 | 它永远不会携带对话、代码、prompt、文件、文件/仓库/分支名、模型内容、凭据,也不发送逐轮或逐工具时间线(见<a href="https://github.com/codewhale-hq/CodeWhale/blob/main/docs/TELEMETRY.md" className="body-link">遥测 schema</a>; |
| 618 | 可用 <code className="inline">codewhale config set telemetry false</code> 或 |
| 619 | <code className="inline">CODEWHALE_TELEMETRY=0</code> 关闭)。也不要求经过托管中继。你选择的托管 provider 会收到本轮所需的 |
| 620 | prompt、项目上下文、工具定义与工具结果。若要让模型推理也保持本地,请使用回环地址上的本地模型路由。 |
| 621 | OS 命令沙箱因平台而异:macOS 在可用时使用 <strong>Seatbelt</strong>。Linux 仅在 <code className="inline">prefer_bwrap = true</code> 且 <code className="inline">/usr/bin/bwrap</code> 可执行时使用 <strong>bubblewrap</strong>;否则命令没有 Codewhale OS 包装器。Windows 当前报告无 OS 沙箱。 |
| 622 | 工作区边界默认为 <code className="inline">--workspace</code>。<code className="inline">/trust</code> 可解除边界。 |
| 623 | 权限姿态可按会话配置。 |
| 624 | </> |
| 625 | ), |
| 626 | sources: [".github/SECURITY.md", "docs/PROVIDERS.md", "docs/RUNTIME_API.md"], |
| 627 | }, |
| 628 | { |
| 629 | q: "MCP 服务器如何工作?", |
| 630 | a: ( |
| 631 | <> |
| 632 | Codewhale 是双向 MCP 客户端和服务器。在 <code className="inline">~/.codewhale/mcp.json</code> 中定义服务器。 |
| 633 | 工具以 <code className="inline">mcp_<server>_<tool></code> 形式呈现。你也可以通过 <code className="inline">codewhale mcp</code> 将 Codewhale 暴露为 MCP 服务器。 |
| 634 | 查看 <Link href={p("/docs/mcp")} className="body-link">文档页面</Link> 了解配置示例。 |
| 635 | </> |
| 636 | ), |
| 637 | sources: ["docs/MCP.md"], |
| 638 | }, |
| 639 | { |
| 640 | q: "如何参与贡献?", |
| 641 | a: ( |
| 642 | <> |
| 643 | 无需签署 CLA。Fork、用约定式提交(<code className="inline">feat:</code>、<code className="inline">fix:</code> 等)创建分支、通过本地检查、提交 PR。 |
| 644 | 维护者亲自阅读每一条内容。从标记为 <code className="inline">good first issue</code> 的议题开始。 |
| 645 | 查看 <Link href={p("/contribute")} className="body-link">贡献页面</Link> 和 <a href="https://github.com/codewhale-hq/CodeWhale/blob/main/CONTRIBUTING.md" className="body-link">CONTRIBUTING.md</a>。 |
| 646 | </> |
| 647 | ), |
| 648 | sources: ["CONTRIBUTING.md"], |
| 649 | }, |
| 650 | { |
| 651 | q: "我在国内,安装很慢怎么办?", |
| 652 | a: ( |
| 653 | <> |
| 654 | 使用镜像源: |
| 655 | <pre tabIndex={0} className="code-block my-2"> |
| 656 | {`# npm 镜像 |
| 657 | npm config set registry https://registry.npmmirror.com |
| 658 | npm install -g codewhale |
| 659 | |
| 660 | # Cargo 镜像(清华 TUNA) |
| 661 | # 在 ~/.cargo/config.toml 中添加: |
| 662 | [source.crates-io] |
| 663 | replace-with = "tuna" |
| 664 | [source.tuna] |
| 665 | registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"`} |
| 666 | </pre> |
| 667 | <p> |
| 668 | 也可以从 <a href="https://github.com/codewhale-hq/CodeWhale/releases" className="body-link">GitHub Releases</a> 直接下载预编译二进制。 |
| 669 | 维护中的 CNB 镜像覆盖其文档列出的目标;Gitee 镜像只有实际存在后才会对外展示。 |
| 670 | </p> |
| 671 | </> |
| 672 | ), |
| 673 | sources: ["README.md", "#1914", "docs/CNB_MIRROR.md"], |
| 674 | }, |
| 675 | { |
| 676 | q: "codewhale.net 是官方网站吗?镜像站点呢?", |
| 677 | a: ( |
| 678 | <> |
| 679 | <p className="mb-2"> |
| 680 | <strong>codewhale.net</strong> 和 <strong>www.codewhale.net</strong> 是 |
| 681 | Codewhale 的官方站点,部署在 Cloudflare 上。网站源码存放于{" "} |
| 682 | <code className="inline">codewhale-hq/CodeWhale</code> 仓库的{" "} |
| 683 | <code className="inline">web/</code> 目录下,任何人都可自行部署为镜像。 |
| 684 | </p> |
| 685 | <p className="mb-2"> |
| 686 | 所有正式发布和 SHA-256 校验文件仅通过{" "} |
| 687 | <a href="https://github.com/codewhale-hq/CodeWhale/releases" className="body-link">GitHub Releases</a> 分发。 |
| 688 | npm 包从 GitHub Releases 下载经校验的二进制。 |
| 689 | </p> |
| 690 | <p className="mb-2"> |
| 691 | 面向无法稳定访问 GitHub 的用户,提供 CNB 镜像( |
| 692 | <Link href={p("/install")} className="body-link">docs/CNB_MIRROR.md</Link>)。 |
| 693 | Cargo 用户可使用 TUNA 镜像在国内加速下载。 |
| 694 | </p> |
| 695 | <p> |
| 696 | 自行部署的网站副本、镜像站和第三方包不受 Codewhale 项目控制。 |
| 697 | 请验证下载来源和校验和。 |
| 698 | </p> |
| 699 | </> |
| 700 | ), |
| 701 | sources: ["#2624", "#3421", "docs/CNB_MIRROR.md"], |
| 702 | }, |
| 703 | { |
| 704 | q: "首次运行时提示 API 密钥被拒绝或认证错误?", |
| 705 | a: ( |
| 706 | <> |
| 707 | <p className="mb-2">运行 <code className="inline">codewhale doctor</code>——它会向 stdout 打印诊断报告:配置路径、凭据存储状态(绝不读取或打印具体值)、提供商/本地/MCP 探针以及发布检查。</p> |
| 708 | <p className="mb-2">常见原因:</p> |
| 709 | <ul className="list-disc pl-5 space-y-1 text-sm text-ink-soft"> |
| 710 | <li>Shell 启动文件中的 <code className="inline">DEEPSEEK_API_KEY</code> 已过期——打开新 Shell 或使用 <code className="inline">codewhale auth set</code></li> |
| 711 | <li>密钥来自错误的提供商——确保密钥与你使用的提供商匹配</li> |
| 712 | <li>网络连接问题——检查 <code className="inline">curl https://api.deepseek.com/v1/models</code></li> |
| 713 | </ul> |
| 714 | </> |
| 715 | ), |
| 716 | sources: ["#907", "#1545"], |
| 717 | }, |
| 718 | { |
| 719 | q: "Model Lab 是什么?Hugging Face 哪些部分可用?", |
| 720 | a: ( |
| 721 | <> |
| 722 | <code className="inline">huggingface</code> provider 是已经接入的 OpenAI 兼容 Hugging Face Inference Providers 路由。 |
| 723 | Model Lab 是规划中的开放模型基础设施层:Hub 发现、模型卡片、数据集、safetensors 适配器和 Jobs。 |
| 724 | 更完整的进展见 <a href="https://github.com/codewhale-hq/CodeWhale/issues/1977" className="body-link">#1977</a>。 |
| 725 | </> |
| 726 | ), |
| 727 | sources: ["#1977", "docs/MODEL_LAB.md"], |
| 728 | }, |
| 729 | { |
| 730 | q: "为什么 token 消耗这么大?/ 缓存命中率为什么低?", |
| 731 | a: ( |
| 732 | <> |
| 733 | Codewhale 每次请求都会发送大量上下文(系统提示、项目说明、工具定义)。 |
| 734 | DeepSeek 的前缀缓存被积极使用——系统提示按最稳定的层级排列以最大化缓存命中。 |
| 735 | 如果你发现 token 使用量很高,请检查:是否在简单查询中使用了 <code className="inline">deepseek-v4-pro</code>(更适合用 Flash)? |
| 736 | 模型自动路由(Fin)可以帮助为每个回合选择合适的模型。 |
| 737 | 缓存命中率取决于提示的稳定性——修改系统提示或切换模型会重置缓存。 |
| 738 | </> |
| 739 | ), |
| 740 | sources: ["#1177", "#1818", "#743"], |
| 741 | }, |
| 742 | { |
| 743 | q: "如何更新 Codewhale?", |
| 744 | a: ( |
| 745 | <> |
| 746 | <pre tabIndex={0} className="code-block mb-2"> |
| 747 | {`# 安装器或发布二进制安装 |
| 748 | codewhale update |
| 749 | |
| 750 | # npm(codewhale update 不会更新 npm 安装) |
| 751 | npm install -g codewhale@latest |
| 752 | |
| 753 | # Cargo |
| 754 | cargo install codewhale-cli --locked --force |
| 755 | |
| 756 | # Homebrew tap |
| 757 | brew update && brew upgrade codewhale`} |
| 758 | </pre> |
| 759 | <p> |
| 760 | 如果通过 npm 或 Homebrew 安装,请用对应的包管理器更新;<code className="inline">codewhale update</code> 不会改动包管理器安装的版本。 |
| 761 | 如果镜像延迟,请从 <a href="https://github.com/codewhale-hq/CodeWhale/releases" className="body-link">GitHub Releases</a> 直接下载。 |
| 762 | </p> |
| 763 | </> |
| 764 | ), |
| 765 | sources: ["README.md", "#1869", "#1914"], |
| 766 | }, |
| 767 | ]; |
| 768 | |
| 769 | export default async function FaqPage({ params }: { params: Promise<{ locale: string }> }) { |
| 770 | const { locale } = await params; |
| 771 | const t = getFaq(locale); |
| 772 | const p = (path: string) => `/${locale}${path}`; |
| 773 | const items = { en: faqEn, zh: faqZh }[pickTextLocale(locale)](p); |
| 774 | const canonicalLocale = canonicalLocaleForPath("/faq", locale); |
| 775 | const jsonLd = buildFaqPageJsonLd({ |
| 776 | items, |
| 777 | url: `${SITE_URL}/${canonicalLocale}/faq`, |
| 778 | inLanguage: canonicalLocale, |
| 779 | }); |
| 780 | |
| 781 | return ( |
| 782 | <> |
| 783 | <script |
| 784 | type="application/ld+json" |
| 785 | dangerouslySetInnerHTML={{ __html: serializeJsonLd(jsonLd) }} |
| 786 | /> |
| 787 | <PageHeader |
| 788 | seal="问" |
| 789 | kicker={t.eyebrow} |
| 790 | title={t.title} |
| 791 | titleAside={t.titleAside} |
| 792 | titleAsideLang={t.titleAsideLang} |
| 793 | lede={t.lead} |
| 794 | pose="talk" |
| 795 | /> |
| 796 | |
| 797 | <div className="page-body"> |
| 798 | <div className="page-body-narrow"> |
| 799 | <FaqSearch items={items} locale={locale} /> |
| 800 | |
| 801 | <div className="empty-state empty-state-compact faq-more"> |
| 802 | <p className="empty-state-title">{t.notCovered}</p> |
| 803 | <div className="empty-state-actions"> |
| 804 | <a href="https://github.com/codewhale-hq/CodeWhale/issues/new/choose" className="btn btn-secondary"> |
| 805 | {t.openIssue} |
| 806 | </a> |
| 807 | </div> |
| 808 | </div> |
| 809 | </div> |
| 810 | </div> |
| 811 | </> |
| 812 | ); |
| 813 | } |
| 814 |