@farming-labs/docs 0.2.72 → 0.2.74

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 (55) hide show
  1. package/dist/{agent-pS2nNQS3.mjs → agent-BJ0KXN-A.mjs} +583 -765
  2. package/dist/{agent-DbDfIqhe.mjs → agent-D0LEY2Vy.mjs} +4 -3
  3. package/dist/{agent-evals-CjYzCQMZ.mjs → agent-evals-LIScgQVm.mjs} +86 -43
  4. package/dist/{agent-export-CpQhD8eA.mjs → agent-export-B92pNe6g.mjs} +12 -11
  5. package/dist/agent-skills-bundle.d.mts +1 -1
  6. package/dist/{agent-skills-server-DZnNB4_S.d.mts → agent-skills-server-BqvIGQb1.d.mts} +2 -2
  7. package/dist/{agent-skills-server-BPVv4gMg.mjs → agent-skills-server-noFn1l_p.mjs} +1 -1
  8. package/dist/agent-skills-vite.d.mts +3 -3
  9. package/dist/agent-skills-vite.mjs +2 -2
  10. package/dist/{agents-B-1h9Jlm.mjs → agents-C228QGbp.mjs} +10 -9
  11. package/dist/cli/index.mjs +34 -30
  12. package/dist/client/react.d.mts +1 -1
  13. package/dist/{cloud-ask-ai-D9gIN4Vr.d.mts → cloud-ask-ai-6X9pVjIY.d.mts} +1 -1
  14. package/dist/{cloud-CyysfDny.mjs → cloud-pdNC-tyj.mjs} +3 -3
  15. package/dist/{codeblocks-DAj7EAwt.mjs → codeblocks-CFuurVIH.mjs} +2 -2
  16. package/dist/{dev-qE7MYEh9.mjs → dev-Cc1cFFj-.mjs} +2 -2
  17. package/dist/docs-cloud-server.d.mts +2 -2
  18. package/dist/docs-cloud-server.mjs +1 -1
  19. package/dist/{doctor-CBy8-tPu.mjs → doctor-CgrUZ3tY.mjs} +15 -14
  20. package/dist/{downgrade-DCxezPZI.mjs → downgrade-w7e6Se0L.mjs} +2 -2
  21. package/dist/{golden-evaluations-DGg_eHIY.mjs → golden-evaluations-DTEPZeb0.mjs} +4 -3
  22. package/dist/index.d.mts +72 -6
  23. package/dist/index.mjs +9 -8
  24. package/dist/{init-p1MHf06G.mjs → init-DAkI0Lkf.mjs} +3 -3
  25. package/dist/markdown-rendering.d.mts +75 -0
  26. package/dist/markdown-rendering.mjs +618 -0
  27. package/dist/markdown-sections-7OoA7ylx.mjs +1492 -0
  28. package/dist/{mcp-BNK45dzD.mjs → mcp-YD37HlPY.mjs} +12 -9
  29. package/dist/mcp.d.mts +13 -2
  30. package/dist/mcp.mjs +121 -60
  31. package/dist/{metadata-D6qlWDu-.mjs → metadata-N252j5_a.mjs} +1 -1
  32. package/dist/{package-version-BXHcIm1T.mjs → package-version-n5AFur8a.mjs} +1 -1
  33. package/dist/{reading-time-DvTuW2Iy.mjs → prompt-references-BIS1eXt4.mjs} +158 -4
  34. package/dist/{search-1aftosa5.d.mts → retrieval-digest-9Kp3uSaZ.d.mts} +69 -5
  35. package/dist/{review-Cace7A2c.mjs → review-Dbzkdl6K.mjs} +10 -9
  36. package/dist/{robots-DmE_wXvG.mjs → robots-DUO0r4UI.mjs} +6 -5
  37. package/dist/{robots-C2SindI5.mjs → robots-RbgmSvPH.mjs} +2 -2
  38. package/dist/{search-BbArHODP.mjs → search-DIyIl-tE.mjs} +1288 -149
  39. package/dist/{search-DB3svkNQ.mjs → search-hcqaEZVN.mjs} +66 -27
  40. package/dist/server.d.mts +5 -5
  41. package/dist/server.mjs +10 -9
  42. package/dist/{sitemap-DPTLh_26.mjs → sitemap-jhkS_jYx.mjs} +10 -9
  43. package/dist/{sitemap-server-PUoOhplO.mjs → sitemap-server-BfyBM7_V.mjs} +1 -1
  44. package/dist/{standards-discovery-CYfiQE13.mjs → standards-discovery-BwL5ffGx.mjs} +4 -3
  45. package/dist/{standards-discovery-DRJ10g7B.d.mts → standards-discovery-CdrOE-05.d.mts} +5 -4
  46. package/dist/{types-B9DNNAdT.d.mts → types-clg5J1R4.d.mts} +60 -1
  47. package/dist/{upgrade-DDJQ5l6n.mjs → upgrade-oz-GChgt.mjs} +2 -2
  48. package/package.json +9 -1
  49. /package/dist/{cloud-ask-ai-hnJfj8-X.mjs → cloud-ask-ai-sbpjOR2K.mjs} +0 -0
  50. /package/dist/{code-blocks-qe0T8-xe.mjs → code-blocks-DnNVNK2M.mjs} +0 -0
  51. /package/dist/{config-z7_R0f86.mjs → config-Wcdj-D0a.mjs} +0 -0
  52. /package/dist/{errors-Cc_qplZU.mjs → errors-DbOhkE1h.mjs} +0 -0
  53. /package/dist/{i18n-CCaFUnAN.mjs → i18n-hHVWcflJ.mjs} +0 -0
  54. /package/dist/{templates-BJnf6B8l.mjs → templates-C6avM0U3.mjs} +0 -0
  55. /package/dist/{utils-C4RC8Zq_.mjs → utils-DpiIioYb.mjs} +0 -0
@@ -1,4 +1,5 @@
1
- import { F as resolveDocsDiscoveryApiRoute, O as buildDocsApiCatalog, P as isDocsStandardsDiscoveryRequest, S as DOCS_AGENT_MANIFEST_FORMAT, _ as DEFAULT_API_CATALOG_FORMAT, a as DEFAULT_A2A_AGENT_CARD_ROUTE, b as DEFAULT_LEGACY_SKILLS_INDEX_ROUTE, c as DEFAULT_AGENT_SKILLS_ARCHIVE_ROUTE_PATTERN, d as DEFAULT_AGENT_SKILLS_ROUTE_PATTERN, j as createDocsStandardsResponse, l as DEFAULT_AGENT_SKILLS_INDEX_FORMAT, n as API_CATALOG_MEDIA_TYPE, r as API_CATALOG_PROFILE_URI, t as AGENT_SKILLS_DISCOVERY_SCHEMA_URI, u as DEFAULT_AGENT_SKILLS_INDEX_ROUTE, v as DEFAULT_API_CATALOG_ROUTE, w as DOCS_AGENT_MANIFEST_SCHEMA_URI } from "./standards-discovery-CYfiQE13.mjs";
1
+ import { S as upsertPageAgentContractMarkdown, b as renderPageAgentFrontmatterYamlLines, o as findDocsMarkdownSection, p as PAGE_AGENT_CONTRACT_FIELD_SCHEMA, s as parseDocsMarkdownSections } from "./markdown-sections-7OoA7ylx.mjs";
2
+ import { F as isDocsStandardsDiscoveryRequest, I as resolveDocsDiscoveryApiRoute, M as createDocsStandardsResponse, S as DOCS_AGENT_MANIFEST_FORMAT, T as DOCS_AGENT_MANIFEST_VERSION, _ as DEFAULT_API_CATALOG_FORMAT, a as DEFAULT_A2A_AGENT_CARD_ROUTE, b as DEFAULT_LEGACY_SKILLS_INDEX_ROUTE, c as DEFAULT_AGENT_SKILLS_ARCHIVE_ROUTE_PATTERN, d as DEFAULT_AGENT_SKILLS_ROUTE_PATTERN, k as buildDocsApiCatalog, l as DEFAULT_AGENT_SKILLS_INDEX_FORMAT, n as API_CATALOG_MEDIA_TYPE, r as API_CATALOG_PROFILE_URI, t as AGENT_SKILLS_DISCOVERY_SCHEMA_URI, u as DEFAULT_AGENT_SKILLS_INDEX_ROUTE, v as DEFAULT_API_CATALOG_ROUTE, w as DOCS_AGENT_MANIFEST_SCHEMA_URI } from "./standards-discovery-BwL5ffGx.mjs";
2
3
  import { createProcessor } from "@mdx-js/mdx";
3
4
 
4
5
  //#region src/mcp-auth.ts
@@ -98,595 +99,6 @@ function isAbsoluteHttpUrl(value) {
98
99
  }
99
100
  }
100
101
 
101
- //#endregion
102
- //#region src/agent-contract.ts
103
- const PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS = [
104
- "task",
105
- "outcome",
106
- "appliesTo",
107
- "prerequisites",
108
- "files",
109
- "commands",
110
- "sideEffects",
111
- "verification",
112
- "rollback",
113
- "failureModes"
114
- ];
115
- const PAGE_AGENT_CONTRACT_FIELDS = ["tokenBudget", ...PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS];
116
- const PAGE_AGENT_CONTRACT_FIELD_SCHEMA = {
117
- tokenBudget: "number",
118
- task: "string",
119
- outcome: "string",
120
- appliesTo: {
121
- framework: "string|string[]",
122
- version: "string|string[]",
123
- package: "string|string[]"
124
- },
125
- prerequisites: "string[]",
126
- files: "string[]",
127
- commands: "Array<string|{run,cwd?,description?}>",
128
- sideEffects: "string[]",
129
- verification: "Array<string|{description?,run?,expect?}>",
130
- rollback: "string[]",
131
- failureModes: "Array<string|{symptom,resolution?}>"
132
- };
133
- const APPLIES_TO_FIELDS = [
134
- "framework",
135
- "version",
136
- "package"
137
- ];
138
- const COMMAND_FIELDS = [
139
- "run",
140
- "cwd",
141
- "description"
142
- ];
143
- const VERIFICATION_FIELDS = [
144
- "description",
145
- "run",
146
- "expect"
147
- ];
148
- const FAILURE_MODE_FIELDS = ["symptom", "resolution"];
149
- const PAGE_AGENT_CONTRACT_START_MARKER = "<!-- farming-labs:agent-contract:start -->";
150
- const PAGE_AGENT_CONTRACT_END_MARKER = "<!-- farming-labs:agent-contract:end -->";
151
- function isRecord(value) {
152
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
153
- }
154
- function normalizeString(value) {
155
- if (typeof value !== "string") return void 0;
156
- return value.trim() || void 0;
157
- }
158
- function normalizeStringList(value) {
159
- if (!Array.isArray(value)) return void 0;
160
- const seen = /* @__PURE__ */ new Set();
161
- const normalized = [];
162
- for (const item of value) {
163
- const text = normalizeString(item);
164
- if (!text || seen.has(text)) continue;
165
- seen.add(text);
166
- normalized.push(text);
167
- }
168
- return normalized.length > 0 ? normalized : void 0;
169
- }
170
- function normalizeStringOrList(value) {
171
- const single = normalizeString(value);
172
- if (single) return [single];
173
- return normalizeStringList(value);
174
- }
175
- function normalizeAppliesTo(value) {
176
- if (!isRecord(value)) return void 0;
177
- const framework = normalizeStringOrList(value.framework);
178
- const version = normalizeStringOrList(value.version);
179
- const packageNames = normalizeStringOrList(value.package);
180
- if (!framework && !version && !packageNames) return void 0;
181
- return {
182
- ...framework ? { framework } : {},
183
- ...version ? { version } : {},
184
- ...packageNames ? { package: packageNames } : {}
185
- };
186
- }
187
- function normalizeCommands(value) {
188
- if (!Array.isArray(value)) return void 0;
189
- const commands = [];
190
- for (const item of value) {
191
- const shorthand = normalizeString(item);
192
- if (shorthand) {
193
- commands.push(shorthand);
194
- continue;
195
- }
196
- if (!isRecord(item)) continue;
197
- const run = normalizeString(item.run);
198
- if (!run) continue;
199
- const cwd = normalizeString(item.cwd);
200
- const description = normalizeString(item.description);
201
- commands.push({
202
- run,
203
- ...cwd ? { cwd } : {},
204
- ...description ? { description } : {}
205
- });
206
- }
207
- return commands.length > 0 ? commands : void 0;
208
- }
209
- function normalizeVerification(value) {
210
- if (!Array.isArray(value)) return void 0;
211
- const verification = [];
212
- for (const item of value) {
213
- const shorthand = normalizeString(item);
214
- if (shorthand) {
215
- verification.push(shorthand);
216
- continue;
217
- }
218
- if (!isRecord(item)) continue;
219
- const description = normalizeString(item.description);
220
- const run = normalizeString(item.run);
221
- const expect = normalizeString(item.expect);
222
- if (!description && !run && !expect) continue;
223
- verification.push({
224
- ...description ? { description } : {},
225
- ...run ? { run } : {},
226
- ...expect ? { expect } : {}
227
- });
228
- }
229
- return verification.length > 0 ? verification : void 0;
230
- }
231
- function normalizeFailureModes(value) {
232
- if (!Array.isArray(value)) return void 0;
233
- const failureModes = [];
234
- for (const item of value) {
235
- const shorthand = normalizeString(item);
236
- if (shorthand) {
237
- failureModes.push(shorthand);
238
- continue;
239
- }
240
- if (!isRecord(item)) continue;
241
- const symptom = normalizeString(item.symptom);
242
- if (!symptom) continue;
243
- const resolution = normalizeString(item.resolution);
244
- failureModes.push({
245
- symptom,
246
- ...resolution ? { resolution } : {}
247
- });
248
- }
249
- return failureModes.length > 0 ? failureModes : void 0;
250
- }
251
- function normalizeTokenBudget(value) {
252
- if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return void 0;
253
- return Math.ceil(value);
254
- }
255
- /**
256
- * Normalize untrusted page frontmatter into the stable agent contract shape.
257
- * Invalid fields are omitted so malformed author input cannot break page delivery.
258
- */
259
- function normalizePageAgentFrontmatter(value) {
260
- if (!isRecord(value)) return void 0;
261
- const tokenBudget = normalizeTokenBudget(value.tokenBudget);
262
- const task = normalizeString(value.task);
263
- const outcome = normalizeString(value.outcome);
264
- const appliesTo = normalizeAppliesTo(value.appliesTo);
265
- const prerequisites = normalizeStringList(value.prerequisites);
266
- const files = normalizeStringList(value.files);
267
- const commands = normalizeCommands(value.commands);
268
- const sideEffects = normalizeStringList(value.sideEffects);
269
- const verification = normalizeVerification(value.verification);
270
- const rollback = normalizeStringList(value.rollback);
271
- const failureModes = normalizeFailureModes(value.failureModes);
272
- const normalized = {
273
- ...tokenBudget !== void 0 ? { tokenBudget } : {},
274
- ...task ? { task } : {},
275
- ...outcome ? { outcome } : {},
276
- ...appliesTo ? { appliesTo } : {},
277
- ...prerequisites ? { prerequisites } : {},
278
- ...files ? { files } : {},
279
- ...commands ? { commands } : {},
280
- ...sideEffects ? { sideEffects } : {},
281
- ...verification ? { verification } : {},
282
- ...rollback ? { rollback } : {},
283
- ...failureModes ? { failureModes } : {}
284
- };
285
- return Object.keys(normalized).length > 0 ? normalized : void 0;
286
- }
287
- function hasStructuredPageAgentContract(value) {
288
- const normalized = normalizePageAgentFrontmatter(value);
289
- if (!normalized) return false;
290
- return PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS.some((field) => normalized[field] !== void 0);
291
- }
292
- function addStringIssue(issues, object, field) {
293
- if (!(field in object)) return;
294
- if (!normalizeString(object[field])) issues.push({
295
- path: `agent.${field}`,
296
- message: "must be a non-empty string"
297
- });
298
- }
299
- function addStringListIssues(issues, object, field) {
300
- if (!(field in object)) return;
301
- const value = object[field];
302
- if (!Array.isArray(value) || value.length === 0) {
303
- issues.push({
304
- path: `agent.${field}`,
305
- message: "must be a non-empty string array"
306
- });
307
- return;
308
- }
309
- value.forEach((item, index) => {
310
- if (!normalizeString(item)) issues.push({
311
- path: `agent.${field}[${index}]`,
312
- message: "must be a non-empty string"
313
- });
314
- });
315
- }
316
- function editDistance(left, right) {
317
- const previous = Array.from({ length: right.length + 1 }, (_, index) => index);
318
- for (let leftIndex = 1; leftIndex <= left.length; leftIndex += 1) {
319
- const current = [leftIndex];
320
- for (let rightIndex = 1; rightIndex <= right.length; rightIndex += 1) current[rightIndex] = Math.min((current[rightIndex - 1] ?? 0) + 1, (previous[rightIndex] ?? 0) + 1, (previous[rightIndex - 1] ?? 0) + (left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1));
321
- previous.splice(0, previous.length, ...current);
322
- }
323
- return previous[right.length] ?? 0;
324
- }
325
- function closestKnownField(field, allowed) {
326
- const closest = allowed.map((candidate) => ({
327
- candidate,
328
- distance: editDistance(field, candidate)
329
- })).sort((left, right) => left.distance - right.distance || left.candidate.localeCompare(right.candidate))[0];
330
- if (!closest) return void 0;
331
- const threshold = Math.max(1, Math.min(3, Math.floor(closest.candidate.length / 3)));
332
- return closest.distance <= threshold ? closest.candidate : void 0;
333
- }
334
- function addUnknownKeyIssues(issues, object, allowed, path) {
335
- for (const field of Object.keys(object)) {
336
- if (allowed.includes(field)) continue;
337
- const suggestion = closestKnownField(field, allowed);
338
- issues.push({
339
- path: `${path}.${field}`,
340
- message: suggestion ? `is not recognized; did you mean "${path}.${suggestion}"?` : "is not recognized"
341
- });
342
- }
343
- }
344
- /** Return author-facing validation issues without throwing. */
345
- function getPageAgentFrontmatterIssues(value) {
346
- if (value === void 0) return [];
347
- if (!isRecord(value)) return [{
348
- path: "agent",
349
- message: "must be an object"
350
- }];
351
- const issues = [];
352
- addUnknownKeyIssues(issues, value, PAGE_AGENT_CONTRACT_FIELDS, "agent");
353
- if ("tokenBudget" in value && (typeof value.tokenBudget !== "number" || !Number.isFinite(value.tokenBudget) || value.tokenBudget <= 0)) issues.push({
354
- path: "agent.tokenBudget",
355
- message: "must be a positive finite number"
356
- });
357
- addStringIssue(issues, value, "task");
358
- addStringIssue(issues, value, "outcome");
359
- if ("appliesTo" in value) if (!isRecord(value.appliesTo)) issues.push({
360
- path: "agent.appliesTo",
361
- message: "must be an object"
362
- });
363
- else {
364
- addUnknownKeyIssues(issues, value.appliesTo, APPLIES_TO_FIELDS, "agent.appliesTo");
365
- for (const field of [
366
- "framework",
367
- "version",
368
- "package"
369
- ]) {
370
- if (!(field in value.appliesTo)) continue;
371
- const fieldValue = value.appliesTo[field];
372
- if (!normalizeStringOrList(fieldValue)) {
373
- issues.push({
374
- path: `agent.appliesTo.${field}`,
375
- message: "must be a non-empty string or string array"
376
- });
377
- continue;
378
- }
379
- if (Array.isArray(fieldValue)) fieldValue.forEach((item, index) => {
380
- if (!normalizeString(item)) issues.push({
381
- path: `agent.appliesTo.${field}[${index}]`,
382
- message: "must be a non-empty string"
383
- });
384
- });
385
- }
386
- if (!normalizeAppliesTo(value.appliesTo)) issues.push({
387
- path: "agent.appliesTo",
388
- message: "must include framework, version, or package"
389
- });
390
- }
391
- for (const field of [
392
- "prerequisites",
393
- "files",
394
- "sideEffects",
395
- "rollback"
396
- ]) addStringListIssues(issues, value, field);
397
- if ("commands" in value) if (!Array.isArray(value.commands) || value.commands.length === 0) issues.push({
398
- path: "agent.commands",
399
- message: "must be a non-empty array"
400
- });
401
- else value.commands.forEach((command, index) => {
402
- if (normalizeString(command)) return;
403
- if (!isRecord(command)) {
404
- issues.push({
405
- path: `agent.commands[${index}]`,
406
- message: "must be a command string or an object with a non-empty run field"
407
- });
408
- return;
409
- }
410
- addUnknownKeyIssues(issues, command, COMMAND_FIELDS, `agent.commands[${index}]`);
411
- if (!normalizeString(command.run)) {
412
- issues.push({
413
- path: `agent.commands[${index}]`,
414
- message: "must be a command string or an object with a non-empty run field"
415
- });
416
- return;
417
- }
418
- for (const field of ["cwd", "description"]) if (field in command && !normalizeString(command[field])) issues.push({
419
- path: `agent.commands[${index}].${field}`,
420
- message: "must be a non-empty string"
421
- });
422
- });
423
- if ("verification" in value) if (!Array.isArray(value.verification) || value.verification.length === 0) issues.push({
424
- path: "agent.verification",
425
- message: "must be a non-empty array"
426
- });
427
- else value.verification.forEach((step, index) => {
428
- if (normalizeString(step)) return;
429
- if (!isRecord(step)) {
430
- issues.push({
431
- path: `agent.verification[${index}]`,
432
- message: "must be a string or an object with description, run, or expect"
433
- });
434
- return;
435
- }
436
- addUnknownKeyIssues(issues, step, VERIFICATION_FIELDS, `agent.verification[${index}]`);
437
- if (!normalizeVerification([step])) {
438
- issues.push({
439
- path: `agent.verification[${index}]`,
440
- message: "must be a string or an object with description, run, or expect"
441
- });
442
- return;
443
- }
444
- for (const field of [
445
- "description",
446
- "run",
447
- "expect"
448
- ]) if (field in step && !normalizeString(step[field])) issues.push({
449
- path: `agent.verification[${index}].${field}`,
450
- message: "must be a non-empty string"
451
- });
452
- });
453
- if ("failureModes" in value) if (!Array.isArray(value.failureModes) || value.failureModes.length === 0) issues.push({
454
- path: "agent.failureModes",
455
- message: "must be a non-empty array"
456
- });
457
- else value.failureModes.forEach((mode, index) => {
458
- if (normalizeString(mode)) return;
459
- if (!isRecord(mode)) {
460
- issues.push({
461
- path: `agent.failureModes[${index}]`,
462
- message: "must be a string or an object with a non-empty symptom field"
463
- });
464
- return;
465
- }
466
- addUnknownKeyIssues(issues, mode, FAILURE_MODE_FIELDS, `agent.failureModes[${index}]`);
467
- if (!normalizeString(mode.symptom)) {
468
- issues.push({
469
- path: `agent.failureModes[${index}]`,
470
- message: "must be a string or an object with a non-empty symptom field"
471
- });
472
- return;
473
- }
474
- if ("resolution" in mode && !normalizeString(mode.resolution)) issues.push({
475
- path: `agent.failureModes[${index}].resolution`,
476
- message: "must be a non-empty string"
477
- });
478
- });
479
- return issues;
480
- }
481
- function yamlString(value) {
482
- return JSON.stringify(value);
483
- }
484
- function renderYamlStringList(lines, indent, key, values) {
485
- lines.push(`${indent}${key}:`);
486
- for (const value of values) lines.push(`${indent} - ${yamlString(value)}`);
487
- }
488
- function renderYamlObjectList(lines, indent, key, values, fields) {
489
- lines.push(`${indent}${key}:`);
490
- for (const value of values) {
491
- if (typeof value === "string") {
492
- lines.push(`${indent} - ${yamlString(value)}`);
493
- continue;
494
- }
495
- const record = value;
496
- const firstField = fields.find((field) => normalizeString(record[field]));
497
- if (!firstField) continue;
498
- lines.push(`${indent} - ${firstField}: ${yamlString(normalizeString(record[firstField]))}`);
499
- for (const field of fields) {
500
- const fieldValue = normalizeString(record[field]);
501
- if (field === firstField || !fieldValue) continue;
502
- lines.push(`${indent} ${field}: ${yamlString(fieldValue)}`);
503
- }
504
- }
505
- }
506
- /** Render normalized `agent` YAML in a stable field order. */
507
- function renderPageAgentFrontmatterYamlLines(value, indentation = 0) {
508
- const agent = normalizePageAgentFrontmatter(value);
509
- if (!agent) return [];
510
- const indent = " ".repeat(Math.max(0, indentation));
511
- const child = `${indent} `;
512
- const lines = [`${indent}agent:`];
513
- if (agent.tokenBudget !== void 0) lines.push(`${child}tokenBudget: ${agent.tokenBudget}`);
514
- if (agent.task) lines.push(`${child}task: ${yamlString(agent.task)}`);
515
- if (agent.outcome) lines.push(`${child}outcome: ${yamlString(agent.outcome)}`);
516
- if (agent.appliesTo) {
517
- lines.push(`${child}appliesTo:`);
518
- const appliesIndent = `${child} `;
519
- for (const field of [
520
- "framework",
521
- "version",
522
- "package"
523
- ]) {
524
- const values = normalizeStringOrList(agent.appliesTo[field]);
525
- if (values) renderYamlStringList(lines, appliesIndent, field, values);
526
- }
527
- }
528
- if (agent.prerequisites) renderYamlStringList(lines, child, "prerequisites", agent.prerequisites);
529
- if (agent.files) renderYamlStringList(lines, child, "files", agent.files);
530
- if (agent.commands) renderYamlObjectList(lines, child, "commands", agent.commands, [
531
- "run",
532
- "cwd",
533
- "description"
534
- ]);
535
- if (agent.sideEffects) renderYamlStringList(lines, child, "sideEffects", agent.sideEffects);
536
- if (agent.verification) renderYamlObjectList(lines, child, "verification", agent.verification, [
537
- "description",
538
- "run",
539
- "expect"
540
- ]);
541
- if (agent.rollback) renderYamlStringList(lines, child, "rollback", agent.rollback);
542
- if (agent.failureModes) renderYamlObjectList(lines, child, "failureModes", agent.failureModes, ["symptom", "resolution"]);
543
- return lines;
544
- }
545
- function inlineCode(value) {
546
- const longestRun = Math.max(0, ...[...value.matchAll(/`+/g)].map((match) => match[0].length));
547
- const fence = "`".repeat(longestRun + 1);
548
- const padding = value.startsWith("`") || value.endsWith("`") ? " " : "";
549
- return `${fence}${padding}${value}${padding}${fence}`;
550
- }
551
- function renderTextList(lines, title, values, code = false) {
552
- lines.push("", `### ${title}`, "");
553
- for (const value of values) lines.push(`- ${code ? inlineCode(value) : value}`);
554
- }
555
- /** Render the structured contract as deterministic, compact machine-readable Markdown. */
556
- function renderPageAgentContractMarkdown(value) {
557
- const agent = normalizePageAgentFrontmatter(value);
558
- if (!agent || !hasStructuredPageAgentContract(agent)) return "";
559
- const lines = [PAGE_AGENT_CONTRACT_START_MARKER, "## Agent Contract"];
560
- if (agent.task) lines.push("", `Task: ${agent.task}`);
561
- if (agent.outcome) lines.push(`Outcome: ${agent.outcome}`);
562
- if (agent.appliesTo) {
563
- lines.push("", "### Applies To", "");
564
- for (const [label, field] of [
565
- ["Framework", "framework"],
566
- ["Version", "version"],
567
- ["Package", "package"]
568
- ]) {
569
- const values = normalizeStringOrList(agent.appliesTo[field]);
570
- if (values) lines.push(`- ${label}: ${values.map(inlineCode).join(", ")}`);
571
- }
572
- }
573
- if (agent.prerequisites) renderTextList(lines, "Prerequisites", agent.prerequisites);
574
- if (agent.files) renderTextList(lines, "Files", agent.files, true);
575
- if (agent.commands) {
576
- lines.push("", "### Commands", "");
577
- for (const command of agent.commands) {
578
- if (typeof command === "string") {
579
- lines.push(`- ${inlineCode(command)}`);
580
- continue;
581
- }
582
- const details = [command.cwd ? `cwd ${inlineCode(command.cwd)}` : void 0, command.description].filter(Boolean);
583
- lines.push(`- ${inlineCode(command.run)}${details.length ? ` — ${details.join("; ")}` : ""}`);
584
- }
585
- }
586
- if (agent.sideEffects) renderTextList(lines, "Side Effects", agent.sideEffects);
587
- if (agent.verification) {
588
- lines.push("", "### Verification", "");
589
- for (const step of agent.verification) {
590
- if (typeof step === "string") {
591
- lines.push(`- ${step}`);
592
- continue;
593
- }
594
- const summary = step.description ?? (step.run ? `Run ${inlineCode(step.run)}` : step.expect ?? "Verification step");
595
- lines.push(`- ${summary}`);
596
- if (step.run && step.description) lines.push(` - Run: ${inlineCode(step.run)}`);
597
- if (step.expect && step.expect !== summary) lines.push(` - Expected: ${step.expect}`);
598
- }
599
- }
600
- if (agent.rollback) renderTextList(lines, "Rollback", agent.rollback);
601
- if (agent.failureModes) {
602
- lines.push("", "### Failure Modes", "");
603
- for (const mode of agent.failureModes) {
604
- if (typeof mode === "string") {
605
- lines.push(`- ${mode}`);
606
- continue;
607
- }
608
- lines.push(`- ${mode.symptom}${mode.resolution ? ` — Recovery: ${mode.resolution}` : ""}`);
609
- }
610
- }
611
- lines.push(PAGE_AGENT_CONTRACT_END_MARKER);
612
- return lines.join("\n");
613
- }
614
- /** Remove generated contract blocks while preserving handwritten guidance. */
615
- function stripGeneratedPageAgentContractMarkdown(markdown) {
616
- const newline = markdown.includes("\r\n") ? "\r\n" : "\n";
617
- const output = [];
618
- let fence;
619
- let pendingBlock;
620
- let skipEmptySeparator = false;
621
- for (const line of markdown.split(/\r?\n/)) {
622
- if (pendingBlock) {
623
- pendingBlock.push(line);
624
- if (isGeneratedAgentContractMarker(line, PAGE_AGENT_CONTRACT_END_MARKER)) {
625
- pendingBlock = void 0;
626
- skipEmptySeparator = true;
627
- }
628
- continue;
629
- }
630
- if (!fence && isGeneratedAgentContractMarker(line, PAGE_AGENT_CONTRACT_START_MARKER)) {
631
- pendingBlock = [line];
632
- continue;
633
- }
634
- if (skipEmptySeparator && line.length === 0) continue;
635
- skipEmptySeparator = false;
636
- output.push(line);
637
- fence = advanceMarkdownFence(line, fence);
638
- }
639
- if (pendingBlock) output.push(...pendingBlock);
640
- while (output[0] === "") output.shift();
641
- return output.join(newline);
642
- }
643
- function isGeneratedAgentContractMarker(line, marker) {
644
- if (line.trim() !== marker) return false;
645
- const markerIndex = line.indexOf(marker);
646
- return markerIndex <= 3 && /^ *$/.test(line.slice(0, markerIndex));
647
- }
648
- function advanceMarkdownFence(line, fence) {
649
- if (fence) {
650
- const closing = /^ {0,3}(`+|~+)[\t ]*$/.exec(line)?.[1];
651
- if (closing?.[0] === fence.character && closing.length >= fence.length) return;
652
- return fence;
653
- }
654
- const opening = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
655
- if (!opening?.[1]) return void 0;
656
- if (opening[1][0] === "`" && opening[2]?.includes("`")) return void 0;
657
- return {
658
- character: opening[1][0],
659
- length: opening[1].length
660
- };
661
- }
662
- function isAgentContractHeadingText(value) {
663
- return value.trim().toLowerCase() === "agent contract";
664
- }
665
- function hasPageAgentContractHeading(markdown) {
666
- let fence;
667
- let previousLine;
668
- for (const line of markdown.split(/\r?\n/)) {
669
- const nextFence = advanceMarkdownFence(line, fence);
670
- if (fence || nextFence) {
671
- fence = nextFence;
672
- previousLine = void 0;
673
- continue;
674
- }
675
- const atxText = /^ {0,3}#{1,6}(?:[\t ]+|$)(.*)$/.exec(line)?.[1]?.replace(/[\t ]+#+[\t ]*$/, "").trim();
676
- if (atxText && isAgentContractHeadingText(atxText)) return true;
677
- if (previousLine && /^ {0,3}(?:=+|-+)[\t ]*$/.test(line) && isAgentContractHeadingText(previousLine)) return true;
678
- previousLine = line.trim().length > 0 && !/^ {4}/.test(line) && !/^ {0,3}\t/.test(line) ? line : void 0;
679
- }
680
- return false;
681
- }
682
- /** Insert one generated contract unless the document already has handwritten contract guidance. */
683
- function upsertPageAgentContractMarkdown(markdown, value) {
684
- const cleaned = stripGeneratedPageAgentContractMarkdown(markdown);
685
- const contract = renderPageAgentContractMarkdown(value);
686
- if (!contract || hasPageAgentContractHeading(cleaned)) return cleaned;
687
- return cleaned ? `${contract}\n\n${cleaned.replace(/^\r?\n+/, "")}` : contract;
688
- }
689
-
690
102
  //#endregion
691
103
  //#region src/related.ts
692
104
  function normalizeDocsRelated(value) {
@@ -736,148 +148,6 @@ function normalizeInlineText(value) {
736
148
  return value.replace(/\s+/g, " ").trim();
737
149
  }
738
150
 
739
- //#endregion
740
- //#region src/markdown-sections.ts
741
- const HTML_ENTITIES = {
742
- amp: "&",
743
- apos: "'",
744
- gt: ">",
745
- lt: "<",
746
- nbsp: " ",
747
- quot: "\""
748
- };
749
- /**
750
- * Reduce inline Markdown in a heading to the visible label used by search and anchors.
751
- * This intentionally covers the common inline constructs without adding a Markdown parser
752
- * dependency to the runtime package.
753
- */
754
- function cleanDocsMarkdownHeadingLabel(value) {
755
- return value.replace(/!\[([^\]]*)\]\([^)]*\)/gu, "$1").replace(/\[([^\]]+)\]\([^)]*\)/gu, "$1").replace(/!\[([^\]]*)\]\[[^\]]*\]/gu, "$1").replace(/\[([^\]]+)\]\[[^\]]*\]/gu, "$1").replace(/<((?:https?:\/\/|mailto:)[^>]+)>/giu, "$1").replace(/<[^>]+>/gu, "").replace(/`+([^`]*?)`+/gu, "$1").replace(/\\([!"#$%&'()*+,\-./:;<=>?@[\]^_`{|}~])/gu, "$1").replace(/[*_~]/gu, "").replace(/&(#(?:x[0-9a-f]+|\d+)|[a-z]+);/giu, (_match, entity) => {
756
- if (entity.startsWith("#x") || entity.startsWith("#X")) {
757
- const codePoint = Number.parseInt(entity.slice(2), 16);
758
- return Number.isSafeInteger(codePoint) && codePoint >= 0 && codePoint <= 1114111 ? String.fromCodePoint(codePoint) : _match;
759
- }
760
- if (entity.startsWith("#")) {
761
- const codePoint = Number.parseInt(entity.slice(1), 10);
762
- return Number.isSafeInteger(codePoint) && codePoint >= 0 && codePoint <= 1114111 ? String.fromCodePoint(codePoint) : _match;
763
- }
764
- return HTML_ENTITIES[entity.toLowerCase()] ?? _match;
765
- }).replace(/\s+/gu, " ").trim();
766
- }
767
- /** Keep anchors aligned with the framework's existing ASCII heading-slug behavior. */
768
- function slugifyDocsMarkdownHeading(value) {
769
- return cleanDocsMarkdownHeadingLabel(value).toLowerCase().replace(/[`'"‘’“”]/gu, "").replace(/&/gu, " and ").replace(/[^a-z0-9\s-]/gu, "").replace(/\s+/gu, "-").replace(/-+/gu, "-").replace(/^-|-$/gu, "");
770
- }
771
- function readOpeningFence(line) {
772
- const match = line.match(/^ {0,3}(`{3,}|~{3,})/u);
773
- if (!match) return void 0;
774
- return {
775
- marker: match[1][0],
776
- length: match[1].length
777
- };
778
- }
779
- function isClosingFence(line, fence) {
780
- const marker = fence.marker === "`" ? "`" : "~";
781
- const match = line.match(new RegExp(`^ {0,3}(${marker}{${fence.length},})[\\t ]*$`, "u"));
782
- return Boolean(match);
783
- }
784
- function readAtxHeading(line) {
785
- const match = line.match(/^ {0,3}(#{1,6})(?:[\t ]+|$)(.*)$/u);
786
- if (!match) return void 0;
787
- return {
788
- title: cleanDocsMarkdownHeadingLabel(match[2].replace(/[\t ]+#+[\t ]*$/u, "").trim()),
789
- level: match[1].length
790
- };
791
- }
792
- function readSetextLevel(line) {
793
- const match = line.match(/^ {0,3}(=+|-+)[\t ]*$/u);
794
- if (!match) return void 0;
795
- return match[1][0] === "=" ? 1 : 2;
796
- }
797
- function normalizeDocsSectionSelector(value) {
798
- let selector = value.trim();
799
- const hashIndex = selector.lastIndexOf("#");
800
- if (hashIndex >= 0) selector = selector.slice(hashIndex + 1);
801
- try {
802
- selector = decodeURIComponent(selector);
803
- } catch {}
804
- return cleanDocsMarkdownHeadingLabel(selector.replace(/^#+/u, "")).toLowerCase();
805
- }
806
- /**
807
- * Parse heading sections once for search, Ask AI hydration, and MCP tools.
808
- * Supports CommonMark ATX indentation, Setext headings, fenced-code exclusion,
809
- * visible inline labels, and stable duplicate anchors.
810
- */
811
- function parseDocsMarkdownSections(markdown) {
812
- const lines = markdown.split(/\r?\n/u);
813
- const headings = [];
814
- const headingCounts = /* @__PURE__ */ new Map();
815
- let openFence;
816
- let setextCandidate;
817
- const pushHeading = (title, level, start) => {
818
- const baseAnchor = slugifyDocsMarkdownHeading(title) || `section-${headings.length}`;
819
- const seen = headingCounts.get(baseAnchor) ?? 0;
820
- headingCounts.set(baseAnchor, seen + 1);
821
- headings.push({
822
- title,
823
- anchor: seen === 0 ? baseAnchor : `${baseAnchor}-${seen}`,
824
- level,
825
- start
826
- });
827
- };
828
- for (let index = 0; index < lines.length; index += 1) {
829
- const line = lines[index];
830
- if (openFence) {
831
- if (isClosingFence(line, openFence)) openFence = void 0;
832
- setextCandidate = void 0;
833
- continue;
834
- }
835
- const openingFence = readOpeningFence(line);
836
- if (openingFence) {
837
- openFence = openingFence;
838
- setextCandidate = void 0;
839
- continue;
840
- }
841
- const setextLevel = readSetextLevel(line);
842
- if (setextLevel && setextCandidate?.index === index - 1) {
843
- const title = cleanDocsMarkdownHeadingLabel(setextCandidate.value.trim());
844
- if (title) pushHeading(title, setextLevel, setextCandidate.index);
845
- setextCandidate = void 0;
846
- continue;
847
- }
848
- const atxHeading = readAtxHeading(line);
849
- if (atxHeading) {
850
- pushHeading(atxHeading.title, atxHeading.level, index);
851
- setextCandidate = void 0;
852
- continue;
853
- }
854
- if (!line.trim() || /^ {4}|^\t/u.test(line)) {
855
- setextCandidate = void 0;
856
- continue;
857
- }
858
- setextCandidate = {
859
- index,
860
- value: line
861
- };
862
- }
863
- return headings.map((heading, index) => {
864
- const end = headings.slice(index + 1).find((candidate) => candidate.level <= heading.level)?.start ?? lines.length;
865
- return {
866
- title: heading.title,
867
- anchor: heading.anchor,
868
- level: heading.level,
869
- content: lines.slice(heading.start, end).join("\n").trim(),
870
- startLine: heading.start + 1,
871
- endLine: end
872
- };
873
- });
874
- }
875
- function findDocsMarkdownSection(markdown, requestedSection) {
876
- const selector = normalizeDocsSectionSelector(requestedSection);
877
- if (!selector) return void 0;
878
- return parseDocsMarkdownSections(markdown).find((section) => normalizeDocsSectionSelector(section.title) === selector || section.anchor === selector);
879
- }
880
-
881
151
  //#endregion
882
152
  //#region src/sitemap.ts
883
153
  const DEFAULT_SITEMAP_XML_ROUTE = "/sitemap.xml";
@@ -2146,6 +1416,543 @@ function findProtectedRanges(content) {
2146
1416
  const htmlLiterals = findHtmlLiteralRanges(content, excludedRanges);
2147
1417
  return mergeProtectedRanges([...excludedRanges, ...htmlLiterals]);
2148
1418
  }
1419
+ function findMarkdownLinkLiteralRanges(content) {
1420
+ try {
1421
+ const offsetAdjustment = content.startsWith("") ? 1 : 0;
1422
+ const tree = docsAudienceMarkdownProcessor.parse(offsetAdjustment > 0 ? content.slice(offsetAdjustment) : content);
1423
+ const ranges = [];
1424
+ const visit = (node) => {
1425
+ const rawStart = getOffset(node.position, "start");
1426
+ const rawEnd = getOffset(node.position, "end");
1427
+ const start = rawStart === void 0 ? void 0 : rawStart + offsetAdjustment;
1428
+ const end = rawEnd === void 0 ? void 0 : rawEnd + offsetAdjustment;
1429
+ if (start !== void 0 && end !== void 0 && (node.type === "link" || node.type === "image" || node.type === "linkReference" || node.type === "imageReference")) {
1430
+ ranges.push({
1431
+ start,
1432
+ end
1433
+ });
1434
+ return;
1435
+ }
1436
+ for (const child of node.children ?? []) visit(child);
1437
+ };
1438
+ visit(tree);
1439
+ return ranges;
1440
+ } catch {
1441
+ return [];
1442
+ }
1443
+ }
1444
+ function findDocsMarkdownPromptBracketLiteralRanges(content, protectedRanges) {
1445
+ const ranges = [];
1446
+ let cursor = 0;
1447
+ while (cursor < content.length) {
1448
+ const index = content.indexOf("[", cursor);
1449
+ if (index === -1 || isEscapedAt(content, index) || isInsideRange(index, protectedRanges)) {
1450
+ if (index === -1) break;
1451
+ cursor = index + 1;
1452
+ continue;
1453
+ }
1454
+ let depth = 1;
1455
+ let end = index + 1;
1456
+ while (end < content.length && depth > 0) {
1457
+ if (content[end] === "\\") {
1458
+ end += 2;
1459
+ continue;
1460
+ }
1461
+ if (content[end] === "[") depth += 1;
1462
+ if (content[end] === "]") depth -= 1;
1463
+ end += 1;
1464
+ }
1465
+ if (depth !== 0) {
1466
+ cursor = index + 1;
1467
+ continue;
1468
+ }
1469
+ const label = content.slice(index + 1, end - 1);
1470
+ if (/<Prompt(?=[\s/>])/.test(label) && /<\/Prompt\s*>/.test(label)) {
1471
+ let rangeEnd = end;
1472
+ if (content[rangeEnd] === "[") {
1473
+ let referenceEnd = rangeEnd + 1;
1474
+ while (referenceEnd < content.length) {
1475
+ if (content[referenceEnd] === "\\") {
1476
+ referenceEnd += 2;
1477
+ continue;
1478
+ }
1479
+ if (content[referenceEnd] === "]") {
1480
+ referenceEnd += 1;
1481
+ break;
1482
+ }
1483
+ referenceEnd += 1;
1484
+ }
1485
+ if (content[referenceEnd - 1] === "]") rangeEnd = referenceEnd;
1486
+ }
1487
+ ranges.push({
1488
+ start: content[index - 1] === "!" ? index - 1 : index,
1489
+ end: rangeEnd
1490
+ });
1491
+ }
1492
+ cursor = end;
1493
+ }
1494
+ return ranges;
1495
+ }
1496
+ const DOCS_MARKDOWN_INTRINSIC_CONTAINER_NAMES = new Set([
1497
+ "a",
1498
+ "abbr",
1499
+ "address",
1500
+ "article",
1501
+ "aside",
1502
+ "audio",
1503
+ "b",
1504
+ "bdi",
1505
+ "bdo",
1506
+ "blockquote",
1507
+ "body",
1508
+ "button",
1509
+ "canvas",
1510
+ "caption",
1511
+ "cite",
1512
+ "code",
1513
+ "colgroup",
1514
+ "data",
1515
+ "datalist",
1516
+ "dd",
1517
+ "del",
1518
+ "details",
1519
+ "dfn",
1520
+ "dialog",
1521
+ "div",
1522
+ "dl",
1523
+ "dt",
1524
+ "em",
1525
+ "fieldset",
1526
+ "figcaption",
1527
+ "figure",
1528
+ "footer",
1529
+ "form",
1530
+ "h1",
1531
+ "h2",
1532
+ "h3",
1533
+ "h4",
1534
+ "h5",
1535
+ "h6",
1536
+ "head",
1537
+ "header",
1538
+ "hgroup",
1539
+ "html",
1540
+ "i",
1541
+ "iframe",
1542
+ "ins",
1543
+ "kbd",
1544
+ "label",
1545
+ "legend",
1546
+ "li",
1547
+ "main",
1548
+ "map",
1549
+ "mark",
1550
+ "math",
1551
+ "menu",
1552
+ "meter",
1553
+ "nav",
1554
+ "noembed",
1555
+ "noframes",
1556
+ "noscript",
1557
+ "object",
1558
+ "ol",
1559
+ "optgroup",
1560
+ "option",
1561
+ "output",
1562
+ "p",
1563
+ "picture",
1564
+ "pre",
1565
+ "progress",
1566
+ "q",
1567
+ "rp",
1568
+ "rt",
1569
+ "ruby",
1570
+ "s",
1571
+ "samp",
1572
+ "script",
1573
+ "search",
1574
+ "section",
1575
+ "select",
1576
+ "slot",
1577
+ "small",
1578
+ "span",
1579
+ "strong",
1580
+ "style",
1581
+ "sub",
1582
+ "summary",
1583
+ "sup",
1584
+ "svg",
1585
+ "table",
1586
+ "tbody",
1587
+ "td",
1588
+ "template",
1589
+ "textarea",
1590
+ "tfoot",
1591
+ "th",
1592
+ "thead",
1593
+ "time",
1594
+ "title",
1595
+ "tr",
1596
+ "u",
1597
+ "ul",
1598
+ "var",
1599
+ "video",
1600
+ "xmp"
1601
+ ]);
1602
+ function normalizeDocsMarkdownIntrinsicContainerName(name) {
1603
+ const normalized = name.toLowerCase();
1604
+ if (!DOCS_MARKDOWN_INTRINSIC_CONTAINER_NAMES.has(normalized)) return void 0;
1605
+ const isLowercase = name === normalized;
1606
+ const isUppercase = name === name.toUpperCase() && /[A-Z]/.test(name);
1607
+ return isLowercase || isUppercase ? normalized : void 0;
1608
+ }
1609
+ function readDocsMarkdownPromptTagAt(content, index) {
1610
+ const closing = content[index + 1] === "/";
1611
+ const nameStart = index + (closing ? 2 : 1);
1612
+ if (!content.startsWith("Prompt", nameStart) || !/[\s/>]/.test(content[nameStart + 6] ?? "")) return;
1613
+ const tag = readGenericMdxJsxTag(content, index);
1614
+ if (!tag) return void 0;
1615
+ const attributesStart = nameStart + 6;
1616
+ let attributesEnd = tag.end - 1;
1617
+ while (attributesEnd > attributesStart && /\s/.test(content[attributesEnd - 1] ?? "")) attributesEnd -= 1;
1618
+ if (content[attributesEnd - 1] === "/") attributesEnd -= 1;
1619
+ return {
1620
+ attributes: closing ? "" : content.slice(attributesStart, attributesEnd),
1621
+ closing,
1622
+ end: tag.end,
1623
+ index,
1624
+ selfClosing: tag.selfClosing
1625
+ };
1626
+ }
1627
+ function findDocsMarkdownHtmlContainerLiteralRanges(content, protectedRanges) {
1628
+ const ranges = [];
1629
+ const openings = [];
1630
+ let cursor = 0;
1631
+ while (cursor < content.length) {
1632
+ const index = content.indexOf("<", cursor);
1633
+ if (index === -1) break;
1634
+ if (isEscapedAt(content, index) || isInsideRange(index, protectedRanges)) {
1635
+ cursor = index + 1;
1636
+ continue;
1637
+ }
1638
+ const closing = content[index + 1] === "/";
1639
+ const nameStart = index + (closing ? 2 : 1);
1640
+ let nameEnd = nameStart;
1641
+ while (/[\w:.-]/.test(content[nameEnd] ?? "")) nameEnd += 1;
1642
+ const name = normalizeDocsMarkdownIntrinsicContainerName(content.slice(nameStart, nameEnd));
1643
+ if (!name) {
1644
+ cursor = index + 1;
1645
+ continue;
1646
+ }
1647
+ const tag = readGenericMdxJsxTag(content, index);
1648
+ if (!tag) {
1649
+ cursor = index + 1;
1650
+ continue;
1651
+ }
1652
+ cursor = tag.end;
1653
+ if (!closing) {
1654
+ if (!tag.selfClosing) openings.push({
1655
+ name,
1656
+ start: index
1657
+ });
1658
+ continue;
1659
+ }
1660
+ let openingIndex = openings.length - 1;
1661
+ while (openingIndex >= 0 && openings[openingIndex].name !== name) openingIndex -= 1;
1662
+ if (openingIndex < 0) continue;
1663
+ const [opening] = openings.splice(openingIndex);
1664
+ ranges.push({
1665
+ start: opening.start,
1666
+ end: tag.end
1667
+ });
1668
+ }
1669
+ return ranges;
1670
+ }
1671
+ function isStandaloneDocsMarkdownPromptHtmlRange(content, start, end) {
1672
+ while (start < end && /\s/.test(content[start] ?? "")) start += 1;
1673
+ while (end > start && /\s/.test(content[end - 1] ?? "")) end -= 1;
1674
+ return readDocsMarkdownPromptTagAt(content, start) !== void 0;
1675
+ }
1676
+ function findDocsMarkdownRawHtmlLiteralRanges(content) {
1677
+ try {
1678
+ const offsetAdjustment = content.startsWith("") ? 1 : 0;
1679
+ const tree = docsAudienceMarkdownProcessor.parse(offsetAdjustment > 0 ? content.slice(offsetAdjustment) : content);
1680
+ const ranges = [];
1681
+ const visit = (node) => {
1682
+ const rawStart = getOffset(node.position, "start");
1683
+ const rawEnd = getOffset(node.position, "end");
1684
+ const start = rawStart === void 0 ? void 0 : rawStart + offsetAdjustment;
1685
+ const end = rawEnd === void 0 ? void 0 : rawEnd + offsetAdjustment;
1686
+ if (node.type === "html" && start !== void 0 && end !== void 0) {
1687
+ if (isStandaloneDocsMarkdownPromptHtmlRange(content, start, end)) return;
1688
+ const elementName = content.slice(start, end).trimStart().match(/^<\/?([A-Za-z][\w:.-]*)(?=[\s/>])/)?.[1];
1689
+ if (elementName && !normalizeDocsMarkdownIntrinsicContainerName(elementName)) return;
1690
+ let cursor = start;
1691
+ let promptDepth = 0;
1692
+ let trailingClosingPrompt;
1693
+ while (cursor < end) {
1694
+ const index = content.indexOf("<", cursor);
1695
+ if (index === -1 || index >= end) break;
1696
+ const tag = readDocsMarkdownPromptTagAt(content, index);
1697
+ if (!tag || tag.end > end) {
1698
+ cursor = index + 1;
1699
+ continue;
1700
+ }
1701
+ if (!tag.closing && !tag.selfClosing) promptDepth += 1;
1702
+ else if (tag.closing && promptDepth > 0) promptDepth -= 1;
1703
+ else if (tag.closing && content.slice(tag.end, end).trim().length === 0) trailingClosingPrompt = tag.index;
1704
+ cursor = tag.end;
1705
+ }
1706
+ const literalEnd = trailingClosingPrompt ?? end;
1707
+ if (literalEnd > start) ranges.push({
1708
+ start,
1709
+ end: literalEnd
1710
+ });
1711
+ return;
1712
+ }
1713
+ for (const child of node.children ?? []) visit(child);
1714
+ };
1715
+ visit(tree);
1716
+ return ranges;
1717
+ } catch {
1718
+ return [];
1719
+ }
1720
+ }
1721
+ function findDocsMarkdownPromptAstInfo(content) {
1722
+ try {
1723
+ const prepared = prepareMdxParserSource(content);
1724
+ const offsetAdjustment = prepared.startsWith("") ? 1 : 0;
1725
+ const tree = docsAudienceMdxProcessor.parse(offsetAdjustment > 0 ? prepared.slice(offsetAdjustment) : prepared);
1726
+ const flowStarts = /* @__PURE__ */ new Set();
1727
+ const starts = /* @__PURE__ */ new Set();
1728
+ const visit = (node) => {
1729
+ if (node.name === "Prompt" && (node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement") && getOffset(node.position, "start") !== void 0) {
1730
+ const start = getOffset(node.position, "start") + offsetAdjustment;
1731
+ starts.add(start);
1732
+ if (node.type === "mdxJsxFlowElement") flowStarts.add(start);
1733
+ }
1734
+ for (const child of node.children ?? []) visit(child);
1735
+ };
1736
+ visit(tree);
1737
+ return {
1738
+ flowStarts,
1739
+ starts
1740
+ };
1741
+ } catch {
1742
+ return;
1743
+ }
1744
+ }
1745
+ function findDocsMarkdownPromptExpressionRanges(content, protectedRanges) {
1746
+ const ranges = [];
1747
+ let protectedIndex = 0;
1748
+ let cursor = 0;
1749
+ while (cursor < content.length) {
1750
+ const start = content.indexOf("{", cursor);
1751
+ if (start === -1) break;
1752
+ if (isEscapedAt(content, start) || isInsideRange(start, protectedRanges)) {
1753
+ cursor = start + 1;
1754
+ continue;
1755
+ }
1756
+ let depth = 1;
1757
+ let end = start + 1;
1758
+ while (end < content.length && depth > 0) {
1759
+ while (protectedIndex < protectedRanges.length && protectedRanges[protectedIndex].end <= end) protectedIndex += 1;
1760
+ const candidate = protectedRanges[protectedIndex];
1761
+ const protectedRange = candidate && end >= candidate.start && end < candidate.end ? candidate : void 0;
1762
+ if (protectedRange) {
1763
+ end = protectedRange.end;
1764
+ continue;
1765
+ }
1766
+ if (content[end] === "{") depth += 1;
1767
+ if (content[end] === "}") depth -= 1;
1768
+ end += 1;
1769
+ }
1770
+ ranges.push({
1771
+ start,
1772
+ end: depth === 0 ? end : content.length
1773
+ });
1774
+ if (depth !== 0) break;
1775
+ cursor = end;
1776
+ }
1777
+ return ranges;
1778
+ }
1779
+ function createDocsMarkdownPromptToken(content, used, startAt) {
1780
+ let index = startAt;
1781
+ let token = "";
1782
+ do {
1783
+ token = `%%PROMPT_${index}%%`;
1784
+ index += 1;
1785
+ } while (content.includes(token) || used.has(token));
1786
+ return token;
1787
+ }
1788
+ function isFallbackDocsMarkdownPromptFlow(content, opening, closing) {
1789
+ const lineStart = Math.max(0, content.lastIndexOf("\n", opening.index - 1) + 1);
1790
+ const prefix = content.slice(lineStart, opening.index);
1791
+ if (!/^[\t ]{0,3}$/.test(prefix)) return false;
1792
+ const lineEnd = content.indexOf("\n", closing.end);
1793
+ const suffix = content.slice(closing.end, lineEnd === -1 ? content.length : lineEnd);
1794
+ return content.slice(opening.end, closing.index).includes("\n") || /^[\t\r ]*$/.test(suffix);
1795
+ }
1796
+ function resolveDocsMarkdownPromptContainer(content, opening) {
1797
+ const lineStart = Math.max(0, content.lastIndexOf("\n", opening.index - 1) + 1);
1798
+ let prefix = content.slice(lineStart, opening.index);
1799
+ let blockquoteDepth = 0;
1800
+ let listIndent = 0;
1801
+ while (true) {
1802
+ const blockquote = /^ {0,3}>[\t ]?/.exec(prefix);
1803
+ if (!blockquote) break;
1804
+ blockquoteDepth += 1;
1805
+ prefix = prefix.slice(blockquote[0].length);
1806
+ }
1807
+ while (true) {
1808
+ const list = /^ {0,3}(?:[-+*]|\d{1,9}[.)])[\t ]+/.exec(prefix);
1809
+ if (!list) break;
1810
+ listIndent += list[0].length;
1811
+ prefix = prefix.slice(list[0].length);
1812
+ }
1813
+ if (listIndent === 0 && /^[\t ]+$/.test(prefix)) {
1814
+ let previousLineEnd = Math.max(0, lineStart - 1);
1815
+ while (previousLineEnd > 0) {
1816
+ const previousLineStart = Math.max(0, content.lastIndexOf("\n", previousLineEnd - 1) + 1);
1817
+ let previousLine = content.slice(previousLineStart, previousLineEnd).replace(/\r$/, "");
1818
+ for (let depth = 0; depth < blockquoteDepth; depth += 1) {
1819
+ const blockquote = /^ {0,3}>[\t ]?/.exec(previousLine);
1820
+ if (!blockquote) {
1821
+ previousLine = "";
1822
+ break;
1823
+ }
1824
+ previousLine = previousLine.slice(blockquote[0].length);
1825
+ }
1826
+ const list = /^ {0,3}(?:[-+*]|\d{1,9}[.)])[\t ]+/.exec(previousLine);
1827
+ if (list && prefix.length >= list[0].length) {
1828
+ listIndent = list[0].length;
1829
+ break;
1830
+ }
1831
+ if (previousLine.trim().length === 0) break;
1832
+ previousLineEnd = Math.max(0, previousLineStart - 1);
1833
+ }
1834
+ }
1835
+ if (blockquoteDepth === 0 && listIndent === 0 || !/^[\t ]*$/.test(prefix)) return;
1836
+ return {
1837
+ blockquoteDepth,
1838
+ listIndent
1839
+ };
1840
+ }
1841
+ function stripDocsMarkdownPromptContainer(children, container) {
1842
+ if (!container) return children;
1843
+ return children.split(/(\r?\n)/).map((segment, index) => {
1844
+ if (index % 2 === 1) return segment;
1845
+ let line = segment;
1846
+ for (let depth = 0; depth < container.blockquoteDepth; depth += 1) {
1847
+ const blockquote = /^ {0,3}>[\t ]?/.exec(line);
1848
+ if (!blockquote) break;
1849
+ line = line.slice(blockquote[0].length);
1850
+ }
1851
+ let remainingIndent = container.listIndent;
1852
+ while (remainingIndent > 0 && /^[\t ]/.test(line)) {
1853
+ line = line.slice(1);
1854
+ remainingIndent -= 1;
1855
+ }
1856
+ return line;
1857
+ }).join("");
1858
+ }
1859
+ function createDocsMarkdownPromptReplacement(content, start, end, token, flow, container, adjacentFlowBefore = false, adjacentFlowAfter = false) {
1860
+ if (!flow || container) return token;
1861
+ const newline = content.includes("\r\n") ? "\r\n" : "\n";
1862
+ const before = content.slice(0, start);
1863
+ const after = content.slice(end);
1864
+ const leading = adjacentFlowBefore || before.length === 0 || /(?:\r?\n){2}$/.test(before) ? "" : /\r?\n$/.test(before) ? newline : newline + newline;
1865
+ const trailing = adjacentFlowAfter || after.length === 0 || /^(?:\r?\n){2}/.test(after) ? "" : /^\r?\n/.test(after) ? newline : newline + newline;
1866
+ return leading + token + trailing;
1867
+ }
1868
+ /**
1869
+ * Extract live MDX Prompt blocks while leaving Markdown literals untouched.
1870
+ *
1871
+ * Prompt bodies are copyable source, so callers can safely run audience,
1872
+ * reference-definition, and heading passes over `markdown`, then restore each
1873
+ * block from its token. Fences (including container fences), inline code, links,
1874
+ * comments, raw elements, and other literal contexts are never extracted.
1875
+ */
1876
+ function extractDocsMarkdownPromptBlocks(content) {
1877
+ if (!/<Prompt(?=[\s/>])/.test(content)) return {
1878
+ blocks: [],
1879
+ markdown: content
1880
+ };
1881
+ const syntaxProtectedRanges = mergeProtectedRanges([...findProtectedRanges(content), ...findMarkdownLinkLiteralRanges(content)]);
1882
+ const expressionRanges = findDocsMarkdownPromptExpressionRanges(content, syntaxProtectedRanges);
1883
+ const baseProtectedRanges = mergeProtectedRanges([
1884
+ ...syntaxProtectedRanges,
1885
+ ...expressionRanges,
1886
+ ...findDocsMarkdownRawHtmlLiteralRanges(content),
1887
+ ...findDocsMarkdownHtmlContainerLiteralRanges(content, syntaxProtectedRanges)
1888
+ ]);
1889
+ const protectedRanges = mergeProtectedRanges([...baseProtectedRanges, ...findDocsMarkdownPromptBracketLiteralRanges(content, baseProtectedRanges)]);
1890
+ const promptAst = findDocsMarkdownPromptAstInfo(content);
1891
+ const pairs = [];
1892
+ const openings = [];
1893
+ let cursor = 0;
1894
+ while (cursor < content.length) {
1895
+ const index = content.indexOf("<", cursor);
1896
+ if (index === -1) break;
1897
+ if (isEscapedAt(content, index) || isInsideRange(index, protectedRanges)) {
1898
+ cursor = index + 1;
1899
+ continue;
1900
+ }
1901
+ const tag = readDocsMarkdownPromptTagAt(content, index);
1902
+ if (!tag) {
1903
+ cursor = index + 1;
1904
+ continue;
1905
+ }
1906
+ cursor = tag.end;
1907
+ if (!tag.closing) {
1908
+ if (promptAst && !promptAst.starts.has(tag.index)) continue;
1909
+ if (!tag.selfClosing) openings.push({
1910
+ completedChildren: [],
1911
+ tag
1912
+ });
1913
+ continue;
1914
+ }
1915
+ const frame = openings.pop();
1916
+ if (!frame) continue;
1917
+ const container = resolveDocsMarkdownPromptContainer(content, frame.tag);
1918
+ const pair = {
1919
+ attributes: frame.tag.attributes,
1920
+ children: stripDocsMarkdownPromptContainer(content.slice(frame.tag.end, tag.index), container),
1921
+ container,
1922
+ end: tag.end,
1923
+ flow: promptAst?.flowStarts.has(frame.tag.index) === true || isFallbackDocsMarkdownPromptFlow(content, frame.tag, tag),
1924
+ start: frame.tag.index
1925
+ };
1926
+ const parent = openings.at(-1);
1927
+ if (parent) parent.completedChildren.push(pair);
1928
+ else pairs.push(pair);
1929
+ }
1930
+ for (const frame of openings) pairs.push(...frame.completedChildren);
1931
+ pairs.sort((left, right) => left.start - right.start);
1932
+ if (pairs.length === 0) return {
1933
+ blocks: [],
1934
+ markdown: content
1935
+ };
1936
+ const usedTokens = /* @__PURE__ */ new Set();
1937
+ const blocks = pairs.map((pair, index) => {
1938
+ const token = createDocsMarkdownPromptToken(content, usedTokens, index);
1939
+ usedTokens.add(token);
1940
+ return {
1941
+ attributes: pair.attributes,
1942
+ children: pair.children,
1943
+ token
1944
+ };
1945
+ });
1946
+ let markdown = content;
1947
+ for (let index = pairs.length - 1; index >= 0; index -= 1) {
1948
+ const replacement = createDocsMarkdownPromptReplacement(content, pairs[index].start, pairs[index].end, blocks[index].token, pairs[index].flow, pairs[index].container, index > 0 && pairs[index - 1].flow && /^[\t \r\n]*$/.test(content.slice(pairs[index - 1].end, pairs[index].start)), index + 1 < pairs.length && pairs[index + 1].flow && /^[\t \r\n]*$/.test(content.slice(pairs[index].end, pairs[index + 1].start)));
1949
+ markdown = markdown.slice(0, pairs[index].start) + replacement + markdown.slice(pairs[index].end);
1950
+ }
1951
+ return {
1952
+ blocks,
1953
+ markdown
1954
+ };
1955
+ }
2149
1956
  function normalizeProjectedWhitespace(content) {
2150
1957
  const protectedRanges = findProtectedRanges(content);
2151
1958
  return content.replace(/\n{3,}/g, (newlines, offset) => {
@@ -2320,7 +2127,7 @@ const DEFAULT_DOCS_DIAGNOSTICS_MCP_TOOLS = {
2320
2127
  getContext: true
2321
2128
  };
2322
2129
  const DOCS_MARKDOWN_SIGNATURE_AGENT_HEADER = "Signature-Agent";
2323
- const DOCS_MARKDOWN_SECTION_INDEX_FORMAT = "docs-markdown-sections.v1";
2130
+ const DOCS_MARKDOWN_SECTION_INDEX_FORMAT = "docs-markdown-sections.v2";
2324
2131
  const DOCS_AI_AGENT_USER_AGENT_PATTERNS = [
2325
2132
  "claudebot",
2326
2133
  "claude-searchbot",
@@ -2389,6 +2196,7 @@ const DOCS_AI_AGENT_USER_AGENT_HEADER_PATTERN = buildDocsUserAgentHeaderPattern(
2389
2196
  const DOCS_TRADITIONAL_BOT_USER_AGENT_HEADER_PATTERN = buildDocsUserAgentHeaderPattern(DOCS_TRADITIONAL_BOT_USER_AGENT_PATTERNS);
2390
2197
  const DOCS_BOT_LIKE_USER_AGENT_HEADER_PATTERN = buildDocsUserAgentHeaderPattern(DOCS_BOT_LIKE_USER_AGENT_TERMS);
2391
2198
  const DOCS_LLMS_TXT_DIRECTIVE_LINE = "LLM index: /llms.txt";
2199
+ const DOCS_MARKDOWN_GENERATED_PREAMBLE_FIELD = "x_farming_labs_generated_preamble";
2392
2200
  const DOCS_MCP_SERVICE_SUBDOMAIN_LABELS = new Set([
2393
2201
  "api",
2394
2202
  "developer",
@@ -2978,6 +2786,13 @@ function validateDocsDiagnosticsSearchConfig(search, errors) {
2978
2786
  requireString("apiKey");
2979
2787
  }
2980
2788
  if (provider === "mcp") requireString("endpoint");
2789
+ const syncNamespace = stringConfigValue(search.syncNamespace);
2790
+ if (syncNamespace && syncNamespace.length > 1024) errors.push({
2791
+ severity: "error",
2792
+ code: "invalid-search-sync-namespace",
2793
+ path: "/search/syncNamespace",
2794
+ message: "search.syncNamespace must be 1024 characters or fewer."
2795
+ });
2981
2796
  if (provider === "custom" && !("adapter" in search)) errors.push({
2982
2797
  severity: "error",
2983
2798
  code: "missing-search-adapter",
@@ -3137,7 +2952,9 @@ function validateDocsAgentFeedbackPayload(value, schema, valuePath = "payload")
3137
2952
  }
3138
2953
  }
3139
2954
  function toDocsMarkdownUrl(url, options = {}) {
3140
- const [withoutHash, hash = ""] = url.split("#", 2);
2955
+ const hashIndex = url.indexOf("#");
2956
+ const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
2957
+ const hash = hashIndex >= 0 ? url.slice(hashIndex + 1) : "";
3141
2958
  const [pathname, query = ""] = withoutHash.split("?", 2);
3142
2959
  const normalizedPath = normalizeDocsUrlPath(pathname || "/");
3143
2960
  const markdownPath = normalizedPath.endsWith(".md") ? normalizedPath : `${normalizedPath}.md`;
@@ -3768,7 +3585,7 @@ function resolveDocsMarkdownMetadataUrl(value, origin) {
3768
3585
  return value;
3769
3586
  }
3770
3587
  }
3771
- function renderDocsMarkdownFrontmatter({ title, description, canonicalUrl, markdownUrl, lastUpdated, agent }) {
3588
+ function renderDocsMarkdownFrontmatter({ title, description, canonicalUrl, markdownUrl, lastUpdated, agent, generatedPreamble }) {
3772
3589
  return [
3773
3590
  "---",
3774
3591
  `title: ${toYamlString(title)}`,
@@ -3776,6 +3593,7 @@ function renderDocsMarkdownFrontmatter({ title, description, canonicalUrl, markd
3776
3593
  `canonical_url: ${toYamlString(canonicalUrl)}`,
3777
3594
  `markdown_url: ${toYamlString(markdownUrl)}`,
3778
3595
  ...lastUpdated ? [`last_updated: ${toYamlString(lastUpdated)}`] : [],
3596
+ ...generatedPreamble ? [`${DOCS_MARKDOWN_GENERATED_PREAMBLE_FIELD}: true`] : [],
3779
3597
  ...renderPageAgentFrontmatterYamlLines(agent),
3780
3598
  "---"
3781
3599
  ].join("\n");
@@ -3798,14 +3616,14 @@ function stripDocsMarkdownFrontmatter(markdown) {
3798
3616
  body: match[2] ?? ""
3799
3617
  };
3800
3618
  }
3801
- function slugifyPublicDocsMarkdownSectionId(value) {
3802
- return value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/`([^`]+)`/g, "$1").replace(/<[^>]*>/g, "").replace(/[^\p{L}\p{N}\s-]/gu, "").trim().replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
3803
- }
3804
3619
  function resolveDocsMarkdownSectionBody(document) {
3805
- const lines = stripDocsMarkdownFrontmatter(document).body.split(/\r?\n/u);
3620
+ const stripped = stripDocsMarkdownFrontmatter(document);
3621
+ const hasGeneratedPreamble = stripped.frontmatter.split(/\r?\n/u).some((line) => line.trim() === `${DOCS_MARKDOWN_GENERATED_PREAMBLE_FIELD}: true`);
3622
+ const lines = stripped.body.split(/\r?\n/u);
3806
3623
  let generatedPreambleStart = 0;
3807
3624
  while (generatedPreambleStart < lines.length && (lines[generatedPreambleStart] ?? "").trim() === "") generatedPreambleStart += 1;
3808
- if (/^#(?:\s+|$)/u.test(lines[generatedPreambleStart] ?? "") && /^URL:\s+\S/u.test(lines[generatedPreambleStart + 1] ?? "")) {
3625
+ if (hasGeneratedPreamble && /^#(?:\s+|$)/u.test(lines[generatedPreambleStart] ?? "") && /^URL:\s+\S/u.test(lines[generatedPreambleStart + 1] ?? "")) {
3626
+ lines[generatedPreambleStart] = "";
3809
3627
  let metadataEnd = generatedPreambleStart + 2;
3810
3628
  while (/^(?:LLM index|Description|Related):\s*/u.test(lines[metadataEnd] ?? "")) metadataEnd += 1;
3811
3629
  for (let index = generatedPreambleStart + 1; index < metadataEnd; index += 1) lines[index] = "";
@@ -3885,21 +3703,14 @@ function isDocsMarkdownSectionIndexRequest(url) {
3885
3703
  }
3886
3704
  function collectDocsMarkdownSections(document) {
3887
3705
  const { body, lineOffset } = resolveDocsMarkdownSectionBody(document);
3888
- const seen = /* @__PURE__ */ new Map();
3889
- return parseDocsMarkdownSections(body).flatMap((section) => {
3890
- const baseId = slugifyPublicDocsMarkdownSectionId(section.title);
3891
- if (!baseId) return [];
3892
- const count = seen.get(baseId) ?? 0;
3893
- seen.set(baseId, count + 1);
3894
- return [{
3895
- id: count === 0 ? baseId : `${baseId}-${count + 1}`,
3896
- heading: section.title,
3897
- level: section.level,
3898
- content: section.content,
3899
- startLine: section.startLine + lineOffset,
3900
- endLine: section.endLine + lineOffset
3901
- }];
3902
- });
3706
+ return parseDocsMarkdownSections(body).map((section) => ({
3707
+ id: section.anchor,
3708
+ heading: section.title,
3709
+ level: section.level,
3710
+ content: section.content,
3711
+ startLine: section.startLine + lineOffset,
3712
+ endLine: section.endLine + lineOffset
3713
+ }));
3903
3714
  }
3904
3715
  function updateDocsMarkdownUrl(value, update) {
3905
3716
  const isAbsolute = /^[a-z][a-z\d+.-]*:/iu.test(value);
@@ -3913,7 +3724,7 @@ function updateDocsMarkdownUrl(value, update) {
3913
3724
  }
3914
3725
  function resolveDocsMarkdownSectionCanonicalUrl(canonicalUrl, sectionId) {
3915
3726
  return updateDocsMarkdownUrl(canonicalUrl, (url) => {
3916
- url.hash = sectionId;
3727
+ url.hash = encodeURIComponent(sectionId);
3917
3728
  });
3918
3729
  }
3919
3730
  function resolveDocsMarkdownSectionFetchUrl(markdownUrl, sectionId, request) {
@@ -3972,7 +3783,7 @@ function buildDocsMarkdownSectionIndex(document, options) {
3972
3783
  ...request.byteBudget ? { byteBudget: request.byteBudget } : {}
3973
3784
  } : void 0;
3974
3785
  return {
3975
- schemaVersion: 1,
3786
+ schemaVersion: 2,
3976
3787
  format: DOCS_MARKDOWN_SECTION_INDEX_FORMAT,
3977
3788
  canonicalUrl: options.canonicalUrl,
3978
3789
  markdownUrl: options.markdownUrl,
@@ -3987,12 +3798,12 @@ function buildDocsMarkdownSectionIndex(document, options) {
3987
3798
  }
3988
3799
  function normalizeRequestedDocsMarkdownSectionId(requestedSection) {
3989
3800
  let selector = requestedSection.trim();
3990
- const hashIndex = selector.lastIndexOf("#");
3801
+ const hashIndex = selector.indexOf("#");
3991
3802
  if (hashIndex >= 0) selector = selector.slice(hashIndex + 1);
3992
3803
  try {
3993
3804
  selector = decodeURIComponent(selector);
3994
3805
  } catch {}
3995
- return selector.replace(/^#+/u, "").toLowerCase();
3806
+ return selector;
3996
3807
  }
3997
3808
  function selectDocsMarkdownSection(document, request) {
3998
3809
  const availableSections = collectDocsMarkdownSections(document);
@@ -4010,8 +3821,12 @@ function selectDocsMarkdownSection(document, request) {
4010
3821
  availableSections
4011
3822
  };
4012
3823
  }
3824
+ const rawRequestedId = requestedSection.trim();
3825
+ const rawExactSection = availableSections.find((candidate) => candidate.id === rawRequestedId);
4013
3826
  const requestedId = normalizeRequestedDocsMarkdownSectionId(requestedSection);
4014
- const directSection = availableSections.find((candidate) => candidate.id === requestedId);
3827
+ const exactSection = rawExactSection ?? availableSections.find((candidate) => candidate.id === requestedId);
3828
+ const caseInsensitiveSections = exactSection ? [] : availableSections.filter((candidate) => candidate.id.toLowerCase() === requestedId.toLowerCase());
3829
+ const directSection = exactSection ?? (caseInsensitiveSections.length === 1 ? caseInsensitiveSections[0] : void 0);
4015
3830
  const { body, lineOffset } = resolveDocsMarkdownSectionBody(document);
4016
3831
  const selectedSharedSection = directSection ? void 0 : findDocsMarkdownSection(body, requestedSection);
4017
3832
  const sharedAliasSection = selectedSharedSection ? availableSections.find((candidate) => candidate.startLine === selectedSharedSection.startLine + lineOffset) : void 0;
@@ -4262,10 +4077,10 @@ function createDocsMarkdownResponse(options) {
4262
4077
  }
4263
4078
  const sectionResult = sectionRequest ? selectDocsMarkdownSection(document, sectionRequest) : void 0;
4264
4079
  const responseDocument = sectionResult?.document ?? document;
4265
- const sectionCanonicalUrl = sectionResult?.found && sectionResult.section ? `${canonicalUrl}#${sectionResult.section.id}` : canonicalUrl;
4080
+ const sectionCanonicalUrl = sectionResult?.found && sectionResult.section ? resolveDocsMarkdownSectionCanonicalUrl(canonicalUrl, sectionResult.section.id) : canonicalUrl;
4266
4081
  const sectionContentLocation = sectionRequest ? appendDocsMarkdownSectionQuery(contentLocation, sectionRequest) : contentLocation;
4267
4082
  const sectionHeaders = sectionResult ? {
4268
- "X-Docs-Markdown-Section": sectionResult.section?.id ?? "",
4083
+ "X-Docs-Markdown-Section": sectionResult.section ? encodeURIComponent(sectionResult.section.id) : "",
4269
4084
  "X-Docs-Markdown-Section-Found": sectionResult.found ? "true" : "false",
4270
4085
  "X-Docs-Markdown-Section-Truncated": sectionResult.truncated ? "true" : "false",
4271
4086
  "X-Docs-Markdown-Estimated-Tokens": String(sectionResult.estimatedTokens),
@@ -4456,7 +4271,10 @@ function renderDocsMarkdownDocument(page, options) {
4456
4271
  if (page.description) lines.push(`Description: ${page.description}`);
4457
4272
  lines.push(...relatedLines);
4458
4273
  lines.push("", upsertPageAgentContractMarkdown(page.agentFallbackRawContent ?? page.agentFallbackContent ?? page.rawContent ?? page.content, page.agent));
4459
- return appendDocsMarkdownSitemapFooter(prependDocsMarkdownFrontmatter(lines.join("\n"), resolveDocsMarkdownPageMetadata(page, options)), options?.sitemap);
4274
+ return appendDocsMarkdownSitemapFooter(prependDocsMarkdownFrontmatter(lines.join("\n"), {
4275
+ ...resolveDocsMarkdownPageMetadata(page, options),
4276
+ generatedPreamble: true
4277
+ }), options?.sitemap);
4460
4278
  }
4461
4279
  function renderDocsSkillDocument(options) {
4462
4280
  const { origin } = options;
@@ -4527,7 +4345,7 @@ function buildDocsAgentDiscoverySpec({ origin, entry = "docs", apiRoute, apiCata
4527
4345
  return {
4528
4346
  $schema: DOCS_AGENT_MANIFEST_SCHEMA_URI,
4529
4347
  format: DOCS_AGENT_MANIFEST_FORMAT,
4530
- version: "1",
4348
+ version: DOCS_AGENT_MANIFEST_VERSION,
4531
4349
  name: "@farming-labs/docs",
4532
4350
  baseUrl: origin,
4533
4351
  site: {
@@ -4890,4 +4708,4 @@ function toYamlString(value) {
4890
4708
  }
4891
4709
 
4892
4710
  //#endregion
4893
- export { matchesDocsLlmsTxtSection as $, PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS as $t, buildDocsAgentDiscoverySpec as A, resolveDocsAudienceMdxContent as At, findDocsMarkdownPage as B, renderDocsSitemapXml as Bt, DOCS_AI_AGENT_USER_AGENT_HEADER_PATTERN as C, selectDocsMarkdownSection as Ct, DOCS_MARKDOWN_SIGNATURE_AGENT_HEADER as D, findDocsAudienceMdxTags as Dt, DOCS_MARKDOWN_SECTION_INDEX_FORMAT as E, findDocsAudienceMdxIssues as Et, buildDocsMcpEndpointCandidates as F, DEFAULT_SITEMAP_XML_ROUTE as Ft, isDocsAgentDiscoveryRequest as G, findDocsMarkdownSection as Gt, getDocsMarkdownCanonicalLinkHeader as H, resolveDocsSitemapPageLastmod as Ht, collectDocsMarkdownSections as I, buildDocsSitemapManifest as It, isDocsDiagnosticsRequest as J, renderDocsRelatedMarkdownLines as Jt, isDocsAgentsRequest as K, parseDocsMarkdownSections as Kt, createDocsMarkdownResponse as L, createDocsSitemapResponse as Lt, buildDocsConfigMap as M, DEFAULT_SITEMAP_MD_DOCS_ROUTE as Mt, buildDocsDiagnostics as N, DEFAULT_SITEMAP_MD_ROUTE as Nt, DOCS_TRADITIONAL_BOT_USER_AGENT_HEADER_PATTERN as O, resolveDocsAgentMdxContent as Ot, buildDocsMarkdownSectionIndex as P, DEFAULT_SITEMAP_MD_WELL_KNOWN_ROUTE as Pt, isDocsSkillRequest as Q, PAGE_AGENT_CONTRACT_START_MARKER as Qt, createDocsStandardsDiscoveryResponse as R, readDocsSitemapManifestFromContentMap as Rt, DEFAULT_SKILL_MD_WELL_KNOWN_ROUTE as S, resolveDocsMcpResourceLocation as Sn, selectDocsLlmsTxtContent as St, DOCS_CONFIG_MAP_TOP_LEVEL_KEYS as T, validateDocsAgentFeedbackPayload as Tt, getDocsMarkdownVaryHeader as U, resolveDocsSitemapRequest as Ut, getDocsLlmsTxtMaxCharsIssue as V, resolveDocsSitemapConfig as Vt, hasDocsMarkdownSignatureAgent as W, toDocsSitemapMarkdownUrl as Wt, isDocsMarkdownSectionIndexRequest as X, PAGE_AGENT_CONTRACT_FIELDS as Xt, isDocsLlmsTxtPublicRequest as Y, PAGE_AGENT_CONTRACT_END_MARKER as Yt, isDocsPublicGetRequest as Z, PAGE_AGENT_CONTRACT_FIELD_SCHEMA as Zt, DEFAULT_LLMS_TXT_MAX_CHARS as _, isDocsMcpRequest as _n, resolveDocsMarkdownRequest as _t, DEFAULT_AGENT_MD_ROUTE as a, stripGeneratedPageAgentContractMarkdown as an, renderDocsMarkdownDocument as at, DEFAULT_OPENAPI_SCHEMA_ROUTE as b, normalizeDocsMcpEndpointPath as bn, resolveDocsRequestApiRoute as bt, DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE as c, DEFAULT_MCP_PUBLIC_ROUTE as cn, resolveDocsAgentContractMcpTools as ct, DEFAULT_DOCS_CONFIG_FORMAT as d, buildDocsMcpProtectedResourceMetadataRoute as dn, resolveDocsAgentsFormat as dt, getPageAgentFrontmatterIssues as en, normalizeDocsPathSegment as et, DEFAULT_DOCS_CONFIG_ROUTE as f, getDocsMcpProtectedResourceMetadataRoutes as fn, resolveDocsLlmsTxtFormat as ft, DEFAULT_LLMS_FULL_TXT_WELL_KNOWN_ROUTE as g, isDocsMcpProtectedResourceMetadataPath as gn, resolveDocsMarkdownRecovery as gt, DEFAULT_LLMS_FULL_TXT_ROUTE as h, isDocsMcpOAuthScopeToken as hn, resolveDocsMarkdownCanonicalUrl as ht, DEFAULT_AGENT_FEEDBACK_ROUTE as i, renderPageAgentFrontmatterYamlLines as in, renderDocsLlmsTxt as it, buildDocsAgentFeedbackSchema as j, DEFAULT_SITEMAP_MANIFEST_PATH as jt, acceptsDocsMarkdown as k, resolveDocsAudienceExposure as kt, DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE as l, DEFAULT_MCP_ROUTE as ln, resolveDocsAgentFeedbackConfig as lt, DEFAULT_DOCS_DIAGNOSTICS_ROUTE as m, hasDocsMcpProtectedResourceConfig as mn, resolveDocsLlmsTxtSections as mt, DEFAULT_AGENTS_MD_WELL_KNOWN_ROUTE as n, normalizePageAgentFrontmatter as nn, parseDocsAgentFeedbackData as nt, DEFAULT_AGENT_MD_WELL_KNOWN_ROUTE as o, upsertPageAgentContractMarkdown as on, renderDocsMarkdownNotFound as ot, DEFAULT_DOCS_DIAGNOSTICS_FORMAT as p, getDocsMcpResourcePaths as pn, resolveDocsLlmsTxtRequest as pt, isDocsConfigRequest as q, normalizeDocsRelated as qt, DEFAULT_AGENT_FEEDBACK_PAYLOAD_SCHEMA as r, renderPageAgentContractMarkdown as rn, renderDocsAgentsDocument as rt, DEFAULT_AGENT_SPEC_ROUTE as s, DEFAULT_MCP_PROTECTED_RESOURCE_METADATA_ROUTE as sn, renderDocsSkillDocument as st, DEFAULT_AGENTS_MD_ROUTE as t, hasStructuredPageAgentContract as tn, normalizeDocsUrlPath as tt, DEFAULT_DOCS_API_ROUTE as u, DEFAULT_MCP_WELL_KNOWN_ROUTE as un, resolveDocsAgentFeedbackRequest as ut, DEFAULT_LLMS_TXT_ROUTE as v, isDocsMcpResourcePath as vn, resolveDocsMarkdownSectionRequest as vt, DOCS_BOT_LIKE_USER_AGENT_HEADER_PATTERN as w, toDocsMarkdownUrl as wt, DEFAULT_SKILL_MD_ROUTE as x, resolveDocsMcpProtectedResourceMetadataLocation as xn, resolveDocsSkillFormat as xt, DEFAULT_LLMS_TXT_WELL_KNOWN_ROUTE as y, normalizeDocsMcpAuthorizationServerUrls as yn, resolveDocsOpenApiDiscoveryConfig as yt, detectDocsMarkdownAgentRequest as z, renderDocsSitemapMarkdown as zt };
4711
+ export { matchesDocsLlmsTxtSection as $, getDocsMcpProtectedResourceMetadataRoutes as $t, buildDocsAgentDiscoverySpec as A, resolveDocsAudienceExposure as At, findDocsMarkdownPage as B, renderDocsSitemapMarkdown as Bt, DOCS_AI_AGENT_USER_AGENT_HEADER_PATTERN as C, selectDocsMarkdownSection as Ct, DOCS_MARKDOWN_SIGNATURE_AGENT_HEADER as D, findDocsAudienceMdxIssues as Dt, DOCS_MARKDOWN_SECTION_INDEX_FORMAT as E, extractDocsMarkdownPromptBlocks as Et, buildDocsMcpEndpointCandidates as F, DEFAULT_SITEMAP_MD_WELL_KNOWN_ROUTE as Ft, isDocsAgentDiscoveryRequest as G, toDocsSitemapMarkdownUrl as Gt, getDocsMarkdownCanonicalLinkHeader as H, resolveDocsSitemapConfig as Ht, collectDocsMarkdownSections as I, DEFAULT_SITEMAP_XML_ROUTE as It, isDocsDiagnosticsRequest as J, DEFAULT_MCP_PROTECTED_RESOURCE_METADATA_ROUTE as Jt, isDocsAgentsRequest as K, normalizeDocsRelated as Kt, createDocsMarkdownResponse as L, buildDocsSitemapManifest as Lt, buildDocsConfigMap as M, DEFAULT_SITEMAP_MANIFEST_PATH as Mt, buildDocsDiagnostics as N, DEFAULT_SITEMAP_MD_DOCS_ROUTE as Nt, DOCS_TRADITIONAL_BOT_USER_AGENT_HEADER_PATTERN as O, findDocsAudienceMdxTags as Ot, buildDocsMarkdownSectionIndex as P, DEFAULT_SITEMAP_MD_ROUTE as Pt, isDocsSkillRequest as Q, buildDocsMcpProtectedResourceMetadataRoute as Qt, createDocsStandardsDiscoveryResponse as R, createDocsSitemapResponse as Rt, DEFAULT_SKILL_MD_WELL_KNOWN_ROUTE as S, selectDocsLlmsTxtContent as St, DOCS_CONFIG_MAP_TOP_LEVEL_KEYS as T, validateDocsAgentFeedbackPayload as Tt, getDocsMarkdownVaryHeader as U, resolveDocsSitemapPageLastmod as Ut, getDocsLlmsTxtMaxCharsIssue as V, renderDocsSitemapXml as Vt, hasDocsMarkdownSignatureAgent as W, resolveDocsSitemapRequest as Wt, isDocsMarkdownSectionIndexRequest as X, DEFAULT_MCP_ROUTE as Xt, isDocsLlmsTxtPublicRequest as Y, DEFAULT_MCP_PUBLIC_ROUTE as Yt, isDocsPublicGetRequest as Z, DEFAULT_MCP_WELL_KNOWN_ROUTE as Zt, DEFAULT_LLMS_TXT_MAX_CHARS as _, resolveDocsMarkdownRequest as _t, DEFAULT_AGENT_MD_ROUTE as a, isDocsMcpResourcePath as an, renderDocsMarkdownDocument as at, DEFAULT_OPENAPI_SCHEMA_ROUTE as b, resolveDocsRequestApiRoute as bt, DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE as c, resolveDocsMcpProtectedResourceMetadataLocation as cn, resolveDocsAgentContractMcpTools as ct, DEFAULT_DOCS_CONFIG_FORMAT as d, resolveDocsAgentsFormat as dt, getDocsMcpResourcePaths as en, normalizeDocsPathSegment as et, DEFAULT_DOCS_CONFIG_ROUTE as f, resolveDocsLlmsTxtFormat as ft, DEFAULT_LLMS_FULL_TXT_WELL_KNOWN_ROUTE as g, resolveDocsMarkdownRecovery as gt, DEFAULT_LLMS_FULL_TXT_ROUTE as h, resolveDocsMarkdownCanonicalUrl as ht, DEFAULT_AGENT_FEEDBACK_ROUTE as i, isDocsMcpRequest as in, renderDocsLlmsTxt as it, buildDocsAgentFeedbackSchema as j, resolveDocsAudienceMdxContent as jt, acceptsDocsMarkdown as k, resolveDocsAgentMdxContent as kt, DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE as l, resolveDocsMcpResourceLocation as ln, resolveDocsAgentFeedbackConfig as lt, DEFAULT_DOCS_DIAGNOSTICS_ROUTE as m, resolveDocsLlmsTxtSections as mt, DEFAULT_AGENTS_MD_WELL_KNOWN_ROUTE as n, isDocsMcpOAuthScopeToken as nn, parseDocsAgentFeedbackData as nt, DEFAULT_AGENT_MD_WELL_KNOWN_ROUTE as o, normalizeDocsMcpAuthorizationServerUrls as on, renderDocsMarkdownNotFound as ot, DEFAULT_DOCS_DIAGNOSTICS_FORMAT as p, resolveDocsLlmsTxtRequest as pt, isDocsConfigRequest as q, renderDocsRelatedMarkdownLines as qt, DEFAULT_AGENT_FEEDBACK_PAYLOAD_SCHEMA as r, isDocsMcpProtectedResourceMetadataPath as rn, renderDocsAgentsDocument as rt, DEFAULT_AGENT_SPEC_ROUTE as s, normalizeDocsMcpEndpointPath as sn, renderDocsSkillDocument as st, DEFAULT_AGENTS_MD_ROUTE as t, hasDocsMcpProtectedResourceConfig as tn, normalizeDocsUrlPath as tt, DEFAULT_DOCS_API_ROUTE as u, resolveDocsAgentFeedbackRequest as ut, DEFAULT_LLMS_TXT_ROUTE as v, resolveDocsMarkdownSectionRequest as vt, DOCS_BOT_LIKE_USER_AGENT_HEADER_PATTERN as w, toDocsMarkdownUrl as wt, DEFAULT_SKILL_MD_ROUTE as x, resolveDocsSkillFormat as xt, DEFAULT_LLMS_TXT_WELL_KNOWN_ROUTE as y, resolveDocsOpenApiDiscoveryConfig as yt, detectDocsMarkdownAgentRequest as z, readDocsSitemapManifestFromContentMap as zt };