@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.
- package/dist/{agent-pS2nNQS3.mjs → agent-BJ0KXN-A.mjs} +583 -765
- package/dist/{agent-DbDfIqhe.mjs → agent-D0LEY2Vy.mjs} +4 -3
- package/dist/{agent-evals-CjYzCQMZ.mjs → agent-evals-LIScgQVm.mjs} +86 -43
- package/dist/{agent-export-CpQhD8eA.mjs → agent-export-B92pNe6g.mjs} +12 -11
- package/dist/agent-skills-bundle.d.mts +1 -1
- package/dist/{agent-skills-server-DZnNB4_S.d.mts → agent-skills-server-BqvIGQb1.d.mts} +2 -2
- package/dist/{agent-skills-server-BPVv4gMg.mjs → agent-skills-server-noFn1l_p.mjs} +1 -1
- package/dist/agent-skills-vite.d.mts +3 -3
- package/dist/agent-skills-vite.mjs +2 -2
- package/dist/{agents-B-1h9Jlm.mjs → agents-C228QGbp.mjs} +10 -9
- package/dist/cli/index.mjs +34 -30
- package/dist/client/react.d.mts +1 -1
- package/dist/{cloud-ask-ai-D9gIN4Vr.d.mts → cloud-ask-ai-6X9pVjIY.d.mts} +1 -1
- package/dist/{cloud-CyysfDny.mjs → cloud-pdNC-tyj.mjs} +3 -3
- package/dist/{codeblocks-DAj7EAwt.mjs → codeblocks-CFuurVIH.mjs} +2 -2
- package/dist/{dev-qE7MYEh9.mjs → dev-Cc1cFFj-.mjs} +2 -2
- package/dist/docs-cloud-server.d.mts +2 -2
- package/dist/docs-cloud-server.mjs +1 -1
- package/dist/{doctor-CBy8-tPu.mjs → doctor-CgrUZ3tY.mjs} +15 -14
- package/dist/{downgrade-DCxezPZI.mjs → downgrade-w7e6Se0L.mjs} +2 -2
- package/dist/{golden-evaluations-DGg_eHIY.mjs → golden-evaluations-DTEPZeb0.mjs} +4 -3
- package/dist/index.d.mts +72 -6
- package/dist/index.mjs +9 -8
- package/dist/{init-p1MHf06G.mjs → init-DAkI0Lkf.mjs} +3 -3
- package/dist/markdown-rendering.d.mts +75 -0
- package/dist/markdown-rendering.mjs +618 -0
- package/dist/markdown-sections-7OoA7ylx.mjs +1492 -0
- package/dist/{mcp-BNK45dzD.mjs → mcp-YD37HlPY.mjs} +12 -9
- package/dist/mcp.d.mts +13 -2
- package/dist/mcp.mjs +121 -60
- package/dist/{metadata-D6qlWDu-.mjs → metadata-N252j5_a.mjs} +1 -1
- package/dist/{package-version-BXHcIm1T.mjs → package-version-n5AFur8a.mjs} +1 -1
- package/dist/{reading-time-DvTuW2Iy.mjs → prompt-references-BIS1eXt4.mjs} +158 -4
- package/dist/{search-1aftosa5.d.mts → retrieval-digest-9Kp3uSaZ.d.mts} +69 -5
- package/dist/{review-Cace7A2c.mjs → review-Dbzkdl6K.mjs} +10 -9
- package/dist/{robots-DmE_wXvG.mjs → robots-DUO0r4UI.mjs} +6 -5
- package/dist/{robots-C2SindI5.mjs → robots-RbgmSvPH.mjs} +2 -2
- package/dist/{search-BbArHODP.mjs → search-DIyIl-tE.mjs} +1288 -149
- package/dist/{search-DB3svkNQ.mjs → search-hcqaEZVN.mjs} +66 -27
- package/dist/server.d.mts +5 -5
- package/dist/server.mjs +10 -9
- package/dist/{sitemap-DPTLh_26.mjs → sitemap-jhkS_jYx.mjs} +10 -9
- package/dist/{sitemap-server-PUoOhplO.mjs → sitemap-server-BfyBM7_V.mjs} +1 -1
- package/dist/{standards-discovery-CYfiQE13.mjs → standards-discovery-BwL5ffGx.mjs} +4 -3
- package/dist/{standards-discovery-DRJ10g7B.d.mts → standards-discovery-CdrOE-05.d.mts} +5 -4
- package/dist/{types-B9DNNAdT.d.mts → types-clg5J1R4.d.mts} +60 -1
- package/dist/{upgrade-DDJQ5l6n.mjs → upgrade-oz-GChgt.mjs} +2 -2
- package/package.json +9 -1
- /package/dist/{cloud-ask-ai-hnJfj8-X.mjs → cloud-ask-ai-sbpjOR2K.mjs} +0 -0
- /package/dist/{code-blocks-qe0T8-xe.mjs → code-blocks-DnNVNK2M.mjs} +0 -0
- /package/dist/{config-z7_R0f86.mjs → config-Wcdj-D0a.mjs} +0 -0
- /package/dist/{errors-Cc_qplZU.mjs → errors-DbOhkE1h.mjs} +0 -0
- /package/dist/{i18n-CCaFUnAN.mjs → i18n-hHVWcflJ.mjs} +0 -0
- /package/dist/{templates-BJnf6B8l.mjs → templates-C6avM0U3.mjs} +0 -0
- /package/dist/{utils-C4RC8Zq_.mjs → utils-DpiIioYb.mjs} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
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:
|
|
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.
|
|
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
|
|
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
|
|
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 ?
|
|
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
|
|
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"),
|
|
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:
|
|
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 $,
|
|
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 };
|