# Silen > A calm, React-first documentation engine powered by Vite, MDX, and AI-ready content. # Agent Contract The Agent Contract is a versioned, inspectable discovery layer. It keeps AI clients from guessing configuration fields, CLI syntax, MCP permissions, or deployed site routes. ## Installed package contract For creating or maintaining a local project, start at: ```text @aicode-nexus/silen/agent/manifest.json ``` The package manifest points to the exact version’s configuration API, CLI and MCP contracts, public TypeScript exports, guide, and task playbooks. For example, `agent/tasks/create-site.md` describes the supported activation path and links back to authoritative machine-readable resources rather than copying their definitions. ## Deployed site contract Each enabled production build publishes a site-specific entry point at `/.well-known/silen/manifest.json`, resolved under `base`. This official site’s live contract is [the Silen manifest](/silen/.well-known/silen/manifest.json). The manifest schema has no deployment origin field. It describes the base, language, resources, tasks, and public project guidance. Resource and task URLs remain base-relative. ```ts ai: { contract: { enabled: true, instructions: '.silen/ai-public.md', tasksDir: '.silen/ai-tasks', }, } ``` Instructions and tasks are explicit public build input. Do not include local absolute paths, secrets, private endpoints, credentials, or unpublished operating details. ## Schema version 2 The current manifest and API documents use `schemaVersion: 2`. The manifest's MCP capability declares `stdio`, protocol versions `2025-11-25` and `2026-07-28`, an empty extension list, local-only operation, read-only default, and the `--allow-write` gate. The API document adds an `outputSchema` for every tool. Successful MCP calls expose the corresponding schema-validated `structuredContent` alongside text. This contract does not advertise remote transport or optional MCP extensions. Those capabilities require separate designs and authorization. The package also contains the generated filesystem Skill at `dist/agent/skills/silen-docs-readonly`, and the CLI API records `silen ai skills` plus `--experimental-skills-over-mcp`. The default manifest still says `extensions: []` because an optional runtime flag is not a site capability. Skill text is procedural knowledge: it does not grant a host permission to run commands, use the network, write files, commit, push, or deploy. ## Client behavior Codex, Claude Code, Cursor, and other clients should consume the same manifest instead of keeping client-specific API copies. When a client does not support the declared contract schema, it must follow linked public Markdown and remain read-only. For deployed content, the site manifest is authoritative; for code generation against an installed package, the package contract is authoritative. Continue with the [local workspace and MCP](/silen/ai/local-workspace-mcp/). # AI-ready documentation Silen treats AI access as part of the documentation build instead of an afterthought. The default output is deterministic, inspectable, and does not call a model. No model, API key, endpoint, embeddings service, or network is required for the core AI-ready documentation workflow. ## Agent Contract Silen gives an AI one versioned discovery entry point instead of making every client memorize a separate tutorial: - For a local project, begin with `@aicode-nexus/silen/agent/manifest.json` from the installed package. It links to the exact config, CLI, MCP, and public TypeScript API plus task playbooks such as `agent/tasks/create-site.md`. - For a deployed site, begin with `/.well-known/silen/manifest.json`. This official site publishes it at `/silen/.well-known/silen/manifest.json`. - For bounded local reads, start `pnpm silen mcp docs`. It is read-only unless the user explicitly adds `--allow-write`. Codex, Claude Code, and Cursor should all read that same manifest and use the same local MCP command. Client setup stays thin; the contract remains the single API reference. If a client does not support the declared schema version, it must fall back to the linked public Markdown and remain read-only. The current manifest and API use `schemaVersion: 2`. They declare local `stdio`, verified protocol versions `2025-11-25` and `2026-07-28`, an empty extension set, and every MCP tool's `outputSchema`. ## Read-only Agent Skill The npm package deterministically generates one `silen-docs-readonly` Agent Skill from the canonical English and Chinese `read-site` and `audit-site` task packs. Its package root is `dist/agent/skills/silen-docs-readonly`; it contains `SKILL.md` plus four progressively loaded references and no scripts, assets, write tasks, model calls, credentials, or implied permissions. ```sh pnpm silen ai skills ./agent-skills ``` The command creates only `./agent-skills/silen-docs-readonly` and refuses to overwrite an existing directory. The filesystem form is the supported portable surface and remains usable offline. ## Add public project instructions Only publish instructions that are safe for every site visitor: ```ts export default defineConfig({ ai: { contract: { instructions: '.silen/ai-public.md', tasksDir: '.silen/ai-tasks', }, }, }) ``` These files become explicit public Agent instructions. Never place private paths, secrets, internal endpoints, or credentials in them. ## Public AI artifacts Each production build can emit: - `llms.txt` for a concise page map - `llms-full.txt` for complete readable content - `ai-index.json` for structured discovery - clean Markdown routes for every public page Pages marked `draft: true` or `ai: false` are excluded from these artifacts. ## Copy for AI The default theme lets readers copy clean page Markdown or a prompt-ready version with the canonical source URL. The copied content comes from the same build artifacts, so it stays aligned with the rendered page. ## Local MCP workspace ```sh pnpm silen ai init docs pnpm silen ai index docs pnpm silen ai audit docs pnpm silen ai eval docs pnpm silen mcp docs ``` The MCP server uses the split SDK v2 and is read-only by default. Write tools appear only when it is started explicitly with `--allow-write`, and all writes remain inside the Markdown workspace. Successful calls return text plus schema-validated `structuredContent`; remote transport is not enabled. ## Model-free quality gate Use the production search index itself as a deterministic retrieval contract: ```sh pnpm silen build docs pnpm silen ai audit docs pnpm silen ai eval docs ``` `ai eval` reads the committed `.silen/ai-evals.json` suite and the built `.silen/dist/search-index.json`; it never calls a model or the network. Exit codes `0`, `1`, and `2` mean pass, retrieval failure, and setup failure. Version 1 keeps whole-`topK` matching. Version 2 adds optional `expected.maxRank` and reports its effective value plus `matchedRank`. Strict `"schemaVersion": 3` requires both target arrays and an explicit rank bound: ```json { "schemaVersion": 3, "topK": 5, "cases": [ { "id": "install-quick-start", "query": "How do I install and start a site?", "expected": { "acceptable": [ { "route": "/guide/", "heading": "Quick start" }, { "route": "/guide/cli-deployment/" } ], "forbidden": [{ "route": "/draft-notes/" }], "maxRank": 1 } } ] } ``` `acceptable` and `forbidden` are both present arrays with zero to 20 targets; at least one must be non-empty. At least one acceptable target must appear at or before `maxRank`, and every forbidden target must stay out of the diagnostic Top K. A negative-only case uses `acceptable: []` and `maxRank: topK`. Unknown fields, overlapping targets, an empty combined target set, and invalid bounds are setup errors. Version 3 keeps authored case order and exposes `matchedRank` plus `forbiddenMatches`; v1 and v2 JSON and human output remain compatible. For this repository, `pnpm site:ai-check` runs build, audit, evaluation, and source-map checks once. It saves the exact JSON report to `artifacts/ai-eval/site-ai-eval.json` for CI, Pages, and release comparison. The rebuildable `.silen/ai/index.json` workspace snapshot is optional. A missing or stale snapshot appears as an audit notice while MCP search continues to run from its in-memory index. ## Ask AI Ask AI is an optional endpoint integration. Silen never places provider keys in the generated site: your server owns authentication and streams a small NDJSON protocol back to the theme. With no explicitly configured endpoint, the Ask AI control and its bundle remain absent. Return to the [getting started guide](/silen/guide/). # Local workspace and MCP The local AI workspace is deterministic and model-free. It gives tools a bounded Markdown root, an inspectable index, and explicit write permission without exposing arbitrary shell execution. No model, API key, endpoint, embeddings service, or network is required. ## Initialize, index, and audit ```sh pnpm silen ai init docs pnpm silen ai index docs pnpm silen ai audit docs pnpm silen ai eval docs ``` `ai init` creates `wiki/` and the ignored `.silen/ai/` cache without changing existing MDX. `ai index` rebuilds the optional `.silen/ai/index.json` workspace snapshot. `ai audit` checks links, citations, generated artifacts, and the production contract. A missing or stale snapshot is only a notice because MCP search uses an in-memory index. ## Build, audit, and evaluate ```sh pnpm silen build docs pnpm silen ai audit docs pnpm silen ai eval docs ``` `ai eval` reads `.silen/ai-evals.json` and the production `.silen/dist/search-index.json`; it neither starts MCP nor calls a model or the network. Version 1 uses one route and optional heading within `topK`. Version 2 adds optional `expected.maxRank`. Strict `"schemaVersion": 3` requires present `acceptable` and `forbidden` arrays, at least one target between them, and an explicit `maxRank` from 1 through `topK`. Negative-only cases use `acceptable: []` and `maxRank: topK`. Version 3 reports `matchedRank: null` when no acceptable target appears and lists prohibited hits in `forbiddenMatches`. Exit `0` means every case passed, exit `1` means a retrieval expectation failed, and exit `2` means the suite or input is invalid. The full diagnostic Top K remains in stable case order. For the Silen repository, `pnpm site:ai-check` composes the complete read-only gate and saves exact evaluation JSON at `artifacts/ai-eval/site-ai-eval.json`. The optional `.silen/ai/index.json` snapshot remains non-blocking and does not replace the production search index. ## Connect an MCP client Run the server from the repository root: ```json { "mcpServers": { "silen": { "command": "pnpm", "args": ["silen", "mcp", "docs"] } } } ``` The default server registers seven read-only tools: `guide`, `list`, `search`, `read`, `backlinks`, `citations`, and `build`. The `build` tool is a bounded preflight: it reads Markdown inputs and existing artifacts but does not load project config, execute MDX, invoke Vite, or write files. ## Protocol and structured results The command uses the stable split TypeScript SDK v2. One `stdio` entry accepts verified legacy `2025-11-25` and modern `2026-07-28` clients; see the [official protocol-version guide](https://ts.sdk.modelcontextprotocol.io/v2/protocol-versions). The server is read-only by default. Every successful tool call includes text and schema-validated `structuredContent`, and every listed tool declares an `outputSchema`. Remote transport is not enabled. For the string-valued `guide` tool, modern clients receive the native string; legacy clients receive the SDK's compatibility `{ result: ... }` object. The object-valued tools keep their existing structured shape in both eras. ## Experimental Skills over MCP Filesystem installation does not require MCP. Hosts that explicitly support the draft Resources binding can opt into the same packaged bytes: ```sh pnpm silen mcp docs --experimental-skills-over-mcp ``` The experiment declares `io.modelcontextprotocol/skills`, serves `skill://index.json`, and maps the five files beneath `skill://silen-docs-readonly/`. It is local stdio only and read-only. The experiment is off by default. It adds no tools, scripts, subscriptions, network transport, or write authority; `--allow-write` remains a separate explicit tool-registration flag. ## Grant writes deliberately ```sh pnpm silen mcp docs --allow-write ``` This explicit flag adds `write`, `link`, and `append`. Writes accept only workspace-relative `.md` or `.mdx` paths, reject traversal and escaping symlinks, use atomic replacement, and enforce a 2 MiB UTF-8 limit. It never adds a shell tool. Grant write mode only to a trusted local client for a bounded task. After a change, run the audit and site build, inspect the Git diff, and obtain separate authorization before committing or deploying. Ask AI is separate: it requires an explicitly configured endpoint. With no endpoint, Silen emits neither the control nor its bundle. Read [Agent Contract](/silen/ai/agent-contract/) for client discovery rules. # CLI and deployment Silen exposes a small CLI. Run it through the project package manager so the command and Agent Contract always match the installed version. ## Primary commands ```sh pnpm silen init docs pnpm silen dev docs --host 127.0.0.1 --port 5173 pnpm silen build docs pnpm silen preview docs --port 4173 ``` `init ` writes a starter config and homepage without replacing existing targets. `dev [root]` starts Vite-backed development. `build [root]` creates the static output and exits after validation. `preview [root]` serves that output with route and locale-aware 404 behavior. The server commands accept `--host` and `--port`; the build has no deployment side effects. AI workspace commands are separate: ```sh pnpm silen ai init docs pnpm silen ai index docs pnpm silen ai audit docs pnpm silen ai eval docs pnpm silen ai skills ./agent-skills pnpm silen mcp docs ``` `ai skills` requires the parent destination, creates only `silen-docs-readonly`, and never overwrites it; optional MCP Resource exposure uses `pnpm silen mcp docs --experimental-skills-over-mcp` and remains experimental and off by default. The MCP command is read-only unless a trusted user explicitly starts it with `--allow-write`. The model-free `ai eval` command reads `.silen/ai-evals.json` and `.silen/dist/search-index.json`; use `--json` for CI. It needs no model, API key, endpoint, embeddings service, or network. Suite `"schemaVersion": 1` retains whole-`topK` matching. Version 2 supports case-specific `expected.maxRank`, defaulting to `topK`, and reports `matchedRank` while preserving the full diagnostic result list. ## Static deployment Publish the contents of `docs/.silen/dist` to any static host. Configure the host to serve generated `index.html` files and assets as written. For a project site such as `https://example.github.io/handbook/`, use: ```ts export default defineConfig({ siteUrl: 'https://example.github.io', base: '/handbook/', }) ``` Do not repeat `/handbook/` in `siteUrl`. The build combines the origin and base for canonical URLs, `hreflang` and `x-default` locale alternates, sitemap entries, and basic Open Graph/Twitter metadata. Markdown and Agent Contract URLs remain base-relative. ## Release check Repository maintainers run one canonical command: ```sh pnpm site:ai-check ``` It executes `site:build` -> `ai audit` -> `ai eval` -> `check:no-maps` once and in order. `pnpm site:check` is a compatibility alias. Core CI, GitHub Pages, and npm release all use the canonical command; an audit or evaluation failure blocks deployment or publication. The official `.silen/ai-evals.json` uses `"schemaVersion": 3`, explicit `maxRank`, and present `acceptable` and `forbidden` target arrays. Reports keep the diagnostic `topK`, stable `matchedRank`, and forbidden evidence. Each workflow uploads `artifacts/ai-eval/site-ai-eval.json` with an always condition when the evaluator produced valid JSON, including retrieval failures or a later source-map failure. Then preview a nested route directly, open a missing route, and inspect `llms.txt` plus `.well-known/silen/manifest.json`. A successful build proves files were generated; those direct checks prove the host serves them at the expected base. Ask AI remains endpoint-only. If no endpoint is configured, its control and bundle are absent. Use [Reference](/silen/reference/) for command syntax and troubleshooting. # Configuration Create `.silen/config.ts` in the content root and export `defineConfig(...)`. The file is trusted project code; keep secrets out because values can affect public HTML and build artifacts. ```ts import { defineConfig } from '@aicode-nexus/silen' export default defineConfig({ title: 'Engineering handbook', description: 'Operating knowledge for the product team.', lang: 'en-US', base: '/handbook/', siteUrl: 'https://docs.example.com', outDir: '.silen/dist', onBrokenLinks: 'error', }) ``` ## URL and metadata fields `base` is the normalized absolute pathname where the site is mounted; use `/` for a domain root or `/handbook/` for a subpath. `siteUrl` is only the HTTP(S) origin—put the deployment path in `base`, not in `siteUrl`. Together they drive canonical links, `hreflang` and `x-default` locale alternates, the sitemap, and basic Open Graph/Twitter metadata. Markdown and Agent Contract URLs remain base-relative. `lang` is a BCP 47 language tag. ## Navigation and locales `themeConfig.nav` and `themeConfig.sidebar` accept `{ text, link }` entries. Root-relative theme links are resolved under `base`. Locale entries can provide a `root`, translated navigation, sidebar, home hero, and message overrides: ```ts themeConfig: { locales: [ { lang: 'en-US', label: 'English', root: '/' }, { lang: 'zh-CN', label: '中文', root: '/zh/' }, ], search: true, } ``` Keep locale route trees mirrored so the language switch can preserve the current route rather than returning to a homepage. ## Integrations and AI `analytics` configures Google, Baidu, or custom scripts. `plugins` is an ordered array of trusted plugin factories. The `ai` booleans control `llms.txt`, `llms-full.txt`, Markdown routes, and `ai-index.json`; all default to enabled. The Agent Contract is also enabled by default and can include explicit public instructions and tasks. ```ts ai: { llmsTxt: true, llmsFullTxt: true, markdownRoutes: true, index: true, contract: { enabled: true, instructions: '.silen/ai-public.md' }, } ``` See the complete field table in [Reference](/silen/reference/) and integration examples in [Integrations](/silen/integrations/). # Quick start Silen turns a directory of Markdown and MDX into a server-rendered static site, local search, and deterministic AI-readable output. Use Node.js `^20.19.0 || >=22.12.0`. ## Install and activate From your project root, install Silen, then activate a `docs` directory: ```sh pnpm add -D @aicode-nexus/silen pnpm silen init docs ``` Silen installs its required `react` and `react-dom` runtime, including MDX's `react/jsx-runtime`, automatically. `init` creates `docs/.silen/config.ts` and `docs/index.mdx`. It is safe for a new or existing directory: if either target already exists, Silen reports the collision instead of overwriting authored content. ## Develop ```sh pnpm silen dev docs ``` Edit `docs/index.mdx` or add another `.md` or `.mdx` file. File routes are created from the directory tree, and client navigation updates without a full page reload. Local search stays on the site; no hosted search account is required. ## Build and inspect ```sh pnpm silen build docs pnpm silen preview docs ``` The default output directory is `docs/.silen/dist`. A build emits complete HTML plus AI artifacts such as `llms.txt`, `llms-full.txt`, `ai-index.json`, and clean Markdown routes. Draft pages and pages with `ai: false` remain out of those AI-facing artifacts. ## Make the first decision explicit Set `base` when the site will live below a host subpath, and set `siteUrl` to the origin when canonical metadata is required: ```ts export default defineConfig({ base: '/handbook/', siteUrl: 'https://docs.example.com', onBrokenLinks: 'error', }) ``` Continue with [project structure](/silen/guide/project-structure/), [configuration](/silen/guide/configuration/), or inspect the [live AI output](/silen/ai/). # Markdown and MDX Use Markdown for durable prose and MDX when a page benefits from a typed React component. Both produce the same route, SSR HTML, search record, and optional AI-readable Markdown. GitHub-flavored Markdown tables, task lists, strikethrough, autolinks, and footnotes keep the same meaning across each output. ## Frontmatter Frontmatter supplies page metadata and layout decisions: ```md --- title: Service runbook description: Diagnose and recover the checkout service. layout: doc lang: en-US ai: true --- ``` `doc` is the default layout. `home` renders the configured hero before page MDX, and `page` keeps the application shell without documentation pagination. `draft: true` excludes the page from AI-readable artifacts and indexes only. It does not stop route scanning, building, or publishing; `ai: false` has the same AI-output boundary for an otherwise public page. Never store private content in the content tree. Keep confidential material outside the site root and its build inputs. ## Links and headings Prefer stable site routes and descriptive link text. Under a non-root `base`, theme-config links are base-aware automatically; authored root-relative links must point at the mounted site path. During build, Silen validates internal page targets and can fail, warn, or ignore according to `onBrokenLinks`. Headings create the document outline. Keep one `#` title, then descend without skipping levels so the outline remains useful to keyboard and screen-reader users. ## Code and components Fenced code blocks receive syntax highlighting and a keyboard-accessible copy button. Silen loads supported Shiki grammars on demand, including `mdx`, `python`, and JSON Lines for `ndjson` fences. Unknown language names safely fall back to plain text. MDX can import components and use expressions: ```mdx import Status from './components/status.tsx' ## Current status ``` MDX executes during the build and can import project code. Treat every MDX file and component as trusted source; Silen is not a sandbox for untrusted user submissions. Keep browser-only access inside effects or client setup so server rendering remains deterministic. For site-wide components, extend the [default theme](/silen/theme/extensions-accessibility/). # Plugins Silen plugins extend the documentation lifecycle without importing internal files. A plugin is a local or npm factory configured directly in `.silen/config.ts`: ```ts import { defineConfig, definePlugin } from '@aicode-nexus/silen' const readingTime = definePlugin( (_context, options: { wordsPerMinute: number }) => ({ name: 'reading-time', transformPageData(page, context) { const words = context.source.trim().split(/\s+/).length return { data: { ...page.data, minutes: Math.max(1, Math.ceil(words / options.wordsPerMinute)), }, } }, }), ) export default defineConfig({ plugins: [[readingTime, { wordsPerMinute: 250 }]], }) ``` ## Lifecycle Silen runs plugins in configuration order. The first release supports `config`, `configResolved`, `extendMdx`, `vite`, `clientModules`, `transformPageData`, `transformHead`, and `buildEnd`. - Use `extendMdx` for Remark and Rehype plugins. - Use `vite` for standard Vite integrations. `virtual:silen/*` modules remain protected by core. - Use `transformPageData` for JSON-serializable metadata consumed by SSR, hydration, search, and AI artifacts. - Use `transformHead` for typed `meta`, `link`, `script`, `style`, or `noscript` entries. - Use `clientModules` for an SSR-safe `wrapRoot` and optional browser-only `setup` function. - Use `buildEnd` to add files such as a sitemap after the output directory is installed. Every plugin needs a `name`; add a distinct `id` when configuring multiple instances. Failures include the identity and hook, such as `Silen plugin analytics:docs failed in transformHead`. ## SSR and compatibility Client modules are imported during SSR and hydration. Do not access `window` or `document` at module scope or inside `wrapRoot`; browser APIs belong in `setup`. Plugin packages should declare `@aicode-nexus/silen` as a peer dependency and import only documented public exports. See the npm-ready sitemap, reading-time, and analytics-client examples in [`examples/plugins`](https://github.com/AICode-Nexus/silen/tree/main/examples/plugins). # Project structure A Silen site is a content root. Keep content and its site configuration together so local development, production builds, and AI tools all resolve the same boundary. ```text docs/ ├── .silen/ │ ├── config.ts │ ├── theme.tsx # optional theme extension │ ├── ai-public.md # optional public agent instructions │ └── dist/ # generated; do not author here ├── public/ │ └── logo.svg ├── assets/ │ └── architecture.png ├── guide/ │ └── index.mdx └── index.mdx ``` ## Content becomes routes Both `.md` and `.mdx` files are scanned. `index.mdx` has compiler route `/`; `guide.mdx` and `guide/index.mdx` both have compiler route `/guide`. The directory form emits `guide/index.html`, with the usual browser URL `/guide/`. Do not create both source forms for the same route; the build rejects duplicate routes instead of choosing one silently. Use directories for sections that will grow. This keeps nearby images, examples, and future child pages easy to locate while preserving stable URLs. ## Configuration and theme `.silen/config.ts` is executable, trusted project configuration. It defines the site title, base, locales, navigation, integrations, and generated AI output. `.silen/theme.tsx` is optional and should extend the default theme when only a component, layout, or wrapper needs to change. ## Static and imported assets Place files that must keep a public filename under `public/` and reference them from the site root, for example `/logo.svg` in configuration. Silen resolves theme links and images against the configured `base`. Import content-owned images from MDX when they should participate in the Vite asset pipeline. ## Generated state `.silen/dist` is the default production output and `.silen/.temp` is temporary build state. Treat both as disposable. The local AI workspace uses `wiki/` for authored Markdown and `.silen/ai/` for its generated index; review the [workspace boundary](/silen/ai/local-workspace-mcp/) before enabling writes. Next, define the site in [configuration](/silen/guide/configuration/). Activate one docs directory From folder to knowledge interface ```sh pnpm add -D @aicode-nexus/silen pnpm silen init docs pnpm silen dev docs ``` Inspect the evidence Live output from this build llms.txt Concise corpus map llms-full.txt Complete readable corpus ai-index.json Structured page discovery Agent manifest Versioned capability contract Guide Markdown Clean route-level source One source, three proofs Useful to readers, agents, and maintainers Human reading AI consumption Extensibility Open source, deliberately small Build the documentation layer with us AI Dev Hub on WeChat # Integrations Silen keeps integrations explicit. Plugins run trusted build or client code, analytics is configured at the site layer, and Ask AI talks only to an endpoint you operate. None of these features requires importing internal Silen files. ## Plugins Plugins are ordered factories in `.silen/config.ts`. Use them for MDX processors, Vite integrations, page metadata, head entries, client setup, or post-build output: ```ts import { defineConfig } from '@aicode-nexus/silen' import readingTime from './plugins/reading-time' export default defineConfig({ plugins: [[readingTime, { wordsPerMinute: 250 }]], }) ``` Every plugin has a `name`; add an `id` for multiple instances. Hooks execute in configuration order and failures report the plugin identity plus hook. Read the complete [plugin lifecycle](/silen/guide/plugins). ## Analytics Analytics is theme-independent and production-only. Configure Google, Baidu, or an ordered custom provider: ```ts analytics: [ { provider: 'google', id: 'G-XXXXXXXXXX' }, { provider: 'baidu', id: 'site-id' }, ] ``` Silen reports the initial page and later client-route changes while ignoring hash-only navigation. Google users should disable automatic history-change pageviews in Enhanced Measurement to avoid duplicates. A custom provider can load external or inline scripts and listen for `silen:pageview`. Scripts are trusted public code; never embed credentials. ## Ask AI Ask AI is an optional theme endpoint, not a bundled model provider: ```ts themeConfig: { ai: { endpoint: '/api/ask' }, } ``` ## Ask AI request Silen sends an HTTP `POST` with `Content-Type: application/json`. The request contract is exactly: ```ts interface AskAiRequest { route: string selectedText?: string messages: Array<{ role: 'user' | 'assistant' content: string }> } ``` `selectedText` is optional; omit it when the reader has not selected content. Messages can include prior user and assistant turns. A concrete request is: ```json { "route": "/guide/", "selectedText": "pnpm silen init docs", "messages": [ { "role": "user", "content": "How do I start?" }, { "role": "assistant", "content": "Install the package first." } ] } ``` ## Ask AI response Return a successful streaming response with either `Content-Type: application/x-ndjson` or `Content-Type: application/ndjson`. This NDJSON response writes one JSON object per line. The event shapes are text `{ type: 'text', value: string }`, citation `{ type: 'citation', title: string, url: string }`, and error `{ type: 'error', message: string }`: ```ndjson {"type":"text","value":"Install with pnpm."} {"type":"citation","title":"Quick start","url":"/guide/"} {"type":"error","message":"Unable to answer."} ``` Silen supplies an `AbortSignal` to the request and aborts a superseded stream or a stream whose dialog closes. Treat that signal and the disconnected HTTP request as cancellation: stop upstream provider work and release resources. Your endpoint owns server-side authentication. Keep provider keys and raw provider errors on the server, and return a safe public failure instead. With no endpoint, Silen emits no Ask AI control and no Ask AI client bundle. For deterministic, provider-free AI access, use the [generated artifacts](/silen/ai/) and [local MCP workspace](/silen/ai/local-workspace-mcp/). # Plugins This route remains available for existing bookmarks. Silen’s plugin API is the ordered, public extension boundary for build and client integrations. A plugin factory is configured in `.silen/config.ts`, receives the current command and root, and returns a named plugin. ```ts import { defineConfig, definePlugin } from '@aicode-nexus/silen' const metadata = definePlugin(() => ({ name: 'product-metadata', transformPageData(page) { return { data: { ...page.data, product: 'checkout' } } }, })) export default defineConfig({ plugins: [metadata] }) ``` Available hooks cover configuration, resolved configuration, Remark/Rehype, Vite, client modules, page data, head entries, and build completion. Hooks run in configuration order. Client modules must be safe during SSR: browser APIs belong in `setup`, not module scope or `wrapRoot`. Plugin packages should use `@aicode-nexus/silen` as a peer dependency and import only documented exports. Continue to the canonical [plugin guide](/silen/guide/plugins) for lifecycle, identity, failure, and packaging details, or see [Integrations](/silen/integrations/) for analytics and Ask AI. # Reference This page is the compact operational reference. Use the linked guides for explanations and examples. ## Configuration | Field | Default | Purpose | | --- | --- | --- | | `title` | `Silen` | Human-readable site title | | `description` | empty | Generated page metadata | | `lang` | `en-US` | Default BCP 47 language | | `base` | `/` | Normalized deployment pathname | | `siteUrl` | unset | Canonical HTTP(S) origin | | `outDir` | `.silen/dist` | Output relative to content root | | `onBrokenLinks` | `error` | `error`, `warn`, or `ignore` | | `themeConfig` | `{}` | Navigation, locales, home, search, Ask AI | | `analytics` | `[]` | Ordered production analytics providers | | `plugins` | `[]` | Ordered trusted plugin entries | | `ai.*` | enabled | AI files, Markdown routes, index, contract | `base` must start with `/`, contain no query/hash or traversal, and is normalized with a trailing slash. `siteUrl` is an origin only, without credentials, path, query, or fragment. ## CLI | Command | Effect | | --- | --- | | `silen init ` | Safely create starter config and homepage | | `silen dev [root]` | Start development; accepts `--host`, `--port` | | `silen build [root]` | Validate and generate static output | | `silen preview [root]` | Serve output; accepts `--host`, `--port` | | `silen ai [path]` | Manage and evaluate the local AI workspace | | `silen ai skills ` | Materialize the packaged `silen-docs-readonly` Skill without overwrite | | `silen mcp [root]` | Serve read-only MCP; optional `--allow-write` and experimental `--experimental-skills-over-mcp` | The package stores the portable Skill at `dist/agent/skills/silen-docs-readonly`. The URI `skill://silen-docs-readonly/SKILL.md` exists only when `--experimental-skills-over-mcp` is present; the default Agent Contract remains `extensions: []`. ## MCP and Agent Contract The local MCP command uses SDK v2 over `stdio` and verifies `2025-11-25` and `2026-07-28`. It exposes seven read-only tools by default and three additional write tools with `--allow-write`; successful calls include text and validated `structuredContent`. Remote transport is not enabled. Agent Contract manifest and API files use `schemaVersion: 2`. The manifest declares the protocol versions and empty extensions; the API declares each tool's `outputSchema`. ## AI evaluation suites `.silen/ai-evals.json` is strict JSON. Version 1 matches one route and optional heading within `topK`; version 2 adds optional `expected.maxRank`. Version 3 uses this strict shape: | Field | Requirement | | --- | --- | | `schemaVersion` | Exact integer `3` | | `topK` | Integer `1..20` | | `cases` | One to 500 ordered cases | | `expected.acceptable` | Required array of zero to 20 unique targets | | `expected.forbidden` | Required array of zero to 20 unique targets | | `expected.maxRank` | Required integer `1..topK`; exact `topK` for negative-only cases | | Target | Strict `{ route, heading? }`; route starts with `/` | At least one target array must be non-empty. Normalized duplicates, overlap within an array, overlap between `acceptable` and `forbidden`, and unknown fields are invalid. Version 3 reports preserve ordered `cases`, `matchedRank`, `forbiddenMatches`, and full diagnostic Top K; v1/v2 behavior remains compatible. Evaluation is read-only and model-free. Repository maintainers run `pnpm site:ai-check`; its exact stable report is `artifacts/ai-eval/site-ai-eval.json`. ## Troubleshooting **A link works locally but fails after deployment.** Confirm the host mount matches `base`, authored root-relative content links include that mount, and the host serves nested `index.html` files. **Canonical URLs include the path twice.** Keep `siteUrl` to the origin and put the path only in `base`. **The language switch returns a missing page.** Create the exact mirrored route under every locale root and include it in translated navigation. **Build reports a duplicate route.** Remove either `topic.mdx` or `topic/index.mdx`; both resolve to the same public route. **A build fails after pnpm reports an ignored esbuild build script.** Approve only that dependency with `pnpm approve-builds esbuild`, reinstall, and retry. No approval is needed when the build already succeeds. **MCP write tools are absent.** This is the safe default. Start the server with `--allow-write` only after the user authorizes a bounded write task. See [configuration](/silen/guide/configuration/) and [CLI/deployment](/silen/guide/cli-deployment/) for longer guidance. # Theme extensions and accessibility Extend the default theme when tokens and configuration are not enough. A theme can replace layouts or MDX components, provide a custom 404, and wrap the React root while inheriting everything else. ```tsx // docs/.silen/theme.tsx import type { ReactNode } from 'react' import DefaultTheme, { defineTheme } from '@aicode-nexus/silen/theme' import './custom.css' function Note({ children }: { readonly children?: ReactNode }) { return } export default defineTheme({ extends: DefaultTheme, components: { Note }, wrapRoot({ children }) { return
{children}
}, }) ``` `defineTheme` merges inherited layouts and components by key. `NotFound` is inherited unless replaced. When both base and extension define `wrapRoot`, the extension wrapper composes outside the base wrapper. Recursive extension is rejected. ## SSR-safe extensions Theme modules and root wrappers run during server rendering and hydration. Do not read `window`, `document`, or `localStorage` at module scope or directly in render. Put browser behavior in an effect or plugin client `setup` function and return cleanup when registering listeners. ## Accessibility contract The default shell includes a skip link and visible focus indicators. Mobile navigation is a labelled modal: opening moves focus into navigation, Escape closes it, and focus returns to the trigger. Search supports its shortcut, arrow-key selection, Enter, Escape, and focus restoration. Code-copy controls are buttons with live status labels. The appearance control is an explicit dark/system/light radio group. Its inline head script applies the stored preference before hydration to prevent a color flash, while system mode follows operating-system changes. Nonessential transitions respect reduced-motion preferences. When replacing an interactive component, keep its accessible name, keyboard path, focus behavior, and server-rendered fallback. Test without a pointer, with 200% zoom, and with reduced motion before shipping. # Theme, layouts, and navigation The default theme is a responsive documentation shell rather than a closed template. It supplies navigation, sidebars, page outlines, local search, appearance controls, code copying, pagination, home heroes, and a complete 404 page. Start with configuration; extend React only when a product requirement cannot be expressed there. ## Layouts Choose a content layout in frontmatter: ```md --- layout: doc --- ``` - `doc` is the default. It applies reading typography, the heading outline, and previous/next links derived from the sidebar. - `home` renders the locale-resolved configured hero and optional feature row before page MDX in a full-width shell. - `page` keeps navigation and a neutral article container without documentation paging. Home hero artwork can provide separate light and dark assets while keeping one accessible description: ```ts themeConfig: { home: { hero: { image: { src: '/workflow-light.jpg', darkSrc: '/workflow-dark.jpg', alt: 'Documentation workflow', }, }, }, } ``` ## Navigation and sidebar ```ts themeConfig: { logo: { src: '/logo.svg', alt: 'Product docs' }, nav: [ { text: 'Guide', link: '/guide/' }, { text: 'GitHub', link: 'https://github.com/example/project' }, ], sidebar: [ { text: 'Getting started', items: [{ text: 'Quick start', link: '/guide/' }], }, ], } ``` Internal theme links are resolved under `base`. HTTP(S) nav links use ordinary browser navigation in the current context. Nav items pass only `href`; they do not automatically add a new context or relationship attributes. MDX-authored links can explicitly set `target="_blank"` and `rel="noopener noreferrer"` when a new context is genuinely useful. Below 960px the persistent sidebar becomes a labelled modal sheet with collapsible groups. At desktop widths, every group remains visible as a semantic section beside the document, and the current page uses the primary theme treatment. ## Search Local search is enabled unless `themeConfig.search` is `false`. It loads on demand, opens from the search button or `Control+K` / `Command+K`, supports keyboard selection, and restores focus when dismissed. Search v2 records page language so results from the active locale are ranked and grouped correctly. ## Locales Locale entries define a BCP 47 `lang`, label, and route `root`; they may override nav, sidebar, home, and UI messages. Mirrored routes let the language switch preserve the current page. The longest matching configured locale root controls document and search language. Frontmatter `lang` does not override the resolved route locale; content requiring another language should live under the corresponding locale root. Customize visual values with [theme tokens](/silen/theme/tokens/) or compose React behavior through [theme extensions](/silen/theme/extensions-accessibility/). # Theme tokens Override semantic CSS variables instead of styling internal utility classes. Tokens are the stable boundary between the default theme’s behavior and a project’s visual identity. ```css /* docs/.silen/custom.css */ :root { --silen-primary: oklch(0.55 0.17 245); --silen-primary-foreground: oklch(0.99 0 0); --silen-radius: 0.5rem; --silen-content-width: 48rem; } .dark { --silen-primary: oklch(0.76 0.12 245); } ``` Import the stylesheet from `.silen/theme.tsx` so Vite includes it in both SSR and the client bundle. ## Color tokens The primary semantic set is `--silen-background`, `--silen-foreground`, `--silen-card`, `--silen-card-foreground`, `--silen-primary`, `--silen-primary-foreground`, `--silen-muted`, `--silen-muted-foreground`, `--silen-border`, `--silen-input`, `--silen-ring`, and `--silen-destructive`. Secondary, accent, and popover tokens map the same semantics to interactive primitives. Define light values on `:root` and dark overrides on `.dark`. Preserve usable contrast between foreground/background and primary/primary-foreground pairs; the appearance control can switch explicitly among dark, system, and light. ## Shape and layout tokens - `--silen-radius` controls the shared corner language. - `--silen-nav-height` sizes the fixed top navigation. - `--silen-sidebar-width` controls the desktop navigation rail. - `--silen-content-width` limits readable document lines. - `--silen-layout-width` limits wide home and page layouts. Change one layer at a time and test long titles, code blocks, both appearance modes, and mobile navigation. Increasing content width may look efficient on a dashboard but makes prose harder to scan. ## Extension boundary Tokens are best for visual changes. Use a [theme extension](/silen/theme/extensions-accessibility/) only when you need a new MDX component, wrapper, layout, or 404 component. # Agent Contract Agent Contract 是版本化、可检查的发现层,让 AI 客户端不必猜测配置字段、CLI 语法、MCP 权限与部署路由。 ## 安装包契约 创建或维护本地项目时,从这里开始: ```text @aicode-nexus/silen/agent/manifest.json ``` 包清单会指向当前准确版本的配置 API、CLI/MCP 契约、公共 TypeScript 导出、指南与任务手册。例如 `agent/tasks/create-site.md` 描述受支持的激活路径,并链接回权威机器可读资源,而不是复制定义。 ## 部署站点契约 开启后,每次生产构建都会发布站点专属的 `/.well-known/silen/manifest.json`,并按 `base` 解析。当前官网的[实时清单](/silen/.well-known/silen/manifest.json)描述 base、语言、资源、任务与公开项目指引;资源与任务 URL 保持 base 相对。manifest schema 不包含部署 origin 字段。 ```ts ai: { contract: { enabled: true, instructions: '.silen/ai-public.md', tasksDir: '.silen/ai-tasks', }, } ``` 指令与任务都是显式公开构建输入。不要包含本地绝对路径、密钥、私有端点、凭证或未公开运行信息。 ## Schema 版本 2 当前 manifest 与 API 文档使用 `schemaVersion: 2`。manifest 的 MCP 能力声明 `stdio`、协议版本 `2025-11-25` 与 `2026-07-28`、空扩展列表、本地运行、 默认只读和 `--allow-write` 门禁。API 文档为每个工具增加 `outputSchema`;MCP 成功调用会同时返回文本与对应的、经过 schema 校验的 `structuredContent`。 该契约不声明远程传输或可选 MCP 扩展;这些能力需要独立设计和授权。 包内还包含生成的文件系统 Skill: `dist/agent/skills/silen-docs-readonly`;CLI API 会记录 `silen ai skills` 和 `--experimental-skills-over-mcp`。默认 manifest 仍声明 `extensions: []`,因为可选 运行参数不等于站点能力。Skill 文本只是流程知识,不授予 Host 运行命令、访问 网络、写文件、提交、推送或部署的权限。 ## 客户端行为 Codex、Claude Code、Cursor 等客户端应使用同一份清单,不要维护各自的 API 副本。若客户端不支持声明的契约 schema,应退回到链接的公开 Markdown,并保持只读。读取部署内容时以站点清单为准;针对已安装包生成代码时以包契约为准。 下一步配置[本地工作区与 MCP](/silen/zh/ai/local-workspace-mcp/)。 # AI-ready 文档 Silen 把 AI 访问视为文档构建的一部分,而不是事后补上的功能。默认输出是 确定、可检查的,并且不会调用模型。核心 AI-ready 文档流程不需要模型、API key、 端点、向量服务或网络。 ## Agent Contract Silen 为 AI 提供一个带版本的发现入口,不需要为每一种客户端重复维护一份教程: - 操作本地项目时,先读取已安装包中的 `@aicode-nexus/silen/agent/manifest.json`。它会链接到准确的配置、CLI、 MCP、公开 TypeScript API,以及 `agent/tasks/create-site.md` 等任务手册。 - 读取部署站点时,先访问 `/.well-known/silen/manifest.json`。当前官方站点的 地址是 `/silen/.well-known/silen/manifest.json`。 - 在本地进行有边界的读取时,启动 `pnpm silen mcp docs`。除非用户显式添加 `--allow-write`,否则它始终只读。 Codex、Claude Code 与 Cursor 都应读取同一份 manifest,并使用同一个本地 MCP 命令。各客户端只保留轻量接入配置,API 真相始终由 Agent Contract 提供。 如果客户端不支持声明的契约版本,必须退回链接的公开 Markdown,并保持只读。 当前 manifest 与 API 使用 `schemaVersion: 2`,声明本地 `stdio`、已验证的 `2025-11-25` 与 `2026-07-28` 协议版本、空扩展集合,以及每个 MCP 工具的 `outputSchema`。 ## 只读 Agent Skill npm 包会从规范的中英文 `read-site` 与 `audit-site` 任务包确定性生成唯一的 `silen-docs-readonly` Agent Skill。包内路径是 `dist/agent/skills/silen-docs-readonly`,其中只有 `SKILL.md` 和四个按需读取的 参考文件,不包含脚本、资产、写任务、模型调用、凭据或隐含权限。 ```sh pnpm silen ai skills ./agent-skills ``` 该命令只创建 `./agent-skills/silen-docs-readonly`;如果目录已经存在就直接失败, 不会覆盖。文件系统形式是受支持的可移植能力,并且可离线使用。 ## 添加公开项目指令 只发布对所有站点访问者都安全的内容: ```ts export default defineConfig({ ai: { contract: { instructions: '.silen/ai-public.md', tasksDir: '.silen/ai-tasks', }, }, }) ``` 这些文件会成为显式公开的 Agent 指令。不要写入私有路径、密钥、内部端点或凭据。 ## 面向 AI 的公开产物 每次生产构建都可以输出: - `llms.txt`,用于精简页面地图 - `llms-full.txt`,用于完整可读内容 - `ai-index.json`,用于结构化发现 - 每个公开页面对应的干净 Markdown 路由 标记为 `draft: true` 或 `ai: false` 的页面会从这些产物中排除。 ## 复制给 AI 默认主题允许读者复制干净的页面 Markdown,或复制带规范来源 URL 的 prompt-ready 版本。复制内容来自同一套构建产物,因此会和渲染页面保持一致。 ## 本地 MCP 工作区 ```sh pnpm silen ai init docs pnpm silen ai index docs pnpm silen ai audit docs pnpm silen ai eval docs pnpm silen mcp docs ``` MCP 服务使用拆分后的 SDK v2,并且默认只读。只有显式使用 `--allow-write` 启动时,写入工具才会出现;所有写入仍被限制在 Markdown 工作区内。成功调用会 同时返回文本和经过 schema 校验的 `structuredContent`,不启用远程传输。 ## 无模型质量门禁 直接把生产搜索索引作为确定性的检索契约: ```sh pnpm silen build docs pnpm silen ai audit docs pnpm silen ai eval docs ``` `ai eval` 只读取已提交的 `.silen/ai-evals.json` 与构建生成的 `.silen/dist/search-index.json`,不会调用模型或网络。退出码 `0`、`1`、`2` 分别表示通过、检索失败、初始化或配置失败。 版本 1 保持完整 `topK` 匹配;版本 2 增加可选的 `expected.maxRank`,并报告 生效值与 `matchedRank`。严格的 `"schemaVersion": 3` 要求两个目标数组与显式 排名边界: ```json { "schemaVersion": 3, "topK": 5, "cases": [ { "id": "install-quick-start", "query": "如何安装并启动站点?", "expected": { "acceptable": [ { "route": "/zh/guide/", "heading": "快速开始" }, { "route": "/zh/guide/cli-deployment/" } ], "forbidden": [{ "route": "/zh/draft-notes/" }], "maxRank": 1 } } ] } ``` `acceptable` 与 `forbidden` 都必须出现,每个数组可包含零到 20 个目标,但两者 不能同时为空。至少一个可接受目标必须在 `maxRank` 以内出现,所有禁止目标都不能 进入诊断 Top K。纯负例使用 `acceptable: []` 与 `maxRank: topK`。未知字段、 重叠目标、空目标集合和非法边界都会成为初始化错误。版本 3 保持案例编写顺序, 并输出 `matchedRank` 与 `forbiddenMatches`;v1/v2 的 JSON 与人类可读输出保持 兼容。 本仓库使用 `pnpm site:ai-check` 一次完成构建、审计、评测和 source map 检查, 并把评测器的原始 JSON 保存到 `artifacts/ai-eval/site-ai-eval.json`,供 CI、Pages 与发布流程比较。 可重建的 `.silen/ai/index.json` 只是可选工作区快照。缺失或过期只会成为 audit 提示,MCP 搜索仍使用内存索引。 ## Ask AI Ask AI 是可选的端点集成。Silen 不会把 provider key 放进生成站点:你的服务端 负责鉴权,并把一套小型 NDJSON 协议流式返回给主题。未显式配置端点时,Ask AI 控件及其 bundle 都不会出现。 返回 [快速开始指南](/silen/zh/guide/)。 # 本地工作区与 MCP 本地 AI 工作区是确定性、无模型的能力层:它为工具提供有边界的 Markdown 根目录、可检查索引与显式写权限,不暴露任意 shell 执行。整个流程不需要模型、API key、端点、向量服务或网络。 ## 初始化、索引与审计 ```sh pnpm silen ai init docs pnpm silen ai index docs pnpm silen ai audit docs pnpm silen ai eval docs ``` `ai init` 创建 `wiki/` 与被忽略的 `.silen/ai/` 缓存,不修改已有 MDX;`ai index` 重建可选的 `.silen/ai/index.json` 工作区快照;`ai audit` 检查链接、引用、生成产物与生产契约。快照缺失或过期只会成为提示,因为 MCP 搜索使用内存索引。 ## 构建、审计与评测 ```sh pnpm silen build docs pnpm silen ai audit docs pnpm silen ai eval docs ``` `ai eval` 读取 `.silen/ai-evals.json` 与生产构建的 `.silen/dist/search-index.json`;它不会启动 MCP,也不会调用模型或网络。版本 1 在 `topK` 内使用单一路由与可选标题;版本 2 增加可选的 `expected.maxRank`。严格的 `"schemaVersion": 3` 要求同时提供 `acceptable` 与 `forbidden` 数组、两者至少包含一个目标,并显式设置 1 到 `topK` 之间的 `maxRank`。纯负例使用 `acceptable: []` 与 `maxRank: topK`。 版本 3 在没有可接受目标时报告 `matchedRank: null`,并把禁止命中列入 `forbiddenMatches`。退出码 `0` 表示全部通过,`1` 表示检索预期失败,`2` 表示套件或输入无效;完整诊断 Top K 保持稳定的案例顺序。 Silen 仓库使用 `pnpm site:ai-check` 组合完整只读门禁,并把评测原始 JSON 保存到 `artifacts/ai-eval/site-ai-eval.json`。可选的 `.silen/ai/index.json` 快照仍是非阻断能力,不会替代生产搜索索引。 ## 连接 MCP 客户端 从仓库根目录启动: ```json { "mcpServers": { "silen": { "command": "pnpm", "args": ["silen", "mcp", "docs"] } } } ``` 默认服务注册七个只读工具:`guide`、`list`、`search`、`read`、`backlinks`、`citations`、`build`。`build` 是有边界的预检,只读取 Markdown 输入与现有产物,不加载项目配置、不执行 MDX、不调用 Vite,也不写文件。 ## 协议与结构化结果 该命令使用稳定的拆分版 TypeScript SDK v2。同一个 `stdio` 入口接受已验证的 legacy `2025-11-25` 与 modern `2026-07-28` 客户端;版本规则见 [官方协议版本指南](https://ts.sdk.modelcontextprotocol.io/v2/protocol-versions)。 服务默认只读。每次成功调用都同时返回文本与经过 schema 校验的 `structuredContent`,每个工具都声明 `outputSchema`;不启用远程传输。 字符串结果的 `guide` 在 modern 客户端中保持原生字符串,在 legacy 客户端中由 SDK 兼容包装为 `{ result: ... }`;对象结果工具在两个协议时代保持原有结构。 ## 实验性 Skills over MCP 文件系统安装不依赖 MCP。明确支持 Resources 草案绑定的 Host 可以选择暴露同一份 包内字节: ```sh pnpm silen mcp docs --experimental-skills-over-mcp ``` 该实验声明 `io.modelcontextprotocol/skills`,提供 `skill://index.json`,并把五个 文件映射到 `skill://silen-docs-readonly/` 下。它只使用本地 stdio 并保持只读;该 实验默认关闭,不增加工具、脚本、订阅、网络传输或写权限;`--allow-write` 仍是 独立的显式工具注册开关。 ## 谨慎授权写入 ```sh pnpm silen mcp docs --allow-write ``` 显式参数会增加 `write`、`link`、`append`。写入只接受工作区相对 `.md`/`.mdx` 路径,拒绝目录穿越和逃逸符号链接,使用原子替换,并限制为 2 MiB UTF-8;它不会增加 shell 工具。 只在边界明确的任务中授权可信本地客户端。修改后运行 audit 与站点构建,检查 Git diff,并在提交或部署前另行取得授权。 Ask AI 是独立能力,必须显式配置端点;没有端点时,Silen 不会输出控件及其 bundle。 客户端发现规则见 [Agent Contract](/silen/zh/ai/agent-contract/)。 # CLI 与部署 Silen 提供一组精简 CLI。通过项目包管理器运行,命令实现与 Agent Contract 就会始终匹配当前安装版本。 ## 主要命令 ```sh pnpm silen init docs pnpm silen dev docs --host 127.0.0.1 --port 5173 pnpm silen build docs pnpm silen preview docs --port 4173 ``` `init ` 写入起始配置与首页,不替换已有目标;`dev [root]` 启动基于 Vite 的开发服务;`build [root]` 校验并生成静态产物;`preview [root]` 提供包含路由与语言感知 404 的预览。服务命令支持 `--host` 和 `--port`,构建命令不会自动部署。 AI 工作区使用独立命令: ```sh pnpm silen ai init docs pnpm silen ai index docs pnpm silen ai audit docs pnpm silen ai eval docs pnpm silen ai skills ./agent-skills pnpm silen mcp docs ``` `ai skills` 必须指定父目录,只创建 `silen-docs-readonly` 且绝不覆盖;可选的 MCP Resource 暴露使用 `pnpm silen mcp docs --experimental-skills-over-mcp`,仍是实验能力 并默认关闭。 MCP 默认只读,只有可信用户显式加入 `--allow-write` 才会注册写工具。无模型的 `ai eval` 只读取 `.silen/ai-evals.json` 与 `.silen/dist/search-index.json`, CI 使用 `--json`;它不需要模型、API key、端点、向量服务或网络。 套件 `"schemaVersion": 1` 保持完整 `topK` 匹配;版本 2 支持逐案例 `expected.maxRank`,省略时默认等于 `topK`,并在保留完整诊断结果的同时 报告 `matchedRank`。 ## 静态部署 把 `docs/.silen/dist` 的内容发布到任意静态托管,并让托管平台按生成结果提供 `index.html` 与资源。例如项目地址为 `https://example.github.io/handbook/`: ```ts export default defineConfig({ siteUrl: 'https://example.github.io', base: '/handbook/', }) ``` 不要在 `siteUrl` 中重复 `/handbook/`。构建会组合 origin 与 base,用于 canonical、`hreflang` 与 `x-default` 语言替代、站点地图和基础 Open Graph/Twitter 元数据。Markdown 与 Agent Contract URL 仍是 base 相对路径。 ## 上线前检查 仓库维护者只运行一个规范命令: ```sh pnpm site:ai-check ``` 它依次且只执行一次 `site:build` -> `ai audit` -> `ai eval` -> `check:no-maps`;`pnpm site:check` 只是兼容别名。Core CI、GitHub Pages 与 npm 发布都使用规范命令,audit 或评测失败会阻断部署和发布。 正式 `.silen/ai-evals.json` 使用 `"schemaVersion": 3`、显式 `maxRank`,以及必需的 `acceptable` 和 `forbidden` 目标数组。报告保留诊断 `topK`、稳定的 `matchedRank` 与禁止命中证据。只要评测器产出了有效 JSON, 每条工作流都会用 always 条件上传 `artifacts/ai-eval/site-ai-eval.json`,包括检索失败或后续 source map 检查失败的情况。 随后直接预览一个嵌套路由和一个不存在的路由,并检查 `llms.txt` 与 `.well-known/silen/manifest.json`。构建成功只证明文件已生成;直接访问才能 证明托管平台按预期 base 提供了它们。 Ask AI 仍然只通过端点接入;未配置端点时,不会出现控件或对应 bundle。 命令语法与排错见[参考手册](/silen/zh/reference/)。 # 配置 在内容根目录创建 `.silen/config.ts`,并导出 `defineConfig(...)`。该文件是可信的项目代码;不要放入密钥,因为配置可能影响公开 HTML 与构建产物。 ```ts import { defineConfig } from '@aicode-nexus/silen' export default defineConfig({ title: '工程手册', description: '产品团队的运行知识。', lang: 'zh-CN', base: '/handbook/', siteUrl: 'https://docs.example.com', outDir: '.silen/dist', onBrokenLinks: 'error', }) ``` ## URL 与元数据 `base` 是站点挂载位置的规范绝对路径;域名根路径使用 `/`,子路径可用 `/handbook/`。`siteUrl` 只能写 HTTP(S) 源,部署路径写在 `base` 中。两者共同生成 canonical、`hreflang` 与 `x-default` 语言替代、站点地图和基础 Open Graph/Twitter 元数据。Markdown 与 Agent Contract URL 仍是 base 相对路径。`lang` 使用 BCP 47 语言标签。 ## 导航与多语言 `themeConfig.nav` 和 `themeConfig.sidebar` 使用 `{ text, link }`。主题里的根相对链接会自动加上 `base`。locale 可设置 `root`,并覆盖导航、侧栏、首页与界面消息: ```ts themeConfig: { locales: [ { lang: 'en-US', label: 'English', root: '/' }, { lang: 'zh-CN', label: '中文', root: '/zh/' }, ], search: true, } ``` 保持语言路由镜像,语言切换器才能保留当前页面,而不是把读者送回首页。 ## 集成与 AI `analytics` 支持 Google、百度与自定义脚本;`plugins` 是有序的可信插件工厂数组。`ai` 可控制 `llms.txt`、`llms-full.txt`、Markdown 路由与 `ai-index.json`,默认全部开启。Agent Contract 默认开启,也可显式加入公开指令和任务。 ```ts ai: { markdownRoutes: true, index: true, contract: { enabled: true, instructions: '.silen/ai-public.md' }, } ``` 完整字段见[参考手册](/silen/zh/reference/),集成示例见[集成](/silen/zh/integrations/)。 # 快速开始 Silen 将 Markdown 与 MDX 目录构建为服务端渲染的静态站点、本地搜索与确定性的 AI 可读产物。请使用 Node.js `^20.19.0 || >=22.12.0`。 ## 安装并激活 在项目根目录安装 Silen,然后激活 `docs` 目录: ```sh pnpm add -D @aicode-nexus/silen pnpm silen init docs ``` Silen 会自动安装所需的 `react`、`react-dom` 运行时以及 MDX 使用的 `react/jsx-runtime`,用户无需单独安装。 `init` 会创建 `docs/.silen/config.ts` 和 `docs/index.mdx`。它既适用于新目录,也适用于已有内容:只要目标文件已存在,Silen 就会报告冲突,不会覆盖你的内容。 ## 本地开发 ```sh pnpm silen dev docs ``` 编辑 `docs/index.mdx`,或增加 `.md`、`.mdx` 文件。目录树会直接形成路由,客户端导航无需整页刷新。本地搜索完全随站点运行,不需要托管搜索账号。 ## 构建并检查 ```sh pnpm silen build docs pnpm silen preview docs ``` 默认输出到 `docs/.silen/dist`。构建结果包括完整 HTML,以及 `llms.txt`、`llms-full.txt`、`ai-index.json` 和干净 Markdown 路由。草稿页与设置了 `ai: false` 的页面不会进入 AI 产物。 ## 明确部署边界 站点部署在子路径时设置 `base`;需要规范链接与站点地图时,将 `siteUrl` 设置为域名源: ```ts export default defineConfig({ base: '/handbook/', siteUrl: 'https://docs.example.com', onBrokenLinks: 'error', }) ``` 下一步阅读[项目结构](/silen/zh/guide/project-structure/)、[配置](/silen/zh/guide/configuration/),或直接检查[真实 AI 产物](/silen/zh/ai/)。 # Markdown 与 MDX 持久说明优先使用 Markdown;页面确实需要类型化 React 组件时再使用 MDX。两者都会生成相同的路由、SSR HTML、搜索记录与可选 AI Markdown。GFM 表格、任务列表、删除线、自动链接与脚注会在这些产物中保持一致语义。 ## Frontmatter Frontmatter 用于页面元数据与布局选择: ```md --- title: 服务运行手册 description: 诊断并恢复结算服务。 layout: doc lang: zh-CN ai: true --- ``` `doc` 是默认布局;`home` 会先渲染配置的 hero,再渲染页面 MDX;`page` 保留应用外壳,但不显示文档翻页。`draft: true` 只会让页面退出 AI 可读产物与索引。它不会阻止路由扫描、构建或发布;`ai: false` 对其他公开页面采用相同的 AI 输出边界。不要把私密内容放入内容树。机密材料应保存在站点根目录及其构建输入之外。 ## 链接与标题 使用稳定站点路由和有意义的链接文字。非根 `base` 下,主题配置链接会自动感知 base;正文里的根相对链接应直接指向挂载路径。构建期间 Silen 会校验内部页面目标,并按 `onBrokenLinks` 选择报错、警告或忽略。 标题会形成页面大纲。每页保留一个 `#` 标题,后续层级不要跳级,以保证键盘与屏幕阅读器用户都能理解结构。 ## 代码与组件 围栏代码块带语法高亮和可键盘操作的复制按钮。Silen 会按需加载 Shiki 支持的语法,包括 `mdx`、`python`,并让 `ndjson` 使用 JSON Lines 语法;未知语言会安全降级为纯文本。MDX 可以导入组件: ```mdx import Status from './components/status.tsx' ## 当前状态 ``` MDX 会在构建中执行,也能导入项目代码,因此必须把它当成可信源文件,而不是不受信任投稿的沙箱。浏览器 API 应放在 effect 或客户端 setup 内,确保服务端渲染可重复。 需要全站组件时,请扩展[默认主题](/silen/zh/theme/extensions-accessibility/)。 # 插件 Silen 插件无需导入内部文件,即可扩展文档生命周期。插件是直接配置在 `.silen/config.ts` 中的本地或 npm 工厂函数: ```ts import { defineConfig, definePlugin } from '@aicode-nexus/silen' const readingTime = definePlugin( (_context, options: { wordsPerMinute: number }) => ({ name: 'reading-time', transformPageData(page, context) { const words = context.source.trim().split(/\s+/).length return { data: { ...page.data, minutes: Math.max(1, Math.ceil(words / options.wordsPerMinute)), }, } }, }), ) export default defineConfig({ plugins: [[readingTime, { wordsPerMinute: 250 }]], }) ``` ## 生命周期 Silen 按配置顺序执行插件。首个版本支持 `config`、`configResolved`、 `extendMdx`、`vite`、`clientModules`、`transformPageData`、 `transformHead` 和 `buildEnd`。 - `extendMdx` 接入 Remark 与 Rehype 插件。 - `vite` 接入标准 Vite 能力;`virtual:silen/*` 模块仍由核心保护。 - `transformPageData` 生成可 JSON 序列化、可供 SSR、hydration、搜索和 AI 产物共同使用的页面数据。 - `transformHead` 添加类型化的 `meta`、`link`、`script`、`style` 或 `noscript` 节点。 - `clientModules` 提供 SSR-safe 的 `wrapRoot` 和可选的浏览器端 `setup`。 - `buildEnd` 在产物目录安装完成后生成 sitemap 等附加文件。 每个插件都必须提供 `name`;同一插件配置多个实例时应提供不同的 `id`。 错误信息会包含插件标识和钩子,例如 `Silen plugin analytics:docs failed in transformHead`。 ## SSR 与兼容性 客户端模块会同时进入 SSR 与 hydration。不要在模块顶层或 `wrapRoot` 中 访问 `window`、`document`;浏览器 API 应放在 `setup` 中。插件包应把 `@aicode-nexus/silen` 声明为 peer dependency,并且只导入文档化的公开 API。 仓库的 [`examples/plugins`](https://github.com/AICode-Nexus/silen/tree/main/examples/plugins) 提供了可直接整理成 npm 包的 sitemap、阅读时间和 analytics-client 示例。 # 项目结构 一个 Silen 站点就是一个内容根目录。把内容与站点配置放在同一边界内,本地开发、生产构建和 AI 工具就会解析同一套文件。 ```text docs/ ├── .silen/ │ ├── config.ts │ ├── theme.tsx # 可选主题扩展 │ ├── ai-public.md # 可选公开 Agent 指令 │ └── dist/ # 生成目录,不要手工编辑 ├── public/ │ └── logo.svg ├── assets/ │ └── architecture.png ├── guide/ │ └── index.mdx └── index.mdx ``` ## 内容如何形成路由 Silen 扫描 `.md` 与 `.mdx`。`index.mdx` 的编译器路由是 `/`;`guide.mdx` 与 `guide/index.mdx` 的编译器路由是 `/guide`。目录形式会生成 `guide/index.html`,通常以 `/guide/` 访问。不要同时创建两个指向同一路由的源文件;构建会明确拒绝重复路由,而不是静默选一个。 会继续增长的栏目适合使用目录,这样相邻图片、示例与子页面更容易维护,公开 URL 也能保持稳定。 ## 配置与主题 `.silen/config.ts` 是可信、可执行的项目配置,定义标题、base、多语言、导航、集成与 AI 产物。`.silen/theme.tsx` 是可选项;仅替换组件、布局或根包装器时,应扩展默认主题。 ## 静态资源与导入资源 必须保留公开文件名的资源放到 `public/`,例如在配置中使用 `/logo.svg`。Silen 会按配置的 `base` 解析主题链接与图片。与内容强关联、需要进入 Vite 资源管线的图片,可从 MDX 中导入。 ## 生成状态 `.silen/dist` 是默认生产输出,`.silen/.temp` 是临时构建状态,都应视为可重新生成。本地 AI 工作区使用 `wiki/` 保存内容,并用 `.silen/ai/` 保存索引。启用写入前请阅读[工作区边界](/silen/zh/ai/local-workspace-mcp/)。 下一步配置[站点选项](/silen/zh/guide/configuration/)。 激活一个文档目录 从文件夹到知识接口 ```sh pnpm add -D @aicode-nexus/silen pnpm silen init docs pnpm silen dev docs ``` 直接检查证据 当前构建的真实产物 llms.txt 简明语料地图 llms-full.txt 完整可读语料 ai-index.json 结构化页面发现 Agent 清单 版本化能力契约 指南 Markdown 干净的路由级内容 一个内容源,三项证明 同时服务读者、智能体与维护者 人类阅读 AI 消费 可扩展性 开源,也保持克制 一起完善文档基础设施 微信公众号:AI Dev Hub # 集成 Silen 让集成保持显式:插件运行可信构建或客户端代码,分析在站点层配置,Ask AI 只访问你自己运营的端点。三者都不需要导入 Silen 内部文件。 ## 插件 插件是 `.silen/config.ts` 中有序排列的工厂,用于 MDX 处理器、Vite 集成、页面元数据、head、客户端 setup 或构建后产物: ```ts import { defineConfig } from '@aicode-nexus/silen' import readingTime from './plugins/reading-time' export default defineConfig({ plugins: [[readingTime, { wordsPerMinute: 250 }]], }) ``` 每个插件必须有 `name`,配置多个实例时增加 `id`。钩子按配置顺序运行,失败信息会包含插件身份与钩子名称。完整说明见[插件生命周期](/silen/zh/guide/plugins)。 ## 站点分析 分析与主题无关,只在生产构建中输出。可配置 Google、百度或有序的自定义 provider: ```ts analytics: [ { provider: 'google', id: 'G-XXXXXXXXXX' }, { provider: 'baidu', id: 'site-id' }, ] ``` Silen 上报初始页面和客户端路由变化,忽略仅 hash 变化。Google 用户应关闭 Enhanced Measurement 中的自动 history-change pageview,避免重复。自定义 provider 可加载外部或内联脚本并监听 `silen:pageview`。脚本是公开可信代码,不要放密钥。 ## Ask AI Ask AI 是可选主题端点,不捆绑模型 provider: ```ts themeConfig: { ai: { endpoint: '/api/ask' } } ``` ## Ask AI 请求 Silen 通过 HTTP `POST` 发送 `Content-Type: application/json` 请求。请求契约严格如下: ```ts interface AskAiRequest { route: string selectedText?: string messages: Array<{ role: 'user' | 'assistant' content: string }> } ``` `selectedText` 是可选字段;读者未选择正文时应省略。`messages` 可以包含之前的 user 与 assistant 对话。具体请求示例: ```json { "route": "/guide/", "selectedText": "pnpm silen init docs", "messages": [ { "role": "user", "content": "如何开始?" }, { "role": "assistant", "content": "先安装依赖。" } ] } ``` ## Ask AI 响应 成功的流式响应必须使用 `Content-Type: application/x-ndjson` 或 `Content-Type: application/ndjson`。每行写入一个 JSON 对象。事件形状分别是文本 `{ type: 'text', value: string }`、引用 `{ type: 'citation', title: string, url: string }` 与错误 `{ type: 'error', message: string }`: ```ndjson {"type":"text","value":"Install with pnpm."} {"type":"citation","title":"Quick start","url":"/guide/"} {"type":"error","message":"Unable to answer."} ``` Silen 会向请求提供 `AbortSignal`,并在新请求取代旧请求或对话框关闭时触发 abort。把该信号与 HTTP 连接断开视为取消:停止上游 provider 工作并释放资源。 端点负责服务端鉴权。provider key 与原始 provider 错误必须留在服务端,只返回安全的公开错误。未配置端点时,不会生成 Ask AI 控件,也不会生成 Ask AI 客户端 bundle。 无需模型 provider 的确定性访问见[生成产物](/silen/zh/ai/)与[本地 MCP](/silen/zh/ai/local-workspace-mcp/)。 # 插件 此路由为已有书签继续保留。Silen 插件 API 是有序、公开的构建与客户端扩展边界。插件工厂在 `.silen/config.ts` 中配置,接收当前 command 与 root,并返回有名称的插件。 ```ts import { defineConfig, definePlugin } from '@aicode-nexus/silen' const metadata = definePlugin(() => ({ name: 'product-metadata', transformPageData(page) { return { data: { ...page.data, product: 'checkout' } } }, })) export default defineConfig({ plugins: [metadata] }) ``` 公开钩子覆盖配置、解析后配置、Remark/Rehype、Vite、客户端模块、页面数据、head 与构建结束。钩子按配置顺序运行。客户端模块必须兼容 SSR:浏览器 API 应放入 `setup`,而不是模块顶层或 `wrapRoot`。插件包应把 `@aicode-nexus/silen` 声明为 peer dependency,并只导入文档化导出。 插件生命周期、身份、失败信息与打包规则请进入正式[插件指南](/silen/zh/guide/plugins);分析与 Ask AI 见[集成](/silen/zh/integrations/)。 # 参考 本页是紧凑的运行参考;解释与完整示例请阅读链接的指南。 ## 配置 | 字段 | 默认值 | 用途 | | --- | --- | --- | | `title` | `Silen` | 站点标题 | | `description` | 空 | 页面元数据 | | `lang` | `en-US` | 默认 BCP 47 语言 | | `base` | `/` | 规范化部署路径 | | `siteUrl` | 未设置 | canonical HTTP(S) origin | | `outDir` | `.silen/dist` | 相对内容根的输出目录 | | `onBrokenLinks` | `error` | `error`、`warn`、`ignore` | | `themeConfig` | `{}` | 导航、语言、首页、搜索、Ask AI | | `analytics` | `[]` | 有序生产分析 provider | | `plugins` | `[]` | 有序可信插件 | | `ai.*` | 开启 | AI 文件、Markdown、索引、契约 | `base` 必须以 `/` 开头,不含 query/hash 或穿越路径,并规范为结尾斜杠。`siteUrl` 只能是 origin,不含凭证、路径、query 或 fragment。 ## CLI | 命令 | 作用 | | --- | --- | | `silen init ` | 安全创建起始配置与首页 | | `silen dev [root]` | 启动开发,支持 `--host`、`--port` | | `silen build [root]` | 校验并生成静态产物 | | `silen preview [root]` | 预览产物,支持 `--host`、`--port` | | `silen ai [path]` | 管理并评测本地 AI 工作区 | | `silen ai skills ` | 无覆盖地写出包内 `silen-docs-readonly` Skill | | `silen mcp [root]` | 启动只读 MCP;可选 `--allow-write` 与实验性 `--experimental-skills-over-mcp` | 包内可移植 Skill 位于 `dist/agent/skills/silen-docs-readonly`。只有显式使用 `--experimental-skills-over-mcp` 时才会提供 `skill://silen-docs-readonly/SKILL.md`;默认 Agent Contract 仍是 `extensions: []`。 ## MCP 与 Agent Contract 本地 MCP 命令使用 SDK v2 与 `stdio`,验证 `2025-11-25` 和 `2026-07-28`。 默认提供七个只读工具,加入 `--allow-write` 后增加三个写工具;成功调用同时返回 文本与经过校验的 `structuredContent`,不启用远程传输。 Agent Contract manifest 与 API 使用 `schemaVersion: 2`。manifest 声明协议版本 和空扩展集合,API 为每个工具声明 `outputSchema`。 ## AI 评测套件 `.silen/ai-evals.json` 是严格 JSON。版本 1 在 `topK` 内匹配单一路由与可选 标题;版本 2 增加可选的 `expected.maxRank`。版本 3 使用以下严格结构: | 字段 | 要求 | | --- | --- | | `schemaVersion` | 精确整数 `3` | | `topK` | 整数 `1..20` | | `cases` | 1 到 500 个有序案例 | | `expected.acceptable` | 必需数组,包含 0 到 20 个不重复目标 | | `expected.forbidden` | 必需数组,包含 0 到 20 个不重复目标 | | `expected.maxRank` | 必需整数 `1..topK`;纯负例必须精确等于 `topK` | | 目标 | 严格 `{ route, heading? }`;route 以 `/` 开头 | 两个目标数组至少有一个非空。规范化后的重复、数组内部重叠、`acceptable` 与 `forbidden` 之间的重叠,以及未知字段都无效。版本 3 报告保留有序 `cases`、 `matchedRank`、`forbiddenMatches` 与完整诊断 Top K;v1/v2 行为保持兼容。 评测仍然只读且不依赖模型。 仓库维护者运行 `pnpm site:ai-check`;其精确稳定报告位于 `artifacts/ai-eval/site-ai-eval.json`。 ## 排错 **本地链接正常,部署后失败。** 检查托管路径是否匹配 `base`、正文根相对链接是否包含挂载路径,以及托管是否按原样提供嵌套 `index.html`。 **canonical 路径重复。** `siteUrl` 只写 origin,路径只写在 `base`。 **语言切换进入 404。** 在每个语言 root 下创建完全镜像的路由,并加入翻译后的导航。 **构建报告重复路由。** 删除 `topic.mdx` 或 `topic/index.mdx` 之一;二者指向同一路由。 **pnpm 提示忽略 esbuild 构建脚本,且 Silen 随后构建失败。** 执行 `pnpm approve-builds esbuild`,只批准该依赖,然后重新安装并重试。如果构建已经成功,则无需批准。 **MCP 没有写工具。** 这是安全默认值。只有用户明确授权有边界的写任务后,才加入 `--allow-write`。 深入阅读[配置](/silen/zh/guide/configuration/)与 [CLI/部署](/silen/zh/guide/cli-deployment/)。 # 主题扩展与无障碍 令牌与配置不够时再扩展默认主题。主题可以替换布局或 MDX 组件、提供自定义 404、包装 React 根节点,同时继承其余能力。 ```tsx // docs/.silen/theme.tsx import type { ReactNode } from 'react' import DefaultTheme, { defineTheme } from '@aicode-nexus/silen/theme' import './custom.css' function Note({ children }: { readonly children?: ReactNode }) { return } export default defineTheme({ extends: DefaultTheme, components: { Note }, wrapRoot({ children }) { return
{children}
}, }) ``` `defineTheme` 按 key 合并继承的布局和组件;未替换时继续继承 `NotFound`。基础主题和扩展都定义 `wrapRoot` 时,扩展包装器组合在外层。递归扩展会被拒绝。 ## SSR 安全 主题模块与根包装器会同时参与服务端渲染和 hydration。不要在模块顶层或 render 中直接读取 `window`、`document`、`localStorage`。浏览器行为放入 effect 或插件客户端 `setup`,注册监听器时返回清理函数。 ## 无障碍契约 默认外壳包含跳转正文链接和清晰焦点样式。移动导航是带标签的模态框:打开后焦点进入导航,Escape 关闭,焦点返回触发按钮。搜索支持快捷键、方向键、Enter、Escape 与焦点恢复;代码复制是带实时状态文本的按钮。 外观控件是明确的深色/系统/浅色单选组。head 内联脚本在 hydration 前应用已保存偏好,避免颜色闪烁;系统模式会跟随操作系统变化。非必要过渡遵循 reduced motion。 替换交互组件时,保留可访问名称、键盘路径、焦点行为与 SSR 降级。上线前用纯键盘、200% 缩放和 reduced motion 检查。 # 主题、布局与导航 默认主题是一套响应式文档外壳,而不是封闭模板。它提供导航、侧栏、页面大纲、本地搜索、外观控制、代码复制、翻页、首页 hero 与完整 404。优先使用配置;只有产品要求无法通过配置表达时才扩展 React。 ## 布局 在 frontmatter 中选择布局: ```md --- layout: doc --- ``` - `doc` 是默认布局,提供阅读排版、标题大纲,以及从侧栏推导的上一篇/下一篇。 - `home` 在页面 MDX 前渲染当前语言的 hero 与可选功能区,并使用全宽外壳。 - `page` 保留导航和中性文章容器,但不显示文档翻页。 首页 hero 可分别配置亮色与暗色图片,并共用一个无障碍说明: ```ts themeConfig: { home: { hero: { image: { src: '/workflow-light.jpg', darkSrc: '/workflow-dark.jpg', alt: '文档工作流', }, }, }, } ``` ## 导航与侧栏 ```ts themeConfig: { logo: { src: '/logo.svg', alt: '产品文档' }, nav: [ { text: '指南', link: '/guide/' }, { text: 'GitHub', link: 'https://github.com/example/project' }, ], sidebar: [ { text: '开始使用', items: [{ text: '快速开始', link: '/guide/' }], }, ], } ``` 内部主题链接会按 `base` 解析。HTTP(S) 导航链接会在当前上下文中按浏览器普通导航处理。nav 条目只传递 `href`,不会自动增加新上下文或关系属性。确实需要新上下文时,MDX 正文链接可显式设置 `target="_blank"` 与 `rel="noopener noreferrer"`。960px 以下,固定侧栏变成带标签、分组可折叠的模态 Sheet;桌面宽度下,每个分组都以语义化区段持续显示在正文旁,当前页面使用主题主色突出显示。 ## 搜索 除非 `themeConfig.search` 为 `false`,否则本地搜索默认开启。搜索按需加载,可通过按钮或 `Control+K` / `Command+K` 打开,支持键盘选择,并在关闭后恢复焦点。search v2 记录页面语言,让当前语言结果得到正确排序与分组。 ## 多语言 locale 条目定义 BCP 47 `lang`、显示标签与路由 `root`,并可覆盖导航、侧栏、首页与界面消息。路由镜像后,语言切换会保留当前页面。匹配长度最长的已配置 locale root 决定文档与搜索语言。frontmatter `lang` 不会覆盖解析后的路由语言;需要另一种语言的内容应放在对应 locale root 下。 视觉定制使用[主题令牌](/silen/zh/theme/tokens/),React 行为使用[主题扩展](/silen/zh/theme/extensions-accessibility/)。 # 主题令牌 覆盖语义 CSS 变量,不要依赖内部 utility class。令牌是默认主题行为与项目视觉身份之间稳定的边界。 ```css /* docs/.silen/custom.css */ :root { --silen-primary: oklch(0.55 0.17 245); --silen-primary-foreground: oklch(0.99 0 0); --silen-radius: 0.5rem; --silen-content-width: 48rem; } .dark { --silen-primary: oklch(0.76 0.12 245); } ``` 从 `.silen/theme.tsx` 导入样式,让 Vite 同时把它加入 SSR 与客户端构建。 ## 颜色令牌 核心语义集合包括 `--silen-background`、`--silen-foreground`、`--silen-card`、`--silen-primary`、`--silen-primary-foreground`、`--silen-muted`、`--silen-muted-foreground`、`--silen-border`、`--silen-input`、`--silen-ring` 与 `--silen-destructive`。secondary、accent、popover 令牌为交互组件提供同样的语义层。 浅色值写在 `:root`,深色覆盖写在 `.dark`。保持前景/背景以及 primary/primary-foreground 之间的可读对比;外观控件允许用户明确选择深色、跟随系统或浅色。 ## 形状与布局 - `--silen-radius` 控制统一圆角。 - `--silen-nav-height` 定义顶部导航高度。 - `--silen-sidebar-width` 控制桌面侧栏。 - `--silen-content-width` 限制正文阅读宽度。 - `--silen-layout-width` 限制首页与 page 布局宽度。 每次只调整一层,并检查长标题、代码块、两种配色与移动导航。更宽不一定更好,正文过宽会降低扫读效率。 令牌适合视觉变化;新增 MDX 组件、包装器、布局或 404 时再使用[主题扩展](/silen/zh/theme/extensions-accessibility/)。