diff --git a/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.i18n.yaml b/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.i18n.yaml index aa4b87ee6a..364bbd3bb6 100644 --- a/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.i18n.yaml +++ b/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-13-documentation-site-projection.md -2026-07-13-documentation-site-projection.md: e8e3070164d9e90dea6406b545067d5fc221550a -2026-07-13-documentation-site-projection.zh.md: 50862ad79cf8b1099c6ef940a12d09098baa0524 +2026-07-13-documentation-site-projection.md: 46462fcf52dd3adfc10127acfd1917f0d1209d55 +2026-07-13-documentation-site-projection.zh.md: 48237c5702d71b6c4e83f8e2c6f14bd7fb879bb0 diff --git a/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.md b/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.md index e8e3070164..46462fcf52 100644 --- a/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.md +++ b/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.md @@ -26,7 +26,7 @@ The projector parses Markdown links without reserializing the document. A link t Mermaid renders the canonical diagrams. The website workspace explicitly declares the five packages that `vitepress-plugin-mermaid` asks Vite to prebundle because pnpm's strict dependency isolation otherwise makes those transitive packages unavailable to the local development server; Knip records this runtime-only use as an intentional dependency exception. -The configured Markdown renderer keeps a build-local cache for non-Mermaid code fences, keyed by the exact content, info string, delimiter, and token attributes. The bilingual projection repeats 886 of its 1,748 code fences, so Shiki renders each distinct representation once. Mermaid fences bypass the cache because the plugin output includes a token-position id. The cache is discarded with the renderer after each build and preserves the emitted fence HTML. +The configured Markdown renderer keeps a build-local cache for non-Mermaid, non-snippet code fences, keyed by the exact content, info string, delimiter, and token attributes. About half of the bilingual projection's code fences repeat, so Shiki renders each distinct representation once. Mermaid fences bypass the cache because the plugin output includes a token-position id, and VitePress snippets resolve their source files during rendering. The cache is enabled only for production builds, is discarded with the renderer after each build, and does not change the emitted fence HTML. Site publication remains separate from site construction. A dedicated GitHub Actions workflow runs the existing documentation gates, uploads `website/.dist` as a Pages artifact, and deploys only after the build succeeds. `actions/configure-pages` supplies the destination's base path to VitePress at build time, so the private Pages origin, a later public project path, and a custom domain do not require distinct checked-in configurations. Pages visibility remains a repository hosting setting rather than a workflow permission. diff --git a/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.zh.md b/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.zh.md index 50862ad79c..48237c5702 100644 --- a/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.zh.md +++ b/.agents/notes/implemented/process/2026-07-13-documentation-site-projection.zh.md @@ -26,7 +26,7 @@ Status: implemented Mermaid 渲染权威图表。网站工作区显式声明 `vitepress-plugin-mermaid` 要求 Vite 预打包的 5 个包,因为 pnpm 的严格依赖隔离会使本地开发服务器无法使用这些传递依赖;Knip 将这种仅运行时使用记录为有意的依赖例外。 -配置后的 Markdown 渲染器会在单次构建期间缓存非 Mermaid 代码围栏,缓存键包含确切正文、info string、分隔符和 token 属性。双语投影的 1748 个代码围栏中有 886 个是重复内容,因此 Shiki 只渲染一次每种不同表示。Mermaid 围栏不会进入缓存,因为插件输出包含 token 位置 id。每次构建后,缓存会随渲染器一同丢弃,并且不会改变生成的围栏 HTML。 +配置后的 Markdown 渲染器会在单次构建期间缓存非 Mermaid、非 snippet 代码围栏,缓存键包含确切正文、info string、分隔符和 token 属性。双语投影中约半数代码围栏是重复内容,因此 Shiki 只渲染一次每种不同表示。Mermaid 围栏不会进入缓存,因为插件输出包含 token 位置 id;VitePress snippet 则在渲染期间解析源文件。缓存仅在生产构建中启用,每次构建后会随渲染器一同丢弃,并且不会改变生成的围栏 HTML。 网站发布与网站构建保持分离。专用 GitHub Actions 工作流运行现有文档门禁,将 `website/.dist` 作为 Pages 产物上传,并只在构建成功后部署。`actions/configure-pages` 在构建时向 VitePress 提供目标位置的 base path,因此私有 Pages 源站、未来的公开项目路径和自定义域名不需要各自的检入配置。Pages 可见性仍是仓库托管设置,而不是工作流权限。 diff --git a/website/.vitepress/config.ts b/website/.vitepress/config.ts index ec1b1a95c9..6798d1452a 100644 --- a/website/.vitepress/config.ts +++ b/website/.vitepress/config.ts @@ -331,9 +331,9 @@ export default withMermaid({ const renderText = md.renderer.rules.text const renderCode = md.renderer.rules.code_inline const renderFence = md.renderer.rules.fence - if (renderText === undefined || renderCode === undefined || renderFence === undefined) { - throw new Error('VitePress Markdown renderer is missing a required rendering rule.') - } + if (renderText === undefined) throw new Error('VitePress Markdown renderer is missing the text rendering rule.') + if (renderCode === undefined) throw new Error('VitePress Markdown renderer is missing the inline-code rendering rule.') + if (renderFence === undefined) throw new Error('VitePress Markdown renderer is missing the fence rendering rule.') md.renderer.rules.text = (...args) => escapeVueInterpolation(renderText(...args)) md.renderer.rules.code_inline = (...args) => escapeVueInterpolation(renderCode(...args)) const renderedFences = new Map() @@ -341,8 +341,11 @@ export default withMermaid({ const [tokens, index] = args const token = tokens[index] if (token === undefined) throw new Error('VitePress code-fence renderer received no token.') - // Mermaid output embeds the token position, so only Shiki fences are reusable. + // Mermaid output embeds the token position, and VitePress snippets resolve source files during rendering. if (['mermaid', 'mmd'].includes(token.info.trim().split(/\s+/, 1)[0] ?? '')) return renderFence(...args) + if (Reflect.get(token, 'src') !== undefined) return renderFence(...args) + // Keep the cache build-local; a dev renderer can survive many HMR updates. + if (process.env.NODE_ENV !== 'production') return renderFence(...args) const key = JSON.stringify([token.content, token.info, token.markup, token.attrs]) const cached = renderedFences.get(key) if (cached !== undefined) return cached