From 899037ad42838ffcf1c46ef936826b41caae8d56 Mon Sep 17 00:00:00 2001 From: CodeWhale Agent Date: Thu, 18 Jun 2026 13:20:45 -0700 Subject: [PATCH 1/3] docs: add v0.8.63 wiki and orchestration terminology --- README.md | 12 +- docs/AGENT_RUNTIME.md | 5 + docs/FLEET.md | 34 +- docs/ORCHESTRATION_TERMINOLOGY.md | 88 ++ docs/SUBAGENTS.md | 8 +- docs/WHALEFLOW_AUTHORING.md | 6 +- docs/WORKROOM_ARCHITECTURE.md | 5 + web/app/[locale]/wiki/[slug]/page.tsx | 408 +++++++++ web/app/[locale]/wiki/page.tsx | 108 +++ web/app/sitemap.ts | 13 +- web/components/nav.tsx | 4 +- web/lib/wiki.ts | 160 ++++ wiki/01-overview.md | 172 ++++ wiki/02-crate-reference.md | 468 +++++++++++ wiki/03-agent-system.md | 994 ++++++++++++++++++++++ wiki/04-tool-system.md | 922 +++++++++++++++++++++ wiki/05-rlm-system.md | 619 ++++++++++++++ wiki/06-whaleflow.md | 1098 +++++++++++++++++++++++++ wiki/07-configuration.md | 291 +++++++ wiki/08-web-layer.md | 273 ++++++ wiki/09-operations.md | 325 ++++++++ wiki/10-constitution.md | 327 ++++++++ wiki/11-skills-system.md | 444 ++++++++++ wiki/12-fleet-system.md | 669 +++++++++++++++ wiki/13-additional-tools.md | 726 ++++++++++++++++ wiki/14-systems-internals.md | 548 ++++++++++++ wiki/README.md | 120 +++ 27 files changed, 8823 insertions(+), 24 deletions(-) create mode 100644 docs/ORCHESTRATION_TERMINOLOGY.md create mode 100644 web/app/[locale]/wiki/[slug]/page.tsx create mode 100644 web/app/[locale]/wiki/page.tsx create mode 100644 web/lib/wiki.ts create mode 100644 wiki/01-overview.md create mode 100644 wiki/02-crate-reference.md create mode 100644 wiki/03-agent-system.md create mode 100644 wiki/04-tool-system.md create mode 100644 wiki/05-rlm-system.md create mode 100644 wiki/06-whaleflow.md create mode 100644 wiki/07-configuration.md create mode 100644 wiki/08-web-layer.md create mode 100644 wiki/09-operations.md create mode 100644 wiki/10-constitution.md create mode 100644 wiki/11-skills-system.md create mode 100644 wiki/12-fleet-system.md create mode 100644 wiki/13-additional-tools.md create mode 100644 wiki/14-systems-internals.md create mode 100644 wiki/README.md diff --git a/README.md b/README.md index 00f44d57d..d4ebe4e3a 100644 --- a/README.md +++ b/README.md @@ -131,8 +131,8 @@ one you want isn't here, that's a good issue to open. ChatGPT/Codex CLI login (working). Routing is more than a base URL swap: `/reasoning` effort is translated into -each provider's wire dialect, sub-agent tiers resolve per provider, and the -system prompt's model facts are templated per-model instead of hardcoded. +each provider's wire dialect, delegated Agent tiers resolve per provider, and +the system prompt's model facts are templated per-model instead of hardcoded. Switch mid-session with `/provider` and `/model`. The full registry — credentials, base URLs, capability boundaries — lives in [docs/PROVIDERS.md](docs/PROVIDERS.md). @@ -231,11 +231,13 @@ The README is the short version. The rest is in docs and on - [User guide](docs/GUIDE.md) · [Install guide](docs/INSTALL.md) · [Configuration](docs/CONFIGURATION.md) · [Provider registry](docs/PROVIDERS.md) - [Modes](docs/MODES.md) — Agent, Plan, and YOLO. -- [Sub-agents](docs/SUBAGENTS.md) — roles, lifecycle, output contract, and - recovery behavior. +- [Agents and Workflows terminology](docs/ORCHESTRATION_TERMINOLOGY.md) — + the public naming model for delegated work and durable orchestration. +- [Agents](docs/SUBAGENTS.md) — delegated roles, lifecycle, output contract, + and recovery behavior. - [Architecture](docs/ARCHITECTURE.md) — crate layout, runtime flow, tool system, extension points, and security model. -- [Fleet](docs/FLEET.md) · [WhaleFlow authoring](docs/WHALEFLOW_AUTHORING.md) · +- [Agent control plane](docs/FLEET.md) · [Workflow authoring](docs/WHALEFLOW_AUTHORING.md) · [MCP](docs/MCP.md) · [Runtime API](docs/RUNTIME_API.md) · [Model Lab](docs/MODEL_LAB.md) - [Keybindings](docs/KEYBINDINGS.md) · [Sandbox & approvals](docs/SANDBOX.md) diff --git a/docs/AGENT_RUNTIME.md b/docs/AGENT_RUNTIME.md index 03baeb065..c45ab90d3 100644 --- a/docs/AGENT_RUNTIME.md +++ b/docs/AGENT_RUNTIME.md @@ -1,5 +1,10 @@ # The CodeWhale Agent Runtime — one durable substrate, familiar launchers +> Public naming: CodeWhale exposes **Agents** for delegated work and +> **Workflows** for durable multi-agent plans. `sub-agent`, `Fleet`, and +> `WhaleFlow` remain implementation names. See +> [Orchestration Terminology](ORCHESTRATION_TERMINOLOGY.md). + This document explains how sub-agents, the headless `exec` path, and Agent Fleet relate. It exists because these had drifted into *two* parallel "worker" systems, and the fix is to make the **fleet-backed worker run** the durable diff --git a/docs/FLEET.md b/docs/FLEET.md index a01afa605..93dff40c0 100644 --- a/docs/FLEET.md +++ b/docs/FLEET.md @@ -1,4 +1,8 @@ -# Agent Fleet +# Agent Control Plane + +> Public naming: this is the **Agent control plane**. `Fleet` is the internal +> scheduler/ledger/host-transport name and the current CLI namespace. See +> [Orchestration Terminology](ORCHESTRATION_TERMINOLOGY.md). Agent Fleet is the local-first control plane for durable multi-worker runs. It is **not** a separate execution engine: a fleet worker is a headless @@ -28,25 +32,27 @@ Fleet state is stored under the workspace in `.codewhale/fleet.jsonl`. Worker logs and adapter logs are stored under `.codewhale/fleet/` and `.codewhale/fleet-host/`. -## Naming: Modes, WhaleFlow, Fleet, and Swarm +## Naming: Agents, Workflows, Fleet, and Swarm -These names describe different layers, not competing systems. Agent, Plan, and -YOLO stay the permission/work modes. WhaleFlow is an orchestration overlay that -can run on top of those modes when the task needs a continuous workflow. +These names describe different layers, not competing product concepts. Agent, +Plan, and YOLO stay the permission/work modes. Publicly, CodeWhale has +**Agents** for delegated work and **Workflows** for durable multi-agent plans. -- **WhaleFlow** is the repeatable workflow plan and user-facing orchestration - overlay: a script/IR that decides which phases and agents run next, keeps - intermediate results out of the main conversation, and can be inspected or - rerun. A WhaleFlow run should have a visible progress view and a clear active - header state instead of feeling like a hidden background task. -- **Fleet** is the execution substrate: headless workers, local/SSH hosts, +- **Agents** are delegated workers with roles, model routes, permissions, + transcripts, and status. +- **Workflows** are repeatable orchestration plans that decide which phases and + Agents run next, keep intermediate results out of the main conversation, and + can be inspected or rerun. +- **Fleet** is the Agent control plane: headless workers, local/SSH hosts, trust policy, leases, heartbeats, logs, receipts, and status APIs. -- **Swarm** is the high-fanout behavior inside WhaleFlow. It is gated in +- **WhaleFlow** is the Workflow engine: typed IR, authoring, validation, and + replay. +- **Swarm** is high-fanout Workflow behavior. It is gated in v0.8.61: `/swarm` must not revive prompt-only sub-agent fanout. It should - compile into a WhaleFlow-backed fleet run once the durable worker and goal + compile into a Workflow-backed Agent run once the durable worker and goal re-dispatch substrate is available. -UI guidance: keep the main transcript calm. A WhaleFlow run should appear as a +UI guidance: keep the main transcript calm. A Workflow run should appear as a compact progress card plus Work/Agents sidebar rows with phase names, worker counts, receipts, and nested indentation for child workers. Use the whale mark sparingly as an active header/status signal; avoid repeating emoji-heavy rows diff --git a/docs/ORCHESTRATION_TERMINOLOGY.md b/docs/ORCHESTRATION_TERMINOLOGY.md new file mode 100644 index 000000000..bcccd672d --- /dev/null +++ b/docs/ORCHESTRATION_TERMINOLOGY.md @@ -0,0 +1,88 @@ +# Orchestration Terminology + +CodeWhale should expose two orchestration concepts in user-facing copy: + +1. **Agents** +2. **Workflows** + +Everything else is an implementation layer, compatibility alias, or architecture +detail. + +## Public Names + +### Agents + +An **Agent** is delegated work with its own role, lifecycle, model route, tool +permissions, transcript, and status. + +Use **Agents** for: + +- child or delegated work launched from a parent session +- background workers +- role-based scouts, reviewers, implementers, and verifiers +- local or remote workers launched by the durable control plane +- status/sidebar rows that show running delegated work + +Public examples: + +- "Open an Agent to review this diff." +- "Agents can run locally or remotely." +- "Agents report receipts, artifacts, and status back to the parent." + +### Workflows + +A **Workflow** is a repeatable multi-step plan that orchestrates agents and +control-flow nodes. + +Use **Workflows** for: + +- DAGs, phases, branches, reductions, loops, and tournaments +- replayable multi-agent plans +- teacher review and promotion gates +- durable orchestration that spans many agents or runs +- user-authored `.workflow.*`, Starlark, JSON, or TOML specs + +Public examples: + +- "Run a Workflow to audit the release." +- "Workflows orchestrate Agents through repeatable plans." +- "Workflow replay verifies the same plan without live model calls." + +## Internal Names + +| Internal name | Public framing | Notes | +|---|---|---| +| `sub-agent` / `subagent` | Agent, child Agent | Keep in code identifiers, config keys, compatibility docs, and protocol fields. Avoid as the headline product term. | +| `Fleet` | Agent control plane | Fleet is the scheduler, ledger, host transport, receipt store, and durable worker substrate for Agents. | +| `WhaleFlow` | Workflow engine | WhaleFlow is the Rust IR/compiler/replay engine behind Workflows. | +| `Workroom` | collaboration context | Workrooms organize threads, links, events, and shared visibility. They are not a third orchestration concept. | +| `/swarm` | high-fanout Workflow behavior | Keep gated or compatibility-only until it compiles into Workflow-backed Agent runs. | + +## Naming Rules + +- Prefer **Agents** and **Workflows** in website, README, wiki, release notes, + screenshots, and first-run UI. +- Use internal names only when explaining source modules, config compatibility, + protocol types, or migration details. +- When an internal name appears, define it through the two public names: + "Fleet is the Agent control plane" or "WhaleFlow is the Workflow engine." +- Do not present Fleet, WhaleFlow, Workrooms, sub-agents, and swarm as five + separate product concepts. +- Keep stable commands and config keys until a separate compatibility issue + intentionally renames them. + +## Recommended Surface Map + +| Surface | Preferred label | Compatibility details | +|---|---|---| +| Sidebar panel | Agents | Existing `/subagents` may remain as an alias. | +| Config UI section | Agents | Existing `[subagents]` keys remain stable. | +| Workflow authoring docs | Workflows | Mention WhaleFlow once as the engine name. | +| Fleet docs | Agent control plane | Keep `codewhale fleet` as the CLI implementation surface. | +| Workroom docs | Collaboration context | Keep workroom links/protocol language for architecture docs. | +| Slash command docs | `/agents`, `/workflows` direction | Existing `/agent`, `/subagents`, `/fleet`, `/swarm` require compatibility planning before renaming. | + +## One-Sentence Product Description + +CodeWhale has two orchestration concepts: **Agents** for delegated work, and +**Workflows** for durable multi-agent plans. diff --git a/docs/SUBAGENTS.md b/docs/SUBAGENTS.md index bbd371cca..d27ba1d7f 100644 --- a/docs/SUBAGENTS.md +++ b/docs/SUBAGENTS.md @@ -1,4 +1,8 @@ -# Sub-Agents +# Agents + +> Public naming: **Agents** are delegated workers. The codebase and some +> compatibility surfaces still use `sub-agent` / `subagent` for the current +> implementation. See [Orchestration Terminology](ORCHESTRATION_TERMINOLOGY.md). Sub-agents are the user-facing vocabulary for nested worker assignments: a parent launches a focused role (`explore`, `review`, `implementer`, `verifier`, @@ -18,7 +22,7 @@ cutover completes. It can still be useful for short in-session delegation, but if a child fails once on a transient provider timeout while an equivalent fleet worker would retry from the ledger, that is a runtime unification gap. For work that must survive provider hiccups, process restarts, sleep, or remote -execution, prefer Fleet or a WhaleFlow-backed fleet run. +execution, prefer the Agent control plane or a Workflow-backed Agent run. Sub-agents inherit the parent's tool registry by default, but child agents are leaf workers: they do not receive `agent` or nested lifecycle tools. `agent` diff --git a/docs/WHALEFLOW_AUTHORING.md b/docs/WHALEFLOW_AUTHORING.md index 04bd24830..5b07e9295 100644 --- a/docs/WHALEFLOW_AUTHORING.md +++ b/docs/WHALEFLOW_AUTHORING.md @@ -1,4 +1,8 @@ -# WhaleFlow Authoring +# Workflow Authoring + +> Public naming: **Workflows** are the user-facing concept. `WhaleFlow` is the +> internal Workflow engine and crate name. See +> [Orchestration Terminology](ORCHESTRATION_TERMINOLOGY.md). WhaleFlow has one runtime boundary: authored workflow source lowers to typed Rust `WorkflowSpec`, Rust validates the IR, and the scheduler/headless worker diff --git a/docs/WORKROOM_ARCHITECTURE.md b/docs/WORKROOM_ARCHITECTURE.md index 227e8ea68..765b87d1d 100644 --- a/docs/WORKROOM_ARCHITECTURE.md +++ b/docs/WORKROOM_ARCHITECTURE.md @@ -1,5 +1,10 @@ # Workroom Architecture +> Public naming: Workrooms are collaboration contexts. They organize threads, +> links, events, and shared visibility; they are not a third orchestration +> concept beside **Agents** and **Workflows**. See +> [Orchestration Terminology](ORCHESTRATION_TERMINOLOGY.md). + ## Purpose Workrooms are CodeWhale's chat-native abstraction for durable, addressable diff --git a/web/app/[locale]/wiki/[slug]/page.tsx b/web/app/[locale]/wiki/[slug]/page.tsx new file mode 100644 index 000000000..df52049fe --- /dev/null +++ b/web/app/[locale]/wiki/[slug]/page.tsx @@ -0,0 +1,408 @@ +import { readFile } from "node:fs/promises"; +import path from "node:path"; +import type { ReactNode } from "react"; +import Link from "next/link"; +import { notFound } from "next/navigation"; +import { Seal } from "@/components/seal"; +import { buildPageMetadata } from "@/lib/page-meta"; +import { + getWikiPage, + WIKI_PAGES, + wikiHref, + wikiStatusClass, + wikiStatusLabel, + type WikiPage, +} from "@/lib/wiki"; + +const wikiRoot = path.join(process.cwd(), "..", "wiki"); + +export function generateStaticParams() { + return WIKI_PAGES.map((page) => ({ slug: page.slug })); +} + +export async function generateMetadata({ + params, +}: { + params: Promise<{ locale: string; slug: string }>; +}) { + const { locale, slug } = await params; + const page = getWikiPage(slug); + const isZh = locale === "zh"; + return buildPageMetadata({ + path: `/wiki/${slug}`, + locale, + title: page ? `${page.title} · CodeWhale Wiki` : "Wiki · CodeWhale", + description: page + ? isZh + ? page.cn + : page.summary + : isZh + ? "CodeWhale 源码地图章节。" + : "A CodeWhale source-map chapter.", + }); +} + +async function readWikiMarkdown(page: WikiPage): Promise { + return readFile(path.join(wikiRoot, page.file), "utf8"); +} + +function normalizeWikiHref(href: string, locale: string): string | null { + if (href.startsWith("#") || href.startsWith("http://") || href.startsWith("https://")) { + return href; + } + + const [rawPath, hash] = href.split("#", 2); + const filename = rawPath.split("/").pop()?.replace(/^\.\//, ""); + const page = filename ? WIKI_PAGES.find((candidate) => candidate.file === filename) : undefined; + if (!page) return null; + + return `${wikiHref(locale, page)}${hash ? `#${hash}` : ""}`; +} + +function renderInline(text: string, locale: string): ReactNode[] { + const parts = text.split(/(`[^`]+`|\*\*[^*]+\*\*|\[[^\]]+\]\([^)]+\))/g); + return parts.filter(Boolean).map((part, index) => { + if (part.startsWith("`") && part.endsWith("`")) { + return ( + + {part.slice(1, -1)} + + ); + } + + if (part.startsWith("**") && part.endsWith("**")) { + return {renderInline(part.slice(2, -2), locale)}; + } + + const linkMatch = part.match(/^\[([^\]]+)\]\(([^)]+)\)$/); + if (linkMatch) { + const href = normalizeWikiHref(linkMatch[2], locale); + if (!href) { + return {renderInline(linkMatch[1], locale)}; + } + const external = href.startsWith("http://") || href.startsWith("https://"); + if (external) { + return ( + + {renderInline(linkMatch[1], locale)} + + ); + } + return ( + + {renderInline(linkMatch[1], locale)} + + ); + } + + return part; + }); +} + +function headingId(text: string): string { + return text + .toLowerCase() + .replace(/`([^`]+)`/g, "$1") + .replace(/[^a-z0-9\u4e00-\u9fff]+/g, "-") + .replace(/^-+|-+$/g, ""); +} + +function renderHeading(level: number, text: string, key: number, locale: string) { + const id = headingId(text); + const content = renderInline(text, locale); + if (level <= 1) { + return ( +

+ {content} +

+ ); + } + if (level === 2) { + return ( +

+ {content} +

+ ); + } + if (level === 3) { + return ( +

+ {content} +

+ ); + } + return ( +

+ {content} +

+ ); +} + +function parseTableRow(line: string): string[] { + const row = line.trim().replace(/^\|/, "").replace(/\|$/, ""); + const cells: string[] = []; + let current = ""; + + for (let index = 0; index < row.length; index += 1) { + const char = row[index]; + if (char === "\\" && row[index + 1] === "|") { + current += "|"; + index += 1; + continue; + } + if (char === "|") { + cells.push(current.trim()); + current = ""; + continue; + } + current += char; + } + + cells.push(current.trim()); + return cells; +} + +function isTableSeparator(line: string): boolean { + return /^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(line); +} + +function isBlockStart(line: string, nextLine = ""): boolean { + const trimmed = line.trim(); + return ( + trimmed.startsWith("```") || + /^#{1,6}\s+/.test(trimmed) || + /^-{3,}$/.test(trimmed) || + trimmed.startsWith(">") || + /^[-*]\s+/.test(trimmed) || + /^\d+\.\s+/.test(trimmed) || + (trimmed.startsWith("|") && isTableSeparator(nextLine)) + ); +} + +function renderMarkdown(markdown: string, locale: string): ReactNode[] { + const lines = markdown.replace(/\r\n/g, "\n").split("\n"); + const blocks: ReactNode[] = []; + let i = 0; + + while (i < lines.length) { + const line = lines[i]; + const trimmed = line.trim(); + if (!trimmed) { + i += 1; + continue; + } + + if (trimmed.startsWith("```")) { + const language = trimmed.slice(3).trim(); + const code: string[] = []; + i += 1; + while (i < lines.length && !lines[i].trim().startsWith("```")) { + code.push(lines[i]); + i += 1; + } + i += 1; + blocks.push( +
+          {code.join("\n")}
+        
, + ); + continue; + } + + const heading = trimmed.match(/^(#{1,6})\s+(.+)$/); + if (heading) { + blocks.push(renderHeading(heading[1].length, heading[2], blocks.length, locale)); + i += 1; + continue; + } + + if (/^-{3,}$/.test(trimmed)) { + blocks.push(
); + i += 1; + continue; + } + + if (trimmed.startsWith(">")) { + const quote: string[] = []; + while (i < lines.length && lines[i].trim().startsWith(">")) { + quote.push(lines[i].trim().replace(/^>\s?/, "")); + i += 1; + } + blocks.push( +
+

{renderInline(quote.join(" "), locale)}

+
, + ); + continue; + } + + if (trimmed.startsWith("|") && isTableSeparator(lines[i + 1] ?? "")) { + const rows: string[][] = [parseTableRow(lines[i])]; + i += 2; + while (i < lines.length && lines[i].trim().startsWith("|")) { + rows.push(parseTableRow(lines[i])); + i += 1; + } + const [header, ...body] = rows; + blocks.push( +
+ + + + {header.map((cell, cellIndex) => ( + + ))} + + + + {body.map((row, rowIndex) => ( + + {row.map((cell, cellIndex) => ( + + ))} + + ))} + +
+ {renderInline(cell, locale)} +
+ {renderInline(cell, locale)} +
+
, + ); + continue; + } + + if (/^[-*]\s+/.test(trimmed)) { + const items: string[] = []; + while (i < lines.length && /^[-*]\s+/.test(lines[i].trim())) { + items.push(lines[i].trim().replace(/^[-*]\s+/, "")); + i += 1; + } + blocks.push( + , + ); + continue; + } + + if (/^\d+\.\s+/.test(trimmed)) { + const items: string[] = []; + while (i < lines.length && /^\d+\.\s+/.test(lines[i].trim())) { + items.push(lines[i].trim().replace(/^\d+\.\s+/, "")); + i += 1; + } + blocks.push( +
    + {items.map((item, itemIndex) => ( +
  1. + {renderInline(item, locale)} +
  2. + ))} +
, + ); + continue; + } + + const paragraph: string[] = []; + while (i < lines.length && lines[i].trim() && !isBlockStart(lines[i], lines[i + 1] ?? "")) { + paragraph.push(lines[i].trim()); + i += 1; + } + blocks.push( +

+ {renderInline(paragraph.join(" "), locale)} +

, + ); + } + + return blocks; +} + +export default async function WikiChapterPage({ + params, +}: { + params: Promise<{ locale: string; slug: string }>; +}) { + const { locale, slug } = await params; + const page = getWikiPage(slug); + if (!page) notFound(); + + const markdown = await readWikiMarkdown(page); + const pageIndex = WIKI_PAGES.findIndex((candidate) => candidate.slug === page.slug); + const previous = WIKI_PAGES[pageIndex - 1]; + const next = WIKI_PAGES[pageIndex + 1]; + const isZh = locale === "zh"; + + return ( + <> +
+
+ +
{isZh ? "Wiki · 章节" : "Wiki · Chapter"}
+
+

+ {page.title}{" "} + + {wikiStatusLabel(page.status, isZh)} + +

+

+ {isZh ? page.cn : page.summary} +

+
+ + {isZh ? "返回 Wiki" : "Back to Wiki"} + + {previous && ( + + {isZh ? "上一章" : "Previous"} · {previous.id} + + )} + {next && ( + + {isZh ? "下一章" : "Next"} · {next.id} + + )} +
+
+ +
+ +
{renderMarkdown(markdown, locale)}
+
+ + ); +} diff --git a/web/app/[locale]/wiki/page.tsx b/web/app/[locale]/wiki/page.tsx new file mode 100644 index 000000000..f14c2ec66 --- /dev/null +++ b/web/app/[locale]/wiki/page.tsx @@ -0,0 +1,108 @@ +import Link from "next/link"; +import { Seal } from "@/components/seal"; +import { buildPageMetadata } from "@/lib/page-meta"; +import { WIKI_PAGES, wikiHref, wikiStatusClass, wikiStatusLabel } from "@/lib/wiki"; + +export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) { + const { locale } = await params; + const isZh = locale === "zh"; + return buildPageMetadata({ + path: "/wiki", + locale, + title: isZh ? "Wiki · CodeWhale" : "Wiki · CodeWhale", + description: isZh + ? "CodeWhale 由递归子 Agent 生成的源码地图:架构、工具、RLM、Whaleflow、Fleet 与运行时内部机制。" + : "The recursive sub-agent generated source map for CodeWhale: architecture, tools, RLM, Whaleflow, Fleet, and runtime internals.", + }); +} + +export default async function WikiPage({ params }: { params: Promise<{ locale: string }> }) { + const { locale } = await params; + const isZh = locale === "zh"; + + return ( + <> +
+
+ +
{isZh ? "Section 03 · 源码地图" : "Section 03 · Source Map"}
+
+

+ Wiki {isZh ? "源码地图" : "Source Map"} +

+

+ {isZh + ? "这套 wiki 是用 CodeWhale 自己的递归子 Agent 系统从源码生成的。它适合做维护者地图:哪些系统已经上线,哪些只是协议或实验性运行时。" + : "This wiki was generated from the source by CodeWhale's own recursive sub-agent system. Treat it as a maintainer map: what is live, what is protocol-level, and what is still experimental runtime work."} +

+
+ + {isZh ? "阅读第一章" : "Read Chapter 01"} + + + {isZh ? "返回文档" : "Back to Docs"} + +
+
+ +
+ {WIKI_PAGES.map((page) => ( + +
+
{page.id}
+
+ {wikiStatusLabel(page.status, isZh)} +
+
+

{page.title}

+

+ {isZh ? page.cn : page.summary} +

+
+ {page.file} -> +
+ + ))} +
+ +
+
+
+
{isZh ? "发布边界" : "Release Boundary"}
+

+ {isZh ? "0.8.63 应该发布地图,不应该夸大运行时。" : "0.8.63 should ship the map, not overstate the runtime."} +

+

+ {isZh + ? "子 Agent、RLM、skills、hooks、MCP、sandbox 与 snapshot 是实际可用的基础。Whaleflow、Fleet 和 Workroom 页面保留实验性标签,直到 core/TUI/runtime API 真的调用这些路径。" + : "Sub-agents, RLM, skills, hooks, MCP, sandboxing, and snapshots are usable foundations today. Whaleflow, Fleet, and Workroom pages keep experimental labels until core, TUI, and Runtime API paths actually execute them."} +

+
+
+
+
+ {isZh ? "建议位置" : "Recommended Location"} +
+
/wiki
+

+ {isZh + ? "网站展示索引、状态和章节正文;Markdown 仍作为源码随仓库一起审查和打 tag。" + : "The site shows the index, status, and chapter content; Markdown stays in the repository as reviewed, tagged source."} +

+
+
+
+
+ + ); +} diff --git a/web/app/sitemap.ts b/web/app/sitemap.ts index cf361c109..0341ff7bf 100644 --- a/web/app/sitemap.ts +++ b/web/app/sitemap.ts @@ -1,10 +1,21 @@ import type { MetadataRoute } from "next"; import { locales } from "@/lib/i18n/config"; import { SITE_URL } from "@/lib/page-meta"; +import { WIKI_PAGES } from "@/lib/wiki"; // Public, indexable routes (locale-prefixed). /admin and /api are // intentionally excluded; see app/robots.ts. -const PATHS = ["", "/install", "/docs", "/faq", "/roadmap", "/feed", "/contribute"]; +const PATHS = [ + "", + "/install", + "/docs", + "/wiki", + ...WIKI_PAGES.map((page) => `/wiki/${page.slug}`), + "/faq", + "/roadmap", + "/feed", + "/contribute", +]; export default function sitemap(): MetadataRoute.Sitemap { const lastModified = new Date(); diff --git a/web/components/nav.tsx b/web/components/nav.tsx index f9f143a6a..9b823c940 100644 --- a/web/components/nav.tsx +++ b/web/components/nav.tsx @@ -9,6 +9,7 @@ import { MobileMenu } from "./mobile-menu"; const EN_LINKS = [ { href: "/en/install", label: "Install", cn: "安装" }, { href: "/en/docs", label: "Docs", cn: "文档" }, + { href: "/en/wiki", label: "Wiki", cn: "源码" }, { href: "/en/feed", label: "Activity", cn: "动态" }, { href: "/en/roadmap", label: "Roadmap", cn: "路线" }, { href: "/en/faq", label: "FAQ", cn: "问答" }, @@ -18,6 +19,7 @@ const EN_LINKS = [ const ZH_LINKS = [ { href: "/zh/install", label: "安装", cn: "" }, { href: "/zh/docs", label: "文档", cn: "" }, + { href: "/zh/wiki", label: "Wiki", cn: "" }, { href: "/zh/feed", label: "动态", cn: "" }, { href: "/zh/roadmap", label: "路线图", cn: "" }, { href: "/zh/faq", label: "常见问题", cn: "" }, @@ -59,7 +61,7 @@ export function Nav({ locale = "en" }: { locale?: Locale }) { -