@farming-labs/docs 0.2.62 → 0.2.63

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.
Files changed (58) hide show
  1. package/dist/agent-CQTH7NFu.mjs +624 -0
  2. package/dist/agent-DKKptIgy.mjs +4365 -0
  3. package/dist/agent-evals-B7MIxuEX.mjs +2144 -0
  4. package/dist/agent-export-CBgWgPvH.mjs +910 -0
  5. package/dist/agent-scope-C_U--OZ7.mjs +283 -0
  6. package/dist/agent-skills-bundle.d.mts +13 -0
  7. package/dist/agent-skills-bundle.mjs +12 -0
  8. package/dist/agent-skills-server-CPja6Syt.d.mts +14 -0
  9. package/dist/agent-skills-server-DraIb6FV.mjs +415 -0
  10. package/dist/agent-skills-vite.d.mts +31 -0
  11. package/dist/agent-skills-vite.mjs +70 -0
  12. package/dist/agents-XWZBub6f.mjs +221 -0
  13. package/dist/analytics-Bx44lg6d.mjs +177 -0
  14. package/dist/cli/index.d.mts +15 -0
  15. package/dist/cli/index.mjs +452 -0
  16. package/dist/client/react.d.mts +45 -0
  17. package/dist/client/react.mjs +223 -0
  18. package/dist/cloud-analytics-CSyFE6SS.mjs +132 -0
  19. package/dist/cloud-ask-ai-sbpjOR2K.mjs +382 -0
  20. package/dist/cloud-ask-ai-zpwkdwnF.d.mts +23 -0
  21. package/dist/cloud-pdNC-tyj.mjs +1615 -0
  22. package/dist/code-blocks-DnNVNK2M.mjs +871 -0
  23. package/dist/codeblocks-CFuurVIH.mjs +250 -0
  24. package/dist/config-Wcdj-D0a.mjs +369 -0
  25. package/dist/dev-Cmy6DtdF.mjs +1333 -0
  26. package/dist/docs-cloud-server.d.mts +70 -0
  27. package/dist/docs-cloud-server.mjs +310 -0
  28. package/dist/doctor-CJqtzKZT.mjs +2036 -0
  29. package/dist/downgrade-w7e6Se0L.mjs +184 -0
  30. package/dist/errors-DbOhkE1h.mjs +20 -0
  31. package/dist/golden-evaluations-Dsvh0etV.mjs +1503 -0
  32. package/dist/i18n-CCaFUnAN.mjs +40 -0
  33. package/dist/index.d.mts +1150 -0
  34. package/dist/index.mjs +10 -0
  35. package/dist/init-CQY0Woe3.mjs +1264 -0
  36. package/dist/mcp-B9dcsivk.mjs +156 -0
  37. package/dist/mcp.d.mts +298 -0
  38. package/dist/mcp.mjs +4430 -0
  39. package/dist/metadata-DWExHQnx.mjs +237 -0
  40. package/dist/package-version-n5AFur8a.mjs +128 -0
  41. package/dist/reading-time-CYZ5VvKU.mjs +742 -0
  42. package/dist/review-Fndl5brR.mjs +673 -0
  43. package/dist/robots-BIpC4j4P.mjs +201 -0
  44. package/dist/robots-CUTahhoY.mjs +179 -0
  45. package/dist/search-B6V6qtiI.mjs +1826 -0
  46. package/dist/search-CaSyi6H6.d.mts +279 -0
  47. package/dist/search-DSjCeOk7.mjs +104 -0
  48. package/dist/server.d.mts +343 -0
  49. package/dist/server.mjs +14 -0
  50. package/dist/sitemap-Cykpe3Tz.mjs +249 -0
  51. package/dist/sitemap-server-C_6Wes83.mjs +1137 -0
  52. package/dist/standards-discovery-C4HUqMd2.d.mts +227 -0
  53. package/dist/standards-discovery-jkykaXq1.mjs +519 -0
  54. package/dist/templates-Bq_P7ctv.mjs +2465 -0
  55. package/dist/types-lMBIdZg0.d.mts +3315 -0
  56. package/dist/upgrade-oz-GChgt.mjs +56 -0
  57. package/dist/utils-DpiIioYb.mjs +225 -0
  58. package/package.json +1 -1
@@ -0,0 +1,3315 @@
1
+ //#region src/types.d.ts
2
+ /**
3
+ * Theme / UI configuration types for the docs framework.
4
+ * Inspired by Fumadocs: https://github.com/fuma-nama/fumadocs
5
+ */
6
+ /**
7
+ * Fine-grained UI configuration for docs themes.
8
+ *
9
+ * Theme authors define defaults for these values in their `createTheme` call.
10
+ * End users can override any value when calling the theme factory.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const myTheme = createTheme({
15
+ * name: "my-theme",
16
+ * ui: {
17
+ * colors: { primary: "#6366f1", background: "#0a0a0a" },
18
+ * radius: "0px",
19
+ * codeBlock: { showLineNumbers: true, theme: "github-dark" },
20
+ * sidebar: { width: 280, style: "bordered" },
21
+ * },
22
+ * });
23
+ * ```
24
+ */
25
+ /**
26
+ * Font style configuration for a single text element (heading, body, etc.).
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * h1: { size: "2.25rem", weight: 700, lineHeight: "1.2", letterSpacing: "-0.02em" }
31
+ * ```
32
+ */
33
+ interface FontStyle {
34
+ /** CSS `font-size` value (e.g. "2.25rem", "36px", "clamp(1.8rem, 3vw, 2.5rem)") */
35
+ size?: string;
36
+ /** CSS `font-weight` value (e.g. 700, "bold", "600") */
37
+ weight?: string | number;
38
+ /** CSS `line-height` value (e.g. "1.2", "1.5", "28px") */
39
+ lineHeight?: string;
40
+ /** CSS `letter-spacing` value (e.g. "-0.02em", "0.05em") */
41
+ letterSpacing?: string;
42
+ }
43
+ /**
44
+ * Typography configuration for the docs.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * typography: {
49
+ * font: {
50
+ * style: { sans: "Inter, sans-serif", mono: "JetBrains Mono, monospace" },
51
+ * h1: { size: "2.25rem", weight: 700, letterSpacing: "-0.02em" },
52
+ * h2: { size: "1.75rem", weight: 600 },
53
+ * body: { size: "1rem", lineHeight: "1.75" },
54
+ * },
55
+ * }
56
+ * ```
57
+ */
58
+ interface TypographyConfig {
59
+ /**
60
+ * Font configuration.
61
+ */
62
+ font?: {
63
+ /**
64
+ * Font family definitions.
65
+ */
66
+ style?: {
67
+ /** 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. */
68
+ mono?: string;
69
+ }; /** Heading 1 (`<h1>`) style overrides */
70
+ h1?: FontStyle; /** Heading 2 (`<h2>`) style overrides */
71
+ h2?: FontStyle; /** Heading 3 (`<h3>`) style overrides */
72
+ h3?: FontStyle; /** Heading 4 (`<h4>`) style overrides */
73
+ h4?: FontStyle; /** Body text style */
74
+ body?: FontStyle; /** Small text style (captions, meta text) */
75
+ small?: FontStyle;
76
+ };
77
+ }
78
+ interface UIConfig {
79
+ /**
80
+ * Theme color tokens.
81
+ *
82
+ * These are mapped to `--color-fd-*` CSS variables at runtime.
83
+ * Accepts any valid CSS color value (hex, rgb, oklch, hsl, etc.).
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * colors: {
88
+ * primary: "oklch(0.72 0.19 149)", // green primary
89
+ * primaryForeground: "#ffffff", // white text on primary
90
+ * accent: "hsl(220 80% 60%)", // blue accent
91
+ * }
92
+ * ```
93
+ */
94
+ colors?: {
95
+ primary?: string;
96
+ primaryForeground?: string;
97
+ background?: string;
98
+ foreground?: string;
99
+ muted?: string;
100
+ mutedForeground?: string;
101
+ border?: string;
102
+ card?: string;
103
+ cardForeground?: string;
104
+ accent?: string;
105
+ accentForeground?: string;
106
+ secondary?: string;
107
+ secondaryForeground?: string;
108
+ popover?: string;
109
+ popoverForeground?: string;
110
+ ring?: string;
111
+ };
112
+ /**
113
+ * Typography settings — font families, heading sizes, weights, etc.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * typography: {
118
+ * font: {
119
+ * style: { sans: "Inter, sans-serif", mono: "JetBrains Mono, monospace" },
120
+ * h1: { size: "2.25rem", weight: 700, letterSpacing: "-0.02em" },
121
+ * body: { size: "1rem", lineHeight: "1.75" },
122
+ * },
123
+ * }
124
+ * ```
125
+ */
126
+ typography?: TypographyConfig;
127
+ /**
128
+ * Global border-radius. Maps to CSS `--radius`.
129
+ * Use "0px" for sharp corners, "0.5rem" for rounded, etc.
130
+ */
131
+ radius?: string;
132
+ /** Layout dimensions */
133
+ layout?: {
134
+ contentWidth?: number;
135
+ sidebarWidth?: number;
136
+ tocWidth?: number;
137
+ toc?: {
138
+ enabled?: boolean;
139
+ depth?: number;
140
+ /**
141
+ * Visual style of the TOC indicator.
142
+ * - `"default"` — highlight active link text color only
143
+ * - `"directional"` — animated thumb bar that tracks active headings (fumadocs style)
144
+ * @default "default"
145
+ */
146
+ style?: "default" | "directional";
147
+ };
148
+ header?: {
149
+ height?: number;
150
+ sticky?: boolean;
151
+ };
152
+ };
153
+ /** Code block rendering config */
154
+ codeBlock?: {
155
+ /** Show line numbers in code blocks @default false */showLineNumbers?: boolean; /** Show copy button @default true */
156
+ showCopyButton?: boolean; /** Shiki theme name for syntax highlighting */
157
+ theme?: string; /** Dark mode shiki theme (for dual-theme setups) */
158
+ darkTheme?: string;
159
+ };
160
+ /** Sidebar styling hints (consumed by theme CSS) */
161
+ sidebar?: {
162
+ /**
163
+ * Visual style of the sidebar.
164
+ * - "default" — standard fumadocs sidebar
165
+ * - "bordered" — visible bordered sections (like better-auth)
166
+ * - "floating" — floating card sidebar
167
+ */
168
+ style?: "default" | "bordered" | "floating"; /** Background color override */
169
+ background?: string; /** Border color override */
170
+ borderColor?: string;
171
+ };
172
+ /** Card styling */
173
+ card?: {
174
+ /** Whether cards have visible borders @default true */bordered?: boolean; /** Card background color override */
175
+ background?: string;
176
+ };
177
+ /** Default props/variants for built-in MDX components (Callout, CodeBlock, Tabs, HoverLink, Prompt, etc.) */
178
+ components?: {
179
+ [key: string]: Record<string, unknown> | ((defaults: unknown) => unknown);
180
+ };
181
+ }
182
+ /**
183
+ * A docs theme configuration.
184
+ *
185
+ * Theme authors create these with `createTheme()`. The `name` identifies the
186
+ * theme (useful for CSS scoping, debugging, analytics). The `ui` object holds
187
+ * all visual configuration.
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * import { createTheme } from "@farming-labs/docs";
192
+ *
193
+ * export const myTheme = createTheme({
194
+ * name: "my-theme",
195
+ * ui: {
196
+ * colors: { primary: "#ff4d8d" },
197
+ * radius: "0px",
198
+ * },
199
+ * });
200
+ * ```
201
+ */
202
+ interface DocsTheme {
203
+ /** Unique name for this theme (used for CSS scoping and debugging) */
204
+ name?: string;
205
+ /** UI configuration — colors, typography, layout, components */
206
+ ui?: UIConfig;
207
+ /**
208
+ * @internal
209
+ * User-provided color overrides tracked by `createTheme`.
210
+ * Only these colors are emitted as inline CSS variables at runtime.
211
+ * Preset defaults stay in the theme's CSS file.
212
+ */
213
+ _userColorOverrides?: Record<string, string>;
214
+ }
215
+ interface DocsMetadata {
216
+ titleTemplate?: string;
217
+ description?: string;
218
+ twitterCard?: "summary" | "summary_large_image";
219
+ }
220
+ interface OGConfig {
221
+ enabled?: boolean;
222
+ type?: "static" | "dynamic";
223
+ endpoint?: string;
224
+ defaultImage?: string;
225
+ }
226
+ /** Single image entry for Open Graph (frontmatter or Next metadata). */
227
+ interface OpenGraphImage {
228
+ url: string;
229
+ width?: number;
230
+ height?: number;
231
+ }
232
+ /** Open Graph block in page frontmatter. When present, used as-is for metadata (replaces generated OG). */
233
+ interface PageOpenGraph {
234
+ images?: OpenGraphImage[];
235
+ title?: string;
236
+ description?: string;
237
+ }
238
+ /** Twitter card block in page frontmatter. When present, used as-is for metadata (replaces generated twitter). */
239
+ interface PageTwitter {
240
+ card?: "summary" | "summary_large_image";
241
+ images?: string[];
242
+ title?: string;
243
+ description?: string;
244
+ }
245
+ type DocsRelatedItem = string;
246
+ interface ResolvedDocsRelatedLink {
247
+ href: string;
248
+ }
249
+ interface PageAgentAppliesTo {
250
+ /** Framework name or names this task applies to, for example `"nextjs"`. */
251
+ framework?: string | string[];
252
+ /** Version range or ranges this task applies to, for example `">=16"`. */
253
+ version?: string | string[];
254
+ /** Package name or names this task applies to, for example `"@farming-labs/next"`. */
255
+ package?: string | string[];
256
+ }
257
+ interface PageAgentCommand {
258
+ /** Exact command an agent may run. */
259
+ run: string;
260
+ /** Optional working directory, relative to the project root unless documented otherwise. */
261
+ cwd?: string;
262
+ /** Short explanation of what the command does. */
263
+ description?: string;
264
+ }
265
+ interface PageAgentVerification {
266
+ /** Human-readable verification step. */
267
+ description?: string;
268
+ /** Optional command used to verify the result. */
269
+ run?: string;
270
+ /** Observable result that indicates success. */
271
+ expect?: string;
272
+ }
273
+ interface PageAgentFailureMode {
274
+ /** Symptom an agent may observe. */
275
+ symptom: string;
276
+ /** Recovery guidance for the symptom. */
277
+ resolution?: string;
278
+ }
279
+ interface PageAgentFrontmatter {
280
+ /**
281
+ * Approximate output token target for machine-readable compaction on this page.
282
+ * Used by `docs agent compact` as a per-page override.
283
+ */
284
+ tokenBudget?: number;
285
+ /** Concrete task the page helps an agent complete. */
286
+ task?: string;
287
+ /** Observable end state the agent should reach. */
288
+ outcome?: string;
289
+ /** Framework, version, and package applicability constraints. */
290
+ appliesTo?: PageAgentAppliesTo;
291
+ /** Conditions or setup that must already be true. */
292
+ prerequisites?: string[];
293
+ /** Files the task is expected to read or change. */
294
+ files?: string[];
295
+ /** Commands the task may require. Strings are supported as a concise shorthand. */
296
+ commands?: Array<string | PageAgentCommand>;
297
+ /** Material state changes or external effects the task can cause. */
298
+ sideEffects?: string[];
299
+ /** Checks that prove the task completed successfully. */
300
+ verification?: Array<string | PageAgentVerification>;
301
+ /** Steps that restore the previous state when the task must be undone. */
302
+ rollback?: string[];
303
+ /** Common symptoms and optional recovery guidance. */
304
+ failureModes?: Array<string | PageAgentFailureMode>;
305
+ }
306
+ interface PageSidebarFrontmatter {
307
+ /**
308
+ * Override how this folder page behaves in the default sidebar when it has children.
309
+ *
310
+ * This is only read from folder landing pages such as `page.mdx` / `index.md`.
311
+ */
312
+ folderIndexBehavior?: SidebarFolderIndexBehavior;
313
+ }
314
+ interface PageFrontmatter {
315
+ title: string;
316
+ description?: string;
317
+ /** Related doc URLs rendered into machine-readable markdown routes and MCP page output. */
318
+ related?: DocsRelatedItem[];
319
+ /** Per-page agent-oriented metadata used by machine-readable docs features. */
320
+ agent?: PageAgentFrontmatter;
321
+ /** Per-page sidebar metadata used when building the docs navigation tree. */
322
+ sidebar?: PageSidebarFrontmatter;
323
+ /** Override or disable the estimated reading time for this page. */
324
+ readingTime?: boolean | number;
325
+ tags?: string[];
326
+ icon?: string;
327
+ /** Path to custom OG image for this page (shorthand). Ignored if `openGraph` is set. */
328
+ ogImage?: string;
329
+ /** Full Open Graph object. When set, replaces any generated OG from config (e.g. dynamic endpoint). */
330
+ openGraph?: PageOpenGraph;
331
+ /** Full Twitter card object. When set, replaces any generated twitter from config. */
332
+ twitter?: PageTwitter;
333
+ /** Sort order in the sidebar. Lower numbers appear first. Pages without `order` are sorted alphabetically after ordered pages. */
334
+ order?: number;
335
+ }
336
+ interface DocsNav {
337
+ /**
338
+ * Sidebar title — a plain string or a React element (e.g. a div with an icon).
339
+ *
340
+ * @example
341
+ * ```tsx
342
+ * // Simple string
343
+ * nav: { title: "My Docs" }
344
+ *
345
+ * // React element with icon
346
+ * nav: {
347
+ * title: <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
348
+ * <Rocket size={18} /> Example Docs
349
+ * </div>
350
+ * }
351
+ * ```
352
+ */
353
+ title?: unknown;
354
+ /** URL the title links to. Defaults to `/{entry}`. */
355
+ url?: string;
356
+ }
357
+ interface ThemeToggleConfig {
358
+ /**
359
+ * Whether to show the light/dark theme toggle in the sidebar.
360
+ * @default true
361
+ */
362
+ enabled?: boolean;
363
+ /**
364
+ * The default / forced theme when the toggle is hidden.
365
+ * Only applies when `enabled` is `false`.
366
+ * @default "system"
367
+ *
368
+ * @example
369
+ * ```ts
370
+ * // Hide toggle, force dark mode
371
+ * themeToggle: { enabled: false, default: "dark" }
372
+ * ```
373
+ */
374
+ default?: "light" | "dark" | "system";
375
+ /**
376
+ * Toggle mode — show only light/dark, or include a system option.
377
+ * @default "light-dark"
378
+ */
379
+ mode?: "light-dark" | "light-dark-system";
380
+ }
381
+ interface BreadcrumbConfig {
382
+ /**
383
+ * Whether to show the breadcrumb navigation above page content.
384
+ * @default true
385
+ */
386
+ enabled?: boolean;
387
+ /**
388
+ * Custom breadcrumb component. Receives the default breadcrumb as children
389
+ * so you can wrap/modify it.
390
+ *
391
+ * @example
392
+ * ```tsx
393
+ * breadcrumb: {
394
+ * component: ({ items }) => <MyBreadcrumb items={items} />,
395
+ * }
396
+ * ```
397
+ */
398
+ component?: unknown;
399
+ }
400
+ /**
401
+ * A leaf page in the sidebar tree.
402
+ */
403
+ interface SidebarPageNode {
404
+ type: "page";
405
+ name: string;
406
+ url: string;
407
+ icon?: unknown;
408
+ }
409
+ /**
410
+ * A folder (group) in the sidebar tree. May contain child pages
411
+ * and nested folders, forming a recursive hierarchy.
412
+ */
413
+ interface SidebarFolderNode {
414
+ type: "folder";
415
+ name: string;
416
+ icon?: unknown;
417
+ /** Index page for this folder (the folder's own landing page). */
418
+ index?: SidebarPageNode;
419
+ /**
420
+ * Optional per-folder override read from the folder page frontmatter before the
421
+ * tree is normalized for the default sidebar.
422
+ */
423
+ folderIndexBehavior?: SidebarFolderIndexBehavior;
424
+ /** Child pages and sub-folders. */
425
+ children: SidebarNode[];
426
+ /** Whether this folder section is collapsible. */
427
+ collapsible?: boolean;
428
+ /** Whether this folder starts open. */
429
+ defaultOpen?: boolean;
430
+ }
431
+ /** A node in the sidebar tree — either a page or a folder. */
432
+ type SidebarNode = SidebarPageNode | SidebarFolderNode;
433
+ /** The full sidebar tree passed to custom sidebar components. */
434
+ interface SidebarTree {
435
+ name: string;
436
+ children: SidebarNode[];
437
+ }
438
+ /**
439
+ * Props passed to a custom sidebar component.
440
+ *
441
+ * Contains all the information needed to build a fully custom sidebar:
442
+ * the complete page tree with parent-child relationships, and the
443
+ * current sidebar configuration.
444
+ */
445
+ interface SidebarComponentProps {
446
+ /** Full page tree with all parent-child-folder relationships. */
447
+ tree: SidebarTree;
448
+ /** Whether folders are collapsible. */
449
+ collapsible: boolean;
450
+ /** Whether folders are rendered flat (Mintlify-style). */
451
+ flat: boolean;
452
+ }
453
+ /**
454
+ * Controls how folders with their own landing page behave in the default sidebar.
455
+ *
456
+ * - `"link"` — clicking the parent row navigates to the folder landing page
457
+ * - `"toggle"` — clicking the parent row only expands/collapses children, and the
458
+ * landing page is rendered as the first child item instead
459
+ */
460
+ type SidebarFolderIndexBehavior = "link" | "toggle" | "hidden";
461
+ type SidebarFolderIndexBehaviorOverrides = Record<string, SidebarFolderIndexBehavior>;
462
+ interface SidebarConfig {
463
+ /**
464
+ * Whether to show the sidebar.
465
+ * @default true
466
+ */
467
+ enabled?: boolean;
468
+ /**
469
+ * Custom sidebar component to replace the default navigation.
470
+ *
471
+ * **Next.js** — Pass a render function that receives `SidebarComponentProps`:
472
+ * ```tsx
473
+ * sidebar: {
474
+ * component: ({ tree, collapsible, flat }) => (
475
+ * <MySidebar tree={tree} />
476
+ * ),
477
+ * }
478
+ * ```
479
+ *
480
+ * **Astro** — Use the `sidebar` named slot on `<DocsLayout>`:
481
+ * ```astro
482
+ * <DocsLayout tree={tree} config={config}>
483
+ * <MySidebar slot="sidebar" tree={tree} />
484
+ * <slot />
485
+ * </DocsLayout>
486
+ * ```
487
+ *
488
+ * **SvelteKit** — Use the `sidebar` snippet on `<DocsLayout>`:
489
+ * ```svelte
490
+ * <DocsLayout {tree} {config}>
491
+ * {#snippet sidebar({ tree, isActive })}
492
+ * <MySidebarNav {tree} {isActive} />
493
+ * {/snippet}
494
+ * {@render children()}
495
+ * </DocsLayout>
496
+ * ```
497
+ *
498
+ * **Nuxt / Vue** — Use the `#sidebar` scoped slot on `<DocsLayout>`:
499
+ * ```vue
500
+ * <DocsLayout :tree="tree" :config="config">
501
+ * <template #sidebar="{ tree, isActive }">
502
+ * <MySidebarNav :tree="tree" :is-active="isActive" />
503
+ * </template>
504
+ * <DocsContent />
505
+ * </DocsLayout>
506
+ * ```
507
+ */
508
+ component?: (props: SidebarComponentProps) => unknown;
509
+ /**
510
+ * Sidebar footer content (rendered below navigation items).
511
+ */
512
+ footer?: unknown;
513
+ /**
514
+ * Sidebar banner content (rendered above navigation items).
515
+ */
516
+ banner?: unknown;
517
+ /**
518
+ * Whether the sidebar is collapsible on desktop.
519
+ * @default true
520
+ */
521
+ collapsible?: boolean;
522
+ /**
523
+ * When true, all folder children are rendered flat in the sidebar
524
+ * (no collapsible sections). Folder index pages appear as category
525
+ * headings with all children listed directly below them.
526
+ *
527
+ * This creates a Mintlify-style sidebar where all navigation items
528
+ * are always visible.
529
+ *
530
+ * @default false
531
+ */
532
+ flat?: boolean;
533
+ /**
534
+ * How folders with their own `page.mdx` / `page.md` behave in the default sidebar.
535
+ *
536
+ * - `"link"` — clicking the parent row navigates to the folder landing page
537
+ * - `"toggle"` — clicking the parent row only expands/collapses children, and the
538
+ * folder landing page appears as the first child item instead
539
+ * - `"hidden"` — the folder landing page route still exists, but the parent row
540
+ * becomes a plain label and only the child pages appear in the sidebar
541
+ *
542
+ * This is the global default. Individual folder pages can still override it with
543
+ * page frontmatter:
544
+ *
545
+ * ```mdx
546
+ * ---
547
+ * sidebar:
548
+ * folderIndexBehavior: "hidden"
549
+ * ---
550
+ * ```
551
+ *
552
+ * When omitted, each adapter keeps its existing folder-parent behavior. Set this
553
+ * explicitly if you want the same sidebar interaction across frameworks.
554
+ */
555
+ folderIndexBehavior?: SidebarFolderIndexBehavior;
556
+ /**
557
+ * Selective per-folder overrides keyed by the folder landing-page URL.
558
+ * Folder page frontmatter still wins when both are present.
559
+ *
560
+ * ```ts
561
+ * sidebar: {
562
+ * folderIndexBehavior: "link",
563
+ * folderIndexBehaviorOverrides: {
564
+ * "/docs/components": "toggle",
565
+ * "/docs/guides": "toggle",
566
+ * },
567
+ * }
568
+ * ```
569
+ */
570
+ folderIndexBehaviorOverrides?: SidebarFolderIndexBehaviorOverrides;
571
+ }
572
+ type OpenDocsTarget = "markdown" | "page" | "source" | "github";
573
+ type OpenDocsProviderId = "chatgpt" | "claude" | "cursor" | "gemini" | "copilot" | "perplexity" | "github";
574
+ /**
575
+ * A single "Open in …" provider shown in the Open dropdown.
576
+ *
577
+ * Pass a string for a built-in provider preset, or pass an object to customize a known provider
578
+ * or keep using a custom `urlTemplate`.
579
+ *
580
+ * @example
581
+ * ```ts
582
+ * "cursor"
583
+ * ```
584
+ *
585
+ * @example
586
+ * ```ts
587
+ * {
588
+ * id: "cursor",
589
+ * prompt: "Use this docs page while editing the codebase: {url}",
590
+ * }
591
+ * ```
592
+ *
593
+ * @example
594
+ * ```ts
595
+ * {
596
+ * name: "Claude",
597
+ * icon: <ClaudeIcon />,
598
+ * urlTemplate: "https://claude.ai?url={url}.md",
599
+ * promptUrlTemplate: "https://claude.ai/new?q={prompt}",
600
+ * }
601
+ * ```
602
+ */
603
+ type OpenDocsProvider = OpenDocsProviderId | OpenDocsProviderConfig;
604
+ interface OpenDocsProviderConfig {
605
+ /** Built-in provider preset to use as the base. */
606
+ id?: OpenDocsProviderId | string;
607
+ /** Display name (e.g. "ChatGPT", "Claude", "Cursor") */
608
+ name?: string;
609
+ /** Alias for `name` when configuring a preset provider. */
610
+ label?: string;
611
+ /** Icon element rendered next to the name */
612
+ icon?: unknown;
613
+ /** Override the target URL inserted into `{url}` for this provider. */
614
+ target?: OpenDocsTarget;
615
+ /** Prompt text used by known provider presets. Supports `{url}`, `{pageUrl}`, `{markdownUrl}`, `{sourceUrl}`, `{mdxUrl}`, and `{githubUrl}`. */
616
+ prompt?: string;
617
+ /** Cursor-specific mode. `"web"` opens cursor.com; `"app"` opens the Cursor app deeplink. */
618
+ mode?: "web" | "app";
619
+ /**
620
+ * URL template. Placeholders:
621
+ * - `{url}` — selected target URL, controlled by `openDocs.target` or provider `target` (encoded).
622
+ * - `{pageUrl}` — rendered docs page URL (encoded).
623
+ * - `{markdownUrl}` — public `.md` route for the page (encoded).
624
+ * - `{sourceUrl}` / `{mdxUrl}` — page URL with `.mdx` suffix (encoded).
625
+ * - `{githubUrl}` — GitHub edit URL for the current page (same as "Edit on GitHub"). Requires `github` in config.
626
+ * - `{prompt}` — prompt text after resolving the target URL placeholders (encoded).
627
+ *
628
+ * @example "https://claude.ai/new?q=Read+this+doc:+{url}.md"
629
+ * @example "{githubUrl}" — open current page file on GitHub (edit view)
630
+ */
631
+ urlTemplate?: string;
632
+ /**
633
+ * Optional URL template used by the built-in `Prompt` MDX component.
634
+ * When omitted, known providers such as ChatGPT, Claude, Cursor, Gemini,
635
+ * Copilot, and Perplexity fall back to a built-in `{prompt}` template by provider name.
636
+ *
637
+ * Placeholders:
638
+ * - `{prompt}` — prompt text (encoded).
639
+ *
640
+ * @example "https://cursor.com/link/prompt?text={prompt}"
641
+ */
642
+ promptUrlTemplate?: string;
643
+ }
644
+ /**
645
+ * Configuration for the "Open in …" dropdown that lets users
646
+ * send the current page to an LLM or external tool.
647
+ *
648
+ * @example
649
+ * ```ts
650
+ * openDocs: {
651
+ * enabled: true,
652
+ * target: "markdown",
653
+ * providers: [
654
+ * "chatgpt",
655
+ * "claude",
656
+ * "cursor",
657
+ * ],
658
+ * }
659
+ * ```
660
+ */
661
+ interface OpenDocsConfig {
662
+ /** Whether to show the "Open" dropdown. @default false */
663
+ enabled?: boolean;
664
+ /**
665
+ * Which URL should be inserted into `{url}` for preset providers and provider templates.
666
+ * @default "markdown"
667
+ */
668
+ target?: OpenDocsTarget;
669
+ /**
670
+ * Prompt text used by built-in provider presets.
671
+ * Supports `{url}`, `{pageUrl}`, `{markdownUrl}`, `{sourceUrl}`, `{mdxUrl}`,
672
+ * and `{githubUrl}`.
673
+ *
674
+ * @default "Read this documentation: {url}"
675
+ */
676
+ prompt?: string;
677
+ /**
678
+ * List of LLM / tool providers to show in the dropdown.
679
+ * If not provided, a sensible default list is used.
680
+ */
681
+ providers?: OpenDocsProvider[];
682
+ }
683
+ /**
684
+ * Configuration for the "Copy Markdown" button that copies
685
+ * the current page's content as Markdown to the clipboard.
686
+ */
687
+ type CopyMarkdownFormat = "markdown" | "text";
688
+ interface CopyMarkdownConfig {
689
+ /** Whether to show the "Copy Markdown" button. @default false */
690
+ enabled?: boolean;
691
+ /** Content format copied by the button. @default "markdown" */
692
+ format?: CopyMarkdownFormat;
693
+ /** Whether to prepend the current page title to copied content. @default false */
694
+ includeTitle?: boolean;
695
+ /** Button label shown before the page is copied. @default "Copy page" */
696
+ label?: string;
697
+ /** Button label shown after a successful copy. @default "Copied!" */
698
+ copiedLabel?: string;
699
+ }
700
+ /**
701
+ * Page-level action buttons shown above the page content
702
+ * (e.g. "Copy Markdown", "Open in …" dropdown).
703
+ *
704
+ * @example
705
+ * ```ts
706
+ * pageActions: {
707
+ * copyMarkdown: { enabled: true },
708
+ * openDocs: {
709
+ * enabled: true,
710
+ * target: "markdown",
711
+ * providers: [
712
+ * "chatgpt",
713
+ * "claude",
714
+ * { id: "cursor", mode: "app" },
715
+ * ],
716
+ * },
717
+ * }
718
+ * ```
719
+ */
720
+ interface PageActionsConfig {
721
+ /** "Copy Markdown" button */
722
+ copyMarkdown?: boolean | CopyMarkdownConfig;
723
+ /** "Open in …" dropdown with LLM / tool providers */
724
+ openDocs?: boolean | OpenDocsConfig;
725
+ /**
726
+ * Where to render the page action buttons relative to the page title.
727
+ *
728
+ * - `"below-title"` — render below the first `<h1>` heading (default)
729
+ * - `"above-title"` — render above the page title / content
730
+ * - `"toc"` — render as a compact rail in the table-of-contents column
731
+ *
732
+ * @default "below-title"
733
+ */
734
+ position?: "above-title" | "below-title" | "toc";
735
+ /**
736
+ * Horizontal alignment of page action buttons.
737
+ *
738
+ * - `"left"` — align to the left (default)
739
+ * - `"right"` — align to the right
740
+ *
741
+ * @default "left"
742
+ */
743
+ alignment?: "left" | "right";
744
+ }
745
+ type DocsAnalyticsSource = "client" | "server" | "mcp";
746
+ type DocsAgentTraceStatus = "started" | "success" | "error" | "retry" | "timeout";
747
+ 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";
748
+ 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";
749
+ interface DocsAnalyticsInput {
750
+ query?: string;
751
+ question?: string;
752
+ feedbackValue?: string;
753
+ feedbackComment?: string;
754
+ feedbackContext?: DocsAgentFeedbackContext;
755
+ feedbackPayload?: Record<string, unknown>;
756
+ agentFeedbackContext?: DocsAgentFeedbackContext;
757
+ agentFeedbackPayload?: Record<string, unknown>;
758
+ content?: string;
759
+ }
760
+ interface DocsEventBase {
761
+ timestamp: string;
762
+ source: DocsAnalyticsSource;
763
+ url?: string;
764
+ path?: string;
765
+ referrer?: string;
766
+ locale?: string;
767
+ input?: DocsAnalyticsInput;
768
+ metadata?: Record<string, unknown>;
769
+ properties?: Record<string, unknown>;
770
+ }
771
+ interface DocsAnalyticsEvent extends DocsEventBase {
772
+ type: DocsAnalyticsEventType | (string & {});
773
+ }
774
+ type DocsAnalyticsEventInput = Omit<DocsAnalyticsEvent, "timestamp" | "source"> & {
775
+ timestamp?: string;
776
+ source?: DocsAnalyticsSource;
777
+ };
778
+ interface DocsObservabilityEvent extends DocsEventBase {
779
+ type: DocsAgentTraceEventType | (string & {});
780
+ traceId?: string;
781
+ spanId?: string;
782
+ parentSpanId?: string;
783
+ name?: string;
784
+ startedAt?: string;
785
+ endedAt?: string;
786
+ durationMs?: number;
787
+ status?: DocsAgentTraceStatus;
788
+ inputPreview?: Record<string, unknown>;
789
+ outputPreview?: Record<string, unknown>;
790
+ }
791
+ type DocsObservabilityEventInput = Omit<DocsObservabilityEvent, "timestamp" | "source"> & {
792
+ timestamp?: string;
793
+ source?: DocsAnalyticsSource;
794
+ };
795
+ type DocsAgentTraceEventInput = Omit<DocsObservabilityEventInput, "type"> & {
796
+ type: DocsAgentTraceEventType;
797
+ name: string;
798
+ };
799
+ interface DocsAnalyticsConfig {
800
+ /** Enable event emission. Defaults to `true` when this object is provided. */
801
+ enabled?: boolean;
802
+ /**
803
+ * Log events to the console.
804
+ *
805
+ * `analytics: true` logs with `console.info`. When `onEvent` is provided,
806
+ * console logging is disabled unless this is set.
807
+ */
808
+ console?: boolean | "log" | "info" | "debug";
809
+ /**
810
+ * Include raw search queries, AI questions, feedback comments, and copied
811
+ * content in emitted events.
812
+ *
813
+ * Defaults to `false`; events still include safe metadata such as lengths,
814
+ * counts, routes, status, and duration.
815
+ */
816
+ includeInputs?: boolean;
817
+ /** Callback fired for every emitted event. */
818
+ onEvent?: (event: DocsAnalyticsEvent) => void | Promise<void>;
819
+ /**
820
+ * Forward events to Docs Cloud when project env vars are available.
821
+ *
822
+ * @default true
823
+ */
824
+ cloud?: boolean;
825
+ }
826
+ type DocsTelemetryFramework = "next" | "tanstack-start" | "sveltekit" | "astro" | "nuxt" | "mcp" | (string & {});
827
+ type DocsTelemetryEventType = "project_detected" | "agent_surface_used" | "mcp_request" | "mcp_tool_used" | (string & {});
828
+ type DocsTelemetryAgentSurface = "agent_spec" | "agents" | "skill" | "markdown" | "llms" | "agent_feedback_schema" | "agent_feedback_submit" | "ask_ai" | "mcp";
829
+ interface DocsTelemetryConfig {
830
+ /** Enable Farming Labs maintainer telemetry. Defaults to production-only enabled. */
831
+ enabled?: boolean;
832
+ /**
833
+ * Public site origin to include in telemetry events.
834
+ *
835
+ * When omitted, the runtime request origin or deployment URL is used when available. Localhost
836
+ * and loopback origins are ignored.
837
+ */
838
+ siteOrigin?: string;
839
+ /**
840
+ * Override the telemetry ingestion endpoint.
841
+ *
842
+ * This is mostly useful for self-hosting, development verification, or tests.
843
+ */
844
+ endpoint?: string;
845
+ }
846
+ interface DocsTelemetryFeatures {
847
+ search: boolean;
848
+ ai: boolean;
849
+ mcp: boolean;
850
+ llmsTxt: boolean;
851
+ pageActions: boolean;
852
+ feedback: boolean;
853
+ agentFeedback: boolean;
854
+ sitemap: boolean;
855
+ robots: boolean;
856
+ apiReference: boolean;
857
+ staticExport: boolean;
858
+ changelog: boolean;
859
+ cloud: boolean;
860
+ review: boolean;
861
+ codeBlocksValidate: boolean;
862
+ }
863
+ interface DocsTelemetryEvent {
864
+ type: DocsTelemetryEventType;
865
+ timestamp: string;
866
+ package: {
867
+ name: "@farming-labs/docs";
868
+ version?: string;
869
+ };
870
+ framework?: DocsTelemetryFramework;
871
+ runtime?: {
872
+ name?: string;
873
+ version?: string;
874
+ };
875
+ site?: {
876
+ origin?: string;
877
+ };
878
+ deployment?: {
879
+ provider?: string;
880
+ environment?: string;
881
+ id?: string;
882
+ region?: string;
883
+ };
884
+ features?: Partial<DocsTelemetryFeatures>;
885
+ properties?: Record<string, unknown>;
886
+ }
887
+ type DocsTelemetryEventInput = Omit<DocsTelemetryEvent, "timestamp" | "package"> & {
888
+ timestamp?: string;
889
+ package?: Partial<DocsTelemetryEvent["package"]>;
890
+ };
891
+ interface DocsCloudApiKeyConfig {
892
+ /**
893
+ * Environment variable that stores the Docs Cloud API key.
894
+ *
895
+ * The key value is never written to docs.json; only this env var name is
896
+ * mirrored for CLI and CI workflows.
897
+ *
898
+ * @default "DOCS_CLOUD_API_KEY"
899
+ */
900
+ env?: string;
901
+ }
902
+ interface DocsCloudPreviewConfig {
903
+ /**
904
+ * Legacy hosted preview deployment gate.
905
+ *
906
+ * Prefer `cloud.deploy.enabled` in new configs.
907
+ *
908
+ * @default true when this legacy object is provided
909
+ */
910
+ enabled?: boolean;
911
+ }
912
+ interface DocsCloudPublishConfig {
913
+ /** How Docs Cloud should publish generated docs changes. @default "draft-pr" */
914
+ mode?: "draft-pr" | "direct-commit";
915
+ /** Branch that generated docs work should target. @default "main" */
916
+ baseBranch?: string;
917
+ }
918
+ interface DocsCloudFeatureConfig {
919
+ /** Whether the hosted cloud feature is enabled. @default true */
920
+ enabled?: boolean;
921
+ }
922
+ interface DocsCloudConfig {
923
+ /**
924
+ * Optional explicit cloud toggle.
925
+ *
926
+ * Prefer omitting this in new projects; the presence of `cloud` opts the
927
+ * project into cloud-aware CLI flows. This remains available for backwards
928
+ * compatibility with older docs.json files.
929
+ */
930
+ enabled?: boolean;
931
+ /** API key lookup used by `docs deploy` and other cloud CLI commands. */
932
+ apiKey?: DocsCloudApiKeyConfig;
933
+ /**
934
+ * Same-origin route for the generated Docs API handler.
935
+ *
936
+ * Next.js layouts use this as the default client analytics proxy when no
937
+ * hosted analytics endpoint env is configured. Set it when the route is
938
+ * mounted somewhere other than `/api/docs`, or when a deployment uses a
939
+ * public base path.
940
+ *
941
+ * @default "/api/docs"
942
+ */
943
+ apiRoute?: string;
944
+ /** Legacy hosted preview deployment settings. Prefer `deploy` in new configs. */
945
+ preview?: DocsCloudPreviewConfig;
946
+ /** Generated docs publishing settings. */
947
+ publish?: DocsCloudPublishConfig;
948
+ /** Hosted analytics settings that can be mirrored to docs.json. */
949
+ analytics?: boolean | Omit<DocsAnalyticsConfig, "onEvent">;
950
+ /** Hosted AI feature toggle. */
951
+ ai?: DocsCloudFeatureConfig;
952
+ /** Hosted deployment feature toggle used by `docs deploy`. */
953
+ deploy?: DocsCloudFeatureConfig;
954
+ }
955
+ interface DocsObservabilityConfig {
956
+ /** Enable trace emission. Defaults to `true` when this object is provided. */
957
+ enabled?: boolean;
958
+ /**
959
+ * Log trace events to the console.
960
+ *
961
+ * `observability: true` logs with `console.info`. When `onEvent` is provided,
962
+ * console logging is disabled unless this is set.
963
+ */
964
+ console?: boolean | "log" | "info" | "debug";
965
+ /**
966
+ * Include raw `input` fields on observability events.
967
+ *
968
+ * Defaults to `false`; events still include safe metadata such as lengths,
969
+ * counts, routes, status, and duration. Built-in trace events use previews
970
+ * instead of raw user-authored text.
971
+ */
972
+ includeInputs?: boolean;
973
+ /** Callback fired for every emitted trace event. */
974
+ onEvent?: (event: DocsObservabilityEvent) => void | Promise<void>;
975
+ }
976
+ /**
977
+ * Configuration for the "Last updated" date display.
978
+ *
979
+ * @example
980
+ * ```ts
981
+ * lastUpdated: { position: "below-title" }
982
+ * ```
983
+ */
984
+ /**
985
+ * Configuration for auto-generated `/llms.txt` and `/llms-full.txt` routes.
986
+ * Native static files at the same public routes take precedence.
987
+ *
988
+ * @see https://llmstxt.org
989
+ */
990
+ interface LlmsTxtConfig {
991
+ /**
992
+ * Whether to enable llms.txt generation.
993
+ * @default true
994
+ */
995
+ enabled?: boolean;
996
+ /**
997
+ * Whether to expose and advertise the RFC 9727 API catalog.
998
+ * Agent Skills discovery remains available when this is disabled.
999
+ * @default true
1000
+ */
1001
+ apiCatalog?: boolean;
1002
+ /**
1003
+ * Base URL for your docs site (used to build absolute links in llms.txt).
1004
+ * @example "https://docs.example.com"
1005
+ */
1006
+ baseUrl?: string;
1007
+ /**
1008
+ * Site title shown at the top of llms.txt.
1009
+ * Falls back to `nav.title` if not set.
1010
+ */
1011
+ siteTitle?: string;
1012
+ /**
1013
+ * Site description shown below the title.
1014
+ */
1015
+ siteDescription?: string;
1016
+ /**
1017
+ * Character budget for generated compact `llms.txt` files.
1018
+ *
1019
+ * `mode: "warn"` logs a warning when the generated content is over budget.
1020
+ * `mode: "error"` returns an error response for that generated file.
1021
+ * `mode: "off"` disables the budget check.
1022
+ *
1023
+ * @default { mode: "warn", chars: 50000 }
1024
+ */
1025
+ maxChars?: LlmsTxtMaxCharsConfig;
1026
+ /**
1027
+ * Optional section-level llms.txt files for progressive disclosure.
1028
+ *
1029
+ * Each section is matched against public docs URLs, for example
1030
+ * `/docs/api/**` derives `/docs/api/llms.txt` and
1031
+ * `/docs/api/llms-full.txt`.
1032
+ */
1033
+ sections?: LlmsTxtSectionConfig[];
1034
+ }
1035
+ type LlmsTxtMaxCharsMode = "warn" | "error" | "off";
1036
+ interface LlmsTxtMaxCharsConfig {
1037
+ /**
1038
+ * How to handle generated llms.txt content that exceeds `chars`.
1039
+ *
1040
+ * @default "warn"
1041
+ */
1042
+ mode?: LlmsTxtMaxCharsMode;
1043
+ /**
1044
+ * Maximum recommended character count.
1045
+ *
1046
+ * @default 50000
1047
+ */
1048
+ chars?: number;
1049
+ }
1050
+ interface LlmsTxtSectionConfig {
1051
+ /**
1052
+ * Human-readable section title shown in the root and section files.
1053
+ */
1054
+ title: string;
1055
+ /**
1056
+ * Optional description shown next to the section link in root llms.txt.
1057
+ */
1058
+ description?: string;
1059
+ /**
1060
+ * Public URL matcher for pages included in this section.
1061
+ *
1062
+ * Supported forms include exact paths such as `/docs/reference` and
1063
+ * prefix globs such as `/docs/api/**`.
1064
+ */
1065
+ match: string | string[];
1066
+ /**
1067
+ * Optional section-specific character budget. Inherits `llmsTxt.maxChars`
1068
+ * when omitted.
1069
+ */
1070
+ maxChars?: LlmsTxtMaxCharsConfig;
1071
+ }
1072
+ interface SitemapXmlConfig {
1073
+ /**
1074
+ * Whether to expose the XML sitemap route.
1075
+ * @default true
1076
+ */
1077
+ enabled?: boolean;
1078
+ /**
1079
+ * Include per-page `<lastmod>` entries when a reliable page date is available.
1080
+ * @default true
1081
+ */
1082
+ includeLastmod?: boolean;
1083
+ }
1084
+ interface SitemapMarkdownConfig {
1085
+ /**
1086
+ * Whether to expose the Markdown sitemap route.
1087
+ * @default true
1088
+ */
1089
+ enabled?: boolean;
1090
+ /**
1091
+ * Include page descriptions in the Markdown sitemap.
1092
+ * @default true
1093
+ */
1094
+ includeDescriptions?: boolean;
1095
+ /**
1096
+ * Include per-page freshness dates in the Markdown sitemap.
1097
+ * @default true
1098
+ */
1099
+ includeLastmod?: boolean;
1100
+ /**
1101
+ * Which URL each Markdown list item should primarily link to.
1102
+ * @default "both"
1103
+ */
1104
+ linkTarget?: "html" | "markdown" | "both";
1105
+ }
1106
+ /**
1107
+ * Configuration for generated `/sitemap.xml`, `/sitemap.md`, `/docs/sitemap.md`, and
1108
+ * `/.well-known/sitemap.md` routes.
1109
+ */
1110
+ interface DocsSitemapConfig {
1111
+ /**
1112
+ * Whether to enable sitemap routes.
1113
+ * @default true
1114
+ */
1115
+ enabled?: boolean;
1116
+ /**
1117
+ * Optional route prefix. For example, `"/docs"` generates
1118
+ * `/docs/sitemap.xml`, `/docs/sitemap.md`, and `/docs/.well-known/sitemap.md`.
1119
+ * @default ""
1120
+ */
1121
+ routePrefix?: string;
1122
+ /**
1123
+ * Public site URL used to build absolute XML sitemap URLs.
1124
+ * Falls back to the request origin at runtime or llmsTxt.baseUrl in the CLI.
1125
+ */
1126
+ baseUrl?: string;
1127
+ /**
1128
+ * Internal generated manifest path.
1129
+ * @default ".farming-labs/sitemap-manifest.json"
1130
+ */
1131
+ manifestPath?: string;
1132
+ /** XML sitemap options. */
1133
+ xml?: boolean | SitemapXmlConfig;
1134
+ /** Markdown sitemap options. */
1135
+ markdown?: boolean | SitemapMarkdownConfig;
1136
+ }
1137
+ interface DocsRobotsRule {
1138
+ /** User-agent name or names for this robots.txt rule block. */
1139
+ userAgent: string | string[];
1140
+ /** Routes to allow for the user-agent block. */
1141
+ allow?: string | string[];
1142
+ /** Routes to disallow for the user-agent block. */
1143
+ disallow?: string | string[];
1144
+ /** Optional crawl-delay value emitted as-is for crawlers that support it. */
1145
+ crawlDelay?: number;
1146
+ }
1147
+ /**
1148
+ * Configuration for generated `robots.txt` agent access policy files.
1149
+ */
1150
+ interface DocsRobotsConfig {
1151
+ /**
1152
+ * Whether robots.txt generation is enabled.
1153
+ * @default true when `robots` is an object
1154
+ */
1155
+ enabled?: boolean;
1156
+ /**
1157
+ * Output file path used by `docs robots generate`.
1158
+ * Falls back to the framework public directory, such as `public/robots.txt`
1159
+ * or `static/robots.txt` for SvelteKit.
1160
+ */
1161
+ path?: string;
1162
+ /**
1163
+ * Public site URL used for the `Sitemap:` line.
1164
+ * Falls back to `sitemap.baseUrl` or `llmsTxt.baseUrl` in the CLI.
1165
+ */
1166
+ baseUrl?: string;
1167
+ /**
1168
+ * Whether to explicitly allow or disallow common AI crawlers.
1169
+ * @default "allow"
1170
+ */
1171
+ ai?: boolean | "allow" | "disallow";
1172
+ /**
1173
+ * Additional AI user-agent names to include beside the defaults.
1174
+ */
1175
+ aiUserAgents?: string | string[];
1176
+ /**
1177
+ * Extra robots.txt rule blocks appended after the generated agent policy.
1178
+ */
1179
+ extraRules?: DocsRobotsRule[];
1180
+ }
1181
+ /**
1182
+ * Tool-level toggles for the built-in MCP server.
1183
+ *
1184
+ * All tools default to `true` when omitted.
1185
+ */
1186
+ interface DocsMcpToolsConfig {
1187
+ /** Expose a `list_docs` tool that returns docs pages grouped by section. */
1188
+ listDocs?: boolean;
1189
+ /** Expose a `list_pages` tool that returns the known docs pages. */
1190
+ listPages?: boolean;
1191
+ /** Expose a `read_page` tool that returns a page by slug or URL path. */
1192
+ readPage?: boolean;
1193
+ /** Expose a `list_tasks` tool for pages with actionable agent contracts. */
1194
+ listTasks?: boolean;
1195
+ /** Expose a `read_task` tool that returns a page's full agent contract. */
1196
+ readTask?: boolean;
1197
+ /** Expose a `search_docs` tool for keyword search over page content. */
1198
+ searchDocs?: boolean;
1199
+ /** Expose a `get_navigation` tool for the docs tree. */
1200
+ getNavigation?: boolean;
1201
+ /** Expose a `get_code_examples` tool for fenced code blocks and their metadata. */
1202
+ getCodeExamples?: boolean;
1203
+ /** Expose a `get_config_schema` tool for docs.config option metadata. */
1204
+ getConfigSchema?: boolean;
1205
+ /** Expose deterministic `get_context` retrieval with a conservative UTF-8 byte ceiling. */
1206
+ getContext?: boolean;
1207
+ }
1208
+ /** Authenticated identity returned by an MCP authentication callback. */
1209
+ interface DocsMcpAuthPrincipal {
1210
+ /** Stable identifier for the authenticated user, service, or agent. */
1211
+ id: string;
1212
+ /** Optional authorization scopes that source adapters can inspect. */
1213
+ scopes?: string[];
1214
+ /** Additional application-specific identity claims. */
1215
+ claims?: Record<string, unknown>;
1216
+ }
1217
+ /** Context passed to an MCP Origin policy callback. */
1218
+ interface DocsMcpOriginContext {
1219
+ /** Origin header supplied by the HTTP client. */
1220
+ origin: string;
1221
+ /** Portable Web Request for the incoming MCP request. */
1222
+ request: Request;
1223
+ }
1224
+ /** Context passed to an opt-in MCP authentication callback. */
1225
+ interface DocsMcpAuthenticateContext {
1226
+ /** Portable Web Request for the incoming MCP request. */
1227
+ request: Request;
1228
+ /** Normalized pathname of the MCP endpoint being requested. */
1229
+ pathname: string;
1230
+ /** Canonical OAuth resource identifier for exact token audience validation. */
1231
+ resource: string;
1232
+ }
1233
+ type DocsMcpAllowedOrigins = "same-origin" | readonly string[] | ((context: DocsMcpOriginContext) => boolean | Promise<boolean>);
1234
+ type DocsMcpAuthenticateResult = DocsMcpAuthPrincipal | null | Response;
1235
+ type DocsMcpAuthenticate = (context: DocsMcpAuthenticateContext) => DocsMcpAuthenticateResult | Promise<DocsMcpAuthenticateResult>;
1236
+ /** Browser CORS response controls for an Origin already accepted by `allowedOrigins`. */
1237
+ interface DocsMcpCorsConfig {
1238
+ /** Additional request headers accepted during browser preflight. */
1239
+ allowedHeaders?: readonly string[];
1240
+ /** Additional response headers exposed to browser clients. */
1241
+ exposedHeaders?: readonly string[];
1242
+ /** Emit `Access-Control-Allow-Credentials: true`. Defaults to `false`. */
1243
+ allowCredentials?: boolean;
1244
+ /** Browser preflight cache lifetime in seconds. Defaults to 600. */
1245
+ maxAgeSeconds?: number;
1246
+ }
1247
+ /** RFC 9728 discovery and endpoint-wide OAuth scope requirements for protected HTTP MCP. */
1248
+ interface DocsMcpProtectedResourceConfig {
1249
+ /**
1250
+ * OAuth authorization server issuer identifiers advertised to MCP clients.
1251
+ * Requires at least one HTTPS URL without query or fragment; loopback HTTP is accepted for development.
1252
+ */
1253
+ authorizationServers: readonly string[];
1254
+ /** OAuth scopes advertised through RFC 9728 `scopes_supported` metadata. */
1255
+ scopesSupported?: readonly string[];
1256
+ /** Scopes every authenticated HTTP MCP principal must have. */
1257
+ requiredScopes?: readonly string[];
1258
+ /** Human-readable protected-resource name. Defaults to the resolved MCP server name. */
1259
+ resourceName?: string;
1260
+ /** Absolute HTTP(S) URL of human-readable authentication guidance for this MCP resource. */
1261
+ resourceDocumentation?: string;
1262
+ }
1263
+ /** Security controls for the Streamable HTTP MCP transport. */
1264
+ interface DocsMcpSecurityConfig {
1265
+ /**
1266
+ * Allowed values for a supplied HTTP Origin header.
1267
+ * Defaults to `"same-origin"`. Requests without Origin remain supported for non-browser clients.
1268
+ */
1269
+ allowedOrigins?: DocsMcpAllowedOrigins;
1270
+ /**
1271
+ * Optional authentication callback. HTTP MCP stays public when omitted. When present,
1272
+ * returning `null` rejects the request with 401 and returning a Response passes it through.
1273
+ */
1274
+ authenticate?: DocsMcpAuthenticate;
1275
+ /**
1276
+ * Opt-in OAuth protected-resource discovery. Requires `authenticate` to protect HTTP MCP.
1277
+ * When active, adapters publish RFC 9728 metadata and framework-generated Bearer challenges.
1278
+ */
1279
+ protectedResource?: DocsMcpProtectedResourceConfig;
1280
+ /** Maximum POST body size in bytes. Defaults to 1 MiB. */
1281
+ maxBodyBytes?: number;
1282
+ /**
1283
+ * CORS responses for accepted browser Origins. Defaults to enabled with exact-Origin responses;
1284
+ * set `false` to suppress CORS headers or use an object for credential/header controls.
1285
+ */
1286
+ cors?: boolean | DocsMcpCorsConfig;
1287
+ }
1288
+ /**
1289
+ * Built-in MCP server configuration.
1290
+ *
1291
+ * When enabled, adapters can expose a Streamable HTTP endpoint for your docs
1292
+ * at `/mcp` and `/.well-known/mcp`, backed by the canonical `/api/docs/mcp` route.
1293
+ * The same config is also reused by the local `docs mcp` stdio command.
1294
+ */
1295
+ interface DocsMcpConfig {
1296
+ /** Whether to enable the built-in MCP server. Defaults to `true` when this object is provided. */
1297
+ enabled?: boolean;
1298
+ /**
1299
+ * Streamable HTTP route for the MCP endpoint.
1300
+ * Defaults to `/api/docs/mcp`; generated projects can also expose it publicly at `/mcp` and `/.well-known/mcp`.
1301
+ */
1302
+ route?: string;
1303
+ /**
1304
+ * Human-readable MCP server name shown to clients.
1305
+ * Defaults to the string `nav.title` when available, otherwise `@farming-labs/docs`.
1306
+ */
1307
+ name?: string;
1308
+ /**
1309
+ * Version string reported by the MCP server.
1310
+ * Defaults to `"0.0.0"` when not set.
1311
+ */
1312
+ version?: string;
1313
+ /** Fine-grained tool toggles. Omitted tools stay enabled. */
1314
+ tools?: DocsMcpToolsConfig;
1315
+ /** Streamable HTTP security controls. Authentication is opt-in; stdio is unaffected. */
1316
+ security?: DocsMcpSecurityConfig;
1317
+ }
1318
+ type DocsSearchResultType = "page" | "heading" | "text";
1319
+ interface DocsSearchSourcePage {
1320
+ title: string;
1321
+ url: string;
1322
+ content: string;
1323
+ description?: string;
1324
+ related?: ResolvedDocsRelatedLink[];
1325
+ agent?: PageAgentFrontmatter;
1326
+ sourcePath?: string;
1327
+ lastModified?: string;
1328
+ lastmod?: string;
1329
+ rawContent?: string;
1330
+ agentContent?: string;
1331
+ agentRawContent?: string;
1332
+ agentFallbackContent?: string;
1333
+ agentFallbackRawContent?: string;
1334
+ type?: "page" | "api" | "code" | "changelog";
1335
+ locale?: string;
1336
+ framework?: string;
1337
+ version?: string;
1338
+ tags?: string[];
1339
+ }
1340
+ interface DocsSearchDocument {
1341
+ id: string;
1342
+ url: string;
1343
+ title: string;
1344
+ content: string;
1345
+ description?: string;
1346
+ section?: string;
1347
+ type: DocsSearchResultType;
1348
+ locale?: string;
1349
+ framework?: string;
1350
+ version?: string;
1351
+ tags?: string[];
1352
+ }
1353
+ interface DocsSearchResult {
1354
+ id: string;
1355
+ url: string;
1356
+ content: string;
1357
+ description?: string;
1358
+ type: DocsSearchResultType;
1359
+ score?: number;
1360
+ section?: string;
1361
+ }
1362
+ interface DocsSearchQuery {
1363
+ query: string;
1364
+ limit?: number;
1365
+ locale?: string;
1366
+ pathname?: string;
1367
+ /** Requested content projection. Omitted callers retain the human-search default. */
1368
+ audience?: "human" | "agent";
1369
+ }
1370
+ interface DocsSearchAdapterContext {
1371
+ pages: DocsSearchSourcePage[];
1372
+ documents: DocsSearchDocument[];
1373
+ /** Resolved content projection supplied to this adapter. */
1374
+ audience?: "human" | "agent";
1375
+ locale?: string;
1376
+ pathname?: string;
1377
+ siteTitle?: string;
1378
+ /** Optional cancellation signal, including diagnostic timeouts. */
1379
+ signal?: AbortSignal;
1380
+ }
1381
+ interface DocsSearchAdapter {
1382
+ name: string;
1383
+ index?(context: DocsSearchAdapterContext): Promise<void>;
1384
+ search(query: DocsSearchQuery, context: DocsSearchAdapterContext): Promise<DocsSearchResult[]>;
1385
+ }
1386
+ type DocsSearchAdapterFactory = (context: DocsSearchAdapterContext) => DocsSearchAdapter | Promise<DocsSearchAdapter>;
1387
+ interface DocsSearchChunkingConfig {
1388
+ /**
1389
+ * How docs content should be chunked before searching.
1390
+ *
1391
+ * - `"page"` keeps one search document per page
1392
+ * - `"section"` splits pages by headings and improves precision
1393
+ *
1394
+ * @default "section"
1395
+ */
1396
+ strategy?: "page" | "section";
1397
+ }
1398
+ interface DocsSearchEmbeddingsConfig {
1399
+ /**
1400
+ * Embeddings provider used for hybrid / semantic search.
1401
+ * The initial built-in provider is Ollama for local or self-hosted setups.
1402
+ */
1403
+ provider: "ollama";
1404
+ /** Embedding model id, e.g. `embeddinggemma`. */
1405
+ model: string;
1406
+ /** Base URL of the embedding API. @default "http://127.0.0.1:11434" */
1407
+ baseUrl?: string;
1408
+ }
1409
+ interface SimpleDocsSearchConfig {
1410
+ provider?: "simple";
1411
+ enabled?: boolean;
1412
+ maxResults?: number;
1413
+ chunking?: DocsSearchChunkingConfig;
1414
+ }
1415
+ interface AlgoliaDocsSearchConfig {
1416
+ provider: "algolia";
1417
+ enabled?: boolean;
1418
+ appId: string;
1419
+ indexName: string;
1420
+ searchApiKey: string;
1421
+ adminApiKey?: string;
1422
+ maxResults?: number;
1423
+ syncOnSearch?: boolean;
1424
+ chunking?: DocsSearchChunkingConfig;
1425
+ }
1426
+ interface TypesenseDocsSearchConfig {
1427
+ provider: "typesense";
1428
+ enabled?: boolean;
1429
+ baseUrl: string;
1430
+ collection: string;
1431
+ apiKey: string;
1432
+ adminApiKey?: string;
1433
+ maxResults?: number;
1434
+ syncOnSearch?: boolean;
1435
+ queryBy?: string[];
1436
+ mode?: "keyword" | "hybrid";
1437
+ embeddings?: DocsSearchEmbeddingsConfig;
1438
+ chunking?: DocsSearchChunkingConfig;
1439
+ }
1440
+ interface McpDocsSearchConfig {
1441
+ provider: "mcp";
1442
+ enabled?: boolean;
1443
+ /**
1444
+ * Streamable HTTP MCP endpoint. Relative paths like `/mcp` or `/.well-known/mcp`
1445
+ * are resolved against the current docs API request URL.
1446
+ */
1447
+ endpoint: string;
1448
+ /**
1449
+ * Optional extra headers passed to the MCP endpoint on initialize/tool calls.
1450
+ */
1451
+ headers?: Record<string, string>;
1452
+ /**
1453
+ * MCP tool name used for search. Defaults to `search_docs`.
1454
+ */
1455
+ toolName?: string;
1456
+ /**
1457
+ * Forward the resolved human/agent projection as the tool's `audience` argument.
1458
+ * HTTP request resolution enables this for same-origin `search_docs` routes.
1459
+ * Remote and custom tools must opt in explicitly after supporting the argument.
1460
+ */
1461
+ forwardAudience?: boolean;
1462
+ /**
1463
+ * Override the MCP protocol version header when needed.
1464
+ */
1465
+ protocolVersion?: string;
1466
+ maxResults?: number;
1467
+ chunking?: DocsSearchChunkingConfig;
1468
+ }
1469
+ type DocsAskAIMcpConfig = Omit<McpDocsSearchConfig, "provider"> & {
1470
+ provider?: "mcp";
1471
+ };
1472
+ interface CustomDocsSearchConfig {
1473
+ provider: "custom";
1474
+ enabled?: boolean;
1475
+ adapter: DocsSearchAdapter | DocsSearchAdapterFactory;
1476
+ maxResults?: number;
1477
+ chunking?: DocsSearchChunkingConfig;
1478
+ }
1479
+ type DocsSearchConfig = SimpleDocsSearchConfig | AlgoliaDocsSearchConfig | McpDocsSearchConfig | TypesenseDocsSearchConfig | CustomDocsSearchConfig;
1480
+ interface LastUpdatedConfig {
1481
+ /**
1482
+ * Whether to show the "Last updated" date.
1483
+ * @default true
1484
+ */
1485
+ enabled?: boolean;
1486
+ /**
1487
+ * Label shown before the formatted date.
1488
+ * @default "Last updated"
1489
+ */
1490
+ label?: string;
1491
+ /**
1492
+ * Where to render the "Last updated" date.
1493
+ *
1494
+ * - `"footer"` — next to the "Edit on GitHub" link at the bottom (default)
1495
+ * - `"below-title"` — below the page title/description, above the content
1496
+ *
1497
+ * @default "footer"
1498
+ */
1499
+ position?: "footer" | "below-title";
1500
+ }
1501
+ type ReadingTimeFormat = "long" | "short";
1502
+ /**
1503
+ * Configuration for estimated page reading time.
1504
+ *
1505
+ * @example
1506
+ * ```ts
1507
+ * readingTime: { enabled: true, wordsPerMinute: 220 }
1508
+ * ```
1509
+ */
1510
+ interface ReadingTimeConfig {
1511
+ /**
1512
+ * Whether to show the estimated reading time.
1513
+ * @default true
1514
+ */
1515
+ enabled?: boolean;
1516
+ /**
1517
+ * Words-per-minute rate used for the estimate.
1518
+ * @default 220
1519
+ */
1520
+ wordsPerMinute?: number;
1521
+ /**
1522
+ * Label style used when rendering the reading-time estimate.
1523
+ *
1524
+ * `"long"` renders labels like `3 min read`; `"short"` renders `3 min`.
1525
+ *
1526
+ * @default "long"
1527
+ */
1528
+ format?: ReadingTimeFormat;
1529
+ /**
1530
+ * Whether fenced and inline code should count toward the estimate.
1531
+ *
1532
+ * Code is ignored by default so the label reflects human prose. Set this to
1533
+ * `true` when code-heavy guides should include examples in the estimate.
1534
+ *
1535
+ * @default false
1536
+ */
1537
+ includeCode?: boolean;
1538
+ }
1539
+ /**
1540
+ * GitHub repository configuration for "Edit on GitHub" links
1541
+ * and source file references.
1542
+ *
1543
+ * @example
1544
+ * ```ts
1545
+ * // Simple repo (not a monorepo)
1546
+ * github: {
1547
+ * url: "https://github.com/Kinfe123/my-docs",
1548
+ * }
1549
+ *
1550
+ * // Monorepo — docs site lives in "website/" subdirectory
1551
+ * github: {
1552
+ * url: "https://github.com/farming-labs/docs",
1553
+ * directory: "website",
1554
+ * branch: "main",
1555
+ * }
1556
+ * ```
1557
+ *
1558
+ * Or as a simple string (branch defaults to "main", no directory prefix):
1559
+ * ```ts
1560
+ * github: "https://github.com/Kinfe123/my-docs"
1561
+ * ```
1562
+ */
1563
+ interface GithubConfig {
1564
+ /** Repository URL (e.g. "https://github.com/farming-labs/docs") */
1565
+ url: string;
1566
+ /** Branch name. @default "main" */
1567
+ branch?: string;
1568
+ /**
1569
+ * Subdirectory inside the repo where the docs site lives.
1570
+ * Use this for monorepos where the docs app is not at the repo root.
1571
+ *
1572
+ * @example "website" → links point to `website/app/docs/…/page.mdx`
1573
+ */
1574
+ directory?: string;
1575
+ }
1576
+ type DocsAskAIFeedbackValue = "like" | "dislike";
1577
+ type DocsAskAIActionType = "copy" | DocsAskAIFeedbackValue;
1578
+ interface DocsAskAIFeedbackMessage {
1579
+ role: "user" | "assistant";
1580
+ content: string;
1581
+ }
1582
+ interface DocsAskAIActionData {
1583
+ type: DocsAskAIActionType;
1584
+ value?: DocsAskAIFeedbackValue;
1585
+ question: string;
1586
+ answer: string;
1587
+ messageId?: string;
1588
+ messageIndex?: number;
1589
+ model?: string;
1590
+ surface?: string;
1591
+ url?: string;
1592
+ path?: string;
1593
+ messages?: DocsAskAIFeedbackMessage[];
1594
+ copied?: boolean;
1595
+ }
1596
+ interface DocsAskAIFeedbackData {
1597
+ value: DocsAskAIFeedbackValue;
1598
+ question: string;
1599
+ answer: string;
1600
+ messageId?: string;
1601
+ messageIndex?: number;
1602
+ model?: string;
1603
+ surface?: string;
1604
+ url?: string;
1605
+ path?: string;
1606
+ messages?: DocsAskAIFeedbackMessage[];
1607
+ }
1608
+ interface DocsAskAIFeedbackConfig {
1609
+ /**
1610
+ * Whether to show the copy, like, and dislike action row after each completed Ask AI answer.
1611
+ * @default true
1612
+ */
1613
+ enabled?: boolean;
1614
+ /** Label for the positive rating button. @default "Helpful" */
1615
+ positiveLabel?: string;
1616
+ /** Label for the negative rating button. @default "Not helpful" */
1617
+ negativeLabel?: string;
1618
+ /** Called when a user rates an Ask AI response. */
1619
+ onFeedback?: (data: DocsAskAIFeedbackData) => void | Promise<void>;
1620
+ }
1621
+ /**
1622
+ * Configuration for "Ask AI" — a RAG-powered chat that lets users
1623
+ * ask questions about the documentation content.
1624
+ *
1625
+ * The AI handler searches relevant doc pages, builds context, and
1626
+ * streams a response from an LLM (OpenAI-compatible API).
1627
+ *
1628
+ * The API key is **never** stored in the config. It is read from the
1629
+ * `OPENAI_API_KEY` environment variable at runtime on the server.
1630
+ *
1631
+ * @example
1632
+ * ```ts
1633
+ * ai: {
1634
+ * enabled: true,
1635
+ * model: "gpt-4o-mini",
1636
+ * systemPrompt: "You are a helpful assistant for our developer docs.",
1637
+ * }
1638
+ * ```
1639
+ */
1640
+ interface AIConfig {
1641
+ /**
1642
+ * Whether to enable "Ask AI" functionality.
1643
+ * When enabled, the unified `/api/docs` route handler will accept
1644
+ * POST requests for AI chat.
1645
+ * @default false
1646
+ */
1647
+ enabled?: boolean;
1648
+ /**
1649
+ * How the AI chat UI is presented.
1650
+ *
1651
+ * - `"search"` — AI tab integrated into the Cmd+K search dialog (default)
1652
+ * - `"floating"` — A floating chat widget (bubble button + slide-out panel)
1653
+ *
1654
+ * @default "search"
1655
+ *
1656
+ * @example
1657
+ * ```ts
1658
+ * // Floating chat bubble in the bottom-right corner
1659
+ * ai: {
1660
+ * enabled: true,
1661
+ * mode: "floating",
1662
+ * position: "bottom-right",
1663
+ * }
1664
+ * ```
1665
+ */
1666
+ mode?: "search" | "floating" | "sidebar-icon";
1667
+ /**
1668
+ * Position of the floating chat button on screen.
1669
+ * Only used when `mode` is `"floating"`.
1670
+ *
1671
+ * - `"bottom-right"` — bottom-right corner (default)
1672
+ * - `"bottom-left"` — bottom-left corner
1673
+ * - `"bottom-center"` — bottom center
1674
+ *
1675
+ * @default "bottom-right"
1676
+ */
1677
+ position?: "bottom-right" | "bottom-left" | "bottom-center";
1678
+ /**
1679
+ * Visual style of the floating chat when opened.
1680
+ * Only used when `mode` is `"floating"`.
1681
+ *
1682
+ * - `"panel"` — A tall panel that slides up from the button position (default).
1683
+ * Stays anchored near the floating button. No backdrop overlay.
1684
+ *
1685
+ * - `"modal"` — A centered modal dialog with a backdrop overlay,
1686
+ * similar to the Cmd+K search dialog. Feels more focused and immersive.
1687
+ *
1688
+ * - `"popover"` — A compact popover near the button. Smaller than the
1689
+ * panel, suitable for quick questions without taking much screen space.
1690
+ *
1691
+ * - `"full-modal"` — A full-screen immersive overlay (inspired by better-auth).
1692
+ * Messages scroll in the center, input is pinned at the bottom.
1693
+ * Suggested questions appear as horizontal pills. Best for
1694
+ * documentation-heavy sites that want a premium AI experience.
1695
+ *
1696
+ * @default "panel"
1697
+ *
1698
+ * @example
1699
+ * ```ts
1700
+ * ai: {
1701
+ * enabled: true,
1702
+ * mode: "floating",
1703
+ * position: "bottom-right",
1704
+ * floatingStyle: "full-modal",
1705
+ * }
1706
+ * ```
1707
+ */
1708
+ floatingStyle?: "panel" | "modal" | "popover" | "full-modal";
1709
+ /**
1710
+ * Custom trigger component for the floating chat button (Next.js only).
1711
+ * Only used when `mode` is `"floating"`.
1712
+ *
1713
+ * The click handler is attached automatically by the wrapper.
1714
+ *
1715
+ * - **Next.js**: Pass a JSX element via this config option.
1716
+ * - **SvelteKit**: Use the `aiTrigger` snippet on `<DocsLayout>`.
1717
+ * - **Nuxt / Vue**: Use the `ai-trigger` slot on `<DocsLayout>`.
1718
+ * - **Astro**: Use `<MyTrigger slot="ai-trigger" />` on `<DocsLayout>`.
1719
+ *
1720
+ * @example
1721
+ * ```tsx
1722
+ * // Next.js — pass JSX directly in config
1723
+ * triggerComponent: <button className="my-chat-btn">Ask AI</button>,
1724
+ * ```
1725
+ *
1726
+ * ```svelte
1727
+ * <!-- SvelteKit — use snippet in layout -->
1728
+ * <DocsLayout {tree} {config}>
1729
+ * {#snippet aiTrigger()}<AskAITrigger />{/snippet}
1730
+ * {@render children()}
1731
+ * </DocsLayout>
1732
+ * ```
1733
+ *
1734
+ * ```vue
1735
+ * <!-- Nuxt / Vue — use named slot in layout -->
1736
+ * <DocsLayout :tree="tree" :config="config">
1737
+ * <template #ai-trigger><AskAITrigger /></template>
1738
+ * <DocsContent />
1739
+ * </DocsLayout>
1740
+ * ```
1741
+ *
1742
+ * ```astro
1743
+ * <!-- Astro — use named slot in layout -->
1744
+ * <DocsLayout tree={tree} config={config}>
1745
+ * <AskAITrigger slot="ai-trigger" />
1746
+ * <DocsContent />
1747
+ * </DocsLayout>
1748
+ * ```
1749
+ */
1750
+ triggerComponent?: unknown;
1751
+ /**
1752
+ * Server-side answer provider used by Ask AI.
1753
+ *
1754
+ * - `"docs-cloud"` — send questions to the configured Docs Cloud project
1755
+ * using `PUBLIC_DOCS_CLOUD_PROJECT_ID` and a browser-safe
1756
+ * Docs Cloud API key env such as `PUBLIC_DOCS_CLOUD_API_KEY`.
1757
+ * If only a server-side key is configured, framework integrations may
1758
+ * proxy through the local docs API route.
1759
+ * - Omit this option to use the built-in OpenAI-compatible RAG handler.
1760
+ *
1761
+ * @example
1762
+ * ```ts
1763
+ * ai: {
1764
+ * enabled: true,
1765
+ * provider: "docs-cloud",
1766
+ * }
1767
+ * ```
1768
+ */
1769
+ provider?: "docs-cloud" | (string & {});
1770
+ /**
1771
+ * Whether Ask AI should request streaming responses when the selected
1772
+ * provider supports them.
1773
+ *
1774
+ * Docs Cloud streams token deltas by default for `provider: "docs-cloud"`.
1775
+ * Set this to `false` to request a single JSON answer instead.
1776
+ *
1777
+ * @default true
1778
+ */
1779
+ stream?: boolean;
1780
+ /**
1781
+ * The LLM model configuration.
1782
+ *
1783
+ * **Simple** — pass a plain string for a single model:
1784
+ * ```ts
1785
+ * model: "gpt-4o-mini"
1786
+ * ```
1787
+ *
1788
+ * **Advanced** — pass an object with multiple selectable models and an
1789
+ * optional `provider` key that references a named provider in `providers`:
1790
+ * ```ts
1791
+ * model: {
1792
+ * models: [
1793
+ * { id: "gpt-4o-mini", label: "GPT-4o mini (fast)", provider: "openai" },
1794
+ * { id: "llama-3.3-70b-versatile", label: "Llama 3.3 70B", provider: "groq" },
1795
+ * ],
1796
+ * defaultModel: "gpt-4o-mini",
1797
+ * }
1798
+ * ```
1799
+ *
1800
+ * When an object is provided, a model selector dropdown appears in the
1801
+ * AI chat interface.
1802
+ *
1803
+ * @default "gpt-4o-mini"
1804
+ */
1805
+ model?: string | {
1806
+ models: {
1807
+ id: string;
1808
+ label: string;
1809
+ provider?: string;
1810
+ }[];
1811
+ defaultModel?: string;
1812
+ };
1813
+ /**
1814
+ * Named provider configurations for multi-provider setups.
1815
+ *
1816
+ * Each key is a provider name referenced by `model.models[].provider`.
1817
+ * Each value contains a `baseUrl` and optional `apiKey`.
1818
+ *
1819
+ * @example
1820
+ * ```ts
1821
+ * providers: {
1822
+ * openai: {
1823
+ * baseUrl: "https://api.openai.com/v1",
1824
+ * apiKey: process.env.OPENAI_API_KEY,
1825
+ * },
1826
+ * groq: {
1827
+ * baseUrl: "https://api.groq.com/openai/v1",
1828
+ * apiKey: process.env.GROQ_API_KEY,
1829
+ * },
1830
+ * }
1831
+ * ```
1832
+ */
1833
+ providers?: Record<string, {
1834
+ baseUrl: string;
1835
+ apiKey?: string;
1836
+ }>;
1837
+ /**
1838
+ * Custom system prompt prepended to the AI conversation.
1839
+ * The documentation context is automatically appended after this prompt.
1840
+ *
1841
+ * @default "You are a helpful documentation assistant. Answer questions
1842
+ * based on the provided documentation context. Be concise and accurate.
1843
+ * If the answer is not in the context, say so honestly."
1844
+ */
1845
+ systemPrompt?: string;
1846
+ /**
1847
+ * Default base URL for an OpenAI-compatible API endpoint.
1848
+ * Used when no per-model `provider` is configured.
1849
+ * @default "https://api.openai.com/v1"
1850
+ */
1851
+ baseUrl?: string;
1852
+ /**
1853
+ * Default API key for the LLM provider.
1854
+ * Used when no per-model `provider` is configured.
1855
+ * Falls back to `process.env.OPENAI_API_KEY` if not set.
1856
+ *
1857
+ * @default process.env.OPENAI_API_KEY
1858
+ *
1859
+ * @example
1860
+ * ```ts
1861
+ * // Default — reads OPENAI_API_KEY automatically
1862
+ * ai: { enabled: true }
1863
+ *
1864
+ * // Custom provider key
1865
+ * ai: {
1866
+ * enabled: true,
1867
+ * apiKey: process.env.GROQ_API_KEY,
1868
+ * }
1869
+ * ```
1870
+ */
1871
+ apiKey?: string;
1872
+ /**
1873
+ * Maximum number of search results to include as context for the AI.
1874
+ * More results = more context but higher token usage.
1875
+ * @default 5
1876
+ */
1877
+ maxResults?: number;
1878
+ /**
1879
+ * Route Ask AI retrieval through the configured MCP `search_docs` tool.
1880
+ *
1881
+ * - `true` uses the MCP server this docs site already exposes at `mcp.route`
1882
+ * (default `/api/docs/mcp`)
1883
+ * - an object can point Ask AI at another Streamable HTTP MCP endpoint
1884
+ *
1885
+ * This only affects Ask AI retrieval. The normal docs search API still uses
1886
+ * the top-level `search` config.
1887
+ *
1888
+ * @default false
1889
+ *
1890
+ * @example
1891
+ * ```ts
1892
+ * ai: {
1893
+ * enabled: true,
1894
+ * useMcp: true,
1895
+ * }
1896
+ * ```
1897
+ */
1898
+ useMcp?: boolean | DocsAskAIMcpConfig;
1899
+ /**
1900
+ * Pre-filled suggested questions shown in the AI chat when empty.
1901
+ * When a user clicks one, it fills the input and submits automatically.
1902
+ *
1903
+ * @example
1904
+ * ```ts
1905
+ * ai: {
1906
+ * enabled: true,
1907
+ * suggestedQuestions: [
1908
+ * "How do I install this?",
1909
+ * "What themes are available?",
1910
+ * "How do I create a custom component?",
1911
+ * ],
1912
+ * }
1913
+ * ```
1914
+ */
1915
+ suggestedQuestions?: string[];
1916
+ /**
1917
+ * Display name for the AI assistant in the chat UI.
1918
+ * Shown as the message label, header title, and passed to the loading component.
1919
+ *
1920
+ * @default "AI"
1921
+ *
1922
+ * @example
1923
+ * ```ts
1924
+ * ai: {
1925
+ * enabled: true,
1926
+ * aiLabel: "DocsBot",
1927
+ * }
1928
+ * ```
1929
+ */
1930
+ aiLabel?: string;
1931
+ /**
1932
+ * Optional npm package-name override used in import examples.
1933
+ * Ask AI normally infers package names and exact imports from retrieved docs context.
1934
+ *
1935
+ * @example
1936
+ * ```ts
1937
+ * ai: {
1938
+ * enabled: true,
1939
+ * packageName: "@farming-labs/docs",
1940
+ * }
1941
+ * ```
1942
+ */
1943
+ packageName?: string;
1944
+ /**
1945
+ * The public URL of the documentation site.
1946
+ * The AI will use this for links instead of relative paths.
1947
+ *
1948
+ * @example
1949
+ * ```ts
1950
+ * ai: {
1951
+ * enabled: true,
1952
+ * docsUrl: "https://docs.farming-labs.dev",
1953
+ * }
1954
+ * ```
1955
+ */
1956
+ docsUrl?: string;
1957
+ /**
1958
+ * Loading indicator variant shown while the AI generates a response.
1959
+ *
1960
+ * - `"shimmer-dots"` — shimmer text + typing dots (default)
1961
+ * - `"circular"` — spinning ring
1962
+ * - `"dots"` — bouncing dots
1963
+ * - `"typing"` — typing dots
1964
+ * - `"wave"` — wave bars
1965
+ * - `"bars"` — thick wave bars
1966
+ * - `"pulse"` — pulsing ring
1967
+ * - `"pulse-dot"` — pulsing dot
1968
+ * - `"terminal"` — blinking terminal cursor
1969
+ * - `"text-blink"` — blinking text
1970
+ * - `"text-shimmer"` — shimmer text only
1971
+ * - `"loading-dots"` — "Thinking..." with animated dots
1972
+ *
1973
+ * @default "shimmer-dots"
1974
+ *
1975
+ * @example
1976
+ * ```ts
1977
+ * ai: {
1978
+ * enabled: true,
1979
+ * loader: "wave",
1980
+ * }
1981
+ * ```
1982
+ */
1983
+ loader?: "shimmer-dots" | "circular" | "dots" | "typing" | "wave" | "bars" | "pulse" | "pulse-dot" | "terminal" | "text-blink" | "text-shimmer" | "loading-dots";
1984
+ /**
1985
+ * Custom loading indicator that overrides the built-in `loader` variant.
1986
+ * Receives `{ name }` (the `aiLabel` value) and returns a React element.
1987
+ *
1988
+ * Only works in Next.js. For other frameworks, use the `loader` option.
1989
+ *
1990
+ * @example
1991
+ * ```tsx
1992
+ * ai: {
1993
+ * enabled: true,
1994
+ * aiLabel: "Sage",
1995
+ * loadingComponent: ({ name }) => (
1996
+ * <div className="flex items-center gap-2 text-sm text-zinc-400">
1997
+ * <span className="animate-pulse">🤔</span>
1998
+ * <span>{name} is thinking...</span>
1999
+ * </div>
2000
+ * ),
2001
+ * }
2002
+ * ```
2003
+ */
2004
+ loadingComponent?: (props: {
2005
+ name: string;
2006
+ }) => unknown;
2007
+ /**
2008
+ * Copy, like, and dislike action row for generated Ask AI answers.
2009
+ *
2010
+ * Set to `false` to hide the row. Pass an object to customize rating labels
2011
+ * and receive legacy like/dislike callback payloads.
2012
+ *
2013
+ * @default true
2014
+ *
2015
+ * @example
2016
+ * ```ts
2017
+ * ai: {
2018
+ * enabled: true,
2019
+ * feedback: {
2020
+ * onFeedback(data) {
2021
+ * console.log(data.value, data.question, data.answer);
2022
+ * },
2023
+ * },
2024
+ * }
2025
+ * ```
2026
+ */
2027
+ feedback?: boolean | DocsAskAIFeedbackConfig;
2028
+ /**
2029
+ * Called when a user clicks an Ask AI response action.
2030
+ *
2031
+ * `data.type` is `"copy"`, `"like"`, or `"dislike"`.
2032
+ *
2033
+ * @example
2034
+ * ```ts
2035
+ * ai: {
2036
+ * enabled: true,
2037
+ * onActions(data) {
2038
+ * if (data.type === "copy") console.log("Copied", data.answer);
2039
+ * if (data.type === "like") console.log("Helpful", data.question);
2040
+ * if (data.type === "dislike") console.log("Not helpful", data.question);
2041
+ * },
2042
+ * }
2043
+ * ```
2044
+ */
2045
+ onActions?: (data: DocsAskAIActionData) => void | Promise<void>;
2046
+ }
2047
+ /**
2048
+ * A single item in the slug-based sidebar ordering.
2049
+ *
2050
+ * @example
2051
+ * ```ts
2052
+ * ordering: [
2053
+ * { slug: "installation" },
2054
+ * { slug: "cli" },
2055
+ * { slug: "themes", children: [
2056
+ * { slug: "default" },
2057
+ * { slug: "darksharp" },
2058
+ * { slug: "pixel-border" },
2059
+ * { slug: "creating-themes" },
2060
+ * ]},
2061
+ * { slug: "reference" },
2062
+ * ]
2063
+ * ```
2064
+ */
2065
+ interface OrderingItem {
2066
+ /** Folder name (not the full path, just the directory name at this level) */
2067
+ slug: string;
2068
+ /** Ordering for child pages within this folder */
2069
+ children?: OrderingItem[];
2070
+ }
2071
+ /**
2072
+ * Data passed to the `onCopyClick` callback when the user clicks the copy button
2073
+ * on a code block in the docs.
2074
+ */
2075
+ interface CodeBlockCopyData {
2076
+ /** Title of the code block (e.g. from the fenced code block meta string), if present */
2077
+ title?: string;
2078
+ /** Raw code content (the text that was copied to the clipboard) */
2079
+ content: string;
2080
+ /** Current page URL at the time of copy */
2081
+ url: string;
2082
+ /** Language / syntax hint (e.g. "tsx", "bash"), if present */
2083
+ language?: string;
2084
+ }
2085
+ /** Feedback value emitted by the built-in docs page feedback buttons. */
2086
+ type DocsFeedbackValue = "positive" | "negative";
2087
+ /**
2088
+ * Data passed to the `feedback.onFeedback` callback when the user submits
2089
+ * page feedback from the built-in docs feedback UI.
2090
+ */
2091
+ interface DocsFeedbackData {
2092
+ /** Whether the user gave positive or negative feedback. */
2093
+ value: DocsFeedbackValue;
2094
+ /** Optional free-form feedback left by the reader. */
2095
+ comment?: string;
2096
+ /** Current page title, when available. */
2097
+ title?: string;
2098
+ /** Current page description, when available. */
2099
+ description?: string;
2100
+ /** Full current page URL at the time of feedback. */
2101
+ url: string;
2102
+ /** Current URL pathname (without origin). */
2103
+ pathname: string;
2104
+ /** Alias of `pathname` for analytics tools that prefer `path`. */
2105
+ path: string;
2106
+ /** Docs entry root, e.g. `"docs"`. */
2107
+ entry: string;
2108
+ /** Page slug relative to the docs entry, e.g. `"installation"` or `"guides/setup"`. */
2109
+ slug: string;
2110
+ /** Active locale, when docs i18n is enabled. */
2111
+ locale?: string;
2112
+ }
2113
+ /**
2114
+ * Page and transport context supplied alongside agent feedback payloads.
2115
+ *
2116
+ * The `payload` itself is customizable through `feedback.agent.schema`; this
2117
+ * context object keeps a small stable envelope for route-aware metadata.
2118
+ */
2119
+ interface DocsAgentFeedbackContext {
2120
+ /** Docs page path, e.g. `"/docs/installation"`. */
2121
+ page?: string;
2122
+ /** Full docs URL, when the caller has one available. */
2123
+ url?: string;
2124
+ /** Docs slug relative to the entry root, e.g. `"installation"`. */
2125
+ slug?: string;
2126
+ /** Active locale when docs i18n is enabled. */
2127
+ locale?: string;
2128
+ /** Arbitrary source label such as `"md-route"`, `"mcp"`, or `"api"`. */
2129
+ source?: string;
2130
+ }
2131
+ /**
2132
+ * Data passed to `feedback.agent.onFeedback`.
2133
+ *
2134
+ * The request body always follows the stable `{ context?, payload }` envelope
2135
+ * while `payload` stays schema-driven so projects can add or remove agent
2136
+ * fields without changing the callback contract.
2137
+ */
2138
+ interface DocsAgentFeedbackData {
2139
+ /** Optional docs/page context associated with the agent feedback. */
2140
+ context?: DocsAgentFeedbackContext;
2141
+ /** Arbitrary payload validated by the configured agent feedback schema. */
2142
+ payload: Record<string, unknown>;
2143
+ }
2144
+ /**
2145
+ * Agent feedback endpoint configuration served through the shared `/api/docs`
2146
+ * route wrapper.
2147
+ */
2148
+ interface AgentFeedbackConfig {
2149
+ /** Enable the agent feedback endpoints. Defaults to `true`; set to `false` to opt out. */
2150
+ enabled?: boolean;
2151
+ /**
2152
+ * Public HTTP route for posting agent feedback.
2153
+ * @default "/api/docs/agent/feedback"
2154
+ */
2155
+ route?: string;
2156
+ /**
2157
+ * Public HTTP route for the machine-readable schema describing the agent
2158
+ * feedback payload.
2159
+ *
2160
+ * Defaults to `${route}/schema`.
2161
+ */
2162
+ schemaRoute?: string;
2163
+ /**
2164
+ * JSON Schema object describing the `payload` field of the request body.
2165
+ *
2166
+ * The shared docs API wraps this under a stable top-level envelope:
2167
+ * `{ context?: DocsAgentFeedbackContext, payload: <schema> }`.
2168
+ */
2169
+ schema?: Record<string, unknown>;
2170
+ /**
2171
+ * Async callback fired when the agent feedback endpoint receives a valid
2172
+ * `{ context?, payload }` body.
2173
+ */
2174
+ onFeedback?: (data: DocsAgentFeedbackData) => void | Promise<void>;
2175
+ }
2176
+ /**
2177
+ * Built-in page feedback configuration.
2178
+ *
2179
+ * When enabled, docs pages render a small feedback prompt at the end of the
2180
+ * content. Clicking a button emits a callback/event with the current page
2181
+ * metadata and the selected sentiment.
2182
+ */
2183
+ interface FeedbackConfig {
2184
+ /** Show the feedback UI. Defaults to `true` when this object is provided. */
2185
+ enabled?: boolean;
2186
+ /** Prompt shown above the feedback buttons. @default "How is this guide?" */
2187
+ question?: string;
2188
+ /** Placeholder shown in the optional free-form feedback field. @default "Share what could be clearer..." */
2189
+ placeholder?: string;
2190
+ /** Require a non-empty comment before feedback can be submitted. @default false */
2191
+ requireComment?: boolean;
2192
+ /** Label for the positive button. @default "Good" */
2193
+ positiveLabel?: string;
2194
+ /** Label for the negative button. @default "Bad" */
2195
+ negativeLabel?: string;
2196
+ /** Label for the submit button. @default "Submit" */
2197
+ submitLabel?: string;
2198
+ /** Message shown after feedback is submitted successfully. @default "Thanks for the feedback." */
2199
+ successMessage?: string;
2200
+ /** Message shown when feedback submission fails. @default "Could not send feedback. Please try again." */
2201
+ errorMessage?: string;
2202
+ /**
2203
+ * Callback fired when the user submits the feedback form.
2204
+ *
2205
+ * For client-only frameworks this runs directly in the browser. In
2206
+ * environments where the config cannot be serialized to the client, the same
2207
+ * payload is also emitted through `window.__fdOnFeedback__` and the
2208
+ * `fd:feedback` custom event.
2209
+ */
2210
+ onFeedback?: (data: DocsFeedbackData) => void | Promise<void>;
2211
+ /**
2212
+ * Machine-oriented feedback endpoints exposed through the shared `/api/docs`
2213
+ * route. The shared docs API exposes the default no-op schema/submit routes
2214
+ * unless this is set to `false`.
2215
+ *
2216
+ * This does not enable the human page feedback UI by itself. To show the
2217
+ * built-in footer prompt, keep using `feedback: true` or `feedback.enabled`.
2218
+ */
2219
+ agent?: boolean | AgentFeedbackConfig;
2220
+ }
2221
+ interface DocsI18nConfig {
2222
+ /** Supported locale identifiers (e.g. ["en", "fr"]). */
2223
+ locales: string[];
2224
+ /** Default locale when `?lang=` is missing or invalid. Defaults to first locale. */
2225
+ defaultLocale?: string;
2226
+ }
2227
+ interface ChangelogFrontmatter {
2228
+ /** Entry title shown in the changelog feed and detail page. */
2229
+ title?: string;
2230
+ /** Short summary shown in the feed and page metadata. */
2231
+ description?: string;
2232
+ /** Optional cover image path or URL for future custom changelog layouts. */
2233
+ image?: string;
2234
+ /** Optional author name(s) displayed in entry meta. */
2235
+ authors?: string | string[];
2236
+ /** Optional version badge (for example `v0.1.0`). */
2237
+ version?: string;
2238
+ /** Optional tags shown as compact badges. */
2239
+ tags?: string[];
2240
+ /** Keep important entries pinned to the top of the listing. */
2241
+ pinned?: boolean;
2242
+ /** Hide the entry from generated routes and search indexes. */
2243
+ draft?: boolean;
2244
+ }
2245
+ interface ChangelogConfig {
2246
+ /**
2247
+ * Whether to enable generated changelog pages.
2248
+ * @default false
2249
+ */
2250
+ enabled?: boolean;
2251
+ /**
2252
+ * URL path where the changelog listing lives inside the docs layout.
2253
+ * Example: `"changelogs"` → `/docs/changelogs` when `entry` is `"docs"`
2254
+ * @default "changelog"
2255
+ */
2256
+ path?: string;
2257
+ /**
2258
+ * Changelog source directory inside the docs content root.
2259
+ *
2260
+ * With the default docs content tree, this becomes:
2261
+ * `app/docs/changelog/2026-03-04/page.mdx`
2262
+ *
2263
+ * Relative values are resolved from the docs content root. Absolute values
2264
+ * are used as-is.
2265
+ *
2266
+ * @default "changelog"
2267
+ */
2268
+ contentDir?: string;
2269
+ /**
2270
+ * Listing page title.
2271
+ * @default "Changelog"
2272
+ */
2273
+ title?: string;
2274
+ /**
2275
+ * Listing page description shown in the changelog header and metadata.
2276
+ */
2277
+ description?: string;
2278
+ /**
2279
+ * Show the built-in changelog search field.
2280
+ * @default true
2281
+ */
2282
+ search?: boolean;
2283
+ /**
2284
+ * Custom React element rendered in the changelog rail.
2285
+ *
2286
+ * This stays `unknown` in the framework-agnostic core so adapters can accept
2287
+ * JSX without adding a React dependency here.
2288
+ */
2289
+ actionsComponent?: unknown;
2290
+ }
2291
+ type ApiReferenceRenderer = "fumadocs" | "scalar";
2292
+ interface ApiReferenceConfig {
2293
+ /**
2294
+ * Whether to enable generated API reference pages.
2295
+ * Supported adapters can generate references from framework route handlers
2296
+ * or a hosted OpenAPI JSON document.
2297
+ * @default false
2298
+ */
2299
+ enabled?: boolean;
2300
+ /**
2301
+ * URL path where the generated API reference lives.
2302
+ * Example: `"api-reference"` → `/api-reference`
2303
+ * @default "api-reference"
2304
+ */
2305
+ path?: string;
2306
+ /**
2307
+ * URL to a remote OpenAPI JSON document.
2308
+ *
2309
+ * When provided, the API reference is generated from this hosted spec instead
2310
+ * of scanning local framework route files.
2311
+ *
2312
+ * Supports:
2313
+ * - absolute URLs like `https://example.com/openapi.json`
2314
+ * - request-relative URLs like `/api/openapi.json` in Next.js
2315
+ *
2316
+ * @example
2317
+ * ```ts
2318
+ * apiReference: {
2319
+ * enabled: true,
2320
+ * specUrl: "https://petstore3.swagger.io/api/v3/openapi.json",
2321
+ * }
2322
+ * ```
2323
+ */
2324
+ specUrl?: string;
2325
+ /**
2326
+ * Which renderer to use for the API reference UI.
2327
+ *
2328
+ * - `"fumadocs"` uses the Fumadocs OpenAPI renderer bundled by `@farming-labs/next`
2329
+ * - `"scalar"` uses the Scalar renderer bundled by `@farming-labs/docs` and the adapters
2330
+ *
2331
+ * Defaults are framework-aware:
2332
+ * - Next.js: `"fumadocs"`
2333
+ * - TanStack Start / SvelteKit / Astro / Nuxt: `"scalar"`
2334
+ */
2335
+ renderer?: ApiReferenceRenderer;
2336
+ /**
2337
+ * Filesystem route root to scan for API handlers.
2338
+ *
2339
+ * For Next.js this defaults to the App Router convention:
2340
+ * `app/api` or `src/app/api`.
2341
+ *
2342
+ * You can override it with a project-relative path like `"app/v1"` or
2343
+ * `"src/app/internal-api"`. If you pass a bare segment like `"api"` or
2344
+ * `"v1"`, it will be resolved inside the detected app directory.
2345
+ */
2346
+ routeRoot?: string;
2347
+ /**
2348
+ * Route entries to exclude from the generated API reference.
2349
+ *
2350
+ * Accepts either URL-style paths like `"/api/hello"` or route-root-relative
2351
+ * entries like `"hello"` / `"hello/route.ts"`.
2352
+ */
2353
+ exclude?: string[];
2354
+ }
2355
+ interface DocsAgentCompactConfig {
2356
+ /**
2357
+ * Direct API key for the Docs Cloud compression API. Prefer `cloud.apiKey.env`
2358
+ * so all Docs Cloud CLI commands share the same root API key configuration.
2359
+ *
2360
+ * @deprecated Configure `cloud.apiKey.env` instead.
2361
+ */
2362
+ apiKey?: string;
2363
+ /**
2364
+ * Environment variable name that stores the Docs Cloud API key. Prefer
2365
+ * `cloud.apiKey.env` so all Docs Cloud CLI commands share the same root API
2366
+ * key configuration.
2367
+ *
2368
+ * @deprecated Configure `cloud.apiKey.env` instead.
2369
+ */
2370
+ apiKeyEnv?: string;
2371
+ /**
2372
+ * Base URL for the compression API.
2373
+ */
2374
+ baseUrl?: string;
2375
+ /**
2376
+ * Compression model name.
2377
+ * @default "docs-cloud-compress-v1"
2378
+ */
2379
+ model?: string;
2380
+ /**
2381
+ * Compression aggressiveness passed to the API.
2382
+ * Must be between `0` and `1`.
2383
+ * @default 0.3
2384
+ */
2385
+ aggressiveness?: number;
2386
+ /**
2387
+ * Upper token target for compressed output.
2388
+ */
2389
+ maxOutputTokens?: number;
2390
+ /**
2391
+ * Lower token target for compressed output.
2392
+ */
2393
+ minOutputTokens?: number;
2394
+ /**
2395
+ * Preserve JSON objects during compression when supported by the provider.
2396
+ */
2397
+ protectJson?: boolean;
2398
+ }
2399
+ interface DocsAgentGoldenTaskFilters {
2400
+ /** Limit retrieval to a framework such as `nextjs`, `astro`, or `nuxt`. */
2401
+ framework?: string;
2402
+ /** Limit retrieval to an exact documented version. */
2403
+ version?: string;
2404
+ /** Limit retrieval to a locale. */
2405
+ locale?: string;
2406
+ }
2407
+ interface DocsAgentGoldenTaskExpectation {
2408
+ /** Canonical page or section URLs that should answer this task. */
2409
+ relevantSources: string[];
2410
+ /** Additional sources that may be cited without reducing precision. */
2411
+ allowedSources?: string[];
2412
+ /** Sources that must not be selected, for example an obsolete version. */
2413
+ forbiddenSources?: string[];
2414
+ /** Citations that must appear. Defaults to `relevantSources`. */
2415
+ requiredCitations?: string[];
2416
+ /** Minimum relevant-source recall in the top K results. Defaults to `1`. */
2417
+ minRecallAtK?: number;
2418
+ /** Maximum acceptable rank for the first relevant source. Defaults to `topK`. */
2419
+ maxFirstRelevantRank?: number;
2420
+ /** Runnable examples that must be found in retrieved context. */
2421
+ examples?: DocsAgentGoldenExpectedExample[];
2422
+ /** Minimum share of context bytes that must come from relevant sources. */
2423
+ minUsefulByteRatio?: number;
2424
+ /**
2425
+ * Scope that the returned sources must actually select. Unlike `filters`, this is an
2426
+ * assertion and does not constrain retrieval, so it can detect a wrong framework,
2427
+ * version, or locale result.
2428
+ */
2429
+ scope?: DocsAgentGoldenTaskFilters;
2430
+ /** Assertions evaluated against an explicitly configured answer runner. */
2431
+ answer?: DocsAgentGoldenAnswerExpectation;
2432
+ }
2433
+ interface DocsAgentGoldenAnswerExpectation {
2434
+ /** Literal fragments that must occur in the generated answer. */
2435
+ includes?: string[];
2436
+ /** Literal fragments that must not occur in the generated answer. */
2437
+ excludes?: string[];
2438
+ /** Citations that the generated answer must contain. */
2439
+ requiredCitations?: string[];
2440
+ /** Additional answer citations that are valid but not required. */
2441
+ allowedCitations?: string[];
2442
+ /** Citations that the generated answer must not contain. */
2443
+ forbiddenCitations?: string[];
2444
+ }
2445
+ type DocsAgentGoldenExampleVerification = "present" | "syntax" | "execute";
2446
+ interface DocsAgentGoldenExpectedExample {
2447
+ /** Canonical page or section URL containing the example. */
2448
+ source?: string;
2449
+ language?: string;
2450
+ framework?: string;
2451
+ packageManager?: string;
2452
+ title?: string;
2453
+ /** Defaults to true. Set false for an intentionally non-runnable example. */
2454
+ runnable?: boolean;
2455
+ /** Literal fragments that must occur in the example. */
2456
+ includes?: string[];
2457
+ /**
2458
+ * Verification strength. Runnable examples default to `syntax`; explicitly
2459
+ * non-runnable examples default to `present`. Runtime execution is always opt-in.
2460
+ */
2461
+ verification?: DocsAgentGoldenExampleVerification;
2462
+ }
2463
+ type DocsAgentEvaluationSurface = "mcp-context" | "configured-search" | "ask-ai-context";
2464
+ interface DocsAgentGoldenTask {
2465
+ /** Stable identifier shown in doctor/review reports. */
2466
+ id: string;
2467
+ /** User-shaped retrieval query. */
2468
+ query: string;
2469
+ /** Optional retrieval scope. */
2470
+ filters?: DocsAgentGoldenTaskFilters;
2471
+ /** Conservative context budget. Uses the MCP context UTF-8 accounting strategy. */
2472
+ tokenBudget?: number;
2473
+ /** Number of ranked search results to evaluate. */
2474
+ topK?: number;
2475
+ /** Override the evaluation surface configured for the task suite. */
2476
+ surface?: DocsAgentEvaluationSurface;
2477
+ /** Evaluator-only expectations used to score the task. */
2478
+ expect: DocsAgentGoldenTaskExpectation;
2479
+ }
2480
+ interface DocsAgentEvaluationSourceReference {
2481
+ url: string;
2482
+ title?: string;
2483
+ framework?: string;
2484
+ version?: string;
2485
+ locale?: string;
2486
+ }
2487
+ /** Blind task input sent to answer providers. Golden expectations stay evaluator-only. */
2488
+ interface DocsAgentEvaluationTaskInput {
2489
+ id: string;
2490
+ query: string;
2491
+ filters?: DocsAgentGoldenTaskFilters;
2492
+ }
2493
+ /** Serializable, expectation-blind request sent to every configured answer provider. */
2494
+ interface DocsAgentEvaluationAnswerRequest {
2495
+ task: DocsAgentEvaluationTaskInput;
2496
+ surface: DocsAgentEvaluationSurface;
2497
+ context: string;
2498
+ sources: readonly DocsAgentEvaluationSourceReference[];
2499
+ }
2500
+ /** Callback answer input. The abort signal is not serialized for HTTP providers. */
2501
+ interface DocsAgentEvaluationAnswerInput extends DocsAgentEvaluationAnswerRequest {
2502
+ /** Aborted when the configured answer timeout elapses. */
2503
+ signal: AbortSignal;
2504
+ }
2505
+ interface DocsAgentEvaluationAnswerResult {
2506
+ text: string;
2507
+ /** Canonical URLs cited by the answer. Markdown links are also extracted from `text`. */
2508
+ citations?: string[];
2509
+ }
2510
+ type DocsAgentEvaluationAnswerRunner = (input: DocsAgentEvaluationAnswerInput) => DocsAgentEvaluationAnswerResult | Promise<DocsAgentEvaluationAnswerResult>;
2511
+ type DocsAgentEvaluationAnswerProvider = {
2512
+ provider: "callback";
2513
+ run: DocsAgentEvaluationAnswerRunner; /** Abort the callback after this many milliseconds. @default 30000 */
2514
+ timeoutMs?: number;
2515
+ } | {
2516
+ provider: "http"; /** Endpoint that accepts `DocsAgentEvaluationAnswerRequest` JSON and returns an answer result. */
2517
+ endpoint: string; /** Optional request headers. Values are never included in evaluation reports. */
2518
+ headers?: Record<string, string>; /** Abort the request after this many milliseconds. @default 30000 */
2519
+ timeoutMs?: number;
2520
+ };
2521
+ interface DocsAgentEvaluationsConfig {
2522
+ /** Enable golden-task evaluation. */
2523
+ enabled?: boolean;
2524
+ /** Default conservative context budget for tasks that omit `tokenBudget`. */
2525
+ tokenBudget?: number;
2526
+ /** Default retrieval depth for tasks that omit `topK`. */
2527
+ topK?: number;
2528
+ /** Retrieval/context surface measured by the task suite. @default "mcp-context" */
2529
+ surface?: DocsAgentEvaluationSurface;
2530
+ /**
2531
+ * Permit configured external search, HTTP answers, and explicit executable-example
2532
+ * verification. Disabled by default so doctor/review remain offline unless explicitly opted in.
2533
+ */
2534
+ allowNetwork?: boolean;
2535
+ /** Timeout for configured retrieval during each task. @default 30000 */
2536
+ searchTimeoutMs?: number;
2537
+ /** Optional callback or HTTP runner used to measure actual generated answers. */
2538
+ answer?: DocsAgentEvaluationAnswerProvider;
2539
+ /** Golden tasks evaluated by `docs doctor` and `docs review`. */
2540
+ tasks?: DocsAgentGoldenTask[];
2541
+ }
2542
+ /**
2543
+ * Project-local Agent Skills published by the runtime, static Agent Bundle, and MCP server.
2544
+ *
2545
+ * Each path may point at a `SKILL.md`, a skill directory containing `SKILL.md`, or a
2546
+ * collection directory whose descendants contain `SKILL.md` files. Paths are resolved
2547
+ * inside the current project/workspace boundary. Only `SKILL.md` and files below the
2548
+ * standard `references/`, `scripts/`, and `assets/` directories are published.
2549
+ */
2550
+ interface DocsAgentSkillsConfig {
2551
+ /** Project-relative skill file, skill directory, or collection directory paths. */
2552
+ paths: string | readonly string[];
2553
+ }
2554
+ /** Concise array shorthand for `agent.skills.paths`. */
2555
+ type DocsAgentSkillsInput = string | readonly string[] | DocsAgentSkillsConfig;
2556
+ /** Explicit A2A service metadata. Configure this only when the URL implements A2A. */
2557
+ interface DocsAgentA2AConfig {
2558
+ interfaceUrl: string;
2559
+ name: string;
2560
+ description: string;
2561
+ documentationUrl: string;
2562
+ provider: {
2563
+ organization: string;
2564
+ url: string;
2565
+ };
2566
+ version?: string;
2567
+ /** A2A protocol version exposed by the interface. @default "0.3" */
2568
+ protocolVersion?: string;
2569
+ /** Transport binding exposed by the interface. @default "HTTP+JSON" */
2570
+ protocolBinding?: string;
2571
+ }
2572
+ interface DocsAgentConfig {
2573
+ /**
2574
+ * Defaults for `docs agent compact`.
2575
+ */
2576
+ compact?: DocsAgentCompactConfig;
2577
+ /**
2578
+ * Offline-by-default retrieval, citation, version, example, and token-budget evaluations.
2579
+ * External providers and runtime execution require explicit opt-in.
2580
+ */
2581
+ evaluations?: boolean | DocsAgentEvaluationsConfig;
2582
+ /** Publish reusable Agent Skills through standards discovery, static exports, and MCP. */
2583
+ skills?: DocsAgentSkillsInput;
2584
+ /** Opt in to an A2A Agent Card for a separately implemented A2A service. */
2585
+ a2a?: DocsAgentA2AConfig;
2586
+ }
2587
+ type DocsReviewSeverity = "off" | "suggestion" | "warn" | "error";
2588
+ type DocsReviewCiMode = "off" | "warn" | "block";
2589
+ interface DocsReviewRulesConfig {
2590
+ /** Check internal markdown/docs links. */
2591
+ brokenLinks?: DocsReviewSeverity;
2592
+ /** Check required page frontmatter such as title and description. */
2593
+ frontmatter?: DocsReviewSeverity;
2594
+ /** Check duplicate docs slugs in the resolved docs tree. */
2595
+ duplicateSlugs?: DocsReviewSeverity;
2596
+ /** Check whether changed markdown/MDX files can be parsed. */
2597
+ invalidMdx?: DocsReviewSeverity;
2598
+ /** Check docs.config examples against known config options when possible. */
2599
+ configExamples?: DocsReviewSeverity;
2600
+ /** Check code fences for useful metadata such as title and framework. */
2601
+ codeFenceMetadata?: DocsReviewSeverity;
2602
+ /** Check runnable command/code fences for package manager context. */
2603
+ runnableMetadata?: DocsReviewSeverity;
2604
+ /** Validate structured page agent contracts and suggest context for implementation-heavy pages. */
2605
+ agentContext?: DocsReviewSeverity;
2606
+ /** Statically validate commands referenced by agent contracts and runnable examples. */
2607
+ commandHealth?: DocsReviewSeverity;
2608
+ /** Require useful related-page coverage on actionable docs pages. */
2609
+ relatedCoverage?: DocsReviewSeverity;
2610
+ /** Report when docs.config could not be evaluated and only partial static parsing is available. */
2611
+ configConfidence?: DocsReviewSeverity;
2612
+ /** Detect disagreement between discovery, resolved config, and the public config schema. */
2613
+ agentSurfaceDrift?: DocsReviewSeverity;
2614
+ /** Run configured agent golden tasks and report failed or unmeasured behavior. */
2615
+ goldenTasks?: DocsReviewSeverity;
2616
+ }
2617
+ interface DocsReviewScoreConfig {
2618
+ /**
2619
+ * Minimum healthy score.
2620
+ * CI reports the threshold in warn mode and blocks below it only when `ci.mode` is `"block"`.
2621
+ *
2622
+ * @default 80
2623
+ */
2624
+ threshold?: number;
2625
+ /**
2626
+ * Point deductions by finding severity.
2627
+ *
2628
+ * @default { error: 20, warn: 8, suggestion: 2 }
2629
+ */
2630
+ weights?: Partial<Record<"error" | "warn" | "suggestion", number>>;
2631
+ }
2632
+ interface DocsReviewCiConfig {
2633
+ /**
2634
+ * Enable Docs Review CI workflow generation.
2635
+ *
2636
+ * @default true
2637
+ */
2638
+ enabled?: boolean;
2639
+ /**
2640
+ * GitHub Actions job/check name for the generated workflow.
2641
+ *
2642
+ * @default "docs-review"
2643
+ */
2644
+ name?: string;
2645
+ /**
2646
+ * How CI should treat unhealthy review results.
2647
+ *
2648
+ * - `"off"`: do not create/report CI output
2649
+ * - `"warn"`: report annotations but pass CI
2650
+ * - `"block"`: fail CI when errors exist or the score is below threshold
2651
+ *
2652
+ * @default "warn"
2653
+ */
2654
+ mode?: DocsReviewCiMode;
2655
+ /**
2656
+ * Emit GitHub workflow command annotations in CI.
2657
+ *
2658
+ * @default true
2659
+ */
2660
+ annotations?: boolean;
2661
+ /**
2662
+ * Reserved for GitHub PR comments from the official action/bot.
2663
+ *
2664
+ * @default true
2665
+ */
2666
+ comment?: boolean;
2667
+ }
2668
+ interface DocsReviewConfig {
2669
+ /**
2670
+ * Enable Docs Review.
2671
+ *
2672
+ * Omitted review config is treated as enabled so docs sites get PR review CI by default.
2673
+ * Set `review: false` to opt out.
2674
+ *
2675
+ * @default true
2676
+ */
2677
+ enabled?: boolean;
2678
+ /** Score threshold and severity weights. */
2679
+ score?: DocsReviewScoreConfig;
2680
+ /** GitHub Actions behavior. */
2681
+ ci?: boolean | DocsReviewCiConfig;
2682
+ /** Optional rule severity overrides. */
2683
+ rules?: DocsReviewRulesConfig;
2684
+ }
2685
+ type DocsCodeBlocksPlannerProvider = "metadata" | "openai" | "openai-compatible" | "cloud";
2686
+ type DocsCodeBlocksRunnerProvider = "local" | "vercel-sandbox" | "e2b" | "daytona" | "cloud";
2687
+ type DocsCodeBlocksValidationMode = "plan" | "report";
2688
+ type DocsCodeBlocksValidationPolicy = "skip" | "warn" | "error";
2689
+ interface DocsCodeBlocksPlannerConfig {
2690
+ /**
2691
+ * Planner used to turn code fence metadata into an execution plan.
2692
+ *
2693
+ * - `"metadata"` reads the fence language and metadata locally.
2694
+ * - `"openai"` calls OpenAI's chat completions API.
2695
+ * - `"openai-compatible"` calls an OpenAI-compatible chat completions endpoint.
2696
+ * - `"cloud"` is reserved for the hosted Farming Labs planner.
2697
+ *
2698
+ * @default "metadata"
2699
+ */
2700
+ provider?: DocsCodeBlocksPlannerProvider;
2701
+ /** Model name for LLM-backed planners. */
2702
+ model?: string;
2703
+ /** OpenAI-compatible base URL. Defaults to `https://api.openai.com/v1` for `provider: "openai"`. */
2704
+ baseUrl?: string;
2705
+ /** Environment variable containing the OpenAI-compatible base URL. */
2706
+ baseUrlEnv?: string;
2707
+ /** API key value. Prefer `apiKeyEnv` so secrets stay out of docs.config. */
2708
+ apiKey?: string;
2709
+ /** Environment variable containing the planner API key. */
2710
+ apiKeyEnv?: string;
2711
+ }
2712
+ interface DocsCodeBlocksRunnerConfig {
2713
+ /**
2714
+ * Runner used to execute planned code blocks.
2715
+ *
2716
+ * @default "local"
2717
+ */
2718
+ provider?: DocsCodeBlocksRunnerProvider;
2719
+ /** Environment variable containing the sandbox provider token. */
2720
+ tokenEnv?: string;
2721
+ /** Advanced override for the Vercel project id env var used by `provider: "vercel-sandbox"`. */
2722
+ projectIdEnv?: string;
2723
+ /** Advanced override for the Vercel team/org id env var used by `provider: "vercel-sandbox"`. */
2724
+ teamIdEnv?: string;
2725
+ /**
2726
+ * Path to a Vercel project metadata file. When enabled, the runner reads
2727
+ * `projectId` and `orgId` from `.vercel/project.json`. If those are not
2728
+ * available, the runner can auto-discover an accessible project from
2729
+ * `VERCEL_TOKEN`.
2730
+ *
2731
+ * @default ".vercel/project.json"
2732
+ */
2733
+ projectJson?: string | false;
2734
+ /** Vercel Sandbox runtime. */
2735
+ runtime?: "node24" | "node22" | "python3.13";
2736
+ /** Daytona API URL env var used by `provider: "daytona"`. */
2737
+ apiUrlEnv?: string;
2738
+ /** Daytona target/region env var used by `provider: "daytona"`. */
2739
+ targetEnv?: string;
2740
+ /** Per-command timeout in milliseconds. */
2741
+ timeoutMs?: number;
2742
+ }
2743
+ interface DocsCodeBlocksValidateConfig {
2744
+ /**
2745
+ * Enable code block validation.
2746
+ *
2747
+ * @default true when `codeBlocks.validate` is an object or `true`
2748
+ */
2749
+ enabled?: boolean;
2750
+ /** Planner config. Use `"metadata"` for local deterministic planning. */
2751
+ planner?: DocsCodeBlocksPlannerProvider | DocsCodeBlocksPlannerConfig;
2752
+ /** Runner config. Use `"vercel-sandbox"` for isolated runtime checks. */
2753
+ runner?: DocsCodeBlocksRunnerProvider | DocsCodeBlocksRunnerConfig;
2754
+ /**
2755
+ * Env files loaded for validation. These are read locally and never committed.
2756
+ *
2757
+ * @default [".env.local", ".env.test", ".env"]
2758
+ */
2759
+ envFile?: string | string[];
2760
+ /**
2761
+ * Runtime env mapping.
2762
+ *
2763
+ * The key is the env var used by the docs code block. The value is the local
2764
+ * env var to read from. For example, `{ OPENAI_API_KEY: "OPENAI_TEST_API_KEY" }`
2765
+ * injects `OPENAI_API_KEY` into the runner from `OPENAI_TEST_API_KEY`.
2766
+ */
2767
+ env?: Record<string, string>;
2768
+ /**
2769
+ * Behavior when a runnable block declares an env var that cannot be resolved.
2770
+ *
2771
+ * @default "skip"
2772
+ */
2773
+ missingEnv?: DocsCodeBlocksValidationPolicy;
2774
+ /**
2775
+ * Behavior when a language cannot be executed by the selected runner.
2776
+ *
2777
+ * @default "skip"
2778
+ */
2779
+ unsupportedLanguage?: DocsCodeBlocksValidationPolicy;
2780
+ /**
2781
+ * Default command mode.
2782
+ *
2783
+ * - `"plan"` builds execution plans without running them.
2784
+ * - `"report"` runs executable plans and reports pass/skip/fail.
2785
+ *
2786
+ * @default "report"
2787
+ */
2788
+ mode?: DocsCodeBlocksValidationMode;
2789
+ }
2790
+ interface DocsCodeBlocksConfig {
2791
+ /**
2792
+ * Validate fenced code blocks from MD/MDX docs.
2793
+ *
2794
+ * @example
2795
+ * ```ts
2796
+ * codeBlocks: {
2797
+ * validate: {
2798
+ * planner: {
2799
+ * provider: "openai",
2800
+ * model: "gpt-4.1-mini",
2801
+ * apiKeyEnv: "OPENAI_API_KEY",
2802
+ * },
2803
+ * runner: {
2804
+ * provider: "vercel-sandbox",
2805
+ * tokenEnv: "VERCEL_TOKEN",
2806
+ * },
2807
+ * env: {
2808
+ * OPENAI_API_KEY: "OPENAI_TEST_API_KEY",
2809
+ * },
2810
+ * },
2811
+ * }
2812
+ * ```
2813
+ */
2814
+ validate?: boolean | DocsCodeBlocksValidateConfig;
2815
+ }
2816
+ interface DocsConfig {
2817
+ /** Entry folder for docs (e.g. "docs" → /docs) */
2818
+ entry: string;
2819
+ /**
2820
+ * Public route prefix for docs pages. Defaults to the `entry` path.
2821
+ * Set to "" or "/" to serve docs from the site root while keeping the
2822
+ * source files and generated app route under `entry`.
2823
+ */
2824
+ docsPath?: string;
2825
+ /** Path to the content directory. Defaults to `entry` value. */
2826
+ contentDir?: string;
2827
+ /**
2828
+ * Internationalization (i18n) configuration.
2829
+ * When set, docs content is expected under `${contentDir}/{locale}` and
2830
+ * the active locale is selected by `?lang=<locale>` in the URL.
2831
+ */
2832
+ i18n?: DocsI18nConfig;
2833
+ /**
2834
+ * Set to `true` when building for full static export (e.g. Cloudflare Pages).
2835
+ * When using `output: 'export'` in Next.js, the `/api/docs` route is not generated.
2836
+ * Set `ai.enabled: false` and optionally rely on client-side search or leave search disabled.
2837
+ */
2838
+ staticExport?: boolean;
2839
+ /** Theme configuration - single source of truth for UI */
2840
+ theme?: DocsTheme;
2841
+ /**
2842
+ * Built-in analytics event stream for docs interactions.
2843
+ *
2844
+ * - `false` -> analytics disabled
2845
+ * - omitted -> analytics disabled unless Docs Cloud provides project identity
2846
+ * - `true` -> log product/usage events to the console
2847
+ * - `{ onEvent(event) { ... } }` -> send events to your analytics sink
2848
+ *
2849
+ * Raw queries, AI questions, feedback comments, and copied content are not
2850
+ * included unless `includeInputs: true` is set.
2851
+ */
2852
+ analytics?: boolean | DocsAnalyticsConfig;
2853
+ /**
2854
+ * Farming Labs maintainer telemetry for production adoption and coarse
2855
+ * agent-optimized feature usage.
2856
+ *
2857
+ * This is separate from project-owned `analytics`. It avoids visitor
2858
+ * identities, page views, raw inputs, docs content, cookies, and per-user
2859
+ * sessions. Disable with `telemetry: false`, `DOCS_TELEMETRY=false`, or
2860
+ * `DOCS_TELEMETRY_DISABLED=1`.
2861
+ */
2862
+ telemetry?: boolean | DocsTelemetryConfig;
2863
+ /**
2864
+ * Docs Cloud integration settings.
2865
+ *
2866
+ * Use this to configure the API key env var and cloud deploy defaults once
2867
+ * in `docs.config.ts`; cloud CLI commands mirror the serializable subset into
2868
+ * `docs.json` automatically.
2869
+ *
2870
+ * @example
2871
+ * ```ts
2872
+ * cloud: {
2873
+ * apiKey: { env: "DOCS_CLOUD_API_KEY" },
2874
+ * deploy: { enabled: true },
2875
+ * publish: { mode: "draft-pr", baseBranch: "main" },
2876
+ * }
2877
+ * ```
2878
+ */
2879
+ cloud?: DocsCloudConfig;
2880
+ /**
2881
+ * Built-in observability stream for agent traces, timing, errors, and runtime debugging.
2882
+ * This is separate from `analytics`; it emits span-like Ask AI and MCP trace events.
2883
+ *
2884
+ * ```ts
2885
+ * observability: {
2886
+ * console: "debug",
2887
+ * onEvent(event) {
2888
+ * console.info(event.type, event.traceId, event.durationMs)
2889
+ * },
2890
+ * }
2891
+ * ```
2892
+ */
2893
+ observability?: boolean | DocsObservabilityConfig;
2894
+ /**
2895
+ * GitHub repository URL or config. Enables "Edit on GitHub" links
2896
+ * on each docs page footer, pointing to the source `.mdx` file.
2897
+ *
2898
+ * @example
2899
+ * ```ts
2900
+ * // Simple — branch defaults to "main"
2901
+ * github: "https://github.com/Kinfe123/my-docs"
2902
+ *
2903
+ * // Monorepo — docs site lives in "website/" subdirectory
2904
+ * github: {
2905
+ * url: "https://github.com/farming-labs/docs",
2906
+ * directory: "website",
2907
+ * }
2908
+ *
2909
+ * // Custom branch
2910
+ * github: {
2911
+ * url: "https://github.com/Kinfe123/my-docs",
2912
+ * branch: "develop",
2913
+ * }
2914
+ * ```
2915
+ */
2916
+ github?: string | GithubConfig;
2917
+ /**
2918
+ * Sidebar navigation header.
2919
+ * Customise the title shown at the top of the sidebar.
2920
+ */
2921
+ nav?: DocsNav;
2922
+ /**
2923
+ * Theme toggle (light/dark mode switcher) in the sidebar.
2924
+ *
2925
+ * - `true` or `undefined` → toggle is shown (default)
2926
+ * - `false` → toggle is hidden, defaults to system theme
2927
+ * - `{ enabled: false, default: "dark" }` → toggle hidden, force dark
2928
+ *
2929
+ * @example
2930
+ * ```ts
2931
+ * // Hide toggle, force dark mode
2932
+ * themeToggle: { enabled: false, default: "dark" }
2933
+ *
2934
+ * // Show toggle with system option
2935
+ * themeToggle: { mode: "light-dark-system" }
2936
+ * ```
2937
+ */
2938
+ themeToggle?: boolean | ThemeToggleConfig;
2939
+ /**
2940
+ * Breadcrumb navigation above page content.
2941
+ *
2942
+ * - `true` or `undefined` → breadcrumb is shown (default)
2943
+ * - `false` → breadcrumb is hidden
2944
+ * - `{ enabled: false }` → breadcrumb is hidden
2945
+ * - `{ component: MyBreadcrumb }` → custom breadcrumb component
2946
+ */
2947
+ breadcrumb?: boolean | BreadcrumbConfig;
2948
+ /**
2949
+ * Sidebar customisation.
2950
+ *
2951
+ * - `true` or `undefined` → default sidebar
2952
+ * - `false` → sidebar is hidden
2953
+ * - `{ component: MySidebar }` → custom sidebar component
2954
+ * - `{ footer: <MyFooter />, banner: <MyBanner /> }` → add footer/banner
2955
+ */
2956
+ sidebar?: boolean | SidebarConfig;
2957
+ /**
2958
+ * Custom MDX component overrides.
2959
+ *
2960
+ * Pass your own React components to replace defaults (e.g. Callout, CodeBlock).
2961
+ * Components must match the expected props interface.
2962
+ *
2963
+ * @example
2964
+ * ```ts
2965
+ * import { MyCallout } from "./components/my-callout";
2966
+ *
2967
+ * export default defineDocs({
2968
+ * entry: "docs",
2969
+ * theme: fumadocs(),
2970
+ * components: {
2971
+ * Callout: MyCallout,
2972
+ * },
2973
+ * });
2974
+ * ```
2975
+ */
2976
+ components?: Record<string, unknown>;
2977
+ /**
2978
+ * Callback fired when the user clicks the copy button on a code block.
2979
+ * Called in addition to the default copy-to-clipboard behavior.
2980
+ * Use it for analytics, logging, or custom behavior.
2981
+ *
2982
+ * @example
2983
+ * ```ts
2984
+ * export default defineDocs({
2985
+ * entry: "docs",
2986
+ * theme: fumadocs(),
2987
+ * onCopyClick(data) {
2988
+ * console.log("Code copied", data.title, data.language, data.url);
2989
+ * analytics.track("code_block_copy", { title: data.title, url: data.url });
2990
+ * },
2991
+ * });
2992
+ * ```
2993
+ */
2994
+ onCopyClick?: (data: CodeBlockCopyData) => void;
2995
+ /**
2996
+ * Code block intelligence for MD/MDX fences, including validation planning
2997
+ * and optional sandboxed execution.
2998
+ */
2999
+ codeBlocks?: DocsCodeBlocksConfig;
3000
+ /**
3001
+ * Built-in page feedback prompt shown at the end of a docs page.
3002
+ *
3003
+ * - `false` or `undefined` → hidden (default)
3004
+ * - `true` → shown with default labels
3005
+ * - `{ enabled: true, onFeedback(data) { ... } }` → shown with callback
3006
+ *
3007
+ * @example
3008
+ * ```ts
3009
+ * import type { DocsFeedbackData } from "@farming-labs/docs";
3010
+ *
3011
+ * export default defineDocs({
3012
+ * entry: "docs",
3013
+ * feedback: {
3014
+ * enabled: true,
3015
+ * onFeedback(data: DocsFeedbackData) {
3016
+ * console.log("Docs feedback", data.value, data.slug, data.url);
3017
+ * },
3018
+ * },
3019
+ * });
3020
+ * ```
3021
+ */
3022
+ feedback?: boolean | FeedbackConfig;
3023
+ /**
3024
+ * Built-in MCP server for agent/assistant access to your docs content.
3025
+ *
3026
+ * - omitted → enable the default MCP surface at `/mcp` and `/.well-known/mcp`, backed by `/api/docs/mcp`
3027
+ * - `true` → enable the default MCP surface at `/mcp` and `/.well-known/mcp`, backed by `/api/docs/mcp`
3028
+ * - `{ route: "/api/docs/mcp" }` → enable with explicit route/config
3029
+ * - `false` or `{ enabled: false }` → disable MCP explicitly
3030
+ */
3031
+ mcp?: boolean | DocsMcpConfig;
3032
+ /**
3033
+ * Shared icon registry for sidebar items and built-in MDX components.
3034
+ *
3035
+ * Map string labels to React elements. Reference them in page frontmatter
3036
+ * with `icon: "label"` and the matching icon renders in the sidebar.
3037
+ * Built-in components such as `Prompt` can also reference these keys for
3038
+ * their card and action icons.
3039
+ *
3040
+ * @example
3041
+ * ```tsx
3042
+ * import { Book, Terminal, Rocket } from "lucide-react";
3043
+ *
3044
+ * export default defineDocs({
3045
+ * entry: "docs",
3046
+ * theme: fumadocs(),
3047
+ * icons: {
3048
+ * book: <Book />,
3049
+ * terminal: <Terminal />,
3050
+ * rocket: <Rocket />,
3051
+ * },
3052
+ * });
3053
+ * ```
3054
+ *
3055
+ * Then in `page.mdx` frontmatter:
3056
+ * ```yaml
3057
+ * ---
3058
+ * title: "CLI Reference"
3059
+ * icon: "terminal"
3060
+ * ---
3061
+ * ```
3062
+ */
3063
+ icons?: Record<string, unknown>;
3064
+ /**
3065
+ * Page action buttons shown above the content area.
3066
+ * Includes "Copy Markdown" and "Open in …" (LLM dropdown).
3067
+ *
3068
+ * @example
3069
+ * ```ts
3070
+ * pageActions: {
3071
+ * copyMarkdown: { enabled: true },
3072
+ * openDocs: {
3073
+ * enabled: true,
3074
+ * target: "markdown",
3075
+ * providers: [
3076
+ * "chatgpt",
3077
+ * "claude",
3078
+ * "cursor",
3079
+ * ],
3080
+ * },
3081
+ * }
3082
+ * ```
3083
+ */
3084
+ pageActions?: PageActionsConfig;
3085
+ /**
3086
+ * Built-in docs search configuration.
3087
+ *
3088
+ * - `true` or omitted → use the built-in simple search
3089
+ * - `{ provider: "typesense", ... }` → use Typesense
3090
+ * - `{ provider: "algolia", ... }` → use Algolia
3091
+ * - `{ provider: "custom", adapter }` → use a custom adapter
3092
+ * - `false` → disable docs search
3093
+ */
3094
+ search?: boolean | DocsSearchConfig;
3095
+ /**
3096
+ * Configuration for the "Last updated" date display.
3097
+ *
3098
+ * - `true` or `undefined` → shown in footer next to "Edit on GitHub" (default)
3099
+ * - `false` → hidden
3100
+ * - `{ position: "below-title" }` → shown below the page title
3101
+ * - `{ position: "footer" }` → shown next to "Edit on GitHub" (default)
3102
+ *
3103
+ * @example
3104
+ * ```ts
3105
+ * // Show below title (Mintlify style)
3106
+ * lastUpdated: { position: "below-title" }
3107
+ *
3108
+ * // Hide entirely
3109
+ * lastUpdated: false
3110
+ * ```
3111
+ */
3112
+ lastUpdated?: boolean | LastUpdatedConfig;
3113
+ /**
3114
+ * Estimated reading time shown at the top of docs pages.
3115
+ *
3116
+ * - `undefined` → disabled by default
3117
+ * - `true` or `{ enabled: true }` → show a computed "{n} min read" label
3118
+ * - `false` → hide it entirely
3119
+ *
3120
+ * @example
3121
+ * ```ts
3122
+ * readingTime: { enabled: true, wordsPerMinute: 220 }
3123
+ * ```
3124
+ */
3125
+ readingTime?: boolean | ReadingTimeConfig;
3126
+ /**
3127
+ * AI-powered "Ask AI" chat for documentation.
3128
+ *
3129
+ * When enabled, the unified API route handler (`/api/docs`) accepts
3130
+ * POST requests for AI chat. The handler uses RAG (Retrieval-Augmented
3131
+ * Generation) — it searches relevant docs, builds context, and streams
3132
+ * a response from an LLM.
3133
+ *
3134
+ * The API key defaults to `process.env.OPENAI_API_KEY`. For other providers,
3135
+ * pass the key via `apiKey: process.env.YOUR_KEY`.
3136
+ *
3137
+ * @example
3138
+ * ```ts
3139
+ * // Enable with defaults (gpt-4o-mini, OPENAI_API_KEY)
3140
+ * ai: { enabled: true }
3141
+ *
3142
+ * // Custom model + system prompt
3143
+ * ai: {
3144
+ * enabled: true,
3145
+ * model: "gpt-4o",
3146
+ * systemPrompt: "You are an expert on our SDK. Be concise.",
3147
+ * }
3148
+ *
3149
+ * // Use a different provider (e.g. Groq)
3150
+ * ai: {
3151
+ * enabled: true,
3152
+ * baseUrl: "https://api.groq.com/openai/v1",
3153
+ * apiKey: process.env.GROQ_API_KEY,
3154
+ * model: "llama-3.1-70b-versatile",
3155
+ * }
3156
+ * ```
3157
+ */
3158
+ ai?: AIConfig;
3159
+ /**
3160
+ * Sidebar ordering strategy.
3161
+ *
3162
+ * - `"alphabetical"` — sort pages alphabetically by folder name (default)
3163
+ * - `"numeric"` — sort by frontmatter `order` field (lower first, unset pages last)
3164
+ * - `OrderingItem[]` — explicit slug-based ordering with nested children
3165
+ *
3166
+ * @default "alphabetical"
3167
+ *
3168
+ * @example
3169
+ * ```ts
3170
+ * // Alphabetical (default)
3171
+ * ordering: "alphabetical",
3172
+ *
3173
+ * // Use frontmatter `order: 1`, `order: 2`, etc.
3174
+ * ordering: "numeric",
3175
+ *
3176
+ * // Explicit slug-based ordering
3177
+ * ordering: [
3178
+ * { slug: "installation" },
3179
+ * { slug: "cli" },
3180
+ * { slug: "configuration" },
3181
+ * { slug: "themes", children: [
3182
+ * { slug: "default" },
3183
+ * { slug: "darksharp" },
3184
+ * { slug: "pixel-border" },
3185
+ * { slug: "creating-themes" },
3186
+ * ]},
3187
+ * { slug: "customization" },
3188
+ * { slug: "reference" },
3189
+ * ]
3190
+ * ```
3191
+ */
3192
+ ordering?: "alphabetical" | "numeric" | OrderingItem[];
3193
+ /**
3194
+ * Auto-generate `/llms.txt` and `/llms-full.txt` routes for LLM-friendly
3195
+ * documentation. Native static files at those routes take precedence, so
3196
+ * `public/llms.txt` or SvelteKit `static/llms.txt` can override the
3197
+ * generated output without extra config.
3198
+ *
3199
+ * @example
3200
+ * ```ts
3201
+ * llmsTxt: {
3202
+ * baseUrl: "https://docs.example.com",
3203
+ * }
3204
+ * ```
3205
+ *
3206
+ * @see https://llmstxt.org
3207
+ */
3208
+ llmsTxt?: boolean | LlmsTxtConfig;
3209
+ /**
3210
+ * Generated XML and Markdown sitemaps for crawlers, agents, and static export.
3211
+ *
3212
+ * Enabled by default. Set `sitemap: false` to opt out.
3213
+ *
3214
+ * @example
3215
+ * ```ts
3216
+ * sitemap: true
3217
+ *
3218
+ * sitemap: {
3219
+ * routePrefix: "/docs",
3220
+ * baseUrl: "https://docs.example.com",
3221
+ * }
3222
+ * ```
3223
+ */
3224
+ sitemap?: boolean | DocsSitemapConfig;
3225
+ /**
3226
+ * Generated robots.txt policy for docs and agent-readable routes.
3227
+ *
3228
+ * Served by the runtime by default when no static `robots.txt` exists. Use
3229
+ * `docs robots generate` for static export or when you want to append to an
3230
+ * existing file.
3231
+ *
3232
+ * @example
3233
+ * ```ts
3234
+ * robots: {
3235
+ * baseUrl: "https://docs.example.com",
3236
+ * ai: "allow",
3237
+ * }
3238
+ * ```
3239
+ */
3240
+ robots?: boolean | DocsRobotsConfig;
3241
+ /**
3242
+ * Generated changelog pages backed by date-folder MDX entries inside the docs
3243
+ * content tree.
3244
+ *
3245
+ * Entry structure:
3246
+ * `docs/changelog/2026-03-04/page.mdx`
3247
+ *
3248
+ * With `entry: "docs"` and `path: "changelogs"`, the public pages render
3249
+ * under the docs layout at `/docs/changelogs`.
3250
+ *
3251
+ * Required frontmatter:
3252
+ * - `title`
3253
+ * - `description`
3254
+ *
3255
+ * @example
3256
+ * ```ts
3257
+ * changelog: {
3258
+ * enabled: true,
3259
+ * path: "changelogs",
3260
+ * contentDir: "changelog",
3261
+ * title: "Changelogs",
3262
+ * description: "Latest product updates and release notes.",
3263
+ * }
3264
+ * ```
3265
+ */
3266
+ changelog?: boolean | ChangelogConfig;
3267
+ /**
3268
+ * Generated API reference pages from framework route conventions or a hosted
3269
+ * OpenAPI JSON document.
3270
+ *
3271
+ * @example
3272
+ * ```ts
3273
+ * apiReference: {
3274
+ * enabled: true,
3275
+ * path: "api-reference",
3276
+ * routeRoot: "api",
3277
+ * }
3278
+ * ```
3279
+ *
3280
+ * @example
3281
+ * ```ts
3282
+ * apiReference: {
3283
+ * enabled: true,
3284
+ * specUrl: "https://example.com/openapi.json",
3285
+ * }
3286
+ * ```
3287
+ */
3288
+ apiReference?: boolean | ApiReferenceConfig;
3289
+ /**
3290
+ * Agent-oriented configuration, including defaults for `docs agent compact`.
3291
+ */
3292
+ agent?: DocsAgentConfig;
3293
+ /**
3294
+ * Docs Review checks changed docs files in CI/local runs and can auto-create
3295
+ * a GitHub Actions workflow during dev/build startup.
3296
+ *
3297
+ * - omitted or `true` → enabled with warn-mode CI and an 80 score threshold
3298
+ * - `false` → disable review and workflow generation
3299
+ *
3300
+ * @example
3301
+ * ```ts
3302
+ * review: {
3303
+ * ci: { mode: "block" },
3304
+ * score: { threshold: 90 },
3305
+ * }
3306
+ * ```
3307
+ */
3308
+ review?: boolean | DocsReviewConfig;
3309
+ /** SEO metadata - separate from theme */
3310
+ metadata?: DocsMetadata;
3311
+ /** Open Graph image handling */
3312
+ og?: OGConfig;
3313
+ }
3314
+ //#endregion
3315
+ export { DocsCloudFeatureConfig as $, DocsTelemetryEvent as $t, DocsAgentGoldenTask as A, PageSidebarFrontmatter as An, DocsRelatedItem as At, DocsAnalyticsEventInput as B, SidebarPageNode as Bn, DocsSearchAdapterContext as Bt, DocsAgentEvaluationTaskInput as C, PageAgentAppliesTo as Cn, DocsMcpSecurityConfig as Ct, DocsAgentGoldenAnswerExpectation as D, PageAgentVerification as Dn, DocsObservabilityConfig as Dt, DocsAgentFeedbackData as E, PageAgentFrontmatter as En, DocsNav as Et, DocsAgentTraceEventInput as F, SidebarComponentProps as Fn, DocsReviewScoreConfig as Ft, DocsAskAIActionType as G, TypographyConfig as Gn, DocsSearchEmbeddingsConfig as Gt, DocsAnalyticsInput as H, SimpleDocsSearchConfig as Hn, DocsSearchChunkingConfig as Ht, DocsAgentTraceEventType as I, SidebarConfig as In, DocsReviewSeverity as It, DocsAskAIFeedbackMessage as J, DocsSearchResultType as Jt, DocsAskAIFeedbackConfig as K, UIConfig as Kn, DocsSearchQuery as Kt, DocsAgentTraceStatus as L, SidebarFolderIndexBehavior as Ln, DocsRobotsConfig as Lt, DocsAgentGoldenTaskFilters as M, ReadingTimeConfig as Mn, DocsReviewCiMode as Mt, DocsAgentSkillsConfig as N, ReadingTimeFormat as Nn, DocsReviewConfig as Nt, DocsAgentGoldenExampleVerification as O, PageFrontmatter as On, DocsObservabilityEvent as Ot, DocsAgentSkillsInput as P, ResolvedDocsRelatedLink as Pn, DocsReviewRulesConfig as Pt, DocsCloudConfig as Q, DocsTelemetryConfig as Qt, DocsAnalyticsConfig as R, SidebarFolderNode as Rn, DocsRobotsRule as Rt, DocsAgentEvaluationSurface as S, PageActionsConfig as Sn, DocsMcpProtectedResourceConfig as St, DocsAgentFeedbackContext as T, PageAgentFailureMode as Tn, DocsMetadata as Tt, DocsAnalyticsSource as U, ThemeToggleConfig as Un, DocsSearchConfig as Ut, DocsAnalyticsEventType as V, SidebarTree as Vn, DocsSearchAdapterFactory as Vt, DocsAskAIActionData as W, TypesenseDocsSearchConfig as Wn, DocsSearchDocument as Wt, DocsAskAIMcpConfig as X, DocsSitemapConfig as Xt, DocsAskAIFeedbackValue as Y, DocsSearchSourcePage as Yt, DocsCloudApiKeyConfig as Z, DocsTelemetryAgentSurface as Zt, DocsAgentEvaluationAnswerProvider as _, OpenDocsProviderConfig as _n, DocsMcpAuthenticateContext as _t, ApiReferenceRenderer as a, FeedbackConfig as an, DocsCodeBlocksRunnerConfig as at, DocsAgentEvaluationAnswerRunner as b, OpenGraphImage as bn, DocsMcpCorsConfig as bt, ChangelogFrontmatter as c, LastUpdatedConfig as cn, DocsCodeBlocksValidationMode as ct, CopyMarkdownFormat as d, LlmsTxtMaxCharsMode as dn, DocsFeedbackData as dt, DocsTelemetryEventInput as en, DocsCloudPreviewConfig as et, CustomDocsSearchConfig as f, LlmsTxtSectionConfig as fn, DocsFeedbackValue as ft, DocsAgentEvaluationAnswerInput as g, OpenDocsProvider as gn, DocsMcpAuthenticate as gt, DocsAgentConfig as h, OpenDocsConfig as hn, DocsMcpAuthPrincipal as ht, ApiReferenceConfig as i, DocsTheme as in, DocsCodeBlocksPlannerProvider as it, DocsAgentGoldenTaskExpectation as j, PageTwitter as jn, DocsReviewCiConfig as jt, DocsAgentGoldenExpectedExample as k, PageOpenGraph as kn, DocsObservabilityEventInput as kt, CodeBlockCopyData as l, LlmsTxtConfig as ln, DocsCodeBlocksValidationPolicy as lt, DocsAgentCompactConfig as m, OGConfig as mn, DocsMcpAllowedOrigins as mt, AgentFeedbackConfig as n, DocsTelemetryFeatures as nn, DocsCodeBlocksConfig as nt, BreadcrumbConfig as o, FontStyle as on, DocsCodeBlocksRunnerProvider as ot, DocsAgentA2AConfig as p, McpDocsSearchConfig as pn, DocsI18nConfig as pt, DocsAskAIFeedbackData as q, DocsSearchResult as qt, AlgoliaDocsSearchConfig as r, DocsTelemetryFramework as rn, DocsCodeBlocksPlannerConfig as rt, ChangelogConfig as s, GithubConfig as sn, DocsCodeBlocksValidateConfig as st, AIConfig as t, DocsTelemetryEventType as tn, DocsCloudPublishConfig as tt, CopyMarkdownConfig as u, LlmsTxtMaxCharsConfig as un, DocsConfig as ut, DocsAgentEvaluationAnswerRequest as v, OpenDocsProviderId as vn, DocsMcpAuthenticateResult as vt, DocsAgentEvaluationsConfig as w, PageAgentCommand as wn, DocsMcpToolsConfig as wt, DocsAgentEvaluationSourceReference as x, OrderingItem as xn, DocsMcpOriginContext as xt, DocsAgentEvaluationAnswerResult as y, OpenDocsTarget as yn, DocsMcpConfig as yt, DocsAnalyticsEvent as z, SidebarNode as zn, DocsSearchAdapter as zt };