@farming-labs/docs 0.2.53 → 0.2.55

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 (51) hide show
  1. package/dist/agent-BOOcHVDL.mjs +623 -0
  2. package/dist/{agent-BMxMpEa0.mjs → agent-DXkXi-pS.mjs} +590 -19
  3. package/dist/agent-evals-BD17jOqL.mjs +1166 -0
  4. package/dist/{agent-export--X9Go-wj.mjs → agent-export-BYznnYed.mjs} +9 -8
  5. package/dist/agent-scope-B8lptqCd.mjs +283 -0
  6. package/dist/agent-surface-drift-LS8zQgbq.mjs +1429 -0
  7. package/dist/{agents-CW-zTNKP.mjs → agents-BHzeeY45.mjs} +7 -6
  8. package/dist/{analytics-BZEwTK-8.mjs → analytics-Bx44lg6d.mjs} +1 -1
  9. package/dist/cli/index.mjs +29 -29
  10. package/dist/client/react.d.mts +1 -1
  11. package/dist/client/react.mjs +1 -1
  12. package/dist/{cloud-zs0qAnKJ.mjs → cloud-HWFlbfLJ.mjs} +4 -4
  13. package/dist/{cloud-ask-ai-BFlx8VMO.mjs → cloud-ask-ai-1k0q6OAH.mjs} +1 -1
  14. package/dist/{cloud-ask-ai-CMzYVzVX.d.mts → cloud-ask-ai-CvRVnwdK.d.mts} +1 -1
  15. package/dist/code-blocks-C9awWzEQ.mjs +871 -0
  16. package/dist/codeblocks-BzfkREEC.mjs +250 -0
  17. package/dist/{config-DhIyFsy9.mjs → config-CydaZ5PB.mjs} +52 -11
  18. package/dist/{dev-DFeVU2Ui.mjs → dev-BA2kRuCn.mjs} +3 -3
  19. package/dist/docs-cloud-server.d.mts +2 -2
  20. package/dist/docs-cloud-server.mjs +2 -2
  21. package/dist/{doctor-CkM5tKdD.mjs → doctor-CNIPJdxN.mjs} +150 -32
  22. package/dist/{downgrade-Dj_KXV11.mjs → downgrade-BStNhyCc.mjs} +2 -2
  23. package/dist/index.d.mts +40 -17
  24. package/dist/index.mjs +6 -7
  25. package/dist/{init-Cmz-oqnp.mjs → init-gnHQ_Pz9.mjs} +3 -3
  26. package/dist/{mcp-B4Q1PN93.mjs → mcp-F9zkBHrU.mjs} +6 -5
  27. package/dist/mcp.d.mts +22 -4
  28. package/dist/mcp.mjs +521 -43
  29. package/dist/{package-version-DxnTZH4m.mjs → package-version-DRIc08EU.mjs} +1 -1
  30. package/dist/{reading-time-BuK2YL23.mjs → reading-time-BrTd3DIh.mjs} +2 -3
  31. package/dist/{review-BEsbm0l2.mjs → review-Dlb8dRRx.mjs} +149 -14
  32. package/dist/{robots-BOwkq9du.mjs → robots-4BUJxlvV.mjs} +4 -5
  33. package/dist/{robots-C6uQG-fS.mjs → robots-DAptQnkx.mjs} +1 -1
  34. package/dist/{search-CtAXkk_J.mjs → search-B8cF77_i.mjs} +6 -5
  35. package/dist/{search-CTu6Bvq-.d.mts → search-BnQKgDbk.d.mts} +1 -1
  36. package/dist/{search-CJNLkdjX.mjs → search-CEg1omHv.mjs} +54 -11
  37. package/dist/server.d.mts +108 -5
  38. package/dist/server.mjs +9 -9
  39. package/dist/{sitemap-OPb8EdNe.mjs → sitemap-D9ivTLm8.mjs} +8 -7
  40. package/dist/{sitemap-server-DnilMEiZ.mjs → sitemap-server-wsNLyVkb.mjs} +1 -1
  41. package/dist/{types-CdKu8KmO.d.mts → types-R-DN23yw.d.mts} +79 -2
  42. package/dist/{upgrade-BNdBB9tQ.mjs → upgrade-CXYRNV0C.mjs} +2 -2
  43. package/package.json +2 -2
  44. package/dist/agent-2t4kZLGo.mjs +0 -10
  45. package/dist/agent-contract-b0akaPcg.mjs +0 -573
  46. package/dist/codeblocks-DWM4IJPL.mjs +0 -1710
  47. package/dist/review-BHdy75TE.mjs +0 -541
  48. /package/dist/{cloud-analytics-Dlk_byos.mjs → cloud-analytics-CSyFE6SS.mjs} +0 -0
  49. /package/dist/{errors-BxfYhp1L.mjs → errors-BFUtdZfC.mjs} +0 -0
  50. /package/dist/{templates-Bty9M6lA.mjs → templates-1Cod8KrJ.mjs} +0 -0
  51. /package/dist/{utils-CMZTjRQT.mjs → utils-DBCCkkJS.mjs} +0 -0
package/dist/mcp.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { a as emitDocsAnalyticsEvent, i as emitDocsAgentTraceEvent, n as createDocsAgentTraceContext, r as createDocsAgentTraceId } from "./analytics-BZEwTK-8.mjs";
2
- import { a as normalizePageAgentFrontmatter, i as hasStructuredPageAgentContract, l as upsertPageAgentContractMarkdown } from "./agent-contract-b0akaPcg.mjs";
3
- import { It as normalizeDocsRelated, Lt as renderDocsRelatedMarkdownLines } from "./agent-BMxMpEa0.mjs";
4
- import { C as resolvePageSidebarFolderIndexBehavior, E as emitDocsTelemetryAgentSurfaceEvent, O as emitDocsTelemetryMcpToolEvent, k as emitDocsTelemetryProjectEvent, m as parseDocsMarkdownSections, p as findDocsMarkdownSection, u as performDocsSearch, x as stripGeneratedAgentProvenance } from "./search-CJNLkdjX.mjs";
1
+ import { a as emitDocsAnalyticsEvent, i as emitDocsAgentTraceEvent, n as createDocsAgentTraceContext, r as createDocsAgentTraceId } from "./analytics-Bx44lg6d.mjs";
2
+ import { Gt as hasStructuredPageAgentContract, Kt as normalizePageAgentFrontmatter, Lt as normalizeDocsRelated, Rt as renderDocsRelatedMarkdownLines, Xt as upsertPageAgentContractMarkdown } from "./agent-DXkXi-pS.mjs";
3
+ import { C as resolvePageSidebarFolderIndexBehavior, E as emitDocsTelemetryAgentSurfaceEvent, O as emitDocsTelemetryMcpToolEvent, k as emitDocsTelemetryProjectEvent, m as parseDocsMarkdownSections, p as findDocsMarkdownSection, u as performDocsSearch, x as stripGeneratedAgentProvenance } from "./search-CEg1omHv.mjs";
4
+ import { a as normalizeAgentScopeValues, i as normalizeAgentLocale, n as agentVersionConstraintsOverlap, r as normalizeAgentFramework, t as agentVersionConstraintMatches } from "./agent-scope-B8lptqCd.mjs";
5
5
  import matter from "gray-matter";
6
6
  import fs from "node:fs";
7
7
  import path from "node:path";
@@ -34,7 +34,22 @@ const DEFAULT_DOCS_MCP_CORS_EXPOSED_HEADERS = Object.freeze([
34
34
  "MCP-Session-Id",
35
35
  "WWW-Authenticate"
36
36
  ]);
37
- const DOCS_CONFIG_SCHEMA_OPTIONS = [
37
+ function freezeDocsConfigSchemaOptions(options) {
38
+ for (const option of options) {
39
+ if (option.values) Object.freeze(option.values);
40
+ if (option.children) {
41
+ freezeDocsConfigSchemaOptions([...option.children]);
42
+ Object.freeze(option.children);
43
+ }
44
+ Object.freeze(option);
45
+ }
46
+ return Object.freeze(options);
47
+ }
48
+ function freezeDocsConfigSchemaExamples(examples) {
49
+ for (const example of examples) Object.freeze(example);
50
+ return Object.freeze(examples);
51
+ }
52
+ const DOCS_CONFIG_SCHEMA_OPTIONS_TEMPLATE = [
38
53
  {
39
54
  path: "entry",
40
55
  name: "entry",
@@ -43,6 +58,14 @@ const DOCS_CONFIG_SCHEMA_OPTIONS = [
43
58
  description: "URL path prefix for documentation routes, for example \"docs\" creates /docs.",
44
59
  docs: "/docs/overview"
45
60
  },
61
+ {
62
+ path: "docsPath",
63
+ name: "docsPath",
64
+ type: "string",
65
+ default: "same as entry",
66
+ description: "Public route prefix for docs pages when it differs from the source entry directory.",
67
+ docs: "/docs/overview"
68
+ },
46
69
  {
47
70
  path: "contentDir",
48
71
  name: "contentDir",
@@ -51,6 +74,13 @@ const DOCS_CONFIG_SCHEMA_OPTIONS = [
51
74
  description: "Path to markdown content files. Adapters outside Next.js usually need this when content does not live under the route prefix.",
52
75
  docs: "/docs/overview"
53
76
  },
77
+ {
78
+ path: "i18n",
79
+ name: "i18n",
80
+ type: "DocsI18nConfig",
81
+ description: "Locale discovery, default locale, and localized docs content configuration.",
82
+ docs: "/docs/reference"
83
+ },
54
84
  {
55
85
  path: "staticExport",
56
86
  name: "staticExport",
@@ -66,6 +96,25 @@ const DOCS_CONFIG_SCHEMA_OPTIONS = [
66
96
  description: "Theme instance from a theme factory such as fumadocs() or pixelBorder().",
67
97
  docs: "/docs/customization/themes"
68
98
  },
99
+ {
100
+ path: "analytics",
101
+ name: "analytics",
102
+ type: "boolean | DocsAnalyticsConfig",
103
+ default: false,
104
+ description: "Built-in privacy-aware product and agent surface analytics."
105
+ },
106
+ {
107
+ path: "telemetry",
108
+ name: "telemetry",
109
+ type: "boolean | DocsTelemetryConfig",
110
+ description: "Project telemetry controls for framework and agent-surface events."
111
+ },
112
+ {
113
+ path: "observability",
114
+ name: "observability",
115
+ type: "boolean | DocsObservabilityConfig",
116
+ description: "Tracing and observability callbacks for search, AI, and agent operations."
117
+ },
69
118
  {
70
119
  path: "nav",
71
120
  name: "nav",
@@ -155,12 +204,419 @@ const DOCS_CONFIG_SCHEMA_OPTIONS = [
155
204
  default: false,
156
205
  description: "Opt-in estimated reading time label with per-page overrides and label format."
157
206
  },
207
+ {
208
+ path: "lastUpdated",
209
+ name: "lastUpdated",
210
+ type: "boolean | LastUpdatedConfig",
211
+ description: "Last-updated metadata and labels derived from source history or page data."
212
+ },
213
+ {
214
+ path: "ordering",
215
+ name: "ordering",
216
+ type: "\"alphabetical\" | \"numeric\" | OrderingItem[]",
217
+ description: "Navigation ordering strategy or explicit ordered navigation entries."
218
+ },
158
219
  {
159
220
  path: "agent",
160
221
  name: "agent",
161
222
  type: "DocsAgentConfig",
162
- description: "Defaults for docs agent compact and generated agent-facing files.",
163
- docs: "/docs/getting-started/agent-ready-docs"
223
+ description: "Agent compaction defaults and deterministic usefulness evaluations.",
224
+ docs: "/docs/getting-started/agent-ready-docs",
225
+ children: [{
226
+ path: "agent.compact",
227
+ name: "compact",
228
+ type: "DocsAgentCompactConfig",
229
+ description: "Defaults for generated agent.md compaction.",
230
+ children: [
231
+ {
232
+ path: "agent.compact.apiKey",
233
+ name: "apiKey",
234
+ type: "string",
235
+ description: "Direct compaction provider API key; prefer apiKeyEnv."
236
+ },
237
+ {
238
+ path: "agent.compact.apiKeyEnv",
239
+ name: "apiKeyEnv",
240
+ type: "string",
241
+ description: "Environment variable containing the compaction provider API key."
242
+ },
243
+ {
244
+ path: "agent.compact.baseUrl",
245
+ name: "baseUrl",
246
+ type: "string",
247
+ description: "Compaction provider base URL."
248
+ },
249
+ {
250
+ path: "agent.compact.model",
251
+ name: "model",
252
+ type: "string",
253
+ description: "Compaction model identifier."
254
+ },
255
+ {
256
+ path: "agent.compact.aggressiveness",
257
+ name: "aggressiveness",
258
+ type: "number",
259
+ default: .3,
260
+ description: "Compression aggressiveness from 0 to 1."
261
+ },
262
+ {
263
+ path: "agent.compact.maxOutputTokens",
264
+ name: "maxOutputTokens",
265
+ type: "number",
266
+ description: "Upper output token target."
267
+ },
268
+ {
269
+ path: "agent.compact.minOutputTokens",
270
+ name: "minOutputTokens",
271
+ type: "number",
272
+ description: "Lower output token target."
273
+ },
274
+ {
275
+ path: "agent.compact.protectJson",
276
+ name: "protectJson",
277
+ type: "boolean",
278
+ description: "Preserve JSON objects during compaction when supported."
279
+ }
280
+ ]
281
+ }, {
282
+ path: "agent.evaluations",
283
+ name: "evaluations",
284
+ type: "boolean | DocsAgentEvaluationsConfig",
285
+ description: "Deterministic golden tasks for retrieval, citation, version, example, and budget evaluation.",
286
+ children: [
287
+ {
288
+ path: "agent.evaluations.enabled",
289
+ name: "enabled",
290
+ type: "boolean",
291
+ default: true,
292
+ description: "Enable configured golden-task evaluation."
293
+ },
294
+ {
295
+ path: "agent.evaluations.tokenBudget",
296
+ name: "tokenBudget",
297
+ type: "number",
298
+ default: 4e3,
299
+ description: "Default hard UTF-8 context-byte ceiling for golden tasks."
300
+ },
301
+ {
302
+ path: "agent.evaluations.topK",
303
+ name: "topK",
304
+ type: "number",
305
+ default: 5,
306
+ description: "Default number of ranked search results evaluated per task."
307
+ },
308
+ {
309
+ path: "agent.evaluations.tasks",
310
+ name: "tasks",
311
+ type: "DocsAgentGoldenTask[]",
312
+ description: "Offline golden task fixtures evaluated by docs doctor and docs review.",
313
+ children: [
314
+ {
315
+ path: "agent.evaluations.tasks[]",
316
+ name: "task",
317
+ type: "DocsAgentGoldenTask",
318
+ description: "One golden task entry."
319
+ },
320
+ {
321
+ path: "agent.evaluations.tasks[].id",
322
+ name: "id",
323
+ type: "string",
324
+ description: "Stable task identifier shown in diagnostics."
325
+ },
326
+ {
327
+ path: "agent.evaluations.tasks[].query",
328
+ name: "query",
329
+ type: "string",
330
+ description: "User-shaped retrieval query."
331
+ },
332
+ {
333
+ path: "agent.evaluations.tasks[].tokenBudget",
334
+ name: "tokenBudget",
335
+ type: "number",
336
+ description: "Per-task UTF-8 context-byte ceiling override."
337
+ },
338
+ {
339
+ path: "agent.evaluations.tasks[].topK",
340
+ name: "topK",
341
+ type: "number",
342
+ description: "Per-task ranked retrieval depth override."
343
+ },
344
+ {
345
+ path: "agent.evaluations.tasks[].filters",
346
+ name: "filters",
347
+ type: "DocsAgentGoldenTaskFilters",
348
+ description: "Framework, version, and locale retrieval scope.",
349
+ children: [
350
+ {
351
+ path: "agent.evaluations.tasks[].filters.framework",
352
+ name: "framework",
353
+ type: "string",
354
+ description: "Required framework, such as nextjs or astro."
355
+ },
356
+ {
357
+ path: "agent.evaluations.tasks[].filters.version",
358
+ name: "version",
359
+ type: "string",
360
+ description: "Exact version requested by the task."
361
+ },
362
+ {
363
+ path: "agent.evaluations.tasks[].filters.locale",
364
+ name: "locale",
365
+ type: "string",
366
+ description: "Required locale."
367
+ }
368
+ ]
369
+ },
370
+ {
371
+ path: "agent.evaluations.tasks[].expect",
372
+ name: "expect",
373
+ type: "DocsAgentGoldenTaskExpectation",
374
+ description: "Deterministic sources, rank, citation, example, and budget expectations.",
375
+ children: [
376
+ {
377
+ path: "agent.evaluations.tasks[].expect.relevantSources",
378
+ name: "relevantSources",
379
+ type: "string[]",
380
+ description: "Canonical page or section URLs that should answer the task."
381
+ },
382
+ {
383
+ path: "agent.evaluations.tasks[].expect.allowedSources",
384
+ name: "allowedSources",
385
+ type: "string[]",
386
+ description: "Additional legitimate citations that do not reduce precision."
387
+ },
388
+ {
389
+ path: "agent.evaluations.tasks[].expect.forbiddenSources",
390
+ name: "forbiddenSources",
391
+ type: "string[]",
392
+ description: "Sources that must not be retrieved or cited."
393
+ },
394
+ {
395
+ path: "agent.evaluations.tasks[].expect.requiredCitations",
396
+ name: "requiredCitations",
397
+ type: "string[]",
398
+ description: "Citations that must appear; defaults to relevantSources."
399
+ },
400
+ {
401
+ path: "agent.evaluations.tasks[].expect.minRecallAtK",
402
+ name: "minRecallAtK",
403
+ type: "number",
404
+ default: 1,
405
+ description: "Minimum relevant-source recall in the top K results."
406
+ },
407
+ {
408
+ path: "agent.evaluations.tasks[].expect.maxFirstRelevantRank",
409
+ name: "maxFirstRelevantRank",
410
+ type: "number",
411
+ description: "Maximum acceptable rank of the first relevant source."
412
+ },
413
+ {
414
+ path: "agent.evaluations.tasks[].expect.minUsefulByteRatio",
415
+ name: "minUsefulByteRatio",
416
+ type: "number",
417
+ description: "Minimum share of context bytes supplied by relevant sources."
418
+ },
419
+ {
420
+ path: "agent.evaluations.tasks[].expect.examples",
421
+ name: "examples",
422
+ type: "DocsAgentGoldenExpectedExample[]",
423
+ description: "Runnable examples that must be present in returned context.",
424
+ children: [
425
+ {
426
+ path: "agent.evaluations.tasks[].expect.examples[]",
427
+ name: "example",
428
+ type: "DocsAgentGoldenExpectedExample",
429
+ description: "One expected code example."
430
+ },
431
+ {
432
+ path: "agent.evaluations.tasks[].expect.examples[].source",
433
+ name: "source",
434
+ type: "string",
435
+ description: "Canonical source URL containing the example."
436
+ },
437
+ {
438
+ path: "agent.evaluations.tasks[].expect.examples[].language",
439
+ name: "language",
440
+ type: "string",
441
+ description: "Expected code-fence language."
442
+ },
443
+ {
444
+ path: "agent.evaluations.tasks[].expect.examples[].framework",
445
+ name: "framework",
446
+ type: "string",
447
+ description: "Expected framework metadata."
448
+ },
449
+ {
450
+ path: "agent.evaluations.tasks[].expect.examples[].packageManager",
451
+ name: "packageManager",
452
+ type: "string",
453
+ description: "Expected package-manager metadata."
454
+ },
455
+ {
456
+ path: "agent.evaluations.tasks[].expect.examples[].title",
457
+ name: "title",
458
+ type: "string",
459
+ description: "Expected code-fence title metadata."
460
+ },
461
+ {
462
+ path: "agent.evaluations.tasks[].expect.examples[].runnable",
463
+ name: "runnable",
464
+ type: "boolean",
465
+ default: true,
466
+ description: "Whether the example must be marked runnable."
467
+ },
468
+ {
469
+ path: "agent.evaluations.tasks[].expect.examples[].includes",
470
+ name: "includes",
471
+ type: "string[]",
472
+ description: "Literal code fragments that must appear."
473
+ }
474
+ ]
475
+ }
476
+ ]
477
+ }
478
+ ]
479
+ }
480
+ ]
481
+ }]
482
+ },
483
+ {
484
+ path: "review",
485
+ name: "review",
486
+ type: "boolean | DocsReviewConfig",
487
+ description: "Docs review scoring, CI behavior, and diagnostic rule severities.",
488
+ docs: "/docs/reference",
489
+ children: [
490
+ {
491
+ path: "review.enabled",
492
+ name: "enabled",
493
+ type: "boolean",
494
+ default: true,
495
+ description: "Enable Docs Review."
496
+ },
497
+ {
498
+ path: "review.score",
499
+ name: "score",
500
+ type: "DocsReviewScoreConfig",
501
+ description: "Healthy threshold and finding severity weights.",
502
+ children: [{
503
+ path: "review.score.threshold",
504
+ name: "threshold",
505
+ type: "number",
506
+ default: 80,
507
+ description: "Minimum healthy review score."
508
+ }, {
509
+ path: "review.score.weights",
510
+ name: "weights",
511
+ type: "{ error?: number; warn?: number; suggestion?: number }",
512
+ description: "Point deductions for each finding severity.",
513
+ children: [
514
+ {
515
+ path: "review.score.weights.error",
516
+ name: "error",
517
+ type: "number",
518
+ default: 20,
519
+ description: "Point deduction for an error finding."
520
+ },
521
+ {
522
+ path: "review.score.weights.warn",
523
+ name: "warn",
524
+ type: "number",
525
+ default: 8,
526
+ description: "Point deduction for a warning finding."
527
+ },
528
+ {
529
+ path: "review.score.weights.suggestion",
530
+ name: "suggestion",
531
+ type: "number",
532
+ default: 2,
533
+ description: "Point deduction for a suggestion finding."
534
+ }
535
+ ]
536
+ }]
537
+ },
538
+ {
539
+ path: "review.ci",
540
+ name: "ci",
541
+ type: "boolean | DocsReviewCiConfig",
542
+ description: "GitHub Actions reporting and blocking behavior.",
543
+ children: [
544
+ {
545
+ path: "review.ci.enabled",
546
+ name: "enabled",
547
+ type: "boolean",
548
+ default: true,
549
+ description: "Enable review workflow generation."
550
+ },
551
+ {
552
+ path: "review.ci.name",
553
+ name: "name",
554
+ type: "string",
555
+ default: "docs-review",
556
+ description: "GitHub Actions job and check name."
557
+ },
558
+ {
559
+ path: "review.ci.mode",
560
+ name: "mode",
561
+ type: "\"off\" | \"warn\" | \"block\"",
562
+ default: "warn",
563
+ description: "Whether CI is disabled, advisory, or blocking.",
564
+ values: [
565
+ "off",
566
+ "warn",
567
+ "block"
568
+ ]
569
+ },
570
+ {
571
+ path: "review.ci.annotations",
572
+ name: "annotations",
573
+ type: "boolean",
574
+ default: true,
575
+ description: "Emit GitHub workflow annotations."
576
+ },
577
+ {
578
+ path: "review.ci.comment",
579
+ name: "comment",
580
+ type: "boolean",
581
+ default: true,
582
+ description: "Allow the official action or bot to post PR comments."
583
+ }
584
+ ]
585
+ },
586
+ {
587
+ path: "review.rules",
588
+ name: "rules",
589
+ type: "DocsReviewRulesConfig",
590
+ description: "Per-rule severity overrides.",
591
+ children: [
592
+ ["brokenLinks", "error"],
593
+ ["frontmatter", "error"],
594
+ ["duplicateSlugs", "error"],
595
+ ["invalidMdx", "error"],
596
+ ["configExamples", "warn"],
597
+ ["codeFenceMetadata", "warn"],
598
+ ["runnableMetadata", "warn"],
599
+ ["agentContext", "warn"],
600
+ ["commandHealth", "warn"],
601
+ ["relatedCoverage", "suggestion"],
602
+ ["configConfidence", "warn"],
603
+ ["agentSurfaceDrift", "error"],
604
+ ["goldenTasks", "warn"]
605
+ ].map(([name, defaultValue]) => ({
606
+ path: `review.rules.${name}`,
607
+ name,
608
+ type: "DocsReviewSeverity",
609
+ default: defaultValue,
610
+ description: `Severity override for the ${name} review rule.`,
611
+ values: [
612
+ "off",
613
+ "suggestion",
614
+ "warn",
615
+ "error"
616
+ ]
617
+ }))
618
+ }
619
+ ]
164
620
  },
165
621
  {
166
622
  path: "pageActions",
@@ -575,7 +1031,8 @@ const DOCS_CONFIG_SCHEMA_OPTIONS = [
575
1031
  description: "Dynamic Open Graph image configuration."
576
1032
  }
577
1033
  ];
578
- const DOCS_CONFIG_SCHEMA_EXAMPLES = [
1034
+ const DOCS_CONFIG_SCHEMA_OPTIONS = freezeDocsConfigSchemaOptions(DOCS_CONFIG_SCHEMA_OPTIONS_TEMPLATE);
1035
+ const DOCS_CONFIG_SCHEMA_EXAMPLES = freezeDocsConfigSchemaExamples([
579
1036
  {
580
1037
  title: "Minimal config",
581
1038
  code: `import { defineDocs } from "@farming-labs/docs";
@@ -634,7 +1091,7 @@ export default defineDocs({
634
1091
  },
635
1092
  });`
636
1093
  }
637
- ];
1094
+ ]);
638
1095
  const searchDocsInputSchema = z.object({
639
1096
  query: z.string().trim().min(1),
640
1097
  limit: z.number().int().min(1).max(25).optional(),
@@ -1065,6 +1522,7 @@ async function createDocsMcpServer(options) {
1065
1522
  function trackMcpTool(tool, values) {
1066
1523
  emitDocsTelemetryMcpToolEvent(telemetryConfig, {
1067
1524
  framework: telemetryFramework,
1525
+ request: options.requestContext?.request,
1068
1526
  tool,
1069
1527
  locale: values?.locale,
1070
1528
  resultCount: values?.resultCount
@@ -2792,7 +3250,7 @@ function toSearchSourcePages(pages) {
2792
3250
  agent: page.agent
2793
3251
  }));
2794
3252
  }
2795
- function getDocsConfigSchema(filters) {
3253
+ function getDocsConfigSchema(filters = {}) {
2796
3254
  const option = filters.option?.trim();
2797
3255
  const query = filters.query?.trim();
2798
3256
  let options = DOCS_CONFIG_SCHEMA_OPTIONS.map(cloneConfigSchemaOption);
@@ -2808,12 +3266,13 @@ function getDocsConfigSchema(filters) {
2808
3266
  } : void 0,
2809
3267
  resultCount: countConfigSchemaOptions(options),
2810
3268
  options,
2811
- examples: DOCS_CONFIG_SCHEMA_EXAMPLES
3269
+ examples: DOCS_CONFIG_SCHEMA_EXAMPLES.map((example) => ({ ...example }))
2812
3270
  };
2813
3271
  }
2814
3272
  function cloneConfigSchemaOption(option) {
2815
3273
  return {
2816
3274
  ...option,
3275
+ values: option.values ? [...option.values] : void 0,
2817
3276
  children: option.children?.map(cloneConfigSchemaOption)
2818
3277
  };
2819
3278
  }
@@ -3339,24 +3798,31 @@ function toStructuredDocsMcpPage(page) {
3339
3798
  function getDocsMcpSourceMarkdown(page) {
3340
3799
  return page.agentRawContent ?? page.agentFallbackRawContent ?? page.rawContent ?? page.agentContent ?? page.agentFallbackContent ?? page.content;
3341
3800
  }
3342
- function normalizeDocsMcpFramework(value) {
3343
- const normalized = value.toLowerCase().replace(/[^a-z0-9]/gu, "");
3344
- if (["next", "nextjs"].includes(normalized)) return "nextjs";
3345
- if (["tanstack", "tanstackstart"].includes(normalized)) return "tanstackstart";
3346
- if (["svelte", "sveltekit"].includes(normalized)) return "sveltekit";
3347
- return normalized;
3348
- }
3349
- function normalizeDocsMcpVersion(value) {
3350
- return value.trim().toLowerCase().replace(/^v(?=\d)/u, "");
3351
- }
3352
- function normalizeDocsMcpLocale(value) {
3353
- return value.trim().toLowerCase().replace(/_/gu, "-");
3801
+ function resolveDocsMcpScopeField(pageValue, contractValue, filter, overlaps, matchesFilter) {
3802
+ const pageValues = normalizeAgentScopeValues(pageValue);
3803
+ const contractValues = normalizeAgentScopeValues(contractValue);
3804
+ const conflict = pageValues.length > 0 && contractValues.length > 0 && !pageValues.some((topLevel) => contractValues.some((contract) => overlaps(topLevel, contract)));
3805
+ const pageMatches = !filter || pageValues.length === 0 || pageValues.some((candidate) => matchesFilter(filter, candidate));
3806
+ const contractMatches = !filter || contractValues.length === 0 || contractValues.some((candidate) => matchesFilter(filter, candidate));
3807
+ const matchedContract = filter ? contractValues.find((candidate) => matchesFilter(filter, candidate)) : void 0;
3808
+ return {
3809
+ conflict,
3810
+ matches: !conflict && pageMatches && contractMatches,
3811
+ value: pageValues[0] ?? matchedContract ?? (contractValues.length === 1 ? contractValues[0] : void 0)
3812
+ };
3354
3813
  }
3355
- function pageMatchesDocsMcpContextScope(page, filters) {
3356
- if (filters.framework && page.framework && normalizeDocsMcpFramework(page.framework) !== normalizeDocsMcpFramework(filters.framework)) return false;
3357
- if (filters.version && page.version && normalizeDocsMcpVersion(page.version) !== normalizeDocsMcpVersion(filters.version)) return false;
3358
- if (filters.locale && page.locale && normalizeDocsMcpLocale(page.locale) !== normalizeDocsMcpLocale(filters.locale)) return false;
3359
- return true;
3814
+ function resolveDocsMcpEffectiveScope(page, filters) {
3815
+ const framework = resolveDocsMcpScopeField(page.framework, page.agent?.appliesTo?.framework, filters.framework, (left, right) => normalizeAgentFramework(left) === normalizeAgentFramework(right), (filter, candidate) => normalizeAgentFramework(filter) === normalizeAgentFramework(candidate));
3816
+ const version = resolveDocsMcpScopeField(page.version, page.agent?.appliesTo?.version, filters.version, agentVersionConstraintsOverlap, agentVersionConstraintMatches);
3817
+ const locale = page.locale?.trim() || void 0;
3818
+ const localeMatches = !filters.locale || !locale || normalizeAgentLocale(locale) === normalizeAgentLocale(filters.locale);
3819
+ return {
3820
+ framework: framework.value,
3821
+ version: version.value,
3822
+ locale,
3823
+ conflict: framework.conflict || version.conflict,
3824
+ matches: framework.matches && version.matches && localeMatches
3825
+ };
3360
3826
  }
3361
3827
  function getDocsMcpResultPageUrl(value) {
3362
3828
  return value.split("#", 1)[0] ?? value;
@@ -3371,11 +3837,20 @@ function getDocsMcpResultAnchor(value) {
3371
3837
  }
3372
3838
  }
3373
3839
  async function buildDocsMcpContext(options) {
3374
- const scopedPages = options.pages.filter((page) => pageMatchesDocsMcpContextScope(page, {
3375
- framework: options.framework,
3376
- version: options.version,
3377
- locale: options.locale
3378
- }));
3840
+ const scopedPageEntries = options.pages.flatMap((page) => {
3841
+ const scope = resolveDocsMcpEffectiveScope(page, {
3842
+ framework: options.framework,
3843
+ version: options.version,
3844
+ locale: options.locale
3845
+ });
3846
+ return scope.matches && !scope.conflict ? [{
3847
+ page,
3848
+ scope
3849
+ }] : [];
3850
+ });
3851
+ const scopedPages = scopedPageEntries.map(({ page }) => page);
3852
+ const scopeByPage = new Map(scopedPageEntries.map(({ page, scope }) => [page, scope]));
3853
+ const maxResults = typeof options.maxResults === "number" && Number.isFinite(options.maxResults) ? Math.max(1, Math.min(50, Math.floor(options.maxResults))) : 50;
3379
3854
  const orderedResults = [...await performDocsSearch({
3380
3855
  pages: toSearchSourcePages(scopedPages),
3381
3856
  query: options.query,
@@ -3408,6 +3883,8 @@ async function buildDocsMcpContext(options) {
3408
3883
  }).flatMap((result) => {
3409
3884
  const page = findDocsPage(scopedPages, getDocsMcpResultPageUrl(result.url), options.entry);
3410
3885
  if (!page) return [];
3886
+ const scope = scopeByPage.get(page);
3887
+ if (!scope) return [];
3411
3888
  const document = upsertPageAgentContractMarkdown(getDocsMcpSourceMarkdown(page), page.agent);
3412
3889
  const resultAnchor = getDocsMcpResultAnchor(result.url);
3413
3890
  const selectedSection = resultAnchor ? findDocsMarkdownSection(document, resultAnchor) : result.section ? findDocsMarkdownSection(document, result.section) : void 0;
@@ -3417,24 +3894,25 @@ async function buildDocsMcpContext(options) {
3417
3894
  return [{
3418
3895
  result,
3419
3896
  page,
3897
+ scope,
3420
3898
  selectedSection,
3421
3899
  rawContent
3422
3900
  }];
3423
- });
3901
+ }).slice(0, maxResults);
3424
3902
  const maxUtf8Bytes = options.tokenBudget;
3425
3903
  const separator = "\n\n---\n\n";
3426
3904
  const separatorUtf8Bytes = docsMcpUtf8Bytes(separator);
3427
3905
  const blocks = [];
3428
3906
  const sources = [];
3429
3907
  let usedUtf8Bytes = 0;
3430
- for (const { result, page, selectedSection, rawContent } of resolvedCandidates) {
3908
+ for (const { result, page, scope, selectedSection, rawContent } of resolvedCandidates) {
3431
3909
  const anchor = selectedSection?.anchor;
3432
3910
  const sourceUrl = anchor ? `${page.url}#${anchor}` : page.url;
3433
3911
  const headerLines = [`## ${page.title}`, `Source: ${sourceUrl}`];
3434
3912
  if (selectedSection?.title) headerLines.push(`Section: ${selectedSection.title}`);
3435
- if (page.framework) headerLines.push(`Framework: ${page.framework}`);
3436
- if (page.version) headerLines.push(`Version: ${page.version}`);
3437
- if (page.locale) headerLines.push(`Locale: ${page.locale}`);
3913
+ if (scope.framework) headerLines.push(`Framework: ${scope.framework}`);
3914
+ if (scope.version) headerLines.push(`Version: ${scope.version}`);
3915
+ if (scope.locale) headerLines.push(`Locale: ${scope.locale}`);
3438
3916
  const header = headerLines.join("\n");
3439
3917
  const separatorBytes = blocks.length === 0 ? 0 : separatorUtf8Bytes;
3440
3918
  const headerBytes = docsMcpUtf8Bytes(`${header}\n\n`);
@@ -3455,10 +3933,10 @@ async function buildDocsMcpContext(options) {
3455
3933
  anchor,
3456
3934
  sourcePath: page.sourcePath,
3457
3935
  lastModified: page.lastModified,
3458
- locale: page.locale,
3459
- framework: page.framework,
3460
- version: page.version,
3461
- tags: page.tags,
3936
+ locale: scope.locale,
3937
+ framework: scope.framework,
3938
+ version: scope.version,
3939
+ tags: page.tags ? [...page.tags] : void 0,
3462
3940
  score: result.score,
3463
3941
  content: limited.text,
3464
3942
  chars: limited.text.length,
@@ -3555,4 +4033,4 @@ function toPageResourceUri(url) {
3555
4033
  }
3556
4034
 
3557
4035
  //#endregion
3558
- export { DEFAULT_DOCS_MCP_CORS_ALLOWED_HEADERS, DEFAULT_DOCS_MCP_CORS_EXPOSED_HEADERS, DEFAULT_DOCS_MCP_CORS_MAX_AGE_SECONDS, DEFAULT_DOCS_MCP_MAX_BODY_BYTES, createDocsMcpHttpHandler, createDocsMcpServer, createFilesystemDocsMcpSource, normalizeDocsMcpRoute, resolveDocsMcpConfig, runDocsMcpStdio };
4036
+ export { DEFAULT_DOCS_MCP_CORS_ALLOWED_HEADERS, DEFAULT_DOCS_MCP_CORS_EXPOSED_HEADERS, DEFAULT_DOCS_MCP_CORS_MAX_AGE_SECONDS, DEFAULT_DOCS_MCP_MAX_BODY_BYTES, DOCS_CONFIG_SCHEMA_OPTIONS, buildDocsMcpContext, createDocsMcpHttpHandler, createDocsMcpServer, createFilesystemDocsMcpSource, getDocsConfigSchema, normalizeDocsMcpRoute, resolveDocsMcpConfig, runDocsMcpStdio };