@pagesmith/docs 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site-dJ3MiiW3.mjs","names":["createNetServer"],"sources":["../src/config.ts","../src/markdown/plugins/rehype-asset-transform.ts","../src/content.ts","../src/navigation.ts","../theme/components/DocFooter.tsx","../theme/components/DocHeader.tsx","../theme/components/DocSidebar.tsx","../theme/components/Html.tsx","../theme/layouts/DocHome.tsx","../theme/layouts/DocNotFound.tsx","../theme/components/DocTOC.tsx","../theme/layouts/DocPage.tsx","../src/render.ts","../src/build.ts","../src/server.ts"],"sourcesContent":["import type { MarkdownConfig } from '@pagesmith/core/markdown'\nimport { execSync } from 'child_process'\nimport { existsSync, readFileSync, readdirSync, statSync } from 'fs'\nimport JSON5 from 'json5'\nimport { basename, dirname, join, resolve } from 'path'\nimport { fileURLToPath } from 'url'\n\ntype FooterLink = {\n label: string\n path: string\n}\n\nexport type DocsUserConfig = {\n name?: string\n title?: string\n description?: string\n origin?: string\n language?: string\n contentDir?: string\n outDir?: string\n publicDir?: string\n /** Base path for deployment under a subdirectory (e.g. '/docs'). Overridden by BASE_URL env var. */\n basePath?: string\n /** Override the header logo link destination (defaults to basePath). */\n homeLink?: string\n footerLinks?: FooterLink[]\n sidebar?: {\n /** Enable collapsible sidebar section groups (default: false) */\n collapsible?: boolean\n }\n search?: {\n enabled?: boolean\n /** Show images in search results (default: false) */\n showImages?: boolean\n /** Show sub-results/sections within pages (default: true) */\n showSubResults?: boolean\n /** Extra CLI flags passed to the pagefind binary */\n pagefindFlags?: string[]\n }\n theme?: {\n lightColor?: string\n darkColor?: string\n layouts?: Record<string, string>\n /** Path to default social sharing image, relative to publicDir or an absolute URL */\n socialImage?: string\n }\n analytics?: {\n googleAnalytics?: string\n }\n /** Path to favicon file relative to project root. Defaults to 'public/favicon.svg'. Set to false to disable. */\n favicon?: string | false\n /** Show \"Edit this page\" link on each page. */\n editLink?: {\n /** GitHub/GitLab repo URL (e.g. 'https://github.com/user/repo') */\n repo: string\n /** Branch name (default: 'main') */\n branch?: string\n /** Label for the link (default: 'Edit this page') */\n label?: string\n }\n /** Show git-based \"last updated\" timestamp on pages (default: false) */\n lastUpdated?: boolean\n /** Generate sitemap.xml during build (default: true when origin is set). Set false to disable. */\n sitemap?: boolean\n markdown?: MarkdownConfig\n home?: {\n configFile?: string\n }\n /** Optional multi-package navigation labels. Maps section slug to display label. */\n packages?: Record<string, { label: string }>\n /**\n * Map output paths to source files/folders that should be copied to the build output.\n * Keys are output directory paths (e.g. \"/\" for root, \"/api\" for api/).\n * Values are arrays of file or folder names resolved relative to the project root.\n * Folders are copied recursively.\n *\n * @example\n * ```json5\n * { assets: { \"/\": [\"llms.txt\", \"robots.txt\"], \"/api\": [\"openapi.json\"] } }\n * ```\n */\n assets?: Record<string, string[]>\n /** Server port and behavior settings for dev and preview commands. */\n server?: {\n /** Default port for the dev server (default: 3000). */\n devPort?: number\n /** Default port for the preview server (default: 4000). */\n previewPort?: number\n /** When true, fail if the configured port is in use instead of finding the next available port (default: false). */\n strictPort?: boolean\n }\n}\n\nexport type ResolvedDocsConfig = {\n rootDir: string\n contentDir: string\n outDir: string\n publicDir: string\n basePath: string\n homeLink?: string\n name: string\n title: string\n description: string\n origin: string\n language: string\n footerLinks: FooterLink[]\n sidebar: {\n collapsible: boolean\n }\n search: {\n enabled: boolean\n showImages: boolean\n showSubResults: boolean\n pagefindFlags: string[]\n }\n theme?: {\n lightColor?: string\n darkColor?: string\n layouts?: Record<string, string>\n }\n analytics?: {\n googleAnalytics?: string\n }\n /** Resolved path to default social sharing image, or undefined if not set. */\n socialImage?: string\n /** Resolved absolute path to favicon file, or false if disabled. */\n favicon: string | false\n /** Resolved absolute path to apple-touch-icon, or false if not found. */\n appleTouchIcon: string | false\n /** Resolved absolute path to ICO fallback (when primary favicon is SVG), or false. */\n faviconFallback: string | false\n editLink?: {\n repo: string\n branch: string\n label: string\n /** Pre-computed edit URL pattern (includes host-specific path structure). */\n editPattern: string\n }\n lastUpdated: boolean\n sitemap: boolean\n markdown?: MarkdownConfig\n homeConfigFile?: string\n packages?: Record<string, { label: string }>\n /** Resolved asset mappings: output path → array of resolved absolute source paths. */\n assets: Map<string, string[]>\n /** Resolved server settings. */\n server: {\n devPort: number\n previewPort: number\n strictPort: boolean\n }\n /** @internal Raw user config — used by validateConfig to distinguish explicit values from fallbacks. */\n _userConfig?: DocsUserConfig\n}\n\nexport type DocsBuildOptions = {\n configPath?: string\n /** Override output directory from CLI (takes precedence over config). */\n outDir?: string\n /** Override base path from CLI (takes precedence over config and BASE_URL env). */\n basePath?: string\n}\n\nexport type DocsDevOptions = DocsBuildOptions & {\n port?: number\n open?: boolean\n}\n\nexport function defineDocsConfig(config: DocsUserConfig): DocsUserConfig {\n return config\n}\n\nexport function loadDocsConfig(configPath?: string): DocsUserConfig {\n const resolvedConfigPath = resolve(configPath ?? join(process.cwd(), 'pagesmith.config.json5'))\n if (!existsSync(resolvedConfigPath)) {\n return {}\n }\n\n return JSON5.parse(readFileSync(resolvedConfigPath, 'utf-8')) as DocsUserConfig\n}\n\n/** Prefix a path with a base path, avoiding double slashes. */\nexport function withBase(basePath: string, path: string): string {\n const base = basePath.replace(/\\/+$/, '')\n if (!base) return path\n if (path.startsWith(base)) return path\n return `${base}${path.startsWith('/') ? '' : '/'}${path}`\n}\n\ntype GitOriginInfo = {\n basePath?: string\n origin?: string\n repoName?: string\n editLinkHost?: 'github' | 'gitlab' | 'bitbucket'\n}\n\n/** Detect basePath and origin from git remote URL. */\nexport function detectGitOrigin(rootDir: string): GitOriginInfo | undefined {\n try {\n const remoteUrl = execSync('git remote get-url origin', {\n cwd: rootDir,\n stdio: ['pipe', 'pipe', 'pipe'],\n encoding: 'utf-8',\n }).trim()\n\n // GitHub HTTPS: https://github.com/owner/repo.git\n // GitHub SSH: git@github.com:owner/repo.git\n let match = remoteUrl.match(/github\\.com[:/]([^/]+)\\/([^/.]+?)(?:\\.git)?$/)\n if (match) {\n const [, owner, repo] = match\n return {\n basePath: `/${repo}`,\n origin: `https://${owner}.github.io`,\n repoName: repo,\n editLinkHost: 'github',\n }\n }\n\n // GitLab HTTPS/SSH\n match = remoteUrl.match(/gitlab\\.com[:/]([^/]+)\\/([^/.]+?)(?:\\.git)?$/)\n if (match) {\n const [, owner, repo] = match\n return {\n basePath: `/${repo}`,\n origin: `https://${owner}.gitlab.io`,\n repoName: repo,\n editLinkHost: 'gitlab',\n }\n }\n\n // Bitbucket HTTPS/SSH\n match = remoteUrl.match(/bitbucket\\.org[:/]([^/]+)\\/([^/.]+?)(?:\\.git)?$/)\n if (match) {\n const [, , repo] = match\n return {\n basePath: `/${repo}`,\n repoName: repo,\n editLinkHost: 'bitbucket',\n }\n }\n } catch {\n // Not a git repo or git not installed — skip silently\n }\n return undefined\n}\n\nfunction readPackageJson(\n rootDir: string,\n): { name?: string; description?: string; homepage?: string } | undefined {\n const pkgPath = join(rootDir, 'package.json')\n if (!existsSync(pkgPath)) return undefined\n try {\n return JSON.parse(readFileSync(pkgPath, 'utf-8'))\n } catch {\n return undefined\n }\n}\n\nfunction resolveContentDir(rootDir: string, explicit?: string): string {\n if (explicit) return resolve(rootDir, explicit)\n const docsDir = resolve(rootDir, 'docs')\n if (existsSync(docsDir)) return docsDir\n return resolve(rootDir, 'content')\n}\n\nexport function resolveDocsConfig(\n configPath?: string,\n overrides?: { outDir?: string; basePath?: string },\n): ResolvedDocsConfig {\n const resolvedConfigPath = resolve(configPath ?? join(process.cwd(), 'pagesmith.config.json5'))\n const rootDir = dirname(resolvedConfigPath)\n const userConfig = loadDocsConfig(resolvedConfigPath)\n const packageName = basename(rootDir)\n const pkg = readPackageJson(rootDir)\n const pkgDisplayName = pkg?.name?.replace(/^@[^/]+\\//, '')\n\n // Detect git origin for smart defaults\n const gitInfo = detectGitOrigin(rootDir)\n\n // CLI flag > BASE_URL env > config basePath > git-detected > default '/'\n const rawBase =\n overrides?.basePath ?? process.env.BASE_URL ?? userConfig.basePath ?? gitInfo?.basePath ?? '/'\n const basePath = rawBase.replace(/\\/+$/, '') // strip trailing slash, '/' becomes ''\n\n const contentDir = resolveContentDir(rootDir, userConfig.contentDir)\n const publicDir = resolve(rootDir, userConfig.publicDir ?? 'public')\n\n // Resolve favicon path\n let resolvedFavicon: string | false\n let resolvedFaviconFallback: string | false = false\n if (userConfig.favicon === false) {\n resolvedFavicon = false\n } else if (typeof userConfig.favicon === 'string') {\n resolvedFavicon = resolve(rootDir, userConfig.favicon)\n } else {\n // Default: check public/favicon.svg, then public/favicon.ico, then bundled default\n const svgPath = join(publicDir, 'favicon.svg')\n const icoPath = join(publicDir, 'favicon.ico')\n if (existsSync(svgPath)) {\n resolvedFavicon = svgPath\n // When SVG is primary, offer ICO as fallback for older browsers\n if (existsSync(icoPath)) {\n resolvedFaviconFallback = icoPath\n }\n } else if (existsSync(icoPath)) {\n resolvedFavicon = icoPath\n } else {\n const corePkgDir = dirname(fileURLToPath(import.meta.resolve('@pagesmith/core/package.json')))\n resolvedFavicon = join(corePkgDir, 'assets', 'favicon.svg')\n }\n }\n\n // Detect apple-touch-icon in public directory\n const appleTouchIconPath = join(publicDir, 'apple-touch-icon.png')\n const resolvedAppleTouchIcon = existsSync(appleTouchIconPath) ? appleTouchIconPath : false\n\n // Resolve asset mappings\n const assets = new Map<string, string[]>()\n if (userConfig.assets) {\n for (const [outputPath, sources] of Object.entries(userConfig.assets)) {\n const resolved = sources.map((source) => resolve(rootDir, source))\n assets.set(outputPath, resolved)\n }\n }\n\n // Resolve default social image (config > convention > none)\n let socialImage: string | undefined\n if (userConfig.theme?.socialImage) {\n socialImage = userConfig.theme.socialImage\n } else {\n for (const ext of ['png', 'jpg', 'jpeg']) {\n if (existsSync(join(publicDir, `og-image.${ext}`))) {\n socialImage = `og-image.${ext}`\n break\n }\n }\n }\n\n // Resolve editLink with multi-host support\n let editLink: ResolvedDocsConfig['editLink']\n if (userConfig.editLink) {\n const repo = userConfig.editLink.repo.replace(/\\/+$/, '')\n const branch = userConfig.editLink.branch ?? 'main'\n const label = userConfig.editLink.label ?? 'Edit this page'\n // Auto-detect host from repo URL\n let editPattern: string\n if (repo.includes('gitlab.com') || repo.includes('gitlab.')) {\n editPattern = `${repo}/-/edit/${branch}`\n } else if (repo.includes('bitbucket.org') || repo.includes('bitbucket.')) {\n editPattern = `${repo}/src/${branch}`\n } else {\n // Default: GitHub-style\n editPattern = `${repo}/edit/${branch}`\n }\n editLink = { repo, branch, label, editPattern }\n }\n\n return {\n rootDir,\n contentDir,\n outDir: overrides?.outDir ?? resolve(rootDir, userConfig.outDir ?? 'gh-pages'),\n publicDir,\n basePath,\n homeLink: userConfig.homeLink,\n name: userConfig.name ?? userConfig.title ?? pkgDisplayName ?? packageName,\n title: userConfig.title ?? userConfig.name ?? pkgDisplayName ?? packageName,\n description:\n userConfig.description ?? pkg?.description ?? 'Documentation site powered by @pagesmith/docs',\n origin: userConfig.origin ?? pkg?.homepage ?? gitInfo?.origin ?? 'https://example.com',\n language: userConfig.language ?? 'en',\n footerLinks: userConfig.footerLinks ?? [],\n search: {\n enabled: userConfig.search?.enabled ?? true,\n showImages: userConfig.search?.showImages ?? false,\n showSubResults: userConfig.search?.showSubResults ?? true,\n pagefindFlags: userConfig.search?.pagefindFlags ?? [],\n },\n sidebar: {\n collapsible: userConfig.sidebar?.collapsible ?? true,\n },\n favicon: resolvedFavicon,\n faviconFallback: resolvedFaviconFallback,\n appleTouchIcon: resolvedAppleTouchIcon,\n editLink,\n lastUpdated: userConfig.lastUpdated ?? false,\n sitemap: userConfig.sitemap ?? true,\n socialImage,\n theme: userConfig.theme,\n analytics: userConfig.analytics,\n markdown: userConfig.markdown,\n homeConfigFile: userConfig.home?.configFile\n ? resolve(rootDir, userConfig.home.configFile)\n : resolve(rootDir, contentDir, 'home.json5'),\n packages: userConfig.packages,\n server: {\n devPort: userConfig.server?.devPort ?? 3000,\n previewPort: userConfig.server?.previewPort ?? 4000,\n strictPort: userConfig.server?.strictPort ?? false,\n },\n assets,\n _userConfig: userConfig,\n }\n}\n\nexport function readJson5File<T>(filePath: string): T | undefined {\n if (!existsSync(filePath)) return undefined\n return JSON5.parse(readFileSync(filePath, 'utf-8')) as T\n}\n\nexport function toTitleCase(value: string): string {\n return value.replace(/[-_]/g, ' ').replace(/\\b\\w/g, (char) => char.toUpperCase())\n}\n\nexport function getPackageDir(): string {\n return resolve(import.meta.dirname, '..')\n}\n\nexport function getThemeRoot(): string {\n return resolve(getPackageDir(), 'theme')\n}\n\nexport function getThemeStylesEntry(): string {\n return resolve(getThemeRoot(), 'styles/main.css')\n}\n\nexport function getThemeRuntimeEntry(): string {\n return resolve(getThemeRoot(), 'runtime/main.ts')\n}\n\nexport type ConfigValidationIssue = {\n field: string\n message: string\n severity: 'error' | 'warn'\n}\n\n/**\n * Validate a resolved docs config. Returns issues found.\n * Checks required fields, verifies referenced directories and asset files exist.\n */\nexport function validateConfig(config: ResolvedDocsConfig): ConfigValidationIssue[] {\n const issues: ConfigValidationIssue[] = []\n\n // Required field checks — only warn when neither name nor title was explicitly set\n // by the user (the resolved config always has a value due to fallback chain).\n const uc = config._userConfig\n const hasExplicitName = uc ? !!(uc.name || uc.title) : config.name !== basename(config.rootDir)\n const hasExplicitTitle = uc ? !!(uc.title || uc.name) : config.title !== basename(config.rootDir)\n\n if (!hasExplicitName) {\n issues.push({\n field: 'name',\n message: 'Missing \"name\" in pagesmith.config.json5 — using directory name as fallback.',\n severity: 'warn',\n })\n }\n\n if (!hasExplicitTitle) {\n issues.push({\n field: 'title',\n message: 'Missing \"title\" in pagesmith.config.json5 — using directory name as fallback.',\n severity: 'warn',\n })\n }\n\n if (config.description === 'Documentation site powered by @pagesmith/docs') {\n issues.push({\n field: 'description',\n message: 'Missing \"description\" in pagesmith.config.json5 — using default placeholder.',\n severity: 'warn',\n })\n }\n\n if (config.origin === 'https://example.com') {\n issues.push({\n field: 'origin',\n message:\n 'Missing \"origin\" in pagesmith.config.json5 — canonical URLs will use https://example.com. Set this to your production URL.',\n severity: 'warn',\n })\n }\n\n // Directory existence checks\n if (!existsSync(config.contentDir)) {\n issues.push({\n field: 'contentDir',\n message: `Content directory does not exist: ${config.contentDir}`,\n severity: 'error',\n })\n }\n\n if (!existsSync(config.publicDir)) {\n // publicDir is optional — just a quiet info, not even a warn\n }\n\n // Asset mapping checks\n for (const [outputPath, sources] of config.assets) {\n for (const sourcePath of sources) {\n if (!existsSync(sourcePath)) {\n issues.push({\n field: `assets[\"${outputPath}\"]`,\n message: `Asset source does not exist: ${sourcePath}`,\n severity: 'error',\n })\n }\n }\n }\n\n // Favicon check\n if (typeof config.favicon === 'string' && !existsSync(config.favicon)) {\n issues.push({\n field: 'favicon',\n message: `Favicon file does not exist: ${config.favicon}`,\n severity: 'warn',\n })\n }\n\n // Layout override checks\n if (config.theme?.layouts) {\n for (const [layoutName, layoutPath] of Object.entries(config.theme.layouts)) {\n const resolvedLayout = resolve(config.rootDir, layoutPath)\n if (!existsSync(resolvedLayout)) {\n issues.push({\n field: `theme.layouts.${layoutName}`,\n message: `Layout file does not exist: ${resolvedLayout}`,\n severity: 'error',\n })\n }\n }\n }\n\n return issues\n}\n\n/**\n * Log validation issues to console. Returns true if there are any errors (severity: 'error').\n */\nexport function reportConfigIssues(issues: ConfigValidationIssue[]): boolean {\n let hasErrors = false\n for (const issue of issues) {\n if (issue.severity === 'error') {\n console.error(`\\x1b[31m✗ [${issue.field}]\\x1b[0m ${issue.message}`)\n hasErrors = true\n } else {\n console.warn(`\\x1b[33m⚠ [${issue.field}]\\x1b[0m ${issue.message}`)\n }\n }\n return hasErrors\n}\n","/**\n * Rehype plugin: transform relative asset references to /assets/ URLs.\n *\n * Converts references like `./image.png` or `./assets/image.png`\n * into site-relative URLs like `/assets/image.png`.\n *\n * Special handling:\n * - `.inline.svg` files: read from disk and embed as inline SVG (supports currentColor)\n * - `.invert.` files: add `invert-on-dark` class for CSS dark-mode inversion\n *\n * Handles <img src=\"...\">, <source srcset=\"...\">, and <a href=\"...\"> for asset files.\n */\n\nimport { existsSync, readFileSync } from 'fs'\nimport type { Element, Root } from 'hast'\nimport { basename, join } from 'path'\nimport { SKIP, visit } from 'unist-util-visit'\n\nconst ASSET_EXTS = /\\.(svg|png|jpg|jpeg|gif|webp|avif|ico)$/i\n\ninterface AssetTransformOptions {\n contentDir?: string\n}\n\nexport function rehypeAssetTransform(options: AssetTransformOptions = {}) {\n return (tree: Root) => {\n visit(tree, 'element', (node: Element, index, parent) => {\n // Transform img src\n if (node.tagName === 'img') {\n const src = node.properties?.src\n if (typeof src !== 'string' || !src.startsWith('./') || !ASSET_EXTS.test(src)) return\n\n // Inline SVG: embed content directly in HTML\n if (src.endsWith('.inline.svg') && options.contentDir) {\n const filePath = join(options.contentDir, src.replace('./', ''))\n if (existsSync(filePath)) {\n let svgContent = readFileSync(filePath, 'utf-8')\n // Strip XML declaration and DOCTYPE\n svgContent = svgContent.replace(/<\\?xml[^?]*\\?>\\s*/g, '')\n svgContent = svgContent.replace(/<!DOCTYPE[^>]*>\\s*/g, '')\n // Add accessibility and styling attributes to root <svg>\n const alt = node.properties?.alt || ''\n svgContent = svgContent.replace(\n '<svg',\n `<svg role=\"img\" aria-label=\"${String(alt).replace(\n /\"/g,\n '&quot;',\n )}\" class=\"inline-svg\"`,\n )\n if (parent && index !== undefined) {\n ;(parent.children as any[])[index] = { type: 'raw', value: svgContent }\n return SKIP\n }\n }\n }\n\n node.properties = node.properties || {}\n node.properties.src = `/assets/${basename(src)}`\n\n // Add invert class for .invert. images\n if (basename(src).includes('.invert.')) {\n const existing = node.properties.className\n node.properties.className = existing\n ? ([...(Array.isArray(existing) ? existing : [existing]), 'invert-on-dark'] as (\n | string\n | number\n )[])\n : ['invert-on-dark']\n }\n }\n\n // Transform source srcset (for <picture> elements)\n if (node.tagName === 'source') {\n const srcset = node.properties?.srcset\n if (typeof srcset === 'string' && srcset.startsWith('./') && ASSET_EXTS.test(srcset)) {\n node.properties = node.properties || {}\n node.properties.srcset = `/assets/${basename(srcset)}`\n }\n }\n\n // Transform a href pointing to asset files\n if (node.tagName === 'a') {\n const href = node.properties?.href\n if (typeof href === 'string' && href.startsWith('./') && ASSET_EXTS.test(href)) {\n node.properties = node.properties || {}\n node.properties.href = `/assets/${basename(href)}`\n }\n }\n })\n }\n}\n","import { processMarkdown, type MarkdownConfig } from '@pagesmith/core/markdown'\nimport type { Heading } from '@pagesmith/core/schemas'\nimport { execFileSync } from 'child_process'\nimport { existsSync, readFileSync, readdirSync } from 'fs'\nimport { availableParallelism } from 'os'\nimport { dirname, extname, join, relative } from 'path'\nimport { z } from 'zod'\nimport { readJson5File, toTitleCase, type ResolvedDocsConfig } from './config.js'\nimport { rehypeAssetTransform } from './markdown/plugins/rehype-asset-transform'\n\nexport type NavItem = {\n label: string\n path: string\n}\n\nexport type SidebarItem = {\n title: string\n path: string\n children?: SidebarItem[]\n}\n\nexport type SidebarSection = {\n title: string\n slug: string\n collapsed?: boolean\n items: SidebarItem[]\n}\n\nexport type PrevNextLink = {\n title: string\n path: string\n}\n\nexport type DocsRootMeta = {\n displayName?: string\n description?: string\n headerLinks?: Array<{ label: string; path: string }>\n footerLinks?: Array<{ label: string; path: string }>\n}\n\nexport type DocsSectionMeta = {\n displayName?: string\n description?: string\n layout?: string\n itemLayout?: string\n orderBy?: 'manual' | 'publishedDate'\n /** Start the sidebar section collapsed (only effective when sidebar.collapsible is true) */\n collapsed?: boolean\n items?: string[]\n series?: Array<{\n slug: string\n displayName: string\n shortName?: string\n description?: string\n articles: string[]\n }>\n}\n\nexport const DocsFrontmatterSchema = z\n .object({\n title: z.string().optional(),\n description: z.string().optional(),\n navLabel: z.string().optional(),\n sidebarLabel: z.string().optional(),\n order: z.number().optional(),\n draft: z.boolean().optional(),\n socialImage: z.string().optional(),\n hero: z.record(z.string(), z.any()).optional(),\n features: z.array(z.record(z.string(), z.any())).optional(),\n })\n .passthrough()\n\nexport type DocsFrontmatter = z.infer<typeof DocsFrontmatterSchema>\n\nexport type DocsPage = {\n title: string\n routePath: string\n contentSlug: string\n section?: string\n frontmatter: DocsFrontmatter\n html: string\n headings: Heading[]\n sourcePath: string\n isHome: boolean\n layoutName: string\n lastUpdated?: string\n}\n\nexport type SiteModel = {\n navItems: NavItem[]\n sidebarBySection: Map<string, SidebarSection[]>\n pageByPath: Map<string, DocsPage>\n rootMeta?: DocsRootMeta\n sectionMetas: Map<string, DocsSectionMeta>\n}\n\nexport const CONTENT_ASSET_EXTS = new Set([\n '.svg',\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.webp',\n '.avif',\n '.ico',\n])\n\nexport function toContentSlug(filePath: string, contentDir: string): string {\n const ext = extname(filePath)\n let slug = relative(contentDir, filePath).replace(/\\\\/g, '/')\n\n if (ext) {\n slug = slug.slice(0, -ext.length)\n }\n\n if (slug === 'README' || slug === 'index') return '/'\n if (slug.endsWith('/README')) slug = slug.slice(0, -7)\n if (slug.endsWith('/index')) slug = slug.slice(0, -6)\n\n return slug\n}\n\nexport function loadRootMeta(contentDir: string): DocsRootMeta | undefined {\n return readJson5File<DocsRootMeta>(join(contentDir, 'meta.json5'))\n}\n\nexport function loadSectionMetas(contentDir: string): Map<string, DocsSectionMeta> {\n const metas = new Map<string, DocsSectionMeta>()\n if (!existsSync(contentDir)) return metas\n for (const entry of readdirSync(contentDir, { withFileTypes: true })) {\n if (!entry.isDirectory() || entry.name.startsWith('.')) continue\n const meta = readJson5File<DocsSectionMeta>(join(contentDir, entry.name, 'meta.json5'))\n if (meta) metas.set(entry.name, meta)\n }\n return metas\n}\n\nfunction collectMarkdownFiles(contentDir: string): string[] {\n const files: string[] = []\n\n function walk(currentDir: string): void {\n for (const entry of readdirSync(currentDir, { withFileTypes: true })) {\n if (entry.name.startsWith('.')) continue\n const fullPath = join(currentDir, entry.name)\n\n if (entry.isDirectory()) {\n walk(fullPath)\n continue\n }\n\n if (entry.name.endsWith('.md')) {\n files.push(fullPath)\n }\n }\n }\n\n if (existsSync(contentDir)) {\n walk(contentDir)\n }\n\n return files.sort()\n}\n\nfunction createRelativeLinkTransform(filePath: string, contentDir: string, basePath: string) {\n return () => (tree: any) => {\n const visit = (node: any): void => {\n if (node?.type === 'element' && node.tagName === 'a') {\n const href = node.properties?.href\n if (typeof href === 'string' && href.includes('.md') && !href.startsWith('http')) {\n // Transform .md references to route paths\n const [rawPath, hash = ''] = href.split('#')\n const targetPath = join(dirname(filePath), rawPath)\n const slug = toContentSlug(targetPath, contentDir)\n const routePath = slug === '/' ? '/' : `/${slug}/`\n const fullPath = `${basePath}${routePath}`\n node.properties = node.properties || {}\n node.properties.href = hash ? `${fullPath}#${hash}` : fullPath\n } else if (\n basePath &&\n typeof href === 'string' &&\n href.startsWith('/') &&\n !href.startsWith('//') &&\n !href.startsWith(basePath)\n ) {\n // Prefix absolute internal links with basePath\n node.properties = node.properties || {}\n node.properties.href = `${basePath}${href}`\n }\n }\n\n if (Array.isArray(node?.children)) {\n for (const child of node.children) {\n visit(child)\n }\n }\n }\n\n visit(tree)\n }\n}\n\n/**\n * Run async tasks with bounded concurrency.\n * Prevents memory blowup when processing thousands of pages.\n */\nasync function mapWithConcurrency<T, R>(\n items: T[],\n concurrency: number,\n fn: (item: T) => Promise<R>,\n): Promise<R[]> {\n const results: R[] = Array.from({ length: items.length })\n let index = 0\n\n async function worker(): Promise<void> {\n while (index < items.length) {\n const i = index++\n results[i] = await fn(items[i])\n }\n }\n\n const workers = Array.from({ length: Math.min(concurrency, items.length) }, () => worker())\n await Promise.all(workers)\n return results\n}\n\n/**\n * Get the git last-modified date for a file.\n * Returns ISO date string or undefined if git is unavailable or the file isn't tracked.\n */\nfunction getGitLastUpdated(filePath: string): string | undefined {\n try {\n const output = execFileSync('git', ['log', '-1', '--format=%cI', '--', filePath], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim()\n return output || undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Generate breadcrumbs from a content slug.\n * Returns array of { label, path } from root to current page.\n */\nexport function buildBreadcrumbs(\n contentSlug: string,\n title: string,\n basePath: string,\n): Array<{ label: string; path: string }> {\n if (contentSlug === '/') return []\n\n const segments = contentSlug.split('/')\n const crumbs: Array<{ label: string; path: string }> = []\n\n for (let i = 0; i < segments.length - 1; i++) {\n const slug = segments.slice(0, i + 1).join('/')\n crumbs.push({\n label: toTitleCase(segments[i]),\n path: `${basePath}/${slug}`,\n })\n }\n\n // Current page (no link)\n crumbs.push({ label: title, path: '' })\n return crumbs\n}\n\nexport async function loadDocsPages(\n config: ResolvedDocsConfig,\n sectionMetas?: Map<string, DocsSectionMeta>,\n): Promise<DocsPage[]> {\n const homeConfig = config.homeConfigFile\n ? readJson5File<Record<string, unknown>>(config.homeConfigFile)\n : undefined\n\n const files = collectMarkdownFiles(config.contentDir)\n const concurrency = Math.max(1, availableParallelism() * 2)\n\n // Process markdown files with bounded concurrency to manage memory at scale\n const results = await mapWithConcurrency(files, concurrency, async (filePath) => {\n const raw = readFileSync(filePath, 'utf-8')\n const markdownConfig: MarkdownConfig = {\n ...(config.markdown ?? {}),\n shiki: {\n themes: config.markdown?.shiki?.themes ?? {\n light: 'github-light',\n dark: 'github-dark',\n },\n defaultShowLineNumbers: config.markdown?.shiki?.defaultShowLineNumbers,\n langAlias: config.markdown?.shiki?.langAlias,\n },\n rehypePlugins: [\n ...(config.markdown?.rehypePlugins ?? []),\n [rehypeAssetTransform, { contentDir: dirname(filePath) }] as const,\n createRelativeLinkTransform(filePath, config.contentDir, config.basePath),\n ],\n }\n\n const result = await processMarkdown(raw, markdownConfig)\n const parsedFrontmatter = DocsFrontmatterSchema.parse(result.frontmatter ?? {})\n const contentSlug = toContentSlug(filePath, config.contentDir)\n const isHome = contentSlug === '/'\n\n const frontmatter =\n isHome && homeConfig ? { ...homeConfig, ...parsedFrontmatter } : parsedFrontmatter\n if (frontmatter.draft) return null\n\n const routePath = isHome ? '/' : `/${contentSlug}`\n const section = isHome ? undefined : contentSlug.split('/')[0]\n const title =\n frontmatter.title ??\n (isHome ? config.title : toTitleCase(contentSlug.split('/').at(-1) ?? section ?? 'Home'))\n\n // Resolve layout name from section meta\n const sectionMeta = section ? sectionMetas?.get(section) : undefined\n const isLanding = section != null && contentSlug === section\n let layoutName: string\n if (isHome) {\n layoutName = 'home'\n } else if (isLanding && sectionMeta?.layout) {\n layoutName = sectionMeta.layout\n } else if (!isLanding && sectionMeta?.itemLayout) {\n layoutName = sectionMeta.itemLayout\n } else {\n layoutName = 'page'\n }\n\n // Git last-updated timestamp (only when enabled)\n const lastUpdated = config.lastUpdated ? getGitLastUpdated(filePath) : undefined\n\n return {\n title,\n routePath,\n contentSlug,\n section,\n frontmatter,\n html: result.html,\n headings: result.headings,\n sourcePath: filePath,\n isHome,\n layoutName,\n lastUpdated,\n } as DocsPage\n })\n\n const pages: DocsPage[] = []\n for (const result of results) {\n if (result != null) pages.push(result)\n }\n return pages.sort((left, right) => left.routePath.localeCompare(right.routePath))\n}\n\nexport function collectContentAssets(contentDir: string): Map<string, string> {\n const assets = new Map<string, string>()\n\n function walk(currentDir: string): void {\n if (!existsSync(currentDir)) return\n\n for (const entry of readdirSync(currentDir, { withFileTypes: true })) {\n if (entry.name.startsWith('.')) continue\n\n const fullPath = join(currentDir, entry.name)\n if (entry.isDirectory()) {\n walk(fullPath)\n continue\n }\n\n if (!CONTENT_ASSET_EXTS.has(extname(entry.name).toLowerCase())) continue\n\n if (assets.has(entry.name) && assets.get(entry.name) !== fullPath) {\n console.warn(\n `pagesmith:docs duplicate companion asset basename \"${entry.name}\" detected; using ${fullPath}`,\n )\n }\n\n assets.set(entry.name, fullPath)\n }\n }\n\n walk(contentDir)\n return assets\n}\n","import { basename } from 'path'\nimport { toTitleCase, type ResolvedDocsConfig } from './config.js'\nimport type {\n DocsPage,\n DocsSectionMeta,\n DocsRootMeta,\n NavItem,\n PrevNextLink,\n SidebarItem,\n SidebarSection,\n SiteModel,\n} from './content.js'\n\nfunction getOrder(page: DocsPage): number {\n return typeof page.frontmatter.order === 'number'\n ? page.frontmatter.order\n : Number.MAX_SAFE_INTEGER\n}\n\nfunction sortPages(pages: DocsPage[]): DocsPage[] {\n return [...pages].sort((left, right) => {\n const orderDelta = getOrder(left) - getOrder(right)\n if (orderDelta !== 0) return orderDelta\n return left.routePath.localeCompare(right.routePath)\n })\n}\n\nfunction sortSectionPages(pages: DocsPage[], meta?: DocsSectionMeta): DocsPage[] {\n if (!meta?.orderBy) return sortPages(pages)\n\n if (meta.orderBy === 'publishedDate') {\n const getPublishedTime = (value: unknown): number => {\n if (!value) return 0\n if (value instanceof Date) return value.getTime()\n if (typeof value === 'string' || typeof value === 'number') {\n return new Date(value).getTime()\n }\n return 0\n }\n\n return [...pages].sort((a, b) => {\n const dateA = getPublishedTime(a.frontmatter.publishedDate)\n const dateB = getPublishedTime(b.frontmatter.publishedDate)\n return dateB - dateA\n })\n }\n\n if (meta.orderBy === 'manual' && meta.items) {\n const order = new Map(meta.items.map((slug, i) => [slug, i]))\n return [...pages].sort((a, b) => {\n const slugA = a.contentSlug.split('/').pop() ?? ''\n const slugB = b.contentSlug.split('/').pop() ?? ''\n const posA = order.get(slugA) ?? Number.MAX_SAFE_INTEGER\n const posB = order.get(slugB) ?? Number.MAX_SAFE_INTEGER\n return posA - posB\n })\n }\n\n return sortPages(pages)\n}\n\nfunction buildSidebarWithSeries(\n sectionSlug: string,\n sectionPages: DocsPage[],\n meta: DocsSectionMeta,\n basePath: string,\n): SidebarSection[] {\n const sections: SidebarSection[] = []\n const pageBySlug = new Map(sectionPages.map((p) => [p.contentSlug.split('/').pop(), p]))\n const landing = sectionPages.find((p) => p.contentSlug === sectionSlug)\n\n for (const series of meta.series!) {\n for (const slug of series.articles) {\n if (!pageBySlug.has(slug)) {\n console.warn(\n `\\x1b[33m⚠ [${sectionSlug}]\\x1b[0m Series \"${series.displayName}\" references article slug \"${slug}\" which does not match any loaded page.`,\n )\n }\n }\n\n const items: SidebarItem[] = series.articles\n .map((slug) => pageBySlug.get(slug))\n .filter((p): p is DocsPage => p != null)\n .map((page) => ({\n title: page.frontmatter.sidebarLabel ?? page.title,\n path: `${basePath}${page.routePath}`,\n }))\n\n if (items.length > 0) {\n sections.push({ title: series.displayName, slug: series.slug, items })\n }\n }\n\n // Prepend landing page to first section if exists\n if (landing && sections.length > 0) {\n sections[0].items.unshift({\n title: landing.frontmatter.sidebarLabel ?? landing.title,\n path: `${basePath}${landing.routePath}`,\n })\n }\n\n return sections\n}\n\nfunction buildSidebarItems(\n sectionSlug: string,\n sectionPages: DocsPage[],\n basePath: string,\n sectionMeta?: DocsSectionMeta,\n): SidebarItem[] {\n type Node = {\n key: string\n title: string\n path: string\n order: number\n children: Map<string, Node>\n }\n\n const roots = new Map<string, Node>()\n const landingPage = sectionPages.find((page) => page.contentSlug === sectionSlug)\n\n for (const page of sortSectionPages(\n sectionPages.filter((entry) => entry.contentSlug !== sectionSlug),\n sectionMeta,\n )) {\n const remainder = page.contentSlug.slice(sectionSlug.length + 1)\n if (!remainder) continue\n\n const segments = remainder.split('/')\n let level = roots\n let accumulated = sectionSlug\n\n for (const [index, segment] of segments.entries()) {\n accumulated = `${accumulated}/${segment}`\n let node = level.get(segment)\n if (!node) {\n node = {\n key: accumulated,\n title: toTitleCase(segment),\n path: `${basePath}${page.routePath}`,\n order: getOrder(page),\n children: new Map<string, Node>(),\n }\n level.set(segment, node)\n }\n\n if (index === segments.length - 1) {\n node.title = page.frontmatter.sidebarLabel ?? page.title\n node.path = `${basePath}${page.routePath}`\n node.order = getOrder(page)\n }\n\n level = node.children\n }\n }\n\n const toItems = (nodes: Map<string, Node>): SidebarItem[] =>\n Array.from(nodes.values())\n .sort((left, right) => {\n const orderDelta = left.order - right.order\n if (orderDelta !== 0) return orderDelta\n return left.title.localeCompare(right.title)\n })\n .map((node) => ({\n title: node.title,\n path: node.path,\n ...(node.children.size > 0 ? { children: toItems(node.children) } : {}),\n }))\n\n const items = toItems(roots)\n\n if (!landingPage) {\n return items\n }\n\n return [\n {\n title: landingPage.frontmatter.sidebarLabel ?? landingPage.title,\n path: `${basePath}${landingPage.routePath}`,\n },\n ...items,\n ]\n}\n\n/**\n * Find the first content page in a section, respecting meta ordering.\n * Excludes the landing page (README.md) itself — returns the first \"child\" page.\n */\nfunction findFirstSectionPage(\n sectionSlug: string,\n sectionPages: DocsPage[],\n meta?: DocsSectionMeta,\n): DocsPage | undefined {\n const nonLanding = sectionPages.filter((p) => p.contentSlug !== sectionSlug)\n if (nonLanding.length === 0) return undefined\n\n // For manual ordering with series, the first article of the first series wins\n if (meta?.orderBy === 'manual' && meta.series && meta.series.length > 0) {\n const pageBySlug = new Map(nonLanding.map((p) => [p.contentSlug.split('/').pop(), p]))\n for (const series of meta.series) {\n for (const slug of series.articles) {\n const page = pageBySlug.get(slug)\n if (page) return page\n }\n }\n }\n\n // For manual ordering with items array\n if (meta?.orderBy === 'manual' && meta.items && meta.items.length > 0) {\n const pageBySlug = new Map(nonLanding.map((p) => [p.contentSlug.split('/').pop(), p]))\n for (const slug of meta.items) {\n const page = pageBySlug.get(slug)\n if (page) return page\n }\n }\n\n // Default: use sortSectionPages\n return sortSectionPages(nonLanding, meta)[0]\n}\n\nexport function buildSiteModel(\n config: ResolvedDocsConfig,\n pages: DocsPage[],\n rootMeta?: DocsRootMeta,\n sectionMetas?: Map<string, DocsSectionMeta>,\n): SiteModel {\n const pageByPath = new Map(pages.map((page) => [page.routePath, page]))\n const sidebarBySection = new Map<string, SidebarSection[]>()\n const navItems: NavItem[] = []\n const pagesBySection = new Map<string, DocsPage[]>()\n\n for (const page of pages) {\n if (!page.section) continue\n if (page.frontmatter.draft) continue\n if (!pagesBySection.has(page.section)) {\n pagesBySection.set(page.section, [])\n }\n pagesBySection.get(page.section)!.push(page)\n }\n\n for (const [sectionSlug, sectionPages] of Array.from(pagesBySection.entries()).sort((a, b) =>\n a[0].localeCompare(b[0]),\n )) {\n const sectionMeta = sectionMetas?.get(sectionSlug)\n const landingPage = sectionPages.find((page) => page.contentSlug === sectionSlug)\n const firstPage = findFirstSectionPage(sectionSlug, sectionPages, sectionMeta)\n const label =\n sectionMeta?.displayName ??\n config.packages?.[sectionSlug]?.label ??\n landingPage?.frontmatter.navLabel ??\n landingPage?.title ??\n firstPage?.frontmatter.navLabel ??\n toTitleCase(sectionSlug)\n const sectionPath = landingPage?.routePath ?? firstPage?.routePath ?? `/${sectionSlug}`\n\n // Only auto-generate nav items if root meta didn't provide explicit headerLinks\n if (!rootMeta?.headerLinks || rootMeta.headerLinks.length === 0) {\n navItems.push({ label, path: `${config.basePath}${sectionPath}` })\n }\n\n // Build sidebar: use series grouping if defined, otherwise flat list\n if (sectionMeta?.series && sectionMeta.series.length > 0) {\n sidebarBySection.set(\n sectionSlug,\n buildSidebarWithSeries(sectionSlug, sectionPages, sectionMeta, config.basePath),\n )\n } else {\n sidebarBySection.set(sectionSlug, [\n {\n title: label,\n slug: sectionSlug,\n collapsed: sectionMeta?.collapsed,\n items: buildSidebarItems(sectionSlug, sectionPages, config.basePath, sectionMeta),\n },\n ])\n }\n }\n\n // If root meta provides explicit header links, resolve section paths to actual pages\n if (rootMeta?.headerLinks && rootMeta.headerLinks.length > 0) {\n for (const link of rootMeta.headerLinks) {\n const rawPath = link.path.startsWith('/') ? link.path : `/${link.path}`\n const sectionSlug = rawPath.replace(/^\\//, '').replace(/\\/.*$/, '')\n const sectionPages = pagesBySection.get(sectionSlug)\n let resolvedPath = rawPath\n\n if (sectionPages) {\n const landing = sectionPages.find((p) => p.contentSlug === sectionSlug)\n if (landing) {\n resolvedPath = landing.routePath\n } else {\n const first = findFirstSectionPage(\n sectionSlug,\n sectionPages,\n sectionMetas?.get(sectionSlug),\n )\n if (first) resolvedPath = first.routePath\n }\n }\n\n navItems.push({\n label: link.label,\n path: `${config.basePath}${resolvedPath}`,\n })\n }\n }\n\n return {\n navItems,\n sidebarBySection,\n pageByPath,\n rootMeta,\n sectionMetas: sectionMetas ?? new Map(),\n }\n}\n\nfunction flattenSidebarItems(items: SidebarItem[]): SidebarItem[] {\n const flattened: SidebarItem[] = []\n\n for (const item of items) {\n flattened.push(item)\n if (item.children) {\n flattened.push(...flattenSidebarItems(item.children))\n }\n }\n\n return flattened\n}\n\nexport function getPrevNext(\n sidebarSections: SidebarSection[] | undefined,\n routePath: string,\n): { prev?: PrevNextLink; next?: PrevNextLink } {\n if (!sidebarSections?.length) return {}\n const flat = flattenSidebarItems(sidebarSections.flatMap((section) => section.items))\n const index = flat.findIndex((item) => item.path === routePath)\n if (index < 0) return {}\n\n const prev = index > 0 ? flat[index - 1] : undefined\n const next = index < flat.length - 1 ? flat[index + 1] : undefined\n\n return {\n prev: prev ? { title: prev.title, path: prev.path } : undefined,\n next: next ? { title: next.title, path: next.path } : undefined,\n }\n}\n\nexport function getSitePayload(config: ResolvedDocsConfig, model: SiteModel) {\n const base = config.basePath\n\n // Use root meta footer links if provided, otherwise config footer links\n const rawFooterLinks = model.rootMeta?.footerLinks ?? config.footerLinks\n\n // Prefix internal footer link paths with basePath\n const footerLinks = base\n ? rawFooterLinks.map((link) => ({\n ...link,\n path:\n link.path.startsWith('/') && !link.path.startsWith('//') && !link.path.startsWith(base)\n ? `${base}${link.path}`\n : link.path,\n }))\n : rawFooterLinks\n\n return {\n origin: config.origin,\n basePath: config.basePath,\n homeLink: config.homeLink,\n name: config.name,\n title: config.title,\n description: config.description,\n language: config.language,\n navItems: model.navItems,\n footerLinks,\n search: config.search,\n sidebar: config.sidebar,\n analytics: config.analytics,\n theme: config.theme,\n socialImage: config.socialImage\n ? config.socialImage.startsWith('http')\n ? config.socialImage\n : `${config.basePath}/${config.socialImage.replace(/^\\//, '')}`\n : undefined,\n favicon: config.favicon !== false ? `${config.basePath}/${basename(config.favicon)}` : false,\n faviconFallback: config.faviconFallback\n ? `${config.basePath}/${basename(config.faviconFallback)}`\n : false,\n appleTouchIcon: config.appleTouchIcon ? `${config.basePath}/apple-touch-icon.png` : false,\n }\n}\n","import { Fragment, h } from '@pagesmith/core/jsx-runtime'\n\ntype PrevNext = {\n title: string\n path: string\n}\n\ntype Props = {\n prev?: PrevNext\n next?: PrevNext\n links?: Array<{ label: string; path: string }>\n copyright?: {\n holder: string\n startYear: number\n }\n}\n\nexport function DocFooter({ prev, next, links, copyright }: Props) {\n const hasPrevNext = prev || next\n const year = new Date().getFullYear()\n\n return (\n <footer class=\"doc-footer\">\n {hasPrevNext ? (\n <nav class=\"doc-footer-nav\" aria-label=\"Page navigation\">\n {prev ? (\n <a href={prev.path + '/'} class=\"doc-footer-link doc-footer-prev\">\n <span class=\"doc-footer-label\">Previous</span>\n <span class=\"doc-footer-title\">{prev.title}</span>\n </a>\n ) : (\n <span />\n )}\n {next ? (\n <a href={next.path + '/'} class=\"doc-footer-link doc-footer-next\">\n <span class=\"doc-footer-label\">Next</span>\n <span class=\"doc-footer-title\">{next.title}</span>\n </a>\n ) : (\n <span />\n )}\n </nav>\n ) : null}\n {links && links.length > 0 ? (\n <nav class=\"doc-footer-links\" aria-label=\"Footer links\">\n {links.map((link) => (\n <a href={link.path}>{link.label}</a>\n ))}\n </nav>\n ) : null}\n {copyright ? (\n <p class=\"doc-footer-copyright\">\n &copy; {copyright.startYear < year ? `${copyright.startYear}–${year}` : `${year}`}{' '}\n {copyright.holder}\n </p>\n ) : null}\n </footer>\n )\n}\n","import { h } from '@pagesmith/core/jsx-runtime'\n\ntype Props = {\n siteName: string\n basePath?: string\n homeLink?: string\n navItems?: Array<{ path: string; label: string }>\n slug: string\n searchEnabled?: boolean\n}\n\nconst hamburgerIcon =\n '<svg viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"><path d=\"M3 5h14M3 10h14M3 15h14\"/></svg>'\n\nconst searchIcon =\n '<svg viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"><circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\"/><path d=\"m13 13 4 4\"/></svg>'\n\nexport function DocHeader({ siteName, basePath, homeLink, navItems, slug, searchEnabled }: Props) {\n const homePath = homeLink || (basePath ? `${basePath}/` : '/')\n const hasNav = navItems && navItems.length > 0\n const base = (basePath || '').replace(/\\/+$/, '')\n\n function isNavActive(itemPath: string): boolean {\n // Extract the section prefix from the nav item path (e.g., /pagesmith/guide)\n const relative = itemPath.startsWith(base) ? itemPath.slice(base.length) : itemPath\n const section = relative.replace(/^\\//, '').split('/')[0]\n return slug.startsWith(`${base}/${section}`)\n }\n\n return (\n <header class=\"doc-header\">\n <div class=\"doc-header-inner\">\n <div class=\"doc-header-left\">\n {hasNav ? (\n <button\n type=\"button\"\n class=\"doc-sidebar-toggle\"\n aria-label=\"Toggle navigation\"\n data-sidebar-toggle=\"\"\n innerHTML={hamburgerIcon}\n />\n ) : null}\n <a href={homePath} class=\"doc-logo\">\n {siteName}\n </a>\n </div>\n {hasNav ? (\n <nav class=\"doc-nav\">\n {navItems!.map((item) => (\n <a href={item.path} class={isNavActive(item.path) ? 'active' : ''}>\n {item.label}\n </a>\n ))}\n </nav>\n ) : null}\n {searchEnabled ? (\n <button\n type=\"button\"\n class=\"doc-search-trigger\"\n aria-label=\"Search\"\n data-search-trigger=\"\"\n >\n <span class=\"doc-search-icon\" innerHTML={searchIcon} />\n <kbd class=\"doc-search-shortcut\">\n <span class=\"doc-search-shortcut-key\">⌘</span>K\n </kbd>\n </button>\n ) : null}\n </div>\n </header>\n )\n}\n","import { Fragment, h } from '@pagesmith/core/jsx-runtime'\n\ntype SidebarItem = {\n title: string\n slug: string\n path: string\n children?: SidebarItem[]\n}\n\ntype SidebarSection = {\n title: string\n collapsed?: boolean\n items: SidebarItem[]\n}\n\ntype Props = {\n sections?: SidebarSection[]\n currentSlug?: string\n collapsible?: boolean\n}\n\nfunction isSectionActive(items: SidebarItem[], currentSlug: string): boolean {\n for (const item of items) {\n if (currentSlug === item.path || currentSlug.startsWith(item.path + '/')) return true\n if (item.children && isSectionActive(item.children, currentSlug)) return true\n }\n return false\n}\n\nfunction renderItems(items: SidebarItem[], currentSlug: string, depth: number = 0): any {\n return (\n <ul class={`doc-sidebar-list ${depth > 0 ? 'doc-sidebar-nested' : ''}`}>\n {items.map((item) => {\n const isActive = currentSlug === item.path\n const hasChildren = item.children && item.children.length > 0\n const isExpanded =\n hasChildren &&\n item.children!.some(\n (child) => currentSlug === child.path || currentSlug.startsWith(child.path + '/'),\n )\n\n return (\n <li\n class={`doc-sidebar-item ${isActive ? 'active' : ''} ${isExpanded ? 'expanded' : ''}`}\n >\n <a href={item.path + '/'} class=\"doc-sidebar-link\">\n {item.title}\n </a>\n {hasChildren ? renderItems(item.children!, currentSlug, depth + 1) : null}\n </li>\n )\n })}\n </ul>\n )\n}\n\nexport function DocSidebar({ sections, currentSlug = '/', collapsible = false }: Props) {\n if (!sections || sections.length === 0) return <Fragment />\n\n return (\n <aside class=\"doc-sidebar\">\n <nav class=\"doc-sidebar-nav\" aria-label=\"Documentation navigation\">\n {sections.map((section) => {\n const sectionActive = isSectionActive(section.items, currentSlug)\n // Section is open if: explicitly not collapsed, or contains the active page\n const isOpen = !section.collapsed || sectionActive\n\n if (collapsible) {\n return (\n <details\n class=\"doc-sidebar-section doc-sidebar-collapsible\"\n open={isOpen || undefined}\n >\n <summary class=\"doc-sidebar-heading\">{section.title}</summary>\n {renderItems(section.items, currentSlug)}\n </details>\n )\n }\n\n return (\n <div class=\"doc-sidebar-section\">\n <p class=\"doc-sidebar-heading\">{section.title}</p>\n {renderItems(section.items, currentSlug)}\n </div>\n )\n })}\n </nav>\n </aside>\n )\n}\n","import { Fragment, h } from '@pagesmith/core/jsx-runtime'\n\ntype Props = {\n title: string\n description?: string\n url?: string\n socialImage?: string\n site: {\n origin: string\n basePath?: string\n name: string\n language?: string\n seo?: { locale?: string; twitterHandle?: string; defaultOgType?: string }\n theme?: { lightColor?: string; darkColor?: string }\n analytics?: { googleAnalytics?: string }\n footerLinks?: Array<{ label: string; path: string }>\n search?: { enabled?: boolean; showImages?: boolean; showSubResults?: boolean }\n socialImage?: string\n favicon?: string | false\n faviconFallback?: string | false\n appleTouchIcon?: string | false\n }\n children?: any\n}\n\nfunction buildCsp(gaId?: string): string {\n const scriptSrc = [\"'self'\", \"'unsafe-inline'\"]\n const connectSrc = [\"'self'\"]\n\n if (gaId) {\n scriptSrc.push('https://www.googletagmanager.com')\n connectSrc.push('https://www.google-analytics.com', 'https://analytics.google.com')\n }\n\n return [\n \"default-src 'self'\",\n `script-src ${scriptSrc.join(' ')}`,\n \"style-src 'self' 'unsafe-inline'\",\n \"img-src 'self' data:\",\n \"font-src 'self'\",\n `connect-src ${connectSrc.join(' ')}`,\n \"object-src 'none'\",\n \"base-uri 'self'\",\n \"form-action 'self'\",\n ].join('; ')\n}\n\nexport function Html({ title, description, url, socialImage, site, children }: Props) {\n const origin = site.origin.replace(/\\/$/, '')\n const base = site.basePath || ''\n const canonicalUrl = url ? `${origin}${url}` : undefined\n const locale = site.seo?.locale || 'en_US'\n const lightColor = site.theme?.lightColor || '#f8fafc'\n const darkColor = site.theme?.darkColor || '#020617'\n const gaId = site.analytics?.googleAnalytics\n const ogImage = socialImage ?? site.socialImage\n const searchEnabled = site.search?.enabled !== false\n const favicon = site.favicon\n const faviconFallback = site.faviconFallback\n const appleTouchIcon = site.appleTouchIcon\n\n return (\n <html lang={site.language || 'en'} class=\"no-js\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <meta name=\"color-scheme\" content=\"light dark\" />\n\n {/* Security */}\n <meta http-equiv=\"Content-Security-Policy\" content={buildCsp(gaId)} />\n <meta name=\"referrer\" content=\"strict-origin-when-cross-origin\" />\n\n <title>{title}</title>\n\n {/* Icons */}\n {favicon !== false && favicon ? (\n <link\n rel=\"icon\"\n href={favicon}\n type={favicon.endsWith('.svg') ? 'image/svg+xml' : 'image/x-icon'}\n />\n ) : null}\n {faviconFallback ? <link rel=\"icon\" href={faviconFallback} sizes=\"32x32\" /> : null}\n {appleTouchIcon ? <link rel=\"apple-touch-icon\" href={appleTouchIcon} /> : null}\n {description ? <meta name=\"description\" content={description} /> : null}\n\n {/* Canonical URL */}\n {canonicalUrl ? <link rel=\"canonical\" href={canonicalUrl} /> : null}\n\n {/* OpenGraph */}\n <meta property=\"og:type\" content=\"website\" />\n {canonicalUrl ? <meta property=\"og:url\" content={canonicalUrl} /> : null}\n <meta property=\"og:title\" content={title} />\n {description ? <meta property=\"og:description\" content={description} /> : null}\n {ogImage ? (\n <meta\n property=\"og:image\"\n content={ogImage.startsWith('http') ? ogImage : `${origin}${ogImage}`}\n />\n ) : null}\n <meta property=\"og:locale\" content={locale} />\n <meta property=\"og:site_name\" content={site.name} />\n\n {/* Theme color */}\n <meta name=\"theme-color\" content={lightColor} media=\"(prefers-color-scheme: light)\" />\n <meta name=\"theme-color\" content={darkColor} media=\"(prefers-color-scheme: dark)\" />\n\n {/* Performance: font preload */}\n <link\n rel=\"preload\"\n href={`${base}/assets/fonts/open-sans-variable.woff2`}\n as=\"font\"\n type=\"font/woff2\"\n crossorigin=\"\"\n />\n {/* Performance: GA preconnect */}\n {gaId ? (\n <link rel=\"preconnect\" href=\"https://www.googletagmanager.com\" crossorigin=\"\" />\n ) : null}\n\n {/* CSS */}\n <link rel=\"stylesheet\" href={`${base}/assets/style.css`} />\n {searchEnabled ? <link rel=\"stylesheet\" href={`${base}/pagefind/pagefind-ui.css`} /> : null}\n\n {/* Remove no-js class */}\n <script innerHTML=\"document.documentElement.classList.remove('no-js')\" />\n {searchEnabled ? <script src={`${base}/pagefind/pagefind-ui.js`} defer /> : null}\n {searchEnabled ? (\n <noscript>\n <style innerHTML=\".doc-search-trigger{display:none!important}\" />\n </noscript>\n ) : null}\n\n {/* Google Analytics */}\n {gaId ? (\n <Fragment>\n <script async src={`https://www.googletagmanager.com/gtag/js?id=${gaId}`} />\n <script\n innerHTML={`window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','${gaId}');`}\n />\n </Fragment>\n ) : null}\n </head>\n <body>\n {children}\n {searchEnabled ? (\n <dialog\n class=\"doc-search-modal\"\n id=\"search-modal\"\n aria-label=\"Search documentation\"\n data-search-show-images={site.search?.showImages ? 'true' : 'false'}\n data-search-show-sub-results={site.search?.showSubResults !== false ? 'true' : 'false'}\n >\n <div class=\"doc-search-modal-inner\">\n <div class=\"doc-search-modal-header\">\n <span class=\"doc-search-modal-title\">Search</span>\n <button\n type=\"button\"\n class=\"doc-search-modal-close\"\n aria-label=\"Close search\"\n data-search-close=\"\"\n innerHTML='<svg viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"><path d=\"m5 5 10 10M15 5 5 15\"/></svg>'\n />\n </div>\n <div class=\"doc-search-modal-body\" data-pagefind-search=\"\" />\n </div>\n </dialog>\n ) : null}\n <script src={`${base}/assets/main.js`} defer />\n </body>\n </html>\n )\n}\n","/**\n * DocHome layout.\n *\n * Documentation landing page with hero, install snippet, features grid,\n * packages grid, code example, and optional markdown content.\n *\n * All sections are optional — omit the frontmatter key and the section\n * is not rendered. Supports both single-package and monorepo projects.\n */\n\nimport { h } from '@pagesmith/core/jsx-runtime'\nimport { DocFooter } from '../components/DocFooter'\nimport { DocHeader } from '../components/DocHeader'\nimport { DocSidebar } from '../components/DocSidebar'\nimport { Html } from '../components/Html'\n\ntype Props = {\n content: string\n frontmatter: Record<string, any>\n headings: Array<{ depth: number; text: string; slug: string }>\n slug: string\n site: any\n [key: string]: any\n}\n\nexport default function DocHome(props: Props) {\n const { content, frontmatter, slug, site } = props\n\n const hero =\n frontmatter.hero ??\n (frontmatter.title || frontmatter.tagline || frontmatter.actions\n ? {\n name: frontmatter.title || site.name,\n text: frontmatter.tagline || frontmatter.title,\n tagline: frontmatter.description,\n badge: frontmatter.badge,\n actions: frontmatter.actions,\n }\n : undefined)\n const features = frontmatter.features\n const install = frontmatter.install\n const packages = frontmatter.packages\n const codeExample = frontmatter.codeExample\n\n // Build sidebar sections from navItems for mobile hamburger menu\n const navItems = site.navItems as Array<{ path: string; label: string }> | undefined\n const sidebarSections =\n navItems && navItems.length > 0\n ? [\n {\n title: 'Navigation',\n items: navItems.map((item: { path: string; label: string }) => ({\n title: item.label,\n slug: item.path,\n path: item.path,\n })),\n },\n ]\n : undefined\n\n return (\n <Html\n title={hero?.name || frontmatter.title || site.title}\n description={hero?.tagline || frontmatter.description || site.description}\n url={slug}\n socialImage={\n frontmatter.socialImage\n ? frontmatter.socialImage.startsWith('http')\n ? frontmatter.socialImage\n : `${site.basePath || ''}/${frontmatter.socialImage.replace(/^\\//, '')}`\n : undefined\n }\n site={site}\n >\n <DocHeader\n siteName={site.name}\n basePath={site.basePath}\n homeLink={site.homeLink}\n navItems={site.navItems}\n slug={slug}\n searchEnabled={site.search?.enabled}\n />\n <main class=\"doc-home\" data-pagefind-body=\"\">\n {/* Mobile sidebar (visible on small screens via hamburger toggle) */}\n <DocSidebar sections={sidebarSections} currentSlug={slug} />\n\n {/* Hero section */}\n {hero ? (\n <section class=\"doc-home-section doc-hero\">\n {hero.badge ? (\n <div class=\"doc-hero-badge\">\n <span class=\"doc-hero-badge-dot\" />\n {hero.badge}\n </div>\n ) : null}\n {hero.name ? <p class=\"doc-hero-name\">{hero.name}</p> : null}\n {hero.text ? <h1 class=\"doc-hero-text\">{hero.text}</h1> : null}\n {hero.tagline ? <p class=\"doc-hero-tagline\">{hero.tagline}</p> : null}\n {hero.actions && hero.actions.length > 0 ? (\n <div class=\"doc-hero-actions\">\n {hero.actions.map((action: any) => (\n <a\n href={action.link}\n class={`doc-hero-action doc-hero-action-${action.theme || 'brand'}`}\n >\n {action.icon ? (\n <span class=\"doc-hero-action-icon\" innerHTML={action.icon} />\n ) : null}\n {action.text}\n </a>\n ))}\n </div>\n ) : null}\n </section>\n ) : null}\n\n {/* Install snippet */}\n {install ? (\n <div class=\"doc-home-section doc-home-install\">\n <div class=\"doc-install-bar\">\n <div class=\"doc-install-header\">\n <span class=\"doc-install-dot doc-install-dot-r\" />\n <span class=\"doc-install-dot doc-install-dot-y\" />\n <span class=\"doc-install-dot doc-install-dot-g\" />\n <span class=\"doc-install-title\">Terminal</span>\n <span style=\"width:36px\" />\n </div>\n <div class=\"doc-install-body\">\n <code>\n <span class=\"doc-install-prompt\">$ </span>\n {install}\n </code>\n <button\n type=\"button\"\n class=\"doc-install-copy\"\n data-copy-text={install}\n onclick={`navigator.clipboard.writeText(this.dataset.copyText);this.textContent='Copied!';setTimeout(()=>this.textContent='Copy',1500)`}\n >\n Copy\n </button>\n </div>\n </div>\n </div>\n ) : null}\n\n {/* Features grid */}\n {features && features.length > 0 ? (\n <section class=\"doc-home-section\">\n <p class=\"doc-home-section-label\">Features</p>\n <div class=\"doc-features\">\n {features.map((feature: any) => (\n <div class=\"doc-feature-card\">\n {feature.icon ? <span class=\"doc-feature-icon\" innerHTML={feature.icon} /> : null}\n <h3 class=\"doc-feature-title\">{feature.title}</h3>\n <p class=\"doc-feature-details\">{feature.details}</p>\n </div>\n ))}\n </div>\n </section>\n ) : null}\n\n {/* Packages grid (monorepo) */}\n {packages && packages.length > 0 ? (\n <section class=\"doc-home-section\">\n <p class=\"doc-home-section-label\">Packages</p>\n <div class=\"doc-packages\">\n {packages.map((pkg: any) => {\n const Tag = pkg.href ? 'a' : 'div'\n return (\n <Tag class=\"doc-package-card\" href={pkg.href || undefined}>\n <div class=\"doc-package-name\">{pkg.name}</div>\n <p class=\"doc-package-desc\">{pkg.description}</p>\n {pkg.version || pkg.tag ? (\n <div class=\"doc-package-meta\">\n {pkg.version ? (\n <span class=\"doc-package-version\">{pkg.version}</span>\n ) : null}\n {pkg.tag ? <span class=\"doc-package-tag\">{pkg.tag}</span> : null}\n </div>\n ) : null}\n </Tag>\n )\n })}\n </div>\n </section>\n ) : null}\n\n {/* Code example */}\n {codeExample ? (\n <section class=\"doc-home-section\">\n <p class=\"doc-home-section-label\">{codeExample.label || 'Quick Start'}</p>\n <div class=\"doc-home-code\">\n <div class=\"doc-home-code-header\">\n <span class=\"doc-install-dot doc-install-dot-r\" />\n <span class=\"doc-install-dot doc-install-dot-y\" />\n <span class=\"doc-install-dot doc-install-dot-g\" />\n <span class=\"doc-home-code-title\">{codeExample.title || ''}</span>\n <span style=\"width:36px\" />\n </div>\n <pre innerHTML={codeExample.code} />\n </div>\n </section>\n ) : null}\n\n {/* Content (if any markdown content is provided) */}\n {content ? (\n <section class=\"doc-home-content\">\n <div class=\"prose\" innerHTML={content} />\n </section>\n ) : null}\n\n {/* Footer */}\n <div class=\"doc-home-footer\">\n <DocFooter links={site.footerLinks} copyright={site.copyright} />\n </div>\n </main>\n </Html>\n )\n}\n","/**\n * DocNotFound layout.\n *\n * 404 page for documentation sites.\n */\n\nimport { h } from '@pagesmith/core/jsx-runtime'\nimport { DocHeader } from '../components/DocHeader'\nimport { Html } from '../components/Html'\n\ntype Props = {\n content: string\n frontmatter: Record<string, any>\n headings: Array<{ depth: number; text: string; slug: string }>\n slug: string\n site: any\n [key: string]: any\n}\n\nexport default function DocNotFound(props: Props) {\n const { site, slug } = props\n const homePath = site.homeLink || (site.basePath ? `${site.basePath}/` : '/')\n\n return (\n <Html\n title={`Page Not Found — ${site.title}`}\n description=\"The requested page could not be found.\"\n url={`${slug}/`}\n site={site}\n >\n <DocHeader\n siteName={site.name}\n basePath={site.basePath}\n homeLink={site.homeLink}\n navItems={site.navItems}\n slug={slug}\n searchEnabled={site.search?.enabled}\n />\n <main class=\"doc-not-found\">\n <div class=\"doc-not-found-container\">\n <p class=\"doc-not-found-code\">404</p>\n <h1 class=\"doc-not-found-title\">Page Not Found</h1>\n <p class=\"doc-not-found-text\">\n The page you are looking for might have been moved or no longer exists.\n </p>\n <div class=\"doc-not-found-actions\">\n <a href={homePath} class=\"doc-not-found-btn doc-not-found-btn-primary\">\n Go Home\n </a>\n </div>\n </div>\n </main>\n </Html>\n )\n}\n","import { Fragment, h } from '@pagesmith/core/jsx-runtime'\nimport type { Heading } from '@pagesmith/core/schemas'\n\ntype Props = {\n headings: Heading[]\n title?: string\n}\n\nexport function DocTOC({ headings, title = 'On this page' }: Props) {\n const filtered = headings.filter((h) => h.depth >= 2 && h.depth <= 3)\n if (filtered.length === 0) return <Fragment />\n\n return (\n <nav class=\"doc-toc\" aria-label=\"Table of contents\">\n <p class=\"doc-toc-title\">{title}</p>\n <ul class=\"doc-toc-list\">\n {filtered.map((heading) => (\n <li class={`doc-toc-item depth-${heading.depth}`}>\n <a href={`#${heading.slug}`}>{heading.text}</a>\n </li>\n ))}\n </ul>\n </nav>\n )\n}\n","/**\n * DocPage layout.\n *\n * Standard documentation page with 3-column grid:\n * left sidebar (navigation) | content | right TOC\n */\n\nimport { Fragment, h } from '@pagesmith/core/jsx-runtime'\nimport { DocFooter } from '../components/DocFooter'\nimport { DocHeader } from '../components/DocHeader'\nimport { DocSidebar } from '../components/DocSidebar'\nimport { DocTOC } from '../components/DocTOC'\nimport { Html } from '../components/Html'\n\ntype Breadcrumb = {\n label: string\n path: string\n}\n\ntype Props = {\n content: string\n frontmatter: Record<string, any>\n headings: Array<{ depth: number; text: string; slug: string }>\n slug: string\n site: any\n pages?: any[]\n sidebarSections?: any[]\n prev?: { title: string; path: string }\n next?: { title: string; path: string }\n breadcrumbs?: Breadcrumb[]\n editUrl?: string\n editLabel?: string\n lastUpdated?: string\n [key: string]: any\n}\n\nfunction formatDate(isoDate: string): string {\n const date = new Date(isoDate)\n return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })\n}\n\nexport default function DocPage(props: Props) {\n const {\n content,\n frontmatter,\n headings,\n slug,\n site,\n next,\n prev,\n sidebarSections,\n breadcrumbs,\n editUrl,\n editLabel,\n lastUpdated,\n } = props\n\n const pageTitle = frontmatter.title ? `${frontmatter.title} — ${site.title}` : site.title\n const ogImage = frontmatter.socialImage\n ? frontmatter.socialImage.startsWith('http')\n ? frontmatter.socialImage\n : `${site.basePath || ''}/${frontmatter.socialImage.replace(/^\\//, '')}`\n : undefined\n const hasPageMeta = editUrl || lastUpdated\n\n return (\n <Html\n title={pageTitle}\n description={frontmatter.description || site.description}\n url={`${slug}/`}\n socialImage={ogImage}\n site={site}\n >\n <DocHeader\n siteName={site.name}\n basePath={site.basePath}\n homeLink={site.homeLink}\n navItems={site.navItems}\n slug={slug}\n searchEnabled={site.search?.enabled}\n />\n <div class=\"doc-layout\">\n <DocSidebar\n sections={sidebarSections}\n currentSlug={slug}\n collapsible={site.sidebar?.collapsible}\n />\n <main class=\"doc-main\" data-pagefind-body=\"\">\n {/* Breadcrumbs */}\n {breadcrumbs && breadcrumbs.length > 1 ? (\n <nav class=\"doc-breadcrumbs\" aria-label=\"Breadcrumbs\">\n {breadcrumbs.map((crumb, i) =>\n crumb.path ? (\n <Fragment>\n {i > 0 ? (\n <span class=\"doc-breadcrumb-sep\" aria-hidden=\"true\">\n /\n </span>\n ) : null}\n <a href={`${crumb.path}/`}>{crumb.label}</a>\n </Fragment>\n ) : (\n <Fragment>\n {i > 0 ? (\n <span class=\"doc-breadcrumb-sep\" aria-hidden=\"true\">\n /\n </span>\n ) : null}\n <span aria-current=\"page\">{crumb.label}</span>\n </Fragment>\n ),\n )}\n </nav>\n ) : null}\n\n {/* Mobile TOC — always at top of content area */}\n {headings.length > 0 ? (\n <details class=\"doc-toc-mobile\">\n <summary>On this page</summary>\n <DocTOC headings={headings} />\n </details>\n ) : null}\n\n <article>\n <div class=\"prose\" innerHTML={content} />\n </article>\n\n {/* Page meta: edit link + last updated */}\n {hasPageMeta ? (\n <div class=\"doc-page-meta\">\n {editUrl ? (\n <a href={editUrl} class=\"doc-edit-link\" target=\"_blank\" rel=\"noopener noreferrer\">\n {editLabel || 'Edit this page'}\n </a>\n ) : null}\n {lastUpdated ? (\n <span class=\"doc-last-updated\">\n Last updated: <time datetime={lastUpdated}>{formatDate(lastUpdated)}</time>\n </span>\n ) : null}\n </div>\n ) : null}\n\n <DocFooter prev={prev} next={next} links={site.footerLinks} copyright={site.copyright} />\n </main>\n <aside class=\"doc-aside\">\n <DocTOC headings={headings} />\n </aside>\n </div>\n </Html>\n )\n}\n","import { createHash } from 'crypto'\nimport { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'fs'\nimport { basename, dirname, join, resolve } from 'path'\nimport { relative } from 'path'\nimport type { ResolvedDocsConfig } from './config.js'\nimport type { DocsPage, DocsSectionMeta, SiteModel } from './content.js'\nimport { buildBreadcrumbs, loadDocsPages, loadRootMeta, loadSectionMetas } from './content.js'\nimport { buildSiteModel, getPrevNext, getSitePayload } from './navigation.js'\nimport DocHome from '../theme/layouts/DocHome'\nimport DocNotFound from '../theme/layouts/DocNotFound'\nimport DocPage from '../theme/layouts/DocPage'\n\ntype DocsRenderable = (props: any) => unknown\n\ntype DocsLayoutRegistry = Record<string, DocsRenderable>\n\nasync function loadUserThemeModule(\n entryPath: string,\n rootDir: string,\n): Promise<Record<string, any>> {\n const { build } = await import('rolldown')\n const { pathToFileURL } = await import('url')\n\n const cacheDir = join(rootDir, 'node_modules', '.cache', 'pagesmith-docs-layouts')\n mkdirSync(cacheDir, { recursive: true })\n\n // Clean up old cached files before writing a new one\n for (const file of readdirSync(cacheDir)) {\n if (file.endsWith('.mjs')) {\n try {\n rmSync(join(cacheDir, file))\n } catch {\n // Ignore errors from concurrent cleanup\n }\n }\n }\n\n // Use content-hash-based filename for stability\n const entryContent = readFileSync(entryPath, 'utf-8')\n const contentHash = createHash('md5').update(entryContent).digest('hex').slice(0, 12)\n const safeBase = basename(entryPath)\n .replace(/[^a-z0-9]+/gi, '-')\n .toLowerCase()\n const outFile = join(cacheDir, `${safeBase}-${contentHash}.mjs`)\n\n // Skip rebuild if cached output already exists\n if (!existsSync(outFile)) {\n const rolldownBuild = build as any\n\n await rolldownBuild({\n input: entryPath,\n output: {\n file: outFile,\n format: 'esm',\n },\n platform: 'node',\n logLevel: 'warn',\n external: [/^node:/, /^@pagesmith\\//],\n moduleTypes: {\n '.ts': 'ts',\n '.tsx': 'tsx',\n },\n })\n }\n\n return import(`${pathToFileURL(outFile).href}?t=${Date.now()}`) as Promise<Record<string, any>>\n}\n\nasync function resolveDocsLayout(\n name: string,\n config: ResolvedDocsConfig,\n fallback?: DocsRenderable,\n): Promise<DocsRenderable> {\n const overridePath = config.theme?.layouts?.[name]\n if (!overridePath) {\n if (fallback) return fallback\n throw new Error(\n `Theme layout \"${name}\" is referenced in meta.json5 but not registered in theme.layouts config`,\n )\n }\n\n const absolutePath = resolve(config.rootDir, overridePath)\n const module = await loadUserThemeModule(absolutePath, config.rootDir)\n\n const knownExports: Record<string, string[]> = {\n home: ['default', 'DocHome', 'Home'],\n page: ['default', 'DocPage', 'Page'],\n notFound: ['default', 'DocNotFound', 'NotFound'],\n }\n const exportNames = knownExports[name] ?? ['default', name]\n\n for (const exportName of exportNames) {\n const candidate = module[exportName]\n if (typeof candidate === 'function') {\n return candidate as DocsRenderable\n }\n }\n\n throw new Error(\n `Theme layout \"${name}\" at ${absolutePath} must export a component as default or one of: ${exportNames.join(', ')}`,\n )\n}\n\nasync function resolveDocsLayouts(\n config: ResolvedDocsConfig,\n sectionMetas?: Map<string, DocsSectionMeta>,\n): Promise<DocsLayoutRegistry> {\n const registry: DocsLayoutRegistry = {\n home: await resolveDocsLayout('home', config, DocHome),\n page: await resolveDocsLayout('page', config, DocPage),\n notFound: await resolveDocsLayout('notFound', config, DocNotFound),\n }\n\n // Collect unique layout names from section metas\n if (sectionMetas) {\n const extraNames = new Set<string>()\n for (const meta of sectionMetas.values()) {\n if (meta.layout && !registry[meta.layout]) extraNames.add(meta.layout)\n if (meta.itemLayout && !registry[meta.itemLayout]) extraNames.add(meta.itemLayout)\n }\n for (const name of extraNames) {\n registry[name] = await resolveDocsLayout(name, config)\n }\n }\n\n return registry\n}\n\nfunction writeHtml(outDir: string, routePath: string, html: string): void {\n const outputPath =\n routePath === '/' ? join(outDir, 'index.html') : join(outDir, routePath.slice(1), 'index.html')\n mkdirSync(dirname(outputPath), { recursive: true })\n writeFileSync(outputPath, `<!DOCTYPE html>\\n${html}`)\n}\n\nexport async function renderDocs(\n config: ResolvedDocsConfig,\n): Promise<{ pages: DocsPage[]; model: SiteModel }> {\n const rootMeta = loadRootMeta(config.contentDir)\n const sectionMetas = loadSectionMetas(config.contentDir)\n const pages = await loadDocsPages(config, sectionMetas)\n const model = buildSiteModel(config, pages, rootMeta, sectionMetas)\n const site = getSitePayload(config, model)\n const layouts = await resolveDocsLayouts(config, sectionMetas)\n\n const base = config.basePath\n\n // Build edit link URL helper\n const buildEditUrl = config.editLink\n ? (sourcePath: string) => {\n const relPath = relative(config.rootDir, sourcePath)\n return `${config.editLink!.editPattern}/${relPath}`\n }\n : undefined\n\n for (const page of pages) {\n const urlPath = `${base}${page.routePath}`\n\n if (page.isHome) {\n // Prefix internal hero action links with basePath\n const frontmatter = { ...page.frontmatter }\n if (frontmatter.hero?.actions) {\n frontmatter.hero = {\n ...frontmatter.hero,\n actions: frontmatter.hero.actions.map((a: any) => ({\n ...a,\n link:\n typeof a.link === 'string' && a.link.startsWith('/') ? `${base}${a.link}` : a.link,\n })),\n }\n }\n const homeActions = Array.isArray(frontmatter.actions) ? frontmatter.actions : undefined\n if (homeActions) {\n frontmatter.actions = homeActions.map((a: any) => ({\n ...a,\n link: typeof a.link === 'string' && a.link.startsWith('/') ? `${base}${a.link}` : a.link,\n }))\n }\n\n const layout = layouts[page.layoutName] ?? layouts.home\n const output = layout({\n content: page.html,\n frontmatter,\n headings: page.headings,\n slug: urlPath,\n site,\n })\n writeHtml(config.outDir, page.routePath, String(output))\n continue\n }\n\n const sidebarSections = page.section ? model.sidebarBySection.get(page.section) : undefined\n const { prev, next } = getPrevNext(sidebarSections, urlPath)\n const breadcrumbs = buildBreadcrumbs(page.contentSlug, page.title, base)\n const editUrl = buildEditUrl ? buildEditUrl(page.sourcePath) : undefined\n const layout = layouts[page.layoutName] ?? layouts.page\n const output = layout({\n content: page.html,\n frontmatter: page.frontmatter,\n headings: page.headings,\n slug: urlPath,\n site,\n sidebarSections,\n prev,\n next,\n breadcrumbs,\n editUrl,\n editLabel: config.editLink?.label,\n lastUpdated: page.lastUpdated,\n })\n writeHtml(config.outDir, page.routePath, String(output))\n }\n\n const notFound = layouts.notFound({\n content: '',\n frontmatter: {\n title: 'Page not found',\n description: 'The page you requested could not be found.',\n },\n headings: [],\n slug: `${base}/404`,\n site,\n })\n const notFoundHtml = `<!DOCTYPE html>\\n${String(notFound)}`\n writeHtml(config.outDir, '/404', String(notFound))\n // Also write 404.html at root for GitHub Pages\n writeFileSync(join(config.outDir, '404.html'), notFoundHtml)\n\n return { pages, model }\n}\n","import { copyPublicFiles } from '@pagesmith/core/assets'\nimport { buildCss } from '@pagesmith/core/css'\nimport {\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'fs'\nimport { basename, dirname, join, relative } from 'path'\nimport { fileURLToPath } from 'url'\nimport {\n getThemeRuntimeEntry,\n getThemeStylesEntry,\n reportConfigIssues,\n resolveDocsConfig,\n validateConfig,\n type DocsBuildOptions,\n type ResolvedDocsConfig,\n} from './config.js'\nimport { collectContentAssets, type DocsPage } from './content.js'\nimport { renderDocs } from './render.js'\n\nasync function bundleThemeAssets(config: ResolvedDocsConfig): Promise<void> {\n const assetsDir = join(config.outDir, 'assets')\n mkdirSync(assetsDir, { recursive: true })\n\n const css = buildCss(getThemeStylesEntry(), { minify: true })\n writeFileSync(join(assetsDir, 'style.css'), css)\n\n const { build } = await import('rolldown')\n\n await build({\n input: getThemeRuntimeEntry(),\n output: {\n dir: assetsDir,\n entryFileNames: 'main.js',\n format: 'esm',\n minify: true,\n },\n platform: 'browser',\n logLevel: 'warn',\n })\n\n // Copy bundled font files to assets/fonts/\n const corePkgDir = dirname(fileURLToPath(import.meta.resolve('@pagesmith/core/package.json')))\n const coreFontsDir = join(corePkgDir, 'assets', 'fonts')\n const outFontsDir = join(assetsDir, 'fonts')\n mkdirSync(outFontsDir, { recursive: true })\n for (const file of readdirSync(coreFontsDir)) {\n if (file.endsWith('.woff2')) {\n copyFileSync(join(coreFontsDir, file), join(outFontsDir, file))\n }\n }\n}\n\nfunction copyPublicAssets(config: ResolvedDocsConfig): void {\n copyPublicFiles(config.publicDir, config.outDir)\n}\n\nfunction copyDirRecursive(srcDir: string, destDir: string): void {\n mkdirSync(destDir, { recursive: true })\n for (const entry of readdirSync(srcDir, { withFileTypes: true })) {\n const srcPath = join(srcDir, entry.name)\n const destPath = join(destDir, entry.name)\n if (entry.isDirectory()) {\n copyDirRecursive(srcPath, destPath)\n } else {\n copyFileSync(srcPath, destPath)\n }\n }\n}\n\nfunction copyMappedAssets(config: ResolvedDocsConfig): void {\n for (const [outputPath, sources] of config.assets) {\n // Normalize output path: \"/\" → outDir root, \"/api\" → outDir/api\n const destDir = outputPath === '/' ? config.outDir : join(config.outDir, outputPath)\n mkdirSync(destDir, { recursive: true })\n\n for (const sourcePath of sources) {\n if (!existsSync(sourcePath)) continue\n\n const stat = statSync(sourcePath)\n if (stat.isDirectory()) {\n copyDirRecursive(sourcePath, join(destDir, basename(sourcePath)))\n } else {\n copyFileSync(sourcePath, join(destDir, basename(sourcePath)))\n }\n }\n }\n}\n\nfunction copyContentAssetsToOutput(outDir: string, assets: Map<string, string>): void {\n if (assets.size === 0) return\n\n const assetsDir = join(outDir, 'assets')\n mkdirSync(assetsDir, { recursive: true })\n\n for (const [fileName, sourcePath] of assets) {\n copyFileSync(sourcePath, join(assetsDir, fileName))\n }\n}\n\nasync function runPagefind(outDir: string, extraFlags: string[] = []): Promise<void> {\n // Resolve pagefind's main entry via import.meta.resolve (works with exports-only packages)\n const { fileURLToPath } = await import('url')\n const mainUrl = import.meta.resolve('pagefind')\n const mainPath = fileURLToPath(mainUrl)\n const pagefindRoot = join(mainPath, '..', '..')\n const binaryPath = join(pagefindRoot, 'lib', 'runner', 'bin.cjs')\n\n const { execFileSync } = await import('child_process')\n execFileSync(process.execPath, [binaryPath, '--site', outDir, ...extraFlags], {\n stdio: 'inherit',\n })\n}\n\nfunction generateSitemap(pages: DocsPage[], config: ResolvedDocsConfig): string {\n const base = `${config.origin}${config.basePath}`\n const urls = pages\n .filter((p) => !p.frontmatter.draft)\n .map((p) => {\n const loc = p.isHome ? `${base}/` : `${base}${p.routePath}/`\n return ` <url><loc>${loc}</loc></url>`\n })\n\n return [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">',\n ...urls,\n '</urlset>',\n ].join('\\n')\n}\n\nconst LLMS_FILES = ['llms.txt', 'llms-full.txt']\n\nfunction copyLlmsFiles(config: ResolvedDocsConfig): void {\n for (const fileName of LLMS_FILES) {\n const sourcePath = join(config.rootDir, fileName)\n const destPath = join(config.outDir, fileName)\n if (existsSync(sourcePath) && !existsSync(destPath)) {\n copyFileSync(sourcePath, destPath)\n }\n }\n}\n\nexport async function build(options: DocsBuildOptions = {}): Promise<void> {\n const startTime = performance.now()\n const config = resolveDocsConfig(options.configPath, {\n outDir: options.outDir,\n basePath: options.basePath,\n })\n\n // Validate config and report issues\n const issues = validateConfig(config)\n if (issues.length > 0) {\n console.log()\n const hasErrors = reportConfigIssues(issues)\n console.log()\n if (hasErrors) {\n throw new Error('Config validation failed — fix the errors above before building.')\n }\n }\n\n if (existsSync(config.outDir)) {\n rmSync(config.outDir, { recursive: true, force: true })\n }\n mkdirSync(config.outDir, { recursive: true })\n\n const contentAssets = collectContentAssets(config.contentDir)\n\n await bundleThemeAssets(config)\n const { pages } = await renderDocs(config)\n copyPublicAssets(config)\n copyMappedAssets(config)\n copyContentAssetsToOutput(config.outDir, contentAssets)\n\n // Copy favicon to output if not already present (e.g. bundled default not in public/)\n if (config.favicon) {\n const faviconDest = join(config.outDir, basename(config.favicon))\n if (!existsSync(faviconDest)) {\n copyFileSync(config.favicon, faviconDest)\n }\n }\n\n // Auto-copy llms.txt convention files from project root\n copyLlmsFiles(config)\n\n // Auto-generate .nojekyll for GitHub Pages compatibility\n writeFileSync(join(config.outDir, '.nojekyll'), '')\n\n // Auto-generate sitemap.xml when origin is configured\n if (config.sitemap && config.origin !== 'https://example.com') {\n writeFileSync(join(config.outDir, 'sitemap.xml'), generateSitemap(pages, config))\n }\n\n // Auto-generate robots.txt if not already present (from publicDir or assets)\n const robotsPath = join(config.outDir, 'robots.txt')\n if (!existsSync(robotsPath)) {\n const hasSitemap = config.sitemap && config.origin !== 'https://example.com'\n const sitemapLine = hasSitemap\n ? `\\nSitemap: ${config.origin}${config.basePath}/sitemap.xml`\n : ''\n writeFileSync(robotsPath, `User-agent: *\\nAllow: /${sitemapLine}\\n`)\n }\n\n // Build summary\n const duration = ((performance.now() - startTime) / 1000).toFixed(1)\n const sectionCount = new Set(pages.map((p) => p.section).filter(Boolean)).size\n console.log()\n console.log(` Built ${pages.length} pages in ${sectionCount} sections (${duration}s)`)\n\n if (config.search.enabled) {\n console.log()\n try {\n await runPagefind(config.outDir, config.search.pagefindFlags)\n } catch (error) {\n console.warn(`\\x1b[33m⚠ Pagefind indexing failed — search will not be available.\\x1b[0m`)\n console.warn(` ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n}\n\n/**\n * Rebuild content only — skips theme bundling and Pagefind indexing.\n * Used by the dev server for fast content-only rebuilds.\n */\nexport async function rebuildContent(options: DocsBuildOptions = {}): Promise<void> {\n const config = resolveDocsConfig(options.configPath, {\n outDir: options.outDir,\n basePath: options.basePath,\n })\n\n const contentAssets = collectContentAssets(config.contentDir)\n\n await renderDocs(config)\n copyPublicAssets(config)\n copyMappedAssets(config)\n copyContentAssetsToOutput(config.outDir, contentAssets)\n\n if (config.favicon) {\n const faviconDest = join(config.outDir, basename(config.favicon))\n if (!existsSync(faviconDest)) {\n copyFileSync(config.favicon, faviconDest)\n }\n }\n}\n","import { exec } from 'child_process'\nimport { existsSync, readFileSync } from 'fs'\nimport { createServer, type IncomingMessage, type ServerResponse } from 'http'\nimport { createServer as createNetServer } from 'net'\nimport { dirname, extname, join, resolve } from 'path'\nimport { fileURLToPath } from 'url'\nimport { watch } from 'chokidar'\nimport { type WebSocket, WebSocketServer } from 'ws'\nimport {\n getThemeRoot,\n resolveDocsConfig,\n type DocsDevOptions,\n type ResolvedDocsConfig,\n} from './config.js'\nimport { loadDocsPages, loadRootMeta, loadSectionMetas, type SiteModel } from './content.js'\nimport { buildSiteModel } from './navigation.js'\nimport { build, rebuildContent } from './build.js'\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.json': 'application/json',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.svg': 'image/svg+xml',\n '.webp': 'image/webp',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.xml': 'application/xml',\n '.txt': 'text/plain; charset=utf-8',\n}\n\nconst WS_CLIENT_SCRIPT = `<script>\n(function() {\n var ws = new WebSocket('ws://' + location.host + '/__ws');\n ws.onmessage = function(e) {\n var msg = JSON.parse(e.data);\n if (msg.type === 'reload') location.reload();\n };\n ws.onclose = function() {\n setTimeout(function() { location.reload(); }, 1000);\n };\n})();\n</script>`\n\nfunction serveFile(\n filePath: string,\n res: ServerResponse,\n injectReload = false,\n statusCode = 200,\n): void {\n const ext = extname(filePath)\n const contentType = MIME[ext] || 'application/octet-stream'\n const body = readFileSync(filePath)\n\n if (ext === '.html' && injectReload) {\n const html = body.toString().replace('</body>', `${WS_CLIENT_SCRIPT}</body>`)\n res.writeHead(statusCode, { 'Content-Type': contentType })\n res.end(html)\n return\n }\n\n res.writeHead(statusCode, { 'Content-Type': contentType })\n res.end(body)\n}\n\nasync function loadSiteModel(config: ResolvedDocsConfig): Promise<SiteModel> {\n const rootMeta = loadRootMeta(config.contentDir)\n const sectionMetas = loadSectionMetas(config.contentDir)\n const pages = await loadDocsPages(config, sectionMetas)\n return buildSiteModel(config, pages, rootMeta, sectionMetas)\n}\n\nfunction logStartupSummary(config: ResolvedDocsConfig, model: SiteModel, baseUrl: string): void {\n const pageCount = model.pageByPath.size\n const sectionCount = model.sidebarBySection.size\n\n console.log(` ${pageCount} pages in ${sectionCount} sections`)\n console.log()\n\n for (const [, sections] of model.sidebarBySection) {\n const itemCount = sections.reduce((sum, s) => sum + s.items.length, 0)\n const title = sections[0]?.title ?? '(unknown)'\n const firstPath = sections[0]?.items[0]?.path ?? ''\n const url = firstPath ? `${baseUrl.replace(/\\/$/, '')}${firstPath}/` : baseUrl\n console.log(` ${title} (${itemCount} pages) ${url}`)\n }\n\n console.log()\n}\n\nfunction openBrowser(url: string): void {\n const cmd =\n process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'\n exec(`${cmd} ${url}`)\n}\n\nfunction isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = createNetServer()\n server.once('error', () => resolve(false))\n server.once('listening', () => {\n server.close(() => resolve(true))\n })\n server.listen(port)\n })\n}\n\nasync function findAvailablePort(\n startPort: number,\n strictPort: boolean,\n label: string,\n): Promise<number> {\n if (await isPortAvailable(startPort)) return startPort\n if (strictPort) {\n throw new Error(\n `Port ${startPort} is already in use (${label}). Disable strictPort to auto-find an available port.`,\n )\n }\n const maxAttempts = 20\n for (let port = startPort + 1; port < startPort + maxAttempts; port++) {\n if (await isPortAvailable(port)) {\n console.log(` Port ${startPort} in use, using ${port}`)\n return port\n }\n }\n throw new Error(`No available port found in range ${startPort}–${startPort + maxAttempts - 1}`)\n}\n\nexport async function startDev(options: DocsDevOptions = {}): Promise<void> {\n const configPath = resolve(options.configPath ?? join(process.cwd(), 'pagesmith.config.json5'))\n\n await build({ configPath })\n const config = resolveDocsConfig(configPath)\n const requestedPort = options.port ?? config.server.devPort\n const port = await findAvailablePort(requestedPort, config.server.strictPort, 'dev')\n const themeRoot = getThemeRoot()\n const watchTargets = [config.contentDir, configPath, themeRoot]\n if (existsSync(config.publicDir)) {\n watchTargets.push(config.publicDir)\n }\n\n let rebuilding = false\n let pending: 'full' | 'content' | false = false\n const clients = new Set<WebSocket>()\n\n const base = config.basePath.replace(/\\/+$/, '')\n\n function log(status: number, method: string, pathname: string): void {\n const color = status < 300 ? '\\x1b[32m' : status < 400 ? '\\x1b[36m' : '\\x1b[33m'\n console.log(` ${color}${status}\\x1b[0m ${method} ${pathname}`)\n }\n\n function notifyClients(): void {\n const payload = JSON.stringify({ type: 'reload' })\n for (const client of clients) {\n client.send(payload)\n }\n }\n\n /**\n * Determine rebuild type based on changed file path.\n * Config/theme changes require full rebuild; content changes only need content rebuild.\n */\n function getChangeType(changedPath: string): 'full' | 'content' {\n const resolved = resolve(changedPath)\n if (resolved === resolve(configPath)) return 'full'\n if (resolved.startsWith(resolve(themeRoot))) return 'full'\n return 'content'\n }\n\n async function doRebuild(type: 'full' | 'content'): Promise<void> {\n const start = performance.now()\n if (type === 'full') {\n await build({ configPath })\n } else {\n await rebuildContent({ configPath })\n }\n const elapsed = Math.round(performance.now() - start)\n console.log(\n ` \\x1b[36m${type === 'full' ? 'Full rebuild' : 'Content rebuild'} in ${elapsed}ms\\x1b[0m`,\n )\n }\n\n const server = createServer((req: IncomingMessage, res: ServerResponse) => {\n const url = new URL(req.url || '/', `http://localhost:${port}`)\n const method = req.method || 'GET'\n let pathname = url.pathname\n\n // Redirect root to basePath\n if (base && (pathname === '/' || pathname === '')) {\n log(302, method, pathname)\n res.writeHead(302, { Location: `${base}/` })\n res.end()\n return\n }\n\n // Strip basePath prefix so file lookup matches outDir structure\n if (base && pathname.startsWith(base)) {\n pathname = pathname.slice(base.length) || '/'\n }\n\n // Serve font files from core assets during dev\n if (pathname.startsWith('/assets/fonts/')) {\n const fontFile = pathname.replace('/assets/fonts/', '')\n const corePkgDir = dirname(fileURLToPath(import.meta.resolve('@pagesmith/core/package.json')))\n const fontPath = join(corePkgDir, 'assets', 'fonts', fontFile)\n if (existsSync(fontPath)) {\n log(200, method, url.pathname)\n res.writeHead(200, {\n 'Content-Type': 'font/woff2',\n 'Cache-Control': 'public, max-age=31536000',\n })\n res.end(readFileSync(fontPath))\n return\n }\n }\n\n let filePath = join(config.outDir, pathname)\n\n if (existsSync(filePath) && !extname(filePath)) {\n filePath = join(filePath, 'index.html')\n }\n\n if (!existsSync(filePath)) {\n // Try 404/index.html then 404.html (GitHub Pages convention)\n const notFoundDir = join(config.outDir, '404', 'index.html')\n const notFoundFile = join(config.outDir, '404.html')\n const notFoundPath = existsSync(notFoundDir)\n ? notFoundDir\n : existsSync(notFoundFile)\n ? notFoundFile\n : null\n if (notFoundPath) {\n log(404, method, url.pathname)\n serveFile(notFoundPath, res, true, 404)\n return\n }\n log(404, method, url.pathname)\n res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' })\n res.end('<h1>404</h1>')\n return\n }\n\n log(200, method, url.pathname)\n serveFile(filePath, res, true)\n })\n\n const wss = new WebSocketServer({ server, path: '/__ws' })\n wss.on('connection', (socket) => {\n clients.add(socket)\n socket.on('close', () => clients.delete(socket))\n })\n\n const devUrl = `http://localhost:${port}${base}/`\n\n // Load site model for startup summary\n const model = await loadSiteModel(config)\n\n server.listen(port, () => {\n console.log()\n console.log(` Docs dev: ${devUrl}`)\n console.log()\n logStartupSummary(config, model, devUrl)\n if (options.open) openBrowser(devUrl)\n })\n\n const watcher = watch(watchTargets, { ignoreInitial: true })\n watcher.on('all', async (_event, changedPath) => {\n const changeType = getChangeType(changedPath)\n\n if (rebuilding) {\n // Escalate to full if any pending change requires it\n pending = pending === 'full' || changeType === 'full' ? 'full' : 'content'\n return\n }\n\n rebuilding = true\n try {\n await doRebuild(changeType)\n notifyClients()\n } catch (err) {\n console.error('Rebuild failed:', err instanceof Error ? err.message : err)\n } finally {\n rebuilding = false\n if (pending) {\n const nextType = pending\n pending = false\n rebuilding = true\n try {\n await doRebuild(nextType)\n notifyClients()\n } catch (err) {\n console.error('Rebuild failed:', err instanceof Error ? err.message : err)\n } finally {\n rebuilding = false\n }\n }\n }\n })\n}\n\nexport async function preview(options: DocsDevOptions = {}): Promise<void> {\n const config = resolveDocsConfig(options.configPath)\n const requestedPort = options.port ?? config.server.previewPort\n const port = await findAvailablePort(requestedPort, config.server.strictPort, 'preview')\n const previewBase = config.basePath.replace(/\\/+$/, '')\n\n const server = createServer((req: IncomingMessage, res: ServerResponse) => {\n const url = new URL(req.url || '/', `http://localhost:${port}`)\n let pathname = url.pathname\n\n // Redirect root to basePath\n if (previewBase && (pathname === '/' || pathname === '')) {\n res.writeHead(302, { Location: `${previewBase}/` })\n res.end()\n return\n }\n\n // Strip basePath prefix\n if (previewBase && pathname.startsWith(previewBase)) {\n pathname = pathname.slice(previewBase.length) || '/'\n }\n\n let filePath = join(config.outDir, pathname)\n\n if (existsSync(filePath) && !extname(filePath)) {\n filePath = join(filePath, 'index.html')\n }\n\n if (!existsSync(filePath)) {\n filePath = join(config.outDir, '404', 'index.html')\n if (!existsSync(filePath)) {\n res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' })\n res.end('Not found')\n return\n }\n serveFile(filePath, res, false, 404)\n return\n }\n\n serveFile(filePath, res)\n })\n\n const previewUrl = `http://localhost:${port}${previewBase}/`\n\n // Load site model for startup summary\n const model = await loadSiteModel(config)\n\n server.listen(port, () => {\n console.log()\n console.log(` Docs preview: ${previewUrl}`)\n console.log()\n logStartupSummary(config, model, previewUrl)\n if (options.open) openBrowser(previewUrl)\n })\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagesmith/docs",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Convention-based documentation package built on @pagesmith/core",
5
5
  "keywords": [
6
6
  "cms",
@@ -24,20 +24,25 @@
24
24
  },
25
25
  "files": [
26
26
  "dist/",
27
- "theme/"
27
+ "theme/",
28
+ "REFERENCE.md"
28
29
  ],
29
30
  "type": "module",
30
31
  "exports": {
31
32
  ".": {
33
+ "types": "./dist/index.d.mts",
32
34
  "import": "./dist/index.mjs"
33
35
  },
34
36
  "./schemas": {
37
+ "types": "./dist/schemas/index.d.mts",
35
38
  "import": "./dist/schemas/index.mjs"
36
39
  },
37
40
  "./schemas/*": {
41
+ "types": "./dist/schemas/*.d.mts",
38
42
  "import": "./dist/schemas/*.mjs"
39
43
  },
40
44
  "./preset": {
45
+ "types": "./dist/preset.d.mts",
41
46
  "import": "./dist/preset.mjs"
42
47
  }
43
48
  },
@@ -47,20 +52,18 @@
47
52
  },
48
53
  "dependencies": {
49
54
  "@pagesmith/core": "*",
50
- "lightningcss": "^1.32.0",
55
+ "chokidar": "^4.0.3",
56
+ "json5": "^2.2.3",
51
57
  "pagefind": "^1.3.0",
52
- "rolldown": "^1.0.0-rc.10"
58
+ "rolldown": "^1.0.0-rc.10",
59
+ "unist-util-visit": "^5.0.0",
60
+ "ws": "^8.19.0",
61
+ "zod": "^4.3.6"
53
62
  },
54
63
  "devDependencies": {
55
64
  "@types/node": "^25.5.0",
56
65
  "@types/ws": "^8.18.1",
57
- "chokidar": "^4.0.3",
58
- "gray-matter": "^4.0.3",
59
- "json5": "^2.2.3",
60
66
  "typescript": "^5.9.0",
61
- "unist-util-visit": "^5.0.0",
62
- "vite-plus": "^0.1.13",
63
- "ws": "^8.19.0",
64
- "zod": "^4.3.6"
67
+ "vite-plus": "^0.1.13"
65
68
  }
66
69
  }
@@ -4,6 +4,7 @@ type Props = {
4
4
  title: string
5
5
  description?: string
6
6
  url?: string
7
+ socialImage?: string
7
8
  site: {
8
9
  origin: string
9
10
  basePath?: string
@@ -14,12 +15,37 @@ type Props = {
14
15
  analytics?: { googleAnalytics?: string }
15
16
  footerLinks?: Array<{ label: string; path: string }>
16
17
  search?: { enabled?: boolean; showImages?: boolean; showSubResults?: boolean }
18
+ socialImage?: string
17
19
  favicon?: string | false
20
+ faviconFallback?: string | false
21
+ appleTouchIcon?: string | false
18
22
  }
19
23
  children?: any
20
24
  }
21
25
 
22
- export function Html({ title, description, url, site, children }: Props) {
26
+ function buildCsp(gaId?: string): string {
27
+ const scriptSrc = ["'self'", "'unsafe-inline'"]
28
+ const connectSrc = ["'self'"]
29
+
30
+ if (gaId) {
31
+ scriptSrc.push('https://www.googletagmanager.com')
32
+ connectSrc.push('https://www.google-analytics.com', 'https://analytics.google.com')
33
+ }
34
+
35
+ return [
36
+ "default-src 'self'",
37
+ `script-src ${scriptSrc.join(' ')}`,
38
+ "style-src 'self' 'unsafe-inline'",
39
+ "img-src 'self' data:",
40
+ "font-src 'self'",
41
+ `connect-src ${connectSrc.join(' ')}`,
42
+ "object-src 'none'",
43
+ "base-uri 'self'",
44
+ "form-action 'self'",
45
+ ].join('; ')
46
+ }
47
+
48
+ export function Html({ title, description, url, socialImage, site, children }: Props) {
23
49
  const origin = site.origin.replace(/\/$/, '')
24
50
  const base = site.basePath || ''
25
51
  const canonicalUrl = url ? `${origin}${url}` : undefined
@@ -27,8 +53,11 @@ export function Html({ title, description, url, site, children }: Props) {
27
53
  const lightColor = site.theme?.lightColor || '#f8fafc'
28
54
  const darkColor = site.theme?.darkColor || '#020617'
29
55
  const gaId = site.analytics?.googleAnalytics
56
+ const ogImage = socialImage ?? site.socialImage
30
57
  const searchEnabled = site.search?.enabled !== false
31
58
  const favicon = site.favicon
59
+ const faviconFallback = site.faviconFallback
60
+ const appleTouchIcon = site.appleTouchIcon
32
61
 
33
62
  return (
34
63
  <html lang={site.language || 'en'} class="no-js">
@@ -36,7 +65,14 @@ export function Html({ title, description, url, site, children }: Props) {
36
65
  <meta charset="utf-8" />
37
66
  <meta name="viewport" content="width=device-width, initial-scale=1" />
38
67
  <meta name="color-scheme" content="light dark" />
68
+
69
+ {/* Security */}
70
+ <meta http-equiv="Content-Security-Policy" content={buildCsp(gaId)} />
71
+ <meta name="referrer" content="strict-origin-when-cross-origin" />
72
+
39
73
  <title>{title}</title>
74
+
75
+ {/* Icons */}
40
76
  {favicon !== false && favicon ? (
41
77
  <link
42
78
  rel="icon"
@@ -44,6 +80,8 @@ export function Html({ title, description, url, site, children }: Props) {
44
80
  type={favicon.endsWith('.svg') ? 'image/svg+xml' : 'image/x-icon'}
45
81
  />
46
82
  ) : null}
83
+ {faviconFallback ? <link rel="icon" href={faviconFallback} sizes="32x32" /> : null}
84
+ {appleTouchIcon ? <link rel="apple-touch-icon" href={appleTouchIcon} /> : null}
47
85
  {description ? <meta name="description" content={description} /> : null}
48
86
 
49
87
  {/* Canonical URL */}
@@ -54,6 +92,12 @@ export function Html({ title, description, url, site, children }: Props) {
54
92
  {canonicalUrl ? <meta property="og:url" content={canonicalUrl} /> : null}
55
93
  <meta property="og:title" content={title} />
56
94
  {description ? <meta property="og:description" content={description} /> : null}
95
+ {ogImage ? (
96
+ <meta
97
+ property="og:image"
98
+ content={ogImage.startsWith('http') ? ogImage : `${origin}${ogImage}`}
99
+ />
100
+ ) : null}
57
101
  <meta property="og:locale" content={locale} />
58
102
  <meta property="og:site_name" content={site.name} />
59
103
 
@@ -61,6 +105,19 @@ export function Html({ title, description, url, site, children }: Props) {
61
105
  <meta name="theme-color" content={lightColor} media="(prefers-color-scheme: light)" />
62
106
  <meta name="theme-color" content={darkColor} media="(prefers-color-scheme: dark)" />
63
107
 
108
+ {/* Performance: font preload */}
109
+ <link
110
+ rel="preload"
111
+ href={`${base}/assets/fonts/open-sans-variable.woff2`}
112
+ as="font"
113
+ type="font/woff2"
114
+ crossorigin=""
115
+ />
116
+ {/* Performance: GA preconnect */}
117
+ {gaId ? (
118
+ <link rel="preconnect" href="https://www.googletagmanager.com" crossorigin="" />
119
+ ) : null}
120
+
64
121
  {/* CSS */}
65
122
  <link rel="stylesheet" href={`${base}/assets/style.css`} />
66
123
  {searchEnabled ? <link rel="stylesheet" href={`${base}/pagefind/pagefind-ui.css`} /> : null}
@@ -62,7 +62,14 @@ export default function DocHome(props: Props) {
62
62
  <Html
63
63
  title={hero?.name || frontmatter.title || site.title}
64
64
  description={hero?.tagline || frontmatter.description || site.description}
65
- url="/"
65
+ url={slug}
66
+ socialImage={
67
+ frontmatter.socialImage
68
+ ? frontmatter.socialImage.startsWith('http')
69
+ ? frontmatter.socialImage
70
+ : `${site.basePath || ''}/${frontmatter.socialImage.replace(/^\//, '')}`
71
+ : undefined
72
+ }
66
73
  site={site}
67
74
  >
68
75
  <DocHeader