@farming-labs/theme 0.2.52 → 0.2.54

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.
@@ -129,7 +129,7 @@ declare function createDocsAPI(options?: DocsAPIOptions): {
129
129
  /**
130
130
  * Create MCP route handlers for `/api/docs/mcp`.
131
131
  *
132
- * Returns `{ GET, POST, DELETE }` for use in a Next.js route handler.
132
+ * Returns `{ GET, POST, DELETE, OPTIONS }` for use in a Next.js route handler.
133
133
  */
134
134
  /**
135
135
  * @deprecated Prefer `createDocsMCPAPI` from `@farming-labs/next/api` in Next.js apps.
@@ -139,6 +139,7 @@ declare function createDocsMCPAPI(options?: DocsMCPAPIOptions): {
139
139
  GET(request: Request): Promise<Response>;
140
140
  POST(request: Request): Promise<Response>;
141
141
  DELETE(request: Request): Promise<Response>;
142
+ OPTIONS(request: Request): Promise<Response>;
142
143
  };
143
144
  //#endregion
144
145
  export { createDocsAPI, createDocsMCPAPI };
package/dist/docs-api.mjs CHANGED
@@ -3,7 +3,7 @@ import { getNextAppDir } from "./get-app-dir.mjs";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import matter from "gray-matter";
6
- import { DEFAULT_SITEMAP_MD_DOCS_ROUTE, buildDocsAskAIContext, buildDocsConfigMap, buildDocsDiagnostics, createDocsAgentTraceContext, createDocsAgentTraceId, createDocsRobotsResponse, createDocsSitemapResponse, detectDocsMarkdownAgentRequest, emitDocsAgentTraceEvent, emitDocsAnalyticsEvent, emitDocsTelemetryAgentSurfaceEvent, emitDocsTelemetryProjectEvent, formatDocsAskAIPackageHints, getDocsLlmsTxtMaxCharsIssue, getDocsMarkdownVaryHeader, hasDocsMarkdownSignatureAgent, inferDocsTelemetryAgentSurface, isDocsConfigRequest, isDocsDiagnosticsRequest, normalizeDocsRelated, performDocsSearch, renderDocsLlmsTxt, renderDocsMarkdownDocument, renderDocsMarkdownNotFound, resolveAskAISearchRequestConfig, resolveChangelogConfig, resolveDocsI18n, resolveDocsLlmsTxtRequest, resolveDocsLlmsTxtSections, resolveDocsLocale, resolveDocsMarkdownRecovery, resolveDocsMetadataBaseUrl, resolveDocsSitemapConfig, resolvePageSidebarFolderIndexBehavior, resolveSearchRequestConfig, selectDocsLlmsTxtContent } from "@farming-labs/docs";
6
+ import { DEFAULT_SITEMAP_MD_DOCS_ROUTE, acceptsDocsMarkdown, buildDocsAskAIContext, buildDocsConfigMap, buildDocsDiagnostics, createDocsAgentTraceContext, createDocsAgentTraceId, createDocsMarkdownResponse, createDocsRobotsResponse, createDocsSitemapResponse, detectDocsMarkdownAgentRequest, emitDocsAgentTraceEvent, emitDocsAnalyticsEvent, emitDocsTelemetryAgentSurfaceEvent, emitDocsTelemetryProjectEvent, formatDocsAskAIPackageHints, getDocsLlmsTxtMaxCharsIssue, hasDocsMarkdownSignatureAgent, inferDocsTelemetryAgentSurface, isDocsConfigRequest, isDocsDiagnosticsRequest, normalizeDocsRelated, normalizePageAgentFrontmatter, performDocsSearch, renderDocsLlmsTxt, renderDocsMarkdownDocument, resolveAskAISearchRequestConfig, resolveChangelogConfig, resolveDocsAgentContractMcpTools, resolveDocsI18n, resolveDocsLlmsTxtRequest, resolveDocsLlmsTxtSections, resolveDocsLocale, resolveDocsMetadataBaseUrl, resolveDocsSitemapConfig, resolvePageSidebarFolderIndexBehavior, resolveSearchRequestConfig, selectDocsLlmsTxtContent } from "@farming-labs/docs";
7
7
  import { buildApiReferenceOpenApiDocumentAsync, createDocsMcpHttpHandler, createFilesystemDocsMcpSource, readDocsSitemapManifest, resolveApiReferenceConfig, resolveDocsMcpConfig } from "@farming-labs/docs/server";
8
8
 
9
9
  //#region src/docs-api.ts
@@ -214,6 +214,7 @@ function buildAgentSpec({ origin, entry, i18n, search, mcp, feedback, llms, site
214
214
  const sitemapConfig = resolveDocsSitemapConfig(sitemap, { baseUrl: llms.baseUrl });
215
215
  const robotsEnabled = isRobotsDiscoveryEnabled(robots);
216
216
  const llmsSections = resolveDocsLlmsTxtSections(llms);
217
+ const agentContractMcpTools = resolveDocsAgentContractMcpTools(mcp);
217
218
  return {
218
219
  version: "1",
219
220
  name: "@farming-labs/docs",
@@ -235,6 +236,7 @@ function buildAgentSpec({ origin, entry, i18n, search, mcp, feedback, llms, site
235
236
  markdownRoutes: true,
236
237
  agentMdOverrides: true,
237
238
  agentBlocks: true,
239
+ structuredAgentContracts: true,
238
240
  agents: true,
239
241
  llms: llms.enabled,
240
242
  skills: true,
@@ -277,6 +279,33 @@ function buildAgentSpec({ origin, entry, i18n, search, mcp, feedback, llms, site
277
279
  "page markdown"
278
280
  ]
279
281
  },
282
+ agentContract: {
283
+ enabled: true,
284
+ schemaVersion: "page-agent-contract.v1",
285
+ source: "page-frontmatter",
286
+ frontmatterPath: "agent",
287
+ markdownSection: "Agent Contract",
288
+ mcpField: "agent",
289
+ ...agentContractMcpTools ? { mcpTools: agentContractMcpTools } : {},
290
+ usefulContractFields: ["task", "outcome"],
291
+ fields: {
292
+ tokenBudget: "number",
293
+ task: "string",
294
+ outcome: "string",
295
+ appliesTo: {
296
+ framework: "string|string[]",
297
+ version: "string|string[]",
298
+ package: "string|string[]"
299
+ },
300
+ prerequisites: "string[]",
301
+ files: "string[]",
302
+ commands: "Array<string|{run,cwd?,description?}>",
303
+ sideEffects: "string[]",
304
+ verification: "Array<string|{description?,run?,expect?}>",
305
+ rollback: "string[]",
306
+ failureModes: "Array<string|{symptom,resolution?}>"
307
+ }
308
+ },
280
309
  llms: {
281
310
  enabled: llms.enabled,
282
311
  defaultTxt: DEFAULT_LLMS_TXT_ROUTE,
@@ -325,10 +354,12 @@ function buildAgentSpec({ origin, entry, i18n, search, mcp, feedback, llms, site
325
354
  "description",
326
355
  "url",
327
356
  "dateModified",
328
- "breadcrumb"
357
+ "breadcrumb",
358
+ "mainEntity"
329
359
  ],
330
360
  canonicalUrlField: "url",
331
- breadcrumbType: "BreadcrumbList"
361
+ breadcrumbType: "BreadcrumbList",
362
+ agentContractType: "HowTo"
332
363
  },
333
364
  openapi: {
334
365
  enabled: openapi.enabled,
@@ -593,7 +624,9 @@ function readCloudConfig(root) {
593
624
  } catch {}
594
625
  }
595
626
  }
596
- function readMcpConfig(root) {
627
+ const MCP_RUNTIME_SECURITY_CONFIG_ERROR = "MCP security is configured in docs.config, but createDocsMCPAPI cannot load executable security callbacks from source text. Import the live config and call createDocsMCPAPI(docsConfig), or pass an explicit mcp.security.authenticate callback. Refusing to create a public MCP endpoint.";
628
+ var McpRuntimeSecurityConfigError = class extends Error {};
629
+ function readMcpConfig(root, options = {}) {
597
630
  for (const ext of FILE_EXTS) {
598
631
  const configPath = path.join(root, `docs.config.${ext}`);
599
632
  if (!fs.existsSync(configPath)) continue;
@@ -607,6 +640,12 @@ function readMcpConfig(root) {
607
640
  if (booleanValue !== void 0) return booleanValue;
608
641
  const block = extractObjectLiteral(scopedContent, scopedSanitized, "mcp");
609
642
  if (!block) continue;
643
+ if (options.rejectRuntimeSecurity) {
644
+ const blockSanitized = stripCommentsAndStrings(block);
645
+ const hasSecurity = findTopLevelPropertyIndex(blockSanitized, "security") !== -1;
646
+ const hasAuthenticate = findTopLevelPropertyIndex(blockSanitized, "authenticate") !== -1;
647
+ if (hasSecurity || hasAuthenticate) throw new McpRuntimeSecurityConfigError(MCP_RUNTIME_SECURITY_CONFIG_ERROR);
648
+ }
610
649
  return {
611
650
  enabled: readBooleanFromBlock(block, "enabled"),
612
651
  route: readStringFromBlock(block, "route"),
@@ -615,14 +654,19 @@ function readMcpConfig(root) {
615
654
  tools: {
616
655
  listDocs: readBooleanFromBlock(block, "listDocs"),
617
656
  listPages: readBooleanFromBlock(block, "listPages"),
657
+ listTasks: readBooleanFromBlock(block, "listTasks"),
658
+ readTask: readBooleanFromBlock(block, "readTask"),
618
659
  readPage: readBooleanFromBlock(block, "readPage"),
619
660
  searchDocs: readBooleanFromBlock(block, "searchDocs"),
620
661
  getNavigation: readBooleanFromBlock(block, "getNavigation"),
621
662
  getCodeExamples: readBooleanFromBlock(block, "getCodeExamples"),
622
- getConfigSchema: readBooleanFromBlock(block, "getConfigSchema")
663
+ getConfigSchema: readBooleanFromBlock(block, "getConfigSchema"),
664
+ getContext: readBooleanFromBlock(block, "getContext")
623
665
  }
624
666
  };
625
- } catch {}
667
+ } catch (error) {
668
+ if (error instanceof McpRuntimeSecurityConfigError) throw error;
669
+ }
626
670
  }
627
671
  }
628
672
  function readStringFromBlock(block, key) {
@@ -897,6 +941,7 @@ function scanDocsDir(docsDir, entry, locale, excludedDirs = [], publicPath = `/$
897
941
  title,
898
942
  description,
899
943
  relatedInput: data.related,
944
+ agent: normalizePageAgentFrontmatter(data.agent),
900
945
  content,
901
946
  rawContent,
902
947
  agentFallbackRawContent: agentRawContent !== rawContent ? agentRawContent : void 0,
@@ -958,6 +1003,7 @@ function scanChangelogDir(changelogDir, entryPath, changelogPath, locale, public
958
1003
  title,
959
1004
  description,
960
1005
  relatedInput: data.related,
1006
+ agent: normalizePageAgentFrontmatter(data.agent),
961
1007
  content,
962
1008
  rawContent,
963
1009
  agentFallbackRawContent: agentRawContent !== rawContent ? agentRawContent : void 0,
@@ -1024,10 +1070,10 @@ function normalizePublicDocsSlug(ctx, value) {
1024
1070
  if (pathname.startsWith(`${normalizedEntry}/`)) return normalizePathSegment(pathname.slice(normalizedEntry.length + 1));
1025
1071
  return normalizePathSegment(pathname);
1026
1072
  }
1027
- function getPublicMarkdownCanonicalLinkHeader({ origin, ctx, requestedPath }) {
1073
+ function getPublicMarkdownCanonicalUrl({ origin, ctx, requestedPath }) {
1028
1074
  const canonicalUrl = new URL(normalizePublicRequestedMarkdownPath(ctx, requestedPath), origin);
1029
1075
  if (ctx.locale) canonicalUrl.searchParams.set("lang", ctx.locale);
1030
- return `<${canonicalUrl.toString()}>; rel="canonical"`;
1076
+ return canonicalUrl.toString();
1031
1077
  }
1032
1078
  function findDocsMcpPage(entry, pages, requestedPath) {
1033
1079
  const normalizedRequest = normalizeRequestedMarkdownPath(entry, requestedPath);
@@ -1036,22 +1082,9 @@ function findDocsMcpPage(entry, pages, requestedPath) {
1036
1082
  for (const page of pages) if (normalizePathSegment(page.slug) === normalizedSlug) return page;
1037
1083
  return null;
1038
1084
  }
1039
- function acceptsMarkdown(request) {
1040
- const accept = request.headers.get("accept");
1041
- if (!accept) return false;
1042
- return accept.split(",").map((value) => value.trim()).some((value) => {
1043
- const [mediaType, ...params] = value.split(";").map((part) => part.trim().toLowerCase());
1044
- if (mediaType !== "text/markdown") return false;
1045
- const qualityParam = params.find((param) => param.split("=", 1)[0]?.trim() === "q");
1046
- if (!qualityParam) return true;
1047
- const qualityValue = qualityParam.slice(qualityParam.indexOf("=") + 1).trim();
1048
- const quality = Number.parseFloat(qualityValue);
1049
- return Number.isFinite(quality) ? quality > 0 : true;
1050
- });
1051
- }
1052
1085
  function resolveMarkdownHeaderDelivery(request) {
1053
1086
  if (hasDocsMarkdownSignatureAgent(request)) return "signature_agent";
1054
- if (acceptsMarkdown(request)) return "accept_header";
1087
+ if (acceptsDocsMarkdown(request)) return "accept_header";
1055
1088
  const agentDetection = detectDocsMarkdownAgentRequest(request);
1056
1089
  if (!agentDetection.detected) return null;
1057
1090
  return agentDetection.method === "heuristic" ? "heuristic" : "user_agent";
@@ -2550,7 +2583,7 @@ function createDocsAPI(options) {
2550
2583
  markdownSourcesByLocale.set(key, sources);
2551
2584
  return sources;
2552
2585
  }
2553
- async function getMarkdownDocument(ctx, requestedPath, origin) {
2586
+ async function getMarkdownRepresentation(ctx, requestedPath, origin) {
2554
2587
  const normalizedRequest = normalizeRequestedMarkdownPath(ctx.entryPath, requestedPath);
2555
2588
  const normalizedPublicRequest = normalizePublicRequestedMarkdownPath(ctx, requestedPath);
2556
2589
  const normalizedEntry = `/${normalizePathSegment(ctx.entryPath)}`;
@@ -2558,27 +2591,36 @@ function createDocsAPI(options) {
2558
2591
  for (const docsDir of ctx.docsDirs) if (isHiddenFolderIndexPageDir(relativeSlug ? path.join(docsDir, ...relativeSlug.split("/")) : docsDir)) return null;
2559
2592
  for (const source of getMarkdownSources(ctx)) {
2560
2593
  const page = findDocsMcpPage(ctx.entryPath, await source.getPages(), requestedPath);
2561
- if (page) return renderMarkdownDocument(withPublicDocsUrl(page, ctx), {
2562
- llmsEnabled: llmsConfig.enabled,
2563
- origin,
2564
- sitemap: sitemapConfig
2565
- });
2594
+ if (page) return {
2595
+ document: renderMarkdownDocument(withPublicDocsUrl(page, ctx), {
2596
+ llmsEnabled: llmsConfig.enabled,
2597
+ origin,
2598
+ sitemap: sitemapConfig
2599
+ }),
2600
+ lastModified: page.agentRawContent === void 0 ? page.lastModified : void 0
2601
+ };
2566
2602
  }
2567
2603
  const fallbackPage = getIndexes(ctx).find((page) => {
2568
2604
  const pageUrl = normalizeUrlPath(page.url);
2569
2605
  return pageUrl === normalizedRequest || pageUrl === normalizedPublicRequest;
2570
2606
  });
2571
- if (fallbackPage) return renderMarkdownDocument(withPublicDocsUrl(fallbackPage, ctx), {
2572
- llmsEnabled: llmsConfig.enabled,
2573
- origin,
2574
- sitemap: sitemapConfig
2575
- });
2607
+ if (fallbackPage) return {
2608
+ document: renderMarkdownDocument(withPublicDocsUrl(fallbackPage, ctx), {
2609
+ llmsEnabled: llmsConfig.enabled,
2610
+ origin,
2611
+ sitemap: sitemapConfig
2612
+ }),
2613
+ lastModified: fallbackPage.agentRawContent === void 0 ? fallbackPage.lastModified : void 0
2614
+ };
2576
2615
  const requestedSlug = normalizePublicDocsSlug(ctx, normalizedPublicRequest);
2577
- for (const page of getIndexes(ctx)) if (normalizePublicDocsSlug(ctx, page.url) === requestedSlug) return renderMarkdownDocument(withPublicDocsUrl(page, ctx), {
2578
- llmsEnabled: llmsConfig.enabled,
2579
- origin,
2580
- sitemap: sitemapConfig
2581
- });
2616
+ for (const page of getIndexes(ctx)) if (normalizePublicDocsSlug(ctx, page.url) === requestedSlug) return {
2617
+ document: renderMarkdownDocument(withPublicDocsUrl(page, ctx), {
2618
+ llmsEnabled: llmsConfig.enabled,
2619
+ origin,
2620
+ sitemap: sitemapConfig
2621
+ }),
2622
+ lastModified: page.agentRawContent === void 0 ? page.lastModified : void 0
2623
+ };
2582
2624
  return null;
2583
2625
  }
2584
2626
  function getLlmsContent(ctx) {
@@ -2765,21 +2807,15 @@ function createDocsAPI(options) {
2765
2807
  const markdownRequest = resolveMarkdownRequest(entry, url, request) ?? resolvePublicMarkdownRequest(entry, docsPath, url, request);
2766
2808
  if (markdownRequest) {
2767
2809
  const markdownOrigin = markdownMetadataBaseUrl || url.origin;
2768
- const document = await getMarkdownDocument(ctx, markdownRequest.requestedPath, markdownOrigin);
2769
- const varyHeader = getDocsMarkdownVaryHeader(request);
2770
- const canonicalLinkHeader = getPublicMarkdownCanonicalLinkHeader({
2810
+ const representation = await getMarkdownRepresentation(ctx, markdownRequest.requestedPath, markdownOrigin);
2811
+ const document = representation?.document ?? null;
2812
+ const canonicalUrl = getPublicMarkdownCanonicalUrl({
2771
2813
  origin: markdownOrigin,
2772
2814
  ctx,
2773
2815
  requestedPath: markdownRequest.requestedPath
2774
2816
  });
2775
2817
  if (!document) {
2776
2818
  const recoveryPages = getIndexes(ctx).map((page) => withPublicDocsUrl(page, ctx));
2777
- const recovery = resolveDocsMarkdownRecovery({
2778
- entry,
2779
- requestedPath: markdownRequest.requestedPath,
2780
- pages: recoveryPages,
2781
- sitemap: sitemapConfig
2782
- });
2783
2819
  await emitDocsAnalyticsEvent(analytics, {
2784
2820
  type: "agent_read",
2785
2821
  source: "server",
@@ -2806,27 +2842,16 @@ function createDocsAPI(options) {
2806
2842
  found: false
2807
2843
  }
2808
2844
  });
2809
- if (recovery.redirect) return new Response(null, {
2810
- status: 307,
2811
- headers: {
2812
- Location: new URL(recovery.redirect.markdownUrl, url.origin).toString(),
2813
- ...varyHeader ? { Vary: varyHeader } : {},
2814
- "X-Robots-Tag": "noindex"
2815
- }
2816
- });
2817
- return new Response(renderDocsMarkdownNotFound({
2845
+ return createDocsMarkdownResponse({
2846
+ request,
2847
+ document: null,
2818
2848
  entry,
2819
2849
  requestedPath: markdownRequest.requestedPath,
2820
2850
  origin: markdownOrigin,
2851
+ canonicalUrl,
2852
+ locale: ctx.locale,
2821
2853
  pages: recoveryPages,
2822
2854
  sitemap: sitemapConfig
2823
- }), {
2824
- status: 200,
2825
- headers: {
2826
- "Content-Type": "text/markdown; charset=utf-8",
2827
- ...varyHeader ? { Vary: varyHeader } : {},
2828
- "X-Robots-Tag": "noindex"
2829
- }
2830
2855
  });
2831
2856
  }
2832
2857
  await emitDocsAnalyticsEvent(analytics, {
@@ -2857,13 +2882,17 @@ function createDocsAPI(options) {
2857
2882
  contentLength: document.length
2858
2883
  }
2859
2884
  });
2860
- return new Response(document, { headers: {
2861
- "Content-Type": "text/markdown; charset=utf-8",
2862
- "Cache-Control": "public, max-age=0, s-maxage=3600",
2863
- Link: canonicalLinkHeader,
2864
- ...varyHeader ? { Vary: varyHeader } : {},
2865
- "X-Robots-Tag": "noindex"
2866
- } });
2885
+ return createDocsMarkdownResponse({
2886
+ request,
2887
+ document,
2888
+ entry,
2889
+ requestedPath: markdownRequest.requestedPath,
2890
+ origin: markdownOrigin,
2891
+ canonicalUrl,
2892
+ locale: ctx.locale,
2893
+ lastModified: representation?.lastModified,
2894
+ sitemap: sitemapConfig
2895
+ });
2867
2896
  }
2868
2897
  const llmsRequest = resolveDocsLlmsTxtRequest(url, llmsConfig, docsPath);
2869
2898
  if (llmsRequest) {
@@ -3040,7 +3069,7 @@ function createDocsAPI(options) {
3040
3069
  /**
3041
3070
  * Create MCP route handlers for `/api/docs/mcp`.
3042
3071
  *
3043
- * Returns `{ GET, POST, DELETE }` for use in a Next.js route handler.
3072
+ * Returns `{ GET, POST, DELETE, OPTIONS }` for use in a Next.js route handler.
3044
3073
  */
3045
3074
  /**
3046
3075
  * @deprecated Prefer `createDocsMCPAPI` from `@farming-labs/next/api` in Next.js apps.
@@ -3051,6 +3080,7 @@ function createDocsMCPAPI(options = {}) {
3051
3080
  const entry = options.entry ?? readEntry(rootDir);
3052
3081
  const appDir = getNextAppDir(rootDir);
3053
3082
  const contentDir = options.contentDir ?? path.join(appDir, entry);
3083
+ const mcpConfig = options.mcp ?? readMcpConfig(rootDir, { rejectRuntimeSecurity: true });
3054
3084
  const navTitle = typeof options.nav?.title === "string" && options.nav.title.trim().length > 0 ? options.nav.title : "Documentation";
3055
3085
  const handlers = createDocsMcpHttpHandler({
3056
3086
  source: createFilesystemDocsMcpSource({
@@ -3060,7 +3090,7 @@ function createDocsMCPAPI(options = {}) {
3060
3090
  siteTitle: navTitle,
3061
3091
  ordering: options.ordering
3062
3092
  }),
3063
- mcp: options.mcp ?? readMcpConfig(rootDir),
3093
+ mcp: mcpConfig,
3064
3094
  search: options.search,
3065
3095
  analytics: options.analytics,
3066
3096
  telemetry: options.telemetry,
@@ -3077,6 +3107,9 @@ function createDocsMCPAPI(options = {}) {
3077
3107
  },
3078
3108
  DELETE(request) {
3079
3109
  return handlers.DELETE({ request });
3110
+ },
3111
+ OPTIONS(request) {
3112
+ return handlers.OPTIONS({ request });
3080
3113
  }
3081
3114
  };
3082
3115
  }
@@ -13,7 +13,7 @@ import path from "node:path";
13
13
  import matter from "gray-matter";
14
14
  import { DocsLayout } from "fumadocs-ui/layouts/docs";
15
15
  import { Suspense } from "react";
16
- import { applySidebarFolderIndexBehavior, buildPageOpenGraph, buildPageTwitter, renderDocsPageStructuredDataJson, resolveChangelogConfig, resolveDocsAgentMdxContent, resolveDocsAnalyticsConfig, resolveDocsMetadataBaseUrl, resolvePageSidebarFolderIndexBehavior, toDocsMarkdownUrl } from "@farming-labs/docs";
16
+ import { applySidebarFolderIndexBehavior, buildPageOpenGraph, buildPageTwitter, normalizePageAgentFrontmatter, renderDocsPageStructuredDataJson, resolveChangelogConfig, resolveDocsAgentMdxContent, resolveDocsAnalyticsConfig, resolveDocsMetadataBaseUrl, resolvePageSidebarFolderIndexBehavior, toDocsMarkdownUrl } from "@farming-labs/docs";
17
17
  import { jsx, jsxs } from "react/jsx-runtime";
18
18
 
19
19
  //#region src/docs-layout.tsx
@@ -428,7 +428,8 @@ function buildStructuredDataMap(config, ctx) {
428
428
  url: withLangInUrl(route, ctx.locale),
429
429
  baseUrl,
430
430
  entry: ctx.entryPath,
431
- dateModified: stat.mtime.toISOString()
431
+ dateModified: stat.mtime.toISOString(),
432
+ agent: normalizePageAgentFrontmatter(data.agent)
432
433
  });
433
434
  }
434
435
  for (const name of fs.readdirSync(dir)) {
package/dist/index.d.mts CHANGED
@@ -16,8 +16,8 @@ import { HoverLink, HoverLinkProps } from "./hover-link.mjs";
16
16
  import { Prompt, PromptProps } from "./prompt.mjs";
17
17
  import { Agent, CodeGroup } from "./mdx.mjs";
18
18
  import { DocsLayout } from "fumadocs-ui/layouts/docs";
19
- import { AIConfig, BreadcrumbConfig, ChangelogConfig, ChangelogFrontmatter, CopyMarkdownConfig, CopyMarkdownFormat, DocsConfig, DocsFeedbackData, DocsFeedbackValue, DocsMetadata, DocsNav, DocsTheme, FeedbackConfig, FontStyle, OGConfig, OpenDocsConfig, OpenDocsProvider, PageActionsConfig, PageFrontmatter, SidebarConfig, ThemeToggleConfig, TypographyConfig, UIConfig, createTheme, deepMerge, defineDocs, extendTheme } from "@farming-labs/docs";
19
+ import { AIConfig, BreadcrumbConfig, ChangelogConfig, ChangelogFrontmatter, CopyMarkdownConfig, CopyMarkdownFormat, DocsConfig, DocsFeedbackData, DocsFeedbackValue, DocsMetadata, DocsNav, DocsTheme, FeedbackConfig, FontStyle, OGConfig, OpenDocsConfig, OpenDocsProvider, PageActionsConfig, PageAgentAppliesTo, PageAgentCommand, PageAgentFailureMode, PageAgentFrontmatter, PageAgentVerification, PageFrontmatter, SidebarConfig, ThemeToggleConfig, TypographyConfig, UIConfig, createTheme, deepMerge, defineDocs, extendTheme } from "@farming-labs/docs";
20
20
  import { DocsBody, DocsPage } from "fumadocs-ui/layouts/docs/page";
21
21
  import { Tab, Tabs } from "fumadocs-ui/components/tabs";
22
22
  import { CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, Pre } from "fumadocs-ui/components/codeblock";
23
- export { type AIConfig, Agent, type BreadcrumbConfig, type ChangelogConfig, type ChangelogFrontmatter, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, CodeGroup, CommandGridUIDefaults, ConcreteUIDefaults, type CopyMarkdownConfig, type CopyMarkdownFormat, DocsBody, DocsClientHooks, DocsCommandSearch, type DocsConfig, DocsFeedback, type DocsFeedbackData, type DocsFeedbackProps, type DocsFeedbackValue, DocsLayout, type DocsMetadata, type DocsNav, DocsPage, DocsPageClient, type DocsTheme, type FeedbackConfig, type FontStyle, DefaultUIDefaults as FumadocsUIDefaults, HardlineUIDefaults, HoverLink, type HoverLinkProps, LedgerUIDefaults, type OGConfig, type OpenDocsConfig, type OpenDocsProvider, PageActions, type PageActionsConfig, type PageFrontmatter, Pre, Prompt, type PromptProps, RootProvider, type SidebarConfig, Tab, Tabs, type ThemeToggleConfig, ThreadlineUIDefaults, type TypographyConfig, type UIConfig, commandGrid, concrete, createDocsLayout, createDocsMetadata, createPageMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs, hardline, ledger, threadline, threadlinePageActions, withLangInUrl };
23
+ export { type AIConfig, Agent, type BreadcrumbConfig, type ChangelogConfig, type ChangelogFrontmatter, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, CodeGroup, CommandGridUIDefaults, ConcreteUIDefaults, type CopyMarkdownConfig, type CopyMarkdownFormat, DocsBody, DocsClientHooks, DocsCommandSearch, type DocsConfig, DocsFeedback, type DocsFeedbackData, type DocsFeedbackProps, type DocsFeedbackValue, DocsLayout, type DocsMetadata, type DocsNav, DocsPage, DocsPageClient, type DocsTheme, type FeedbackConfig, type FontStyle, DefaultUIDefaults as FumadocsUIDefaults, HardlineUIDefaults, HoverLink, type HoverLinkProps, LedgerUIDefaults, type OGConfig, type OpenDocsConfig, type OpenDocsProvider, PageActions, type PageActionsConfig, type PageAgentAppliesTo, type PageAgentCommand, type PageAgentFailureMode, type PageAgentFrontmatter, type PageAgentVerification, type PageFrontmatter, Pre, Prompt, type PromptProps, RootProvider, type SidebarConfig, Tab, Tabs, type ThemeToggleConfig, ThreadlineUIDefaults, type TypographyConfig, type UIConfig, commandGrid, concrete, createDocsLayout, createDocsMetadata, createPageMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs, hardline, ledger, threadline, threadlinePageActions, withLangInUrl };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/theme",
3
- "version": "0.2.52",
3
+ "version": "0.2.54",
4
4
  "description": "Theme package for @farming-labs/docs — layout, provider, MDX components, and styles",
5
5
  "keywords": [
6
6
  "docs",
@@ -146,7 +146,7 @@
146
146
  "tsdown": "^0.20.3",
147
147
  "typescript": "^5.9.3",
148
148
  "vitest": "^4.1.8",
149
- "@farming-labs/docs": "0.2.52"
149
+ "@farming-labs/docs": "0.2.54"
150
150
  },
151
151
  "peerDependencies": {
152
152
  "@farming-labs/docs": ">=0.0.1",