@farming-labs/docs 0.2.53 → 0.2.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/agent-BXvi0uhS.mjs +623 -0
  2. package/dist/{agent-BMxMpEa0.mjs → agent-DXkXi-pS.mjs} +590 -19
  3. package/dist/agent-evals-BD17jOqL.mjs +1166 -0
  4. package/dist/{agent-export--X9Go-wj.mjs → agent-export-n-a0GbeU.mjs} +9 -8
  5. package/dist/agent-scope-B8lptqCd.mjs +283 -0
  6. package/dist/agent-surface-drift-LS8zQgbq.mjs +1429 -0
  7. package/dist/{agents-CW-zTNKP.mjs → agents-BJaRQimo.mjs} +7 -6
  8. package/dist/{analytics-BZEwTK-8.mjs → analytics-Bx44lg6d.mjs} +1 -1
  9. package/dist/cli/index.mjs +29 -29
  10. package/dist/client/react.d.mts +1 -1
  11. package/dist/client/react.mjs +1 -1
  12. package/dist/{cloud-zs0qAnKJ.mjs → cloud-HWFlbfLJ.mjs} +4 -4
  13. package/dist/{cloud-ask-ai-BFlx8VMO.mjs → cloud-ask-ai-1k0q6OAH.mjs} +1 -1
  14. package/dist/{cloud-ask-ai-CMzYVzVX.d.mts → cloud-ask-ai-466g6uAi.d.mts} +1 -1
  15. package/dist/code-blocks-C9awWzEQ.mjs +871 -0
  16. package/dist/codeblocks-BzfkREEC.mjs +250 -0
  17. package/dist/{config-DhIyFsy9.mjs → config-CydaZ5PB.mjs} +52 -11
  18. package/dist/{dev-DFeVU2Ui.mjs → dev-BA2kRuCn.mjs} +3 -3
  19. package/dist/docs-cloud-server.d.mts +2 -2
  20. package/dist/docs-cloud-server.mjs +2 -2
  21. package/dist/{doctor-CkM5tKdD.mjs → doctor-CQpQ2zZm.mjs} +150 -32
  22. package/dist/{downgrade-Dj_KXV11.mjs → downgrade-BStNhyCc.mjs} +2 -2
  23. package/dist/index.d.mts +36 -17
  24. package/dist/index.mjs +6 -7
  25. package/dist/{init-Cmz-oqnp.mjs → init-gnHQ_Pz9.mjs} +3 -3
  26. package/dist/{mcp-B4Q1PN93.mjs → mcp-DnxZZWpY.mjs} +6 -5
  27. package/dist/mcp.d.mts +22 -4
  28. package/dist/mcp.mjs +520 -43
  29. package/dist/{package-version-DxnTZH4m.mjs → package-version-DRIc08EU.mjs} +1 -1
  30. package/dist/{reading-time-BuK2YL23.mjs → reading-time-BrTd3DIh.mjs} +2 -3
  31. package/dist/{review-BEsbm0l2.mjs → review-B6gyEFkD.mjs} +149 -14
  32. package/dist/{robots-BOwkq9du.mjs → robots-4BUJxlvV.mjs} +4 -5
  33. package/dist/{robots-C6uQG-fS.mjs → robots-DAptQnkx.mjs} +1 -1
  34. package/dist/{search-CJNLkdjX.mjs → search-CJIC1Cqo.mjs} +1 -2
  35. package/dist/{search-CtAXkk_J.mjs → search-CbPm2x5g.mjs} +6 -5
  36. package/dist/{search-CTu6Bvq-.d.mts → search-CfWvmVYA.d.mts} +1 -1
  37. package/dist/server.d.mts +108 -5
  38. package/dist/server.mjs +9 -9
  39. package/dist/{sitemap-OPb8EdNe.mjs → sitemap-D6nP3J1Q.mjs} +8 -7
  40. package/dist/{sitemap-server-DnilMEiZ.mjs → sitemap-server-wsNLyVkb.mjs} +1 -1
  41. package/dist/{types-CdKu8KmO.d.mts → types-BVgucdVm.d.mts} +77 -1
  42. package/dist/{upgrade-BNdBB9tQ.mjs → upgrade-CXYRNV0C.mjs} +2 -2
  43. package/package.json +1 -1
  44. package/dist/agent-2t4kZLGo.mjs +0 -10
  45. package/dist/agent-contract-b0akaPcg.mjs +0 -573
  46. package/dist/codeblocks-DWM4IJPL.mjs +0 -1710
  47. package/dist/review-BHdy75TE.mjs +0 -541
  48. /package/dist/{cloud-analytics-Dlk_byos.mjs → cloud-analytics-CSyFE6SS.mjs} +0 -0
  49. /package/dist/{errors-BxfYhp1L.mjs → errors-BFUtdZfC.mjs} +0 -0
  50. /package/dist/{templates-Bty9M6lA.mjs → templates-1Cod8KrJ.mjs} +0 -0
  51. /package/dist/{utils-CMZTjRQT.mjs → utils-DBCCkkJS.mjs} +0 -0
@@ -1,5 +1,592 @@
1
- import { l as upsertPageAgentContractMarkdown, s as renderPageAgentFrontmatterYamlLines } from "./agent-contract-b0akaPcg.mjs";
1
+ //#region src/agent-contract.ts
2
+ const PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS = [
3
+ "task",
4
+ "outcome",
5
+ "appliesTo",
6
+ "prerequisites",
7
+ "files",
8
+ "commands",
9
+ "sideEffects",
10
+ "verification",
11
+ "rollback",
12
+ "failureModes"
13
+ ];
14
+ const PAGE_AGENT_CONTRACT_FIELDS = ["tokenBudget", ...PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS];
15
+ const PAGE_AGENT_CONTRACT_FIELD_SCHEMA = {
16
+ tokenBudget: "number",
17
+ task: "string",
18
+ outcome: "string",
19
+ appliesTo: {
20
+ framework: "string|string[]",
21
+ version: "string|string[]",
22
+ package: "string|string[]"
23
+ },
24
+ prerequisites: "string[]",
25
+ files: "string[]",
26
+ commands: "Array<string|{run,cwd?,description?}>",
27
+ sideEffects: "string[]",
28
+ verification: "Array<string|{description?,run?,expect?}>",
29
+ rollback: "string[]",
30
+ failureModes: "Array<string|{symptom,resolution?}>"
31
+ };
32
+ const APPLIES_TO_FIELDS = [
33
+ "framework",
34
+ "version",
35
+ "package"
36
+ ];
37
+ const COMMAND_FIELDS = [
38
+ "run",
39
+ "cwd",
40
+ "description"
41
+ ];
42
+ const VERIFICATION_FIELDS = [
43
+ "description",
44
+ "run",
45
+ "expect"
46
+ ];
47
+ const FAILURE_MODE_FIELDS = ["symptom", "resolution"];
48
+ const PAGE_AGENT_CONTRACT_START_MARKER = "<!-- farming-labs:agent-contract:start -->";
49
+ const PAGE_AGENT_CONTRACT_END_MARKER = "<!-- farming-labs:agent-contract:end -->";
50
+ function isRecord(value) {
51
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
52
+ }
53
+ function normalizeString(value) {
54
+ if (typeof value !== "string") return void 0;
55
+ return value.trim() || void 0;
56
+ }
57
+ function normalizeStringList(value) {
58
+ if (!Array.isArray(value)) return void 0;
59
+ const seen = /* @__PURE__ */ new Set();
60
+ const normalized = [];
61
+ for (const item of value) {
62
+ const text = normalizeString(item);
63
+ if (!text || seen.has(text)) continue;
64
+ seen.add(text);
65
+ normalized.push(text);
66
+ }
67
+ return normalized.length > 0 ? normalized : void 0;
68
+ }
69
+ function normalizeStringOrList(value) {
70
+ const single = normalizeString(value);
71
+ if (single) return [single];
72
+ return normalizeStringList(value);
73
+ }
74
+ function normalizeAppliesTo(value) {
75
+ if (!isRecord(value)) return void 0;
76
+ const framework = normalizeStringOrList(value.framework);
77
+ const version = normalizeStringOrList(value.version);
78
+ const packageNames = normalizeStringOrList(value.package);
79
+ if (!framework && !version && !packageNames) return void 0;
80
+ return {
81
+ ...framework ? { framework } : {},
82
+ ...version ? { version } : {},
83
+ ...packageNames ? { package: packageNames } : {}
84
+ };
85
+ }
86
+ function normalizeCommands(value) {
87
+ if (!Array.isArray(value)) return void 0;
88
+ const commands = [];
89
+ for (const item of value) {
90
+ const shorthand = normalizeString(item);
91
+ if (shorthand) {
92
+ commands.push(shorthand);
93
+ continue;
94
+ }
95
+ if (!isRecord(item)) continue;
96
+ const run = normalizeString(item.run);
97
+ if (!run) continue;
98
+ const cwd = normalizeString(item.cwd);
99
+ const description = normalizeString(item.description);
100
+ commands.push({
101
+ run,
102
+ ...cwd ? { cwd } : {},
103
+ ...description ? { description } : {}
104
+ });
105
+ }
106
+ return commands.length > 0 ? commands : void 0;
107
+ }
108
+ function normalizeVerification(value) {
109
+ if (!Array.isArray(value)) return void 0;
110
+ const verification = [];
111
+ for (const item of value) {
112
+ const shorthand = normalizeString(item);
113
+ if (shorthand) {
114
+ verification.push(shorthand);
115
+ continue;
116
+ }
117
+ if (!isRecord(item)) continue;
118
+ const description = normalizeString(item.description);
119
+ const run = normalizeString(item.run);
120
+ const expect = normalizeString(item.expect);
121
+ if (!description && !run && !expect) continue;
122
+ verification.push({
123
+ ...description ? { description } : {},
124
+ ...run ? { run } : {},
125
+ ...expect ? { expect } : {}
126
+ });
127
+ }
128
+ return verification.length > 0 ? verification : void 0;
129
+ }
130
+ function normalizeFailureModes(value) {
131
+ if (!Array.isArray(value)) return void 0;
132
+ const failureModes = [];
133
+ for (const item of value) {
134
+ const shorthand = normalizeString(item);
135
+ if (shorthand) {
136
+ failureModes.push(shorthand);
137
+ continue;
138
+ }
139
+ if (!isRecord(item)) continue;
140
+ const symptom = normalizeString(item.symptom);
141
+ if (!symptom) continue;
142
+ const resolution = normalizeString(item.resolution);
143
+ failureModes.push({
144
+ symptom,
145
+ ...resolution ? { resolution } : {}
146
+ });
147
+ }
148
+ return failureModes.length > 0 ? failureModes : void 0;
149
+ }
150
+ function normalizeTokenBudget(value) {
151
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return void 0;
152
+ return Math.ceil(value);
153
+ }
154
+ /**
155
+ * Normalize untrusted page frontmatter into the stable agent contract shape.
156
+ * Invalid fields are omitted so malformed author input cannot break page delivery.
157
+ */
158
+ function normalizePageAgentFrontmatter(value) {
159
+ if (!isRecord(value)) return void 0;
160
+ const tokenBudget = normalizeTokenBudget(value.tokenBudget);
161
+ const task = normalizeString(value.task);
162
+ const outcome = normalizeString(value.outcome);
163
+ const appliesTo = normalizeAppliesTo(value.appliesTo);
164
+ const prerequisites = normalizeStringList(value.prerequisites);
165
+ const files = normalizeStringList(value.files);
166
+ const commands = normalizeCommands(value.commands);
167
+ const sideEffects = normalizeStringList(value.sideEffects);
168
+ const verification = normalizeVerification(value.verification);
169
+ const rollback = normalizeStringList(value.rollback);
170
+ const failureModes = normalizeFailureModes(value.failureModes);
171
+ const normalized = {
172
+ ...tokenBudget !== void 0 ? { tokenBudget } : {},
173
+ ...task ? { task } : {},
174
+ ...outcome ? { outcome } : {},
175
+ ...appliesTo ? { appliesTo } : {},
176
+ ...prerequisites ? { prerequisites } : {},
177
+ ...files ? { files } : {},
178
+ ...commands ? { commands } : {},
179
+ ...sideEffects ? { sideEffects } : {},
180
+ ...verification ? { verification } : {},
181
+ ...rollback ? { rollback } : {},
182
+ ...failureModes ? { failureModes } : {}
183
+ };
184
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
185
+ }
186
+ function hasStructuredPageAgentContract(value) {
187
+ const normalized = normalizePageAgentFrontmatter(value);
188
+ if (!normalized) return false;
189
+ return PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS.some((field) => normalized[field] !== void 0);
190
+ }
191
+ function addStringIssue(issues, object, field) {
192
+ if (!(field in object)) return;
193
+ if (!normalizeString(object[field])) issues.push({
194
+ path: `agent.${field}`,
195
+ message: "must be a non-empty string"
196
+ });
197
+ }
198
+ function addStringListIssues(issues, object, field) {
199
+ if (!(field in object)) return;
200
+ const value = object[field];
201
+ if (!Array.isArray(value) || value.length === 0) {
202
+ issues.push({
203
+ path: `agent.${field}`,
204
+ message: "must be a non-empty string array"
205
+ });
206
+ return;
207
+ }
208
+ value.forEach((item, index) => {
209
+ if (!normalizeString(item)) issues.push({
210
+ path: `agent.${field}[${index}]`,
211
+ message: "must be a non-empty string"
212
+ });
213
+ });
214
+ }
215
+ function editDistance(left, right) {
216
+ const previous = Array.from({ length: right.length + 1 }, (_, index) => index);
217
+ for (let leftIndex = 1; leftIndex <= left.length; leftIndex += 1) {
218
+ const current = [leftIndex];
219
+ 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));
220
+ previous.splice(0, previous.length, ...current);
221
+ }
222
+ return previous[right.length] ?? 0;
223
+ }
224
+ function closestKnownField(field, allowed) {
225
+ const closest = allowed.map((candidate) => ({
226
+ candidate,
227
+ distance: editDistance(field, candidate)
228
+ })).sort((left, right) => left.distance - right.distance || left.candidate.localeCompare(right.candidate))[0];
229
+ if (!closest) return void 0;
230
+ const threshold = Math.max(1, Math.min(3, Math.floor(closest.candidate.length / 3)));
231
+ return closest.distance <= threshold ? closest.candidate : void 0;
232
+ }
233
+ function addUnknownKeyIssues(issues, object, allowed, path) {
234
+ for (const field of Object.keys(object)) {
235
+ if (allowed.includes(field)) continue;
236
+ const suggestion = closestKnownField(field, allowed);
237
+ issues.push({
238
+ path: `${path}.${field}`,
239
+ message: suggestion ? `is not recognized; did you mean "${path}.${suggestion}"?` : "is not recognized"
240
+ });
241
+ }
242
+ }
243
+ /** Return author-facing validation issues without throwing. */
244
+ function getPageAgentFrontmatterIssues(value) {
245
+ if (value === void 0) return [];
246
+ if (!isRecord(value)) return [{
247
+ path: "agent",
248
+ message: "must be an object"
249
+ }];
250
+ const issues = [];
251
+ addUnknownKeyIssues(issues, value, PAGE_AGENT_CONTRACT_FIELDS, "agent");
252
+ if ("tokenBudget" in value && (typeof value.tokenBudget !== "number" || !Number.isFinite(value.tokenBudget) || value.tokenBudget <= 0)) issues.push({
253
+ path: "agent.tokenBudget",
254
+ message: "must be a positive finite number"
255
+ });
256
+ addStringIssue(issues, value, "task");
257
+ addStringIssue(issues, value, "outcome");
258
+ if ("appliesTo" in value) if (!isRecord(value.appliesTo)) issues.push({
259
+ path: "agent.appliesTo",
260
+ message: "must be an object"
261
+ });
262
+ else {
263
+ addUnknownKeyIssues(issues, value.appliesTo, APPLIES_TO_FIELDS, "agent.appliesTo");
264
+ for (const field of [
265
+ "framework",
266
+ "version",
267
+ "package"
268
+ ]) {
269
+ if (!(field in value.appliesTo)) continue;
270
+ const fieldValue = value.appliesTo[field];
271
+ if (!normalizeStringOrList(fieldValue)) {
272
+ issues.push({
273
+ path: `agent.appliesTo.${field}`,
274
+ message: "must be a non-empty string or string array"
275
+ });
276
+ continue;
277
+ }
278
+ if (Array.isArray(fieldValue)) fieldValue.forEach((item, index) => {
279
+ if (!normalizeString(item)) issues.push({
280
+ path: `agent.appliesTo.${field}[${index}]`,
281
+ message: "must be a non-empty string"
282
+ });
283
+ });
284
+ }
285
+ if (!normalizeAppliesTo(value.appliesTo)) issues.push({
286
+ path: "agent.appliesTo",
287
+ message: "must include framework, version, or package"
288
+ });
289
+ }
290
+ for (const field of [
291
+ "prerequisites",
292
+ "files",
293
+ "sideEffects",
294
+ "rollback"
295
+ ]) addStringListIssues(issues, value, field);
296
+ if ("commands" in value) if (!Array.isArray(value.commands) || value.commands.length === 0) issues.push({
297
+ path: "agent.commands",
298
+ message: "must be a non-empty array"
299
+ });
300
+ else value.commands.forEach((command, index) => {
301
+ if (normalizeString(command)) return;
302
+ if (!isRecord(command)) {
303
+ issues.push({
304
+ path: `agent.commands[${index}]`,
305
+ message: "must be a command string or an object with a non-empty run field"
306
+ });
307
+ return;
308
+ }
309
+ addUnknownKeyIssues(issues, command, COMMAND_FIELDS, `agent.commands[${index}]`);
310
+ if (!normalizeString(command.run)) {
311
+ issues.push({
312
+ path: `agent.commands[${index}]`,
313
+ message: "must be a command string or an object with a non-empty run field"
314
+ });
315
+ return;
316
+ }
317
+ for (const field of ["cwd", "description"]) if (field in command && !normalizeString(command[field])) issues.push({
318
+ path: `agent.commands[${index}].${field}`,
319
+ message: "must be a non-empty string"
320
+ });
321
+ });
322
+ if ("verification" in value) if (!Array.isArray(value.verification) || value.verification.length === 0) issues.push({
323
+ path: "agent.verification",
324
+ message: "must be a non-empty array"
325
+ });
326
+ else value.verification.forEach((step, index) => {
327
+ if (normalizeString(step)) return;
328
+ if (!isRecord(step)) {
329
+ issues.push({
330
+ path: `agent.verification[${index}]`,
331
+ message: "must be a string or an object with description, run, or expect"
332
+ });
333
+ return;
334
+ }
335
+ addUnknownKeyIssues(issues, step, VERIFICATION_FIELDS, `agent.verification[${index}]`);
336
+ if (!normalizeVerification([step])) {
337
+ issues.push({
338
+ path: `agent.verification[${index}]`,
339
+ message: "must be a string or an object with description, run, or expect"
340
+ });
341
+ return;
342
+ }
343
+ for (const field of [
344
+ "description",
345
+ "run",
346
+ "expect"
347
+ ]) if (field in step && !normalizeString(step[field])) issues.push({
348
+ path: `agent.verification[${index}].${field}`,
349
+ message: "must be a non-empty string"
350
+ });
351
+ });
352
+ if ("failureModes" in value) if (!Array.isArray(value.failureModes) || value.failureModes.length === 0) issues.push({
353
+ path: "agent.failureModes",
354
+ message: "must be a non-empty array"
355
+ });
356
+ else value.failureModes.forEach((mode, index) => {
357
+ if (normalizeString(mode)) return;
358
+ if (!isRecord(mode)) {
359
+ issues.push({
360
+ path: `agent.failureModes[${index}]`,
361
+ message: "must be a string or an object with a non-empty symptom field"
362
+ });
363
+ return;
364
+ }
365
+ addUnknownKeyIssues(issues, mode, FAILURE_MODE_FIELDS, `agent.failureModes[${index}]`);
366
+ if (!normalizeString(mode.symptom)) {
367
+ issues.push({
368
+ path: `agent.failureModes[${index}]`,
369
+ message: "must be a string or an object with a non-empty symptom field"
370
+ });
371
+ return;
372
+ }
373
+ if ("resolution" in mode && !normalizeString(mode.resolution)) issues.push({
374
+ path: `agent.failureModes[${index}].resolution`,
375
+ message: "must be a non-empty string"
376
+ });
377
+ });
378
+ return issues;
379
+ }
380
+ function yamlString(value) {
381
+ return JSON.stringify(value);
382
+ }
383
+ function renderYamlStringList(lines, indent, key, values) {
384
+ lines.push(`${indent}${key}:`);
385
+ for (const value of values) lines.push(`${indent} - ${yamlString(value)}`);
386
+ }
387
+ function renderYamlObjectList(lines, indent, key, values, fields) {
388
+ lines.push(`${indent}${key}:`);
389
+ for (const value of values) {
390
+ if (typeof value === "string") {
391
+ lines.push(`${indent} - ${yamlString(value)}`);
392
+ continue;
393
+ }
394
+ const record = value;
395
+ const firstField = fields.find((field) => normalizeString(record[field]));
396
+ if (!firstField) continue;
397
+ lines.push(`${indent} - ${firstField}: ${yamlString(normalizeString(record[firstField]))}`);
398
+ for (const field of fields) {
399
+ const fieldValue = normalizeString(record[field]);
400
+ if (field === firstField || !fieldValue) continue;
401
+ lines.push(`${indent} ${field}: ${yamlString(fieldValue)}`);
402
+ }
403
+ }
404
+ }
405
+ /** Render normalized `agent` YAML in a stable field order. */
406
+ function renderPageAgentFrontmatterYamlLines(value, indentation = 0) {
407
+ const agent = normalizePageAgentFrontmatter(value);
408
+ if (!agent) return [];
409
+ const indent = " ".repeat(Math.max(0, indentation));
410
+ const child = `${indent} `;
411
+ const lines = [`${indent}agent:`];
412
+ if (agent.tokenBudget !== void 0) lines.push(`${child}tokenBudget: ${agent.tokenBudget}`);
413
+ if (agent.task) lines.push(`${child}task: ${yamlString(agent.task)}`);
414
+ if (agent.outcome) lines.push(`${child}outcome: ${yamlString(agent.outcome)}`);
415
+ if (agent.appliesTo) {
416
+ lines.push(`${child}appliesTo:`);
417
+ const appliesIndent = `${child} `;
418
+ for (const field of [
419
+ "framework",
420
+ "version",
421
+ "package"
422
+ ]) {
423
+ const values = normalizeStringOrList(agent.appliesTo[field]);
424
+ if (values) renderYamlStringList(lines, appliesIndent, field, values);
425
+ }
426
+ }
427
+ if (agent.prerequisites) renderYamlStringList(lines, child, "prerequisites", agent.prerequisites);
428
+ if (agent.files) renderYamlStringList(lines, child, "files", agent.files);
429
+ if (agent.commands) renderYamlObjectList(lines, child, "commands", agent.commands, [
430
+ "run",
431
+ "cwd",
432
+ "description"
433
+ ]);
434
+ if (agent.sideEffects) renderYamlStringList(lines, child, "sideEffects", agent.sideEffects);
435
+ if (agent.verification) renderYamlObjectList(lines, child, "verification", agent.verification, [
436
+ "description",
437
+ "run",
438
+ "expect"
439
+ ]);
440
+ if (agent.rollback) renderYamlStringList(lines, child, "rollback", agent.rollback);
441
+ if (agent.failureModes) renderYamlObjectList(lines, child, "failureModes", agent.failureModes, ["symptom", "resolution"]);
442
+ return lines;
443
+ }
444
+ function inlineCode(value) {
445
+ const longestRun = Math.max(0, ...[...value.matchAll(/`+/g)].map((match) => match[0].length));
446
+ const fence = "`".repeat(longestRun + 1);
447
+ const padding = value.startsWith("`") || value.endsWith("`") ? " " : "";
448
+ return `${fence}${padding}${value}${padding}${fence}`;
449
+ }
450
+ function renderTextList(lines, title, values, code = false) {
451
+ lines.push("", `### ${title}`, "");
452
+ for (const value of values) lines.push(`- ${code ? inlineCode(value) : value}`);
453
+ }
454
+ /** Render the structured contract as deterministic, compact machine-readable Markdown. */
455
+ function renderPageAgentContractMarkdown(value) {
456
+ const agent = normalizePageAgentFrontmatter(value);
457
+ if (!agent || !hasStructuredPageAgentContract(agent)) return "";
458
+ const lines = [PAGE_AGENT_CONTRACT_START_MARKER, "## Agent Contract"];
459
+ if (agent.task) lines.push("", `Task: ${agent.task}`);
460
+ if (agent.outcome) lines.push(`Outcome: ${agent.outcome}`);
461
+ if (agent.appliesTo) {
462
+ lines.push("", "### Applies To", "");
463
+ for (const [label, field] of [
464
+ ["Framework", "framework"],
465
+ ["Version", "version"],
466
+ ["Package", "package"]
467
+ ]) {
468
+ const values = normalizeStringOrList(agent.appliesTo[field]);
469
+ if (values) lines.push(`- ${label}: ${values.map(inlineCode).join(", ")}`);
470
+ }
471
+ }
472
+ if (agent.prerequisites) renderTextList(lines, "Prerequisites", agent.prerequisites);
473
+ if (agent.files) renderTextList(lines, "Files", agent.files, true);
474
+ if (agent.commands) {
475
+ lines.push("", "### Commands", "");
476
+ for (const command of agent.commands) {
477
+ if (typeof command === "string") {
478
+ lines.push(`- ${inlineCode(command)}`);
479
+ continue;
480
+ }
481
+ const details = [command.cwd ? `cwd ${inlineCode(command.cwd)}` : void 0, command.description].filter(Boolean);
482
+ lines.push(`- ${inlineCode(command.run)}${details.length ? ` — ${details.join("; ")}` : ""}`);
483
+ }
484
+ }
485
+ if (agent.sideEffects) renderTextList(lines, "Side Effects", agent.sideEffects);
486
+ if (agent.verification) {
487
+ lines.push("", "### Verification", "");
488
+ for (const step of agent.verification) {
489
+ if (typeof step === "string") {
490
+ lines.push(`- ${step}`);
491
+ continue;
492
+ }
493
+ const summary = step.description ?? (step.run ? `Run ${inlineCode(step.run)}` : step.expect ?? "Verification step");
494
+ lines.push(`- ${summary}`);
495
+ if (step.run && step.description) lines.push(` - Run: ${inlineCode(step.run)}`);
496
+ if (step.expect && step.expect !== summary) lines.push(` - Expected: ${step.expect}`);
497
+ }
498
+ }
499
+ if (agent.rollback) renderTextList(lines, "Rollback", agent.rollback);
500
+ if (agent.failureModes) {
501
+ lines.push("", "### Failure Modes", "");
502
+ for (const mode of agent.failureModes) {
503
+ if (typeof mode === "string") {
504
+ lines.push(`- ${mode}`);
505
+ continue;
506
+ }
507
+ lines.push(`- ${mode.symptom}${mode.resolution ? ` — Recovery: ${mode.resolution}` : ""}`);
508
+ }
509
+ }
510
+ lines.push(PAGE_AGENT_CONTRACT_END_MARKER);
511
+ return lines.join("\n");
512
+ }
513
+ /** Remove generated contract blocks while preserving handwritten guidance. */
514
+ function stripGeneratedPageAgentContractMarkdown(markdown) {
515
+ const newline = markdown.includes("\r\n") ? "\r\n" : "\n";
516
+ const output = [];
517
+ let fence;
518
+ let pendingBlock;
519
+ let skipEmptySeparator = false;
520
+ for (const line of markdown.split(/\r?\n/)) {
521
+ if (pendingBlock) {
522
+ pendingBlock.push(line);
523
+ if (isGeneratedAgentContractMarker(line, PAGE_AGENT_CONTRACT_END_MARKER)) {
524
+ pendingBlock = void 0;
525
+ skipEmptySeparator = true;
526
+ }
527
+ continue;
528
+ }
529
+ if (!fence && isGeneratedAgentContractMarker(line, PAGE_AGENT_CONTRACT_START_MARKER)) {
530
+ pendingBlock = [line];
531
+ continue;
532
+ }
533
+ if (skipEmptySeparator && line.length === 0) continue;
534
+ skipEmptySeparator = false;
535
+ output.push(line);
536
+ fence = advanceMarkdownFence(line, fence);
537
+ }
538
+ if (pendingBlock) output.push(...pendingBlock);
539
+ while (output[0] === "") output.shift();
540
+ return output.join(newline);
541
+ }
542
+ function isGeneratedAgentContractMarker(line, marker) {
543
+ if (line.trim() !== marker) return false;
544
+ const markerIndex = line.indexOf(marker);
545
+ return markerIndex <= 3 && /^ *$/.test(line.slice(0, markerIndex));
546
+ }
547
+ function advanceMarkdownFence(line, fence) {
548
+ if (fence) {
549
+ const closing = /^ {0,3}(`+|~+)[\t ]*$/.exec(line)?.[1];
550
+ if (closing?.[0] === fence.character && closing.length >= fence.length) return;
551
+ return fence;
552
+ }
553
+ const opening = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
554
+ if (!opening?.[1]) return void 0;
555
+ if (opening[1][0] === "`" && opening[2]?.includes("`")) return void 0;
556
+ return {
557
+ character: opening[1][0],
558
+ length: opening[1].length
559
+ };
560
+ }
561
+ function isAgentContractHeadingText(value) {
562
+ return value.trim().toLowerCase() === "agent contract";
563
+ }
564
+ function hasPageAgentContractHeading(markdown) {
565
+ let fence;
566
+ let previousLine;
567
+ for (const line of markdown.split(/\r?\n/)) {
568
+ const nextFence = advanceMarkdownFence(line, fence);
569
+ if (fence || nextFence) {
570
+ fence = nextFence;
571
+ previousLine = void 0;
572
+ continue;
573
+ }
574
+ const atxText = /^ {0,3}#{1,6}(?:[\t ]+|$)(.*)$/.exec(line)?.[1]?.replace(/[\t ]+#+[\t ]*$/, "").trim();
575
+ if (atxText && isAgentContractHeadingText(atxText)) return true;
576
+ if (previousLine && /^ {0,3}(?:=+|-+)[\t ]*$/.test(line) && isAgentContractHeadingText(previousLine)) return true;
577
+ previousLine = line.trim().length > 0 && !/^ {4}/.test(line) && !/^ {0,3}\t/.test(line) ? line : void 0;
578
+ }
579
+ return false;
580
+ }
581
+ /** Insert one generated contract unless the document already has handwritten contract guidance. */
582
+ function upsertPageAgentContractMarkdown(markdown, value) {
583
+ const cleaned = stripGeneratedPageAgentContractMarkdown(markdown);
584
+ const contract = renderPageAgentContractMarkdown(value);
585
+ if (!contract || hasPageAgentContractHeading(cleaned)) return cleaned;
586
+ return cleaned ? `${contract}\n\n${cleaned.replace(/^\r?\n+/, "")}` : contract;
587
+ }
2
588
 
589
+ //#endregion
3
590
  //#region src/related.ts
4
591
  function normalizeDocsRelated(value) {
5
592
  if (!Array.isArray(value)) return [];
@@ -2196,23 +2783,7 @@ function buildDocsAgentDiscoverySpec({ origin, entry = "docs", i18n = null, sear
2196
2783
  mcpField: "agent",
2197
2784
  ...agentContractMcpTools ? { mcpTools: agentContractMcpTools } : {},
2198
2785
  usefulContractFields: ["task", "outcome"],
2199
- fields: {
2200
- tokenBudget: "number",
2201
- task: "string",
2202
- outcome: "string",
2203
- appliesTo: {
2204
- framework: "string|string[]",
2205
- version: "string|string[]",
2206
- package: "string|string[]"
2207
- },
2208
- prerequisites: "string[]",
2209
- files: "string[]",
2210
- commands: "Array<string|{run,cwd?,description?}>",
2211
- sideEffects: "string[]",
2212
- verification: "Array<string|{description?,run?,expect?}>",
2213
- rollback: "string[]",
2214
- failureModes: "Array<string|{symptom,resolution?}>"
2215
- }
2786
+ fields: PAGE_AGENT_CONTRACT_FIELD_SCHEMA
2216
2787
  },
2217
2788
  llms: {
2218
2789
  enabled: llmsEnabled,
@@ -2419,4 +2990,4 @@ function toYamlString(value) {
2419
2990
  }
2420
2991
 
2421
2992
  //#endregion
2422
- export { normalizeDocsUrlPath as $, acceptsDocsMarkdown as A, renderDocsSitemapMarkdown as At, getDocsMarkdownCanonicalLinkHeader as B, DEFAULT_OPENAPI_SCHEMA_ROUTE as C, DEFAULT_SITEMAP_MD_DOCS_ROUTE as Ct, DOCS_BOT_LIKE_USER_AGENT_HEADER_PATTERN as D, buildDocsSitemapManifest as Dt, DOCS_AI_AGENT_USER_AGENT_HEADER_PATTERN as E, DEFAULT_SITEMAP_XML_ROUTE as Et, buildDocsMcpEndpointCandidates as F, toDocsSitemapMarkdownUrl as Ft, isDocsConfigRequest as G, hasDocsMarkdownSignatureAgent as H, createDocsMarkdownResponse as I, normalizeDocsRelated as It, isDocsMcpRequest as J, isDocsDiagnosticsRequest as K, detectDocsMarkdownAgentRequest as L, renderDocsRelatedMarkdownLines as Lt, buildDocsAgentFeedbackSchema as M, resolveDocsSitemapConfig as Mt, buildDocsConfigMap as N, resolveDocsSitemapPageLastmod as Nt, DOCS_MARKDOWN_SIGNATURE_AGENT_HEADER as O, createDocsSitemapResponse as Ot, buildDocsDiagnostics as P, resolveDocsSitemapRequest as Pt, normalizeDocsPathSegment as Q, findDocsMarkdownPage as R, DEFAULT_MCP_WELL_KNOWN_ROUTE as S, DEFAULT_SITEMAP_MANIFEST_PATH as St, DEFAULT_SKILL_MD_WELL_KNOWN_ROUTE as T, DEFAULT_SITEMAP_MD_WELL_KNOWN_ROUTE as Tt, isDocsAgentDiscoveryRequest as U, getDocsMarkdownVaryHeader as V, isDocsAgentsRequest as W, isDocsSkillRequest as X, isDocsPublicGetRequest as Y, matchesDocsLlmsTxtSection as Z, DEFAULT_LLMS_TXT_MAX_CHARS as _, resolveDocsOpenApiDiscoveryConfig as _t, DEFAULT_AGENT_MD_ROUTE as a, renderDocsSkillDocument as at, DEFAULT_MCP_PUBLIC_ROUTE as b, toDocsMarkdownUrl as bt, DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE as c, resolveDocsAgentFeedbackRequest as ct, DEFAULT_DOCS_CONFIG_FORMAT as d, resolveDocsLlmsTxtFormat as dt, parseDocsAgentFeedbackData as et, DEFAULT_DOCS_CONFIG_ROUTE as f, resolveDocsLlmsTxtRequest as ft, DEFAULT_LLMS_FULL_TXT_WELL_KNOWN_ROUTE as g, resolveDocsMarkdownRequest as gt, DEFAULT_LLMS_FULL_TXT_ROUTE as h, resolveDocsMarkdownRecovery as ht, DEFAULT_AGENT_FEEDBACK_ROUTE as i, renderDocsMarkdownNotFound as it, buildDocsAgentDiscoverySpec as j, renderDocsSitemapXml as jt, DOCS_TRADITIONAL_BOT_USER_AGENT_HEADER_PATTERN as k, readDocsSitemapManifestFromContentMap as kt, DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE as l, resolveDocsAgentMdxContent as lt, DEFAULT_DOCS_DIAGNOSTICS_ROUTE as m, resolveDocsMarkdownCanonicalUrl as mt, DEFAULT_AGENTS_MD_WELL_KNOWN_ROUTE as n, renderDocsLlmsTxt as nt, DEFAULT_AGENT_MD_WELL_KNOWN_ROUTE as o, resolveDocsAgentContractMcpTools as ot, DEFAULT_DOCS_DIAGNOSTICS_FORMAT as p, resolveDocsLlmsTxtSections as pt, isDocsLlmsTxtPublicRequest as q, DEFAULT_AGENT_FEEDBACK_PAYLOAD_SCHEMA as r, renderDocsMarkdownDocument as rt, DEFAULT_AGENT_SPEC_ROUTE as s, resolveDocsAgentFeedbackConfig as st, DEFAULT_AGENTS_MD_ROUTE as t, renderDocsAgentsDocument as tt, DEFAULT_DOCS_API_ROUTE as u, resolveDocsAgentsFormat as ut, DEFAULT_LLMS_TXT_ROUTE as v, resolveDocsSkillFormat as vt, DEFAULT_SKILL_MD_ROUTE as w, DEFAULT_SITEMAP_MD_ROUTE as wt, DEFAULT_MCP_ROUTE as x, validateDocsAgentFeedbackPayload as xt, DEFAULT_LLMS_TXT_WELL_KNOWN_ROUTE as y, selectDocsLlmsTxtContent as yt, getDocsLlmsTxtMaxCharsIssue as z };
2993
+ export { normalizeDocsPathSegment as $, DOCS_TRADITIONAL_BOT_USER_AGENT_HEADER_PATTERN as A, readDocsSitemapManifestFromContentMap as At, getDocsLlmsTxtMaxCharsIssue as B, PAGE_AGENT_CONTRACT_FIELDS as Bt, DEFAULT_OPENAPI_SCHEMA_ROUTE as C, DEFAULT_SITEMAP_MANIFEST_PATH as Ct, DOCS_BOT_LIKE_USER_AGENT_HEADER_PATTERN as D, DEFAULT_SITEMAP_XML_ROUTE as Dt, DOCS_AI_AGENT_USER_AGENT_HEADER_PATTERN as E, DEFAULT_SITEMAP_MD_WELL_KNOWN_ROUTE as Et, buildDocsDiagnostics as F, resolveDocsSitemapRequest as Ft, isDocsAgentsRequest as G, hasStructuredPageAgentContract as Gt, getDocsMarkdownVaryHeader as H, PAGE_AGENT_CONTRACT_START_MARKER as Ht, buildDocsMcpEndpointCandidates as I, toDocsSitemapMarkdownUrl as It, isDocsLlmsTxtPublicRequest as J, renderPageAgentFrontmatterYamlLines as Jt, isDocsConfigRequest as K, normalizePageAgentFrontmatter as Kt, createDocsMarkdownResponse as L, normalizeDocsRelated as Lt, buildDocsAgentDiscoverySpec as M, renderDocsSitemapXml as Mt, buildDocsAgentFeedbackSchema as N, resolveDocsSitemapConfig as Nt, DOCS_CONFIG_MAP_TOP_LEVEL_KEYS as O, buildDocsSitemapManifest as Ot, buildDocsConfigMap as P, resolveDocsSitemapPageLastmod as Pt, matchesDocsLlmsTxtSection as Q, detectDocsMarkdownAgentRequest as R, renderDocsRelatedMarkdownLines as Rt, DEFAULT_MCP_WELL_KNOWN_ROUTE as S, validateDocsAgentFeedbackPayload as St, DEFAULT_SKILL_MD_WELL_KNOWN_ROUTE as T, DEFAULT_SITEMAP_MD_ROUTE as Tt, hasDocsMarkdownSignatureAgent as U, PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS as Ut, getDocsMarkdownCanonicalLinkHeader as V, PAGE_AGENT_CONTRACT_FIELD_SCHEMA as Vt, isDocsAgentDiscoveryRequest as W, getPageAgentFrontmatterIssues as Wt, isDocsPublicGetRequest as X, upsertPageAgentContractMarkdown as Xt, isDocsMcpRequest as Y, stripGeneratedPageAgentContractMarkdown as Yt, isDocsSkillRequest as Z, DEFAULT_LLMS_TXT_MAX_CHARS as _, resolveDocsMarkdownRequest as _t, DEFAULT_AGENT_MD_ROUTE as a, renderDocsMarkdownNotFound as at, DEFAULT_MCP_PUBLIC_ROUTE as b, selectDocsLlmsTxtContent as bt, DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE as c, resolveDocsAgentFeedbackConfig as ct, DEFAULT_DOCS_CONFIG_FORMAT as d, resolveDocsAgentsFormat as dt, normalizeDocsUrlPath 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, renderDocsMarkdownDocument as it, acceptsDocsMarkdown as j, renderDocsSitemapMarkdown as jt, DOCS_MARKDOWN_SIGNATURE_AGENT_HEADER as k, createDocsSitemapResponse as kt, DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE as l, resolveDocsAgentFeedbackRequest as lt, DEFAULT_DOCS_DIAGNOSTICS_ROUTE as m, resolveDocsLlmsTxtSections as mt, DEFAULT_AGENTS_MD_WELL_KNOWN_ROUTE as n, renderDocsAgentsDocument as nt, DEFAULT_AGENT_MD_WELL_KNOWN_ROUTE as o, renderDocsSkillDocument as ot, DEFAULT_DOCS_DIAGNOSTICS_FORMAT as p, resolveDocsLlmsTxtRequest as pt, isDocsDiagnosticsRequest as q, renderPageAgentContractMarkdown as qt, DEFAULT_AGENT_FEEDBACK_PAYLOAD_SCHEMA as r, renderDocsLlmsTxt as rt, DEFAULT_AGENT_SPEC_ROUTE as s, resolveDocsAgentContractMcpTools as st, DEFAULT_AGENTS_MD_ROUTE as t, parseDocsAgentFeedbackData as tt, DEFAULT_DOCS_API_ROUTE as u, resolveDocsAgentMdxContent as ut, DEFAULT_LLMS_TXT_ROUTE as v, resolveDocsOpenApiDiscoveryConfig as vt, DEFAULT_SKILL_MD_ROUTE as w, DEFAULT_SITEMAP_MD_DOCS_ROUTE as wt, DEFAULT_MCP_ROUTE as x, toDocsMarkdownUrl as xt, DEFAULT_LLMS_TXT_WELL_KNOWN_ROUTE as y, resolveDocsSkillFormat as yt, findDocsMarkdownPage as z, PAGE_AGENT_CONTRACT_END_MARKER as zt };