| 1 | /** |
| 2 | * docs-map.ts — canonical documentation registry for codewhale.net. |
| 3 | * |
| 4 | * Maps every first-class documentation topic area to its repo source file(s) |
| 5 | * and website route. This is the single source of truth for the docs hub |
| 6 | * sidebar, breadcrumbs, and drift/parity checks. |
| 7 | * |
| 8 | * EXTENSION PATH FOR NEW LOCALES: |
| 9 | * Labels are keyed by locale. Add a new locale column and update the page |
| 10 | * components that consume this map. The topic IDs, slugs, and repo sources |
| 11 | * are locale-agnostic. |
| 12 | */ |
| 13 | |
| 14 | export interface DocTopic { |
| 15 | /** Stable identifier used in routes and anchors. */ |
| 16 | id: string; |
| 17 | /** URL slug for the docs sub-route (e.g. "install"). */ |
| 18 | slug: string; |
| 19 | /** Label per locale. */ |
| 20 | label: { en: string; zh: string }; |
| 21 | /** Short description per locale. */ |
| 22 | description: { en: string; zh: string }; |
| 23 | /** Repo source file(s) — the canonical markdown doc in the repo. */ |
| 24 | repoSource: string | string[]; |
| 25 | /** Whether this topic has a dedicated website page (vs. linking out). */ |
| 26 | hasPage: boolean; |
| 27 | /** Locale-relative website path when the page lives outside `/docs/<slug>`. */ |
| 28 | sitePath?: string; |
| 29 | /** Category for grouping in the sidebar. */ |
| 30 | category: "getting-started" | "core-concepts" | "reference" | "extending" | "operations"; |
| 31 | } |
| 32 | |
| 33 | /** Sidebar and breadcrumb labels for each docs-map category. */ |
| 34 | export const DOC_CATEGORY_LABELS: Record<DocTopic["category"], { en: string; zh: string }> = { |
| 35 | "getting-started": { en: "Get started", zh: "开始使用" }, |
| 36 | "core-concepts": { en: "Work with Codewhale", zh: "日常使用" }, |
| 37 | extending: { en: "Extend and automate", zh: "扩展与自动化" }, |
| 38 | operations: { en: "Get help", zh: "获取帮助" }, |
| 39 | reference: { en: "Reference", zh: "参考" }, |
| 40 | }; |
| 41 | |
| 42 | export const DOC_TOPICS: DocTopic[] = [ |
| 43 | { |
| 44 | id: "install", |
| 45 | slug: "install", |
| 46 | label: { en: "Install Codewhale", zh: "安装 Codewhale" }, |
| 47 | description: { |
| 48 | en: "The installer, npm, Homebrew tap, Cargo, and release binaries, with the output each step prints.", |
| 49 | zh: "安装脚本、npm、Homebrew tap、Cargo 与发布版二进制文件,以及每一步应有的输出。", |
| 50 | }, |
| 51 | repoSource: "docs/INSTALL.md", |
| 52 | hasPage: true, |
| 53 | sitePath: "install", |
| 54 | category: "getting-started", |
| 55 | }, |
| 56 | { |
| 57 | id: "guide", |
| 58 | slug: "guide", |
| 59 | label: { en: "Start your first task", zh: "开始第一个任务" }, |
| 60 | description: { |
| 61 | en: "Install, connect a model, and give Codewhale a task in your project.", |
| 62 | zh: "安装、连接模型,然后在你的项目里交给 Codewhale 一项任务。", |
| 63 | }, |
| 64 | repoSource: ["docs/GUIDE.md", "docs/KEYBINDINGS.md"], |
| 65 | hasPage: true, |
| 66 | category: "getting-started", |
| 67 | }, |
| 68 | { |
| 69 | id: "auth", |
| 70 | slug: "auth", |
| 71 | label: { en: "Connect a provider", zh: "连接模型提供商" }, |
| 72 | description: { |
| 73 | en: "Save a provider key, check which key is used, run a local model, or sign in to the optional account.", |
| 74 | zh: "保存提供商密钥、查看当前使用的密钥、运行本地模型,或登录可选的账户。", |
| 75 | }, |
| 76 | repoSource: ["docs/CONFIGURATION.md", "docs/CODEWHALE_AGENT.md"], |
| 77 | hasPage: true, |
| 78 | category: "getting-started", |
| 79 | }, |
| 80 | { |
| 81 | id: "providers", |
| 82 | slug: "providers", |
| 83 | label: { en: "Choose a model", zh: "选择模型" }, |
| 84 | description: { |
| 85 | en: "Supported providers, switching models, and local runners such as Ollama, vLLM, and SGLang.", |
| 86 | zh: "支持的提供商、切换模型,以及 Ollama、vLLM、SGLang 等本地运行器。", |
| 87 | }, |
| 88 | repoSource: ["docs/PROVIDERS.md", "docs/MODEL_LAB.md"], |
| 89 | hasPage: true, |
| 90 | sitePath: "models", |
| 91 | category: "getting-started", |
| 92 | }, |
| 93 | { |
| 94 | id: "configuration", |
| 95 | slug: "configuration", |
| 96 | label: { en: "Change settings", zh: "修改设置" }, |
| 97 | description: { |
| 98 | en: "Find the config file, change settings from the session or shell, and see what a repository may override.", |
| 99 | zh: "找到配置文件,在会话或 shell 中修改设置,并了解仓库可以覆盖哪些设置。", |
| 100 | }, |
| 101 | repoSource: ["docs/CONFIGURATION.md", "docs/LEGACY_PATHS.md"], |
| 102 | hasPage: true, |
| 103 | category: "getting-started", |
| 104 | }, |
| 105 | { |
| 106 | id: "modes", |
| 107 | slug: "modes", |
| 108 | label: { en: "Set modes and approvals", zh: "设置模式与审批" }, |
| 109 | description: { |
| 110 | en: "Plan, Work, or Operate for the kind of work; Ask, Auto-Review, or Full Access for when it asks you.", |
| 111 | zh: "用 Plan、Work、Operate 选择工作类型,用 Ask、Auto-Review、Full Access 决定它何时问你。", |
| 112 | }, |
| 113 | repoSource: "docs/MODES.md", |
| 114 | hasPage: true, |
| 115 | category: "core-concepts", |
| 116 | }, |
| 117 | { |
| 118 | id: "review", |
| 119 | slug: "review", |
| 120 | label: { en: "Review what changed", zh: "查看改动" }, |
| 121 | description: { |
| 122 | en: "See every edit, roll files back to an earlier turn, get a code review, and keep a review receipt.", |
| 123 | zh: "查看每一处修改,把文件回滚到之前的回合,做代码审查,并保留审查收据。", |
| 124 | }, |
| 125 | repoSource: ["docs/RECEIPTS.md", "docs/CONFIGURATION.md"], |
| 126 | hasPage: true, |
| 127 | category: "core-concepts", |
| 128 | }, |
| 129 | { |
| 130 | id: "work", |
| 131 | slug: "work", |
| 132 | label: { en: "Track progress", zh: "跟踪进度" }, |
| 133 | description: { |
| 134 | en: "Follow the goal, To-do list, and sub-agents in the workbar, and hand work to a fresh session.", |
| 135 | zh: "在工作栏中跟踪目标、To-do 列表和子 Agent,并把工作交接给新的会话。", |
| 136 | }, |
| 137 | repoSource: ["docs/TOOL_SURFACE.md", "docs/TOOL_LIFECYCLE.md"], |
| 138 | hasPage: true, |
| 139 | category: "core-concepts", |
| 140 | }, |
| 141 | { |
| 142 | id: "subagents", |
| 143 | slug: "subagents", |
| 144 | label: { en: "Run agents in parallel", zh: "并行运行 Agent" }, |
| 145 | description: { |
| 146 | en: "Hand independent parts of a task to sub-agents, pick roles, and keep parallel edits in worktrees.", |
| 147 | zh: "把任务中独立的部分交给子 Agent,选择角色,并用工作树隔离并行修改。", |
| 148 | }, |
| 149 | repoSource: "docs/SUBAGENTS.md", |
| 150 | hasPage: true, |
| 151 | category: "core-concepts", |
| 152 | }, |
| 153 | { |
| 154 | id: "fleet", |
| 155 | slug: "fleet", |
| 156 | label: { en: "Run a workflow", zh: "运行 Workflow" }, |
| 157 | description: { |
| 158 | en: "Save roles in a Fleet, write a repeatable Workflow, run it as a Lane, and run batches of tasks.", |
| 159 | zh: "在 Fleet 中保存角色,编写可重复的 Workflow,把它作为 Lane 运行,并批量执行任务。", |
| 160 | }, |
| 161 | repoSource: ["docs/FLEET.md", "docs/WORKFLOW_AUTHORING.md"], |
| 162 | hasPage: true, |
| 163 | category: "core-concepts", |
| 164 | }, |
| 165 | { |
| 166 | id: "sandbox", |
| 167 | slug: "sandbox", |
| 168 | label: { en: "Limit what commands can touch", zh: "限制命令的访问范围" }, |
| 169 | description: { |
| 170 | en: "The OS sandbox on macOS, Linux, and Windows, how to turn it on, and how much a command may write.", |
| 171 | zh: "macOS、Linux 和 Windows 上的操作系统沙箱、如何开启,以及命令能写到哪里。", |
| 172 | }, |
| 173 | repoSource: "docs/SANDBOX.md", |
| 174 | hasPage: true, |
| 175 | category: "core-concepts", |
| 176 | }, |
| 177 | { |
| 178 | id: "trust", |
| 179 | slug: "trust", |
| 180 | label: { en: "See what leaves your machine", zh: "了解哪些数据会离开本机" }, |
| 181 | description: { |
| 182 | en: "What stays local, what a provider receives, what usage counting sends, and how to turn it off.", |
| 183 | zh: "哪些留在本地、提供商会收到什么、用量统计发送什么,以及如何关闭。", |
| 184 | }, |
| 185 | repoSource: ["docs/SANDBOX.md", "docs/AUTHORIZATION_ORDER.md", "docs/TELEMETRY.md", "docs/public-surface-facts.json"], |
| 186 | hasPage: true, |
| 187 | category: "core-concepts", |
| 188 | }, |
| 189 | { |
| 190 | id: "mcp", |
| 191 | slug: "mcp", |
| 192 | label: { en: "Connect tools with MCP", zh: "用 MCP 连接工具" }, |
| 193 | description: { |
| 194 | en: "Add local (stdio) or remote (HTTP) MCP servers, sign in with OAuth, serve Codewhale over MCP, and try code mode.", |
| 195 | zh: "添加本地(stdio)或远程(HTTP)MCP 服务器、用 OAuth 登录、把 Codewhale 作为 MCP 服务器运行,并试用代码模式。", |
| 196 | }, |
| 197 | repoSource: "docs/MCP.md", |
| 198 | hasPage: true, |
| 199 | category: "extending", |
| 200 | }, |
| 201 | { |
| 202 | id: "hooks", |
| 203 | slug: "hooks", |
| 204 | label: { en: "Run commands on events", zh: "在事件发生时运行命令" }, |
| 205 | description: { |
| 206 | en: "Run your own scripts at session start, before a tool call, at turn end, or when Codewhale waits for you.", |
| 207 | zh: "在会话开始、工具调用之前、回合结束或 Codewhale 等你回应时运行你自己的脚本。", |
| 208 | }, |
| 209 | repoSource: ["docs/rfcs/1364-hooks-lifecycle.md", "docs/CONFIGURATION.md"], |
| 210 | hasPage: true, |
| 211 | category: "extending", |
| 212 | }, |
| 213 | { |
| 214 | id: "skills", |
| 215 | slug: "skills", |
| 216 | label: { en: "Add skills", zh: "添加技能" }, |
| 217 | description: { |
| 218 | en: "Install, find, trust, and load reusable instruction packages.", |
| 219 | zh: "安装、查找、信任并加载可复用的指令包。", |
| 220 | }, |
| 221 | repoSource: "docs/SKILLS.md", |
| 222 | hasPage: false, |
| 223 | category: "extending", |
| 224 | }, |
| 225 | { |
| 226 | id: "plugins", |
| 227 | slug: "plugins", |
| 228 | label: { en: "Add plugins", zh: "添加插件" }, |
| 229 | description: { |
| 230 | en: "Find, install, review, and trust plugin bundles.", |
| 231 | zh: "查找、安装、审查并信任插件包。", |
| 232 | }, |
| 233 | repoSource: ["docs/PLUGINS.md", "docs/PLUGIN_BUNDLES.md", "docs/EXTENSIONS.md"], |
| 234 | hasPage: false, |
| 235 | category: "extending", |
| 236 | }, |
| 237 | { |
| 238 | id: "runtime-api", |
| 239 | slug: "runtime-api", |
| 240 | label: { en: "Automate with the Runtime API", zh: "用 Runtime API 自动化" }, |
| 241 | description: { |
| 242 | en: "Run one-shot jobs from scripts, or drive threads, events, and approvals over the local HTTP API.", |
| 243 | zh: "在脚本中运行一次性任务,或通过本地 HTTP API 驱动线程、事件和审批。", |
| 244 | }, |
| 245 | repoSource: "docs/RUNTIME_API.md", |
| 246 | hasPage: true, |
| 247 | category: "extending", |
| 248 | }, |
| 249 | { |
| 250 | id: "web", |
| 251 | slug: "web", |
| 252 | label: { en: "Open the browser client", zh: "打开浏览器客户端" }, |
| 253 | description: { |
| 254 | en: "Work in a local browser tab, or continue a terminal session from the web app with /rc.", |
| 255 | zh: "在本机浏览器标签页中工作,或用 /rc 在网页应用中接着使用终端会话。", |
| 256 | }, |
| 257 | repoSource: "docs/WEB.md", |
| 258 | hasPage: true, |
| 259 | category: "extending", |
| 260 | }, |
| 261 | // Fleet is the canonical customer noun; `/docs/pod` remains a |
| 262 | // permanent compatibility redirect in app/[locale]/docs/pod/page.tsx. |
| 263 | { |
| 264 | id: "computers", |
| 265 | slug: "computers", |
| 266 | label: { en: "Send a task to the cloud", zh: "把任务发送到云端" }, |
| 267 | description: { |
| 268 | en: "Preview: propose, confirm, and track a cloud agent that opens a pull request on GitHub, CNB, or Gitee.", |
| 269 | zh: "预览版:提议、确认并跟踪一个在 GitHub、CNB 或 Gitee 上提交拉取请求的云端 Agent。", |
| 270 | }, |
| 271 | repoSource: ["docs/DAYTONA_CLOUD_DISPATCH.md", "docs/CODEWHALE_AGENT.md"], |
| 272 | hasPage: true, |
| 273 | category: "extending", |
| 274 | }, |
| 275 | { |
| 276 | id: "troubleshooting", |
| 277 | slug: "troubleshooting", |
| 278 | label: { en: "Fix a problem", zh: "排查问题" }, |
| 279 | description: { |
| 280 | en: "Diagnose in one command, then fix install, key, network, stuck-turn, session, and MCP problems.", |
| 281 | zh: "用一条命令诊断,再解决安装、密钥、网络、回合卡住、会话和 MCP 等问题。", |
| 282 | }, |
| 283 | repoSource: ["docs/OPERATIONS_RUNBOOK.md", "docs/DOCKER.md"], |
| 284 | hasPage: true, |
| 285 | category: "operations", |
| 286 | }, |
| 287 | { |
| 288 | id: "contribution", |
| 289 | slug: "contribution", |
| 290 | label: { en: "Contribute", zh: "参与贡献" }, |
| 291 | description: { |
| 292 | en: "The contributing guide, agent ethos, contributor credits, and release process.", |
| 293 | zh: "贡献指南、Agent 准则、贡献者致谢和发布流程。", |
| 294 | }, |
| 295 | repoSource: [ |
| 296 | "CONTRIBUTING.md", |
| 297 | "docs/AGENT_ETHOS.md", |
| 298 | "docs/CONTRIBUTORS.md", |
| 299 | "docs/RELEASE_CHECKLIST.md", |
| 300 | ], |
| 301 | hasPage: false, |
| 302 | category: "operations", |
| 303 | }, |
| 304 | { |
| 305 | id: "vocabulary", |
| 306 | slug: "vocabulary", |
| 307 | label: { en: "Product terms", zh: "产品名词" }, |
| 308 | description: { |
| 309 | en: "Fleet, Workflow, Lane, and Runtime; Plan, Work, and Operate — each in one sentence.", |
| 310 | zh: "Fleet、Workflow、Lane 与 Runtime;Plan、Work 与 Operate——各用一句话说明。", |
| 311 | }, |
| 312 | repoSource: ["docs/FLEET.md", "docs/MODES.md", "docs/public-surface-facts.json"], |
| 313 | hasPage: true, |
| 314 | category: "reference", |
| 315 | }, |
| 316 | { |
| 317 | id: "constitution", |
| 318 | slug: "constitution", |
| 319 | label: { en: "Constitution", zh: "宪章" }, |
| 320 | description: { |
| 321 | en: "What the agent treats as law: built-in rules, your personal constitution, and a repository's own.", |
| 322 | zh: "Agent 视为准则的内容:内置规则、你的个人宪章,以及仓库自己的宪章。", |
| 323 | }, |
| 324 | repoSource: "docs/ARCHITECTURE.md", |
| 325 | hasPage: true, |
| 326 | sitePath: "constitution", |
| 327 | category: "reference", |
| 328 | }, |
| 329 | { |
| 330 | id: "tools", |
| 331 | slug: "tools", |
| 332 | label: { en: "Built-in tools", zh: "内置工具" }, |
| 333 | description: { |
| 334 | en: "The small set of tools every session starts with, and how Codewhale finds the rest.", |
| 335 | zh: "每个会话默认携带的少量工具,以及 Codewhale 如何按需找到其余工具。", |
| 336 | }, |
| 337 | repoSource: ["docs/TOOL_SURFACE.md", "docs/RUNTIME_SIMPLIFICATION_DESIGN.md"], |
| 338 | hasPage: true, |
| 339 | category: "reference", |
| 340 | }, |
| 341 | ]; |
| 342 | |
| 343 | /** Convenience lookup. */ |
| 344 | export function getTopic(id: string): DocTopic | undefined { |
| 345 | return DOC_TOPICS.find((t) => t.id === id); |
| 346 | } |
| 347 | |
| 348 | /** Group topics by category for sidebar rendering. */ |
| 349 | export function getTopicsByCategory(): Map<DocTopic["category"], DocTopic[]> { |
| 350 | const map = new Map<DocTopic["category"], DocTopic[]>(); |
| 351 | for (const t of DOC_TOPICS) { |
| 352 | const group = map.get(t.category) ?? []; |
| 353 | group.push(t); |
| 354 | map.set(t.category, group); |
| 355 | } |
| 356 | return map; |
| 357 | } |
| 358 | |
| 359 | /** Resolve a topic to its on-site route or canonical repository document. */ |
| 360 | export function docTopicHref(topic: DocTopic, locale: string): string { |
| 361 | if (topic.sitePath) return `/${locale}/${topic.sitePath}`; |
| 362 | if (topic.hasPage) return `/${locale}/docs/${topic.slug}`; |
| 363 | const source = Array.isArray(topic.repoSource) ? topic.repoSource[0] : topic.repoSource; |
| 364 | return `${REPO_DOCS_BASE}/${source}`; |
| 365 | } |
| 366 | |
| 367 | /** Whether following a topic leaves codewhale.net for the source document. */ |
| 368 | export function docTopicIsExternal(topic: DocTopic): boolean { |
| 369 | return !topic.hasPage; |
| 370 | } |
| 371 | |
| 372 | /** Repo source base URL for generating direct links. */ |
| 373 | export const REPO_DOCS_BASE = "https://github.com/codewhale-hq/CodeWhale/blob/main"; |
| 374 |