import { isValidElement, useEffect, useMemo, useRef, useState, type ReactNode, } from "react"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import manifestRaw from "./generated/docs-manifest.json"; type Locale = "en" | "zh"; type ThemeMode = "system" | "dark" | "light"; type ResolvedTheme = "dark" | "light"; type ReaderScale = "compact" | "comfortable" | "relaxed"; type ReaderWidth = "normal" | "wide"; type Journey = | "start" | "build" | "integrate" | "operate" | "secure" | "contribute" | "reference" | "hardware" | "localize" | "troubleshoot"; type Audience = | "newcomer" | "builder" | "operator" | "security" | "contributor" | "integrator" | "hardware"; type DocKind = "guide" | "reference" | "runbook" | "policy" | "template" | "report"; type GroupMode = "journey" | "section" | "kind" | "language"; type ManifestDoc = { id: string; path: string; title: string; summary: string; section: string; language: string; journey: Journey; audience: Audience; kind: DocKind; tags: string[]; readingMinutes: number; startHere: boolean; sourceUrl: string; }; type ManifestDocRaw = Omit< ManifestDoc, "journey" | "audience" | "kind" | "tags" | "readingMinutes" | "startHere" > & Partial< Pick< ManifestDoc, "journey" | "audience" | "kind" | "tags" | "readingMinutes" | "startHere" > >; type HeadingItem = { id: string; level: number; text: string; }; type Localized = Record; type PaletteEntry = { id: string; label: string; hint: string; run: () => void; }; const repoBase = "https://github.com/zeroclaw-labs/zeroclaw/blob/main"; const rawBase = "https://raw.githubusercontent.com/zeroclaw-labs/zeroclaw/main"; const languageNames: Record = { en: { en: "English", zh: "英文" }, "zh-CN": { en: "Chinese (Simplified)", zh: "简体中文" }, ja: { en: "Japanese", zh: "日文" }, ru: { en: "Russian", zh: "俄文" }, fr: { en: "French", zh: "法文" }, vi: { en: "Vietnamese", zh: "越南文" }, el: { en: "Greek", zh: "希腊文" }, }; const journeyOrder: Journey[] = [ "start", "build", "integrate", "operate", "secure", "contribute", "reference", "hardware", "localize", "troubleshoot", ]; const audienceOrder: Audience[] = [ "newcomer", "builder", "integrator", "operator", "security", "contributor", "hardware", ]; const kindOrder: DocKind[] = ["guide", "reference", "runbook", "policy", "template", "report"]; const journeyNames: Record = { start: { en: "Start", zh: "起步" }, build: { en: "Build", zh: "构建" }, integrate: { en: "Integrate", zh: "集成" }, operate: { en: "Operate", zh: "运维" }, secure: { en: "Secure", zh: "安全" }, contribute: { en: "Contribute", zh: "贡献" }, reference: { en: "Reference", zh: "参考" }, hardware: { en: "Hardware", zh: "硬件" }, localize: { en: "Localization", zh: "多语言" }, troubleshoot: { en: "Troubleshoot", zh: "排障" }, }; const audienceNames: Record = { newcomer: { en: "Newcomer", zh: "新手" }, builder: { en: "Builder", zh: "开发者" }, integrator: { en: "Integrator", zh: "集成者" }, operator: { en: "Operator", zh: "运维" }, security: { en: "Security", zh: "安全" }, contributor: { en: "Contributor", zh: "贡献者" }, hardware: { en: "Hardware", zh: "硬件工程师" }, }; const kindNames: Record = { guide: { en: "Guide", zh: "指南" }, reference: { en: "Reference", zh: "参考" }, runbook: { en: "Runbook", zh: "运行手册" }, policy: { en: "Policy", zh: "策略规范" }, template: { en: "Template", zh: "模板" }, report: { en: "Report", zh: "报告" }, }; const readingPaths: Array<{ id: string; label: Localized; detail: Localized; filters: Partial<{ journey: Journey; audience: Audience; kind: DocKind; section: string; }>; }> = [ { id: "newcomer", label: { en: "New to ZeroClaw", zh: "初次了解 ZeroClaw" }, detail: { en: "Onboarding and first successful run in the shortest path.", zh: "最短路径完成安装、配置和首个可运行实例。", }, filters: { journey: "start", audience: "newcomer" }, }, { id: "builder", label: { en: "Build & Extend", zh: "开发与扩展" }, detail: { en: "Commands, config, providers, channels, and architecture references.", zh: "命令、配置、Provider、Channel 与架构参考。", }, filters: { journey: "build", audience: "builder" }, }, { id: "operate", label: { en: "Operate in Production", zh: "生产运维" }, detail: { en: "Runbooks, CI/CD gates, release flow, and observability checks.", zh: "运行手册、CI/CD 门禁、发布流程与可观测性校验。", }, filters: { journey: "operate", audience: "operator" }, }, { id: "secure", label: { en: "Security Hardening", zh: "安全强化" }, detail: { en: "Sandboxing, advisories, and secure runtime baseline.", zh: "沙箱、安全公告与安全运行时基线。", }, filters: { journey: "secure", audience: "security" }, }, { id: "integrate", label: { en: "Integrations", zh: "外部集成" }, detail: { en: "Connect ZeroClaw with chat platforms and external providers.", zh: "将 ZeroClaw 接入聊天平台与外部模型能力。", }, filters: { journey: "integrate", audience: "integrator" }, }, { id: "contribute", label: { en: "Contribute", zh: "贡献流程" }, detail: { en: "Contributor workflow, reviews, and collaboration playbooks.", zh: "贡献者流程、评审规范与协作手册。", }, filters: { journey: "contribute", audience: "contributor" }, }, ]; function asJourney(value: string | undefined): Journey { const candidate = (value ?? "").toLowerCase() as Journey; return journeyOrder.includes(candidate) ? candidate : "build"; } function asAudience(value: string | undefined): Audience { const candidate = (value ?? "").toLowerCase() as Audience; return audienceOrder.includes(candidate) ? candidate : "builder"; } function asKind(value: string | undefined): DocKind { const candidate = (value ?? "").toLowerCase() as DocKind; return kindOrder.includes(candidate) ? candidate : "guide"; } function normalizeManifestDoc(doc: ManifestDocRaw): ManifestDoc { const summary = doc.summary?.trim() || "Project documentation."; const tags = Array.isArray(doc.tags) ? doc.tags .map((tag) => tag.trim().toLowerCase()) .filter((tag) => tag.length > 0) .slice(0, 8) : []; return { ...doc, summary, journey: asJourney(doc.journey), audience: asAudience(doc.audience), kind: asKind(doc.kind), tags, readingMinutes: typeof doc.readingMinutes === "number" && Number.isFinite(doc.readingMinutes) ? Math.max(1, Math.round(doc.readingMinutes)) : 1, startHere: Boolean(doc.startHere), }; } const docs = [...(manifestRaw as ManifestDocRaw[])] .map((doc) => normalizeManifestDoc(doc)) .sort((a, b) => a.path.localeCompare(b.path)); const copy = { en: { navDocs: "Docs", navGitHub: "GitHub", navWebsite: "zeroclawlabs.ai", badge: "PRIVATE AGENT INTELLIGENCE.", title: "Zero overhead. Zero compromise. 100% Rust. 100% Agnostic.", summary: "Fast, small, and fully autonomous AI assistant infrastructure.", summary2: "Deploy anywhere. Swap anything.", notice: "Official source channels: use this repository as the source of truth and zeroclawlabs.ai as the official website.", ctaDocs: "Read docs now", ctaBootstrap: "One-click bootstrap", commandLaneTitle: "Runtime command lane", commandLaneHint: "From official setup and operations flow", engineeringTitle: "Engineering foundations", docsWorkspace: "Documentation Workspace", docsLead: "All repository docs are indexed and readable directly on this GitHub Pages site with engineering-first layout and typography.", docsIndexed: "Indexed", docsFiltered: "Filtered", docsActive: "Active", readingPathsTitle: "Reading paths", readingPathsLead: "Choose a task-oriented route first, then drill down with taxonomy filters.", startHereTitle: "Start here", startHereLead: "Core docs for first-time users who want the fastest reliable onboarding.", noStartHere: "No starter docs matched the current language/filter context.", startBadge: "Starter", sectionFilter: "Section", languageFilter: "Language", journeyFilter: "Journey", audienceFilter: "Audience", kindFilter: "Doc type", groupBy: "Group by", allJourneys: "All journeys", allAudiences: "All audiences", allKinds: "All doc types", groupJourney: "Journey", groupSection: "Section", groupKind: "Doc type", groupLanguage: "Language", resetFilters: "Reset filters", search: "Search docs by title, path, summary, or keyword", commandPalette: "Command palette", sourceLabel: "Source", docJourney: "Journey", docAudience: "Audience", docKind: "Type", docReadTime: "Read time", docTags: "Tags", minuteUnit: "min", relatedDocs: "Related docs", noRelated: "No strongly related docs found yet.", openOnGithub: "Open on GitHub", openRaw: "Open raw", loading: "Loading document...", fallback: "Document preview is unavailable right now. You can still open the source directly:", empty: "No docs matched your current filters.", allSections: "All sections", allLanguages: "All languages", outline: "Outline", noOutline: "No headings found in this document.", reading: "Reading mode", scaleLabel: "Scale", widthLabel: "Width", compact: "Compact", comfortable: "Comfortable", relaxed: "Relaxed", normalWidth: "Normal", wideWidth: "Wide", previousDoc: "Previous", nextDoc: "Next", paletteHint: "Type a command or document name", actionFocus: "Focus docs search", actionTop: "Back to top", actionTheme: "Cycle theme", actionLocale: "Toggle language", status: "Current Theme", }, zh: { navDocs: "文档", navGitHub: "GitHub", navWebsite: "zeroclawlabs.ai", badge: "PRIVATE AGENT INTELLIGENCE.", title: "Zero overhead. Zero compromise. 100% Rust. 100% Agnostic.", summary: "Fast, small, and fully autonomous AI assistant infrastructure.", summary2: "Deploy anywhere. Swap anything.", notice: "官方信息渠道:请以本仓库为事实来源,以 zeroclawlabs.ai 为官方网站。", ctaDocs: "立即阅读文档", ctaBootstrap: "一键安装", commandLaneTitle: "运行命令通道", commandLaneHint: "来自官方安装与运维流程", engineeringTitle: "工程基础", docsWorkspace: "文档工作区", docsLead: "仓库全量文档已建立索引并支持在 GitHub Pages 页面内直接阅读,采用工程化排版与阅读体验。", docsIndexed: "总文档", docsFiltered: "筛选后", docsActive: "当前文档", readingPathsTitle: "阅读路径", readingPathsLead: "先按任务路径进入,再用分类筛选做深入浏览。", startHereTitle: "新手起步", startHereLead: "面向首次接触 ZeroClaw 的核心文档,快速完成有效上手。", noStartHere: "当前语言/筛选条件下暂无起步文档。", startBadge: "起步", sectionFilter: "分组", languageFilter: "语言", journeyFilter: "阶段路径", audienceFilter: "适用角色", kindFilter: "文档类型", groupBy: "分组方式", allJourneys: "全部路径", allAudiences: "全部角色", allKinds: "全部类型", groupJourney: "按路径", groupSection: "按目录", groupKind: "按类型", groupLanguage: "按语言", resetFilters: "重置筛选", search: "按标题、路径、摘要或关键字搜索", commandPalette: "命令面板", sourceLabel: "来源", docJourney: "阶段", docAudience: "角色", docKind: "类型", docReadTime: "阅读时长", docTags: "标签", minuteUnit: "分钟", relatedDocs: "相关推荐", noRelated: "暂未找到高相关文档。", openOnGithub: "在 GitHub 打开", openRaw: "打开原文", loading: "文档加载中...", fallback: "当前无法预览文档,你仍可直接打开源文件:", empty: "当前筛选下没有匹配文档。", allSections: "全部分组", allLanguages: "全部语言", outline: "目录", noOutline: "当前文档没有可提取的标题。", reading: "阅读模式", scaleLabel: "字号", widthLabel: "宽度", compact: "紧凑", comfortable: "舒适", relaxed: "宽松", normalWidth: "标准", wideWidth: "加宽", previousDoc: "上一篇", nextDoc: "下一篇", paletteHint: "输入命令或文档名称", actionFocus: "聚焦文档搜索", actionTop: "回到顶部", actionTheme: "切换主题", actionLocale: "切换语言", status: "当前主题", }, } as const; const commandLane: Array<{ command: string; hint: Localized }> = [ { command: "zeroclaw onboard --interactive", hint: { en: "Generate config and credentials", zh: "生成配置与凭据" }, }, { command: "zeroclaw agent", hint: { en: "Run interactive agent mode", zh: "运行交互式 Agent 模式" }, }, { command: "zeroclaw gateway && zeroclaw daemon", hint: { en: "Start runtime services", zh: "启动运行时服务" }, }, { command: "zeroclaw doctor", hint: { en: "Validate environment and runtime health", zh: "校验环境与运行时健康状态", }, }, ]; const engineeringPillars: Array<{ title: Localized; detail: Localized }> = [ { title: { en: "Trait-driven architecture", zh: "Trait 驱动架构" }, detail: { en: "Providers, channels, tools, memory, and tunnels remain swappable through interfaces.", zh: "Provider、Channel、Tool、Memory、Tunnel 通过接口保持可插拔。", }, }, { title: { en: "Secure by default runtime", zh: "默认安全运行时" }, detail: { en: "Pairing, sandboxing, explicit allowlists, and workspace scoping are baseline controls.", zh: "配对、沙箱、显式白名单与工作区作用域作为基线控制。", }, }, { title: { en: "Build once, run anywhere", zh: "一次构建,到处运行" }, detail: { en: "Single-binary Rust workflow across ARM, x86, and RISC-V from edge to cloud.", zh: "单一 Rust 二进制工作流覆盖 ARM、x86、RISC-V,从边缘到云端。", }, }, ]; function normalizePath(input: string): string { return input .replace(/\\/g, "/") .replace(/^\/+/, "") .replace(/\/+/g, "/") .replace(/^\.\//, ""); } function slugify(text: string): string { return text .toLowerCase() .replace(/<[^>]+>/g, "") .replace(/\[[^\]]+\]\([^)]*\)/g, "") .replace(/[^\w\u4e00-\u9fa5\s-]/g, "") .trim() .replace(/\s+/g, "-") .replace(/-+/g, "-"); } function nodeText(node: ReactNode): string { if (typeof node === "string" || typeof node === "number") { return String(node); } if (Array.isArray(node)) { return node.map((part) => nodeText(part)).join(""); } if (isValidElement(node)) { return nodeText(node.props.children as ReactNode); } return ""; } function encodePathSegments(filePath: string): string { return normalizePath(filePath) .split("/") .map((segment) => encodeURIComponent(segment)) .join("/"); } function docsContentUrl(filePath: string): string { return `${import.meta.env.BASE_URL}docs-content/${encodePathSegments(filePath)}`; } function withRepo(filePath: string): string { return `${repoBase}/${normalizePath(filePath)}`; } function withRaw(filePath: string): string { return `${rawBase}/${normalizePath(filePath)}`; } function cleanHeadingText(raw: string): string { return raw .replace(/`([^`]+)`/g, "$1") .replace(/\[([^\]]+)\]\([^)]*\)/g, "$1") .replace(/\s+#*$/, "") .trim(); } function extractHeadings(markdown: string): HeadingItem[] { const lines = markdown.split(/\r?\n/); const headings: HeadingItem[] = []; const slugCounts = new Map(); let inCode = false; for (const rawLine of lines) { const line = rawLine.trim(); if (line.startsWith("```")) { inCode = !inCode; continue; } if (inCode) { continue; } const match = /^(#{1,3})\s+(.+)$/.exec(line); if (!match) { continue; } const level = match[1].length; const text = cleanHeadingText(match[2]); const base = slugify(text) || `section-${headings.length + 1}`; const seen = (slugCounts.get(base) ?? 0) + 1; slugCounts.set(base, seen); const id = seen === 1 ? base : `${base}-${seen}`; headings.push({ id, level, text }); } return headings; } function inferSectionLabel(section: string, locale: Locale): string { if (section === "root") { return locale === "zh" ? "仓库根目录" : "Repository Root"; } if (section === "docs") { return locale === "zh" ? "文档总览" : "Docs Core"; } if (section.startsWith("i18n/")) { const language = section.split("/")[1] ?? "i18n"; return locale === "zh" ? `多语言 / ${formatLanguage(language, locale)}` : `i18n / ${formatLanguage(language, locale)}`; } const pretty = section.replace(/[-_]/g, " "); return pretty.charAt(0).toUpperCase() + pretty.slice(1); } function formatLanguage(language: string, locale: Locale): string { if (languageNames[language]) { return languageNames[language][locale]; } if (language === "en") { return locale === "zh" ? "英文" : "English"; } return language; } function formatJourney(journey: Journey, locale: Locale): string { return journeyNames[journey][locale]; } function formatAudience(audience: Audience, locale: Locale): string { return audienceNames[audience][locale]; } function formatKind(kind: DocKind, locale: Locale): string { return kindNames[kind][locale]; } function groupLabel(groupBy: GroupMode, key: string, locale: Locale) { if (groupBy === "journey") { return formatJourney(asJourney(key), locale); } if (groupBy === "kind") { return formatKind(asKind(key), locale); } if (groupBy === "language") { return formatLanguage(key, locale); } return inferSectionLabel(key, locale); } function groupOrderIndex(groupBy: GroupMode, key: string): number { if (groupBy === "journey") { return journeyOrder.indexOf(asJourney(key)); } if (groupBy === "kind") { return kindOrder.indexOf(asKind(key)); } if (groupBy === "language") { return key === "en" ? -1 : 0; } if (groupBy === "section") { if (key === "root") return -2; if (key === "docs") return -1; } return 999; } function canonicalDocPath(candidate: string, docSet: Set): string | null { const normalized = normalizePath(candidate); const attempts = new Set([normalized]); if (normalized.endsWith("/")) { attempts.add(`${normalized}README.md`); attempts.add(`${normalized}README.mdx`); } if (!/\.[a-zA-Z0-9]+$/.test(normalized)) { attempts.add(`${normalized}.md`); attempts.add(`${normalized}.mdx`); attempts.add(`${normalized}/README.md`); attempts.add(`${normalized}/README.mdx`); } for (const attempt of attempts) { if (docSet.has(attempt)) { return attempt; } } return null; } function resolveRelativePath(fromPath: string, target: string): { path: string; hash: string; } { const base = new URL(`https://repo.local/${normalizePath(fromPath)}`); const resolved = new URL(target, base); return { path: normalizePath(decodeURIComponent(resolved.pathname)), hash: decodeURIComponent(resolved.hash.replace(/^#/, "")), }; } function getInitialDocPath(docSet: Set): string { if (typeof window === "undefined") { return docs[0]?.path ?? ""; } const url = new URL(window.location.href); const requested = url.searchParams.get("doc"); if (requested) { const decoded = normalizePath(decodeURIComponent(requested)); if (docSet.has(decoded)) { return decoded; } } return docs[0]?.path ?? ""; } export default function App(): JSX.Element { const [locale, setLocale] = useState(() => { if (typeof window === "undefined") { return "en"; } return window.localStorage.getItem("zc-locale") === "zh" ? "zh" : "en"; }); const [themeMode, setThemeMode] = useState(() => { if (typeof window === "undefined") { return "system"; } const stored = window.localStorage.getItem("zc-theme"); if (stored === "light" || stored === "dark" || stored === "system") { return stored; } return "system"; }); const docSet = useMemo(() => new Set(docs.map((doc) => doc.path)), []); const [selectedPath, setSelectedPath] = useState(() => getInitialDocPath(docSet) ); const [resolvedTheme, setResolvedTheme] = useState("dark"); const [query, setQuery] = useState(""); const [sectionFilter, setSectionFilter] = useState("all"); const [languageFilter, setLanguageFilter] = useState("all"); const [journeyFilter, setJourneyFilter] = useState("all"); const [audienceFilter, setAudienceFilter] = useState("all"); const [kindFilter, setKindFilter] = useState("all"); const [groupBy, setGroupBy] = useState("journey"); const [activePathway, setActivePathway] = useState(null); const [markdownCache, setMarkdownCache] = useState>({}); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const [paletteOpen, setPaletteOpen] = useState(false); const [paletteQuery, setPaletteQuery] = useState(""); const [readerScale, setReaderScale] = useState("comfortable"); const [readerWidth, setReaderWidth] = useState("normal"); const [pendingAnchor, setPendingAnchor] = useState(""); const docsSearchRef = useRef(null); const paletteInputRef = useRef(null); const text = copy[locale]; useEffect(() => { window.localStorage.setItem("zc-locale", locale); }, [locale]); useEffect(() => { window.localStorage.setItem("zc-theme", themeMode); const media = window.matchMedia("(prefers-color-scheme: dark)"); const applyTheme = (): void => { const nextTheme: ResolvedTheme = themeMode === "system" ? (media.matches ? "dark" : "light") : themeMode; document.documentElement.setAttribute("data-theme", nextTheme); setResolvedTheme(nextTheme); }; applyTheme(); if (themeMode === "system") { media.addEventListener("change", applyTheme); return () => media.removeEventListener("change", applyTheme); } return undefined; }, [themeMode]); const sectionOptions = useMemo( () => ["all", ...new Set(docs.map((doc) => doc.section))], [] ); const languageOptions = useMemo( () => ["all", ...new Set(docs.map((doc) => doc.language))], [] ); const journeyOptions = useMemo( () => ["all", ...journeyOrder.filter((journey) => docs.some((doc) => doc.journey === journey))], [] ); const audienceOptions = useMemo( () => ["all", ...audienceOrder.filter((audience) => docs.some((doc) => doc.audience === audience))], [] ); const kindOptions = useMemo( () => ["all", ...kindOrder.filter((kind) => docs.some((doc) => doc.kind === kind))], [] ); const filteredDocs = useMemo(() => { const needle = query.trim().toLowerCase(); return docs.filter((doc) => { if (sectionFilter !== "all" && doc.section !== sectionFilter) { return false; } if (languageFilter !== "all" && doc.language !== languageFilter) { return false; } if (journeyFilter !== "all" && doc.journey !== journeyFilter) { return false; } if (audienceFilter !== "all" && doc.audience !== audienceFilter) { return false; } if (kindFilter !== "all" && doc.kind !== kindFilter) { return false; } if (!needle) { return true; } const bag = [ doc.title, doc.summary, doc.path, doc.section, doc.language, doc.journey, doc.audience, doc.kind, doc.tags.join(" "), ] .join(" ") .toLowerCase(); return bag.includes(needle); }); }, [audienceFilter, journeyFilter, kindFilter, languageFilter, query, sectionFilter]); const pathwayStats = useMemo( () => readingPaths.map((pathway) => { const total = docs.filter((doc) => { if (pathway.filters.journey && doc.journey !== pathway.filters.journey) { return false; } if (pathway.filters.audience && doc.audience !== pathway.filters.audience) { return false; } if (pathway.filters.kind && doc.kind !== pathway.filters.kind) { return false; } if (pathway.filters.section && doc.section !== pathway.filters.section) { return false; } return true; }).length; return { ...pathway, total }; }), [] ); const starterDocs = useMemo(() => { const preferredLanguages = locale === "zh" ? ["zh-CN", "en"] : ["en"]; return docs .filter((doc) => doc.startHere) .map((doc) => { const languageRank = preferredLanguages.indexOf(doc.language); return { ...doc, _rank: (languageRank === -1 ? 9 : languageRank) * 100 + journeyOrder.indexOf(doc.journey) * 10 + doc.readingMinutes, }; }) .sort((a, b) => a._rank - b._rank) .slice(0, 8); }, [locale]); const docsByPath = useMemo(() => new Map(docs.map((doc) => [doc.path, doc])), []); const selectedDoc = docsByPath.get(selectedPath) ?? filteredDocs[0] ?? docs[0] ?? null; useEffect(() => { if (!selectedDoc) { return; } if (selectedPath !== selectedDoc.path) { setSelectedPath(selectedDoc.path); } }, [selectedDoc, selectedPath]); useEffect(() => { if (!selectedDoc) { return; } const url = new URL(window.location.href); const current = url.searchParams.get("doc"); if (current !== selectedDoc.path) { url.searchParams.set("doc", selectedDoc.path); window.history.replaceState({}, "", `${url.pathname}?${url.searchParams.toString()}`); } }, [selectedDoc]); useEffect(() => { function onPopState(): void { const url = new URL(window.location.href); const next = url.searchParams.get("doc"); if (!next) { return; } const normalized = normalizePath(decodeURIComponent(next)); if (docSet.has(normalized)) { setSelectedPath(normalized); } } window.addEventListener("popstate", onPopState); return () => window.removeEventListener("popstate", onPopState); }, [docSet]); const activePath = selectedDoc?.path ?? ""; const markdown = markdownCache[activePath] ?? ""; useEffect(() => { if (!selectedDoc) { return; } if (markdownCache[activePath]) { return; } let cancelled = false; const controller = new AbortController(); async function loadDoc(): Promise { setLoading(true); setError(""); const localUrl = docsContentUrl(activePath); const fallbackRawUrl = withRaw(activePath); const tryFetch = async (url: string): Promise => { try { const response = await fetch(url, { signal: controller.signal }); if (!response.ok) { return null; } return await response.text(); } catch { return null; } }; const localContent = await tryFetch(localUrl); const content = localContent ?? (await tryFetch(fallbackRawUrl)); if (cancelled) { return; } if (content === null) { setError("fetch_failed"); setLoading(false); return; } setMarkdownCache((prev) => ({ ...prev, [activePath]: content, })); setLoading(false); } void loadDoc(); return () => { cancelled = true; controller.abort(); }; }, [activePath, markdownCache, selectedDoc]); const headings = useMemo(() => extractHeadings(markdown), [markdown]); useEffect(() => { if (!pendingAnchor) { return; } const timer = window.setTimeout(() => { const target = document.getElementById(pendingAnchor); if (target) { target.scrollIntoView({ behavior: "smooth", block: "start" }); } setPendingAnchor(""); }, 90); return () => window.clearTimeout(timer); }, [headings, pendingAnchor]); const groupedDocs = useMemo(() => { const grouped = new Map(); for (const doc of filteredDocs) { const key = groupBy === "journey" ? doc.journey : groupBy === "kind" ? doc.kind : groupBy === "language" ? doc.language : doc.section; if (!grouped.has(key)) { grouped.set(key, []); } grouped.get(key)?.push(doc); } return [...grouped.entries()] .map(([key, entries]) => [ key, [...entries].sort((a, b) => a.title.localeCompare(b.title)), ] as const) .sort((a, b) => { const aIndex = groupOrderIndex(groupBy, a[0]); const bIndex = groupOrderIndex(groupBy, b[0]); if (aIndex !== bIndex) { return aIndex - bIndex; } return groupLabel(groupBy, a[0], locale).localeCompare(groupLabel(groupBy, b[0], locale)); }); }, [filteredDocs, groupBy, locale]); const currentIndex = filteredDocs.findIndex((doc) => doc.path === activePath); const previousDoc = currentIndex > 0 ? filteredDocs[currentIndex - 1] : null; const nextDoc = currentIndex >= 0 && currentIndex < filteredDocs.length - 1 ? filteredDocs[currentIndex + 1] : null; const relatedDocs = useMemo(() => { if (!selectedDoc) { return []; } const selectedTags = new Set(selectedDoc.tags); return docs .filter((doc) => doc.path !== selectedDoc.path) .map((doc) => { let score = 0; if (doc.journey === selectedDoc.journey) score += 4; if (doc.audience === selectedDoc.audience) score += 3; if (doc.kind === selectedDoc.kind) score += 2; if (doc.section === selectedDoc.section) score += 2; if (doc.language === selectedDoc.language) score += 1; const sharedTags = doc.tags.filter((tag) => selectedTags.has(tag)).length; score += sharedTags * 2; return { doc, score }; }) .filter((entry) => entry.score > 0) .sort((a, b) => { if (b.score !== a.score) { return b.score - a.score; } if (a.doc.readingMinutes !== b.doc.readingMinutes) { return a.doc.readingMinutes - b.doc.readingMinutes; } return a.doc.title.localeCompare(b.doc.title); }) .slice(0, 8) .map((entry) => entry.doc); }, [selectedDoc]); const openDoc = (docPath: string, anchor = ""): void => { if (!docSet.has(docPath)) { return; } setSelectedPath(docPath); if (anchor) { setPendingAnchor(anchor); } }; const cycleTheme = (): void => { setThemeMode((prev) => { if (prev === "system") return "dark"; if (prev === "dark") return "light"; return "system"; }); }; const jumpToTop = (): void => { window.scrollTo({ top: 0, behavior: "smooth" }); }; const focusSearch = (): void => { docsSearchRef.current?.focus(); }; const applyPathway = (pathwayId: string): void => { const pathway = readingPaths.find((entry) => entry.id === pathwayId); if (!pathway) { return; } setActivePathway(pathway.id); setQuery(""); setSectionFilter(pathway.filters.section ?? "all"); setLanguageFilter("all"); setJourneyFilter(pathway.filters.journey ?? "all"); setAudienceFilter(pathway.filters.audience ?? "all"); setKindFilter(pathway.filters.kind ?? "all"); setGroupBy("journey"); }; const resetFilters = (): void => { setActivePathway(null); setQuery(""); setSectionFilter("all"); setLanguageFilter("all"); setJourneyFilter("all"); setAudienceFilter("all"); setKindFilter("all"); setGroupBy("journey"); }; const paletteActions = useMemo( () => [ { id: "focus-search", label: text.actionFocus, hint: text.docsWorkspace, run: () => { document .getElementById("docs-workspace") ?.scrollIntoView({ behavior: "smooth", block: "start" }); setTimeout(() => docsSearchRef.current?.focus(), 220); }, }, { id: "back-top", label: text.actionTop, hint: "Home", run: jumpToTop, }, { id: "toggle-theme", label: text.actionTheme, hint: `${text.status}: ${resolvedTheme}`, run: cycleTheme, }, { id: "toggle-locale", label: text.actionLocale, hint: locale === "en" ? "EN -> 中文" : "中文 -> EN", run: () => setLocale((prev) => (prev === "en" ? "zh" : "en")), }, ], [locale, resolvedTheme, text.actionFocus, text.actionLocale, text.actionTheme, text.actionTop, text.docsWorkspace, text.status] ); const paletteResults = useMemo(() => { const needle = paletteQuery.trim().toLowerCase(); const actionEntries: PaletteEntry[] = paletteActions; const docEntries: PaletteEntry[] = docs .filter((doc) => { if (!needle) { return true; } return [ doc.title, doc.summary, doc.path, doc.section, doc.language, doc.journey, doc.audience, doc.kind, doc.tags.join(" "), ] .join(" ") .toLowerCase() .includes(needle); }) .slice(0, 18) .map((doc) => ({ id: `doc-${doc.id}`, label: doc.title, hint: `${formatJourney(doc.journey, locale)} · ${doc.path}`, run: () => { openDoc(doc.path); document .getElementById("docs-workspace") ?.scrollIntoView({ behavior: "smooth", block: "start" }); }, })); if (!needle) { return [...actionEntries, ...docEntries.slice(0, 10)]; } const matchedActions = actionEntries.filter((entry) => `${entry.label} ${entry.hint}`.toLowerCase().includes(needle) ); return [...matchedActions, ...docEntries]; }, [locale, paletteActions, paletteQuery]); useEffect(() => { function onKeyDown(event: KeyboardEvent): void { const withCommand = (event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k"; if (withCommand) { event.preventDefault(); setPaletteOpen((prev) => !prev); return; } if (event.key === "Escape") { setPaletteOpen(false); } } window.addEventListener("keydown", onKeyDown); return () => window.removeEventListener("keydown", onKeyDown); }, []); useEffect(() => { if (paletteOpen) { setTimeout(() => paletteInputRef.current?.focus(), 0); } else { setPaletteQuery(""); } }, [paletteOpen]); if (!selectedDoc) { return
; } let headingRenderIndex = 0; return (
ZeroClaw
{(["system", "dark", "light"] as ThemeMode[]).map((mode) => ( ))}

{text.badge}

{text.title}

{text.summary}

{text.summary2}

{text.notice}

Runtime Memory

< 5MB

Cold Start

< 10ms

Edge Hardware

$10-class

Docs Indexed

{docs.length}

{text.engineeringTitle}

{engineeringPillars.map((pillar) => (

{pillar.title[locale]}

{pillar.detail[locale]}

))}

{text.docsWorkspace}

{text.docsLead}

{text.docsIndexed}: {docs.length} {text.docsFiltered}: {filteredDocs.length} {text.docsActive}: {selectedDoc.title} {activePathway ? ( {text.readingPathsTitle}:{" "} {readingPaths.find((entry) => entry.id === activePathway)?.label[locale] ?? "-"} ) : null}

{text.readingPathsTitle}

{text.readingPathsLead}

{pathwayStats.map((pathway) => ( ))}

{text.startHereTitle}

{text.startHereLead}

{starterDocs.length === 0 ? (

{text.noStartHere}

) : ( starterDocs.map((doc) => ( )) )}
{ setActivePathway(null); setQuery(event.target.value); }} placeholder={text.search} aria-label={text.search} />

{text.sourceLabel}

{formatJourney(selectedDoc.journey, locale)} / {inferSectionLabel(selectedDoc.section, locale)} / {selectedDoc.title}

{selectedDoc.title}

{activePath}
{text.docJourney}: {formatJourney(selectedDoc.journey, locale)} {text.docAudience}:{" "} {formatAudience(selectedDoc.audience, locale)} {text.docKind}: {formatKind(selectedDoc.kind, locale)} {text.docReadTime}: {selectedDoc.readingMinutes}{" "} {text.minuteUnit}
{selectedDoc.tags.length > 0 ? (
{selectedDoc.tags.map((tag) => ( {tag} ))}
) : null}
{loading ?

{text.loading}

: null} {!loading && error ? (

{text.fallback} {withRepo(activePath)}

) : null} {!loading && !error && markdown ? (
{ const id = headings[headingRenderIndex]?.id ?? slugify(nodeText(children)); headingRenderIndex += 1; return

{children}

; }, h2: ({ children }) => { const id = headings[headingRenderIndex]?.id ?? slugify(nodeText(children)); headingRenderIndex += 1; return

{children}

; }, h3: ({ children }) => { const id = headings[headingRenderIndex]?.id ?? slugify(nodeText(children)); headingRenderIndex += 1; return

{children}

; }, a: ({ href, children }) => { const target = href ?? ""; if (!target) { return {children}; } if (target.startsWith("#")) { const anchor = decodeURIComponent(target.replace(/^#/, "")); return ( { event.preventDefault(); setPendingAnchor(anchor); }} > {children} ); } if (/^[a-z]+:/i.test(target)) { return ( {children} ); } const resolved = resolveRelativePath(activePath, target); const docPath = canonicalDocPath(resolved.path, docSet); if (docPath) { const hrefDoc = `?doc=${encodeURIComponent(docPath)}`; const hrefAnchor = resolved.hash ? `#${encodeURIComponent(resolved.hash)}` : ""; return ( { event.preventDefault(); openDoc(docPath, resolved.hash); }} > {children} ); } const looksLikeAsset = resolved.path.startsWith("docs/") || /\.(png|jpe?g|gif|webp|svg|avif|txt|toml|json|yaml|yml)$/i.test( resolved.path ); if (looksLikeAsset) { return ( {children} ); } return ( {children} ); }, img: ({ src, alt }) => { const original = src ?? ""; if (!original) { return null; } if (/^https?:\/\//i.test(original) || original.startsWith("data:")) { return {alt; } const resolved = resolveRelativePath(activePath, original); const localAsset = docsContentUrl(resolved.path); return ( {alt { (event.currentTarget as HTMLImageElement).src = withRaw( resolved.path ); }} /> ); }, }} > {markdown}
) : null}

ZeroClaw · Trait-driven architecture · secure-by-default runtime · pluggable everything

{paletteOpen ? (
setPaletteOpen(false)}>
event.stopPropagation()} > setPaletteQuery(event.target.value)} onKeyDown={(event) => { if (event.key === "Enter" && paletteResults[0]) { paletteResults[0].run(); setPaletteOpen(false); } }} placeholder={text.paletteHint} aria-label={text.paletteHint} />
{paletteResults.slice(0, 16).map((entry) => ( ))}
) : null}
); }