| 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 | export const DOC_TOPICS: DocTopic[] = [ |
| 34 | { |
| 35 | id: "install", |
| 36 | slug: "install", |
| 37 | label: { en: "Install", zh: "安装" }, |
| 38 | description: { |
| 39 | en: "npm, Cargo, Homebrew, Docker, prebuilt binaries, CNB mirror, and where config lives.", |
| 40 | zh: "npm、Cargo、Homebrew、Docker、预编译二进制、CNB 镜像,以及配置文件位置。", |
| 41 | }, |
| 42 | repoSource: "docs/INSTALL.md", |
| 43 | hasPage: true, |
| 44 | sitePath: "install", |
| 45 | category: "getting-started", |
| 46 | }, |
| 47 | { |
| 48 | id: "guide", |
| 49 | slug: "guide", |
| 50 | label: { en: "User Guide", zh: "使用指南" }, |
| 51 | description: { |
| 52 | en: "First run, sessions, commands, keyboard shortcuts, and everyday workflows.", |
| 53 | zh: "首次运行、会话、命令、快捷键和日常使用流程。", |
| 54 | }, |
| 55 | repoSource: ["docs/GUIDE.md", "docs/KEYBINDINGS.md"], |
| 56 | hasPage: true, |
| 57 | category: "getting-started", |
| 58 | }, |
| 59 | { |
| 60 | id: "vocabulary", |
| 61 | slug: "vocabulary", |
| 62 | label: { en: "Vocabulary", zh: "产品名词" }, |
| 63 | description: { |
| 64 | en: "The exact product nouns — Fleet, Workflow, Lane, Runtime; Plan / Act / Operate; Consultant; and explicit route provenance — plus measurement principles.", |
| 65 | zh: "确切的产品名词——Fleet、Workflow、Lane、Runtime;Plan / Act / Operate;Consultant;明确的路由来源——以及测量原则。", |
| 66 | }, |
| 67 | repoSource: ["docs/FLEET.md", "docs/MODES.md", "docs/public-surface-facts.json"], |
| 68 | hasPage: true, |
| 69 | category: "core-concepts", |
| 70 | }, |
| 71 | { |
| 72 | id: "configuration", |
| 73 | slug: "configuration", |
| 74 | label: { en: "Configuration", zh: "配置" }, |
| 75 | description: { |
| 76 | en: "config.toml reference, environment variables, project overrides, and legacy paths.", |
| 77 | zh: "config.toml 参考、环境变量、项目覆盖和旧版路径。", |
| 78 | }, |
| 79 | repoSource: ["docs/CONFIGURATION.md", "docs/LEGACY_PATHS.md"], |
| 80 | hasPage: true, |
| 81 | category: "getting-started", |
| 82 | }, |
| 83 | { |
| 84 | id: "providers", |
| 85 | slug: "providers", |
| 86 | label: { en: "Providers & Models", zh: "提供商与模型" }, |
| 87 | description: { |
| 88 | en: "Supported providers, model switching, local runtimes (vLLM, Ollama, SGLang), and Model Lab.", |
| 89 | zh: "支持的提供商、模型切换、本地运行时(vLLM、Ollama、SGLang)和模型实验室。", |
| 90 | }, |
| 91 | repoSource: ["docs/PROVIDERS.md", "docs/MODEL_LAB.md"], |
| 92 | hasPage: true, |
| 93 | sitePath: "models", |
| 94 | category: "reference", |
| 95 | }, |
| 96 | { |
| 97 | id: "constitution", |
| 98 | slug: "constitution", |
| 99 | label: { en: "Constitution", zh: "嵌套宪法" }, |
| 100 | description: { |
| 101 | en: "Agent identity, authority hierarchy, evidence rules, and the nested law system.", |
| 102 | zh: "Agent 自我模型、权威层次、证据规则和嵌套法律系统。", |
| 103 | }, |
| 104 | repoSource: "docs/ARCHITECTURE.md", |
| 105 | hasPage: true, |
| 106 | category: "core-concepts", |
| 107 | }, |
| 108 | { |
| 109 | id: "modes", |
| 110 | slug: "modes", |
| 111 | label: { en: "Modes", zh: "模式" }, |
| 112 | description: { |
| 113 | en: "Plan, Act, Operate modes and orthogonal permission posture.", |
| 114 | zh: "Plan、Act、Operate 三种模式与正交权限姿态。", |
| 115 | }, |
| 116 | repoSource: "docs/MODES.md", |
| 117 | hasPage: true, |
| 118 | category: "core-concepts", |
| 119 | }, |
| 120 | { |
| 121 | id: "tools", |
| 122 | slug: "tools", |
| 123 | label: { en: "Tools", zh: "工具" }, |
| 124 | description: { |
| 125 | en: "Canonical action tools, deferred discovery, and replay compatibility.", |
| 126 | zh: "Canonical action 工具、延迟发现与回放兼容边界。", |
| 127 | }, |
| 128 | repoSource: ["docs/TOOL_SURFACE.md", "docs/RUNTIME_SIMPLIFICATION_DESIGN.md"], |
| 129 | hasPage: true, |
| 130 | category: "core-concepts", |
| 131 | }, |
| 132 | { |
| 133 | id: "work", |
| 134 | slug: "work", |
| 135 | label: { en: "Work Surface", zh: "工作面板" }, |
| 136 | description: { |
| 137 | en: "The sole canonical To-do ledger, model-facing Work grounding, and how work state flows to the sidebar, relay, and sub-agents.", |
| 138 | zh: "唯一的 To-do 台账、模型可见的 Work grounding,以及工作状态如何流向侧栏、relay 和子 Agent。", |
| 139 | }, |
| 140 | repoSource: ["docs/TOOL_SURFACE.md", "docs/TOOL_LIFECYCLE.md"], |
| 141 | hasPage: true, |
| 142 | category: "core-concepts", |
| 143 | }, |
| 144 | { |
| 145 | id: "subagents", |
| 146 | slug: "subagents", |
| 147 | label: { en: "Sub-Agents", zh: "子 Agent" }, |
| 148 | description: { |
| 149 | en: "Parallel execution, role types, transcript handles, and nesting.", |
| 150 | zh: "并行执行、角色类型、transcript 句柄和嵌套。", |
| 151 | }, |
| 152 | repoSource: "docs/SUBAGENTS.md", |
| 153 | hasPage: true, |
| 154 | category: "core-concepts", |
| 155 | }, |
| 156 | { |
| 157 | id: "mcp", |
| 158 | slug: "mcp", |
| 159 | label: { en: "MCP", zh: "MCP" }, |
| 160 | description: { |
| 161 | en: "Model Context Protocol — consuming and exposing tools via stdio and HTTP/SSE.", |
| 162 | zh: "Model Context Protocol — 通过 stdio 和 HTTP/SSE 消费和暴露工具。", |
| 163 | }, |
| 164 | repoSource: "docs/MCP.md", |
| 165 | hasPage: true, |
| 166 | category: "extending", |
| 167 | }, |
| 168 | { |
| 169 | id: "hooks", |
| 170 | slug: "hooks", |
| 171 | label: { en: "Hooks", zh: "钩子" }, |
| 172 | description: { |
| 173 | en: "Lifecycle hooks for pre/post tool execution, mode changes, and session events.", |
| 174 | zh: "工具执行前后、模式切换和会话事件的生命周期钩子。", |
| 175 | }, |
| 176 | repoSource: ["docs/rfcs/1364-hooks-lifecycle.md", "docs/CONFIGURATION.md"], |
| 177 | hasPage: true, |
| 178 | category: "extending", |
| 179 | }, |
| 180 | { |
| 181 | id: "sandbox", |
| 182 | slug: "sandbox", |
| 183 | label: { en: "Sandbox & Approval", zh: "沙箱与审批" }, |
| 184 | description: { |
| 185 | en: "Available Seatbelt (macOS), opt-in bubblewrap (Linux), platform gaps, and approval policies.", |
| 186 | zh: "可用的 Seatbelt(macOS)、显式启用的 bubblewrap(Linux)、平台缺口和审批策略。", |
| 187 | }, |
| 188 | repoSource: "docs/SANDBOX.md", |
| 189 | hasPage: true, |
| 190 | category: "core-concepts", |
| 191 | }, |
| 192 | { |
| 193 | id: "runtime-api", |
| 194 | slug: "runtime-api", |
| 195 | label: { en: "Runtime API", zh: "运行时 API" }, |
| 196 | description: { |
| 197 | en: "Public HTTP API for integrations, bridges, and automation.", |
| 198 | zh: "用于集成、桥接和自动化的公开 HTTP API。", |
| 199 | }, |
| 200 | repoSource: "docs/RUNTIME_API.md", |
| 201 | hasPage: true, |
| 202 | category: "extending", |
| 203 | }, |
| 204 | { |
| 205 | id: "web", |
| 206 | slug: "web", |
| 207 | label: { en: "Browser Client", zh: "浏览器客户端" }, |
| 208 | description: { |
| 209 | en: "Run the embedded browser client on loopback, with its one-time bootstrap and session boundaries.", |
| 210 | zh: "仅在本机回环地址运行内置浏览器客户端,了解一次性引导与会话边界。", |
| 211 | }, |
| 212 | repoSource: "docs/WEB.md", |
| 213 | hasPage: true, |
| 214 | category: "extending", |
| 215 | }, |
| 216 | { |
| 217 | id: "fleet", |
| 218 | slug: "fleet", |
| 219 | label: { en: "Fleet / Workflow", zh: "Fleet / Workflow" }, |
| 220 | description: { |
| 221 | en: "Durable task execution, fleet management, and Workflow authoring.", |
| 222 | zh: "持久任务执行、Fleet 管理和 Workflow 编写。", |
| 223 | }, |
| 224 | repoSource: ["docs/FLEET.md", "docs/WORKFLOW_AUTHORING.md"], |
| 225 | hasPage: true, |
| 226 | category: "operations", |
| 227 | }, |
| 228 | { |
| 229 | id: "troubleshooting", |
| 230 | slug: "troubleshooting", |
| 231 | label: { en: "Troubleshooting", zh: "排障" }, |
| 232 | description: { |
| 233 | en: "Common issues, diagnostics, operations runbook, and Docker notes.", |
| 234 | zh: "常见问题、诊断、运维手册和 Docker 说明。", |
| 235 | }, |
| 236 | repoSource: ["docs/OPERATIONS_RUNBOOK.md", "docs/DOCKER.md"], |
| 237 | hasPage: true, |
| 238 | category: "operations", |
| 239 | }, |
| 240 | { |
| 241 | id: "contribution", |
| 242 | slug: "contribution", |
| 243 | label: { en: "Contribution", zh: "贡献" }, |
| 244 | description: { |
| 245 | en: "Contributing guide, agent ethos, contributor credits, and release process.", |
| 246 | zh: "贡献指南、Agent 伦理、贡献者致谢和发布流程。", |
| 247 | }, |
| 248 | repoSource: [ |
| 249 | "CONTRIBUTING.md", |
| 250 | "docs/AGENT_ETHOS.md", |
| 251 | "docs/CONTRIBUTORS.md", |
| 252 | "docs/RELEASE_CHECKLIST.md", |
| 253 | ], |
| 254 | hasPage: false, |
| 255 | category: "operations", |
| 256 | }, |
| 257 | ]; |
| 258 | |
| 259 | /** Convenience lookup. */ |
| 260 | export function getTopic(id: string): DocTopic | undefined { |
| 261 | return DOC_TOPICS.find((t) => t.id === id); |
| 262 | } |
| 263 | |
| 264 | /** Group topics by category for sidebar rendering. */ |
| 265 | export function getTopicsByCategory(): Map<string, DocTopic[]> { |
| 266 | const map = new Map<string, DocTopic[]>(); |
| 267 | for (const t of DOC_TOPICS) { |
| 268 | const group = map.get(t.category) ?? []; |
| 269 | group.push(t); |
| 270 | map.set(t.category, group); |
| 271 | } |
| 272 | return map; |
| 273 | } |
| 274 | |
| 275 | /** Resolve a topic to its on-site route or canonical repository document. */ |
| 276 | export function docTopicHref(topic: DocTopic, locale: string): string { |
| 277 | if (topic.sitePath) return `/${locale}/${topic.sitePath}`; |
| 278 | if (topic.hasPage) return `/${locale}/docs/${topic.slug}`; |
| 279 | const source = Array.isArray(topic.repoSource) ? topic.repoSource[0] : topic.repoSource; |
| 280 | return `${REPO_DOCS_BASE}/${source}`; |
| 281 | } |
| 282 | |
| 283 | /** Whether following a topic leaves codewhale.net for the source document. */ |
| 284 | export function docTopicIsExternal(topic: DocTopic): boolean { |
| 285 | return !topic.hasPage; |
| 286 | } |
| 287 | |
| 288 | /** Repo source base URL for generating direct links. */ |
| 289 | export const REPO_DOCS_BASE = "https://github.com/Hmbown/CodeWhale/blob/main"; |
| 290 |