| 1 | import { buildPageMetadata } from "@/lib/page-meta"; |
| 2 | |
| 3 | export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) { |
| 4 | const { locale } = await params; |
| 5 | const isZh = locale === "zh"; |
| 6 | return buildPageMetadata({ |
| 7 | path: "/docs/configuration", |
| 8 | locale, |
| 9 | title: isZh ? "配置 · Codewhale 文档" : "Configuration · Codewhale Docs", |
| 10 | description: isZh |
| 11 | ? "config.toml 的查找顺序、项目级覆盖、凭据优先级和旧版路径迁移。" |
| 12 | : "Where config.toml is read from, the per-project overlay, credential precedence, and legacy path migration.", |
| 13 | }); |
| 14 | } |
| 15 | |
| 16 | export default async function ConfigurationPage({ |
| 17 | params, |
| 18 | }: { |
| 19 | params: Promise<{ locale: string }>; |
| 20 | }) { |
| 21 | const { locale } = await params; |
| 22 | const isZh = locale === "zh"; |
| 23 | const bodyClass = isZh |
| 24 | ? "text-ink-soft leading-[1.9] tracking-wide" |
| 25 | : "text-ink-soft leading-relaxed"; |
| 26 | |
| 27 | return ( |
| 28 | <section className="space-y-10"> |
| 29 | <section id="overview" className="scroll-mt-32"> |
| 30 | <h2 className="font-display text-3xl mb-1">{isZh ? "配置" : "Configuration"}</h2> |
| 31 | <p className={`${bodyClass} mt-3`}> |
| 32 | {isZh |
| 33 | ? "Codewhale 从 ~/.codewhale/config.toml 读取配置(旧版 ~/.deepseek/config.toml 仍作为回退读取)。--config 标志和 CODEWHALE_CONFIG_PATH 环境变量可以指定别的路径,两者同时设置时 --config 优先;文件加载之后再应用环境变量覆盖。" |
| 34 | : "Codewhale reads its configuration from ~/.codewhale/config.toml (the legacy ~/.deepseek/config.toml is still read as a fallback). The --config flag and the CODEWHALE_CONFIG_PATH environment variable can point elsewhere; --config wins when both are set, and environment variable overrides are applied after the file is loaded."} |
| 35 | </p> |
| 36 | <pre className="code-block mt-4">{`codewhale --config /path/to/config.toml |
| 37 | CODEWHALE_CONFIG_PATH=/path/to/config.toml`}</pre> |
| 38 | <p className={`${bodyClass} mt-3`}> |
| 39 | {isZh ? ( |
| 40 | <> |
| 41 | 在 TUI 里运行 <code className="inline">/config audit</code>{" "} |
| 42 | 可以查看哪些文档化的键能在当前会话修改、哪些能持久化、哪些只能改文件或需要重启——改动前以它输出的 |
| 43 | “Command / reason” 列为准。 |
| 44 | </> |
| 45 | ) : ( |
| 46 | <> |
| 47 | Inside the TUI, <code className="inline">/config audit</code> shows which documented keys |
| 48 | can change in the current session, which can also be persisted, and which stay file-only or |
| 49 | restart-only — treat its “Command / reason” column as the source of truth before editing by |
| 50 | hand. |
| 51 | </> |
| 52 | )} |
| 53 | </p> |
| 54 | </section> |
| 55 | |
| 56 | <section id="project-overlay" className="scroll-mt-32"> |
| 57 | <h2 className="font-display text-2xl mb-1"> |
| 58 | {isZh ? "项目级覆盖" : "Per-project overlay"} |
| 59 | </h2> |
| 60 | <p className={`${bodyClass} mt-3`}> |
| 61 | {isZh |
| 62 | ? "当工作区包含常规文件 <workspace>/.codewhale/config.toml 时,其中声明的安全取值会合并到全局配置之上(旧版 <workspace>/.deepseek/config.toml 在新路径缺失时仍会读取;符号链接的项目配置会被拒绝)。这让仓库可以建议模型或收紧本地安全姿态,而不动用户的全局配置。单次启动可用 --no-project-config 跳过覆盖。" |
| 63 | : "When a workspace contains a regular-file <workspace>/.codewhale/config.toml, the safe values it declares are merged on top of the global config (legacy <workspace>/.deepseek/config.toml files are still read when the Codewhale path is absent; symlinked project configs are rejected). This lets a repository suggest a model or tighten the local safety posture without touching the user's global config. Pass --no-project-config to skip the overlay for one launch."} |
| 64 | </p> |
| 65 | <p className={`${bodyClass} mt-3`}> |
| 66 | {isZh |
| 67 | ? "覆盖层有意保持狭窄:支持 model、reasoning_effort、approval_policy 与 sandbox_mode(只能收紧)、notes_path、max_subagents(夹紧到 1..=20)、allow_shell(false 生效,true 被忽略)。凭据、端点、提供商选择、MCP 配置、hooks、skills 和 instructions = [...] 始终属于用户全局配置——仓库里的 config.toml 声明 api_key、base_url 或 provider 会被忽略,克隆的仓库无法借此选择任意本地文件进入提示词。" |
| 68 | : "The overlay is intentionally narrow: it supports model, reasoning_effort, approval_policy and sandbox_mode (tightening values only), notes_path, max_subagents (clamped to 1..=20), and allow_shell (false applies, true is ignored). Credentials, endpoints, provider selection, MCP config, hooks, skills, and instructions = [...] stay user-global — a repo-local config.toml that declares api_key, base_url, or provider is ignored, so a cloned repository cannot pick arbitrary local files into the prompt."} |
| 69 | </p> |
| 70 | </section> |
| 71 | |
| 72 | <section id="credentials" className="scroll-mt-32"> |
| 73 | <h2 className="font-display text-2xl mb-1"> |
| 74 | {isZh ? "凭据查找" : "Credential lookup"} |
| 75 | </h2> |
| 76 | <p className={`${bodyClass} mt-3`}> |
| 77 | {isZh ? ( |
| 78 | <> |
| 79 | 在显式 <code className="inline">--api-key</code> 之后,凭据按 config → keyring → env |
| 80 | 的顺序解析。<code className="inline">codewhale auth status</code>{" "} |
| 81 | 可以查看当前提供商的配置文件、系统 keyring 后端、环境变量、生效来源和末四位标签,而不会打印密钥本身。托管、OpenAI 兼容、自托管或 Anthropic 原生路由用{" "} |
| 82 | <code className="inline">{"provider = \"<id>\""}</code> 或{" "} |
| 83 | <code className="inline">codewhale --provider <id></code>{" "} |
| 84 | 选择;完整注册表见模型与提供商页和 docs/PROVIDERS.md。 |
| 85 | </> |
| 86 | ) : ( |
| 87 | <> |
| 88 | After any explicit <code className="inline">--api-key</code>, credentials resolve in |
| 89 | config → keyring → env order. <code className="inline">codewhale auth status</code>{" "} |
| 90 | inspects the active provider's config file, OS keyring backend, environment variable, |
| 91 | winning source, and last-four label without printing the key itself. Hosted, generic |
| 92 | OpenAI-compatible, self-hosted, or native Anthropic routes are selected with{" "} |
| 93 | <code className="inline">{"provider = \"<id>\""}</code> or{" "} |
| 94 | <code className="inline">codewhale --provider <id></code>; the full registry lives on |
| 95 | the Models & providers page and in docs/PROVIDERS.md. |
| 96 | </> |
| 97 | )} |
| 98 | </p> |
| 99 | </section> |
| 100 | |
| 101 | <section id="legacy-paths" className="scroll-mt-32"> |
| 102 | <h2 className="font-display text-2xl mb-1"> |
| 103 | {isZh ? "旧版 .deepseek/ 路径" : "Legacy .deepseek/ paths"} |
| 104 | </h2> |
| 105 | <p className={`${bodyClass} mt-3`}> |
| 106 | {isZh |
| 107 | ? "Codewhale 由 DeepSeek-TUI 更名而来。为了不破坏既有安装,运行时从新的 ~/.codewhale/ 位置读取状态,但在只有旧目录存在时回退到 ~/.deepseek/,并且始终写入 ~/.codewhale/——读取带回退、写入新位置。状态目录解析集中在 crates/config/src/lib.rs 的 resolve_state_dir / ensure_state_dir 中,每一处旧路径引用都有审计过的保留决定。" |
| 108 | : "Codewhale was renamed from DeepSeek-TUI. To avoid breaking existing installs, the runtime reads state from the new ~/.codewhale/ location but falls back to ~/.deepseek/ when only the legacy directory exists, and always writes to ~/.codewhale/ — read-with-fallback, write-to-new. State-dir resolution is consolidated in resolve_state_dir / ensure_state_dir in crates/config/src/lib.rs, and every legacy path reference carries an audited keep decision."} |
| 109 | </p> |
| 110 | </section> |
| 111 | |
| 112 | <section id="source" className="hairline-t pt-8"> |
| 113 | <p className="text-sm text-ink-mute"> |
| 114 | {isZh |
| 115 | ? "来源文档:docs/CONFIGURATION.md, docs/LEGACY_PATHS.md · 更新时请同步修改 docs-map.ts。" |
| 116 | : "Source documents: docs/CONFIGURATION.md, docs/LEGACY_PATHS.md · Update docs-map.ts when changing."} |
| 117 | </p> |
| 118 | </section> |
| 119 | </section> |
| 120 | ); |
| 121 | } |
| 122 |