//#region src/types.d.ts /** * Theme / UI configuration types for the docs framework. * Inspired by Fumadocs: https://github.com/fuma-nama/fumadocs */ /** * Fine-grained UI configuration for docs themes. * * Theme authors define defaults for these values in their `createTheme` call. * End users can override any value when calling the theme factory. * * @example * ```ts * const myTheme = createTheme({ * name: "my-theme", * ui: { * colors: { primary: "#6366f1", background: "#0a0a0a" }, * radius: "0px", * codeBlock: { showLineNumbers: true, theme: "github-dark" }, * sidebar: { width: 280, style: "bordered" }, * }, * }); * ``` */ /** * Font style configuration for a single text element (heading, body, etc.). * * @example * ```ts * h1: { size: "2.25rem", weight: 700, lineHeight: "1.2", letterSpacing: "-0.02em" } * ``` */ interface FontStyle { /** CSS `font-size` value (e.g. "2.25rem", "36px", "clamp(1.8rem, 3vw, 2.5rem)") */ size?: string; /** CSS `font-weight` value (e.g. 700, "bold", "600") */ weight?: string | number; /** CSS `line-height` value (e.g. "1.2", "1.5", "28px") */ lineHeight?: string; /** CSS `letter-spacing` value (e.g. "-0.02em", "0.05em") */ letterSpacing?: string; } /** * Typography configuration for the docs. * * @example * ```ts * typography: { * font: { * style: { sans: "Inter, sans-serif", mono: "JetBrains Mono, monospace" }, * h1: { size: "2.25rem", weight: 700, letterSpacing: "-0.02em" }, * h2: { size: "1.75rem", weight: 600 }, * body: { size: "1rem", lineHeight: "1.75" }, * }, * } * ``` */ interface TypographyConfig { /** * Font configuration. */ font?: { /** * Font family definitions. */ style?: { /** Sans-serif font family — used for body text, headings, and UI elements. */sans?: string; /** Monospace font family — used for code blocks, inline code, and terminal output. */ mono?: string; }; /** Heading 1 (`

`) style overrides */ h1?: FontStyle; /** Heading 2 (`

`) style overrides */ h2?: FontStyle; /** Heading 3 (`

`) style overrides */ h3?: FontStyle; /** Heading 4 (`

`) style overrides */ h4?: FontStyle; /** Body text style */ body?: FontStyle; /** Small text style (captions, meta text) */ small?: FontStyle; }; } interface UIConfig { /** * Theme color tokens. * * These are mapped to `--color-fd-*` CSS variables at runtime. * Accepts any valid CSS color value (hex, rgb, oklch, hsl, etc.). * * @example * ```ts * colors: { * primary: "oklch(0.72 0.19 149)", // green primary * primaryForeground: "#ffffff", // white text on primary * accent: "hsl(220 80% 60%)", // blue accent * } * ``` */ colors?: { primary?: string; primaryForeground?: string; background?: string; foreground?: string; muted?: string; mutedForeground?: string; border?: string; card?: string; cardForeground?: string; accent?: string; accentForeground?: string; secondary?: string; secondaryForeground?: string; popover?: string; popoverForeground?: string; ring?: string; }; /** * Typography settings — font families, heading sizes, weights, etc. * * @example * ```ts * typography: { * font: { * style: { sans: "Inter, sans-serif", mono: "JetBrains Mono, monospace" }, * h1: { size: "2.25rem", weight: 700, letterSpacing: "-0.02em" }, * body: { size: "1rem", lineHeight: "1.75" }, * }, * } * ``` */ typography?: TypographyConfig; /** * Global border-radius. Maps to CSS `--radius`. * Use "0px" for sharp corners, "0.5rem" for rounded, etc. */ radius?: string; /** Layout dimensions */ layout?: { contentWidth?: number; sidebarWidth?: number; tocWidth?: number; toc?: { enabled?: boolean; depth?: number; /** * Visual style of the TOC indicator. * - `"default"` — highlight active link text color only * - `"directional"` — animated thumb bar that tracks active headings (fumadocs style) * @default "default" */ style?: "default" | "directional"; }; header?: { height?: number; sticky?: boolean; }; }; /** Code block rendering config */ codeBlock?: { /** Show line numbers in code blocks @default false */showLineNumbers?: boolean; /** Show copy button @default true */ showCopyButton?: boolean; /** Shiki theme name for syntax highlighting */ theme?: string; /** Dark mode shiki theme (for dual-theme setups) */ darkTheme?: string; }; /** Sidebar styling hints (consumed by theme CSS) */ sidebar?: { /** * Visual style of the sidebar. * - "default" — standard fumadocs sidebar * - "bordered" — visible bordered sections (like better-auth) * - "floating" — floating card sidebar */ style?: "default" | "bordered" | "floating"; /** Background color override */ background?: string; /** Border color override */ borderColor?: string; }; /** Card styling */ card?: { /** Whether cards have visible borders @default true */bordered?: boolean; /** Card background color override */ background?: string; }; /** Default props/variants for built-in MDX components (Callout, CodeBlock, Tabs, HoverLink, Prompt, etc.) */ components?: { [key: string]: Record | ((defaults: unknown) => unknown); }; } /** * A docs theme configuration. * * Theme authors create these with `createTheme()`. The `name` identifies the * theme (useful for CSS scoping, debugging, analytics). The `ui` object holds * all visual configuration. * * @example * ```ts * import { createTheme } from "@farming-labs/docs"; * * export const myTheme = createTheme({ * name: "my-theme", * ui: { * colors: { primary: "#ff4d8d" }, * radius: "0px", * }, * }); * ``` */ interface DocsTheme { /** Unique name for this theme (used for CSS scoping and debugging) */ name?: string; /** UI configuration — colors, typography, layout, components */ ui?: UIConfig; /** * @internal * User-provided color overrides tracked by `createTheme`. * Only these colors are emitted as inline CSS variables at runtime. * Preset defaults stay in the theme's CSS file. */ _userColorOverrides?: Record; } interface DocsMetadata { titleTemplate?: string; description?: string; twitterCard?: "summary" | "summary_large_image"; } interface OGConfig { enabled?: boolean; type?: "static" | "dynamic"; endpoint?: string; defaultImage?: string; } /** Single image entry for Open Graph (frontmatter or Next metadata). */ interface OpenGraphImage { url: string; width?: number; height?: number; } /** Open Graph block in page frontmatter. When present, used as-is for metadata (replaces generated OG). */ interface PageOpenGraph { images?: OpenGraphImage[]; title?: string; description?: string; } /** Twitter card block in page frontmatter. When present, used as-is for metadata (replaces generated twitter). */ interface PageTwitter { card?: "summary" | "summary_large_image"; images?: string[]; title?: string; description?: string; } type DocsRelatedItem = string; interface ResolvedDocsRelatedLink { href: string; } interface PageAgentFrontmatter { /** * Approximate output token target for machine-readable compaction on this page. * Used by `docs agent compact` as a per-page override. */ tokenBudget?: number; } interface PageSidebarFrontmatter { /** * Override how this folder page behaves in the default sidebar when it has children. * * This is only read from folder landing pages such as `page.mdx` / `index.md`. */ folderIndexBehavior?: SidebarFolderIndexBehavior; } interface PageFrontmatter { title: string; description?: string; /** Related doc URLs rendered into machine-readable markdown routes and MCP page output. */ related?: DocsRelatedItem[]; /** Per-page agent-oriented metadata used by machine-readable docs features. */ agent?: PageAgentFrontmatter; /** Per-page sidebar metadata used when building the docs navigation tree. */ sidebar?: PageSidebarFrontmatter; /** Override or disable the estimated reading time for this page. */ readingTime?: boolean | number; tags?: string[]; icon?: string; /** Path to custom OG image for this page (shorthand). Ignored if `openGraph` is set. */ ogImage?: string; /** Full Open Graph object. When set, replaces any generated OG from config (e.g. dynamic endpoint). */ openGraph?: PageOpenGraph; /** Full Twitter card object. When set, replaces any generated twitter from config. */ twitter?: PageTwitter; /** Sort order in the sidebar. Lower numbers appear first. Pages without `order` are sorted alphabetically after ordered pages. */ order?: number; } interface DocsNav { /** * Sidebar title — a plain string or a React element (e.g. a div with an icon). * * @example * ```tsx * // Simple string * nav: { title: "My Docs" } * * // React element with icon * nav: { * title:
* Example Docs *
* } * ``` */ title?: unknown; /** URL the title links to. Defaults to `/{entry}`. */ url?: string; } interface ThemeToggleConfig { /** * Whether to show the light/dark theme toggle in the sidebar. * @default true */ enabled?: boolean; /** * The default / forced theme when the toggle is hidden. * Only applies when `enabled` is `false`. * @default "system" * * @example * ```ts * // Hide toggle, force dark mode * themeToggle: { enabled: false, default: "dark" } * ``` */ default?: "light" | "dark" | "system"; /** * Toggle mode — show only light/dark, or include a system option. * @default "light-dark" */ mode?: "light-dark" | "light-dark-system"; } interface BreadcrumbConfig { /** * Whether to show the breadcrumb navigation above page content. * @default true */ enabled?: boolean; /** * Custom breadcrumb component. Receives the default breadcrumb as children * so you can wrap/modify it. * * @example * ```tsx * breadcrumb: { * component: ({ items }) => , * } * ``` */ component?: unknown; } /** * A leaf page in the sidebar tree. */ interface SidebarPageNode { type: "page"; name: string; url: string; icon?: unknown; } /** * A folder (group) in the sidebar tree. May contain child pages * and nested folders, forming a recursive hierarchy. */ interface SidebarFolderNode { type: "folder"; name: string; icon?: unknown; /** Index page for this folder (the folder's own landing page). */ index?: SidebarPageNode; /** * Optional per-folder override read from the folder page frontmatter before the * tree is normalized for the default sidebar. */ folderIndexBehavior?: SidebarFolderIndexBehavior; /** Child pages and sub-folders. */ children: SidebarNode[]; /** Whether this folder section is collapsible. */ collapsible?: boolean; /** Whether this folder starts open. */ defaultOpen?: boolean; } /** A node in the sidebar tree — either a page or a folder. */ type SidebarNode = SidebarPageNode | SidebarFolderNode; /** The full sidebar tree passed to custom sidebar components. */ interface SidebarTree { name: string; children: SidebarNode[]; } /** * Props passed to a custom sidebar component. * * Contains all the information needed to build a fully custom sidebar: * the complete page tree with parent-child relationships, and the * current sidebar configuration. */ interface SidebarComponentProps { /** Full page tree with all parent-child-folder relationships. */ tree: SidebarTree; /** Whether folders are collapsible. */ collapsible: boolean; /** Whether folders are rendered flat (Mintlify-style). */ flat: boolean; } /** * Controls how folders with their own landing page behave in the default sidebar. * * - `"link"` — clicking the parent row navigates to the folder landing page * - `"toggle"` — clicking the parent row only expands/collapses children, and the * landing page is rendered as the first child item instead */ type SidebarFolderIndexBehavior = "link" | "toggle" | "hidden"; type SidebarFolderIndexBehaviorOverrides = Record; interface SidebarConfig { /** * Whether to show the sidebar. * @default true */ enabled?: boolean; /** * Custom sidebar component to replace the default navigation. * * **Next.js** — Pass a render function that receives `SidebarComponentProps`: * ```tsx * sidebar: { * component: ({ tree, collapsible, flat }) => ( * * ), * } * ``` * * **Astro** — Use the `sidebar` named slot on ``: * ```astro * * * * * ``` * * **SvelteKit** — Use the `sidebar` snippet on ``: * ```svelte * * {#snippet sidebar({ tree, isActive })} * * {/snippet} * {@render children()} * * ``` * * **Nuxt / Vue** — Use the `#sidebar` scoped slot on ``: * ```vue * * * * * ``` */ component?: (props: SidebarComponentProps) => unknown; /** * Sidebar footer content (rendered below navigation items). */ footer?: unknown; /** * Sidebar banner content (rendered above navigation items). */ banner?: unknown; /** * Whether the sidebar is collapsible on desktop. * @default true */ collapsible?: boolean; /** * When true, all folder children are rendered flat in the sidebar * (no collapsible sections). Folder index pages appear as category * headings with all children listed directly below them. * * This creates a Mintlify-style sidebar where all navigation items * are always visible. * * @default false */ flat?: boolean; /** * How folders with their own `page.mdx` / `page.md` behave in the default sidebar. * * - `"link"` — clicking the parent row navigates to the folder landing page * - `"toggle"` — clicking the parent row only expands/collapses children, and the * folder landing page appears as the first child item instead * - `"hidden"` — the folder landing page route still exists, but the parent row * becomes a plain label and only the child pages appear in the sidebar * * This is the global default. Individual folder pages can still override it with * page frontmatter: * * ```mdx * --- * sidebar: * folderIndexBehavior: "hidden" * --- * ``` * * When omitted, each adapter keeps its existing folder-parent behavior. Set this * explicitly if you want the same sidebar interaction across frameworks. */ folderIndexBehavior?: SidebarFolderIndexBehavior; /** * Selective per-folder overrides keyed by the folder landing-page URL. * Folder page frontmatter still wins when both are present. * * ```ts * sidebar: { * folderIndexBehavior: "link", * folderIndexBehaviorOverrides: { * "/docs/components": "toggle", * "/docs/guides": "toggle", * }, * } * ``` */ folderIndexBehaviorOverrides?: SidebarFolderIndexBehaviorOverrides; } type OpenDocsTarget = "markdown" | "page" | "source" | "github"; type OpenDocsProviderId = "chatgpt" | "claude" | "cursor" | "gemini" | "copilot" | "github"; /** * A single "Open in …" provider shown in the Open dropdown. * * Pass a string for a built-in provider preset, or pass an object to customize a known provider * or keep using a custom `urlTemplate`. * * @example * ```ts * "cursor" * ``` * * @example * ```ts * { * id: "cursor", * prompt: "Use this docs page while editing the codebase: {url}", * } * ``` * * @example * ```ts * { * name: "Claude", * icon: , * urlTemplate: "https://claude.ai?url={url}.md", * promptUrlTemplate: "https://claude.ai/new?q={prompt}", * } * ``` */ type OpenDocsProvider = OpenDocsProviderId | OpenDocsProviderConfig; interface OpenDocsProviderConfig { /** Built-in provider preset to use as the base. */ id?: OpenDocsProviderId | string; /** Display name (e.g. "ChatGPT", "Claude", "Cursor") */ name?: string; /** Alias for `name` when configuring a preset provider. */ label?: string; /** Icon element rendered next to the name */ icon?: unknown; /** Override the target URL inserted into `{url}` for this provider. */ target?: OpenDocsTarget; /** Prompt text used by known provider presets. Supports `{url}`, `{pageUrl}`, `{markdownUrl}`, `{sourceUrl}`, `{mdxUrl}`, and `{githubUrl}`. */ prompt?: string; /** Cursor-specific mode. `"web"` opens cursor.com; `"app"` opens the Cursor app deeplink. */ mode?: "web" | "app"; /** * URL template. Placeholders: * - `{url}` — selected target URL, controlled by `openDocs.target` or provider `target` (encoded). * - `{pageUrl}` — rendered docs page URL (encoded). * - `{markdownUrl}` — public `.md` route for the page (encoded). * - `{sourceUrl}` / `{mdxUrl}` — page URL with `.mdx` suffix (encoded). * - `{githubUrl}` — GitHub edit URL for the current page (same as "Edit on GitHub"). Requires `github` in config. * - `{prompt}` — prompt text after resolving the target URL placeholders (encoded). * * @example "https://claude.ai/new?q=Read+this+doc:+{url}.md" * @example "{githubUrl}" — open current page file on GitHub (edit view) */ urlTemplate?: string; /** * Optional URL template used by the built-in `Prompt` MDX component. * When omitted, known providers such as ChatGPT, Claude, Cursor, Gemini, * and Copilot fall back to a built-in `{prompt}` template by provider name. * * Placeholders: * - `{prompt}` — prompt text (encoded). * * @example "https://cursor.com/link/prompt?text={prompt}" */ promptUrlTemplate?: string; } /** * Configuration for the "Open in …" dropdown that lets users * send the current page to an LLM or external tool. * * @example * ```ts * openDocs: { * enabled: true, * target: "markdown", * providers: [ * "chatgpt", * "claude", * "cursor", * ], * } * ``` */ interface OpenDocsConfig { /** Whether to show the "Open" dropdown. @default false */ enabled?: boolean; /** * Which URL should be inserted into `{url}` for preset providers and provider templates. * @default "markdown" */ target?: OpenDocsTarget; /** * Prompt text used by built-in provider presets. * Supports `{url}`, `{pageUrl}`, `{markdownUrl}`, `{sourceUrl}`, `{mdxUrl}`, * and `{githubUrl}`. * * @default "Read this documentation: {url}" */ prompt?: string; /** * List of LLM / tool providers to show in the dropdown. * If not provided, a sensible default list is used. */ providers?: OpenDocsProvider[]; } /** * Configuration for the "Copy Markdown" button that copies * the current page's content as Markdown to the clipboard. */ interface CopyMarkdownConfig { /** Whether to show the "Copy Markdown" button. @default false */ enabled?: boolean; } /** * Page-level action buttons shown above the page content * (e.g. "Copy Markdown", "Open in …" dropdown). * * @example * ```ts * pageActions: { * copyMarkdown: { enabled: true }, * openDocs: { * enabled: true, * target: "markdown", * providers: [ * "chatgpt", * "claude", * { id: "cursor", mode: "app" }, * ], * }, * } * ``` */ interface PageActionsConfig { /** "Copy Markdown" button */ copyMarkdown?: boolean | CopyMarkdownConfig; /** "Open in …" dropdown with LLM / tool providers */ openDocs?: boolean | OpenDocsConfig; /** * Where to render the page action buttons relative to the page title. * * - `"below-title"` — render below the first `

` heading (default) * - `"above-title"` — render above the page title / content * - `"toc"` — render as a compact rail in the table-of-contents column * * @default "below-title" */ position?: "above-title" | "below-title" | "toc"; /** * Horizontal alignment of page action buttons. * * - `"left"` — align to the left (default) * - `"right"` — align to the right * * @default "left" */ alignment?: "left" | "right"; } type DocsAnalyticsSource = "client" | "server" | "mcp"; type DocsAgentTraceStatus = "started" | "success" | "error" | "retry" | "timeout"; type DocsAgentTraceEventType = "run.start" | "run.end" | "run.error" | "user.input" | "prompt.build" | "retrieval.query" | "retrieval.result" | "retrieval.error" | "model.call" | "model.response" | "model.stream" | "model.error" | "tool.call" | "tool.result" | "tool.error" | "retry" | "timeout" | "error" | "agent.final"; type DocsAnalyticsEventType = "page_view" | "search_open" | "search_close" | "search_query" | "search_result_click" | "search_error" | "ai_open" | "ai_close" | "ai_question" | "ai_response" | "ai_feedback" | "ai_error" | "ai_clear" | "page_action_copy_markdown" | "page_action_open_docs_menu" | "page_action_open_docs" | "code_block_copy" | "feedback_select" | "feedback_submit" | "feedback_error" | "agent_read" | "agent_spec_request" | "agents_request" | "agent_feedback_schema" | "agent_feedback_submit" | "agent_feedback_error" | "markdown_request" | "llms_request" | "skill_request" | "api_search" | "api_ai_request" | "api_ai_response" | "api_ai_error" | "mcp_request" | "mcp_tool"; interface DocsAnalyticsInput { query?: string; question?: string; feedbackValue?: string; feedbackComment?: string; content?: string; } interface DocsEventBase { timestamp: string; source: DocsAnalyticsSource; url?: string; path?: string; referrer?: string; locale?: string; input?: DocsAnalyticsInput; metadata?: Record; properties?: Record; } interface DocsAnalyticsEvent extends DocsEventBase { type: DocsAnalyticsEventType | (string & {}); } type DocsAnalyticsEventInput = Omit & { timestamp?: string; source?: DocsAnalyticsSource; }; interface DocsObservabilityEvent extends DocsEventBase { type: DocsAgentTraceEventType | (string & {}); traceId?: string; spanId?: string; parentSpanId?: string; name?: string; startedAt?: string; endedAt?: string; durationMs?: number; status?: DocsAgentTraceStatus; inputPreview?: Record; outputPreview?: Record; } type DocsObservabilityEventInput = Omit & { timestamp?: string; source?: DocsAnalyticsSource; }; type DocsAgentTraceEventInput = Omit & { type: DocsAgentTraceEventType; name: string; }; interface DocsAnalyticsConfig { /** Enable event emission. Defaults to `true` when this object is provided. */ enabled?: boolean; /** * Log events to the console. * * `analytics: true` logs with `console.info`. When `onEvent` is provided, * console logging is disabled unless this is set. */ console?: boolean | "log" | "info" | "debug"; /** * Include raw search queries, AI questions, feedback comments, and copied * content in emitted events. * * Defaults to `false`; events still include safe metadata such as lengths, * counts, routes, status, and duration. */ includeInputs?: boolean; /** Callback fired for every emitted event. */ onEvent?: (event: DocsAnalyticsEvent) => void | Promise; } interface DocsCloudApiKeyConfig { /** * Environment variable that stores the Docs Cloud API key. * * The key value is never written to docs.json; only this env var name is * mirrored for CLI and CI workflows. * * @default "DOCS_CLOUD_API_KEY" */ env?: string; } interface DocsCloudPreviewConfig { /** * Legacy hosted preview deployment gate. * * Prefer `cloud.deploy.enabled` in new configs. * * @default true when this legacy object is provided */ enabled?: boolean; } interface DocsCloudPublishConfig { /** How Docs Cloud should publish generated docs changes. @default "draft-pr" */ mode?: "draft-pr" | "direct-commit"; /** Branch that generated docs work should target. @default "main" */ baseBranch?: string; } interface DocsCloudFeatureConfig { /** Whether the hosted cloud feature is enabled. @default true */ enabled?: boolean; } interface DocsCloudConfig { /** * Optional explicit cloud toggle. * * Prefer omitting this in new projects; the presence of `cloud` opts the * project into cloud-aware CLI flows. This remains available for backwards * compatibility with older docs.json files. */ enabled?: boolean; /** API key lookup used by `docs deploy` and other cloud CLI commands. */ apiKey?: DocsCloudApiKeyConfig; /** Legacy hosted preview deployment settings. Prefer `deploy` in new configs. */ preview?: DocsCloudPreviewConfig; /** Generated docs publishing settings. */ publish?: DocsCloudPublishConfig; /** Hosted analytics settings that can be mirrored to docs.json. */ analytics?: boolean | Omit; /** Hosted AI feature toggle. */ ai?: DocsCloudFeatureConfig; /** Hosted deployment feature toggle used by `docs deploy`. */ deploy?: DocsCloudFeatureConfig; } interface DocsObservabilityConfig { /** Enable trace emission. Defaults to `true` when this object is provided. */ enabled?: boolean; /** * Log trace events to the console. * * `observability: true` logs with `console.info`. When `onEvent` is provided, * console logging is disabled unless this is set. */ console?: boolean | "log" | "info" | "debug"; /** * Include raw `input` fields on observability events. * * Defaults to `false`; events still include safe metadata such as lengths, * counts, routes, status, and duration. Built-in trace events use previews * instead of raw user-authored text. */ includeInputs?: boolean; /** Callback fired for every emitted trace event. */ onEvent?: (event: DocsObservabilityEvent) => void | Promise; } /** * Configuration for the "Last updated" date display. * * @example * ```ts * lastUpdated: { position: "below-title" } * ``` */ /** * Configuration for auto-generated `/llms.txt` and `/llms-full.txt` routes. * Native static files at the same public routes take precedence. * * @see https://llmstxt.org */ interface LlmsTxtConfig { /** * Whether to enable llms.txt generation. * @default true */ enabled?: boolean; /** * Base URL for your docs site (used to build absolute links in llms.txt). * @example "https://docs.example.com" */ baseUrl?: string; /** * Site title shown at the top of llms.txt. * Falls back to `nav.title` if not set. */ siteTitle?: string; /** * Site description shown below the title. */ siteDescription?: string; /** * Character budget for generated compact `llms.txt` files. * * `mode: "warn"` logs a warning when the generated content is over budget. * `mode: "error"` returns an error response for that generated file. * `mode: "off"` disables the budget check. * * @default { mode: "warn", chars: 50000 } */ maxChars?: LlmsTxtMaxCharsConfig; /** * Optional section-level llms.txt files for progressive disclosure. * * Each section is matched against public docs URLs, for example * `/docs/api/**` derives `/docs/api/llms.txt` and * `/docs/api/llms-full.txt`. */ sections?: LlmsTxtSectionConfig[]; } type LlmsTxtMaxCharsMode = "warn" | "error" | "off"; interface LlmsTxtMaxCharsConfig { /** * How to handle generated llms.txt content that exceeds `chars`. * * @default "warn" */ mode?: LlmsTxtMaxCharsMode; /** * Maximum recommended character count. * * @default 50000 */ chars?: number; } interface LlmsTxtSectionConfig { /** * Human-readable section title shown in the root and section files. */ title: string; /** * Optional description shown next to the section link in root llms.txt. */ description?: string; /** * Public URL matcher for pages included in this section. * * Supported forms include exact paths such as `/docs/reference` and * prefix globs such as `/docs/api/**`. */ match: string | string[]; /** * Optional section-specific character budget. Inherits `llmsTxt.maxChars` * when omitted. */ maxChars?: LlmsTxtMaxCharsConfig; } interface SitemapXmlConfig { /** * Whether to expose the XML sitemap route. * @default true */ enabled?: boolean; /** * Include per-page `` entries when a reliable page date is available. * @default true */ includeLastmod?: boolean; } interface SitemapMarkdownConfig { /** * Whether to expose the Markdown sitemap route. * @default true */ enabled?: boolean; /** * Include page descriptions in the Markdown sitemap. * @default true */ includeDescriptions?: boolean; /** * Include per-page freshness dates in the Markdown sitemap. * @default true */ includeLastmod?: boolean; /** * Which URL each Markdown list item should primarily link to. * @default "both" */ linkTarget?: "html" | "markdown" | "both"; } /** * Configuration for generated `/sitemap.xml`, `/sitemap.md`, `/docs/sitemap.md`, and * `/.well-known/sitemap.md` routes. */ interface DocsSitemapConfig { /** * Whether to enable sitemap routes. * @default true */ enabled?: boolean; /** * Optional route prefix. For example, `"/docs"` generates * `/docs/sitemap.xml`, `/docs/sitemap.md`, and `/docs/.well-known/sitemap.md`. * @default "" */ routePrefix?: string; /** * Public site URL used to build absolute XML sitemap URLs. * Falls back to the request origin at runtime or llmsTxt.baseUrl in the CLI. */ baseUrl?: string; /** * Internal generated manifest path. * @default ".farming-labs/sitemap-manifest.json" */ manifestPath?: string; /** XML sitemap options. */ xml?: boolean | SitemapXmlConfig; /** Markdown sitemap options. */ markdown?: boolean | SitemapMarkdownConfig; } interface DocsRobotsRule { /** User-agent name or names for this robots.txt rule block. */ userAgent: string | string[]; /** Routes to allow for the user-agent block. */ allow?: string | string[]; /** Routes to disallow for the user-agent block. */ disallow?: string | string[]; /** Optional crawl-delay value emitted as-is for crawlers that support it. */ crawlDelay?: number; } /** * Configuration for generated `robots.txt` agent access policy files. */ interface DocsRobotsConfig { /** * Whether robots.txt generation is enabled. * @default true when `robots` is an object */ enabled?: boolean; /** * Output file path used by `docs robots generate`. * Falls back to the framework public directory, such as `public/robots.txt` * or `static/robots.txt` for SvelteKit. */ path?: string; /** * Public site URL used for the `Sitemap:` line. * Falls back to `sitemap.baseUrl` or `llmsTxt.baseUrl` in the CLI. */ baseUrl?: string; /** * Whether to explicitly allow or disallow common AI crawlers. * @default "allow" */ ai?: boolean | "allow" | "disallow"; /** * Additional AI user-agent names to include beside the defaults. */ aiUserAgents?: string | string[]; /** * Extra robots.txt rule blocks appended after the generated agent policy. */ extraRules?: DocsRobotsRule[]; } /** * Tool-level toggles for the built-in MCP server. * * All tools default to `true` when omitted. */ interface DocsMcpToolsConfig { /** Expose a `list_docs` tool that returns docs pages grouped by section. */ listDocs?: boolean; /** Expose a `list_pages` tool that returns the known docs pages. */ listPages?: boolean; /** Expose a `read_page` tool that returns a page by slug or URL path. */ readPage?: boolean; /** Expose a `search_docs` tool for keyword search over page content. */ searchDocs?: boolean; /** Expose a `get_navigation` tool for the docs tree. */ getNavigation?: boolean; /** Expose a `get_code_examples` tool for fenced code blocks and their metadata. */ getCodeExamples?: boolean; /** Expose a `get_config_schema` tool for docs.config option metadata. */ getConfigSchema?: boolean; } /** * Built-in MCP server configuration. * * When enabled, adapters can expose a Streamable HTTP endpoint for your docs * at `/mcp` and `/.well-known/mcp`, backed by the canonical `/api/docs/mcp` route. * The same config is also reused by the local `docs mcp` stdio command. */ interface DocsMcpConfig { /** Whether to enable the built-in MCP server. Defaults to `true` when this object is provided. */ enabled?: boolean; /** * Streamable HTTP route for the MCP endpoint. * Defaults to `/api/docs/mcp`; generated projects can also expose it publicly at `/mcp` and `/.well-known/mcp`. */ route?: string; /** * Human-readable MCP server name shown to clients. * Defaults to the string `nav.title` when available, otherwise `@farming-labs/docs`. */ name?: string; /** * Version string reported by the MCP server. * Defaults to `"0.0.0"` when not set. */ version?: string; /** Fine-grained tool toggles. Omitted tools stay enabled. */ tools?: DocsMcpToolsConfig; } type DocsSearchResultType = "page" | "heading" | "text"; interface DocsSearchSourcePage { title: string; url: string; content: string; description?: string; related?: ResolvedDocsRelatedLink[]; sourcePath?: string; lastModified?: string; lastmod?: string; rawContent?: string; agentContent?: string; agentRawContent?: string; agentFallbackContent?: string; agentFallbackRawContent?: string; type?: "page" | "api" | "code" | "changelog"; locale?: string; framework?: string; version?: string; tags?: string[]; } interface DocsSearchDocument { id: string; url: string; title: string; content: string; description?: string; section?: string; type: DocsSearchResultType; locale?: string; framework?: string; version?: string; tags?: string[]; } interface DocsSearchResult { id: string; url: string; content: string; description?: string; type: DocsSearchResultType; score?: number; section?: string; } interface DocsSearchQuery { query: string; limit?: number; locale?: string; pathname?: string; } interface DocsSearchAdapterContext { pages: DocsSearchSourcePage[]; documents: DocsSearchDocument[]; locale?: string; pathname?: string; siteTitle?: string; } interface DocsSearchAdapter { name: string; index?(context: DocsSearchAdapterContext): Promise; search(query: DocsSearchQuery, context: DocsSearchAdapterContext): Promise; } type DocsSearchAdapterFactory = (context: DocsSearchAdapterContext) => DocsSearchAdapter | Promise; interface DocsSearchChunkingConfig { /** * How docs content should be chunked before searching. * * - `"page"` keeps one search document per page * - `"section"` splits pages by headings and improves precision * * @default "section" */ strategy?: "page" | "section"; } interface DocsSearchEmbeddingsConfig { /** * Embeddings provider used for hybrid / semantic search. * The initial built-in provider is Ollama for local or self-hosted setups. */ provider: "ollama"; /** Embedding model id, e.g. `embeddinggemma`. */ model: string; /** Base URL of the embedding API. @default "http://127.0.0.1:11434" */ baseUrl?: string; } interface SimpleDocsSearchConfig { provider?: "simple"; enabled?: boolean; maxResults?: number; chunking?: DocsSearchChunkingConfig; } interface AlgoliaDocsSearchConfig { provider: "algolia"; enabled?: boolean; appId: string; indexName: string; searchApiKey: string; adminApiKey?: string; maxResults?: number; syncOnSearch?: boolean; chunking?: DocsSearchChunkingConfig; } interface TypesenseDocsSearchConfig { provider: "typesense"; enabled?: boolean; baseUrl: string; collection: string; apiKey: string; adminApiKey?: string; maxResults?: number; syncOnSearch?: boolean; queryBy?: string[]; mode?: "keyword" | "hybrid"; embeddings?: DocsSearchEmbeddingsConfig; chunking?: DocsSearchChunkingConfig; } interface McpDocsSearchConfig { provider: "mcp"; enabled?: boolean; /** * Streamable HTTP MCP endpoint. Relative paths like `/mcp` or `/.well-known/mcp` * are resolved against the current docs API request URL. */ endpoint: string; /** * Optional extra headers passed to the MCP endpoint on initialize/tool calls. */ headers?: Record; /** * MCP tool name used for search. Defaults to `search_docs`. */ toolName?: string; /** * Override the MCP protocol version header when needed. */ protocolVersion?: string; maxResults?: number; chunking?: DocsSearchChunkingConfig; } type DocsAskAIMcpConfig = Omit & { provider?: "mcp"; }; interface CustomDocsSearchConfig { provider: "custom"; enabled?: boolean; adapter: DocsSearchAdapter | DocsSearchAdapterFactory; maxResults?: number; chunking?: DocsSearchChunkingConfig; } type DocsSearchConfig = SimpleDocsSearchConfig | AlgoliaDocsSearchConfig | McpDocsSearchConfig | TypesenseDocsSearchConfig | CustomDocsSearchConfig; interface LastUpdatedConfig { /** * Whether to show the "Last updated" date. * @default true */ enabled?: boolean; /** * Where to render the "Last updated" date. * * - `"footer"` — next to the "Edit on GitHub" link at the bottom (default) * - `"below-title"` — below the page title/description, above the content * * @default "footer" */ position?: "footer" | "below-title"; } /** * Configuration for estimated page reading time. * * @example * ```ts * readingTime: { enabled: true, wordsPerMinute: 220 } * ``` */ interface ReadingTimeConfig { /** * Whether to show the estimated reading time. * @default true */ enabled?: boolean; /** * Words-per-minute rate used for the estimate. * @default 220 */ wordsPerMinute?: number; } /** * GitHub repository configuration for "Edit on GitHub" links * and source file references. * * @example * ```ts * // Simple repo (not a monorepo) * github: { * url: "https://github.com/Kinfe123/my-docs", * } * * // Monorepo — docs site lives in "website/" subdirectory * github: { * url: "https://github.com/farming-labs/docs", * directory: "website", * branch: "main", * } * ``` * * Or as a simple string (branch defaults to "main", no directory prefix): * ```ts * github: "https://github.com/Kinfe123/my-docs" * ``` */ interface GithubConfig { /** Repository URL (e.g. "https://github.com/farming-labs/docs") */ url: string; /** Branch name. @default "main" */ branch?: string; /** * Subdirectory inside the repo where the docs site lives. * Use this for monorepos where the docs app is not at the repo root. * * @example "website" → links point to `website/app/docs/…/page.mdx` */ directory?: string; } type DocsAskAIFeedbackValue = "like" | "dislike"; type DocsAskAIActionType = "copy" | DocsAskAIFeedbackValue; interface DocsAskAIFeedbackMessage { role: "user" | "assistant"; content: string; } interface DocsAskAIActionData { type: DocsAskAIActionType; value?: DocsAskAIFeedbackValue; question: string; answer: string; messageId?: string; messageIndex?: number; model?: string; surface?: string; url?: string; path?: string; messages?: DocsAskAIFeedbackMessage[]; copied?: boolean; } interface DocsAskAIFeedbackData { value: DocsAskAIFeedbackValue; question: string; answer: string; messageId?: string; messageIndex?: number; model?: string; surface?: string; url?: string; path?: string; messages?: DocsAskAIFeedbackMessage[]; } interface DocsAskAIFeedbackConfig { /** * Whether to show the copy, like, and dislike action row after each completed Ask AI answer. * @default true */ enabled?: boolean; /** Label for the positive rating button. @default "Helpful" */ positiveLabel?: string; /** Label for the negative rating button. @default "Not helpful" */ negativeLabel?: string; /** Called when a user rates an Ask AI response. */ onFeedback?: (data: DocsAskAIFeedbackData) => void | Promise; } /** * Configuration for "Ask AI" — a RAG-powered chat that lets users * ask questions about the documentation content. * * The AI handler searches relevant doc pages, builds context, and * streams a response from an LLM (OpenAI-compatible API). * * The API key is **never** stored in the config. It is read from the * `OPENAI_API_KEY` environment variable at runtime on the server. * * @example * ```ts * ai: { * enabled: true, * model: "gpt-4o-mini", * systemPrompt: "You are a helpful assistant for our developer docs.", * } * ``` */ interface AIConfig { /** * Whether to enable "Ask AI" functionality. * When enabled, the unified `/api/docs` route handler will accept * POST requests for AI chat. * @default false */ enabled?: boolean; /** * How the AI chat UI is presented. * * - `"search"` — AI tab integrated into the Cmd+K search dialog (default) * - `"floating"` — A floating chat widget (bubble button + slide-out panel) * * @default "search" * * @example * ```ts * // Floating chat bubble in the bottom-right corner * ai: { * enabled: true, * mode: "floating", * position: "bottom-right", * } * ``` */ mode?: "search" | "floating" | "sidebar-icon"; /** * Position of the floating chat button on screen. * Only used when `mode` is `"floating"`. * * - `"bottom-right"` — bottom-right corner (default) * - `"bottom-left"` — bottom-left corner * - `"bottom-center"` — bottom center * * @default "bottom-right" */ position?: "bottom-right" | "bottom-left" | "bottom-center"; /** * Visual style of the floating chat when opened. * Only used when `mode` is `"floating"`. * * - `"panel"` — A tall panel that slides up from the button position (default). * Stays anchored near the floating button. No backdrop overlay. * * - `"modal"` — A centered modal dialog with a backdrop overlay, * similar to the Cmd+K search dialog. Feels more focused and immersive. * * - `"popover"` — A compact popover near the button. Smaller than the * panel, suitable for quick questions without taking much screen space. * * - `"full-modal"` — A full-screen immersive overlay (inspired by better-auth). * Messages scroll in the center, input is pinned at the bottom. * Suggested questions appear as horizontal pills. Best for * documentation-heavy sites that want a premium AI experience. * * @default "panel" * * @example * ```ts * ai: { * enabled: true, * mode: "floating", * position: "bottom-right", * floatingStyle: "full-modal", * } * ``` */ floatingStyle?: "panel" | "modal" | "popover" | "full-modal"; /** * Custom trigger component for the floating chat button (Next.js only). * Only used when `mode` is `"floating"`. * * The click handler is attached automatically by the wrapper. * * - **Next.js**: Pass a JSX element via this config option. * - **SvelteKit**: Use the `aiTrigger` snippet on ``. * - **Nuxt / Vue**: Use the `ai-trigger` slot on ``. * - **Astro**: Use `` on ``. * * @example * ```tsx * // Next.js — pass JSX directly in config * triggerComponent: , * ``` * * ```svelte * * * {#snippet aiTrigger()}{/snippet} * {@render children()} * * ``` * * ```vue * * * * * * ``` * * ```astro * * * * * * ``` */ triggerComponent?: unknown; /** * The LLM model configuration. * * **Simple** — pass a plain string for a single model: * ```ts * model: "gpt-4o-mini" * ``` * * **Advanced** — pass an object with multiple selectable models and an * optional `provider` key that references a named provider in `providers`: * ```ts * model: { * models: [ * { id: "gpt-4o-mini", label: "GPT-4o mini (fast)", provider: "openai" }, * { id: "llama-3.3-70b-versatile", label: "Llama 3.3 70B", provider: "groq" }, * ], * defaultModel: "gpt-4o-mini", * } * ``` * * When an object is provided, a model selector dropdown appears in the * AI chat interface. * * @default "gpt-4o-mini" */ model?: string | { models: { id: string; label: string; provider?: string; }[]; defaultModel?: string; }; /** * Named provider configurations for multi-provider setups. * * Each key is a provider name referenced by `model.models[].provider`. * Each value contains a `baseUrl` and optional `apiKey`. * * @example * ```ts * providers: { * openai: { * baseUrl: "https://api.openai.com/v1", * apiKey: process.env.OPENAI_API_KEY, * }, * groq: { * baseUrl: "https://api.groq.com/openai/v1", * apiKey: process.env.GROQ_API_KEY, * }, * } * ``` */ providers?: Record; /** * Custom system prompt prepended to the AI conversation. * The documentation context is automatically appended after this prompt. * * @default "You are a helpful documentation assistant. Answer questions * based on the provided documentation context. Be concise and accurate. * If the answer is not in the context, say so honestly." */ systemPrompt?: string; /** * Default base URL for an OpenAI-compatible API endpoint. * Used when no per-model `provider` is configured. * @default "https://api.openai.com/v1" */ baseUrl?: string; /** * Default API key for the LLM provider. * Used when no per-model `provider` is configured. * Falls back to `process.env.OPENAI_API_KEY` if not set. * * @default process.env.OPENAI_API_KEY * * @example * ```ts * // Default — reads OPENAI_API_KEY automatically * ai: { enabled: true } * * // Custom provider key * ai: { * enabled: true, * apiKey: process.env.GROQ_API_KEY, * } * ``` */ apiKey?: string; /** * Maximum number of search results to include as context for the AI. * More results = more context but higher token usage. * @default 5 */ maxResults?: number; /** * Route Ask AI retrieval through the configured MCP `search_docs` tool. * * - `true` uses the MCP server this docs site already exposes at `mcp.route` * (default `/api/docs/mcp`) * - an object can point Ask AI at another Streamable HTTP MCP endpoint * * This only affects Ask AI retrieval. The normal docs search API still uses * the top-level `search` config. * * @default false * * @example * ```ts * ai: { * enabled: true, * useMcp: true, * } * ``` */ useMcp?: boolean | DocsAskAIMcpConfig; /** * Pre-filled suggested questions shown in the AI chat when empty. * When a user clicks one, it fills the input and submits automatically. * * @example * ```ts * ai: { * enabled: true, * suggestedQuestions: [ * "How do I install this?", * "What themes are available?", * "How do I create a custom component?", * ], * } * ``` */ suggestedQuestions?: string[]; /** * Display name for the AI assistant in the chat UI. * Shown as the message label, header title, and passed to the loading component. * * @default "AI" * * @example * ```ts * ai: { * enabled: true, * aiLabel: "DocsBot", * } * ``` */ aiLabel?: string; /** * Optional npm package-name override used in import examples. * Ask AI normally infers package names and exact imports from retrieved docs context. * * @example * ```ts * ai: { * enabled: true, * packageName: "@farming-labs/docs", * } * ``` */ packageName?: string; /** * The public URL of the documentation site. * The AI will use this for links instead of relative paths. * * @example * ```ts * ai: { * enabled: true, * docsUrl: "https://docs.farming-labs.dev", * } * ``` */ docsUrl?: string; /** * Loading indicator variant shown while the AI generates a response. * * - `"shimmer-dots"` — shimmer text + typing dots (default) * - `"circular"` — spinning ring * - `"dots"` — bouncing dots * - `"typing"` — typing dots * - `"wave"` — wave bars * - `"bars"` — thick wave bars * - `"pulse"` — pulsing ring * - `"pulse-dot"` — pulsing dot * - `"terminal"` — blinking terminal cursor * - `"text-blink"` — blinking text * - `"text-shimmer"` — shimmer text only * - `"loading-dots"` — "Thinking..." with animated dots * * @default "shimmer-dots" * * @example * ```ts * ai: { * enabled: true, * loader: "wave", * } * ``` */ loader?: "shimmer-dots" | "circular" | "dots" | "typing" | "wave" | "bars" | "pulse" | "pulse-dot" | "terminal" | "text-blink" | "text-shimmer" | "loading-dots"; /** * Custom loading indicator that overrides the built-in `loader` variant. * Receives `{ name }` (the `aiLabel` value) and returns a React element. * * Only works in Next.js. For other frameworks, use the `loader` option. * * @example * ```tsx * ai: { * enabled: true, * aiLabel: "Sage", * loadingComponent: ({ name }) => ( *
* 🤔 * {name} is thinking... *
* ), * } * ``` */ loadingComponent?: (props: { name: string; }) => unknown; /** * Copy, like, and dislike action row for generated Ask AI answers. * * Set to `false` to hide the row. Pass an object to customize rating labels * and receive legacy like/dislike callback payloads. * * @default true * * @example * ```ts * ai: { * enabled: true, * feedback: { * onFeedback(data) { * console.log(data.value, data.question, data.answer); * }, * }, * } * ``` */ feedback?: boolean | DocsAskAIFeedbackConfig; /** * Called when a user clicks an Ask AI response action. * * `data.type` is `"copy"`, `"like"`, or `"dislike"`. * * @example * ```ts * ai: { * enabled: true, * onActions(data) { * if (data.type === "copy") console.log("Copied", data.answer); * if (data.type === "like") console.log("Helpful", data.question); * if (data.type === "dislike") console.log("Not helpful", data.question); * }, * } * ``` */ onActions?: (data: DocsAskAIActionData) => void | Promise; } /** * A single item in the slug-based sidebar ordering. * * @example * ```ts * ordering: [ * { slug: "installation" }, * { slug: "cli" }, * { slug: "themes", children: [ * { slug: "default" }, * { slug: "darksharp" }, * { slug: "pixel-border" }, * { slug: "creating-themes" }, * ]}, * { slug: "reference" }, * ] * ``` */ interface OrderingItem { /** Folder name (not the full path, just the directory name at this level) */ slug: string; /** Ordering for child pages within this folder */ children?: OrderingItem[]; } /** * Data passed to the `onCopyClick` callback when the user clicks the copy button * on a code block in the docs. */ interface CodeBlockCopyData { /** Title of the code block (e.g. from the fenced code block meta string), if present */ title?: string; /** Raw code content (the text that was copied to the clipboard) */ content: string; /** Current page URL at the time of copy */ url: string; /** Language / syntax hint (e.g. "tsx", "bash"), if present */ language?: string; } /** Feedback value emitted by the built-in docs page feedback buttons. */ type DocsFeedbackValue = "positive" | "negative"; /** * Data passed to the `feedback.onFeedback` callback when the user submits * page feedback from the built-in docs feedback UI. */ interface DocsFeedbackData { /** Whether the user gave positive or negative feedback. */ value: DocsFeedbackValue; /** Optional free-form feedback left by the reader. */ comment?: string; /** Current page title, when available. */ title?: string; /** Current page description, when available. */ description?: string; /** Full current page URL at the time of feedback. */ url: string; /** Current URL pathname (without origin). */ pathname: string; /** Alias of `pathname` for analytics tools that prefer `path`. */ path: string; /** Docs entry root, e.g. `"docs"`. */ entry: string; /** Page slug relative to the docs entry, e.g. `"installation"` or `"guides/setup"`. */ slug: string; /** Active locale, when docs i18n is enabled. */ locale?: string; } /** * Page and transport context supplied alongside agent feedback payloads. * * The `payload` itself is customizable through `feedback.agent.schema`; this * context object keeps a small stable envelope for route-aware metadata. */ interface DocsAgentFeedbackContext { /** Docs page path, e.g. `"/docs/installation"`. */ page?: string; /** Full docs URL, when the caller has one available. */ url?: string; /** Docs slug relative to the entry root, e.g. `"installation"`. */ slug?: string; /** Active locale when docs i18n is enabled. */ locale?: string; /** Arbitrary source label such as `"md-route"`, `"mcp"`, or `"api"`. */ source?: string; } /** * Data passed to `feedback.agent.onFeedback`. * * The request body always follows the stable `{ context?, payload }` envelope * while `payload` stays schema-driven so projects can add or remove agent * fields without changing the callback contract. */ interface DocsAgentFeedbackData { /** Optional docs/page context associated with the agent feedback. */ context?: DocsAgentFeedbackContext; /** Arbitrary payload validated by the configured agent feedback schema. */ payload: Record; } /** * Agent feedback endpoint configuration served through the shared `/api/docs` * route wrapper. */ interface AgentFeedbackConfig { /** Enable the agent feedback endpoints. Defaults to `true`; set to `false` to opt out. */ enabled?: boolean; /** * Public HTTP route for posting agent feedback. * @default "/api/docs/agent/feedback" */ route?: string; /** * Public HTTP route for the machine-readable schema describing the agent * feedback payload. * * Defaults to `${route}/schema`. */ schemaRoute?: string; /** * JSON Schema object describing the `payload` field of the request body. * * The shared docs API wraps this under a stable top-level envelope: * `{ context?: DocsAgentFeedbackContext, payload: }`. */ schema?: Record; /** * Async callback fired when the agent feedback endpoint receives a valid * `{ context?, payload }` body. */ onFeedback?: (data: DocsAgentFeedbackData) => void | Promise; } /** * Built-in page feedback configuration. * * When enabled, docs pages render a small feedback prompt at the end of the * content. Clicking a button emits a callback/event with the current page * metadata and the selected sentiment. */ interface FeedbackConfig { /** Show the feedback UI. Defaults to `true` when this object is provided. */ enabled?: boolean; /** Prompt shown above the feedback buttons. @default "How is this guide?" */ question?: string; /** Placeholder shown in the optional free-form feedback field. @default "Leave your feedback..." */ placeholder?: string; /** Label for the positive button. @default "Good" */ positiveLabel?: string; /** Label for the negative button. @default "Bad" */ negativeLabel?: string; /** Label for the submit button. @default "Submit" */ submitLabel?: string; /** * Callback fired when the user submits the feedback form. * * For client-only frameworks this runs directly in the browser. In * environments where the config cannot be serialized to the client, the same * payload is also emitted through `window.__fdOnFeedback__` and the * `fd:feedback` custom event. */ onFeedback?: (data: DocsFeedbackData) => void | Promise; /** * Machine-oriented feedback endpoints exposed through the shared `/api/docs` * route. The shared docs API exposes the default no-op schema/submit routes * unless this is set to `false`. * * This does not enable the human page feedback UI by itself. To show the * built-in footer prompt, keep using `feedback: true` or `feedback.enabled`. */ agent?: boolean | AgentFeedbackConfig; } interface DocsI18nConfig { /** Supported locale identifiers (e.g. ["en", "fr"]). */ locales: string[]; /** Default locale when `?lang=` is missing or invalid. Defaults to first locale. */ defaultLocale?: string; } interface ChangelogFrontmatter { /** Entry title shown in the changelog feed and detail page. */ title?: string; /** Short summary shown in the feed and page metadata. */ description?: string; /** Optional cover image path or URL for future custom changelog layouts. */ image?: string; /** Optional author name(s) displayed in entry meta. */ authors?: string | string[]; /** Optional version badge (for example `v0.1.0`). */ version?: string; /** Optional tags shown as compact badges. */ tags?: string[]; /** Keep important entries pinned to the top of the listing. */ pinned?: boolean; /** Hide the entry from generated routes and search indexes. */ draft?: boolean; } interface ChangelogConfig { /** * Whether to enable generated changelog pages. * @default false */ enabled?: boolean; /** * URL path where the changelog listing lives inside the docs layout. * Example: `"changelogs"` → `/docs/changelogs` when `entry` is `"docs"` * @default "changelog" */ path?: string; /** * Changelog source directory inside the docs content root. * * With the default docs content tree, this becomes: * `app/docs/changelog/2026-03-04/page.mdx` * * Relative values are resolved from the docs content root. Absolute values * are used as-is. * * @default "changelog" */ contentDir?: string; /** * Listing page title. * @default "Changelog" */ title?: string; /** * Listing page description shown in the changelog header and metadata. */ description?: string; /** * Show the built-in changelog search field. * @default true */ search?: boolean; /** * Custom React element rendered in the changelog rail. * * This stays `unknown` in the framework-agnostic core so adapters can accept * JSX without adding a React dependency here. */ actionsComponent?: unknown; } type ApiReferenceRenderer = "fumadocs" | "scalar"; interface ApiReferenceConfig { /** * Whether to enable generated API reference pages. * The initial implementation is wired for Next.js route handlers. * @default false */ enabled?: boolean; /** * URL path where the generated API reference lives. * Example: `"api-reference"` → `/api-reference` * @default "api-reference" */ path?: string; /** * URL to a remote OpenAPI JSON document. * * When provided, the API reference is generated from this hosted spec instead * of scanning local framework route files. * * Supports: * - absolute URLs like `https://example.com/openapi.json` * - request-relative URLs like `/api/openapi.json` in Next.js * * @example * ```ts * apiReference: { * enabled: true, * specUrl: "https://petstore3.swagger.io/api/v3/openapi.json", * } * ``` */ specUrl?: string; /** * Which renderer to use for the API reference UI. * * - `"fumadocs"` uses `fumadocs-openapi` * - `"scalar"` uses the existing Scalar renderer * * Defaults are framework-aware: * - Next.js: `"fumadocs"` * - TanStack Start / SvelteKit / Astro / Nuxt: `"scalar"` */ renderer?: ApiReferenceRenderer; /** * Filesystem route root to scan for API handlers. * * For Next.js this defaults to the App Router convention: * `app/api` or `src/app/api`. * * You can override it with a project-relative path like `"app/v1"` or * `"src/app/internal-api"`. If you pass a bare segment like `"api"` or * `"v1"`, it will be resolved inside the detected app directory. */ routeRoot?: string; /** * Route entries to exclude from the generated API reference. * * Accepts either URL-style paths like `"/api/hello"` or route-root-relative * entries like `"hello"` / `"hello/route.ts"`. */ exclude?: string[]; } interface DocsAgentCompactConfig { /** * Direct API key for the Token Company compression API. * * Prefer `apiKeyEnv` for checked-in config files so secrets stay in the environment. */ apiKey?: string; /** * Environment variable name that stores the Token Company API key. */ apiKeyEnv?: string; /** * Base URL for the Token Company API. */ baseUrl?: string; /** * Compression model name. * @default "bear-1.2" */ model?: string; /** * Compression aggressiveness passed to the API. * Must be between `0` and `1`. * @default 0.3 */ aggressiveness?: number; /** * Upper token target for compressed output. */ maxOutputTokens?: number; /** * Lower token target for compressed output. */ minOutputTokens?: number; /** * Preserve JSON objects during compression when supported by the provider. */ protectJson?: boolean; } interface DocsAgentConfig { /** * Defaults for `docs agent compact`. */ compact?: DocsAgentCompactConfig; } type DocsReviewSeverity = "off" | "suggestion" | "warn" | "error"; type DocsReviewCiMode = "off" | "warn" | "block"; interface DocsReviewRulesConfig { /** Check internal markdown/docs links. */ brokenLinks?: DocsReviewSeverity; /** Check required page frontmatter such as title and description. */ frontmatter?: DocsReviewSeverity; /** Check duplicate docs slugs in the resolved docs tree. */ duplicateSlugs?: DocsReviewSeverity; /** Check whether changed markdown/MDX files can be parsed. */ invalidMdx?: DocsReviewSeverity; /** Check docs.config examples against known config options when possible. */ configExamples?: DocsReviewSeverity; /** Check code fences for useful metadata such as title and framework. */ codeFenceMetadata?: DocsReviewSeverity; /** Check runnable command/code fences for package manager context. */ runnableMetadata?: DocsReviewSeverity; /** Suggest machine-facing context for implementation-heavy pages. */ agentContext?: DocsReviewSeverity; } interface DocsReviewScoreConfig { /** * Minimum healthy score. * CI reports the threshold in warn mode and blocks below it only when `ci.mode` is `"block"`. * * @default 80 */ threshold?: number; /** * Point deductions by finding severity. * * @default { error: 20, warn: 8, suggestion: 2 } */ weights?: Partial>; } interface DocsReviewCiConfig { /** * Enable Docs Review CI workflow generation. * * @default true */ enabled?: boolean; /** * GitHub Actions job/check name for the generated workflow. * * @default "docs-review" */ name?: string; /** * How CI should treat unhealthy review results. * * - `"off"`: do not create/report CI output * - `"warn"`: report annotations but pass CI * - `"block"`: fail CI when errors exist or the score is below threshold * * @default "warn" */ mode?: DocsReviewCiMode; /** * Emit GitHub workflow command annotations in CI. * * @default true */ annotations?: boolean; /** * Reserved for GitHub PR comments from the official action/bot. * * @default true */ comment?: boolean; } interface DocsReviewConfig { /** * Enable Docs Review. * * Omitted review config is treated as enabled so docs sites get PR review CI by default. * Set `review: false` to opt out. * * @default true */ enabled?: boolean; /** Score threshold and severity weights. */ score?: DocsReviewScoreConfig; /** GitHub Actions behavior. */ ci?: boolean | DocsReviewCiConfig; /** Optional rule severity overrides. */ rules?: DocsReviewRulesConfig; } type DocsCodeBlocksPlannerProvider = "metadata" | "openai" | "openai-compatible" | "cloud"; type DocsCodeBlocksRunnerProvider = "local" | "vercel-sandbox" | "e2b" | "daytona" | "cloud"; type DocsCodeBlocksValidationMode = "plan" | "report"; type DocsCodeBlocksValidationPolicy = "skip" | "warn" | "error"; interface DocsCodeBlocksPlannerConfig { /** * Planner used to turn code fence metadata into an execution plan. * * - `"metadata"` reads the fence language and metadata locally. * - `"openai"` calls OpenAI's chat completions API. * - `"openai-compatible"` calls an OpenAI-compatible chat completions endpoint. * - `"cloud"` is reserved for the hosted Farming Labs planner. * * @default "metadata" */ provider?: DocsCodeBlocksPlannerProvider; /** Model name for LLM-backed planners. */ model?: string; /** OpenAI-compatible base URL. Defaults to `https://api.openai.com/v1` for `provider: "openai"`. */ baseUrl?: string; /** Environment variable containing the OpenAI-compatible base URL. */ baseUrlEnv?: string; /** API key value. Prefer `apiKeyEnv` so secrets stay out of docs.config. */ apiKey?: string; /** Environment variable containing the planner API key. */ apiKeyEnv?: string; } interface DocsCodeBlocksRunnerConfig { /** * Runner used to execute planned code blocks. * * @default "local" */ provider?: DocsCodeBlocksRunnerProvider; /** Environment variable containing the sandbox provider token. */ tokenEnv?: string; /** Advanced override for the Vercel project id env var used by `provider: "vercel-sandbox"`. */ projectIdEnv?: string; /** Advanced override for the Vercel team/org id env var used by `provider: "vercel-sandbox"`. */ teamIdEnv?: string; /** * Path to a Vercel project metadata file. When enabled, the runner reads * `projectId` and `orgId` from `.vercel/project.json`. If those are not * available, the runner can auto-discover an accessible project from * `VERCEL_TOKEN`. * * @default ".vercel/project.json" */ projectJson?: string | false; /** Vercel Sandbox runtime. */ runtime?: "node24" | "node22" | "python3.13"; /** Daytona API URL env var used by `provider: "daytona"`. */ apiUrlEnv?: string; /** Daytona target/region env var used by `provider: "daytona"`. */ targetEnv?: string; /** Per-command timeout in milliseconds. */ timeoutMs?: number; } interface DocsCodeBlocksValidateConfig { /** * Enable code block validation. * * @default true when `codeBlocks.validate` is an object or `true` */ enabled?: boolean; /** Planner config. Use `"metadata"` for local deterministic planning. */ planner?: DocsCodeBlocksPlannerProvider | DocsCodeBlocksPlannerConfig; /** Runner config. Use `"vercel-sandbox"` for isolated runtime checks. */ runner?: DocsCodeBlocksRunnerProvider | DocsCodeBlocksRunnerConfig; /** * Env files loaded for validation. These are read locally and never committed. * * @default [".env.local", ".env.test", ".env"] */ envFile?: string | string[]; /** * Runtime env mapping. * * The key is the env var used by the docs code block. The value is the local * env var to read from. For example, `{ OPENAI_API_KEY: "OPENAI_TEST_API_KEY" }` * injects `OPENAI_API_KEY` into the runner from `OPENAI_TEST_API_KEY`. */ env?: Record; /** * Behavior when a runnable block declares an env var that cannot be resolved. * * @default "skip" */ missingEnv?: DocsCodeBlocksValidationPolicy; /** * Behavior when a language cannot be executed by the selected runner. * * @default "skip" */ unsupportedLanguage?: DocsCodeBlocksValidationPolicy; /** * Default command mode. * * - `"plan"` builds execution plans without running them. * - `"report"` runs executable plans and reports pass/skip/fail. * * @default "report" */ mode?: DocsCodeBlocksValidationMode; } interface DocsCodeBlocksConfig { /** * Validate fenced code blocks from MD/MDX docs. * * @example * ```ts * codeBlocks: { * validate: { * planner: { * provider: "openai", * model: "gpt-4.1-mini", * apiKeyEnv: "OPENAI_API_KEY", * }, * runner: { * provider: "vercel-sandbox", * tokenEnv: "VERCEL_TOKEN", * }, * env: { * OPENAI_API_KEY: "OPENAI_TEST_API_KEY", * }, * }, * } * ``` */ validate?: boolean | DocsCodeBlocksValidateConfig; } interface DocsConfig { /** Entry folder for docs (e.g. "docs" → /docs) */ entry: string; /** * Public route prefix for docs pages. Defaults to the `entry` path. * Set to "" or "/" to serve docs from the site root while keeping the * source files and generated app route under `entry`. */ docsPath?: string; /** Path to the content directory. Defaults to `entry` value. */ contentDir?: string; /** * Internationalization (i18n) configuration. * When set, docs content is expected under `${contentDir}/{locale}` and * the active locale is selected by `?lang=` in the URL. */ i18n?: DocsI18nConfig; /** * Set to `true` when building for full static export (e.g. Cloudflare Pages). * When using `output: 'export'` in Next.js, the `/api/docs` route is not generated. * Set `ai.enabled: false` and optionally rely on client-side search or leave search disabled. */ staticExport?: boolean; /** Theme configuration - single source of truth for UI */ theme?: DocsTheme; /** * Built-in analytics event stream for docs interactions. * * - `false` -> analytics disabled * - omitted -> analytics disabled unless Docs Cloud provides project identity * - `true` -> log product/usage events to the console * - `{ onEvent(event) { ... } }` -> send events to your analytics sink * * Raw queries, AI questions, feedback comments, and copied content are not * included unless `includeInputs: true` is set. */ analytics?: boolean | DocsAnalyticsConfig; /** * Docs Cloud integration settings. * * Use this to configure the API key env var and cloud deploy defaults once * in `docs.config.ts`; cloud CLI commands mirror the serializable subset into * `docs.json` automatically. * * @example * ```ts * cloud: { * apiKey: { env: "DOCS_CLOUD_API_KEY" }, * deploy: { enabled: true }, * publish: { mode: "draft-pr", baseBranch: "main" }, * } * ``` */ cloud?: DocsCloudConfig; /** * Built-in observability stream for agent traces, timing, errors, and runtime debugging. * This is separate from `analytics`; it emits span-like Ask AI and MCP trace events. * * ```ts * observability: { * console: "debug", * onEvent(event) { * console.info(event.type, event.traceId, event.durationMs) * }, * } * ``` */ observability?: boolean | DocsObservabilityConfig; /** * GitHub repository URL or config. Enables "Edit on GitHub" links * on each docs page footer, pointing to the source `.mdx` file. * * @example * ```ts * // Simple — branch defaults to "main" * github: "https://github.com/Kinfe123/my-docs" * * // Monorepo — docs site lives in "website/" subdirectory * github: { * url: "https://github.com/farming-labs/docs", * directory: "website", * } * * // Custom branch * github: { * url: "https://github.com/Kinfe123/my-docs", * branch: "develop", * } * ``` */ github?: string | GithubConfig; /** * Sidebar navigation header. * Customise the title shown at the top of the sidebar. */ nav?: DocsNav; /** * Theme toggle (light/dark mode switcher) in the sidebar. * * - `true` or `undefined` → toggle is shown (default) * - `false` → toggle is hidden, defaults to system theme * - `{ enabled: false, default: "dark" }` → toggle hidden, force dark * * @example * ```ts * // Hide toggle, force dark mode * themeToggle: { enabled: false, default: "dark" } * * // Show toggle with system option * themeToggle: { mode: "light-dark-system" } * ``` */ themeToggle?: boolean | ThemeToggleConfig; /** * Breadcrumb navigation above page content. * * - `true` or `undefined` → breadcrumb is shown (default) * - `false` → breadcrumb is hidden * - `{ enabled: false }` → breadcrumb is hidden * - `{ component: MyBreadcrumb }` → custom breadcrumb component */ breadcrumb?: boolean | BreadcrumbConfig; /** * Sidebar customisation. * * - `true` or `undefined` → default sidebar * - `false` → sidebar is hidden * - `{ component: MySidebar }` → custom sidebar component * - `{ footer: , banner: }` → add footer/banner */ sidebar?: boolean | SidebarConfig; /** * Custom MDX component overrides. * * Pass your own React components to replace defaults (e.g. Callout, CodeBlock). * Components must match the expected props interface. * * @example * ```ts * import { MyCallout } from "./components/my-callout"; * * export default defineDocs({ * entry: "docs", * theme: fumadocs(), * components: { * Callout: MyCallout, * }, * }); * ``` */ components?: Record; /** * Callback fired when the user clicks the copy button on a code block. * Called in addition to the default copy-to-clipboard behavior. * Use it for analytics, logging, or custom behavior. * * @example * ```ts * export default defineDocs({ * entry: "docs", * theme: fumadocs(), * onCopyClick(data) { * console.log("Code copied", data.title, data.language, data.url); * analytics.track("code_block_copy", { title: data.title, url: data.url }); * }, * }); * ``` */ onCopyClick?: (data: CodeBlockCopyData) => void; /** * Code block intelligence for MD/MDX fences, including validation planning * and optional sandboxed execution. */ codeBlocks?: DocsCodeBlocksConfig; /** * Built-in page feedback prompt shown at the end of a docs page. * * - `false` or `undefined` → hidden (default) * - `true` → shown with default labels * - `{ enabled: true, onFeedback(data) { ... } }` → shown with callback * * @example * ```ts * import type { DocsFeedbackData } from "@farming-labs/docs"; * * export default defineDocs({ * entry: "docs", * feedback: { * enabled: true, * onFeedback(data: DocsFeedbackData) { * console.log("Docs feedback", data.value, data.slug, data.url); * }, * }, * }); * ``` */ feedback?: boolean | FeedbackConfig; /** * Built-in MCP server for agent/assistant access to your docs content. * * - omitted → enable the default MCP surface at `/mcp` and `/.well-known/mcp`, backed by `/api/docs/mcp` * - `true` → enable the default MCP surface at `/mcp` and `/.well-known/mcp`, backed by `/api/docs/mcp` * - `{ route: "/api/docs/mcp" }` → enable with explicit route/config * - `false` or `{ enabled: false }` → disable MCP explicitly */ mcp?: boolean | DocsMcpConfig; /** * Shared icon registry for sidebar items and built-in MDX components. * * Map string labels to React elements. Reference them in page frontmatter * with `icon: "label"` and the matching icon renders in the sidebar. * Built-in components such as `Prompt` can also reference these keys for * their card and action icons. * * @example * ```tsx * import { Book, Terminal, Rocket } from "lucide-react"; * * export default defineDocs({ * entry: "docs", * theme: fumadocs(), * icons: { * book: , * terminal: , * rocket: , * }, * }); * ``` * * Then in `page.mdx` frontmatter: * ```yaml * --- * title: "CLI Reference" * icon: "terminal" * --- * ``` */ icons?: Record; /** * Page action buttons shown above the content area. * Includes "Copy Markdown" and "Open in …" (LLM dropdown). * * @example * ```ts * pageActions: { * copyMarkdown: { enabled: true }, * openDocs: { * enabled: true, * target: "markdown", * providers: [ * "chatgpt", * "claude", * "cursor", * ], * }, * } * ``` */ pageActions?: PageActionsConfig; /** * Built-in docs search configuration. * * - `true` or omitted → use the built-in simple search * - `{ provider: "typesense", ... }` → use Typesense * - `{ provider: "algolia", ... }` → use Algolia * - `{ provider: "custom", adapter }` → use a custom adapter * - `false` → disable docs search */ search?: boolean | DocsSearchConfig; /** * Configuration for the "Last updated" date display. * * - `true` or `undefined` → shown in footer next to "Edit on GitHub" (default) * - `false` → hidden * - `{ position: "below-title" }` → shown below the page title * - `{ position: "footer" }` → shown next to "Edit on GitHub" (default) * * @example * ```ts * // Show below title (Mintlify style) * lastUpdated: { position: "below-title" } * * // Hide entirely * lastUpdated: false * ``` */ lastUpdated?: boolean | LastUpdatedConfig; /** * Estimated reading time shown at the top of docs pages. * * - `undefined` → disabled by default * - `true` or `{ enabled: true }` → show a computed "{n} min read" label * - `false` → hide it entirely * * @example * ```ts * readingTime: { enabled: true, wordsPerMinute: 220 } * ``` */ readingTime?: boolean | ReadingTimeConfig; /** * AI-powered "Ask AI" chat for documentation. * * When enabled, the unified API route handler (`/api/docs`) accepts * POST requests for AI chat. The handler uses RAG (Retrieval-Augmented * Generation) — it searches relevant docs, builds context, and streams * a response from an LLM. * * The API key defaults to `process.env.OPENAI_API_KEY`. For other providers, * pass the key via `apiKey: process.env.YOUR_KEY`. * * @example * ```ts * // Enable with defaults (gpt-4o-mini, OPENAI_API_KEY) * ai: { enabled: true } * * // Custom model + system prompt * ai: { * enabled: true, * model: "gpt-4o", * systemPrompt: "You are an expert on our SDK. Be concise.", * } * * // Use a different provider (e.g. Groq) * ai: { * enabled: true, * baseUrl: "https://api.groq.com/openai/v1", * apiKey: process.env.GROQ_API_KEY, * model: "llama-3.1-70b-versatile", * } * ``` */ ai?: AIConfig; /** * Sidebar ordering strategy. * * - `"alphabetical"` — sort pages alphabetically by folder name (default) * - `"numeric"` — sort by frontmatter `order` field (lower first, unset pages last) * - `OrderingItem[]` — explicit slug-based ordering with nested children * * @default "alphabetical" * * @example * ```ts * // Alphabetical (default) * ordering: "alphabetical", * * // Use frontmatter `order: 1`, `order: 2`, etc. * ordering: "numeric", * * // Explicit slug-based ordering * ordering: [ * { slug: "installation" }, * { slug: "cli" }, * { slug: "configuration" }, * { slug: "themes", children: [ * { slug: "default" }, * { slug: "darksharp" }, * { slug: "pixel-border" }, * { slug: "creating-themes" }, * ]}, * { slug: "customization" }, * { slug: "reference" }, * ] * ``` */ ordering?: "alphabetical" | "numeric" | OrderingItem[]; /** * Auto-generate `/llms.txt` and `/llms-full.txt` routes for LLM-friendly * documentation. Native static files at those routes take precedence, so * `public/llms.txt` or SvelteKit `static/llms.txt` can override the * generated output without extra config. * * @example * ```ts * llmsTxt: { * baseUrl: "https://docs.example.com", * } * ``` * * @see https://llmstxt.org */ llmsTxt?: boolean | LlmsTxtConfig; /** * Generated XML and Markdown sitemaps for crawlers, agents, and static export. * * Enabled by default. Set `sitemap: false` to opt out. * * @example * ```ts * sitemap: true * * sitemap: { * routePrefix: "/docs", * baseUrl: "https://docs.example.com", * } * ``` */ sitemap?: boolean | DocsSitemapConfig; /** * Generated robots.txt policy for docs and agent-readable routes. * * Served by the runtime by default when no static `robots.txt` exists. Use * `docs robots generate` for static export or when you want to append to an * existing file. * * @example * ```ts * robots: { * baseUrl: "https://docs.example.com", * ai: "allow", * } * ``` */ robots?: boolean | DocsRobotsConfig; /** * Generated changelog pages backed by date-folder MDX entries inside the docs * content tree. * * Entry structure: * `docs/changelog/2026-03-04/page.mdx` * * With `entry: "docs"` and `path: "changelogs"`, the public pages render * under the docs layout at `/docs/changelogs`. * * Required frontmatter: * - `title` * - `description` * * @example * ```ts * changelog: { * enabled: true, * path: "changelogs", * contentDir: "changelog", * title: "Changelogs", * description: "Latest product updates and release notes.", * } * ``` */ changelog?: boolean | ChangelogConfig; /** * Generated API reference pages from framework route conventions or a hosted * OpenAPI JSON document. * * @example * ```ts * apiReference: { * enabled: true, * path: "api-reference", * routeRoot: "api", * } * ``` * * @example * ```ts * apiReference: { * enabled: true, * specUrl: "https://example.com/openapi.json", * } * ``` */ apiReference?: boolean | ApiReferenceConfig; /** * Agent-oriented configuration, including defaults for `docs agent compact`. */ agent?: DocsAgentConfig; /** * Docs Review checks changed docs files in CI/local runs and can auto-create * a GitHub Actions workflow during dev/build startup. * * - omitted or `true` → enabled with warn-mode CI and an 80 score threshold * - `false` → disable review and workflow generation * * @example * ```ts * review: { * ci: { mode: "block" }, * score: { threshold: 90 }, * } * ``` */ review?: boolean | DocsReviewConfig; /** SEO metadata - separate from theme */ metadata?: DocsMetadata; /** Open Graph image handling */ og?: OGConfig; } //#endregion export { DocsObservabilityEventInput as $, SimpleDocsSearchConfig as $t, DocsCloudApiKeyConfig as A, McpDocsSearchConfig as At, DocsCodeBlocksValidateConfig as B, PageFrontmatter as Bt, DocsAskAIActionData as C, FontStyle as Ct, DocsAskAIFeedbackMessage as D, LlmsTxtMaxCharsConfig as Dt, DocsAskAIFeedbackData as E, LlmsTxtConfig as Et, DocsCodeBlocksConfig as F, OpenDocsProviderId as Ft, DocsFeedbackValue as G, ResolvedDocsRelatedLink as Gt, DocsCodeBlocksValidationPolicy as H, PageSidebarFrontmatter as Ht, DocsCodeBlocksPlannerConfig as I, OpenDocsTarget as It, DocsMcpToolsConfig as J, SidebarFolderIndexBehavior as Jt, DocsI18nConfig as K, SidebarComponentProps as Kt, DocsCodeBlocksPlannerProvider as L, OpenGraphImage as Lt, DocsCloudFeatureConfig as M, OpenDocsConfig as Mt, DocsCloudPreviewConfig as N, OpenDocsProvider as Nt, DocsAskAIFeedbackValue as O, LlmsTxtMaxCharsMode as Ot, DocsCloudPublishConfig as P, OpenDocsProviderConfig as Pt, DocsObservabilityEvent as Q, SidebarTree as Qt, DocsCodeBlocksRunnerConfig as R, OrderingItem as Rt, DocsAnalyticsSource as S, FeedbackConfig as St, DocsAskAIFeedbackConfig as T, LastUpdatedConfig as Tt, DocsConfig as U, PageTwitter as Ut, DocsCodeBlocksValidationMode as V, PageOpenGraph as Vt, DocsFeedbackData as W, ReadingTimeConfig as Wt, DocsNav as X, SidebarNode as Xt, DocsMetadata as Y, SidebarFolderNode as Yt, DocsObservabilityConfig as Z, SidebarPageNode as Zt, DocsAnalyticsConfig as _, DocsSearchResult as _t, ApiReferenceRenderer as a, DocsReviewScoreConfig as at, DocsAnalyticsEventType as b, DocsSitemapConfig as bt, ChangelogFrontmatter as c, DocsRobotsRule as ct, CustomDocsSearchConfig as d, DocsSearchAdapterFactory as dt, ThemeToggleConfig as en, DocsRelatedItem as et, DocsAgentFeedbackContext as f, DocsSearchChunkingConfig as ft, DocsAgentTraceStatus as g, DocsSearchQuery as gt, DocsAgentTraceEventType as h, DocsSearchEmbeddingsConfig as ht, ApiReferenceConfig as i, DocsReviewRulesConfig as it, DocsCloudConfig as j, OGConfig as jt, DocsAskAIMcpConfig as k, LlmsTxtSectionConfig as kt, CodeBlockCopyData as l, DocsSearchAdapter as lt, DocsAgentTraceEventInput as m, DocsSearchDocument as mt, AgentFeedbackConfig as n, TypographyConfig as nn, DocsReviewCiMode as nt, BreadcrumbConfig as o, DocsReviewSeverity as ot, DocsAgentFeedbackData as p, DocsSearchConfig as pt, DocsMcpConfig as q, SidebarConfig as qt, AlgoliaDocsSearchConfig as r, UIConfig as rn, DocsReviewConfig as rt, ChangelogConfig as s, DocsRobotsConfig as st, AIConfig as t, TypesenseDocsSearchConfig as tn, DocsReviewCiConfig as tt, CopyMarkdownConfig as u, DocsSearchAdapterContext as ut, DocsAnalyticsEvent as v, DocsSearchResultType as vt, DocsAskAIActionType as w, GithubConfig as wt, DocsAnalyticsInput as x, DocsTheme as xt, DocsAnalyticsEventInput as y, DocsSearchSourcePage as yt, DocsCodeBlocksRunnerProvider as z, PageActionsConfig as zt };