@farming-labs/docs 0.2.120 → 0.2.121

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 (188) hide show
  1. package/README.md +8 -0
  2. package/dist/access.d.mts +13 -0
  3. package/dist/access.mjs +56 -0
  4. package/dist/agent-conformance.d.mts +60 -0
  5. package/dist/agent-conformance.mjs +538 -0
  6. package/dist/agent-contract.d.mts +47 -0
  7. package/dist/agent-contract.mjs +645 -0
  8. package/dist/agent-detection.d.mts +6 -0
  9. package/dist/agent-detection.mjs +83 -0
  10. package/dist/agent-evals.d.mts +224 -0
  11. package/dist/{agent-evals-BLNLvXbG.mjs → agent-evals.mjs} +7 -565
  12. package/dist/agent-feedback-evaluations-node.mjs +38 -0
  13. package/dist/agent-feedback-evaluations.d.mts +91 -0
  14. package/dist/{agent-feedback-evaluations-CcMGlgsO.mjs → agent-feedback-evaluations.mjs} +2 -2
  15. package/dist/agent-feedback-loop.d.mts +45 -0
  16. package/dist/{agent-feedback-loop-CcZL_sb1.mjs → agent-feedback-loop.mjs} +1 -1
  17. package/dist/agent-maintenance.d.mts +71 -0
  18. package/dist/{agent-maintenance-CuZ7iAKq.mjs → agent-maintenance.mjs} +1 -1
  19. package/dist/agent-provenance.d.mts +23 -0
  20. package/dist/agent-provenance.mjs +77 -0
  21. package/dist/agent-scope.mjs +321 -0
  22. package/dist/agent-skills-archive.mjs +86 -0
  23. package/dist/agent-skills-bundle.d.mts +1 -1
  24. package/dist/{agent-skills-progressive-disclosure-PjPtTYL-.mjs → agent-skills-progressive-disclosure.mjs} +2 -2
  25. package/dist/{agent-skills-server-D5IuvwM7.d.mts → agent-skills-server.d.mts} +3 -3
  26. package/dist/{agent-skills-server-BC7md56k.mjs → agent-skills-server.mjs} +2 -2
  27. package/dist/agent-skills-vite.d.mts +3 -3
  28. package/dist/agent-skills-vite.mjs +1 -2
  29. package/dist/agent-surface-drift.mjs +236 -0
  30. package/dist/{golden-evaluations-CLUViycJ.mjs → agent-usefulness.mjs} +5 -290
  31. package/dist/{content-change-hydration-wqXIZHp6.d.mts → agent.d.mts} +10 -411
  32. package/dist/agent.mjs +2729 -0
  33. package/dist/{analytics-w3FDOksr.d.mts → analytics.d.mts} +2 -2
  34. package/dist/{analytics-p8Vhhu2P.mjs → analytics.mjs} +2 -2
  35. package/dist/{sitemap-server-BUdPBcGs.d.mts → api-reference.d.mts} +2 -6
  36. package/dist/api-reference.mjs +1481 -0
  37. package/dist/{audience-exposure-DBrFWULA.d.mts → audience-exposure.d.mts} +1 -1
  38. package/dist/audience-exposure.mjs +8 -0
  39. package/dist/audience.d.mts +44 -0
  40. package/dist/audience.mjs +1654 -0
  41. package/dist/authoring-mcp.d.mts +44 -0
  42. package/dist/{authoring-mcp-CiCUQe3o.mjs → authoring-mcp.mjs} +3 -3
  43. package/dist/browser.d.mts +6 -4
  44. package/dist/browser.mjs +6 -7
  45. package/dist/build.d.mts +8 -0
  46. package/dist/build.mjs +8 -0
  47. package/dist/changelog.d.mts +20 -0
  48. package/dist/changelog.mjs +39 -0
  49. package/dist/{agent-export-CA6IUQ7T.mjs → cli/agent-export.mjs} +19 -45
  50. package/dist/{agent-CYk2DxY7.mjs → cli/agent.mjs} +6 -35
  51. package/dist/{agents-BUiVmj8i.mjs → cli/agents.mjs} +5 -18
  52. package/dist/cli/api-doctor.mjs +206 -0
  53. package/dist/{authoring-C2ymvYWl.mjs → cli/authoring.mjs} +2 -8
  54. package/dist/{cloud-6eKrlmKd.mjs → cli/cloud.mjs} +3 -3
  55. package/dist/{codeblocks-CHpgAwY-.mjs → cli/codeblocks.mjs} +2 -2
  56. package/dist/cli/config.d.mts +11 -0
  57. package/dist/{config-BZnKAj_Y.mjs → cli/config.mjs} +1 -1
  58. package/dist/cli/dev-banner.mjs +58 -0
  59. package/dist/{dev-Bnn-NUNa.mjs → cli/dev.mjs} +3 -57
  60. package/dist/{doctor-Bfkrkzad.mjs → cli/doctor.mjs} +41 -226
  61. package/dist/{downgrade-CHMta85e.mjs → cli/downgrade.mjs} +2 -2
  62. package/dist/cli/errors.d.mts +4 -0
  63. package/dist/{errors-BtnVLhNF.mjs → cli/errors.mjs} +1 -1
  64. package/dist/{feedback-evals-DMilg9pY.mjs → cli/feedback-evals.mjs} +3 -36
  65. package/dist/{feedback-DL4T5oIO.mjs → cli/feedback.mjs} +1 -1
  66. package/dist/cli/git-dates.mjs +35 -0
  67. package/dist/cli/golden-evaluations.mjs +52 -0
  68. package/dist/cli/index.d.mts +2 -3
  69. package/dist/cli/index.mjs +38 -38
  70. package/dist/{init-K0LmXDZ5.mjs → cli/init.mjs} +3 -3
  71. package/dist/{mcp-iLCmnPJI.mjs → cli/mcp.mjs} +7 -19
  72. package/dist/{openapi-diff-HcpUNjA-.mjs → cli/openapi-diff.mjs} +2 -7
  73. package/dist/{openapi-sdk-BQKC6H-_.mjs → cli/openapi-sdk.mjs} +2 -7
  74. package/dist/{openapi-source-DK6ts_Bk.mjs → cli/openapi-source.mjs} +2 -2
  75. package/dist/{package-version-HJhYeq4M.mjs → cli/package-version.mjs} +2 -2
  76. package/dist/{propose-JmUv_BTt.mjs → cli/propose.mjs} +1 -1
  77. package/dist/{review-C6EmbV0l.mjs → cli/review.mjs} +16 -15
  78. package/dist/{robots-DteZB8vl.mjs → cli/robots.mjs} +3 -7
  79. package/dist/{search-Bhuv_YsL.mjs → cli/search.mjs} +7 -20
  80. package/dist/{sitemap-DW5LDKDa.mjs → cli/sitemap.mjs} +7 -42
  81. package/dist/{skills-BAPQLSCm.mjs → cli/skills.mjs} +5 -19
  82. package/dist/{templates-BuQ8YsGv.mjs → cli/templates.mjs} +1 -1
  83. package/dist/{upgrade-DlQMOFV1.mjs → cli/upgrade.mjs} +2 -2
  84. package/dist/{utils-C7KDrPpA.mjs → cli/utils.mjs} +1 -1
  85. package/dist/client/react.d.mts +2 -18
  86. package/dist/client/react.mjs +1 -157
  87. package/dist/{cloud-analytics-D14HplI7.mjs → cloud-analytics.mjs} +1 -1
  88. package/dist/{cloud-ask-ai-BrsTXQf6.d.mts → cloud-ask-ai.d.mts} +2 -2
  89. package/dist/{cloud-ask-ai-BqKhjpS5.mjs → cloud-ask-ai.mjs} +3 -3
  90. package/dist/code-blocks.d.mts +51 -0
  91. package/dist/{code-blocks-GYdvS3BH.mjs → code-blocks.mjs} +2 -2
  92. package/dist/code-group-mdx.d.mts +11 -0
  93. package/dist/code-group-mdx.mjs +57 -0
  94. package/dist/content-change-hydration.d.mts +87 -0
  95. package/dist/{openapi-mcp-BIOTLiA7.mjs → content-change-hydration.mjs} +5 -210
  96. package/dist/content-changes.d.mts +47 -0
  97. package/dist/content-changes.mjs +216 -0
  98. package/dist/create-theme.d.mts +48 -0
  99. package/dist/create-theme.mjs +57 -0
  100. package/dist/date.d.mts +5 -0
  101. package/dist/date.mjs +17 -0
  102. package/dist/define-docs.d.mts +9 -0
  103. package/dist/define-docs.mjs +46 -0
  104. package/dist/docs-cloud-client.d.mts +18 -0
  105. package/dist/docs-cloud-client.mjs +161 -0
  106. package/dist/docs-cloud-server.d.mts +2 -2
  107. package/dist/docs-cloud-server.mjs +2 -3
  108. package/dist/heading-toc.d.mts +10 -0
  109. package/dist/heading-toc.mjs +23 -0
  110. package/dist/http-body.d.mts +14 -0
  111. package/dist/{http-body-DkAPk6D5.mjs → http-body.mjs} +1 -1
  112. package/dist/http-cache.d.mts +25 -0
  113. package/dist/http-cache.mjs +140 -0
  114. package/dist/http-link.mjs +81 -0
  115. package/dist/i18n.d.mts +18 -0
  116. package/dist/{i18n-B1gJ9EW0.mjs → i18n.mjs} +1 -1
  117. package/dist/index.d.mts +42 -674
  118. package/dist/index.mjs +40 -14
  119. package/dist/markdown-rendering.mjs +1 -1
  120. package/dist/markdown-section-cache.mjs +49 -0
  121. package/dist/markdown-sections.d.mts +47 -0
  122. package/dist/{markdown-sections-9Oxr33b-.mjs → markdown-sections.mjs} +29 -703
  123. package/dist/mcp-auth.d.mts +14 -0
  124. package/dist/mcp-auth.mjs +99 -0
  125. package/dist/mcp.d.mts +5 -3
  126. package/dist/mcp.mjs +21 -9
  127. package/dist/mdx.d.mts +6 -0
  128. package/dist/mdx.mjs +7 -0
  129. package/dist/metadata.d.mts +60 -0
  130. package/dist/{metadata-BOHn0Y5K.mjs → metadata.mjs} +2 -2
  131. package/dist/native-api-reference.mjs +968 -0
  132. package/dist/okf.d.mts +42 -0
  133. package/dist/okf.mjs +145 -0
  134. package/dist/openapi-contract.mjs +154 -0
  135. package/dist/{openapi-mcp-node-C4jUpZG6.mjs → openapi-mcp-node.mjs} +1 -1
  136. package/dist/openapi-mcp.d.mts +26 -0
  137. package/dist/openapi-mcp.mjs +132 -0
  138. package/dist/openapi-operations.d.mts +71 -0
  139. package/dist/{openapi-operations-DFpaqOqA.mjs → openapi-operations.mjs} +1 -1
  140. package/dist/openapi-overlays.mjs +221 -0
  141. package/dist/openapi-references.mjs +233 -0
  142. package/dist/pagination.d.mts +7 -0
  143. package/dist/pagination.mjs +100 -0
  144. package/dist/prompt-references.d.mts +12 -0
  145. package/dist/prompt-references.mjs +132 -0
  146. package/dist/prompt-utils.d.mts +36 -0
  147. package/dist/{prompt-utils-B5g-bv7o.mjs → prompt-utils.mjs} +1 -57
  148. package/dist/reading-time.d.mts +23 -0
  149. package/dist/reading-time.mjs +58 -0
  150. package/dist/related.d.mts +7 -0
  151. package/dist/related.mjs +50 -0
  152. package/dist/retrieval-digest.d.mts +16 -0
  153. package/dist/{retrieval-digest-CT-eIEcp.mjs → retrieval-digest.mjs} +1 -1
  154. package/dist/review.d.mts +69 -0
  155. package/dist/review.mjs +562 -0
  156. package/dist/robots.d.mts +54 -0
  157. package/dist/{robots-BYJAVeI6.mjs → robots.mjs} +5 -3
  158. package/dist/runtime.d.mts +3 -3
  159. package/dist/runtime.mjs +3 -9
  160. package/dist/search.d.mts +210 -0
  161. package/dist/search.mjs +3401 -0
  162. package/dist/server.d.mts +22 -198
  163. package/dist/server.mjs +21 -19
  164. package/dist/sidebar.d.mts +15 -0
  165. package/dist/sidebar.mjs +73 -0
  166. package/dist/sitemap-server.d.mts +7 -0
  167. package/dist/{sitemap-server-Lg3YhUx4.mjs → sitemap-server.mjs} +2 -2
  168. package/dist/{sitemap-Cl8vrixd.d.mts → sitemap.d.mts} +3 -3
  169. package/dist/sitemap.mjs +254 -0
  170. package/dist/{standards-discovery-BHPc7YIX.d.mts → standards-discovery.d.mts} +2 -2
  171. package/dist/{standards-discovery-sSEojU80.mjs → standards-discovery.mjs} +3 -139
  172. package/dist/telemetry-runtime.d.mts +42 -0
  173. package/dist/telemetry-runtime.mjs +238 -0
  174. package/dist/telemetry.d.mts +15 -0
  175. package/dist/telemetry.mjs +117 -0
  176. package/dist/{types-BJFeMXWZ.d.mts → types.d.mts} +3 -2
  177. package/dist/urls.d.mts +7 -0
  178. package/dist/urls.mjs +21 -0
  179. package/dist/utils.d.mts +8 -0
  180. package/dist/utils.mjs +22 -0
  181. package/package.json +21 -3
  182. package/dist/agent-DkAidqtV.mjs +0 -9026
  183. package/dist/api-reference-BYee4zMo.mjs +0 -3046
  184. package/dist/prompt-references-DMgbu_dz.mjs +0 -1082
  185. package/dist/retrieval-digest-AOx2-LbC.d.mts +0 -367
  186. package/dist/sidebar-CFHBj29f.mjs +0 -421
  187. package/dist/sidebar-CMPbVfGP.d.mts +0 -63
  188. /package/dist/{openapi-CfCzX_a1.mjs → cli/openapi.mjs} +0 -0
package/dist/okf.d.mts ADDED
@@ -0,0 +1,42 @@
1
+ import { DocsOkfActorTimestamp, DocsOkfConfig, DocsOkfTrustMetadata, DocsOkfTrustMetadataInput } from "./types.mjs";
2
+
3
+ //#region src/okf.d.ts
4
+ declare const DOCS_OKF_VERSION = "0.2";
5
+ declare const DOCS_OKF_BUNDLE_FORMAT = "open-knowledge-format.v0.2";
6
+ declare const DEFAULT_DOCS_OKF_ROUTE = "/.well-known/okf.json";
7
+ interface DocsOkfPageLike {
8
+ url: string;
9
+ title: string;
10
+ canonicalUrl?: string;
11
+ sourcePath?: string;
12
+ lastModified?: string;
13
+ lastmod?: string;
14
+ okf?: DocsOkfTrustMetadataInput;
15
+ }
16
+ interface DocsOkfResolvedConfig extends DocsOkfTrustMetadataInput {
17
+ enabled: boolean;
18
+ route: string;
19
+ generatedBy: string;
20
+ staleAfterDays?: number;
21
+ }
22
+ interface DocsOkfKnowledgeDocument {
23
+ id: string;
24
+ url: string;
25
+ title: string;
26
+ content?: string;
27
+ trust: DocsOkfTrustMetadata;
28
+ }
29
+ interface DocsOkfBundle {
30
+ format: typeof DOCS_OKF_BUNDLE_FORMAT;
31
+ spec_version: typeof DOCS_OKF_VERSION;
32
+ generated: DocsOkfActorTimestamp;
33
+ documents: DocsOkfKnowledgeDocument[];
34
+ }
35
+ declare function normalizeDocsOkfTrustMetadataInput(value: unknown): DocsOkfTrustMetadataInput | undefined;
36
+ declare function resolveDocsOkfConfig(value?: boolean | DocsOkfConfig): DocsOkfResolvedConfig;
37
+ declare function resolveDocsOkfTrustMetadata(page: DocsOkfPageLike, value?: boolean | DocsOkfConfig, now?: Date): DocsOkfTrustMetadata;
38
+ declare function buildDocsOkfBundle(pages: readonly (DocsOkfPageLike & {
39
+ content?: string;
40
+ })[], value?: boolean | DocsOkfConfig): DocsOkfBundle;
41
+ //#endregion
42
+ export { DEFAULT_DOCS_OKF_ROUTE, DOCS_OKF_BUNDLE_FORMAT, DOCS_OKF_VERSION, DocsOkfBundle, DocsOkfKnowledgeDocument, DocsOkfPageLike, DocsOkfResolvedConfig, buildDocsOkfBundle, normalizeDocsOkfTrustMetadataInput, resolveDocsOkfConfig, resolveDocsOkfTrustMetadata };
package/dist/okf.mjs ADDED
@@ -0,0 +1,145 @@
1
+ //#region src/okf.ts
2
+ const DOCS_OKF_VERSION = "0.2";
3
+ const DOCS_OKF_BUNDLE_FORMAT = "open-knowledge-format.v0.2";
4
+ const DEFAULT_DOCS_OKF_ROUTE = "/.well-known/okf.json";
5
+ function cleanString(value) {
6
+ if (typeof value !== "string") return void 0;
7
+ return value.trim() || void 0;
8
+ }
9
+ function normalizeDate(value) {
10
+ if (value instanceof Date && Number.isFinite(value.getTime())) return value.toISOString();
11
+ const stringValue = cleanString(value);
12
+ if (!stringValue) return void 0;
13
+ const parsed = new Date(stringValue);
14
+ return Number.isFinite(parsed.getTime()) ? parsed.toISOString() : void 0;
15
+ }
16
+ function normalizeDateOnly(value) {
17
+ return normalizeDate(value)?.slice(0, 10);
18
+ }
19
+ function normalizeStatus(value) {
20
+ return value === "draft" || value === "stable" || value === "deprecated" ? value : void 0;
21
+ }
22
+ function normalizeActorTimestamp(value) {
23
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
24
+ const record = value;
25
+ const by = cleanString(record.by);
26
+ const at = normalizeDate(record.at);
27
+ return by && at ? {
28
+ by,
29
+ at
30
+ } : void 0;
31
+ }
32
+ function normalizeSource(value) {
33
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
34
+ const record = value;
35
+ const resource = cleanString(record.resource);
36
+ if (!resource) return void 0;
37
+ const usageCount = typeof record.usage_count === "number" && Number.isInteger(record.usage_count) ? Math.max(0, record.usage_count) : void 0;
38
+ const usageWindowRecord = record.usage_window && typeof record.usage_window === "object" && !Array.isArray(record.usage_window) ? record.usage_window : void 0;
39
+ const usageWindow = usageWindowRecord ? {
40
+ ...normalizeDate(usageWindowRecord.start) ? { start: normalizeDate(usageWindowRecord.start) } : {},
41
+ ...normalizeDate(usageWindowRecord.end) ? { end: normalizeDate(usageWindowRecord.end) } : {}
42
+ } : void 0;
43
+ return {
44
+ resource,
45
+ ...cleanString(record.id) ? { id: cleanString(record.id) } : {},
46
+ ...cleanString(record.title) ? { title: cleanString(record.title) } : {},
47
+ ...cleanString(record.author) ? { author: cleanString(record.author) } : {},
48
+ ...usageCount !== void 0 ? { usage_count: usageCount } : {},
49
+ ...normalizeDate(record.last_modified) ? { last_modified: normalizeDate(record.last_modified) } : {},
50
+ ...usageWindow && Object.keys(usageWindow).length > 0 ? { usage_window: usageWindow } : {}
51
+ };
52
+ }
53
+ function normalizeDocsOkfTrustMetadataInput(value) {
54
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
55
+ const record = value;
56
+ const sources = Array.isArray(record.sources) ? record.sources.flatMap((source) => {
57
+ const normalized = normalizeSource(source);
58
+ return normalized ? [normalized] : [];
59
+ }) : void 0;
60
+ const verified = Array.isArray(record.verified) ? record.verified.flatMap((entry) => {
61
+ const normalized = normalizeActorTimestamp(entry);
62
+ return normalized ? [normalized] : [];
63
+ }) : void 0;
64
+ const generated = normalizeActorTimestamp(record.generated);
65
+ const status = normalizeStatus(record.status);
66
+ const staleAfter = normalizeDateOnly(record.stale_after);
67
+ const result = {
68
+ ...sources && sources.length > 0 ? { sources } : {},
69
+ ...generated ? { generated } : {},
70
+ ...verified && verified.length > 0 ? { verified } : {},
71
+ ...status ? { status } : {},
72
+ ...staleAfter ? { stale_after: staleAfter } : {}
73
+ };
74
+ return Object.keys(result).length > 0 ? result : void 0;
75
+ }
76
+ function resolveDocsOkfConfig(value) {
77
+ const config = value && typeof value === "object" ? value : {};
78
+ return {
79
+ enabled: value === true || typeof value === "object" && value !== null && value.enabled !== false,
80
+ route: cleanString(config.route) ?? DEFAULT_DOCS_OKF_ROUTE,
81
+ generatedBy: cleanString(config.generatedBy) ?? "software:@farming-labs/docs",
82
+ ...Number.isInteger(config.staleAfterDays) && (config.staleAfterDays ?? 0) > 0 ? { staleAfterDays: config.staleAfterDays } : {},
83
+ ...normalizeDocsOkfTrustMetadataInput(config)
84
+ };
85
+ }
86
+ function addDays(value, days) {
87
+ const parsed = new Date(value);
88
+ if (!Number.isFinite(parsed.getTime())) return void 0;
89
+ parsed.setUTCDate(parsed.getUTCDate() + days);
90
+ return parsed.toISOString().slice(0, 10);
91
+ }
92
+ function trustTier(verified) {
93
+ if (verified.some((entry) => entry.by.toLowerCase().startsWith("human:"))) return "human-reviewed";
94
+ return verified.length > 0 ? "machine-confirmed" : "unverified";
95
+ }
96
+ function resolveDocsOkfTrustMetadata(page, value, now = /* @__PURE__ */ new Date()) {
97
+ const config = resolveDocsOkfConfig(value);
98
+ const authored = normalizeDocsOkfTrustMetadataInput(page.okf) ?? {};
99
+ const bestTimestamp = normalizeDate(page.lastmod) ?? normalizeDate(page.lastModified);
100
+ const generated = authored.generated ?? config.generated ?? {
101
+ by: config.generatedBy,
102
+ at: bestTimestamp ?? "1970-01-01T00:00:00.000Z"
103
+ };
104
+ const sources = [...authored.sources ?? config.sources ?? []];
105
+ if (sources.length === 0) sources.push({
106
+ resource: page.canonicalUrl ?? page.url,
107
+ ...page.sourcePath ? { id: page.sourcePath } : {},
108
+ title: page.title,
109
+ ...bestTimestamp ? { last_modified: bestTimestamp } : {}
110
+ });
111
+ const verified = [...authored.verified ?? config.verified ?? []];
112
+ const staleAfter = authored.stale_after ?? config.stale_after ?? (config.staleAfterDays && bestTimestamp ? addDays(bestTimestamp, config.staleAfterDays) : void 0);
113
+ return {
114
+ sources,
115
+ generated,
116
+ verified,
117
+ status: authored.status ?? config.status ?? "stable",
118
+ ...staleAfter ? { stale_after: staleAfter } : {},
119
+ trust_tier: trustTier(verified),
120
+ stale: staleAfter ? now.getTime() > (/* @__PURE__ */ new Date(`${staleAfter}T23:59:59.999Z`)).getTime() : false
121
+ };
122
+ }
123
+ function buildDocsOkfBundle(pages, value) {
124
+ const config = resolveDocsOkfConfig(value);
125
+ const documents = pages.map((page) => ({
126
+ id: page.sourcePath ?? page.url,
127
+ url: page.canonicalUrl ?? page.url,
128
+ title: page.title,
129
+ ...page.content ? { content: page.content } : {},
130
+ trust: resolveDocsOkfTrustMetadata(page, config)
131
+ })).sort((left, right) => left.url.localeCompare(right.url));
132
+ const generatedAt = documents.reduce((latest, document) => document.trust.generated.at > latest ? document.trust.generated.at : latest, "1970-01-01T00:00:00.000Z");
133
+ return {
134
+ format: DOCS_OKF_BUNDLE_FORMAT,
135
+ spec_version: DOCS_OKF_VERSION,
136
+ generated: {
137
+ by: config.generatedBy,
138
+ at: generatedAt
139
+ },
140
+ documents
141
+ };
142
+ }
143
+
144
+ //#endregion
145
+ export { DEFAULT_DOCS_OKF_ROUTE, DOCS_OKF_BUNDLE_FORMAT, DOCS_OKF_VERSION, buildDocsOkfBundle, normalizeDocsOkfTrustMetadataInput, resolveDocsOkfConfig, resolveDocsOkfTrustMetadata };
@@ -0,0 +1,154 @@
1
+ //#region src/openapi-contract.ts
2
+ const OPENAPI_HTTP_METHODS = [
3
+ "get",
4
+ "put",
5
+ "post",
6
+ "delete",
7
+ "options",
8
+ "head",
9
+ "patch",
10
+ "trace"
11
+ ];
12
+ var OpenApiContractValidationError = class extends Error {
13
+ diagnostics;
14
+ constructor(result) {
15
+ const first = result.diagnostics[0];
16
+ const remaining = result.diagnostics.length - 1;
17
+ super(first ? `OpenAPI contract validation failed at ${first.path}: ${first.message}${remaining > 0 ? ` (${remaining} more ${remaining === 1 ? "error" : "errors"})` : ""}` : "OpenAPI contract validation failed.");
18
+ this.name = "OpenApiContractValidationError";
19
+ this.diagnostics = result.diagnostics;
20
+ }
21
+ };
22
+ function validateOpenApiContract(document) {
23
+ const state = {
24
+ diagnostics: [],
25
+ operationIds: /* @__PURE__ */ new Map(),
26
+ operationCount: 0,
27
+ activePathItems: /* @__PURE__ */ new WeakSet()
28
+ };
29
+ const hasOpenApi = Object.hasOwn(document, "openapi");
30
+ const hasSwagger = Object.hasOwn(document, "swagger");
31
+ let dialect;
32
+ let version;
33
+ if (hasOpenApi && hasSwagger) addDiagnostic(state, "conflicting-version-fields", "/", "Use either the `openapi` field or the `swagger` field, not both.");
34
+ else if (hasOpenApi) {
35
+ dialect = "openapi";
36
+ version = validateOpenApiVersion(document.openapi, state);
37
+ } else if (hasSwagger) {
38
+ dialect = "swagger";
39
+ version = validateSwaggerVersion(document.swagger, state);
40
+ } else addDiagnostic(state, "missing-version", "/", "The document must declare an `openapi` or `swagger` specification version.");
41
+ inspectPathItemMap(document.paths, "/paths", "paths", state);
42
+ if (document.webhooks !== void 0) inspectPathItemMap(document.webhooks, "/webhooks", "webhooks", state);
43
+ return {
44
+ valid: state.diagnostics.length === 0,
45
+ dialect,
46
+ version,
47
+ operationCount: state.operationCount,
48
+ diagnostics: state.diagnostics
49
+ };
50
+ }
51
+ function assertValidOpenApiContract(document) {
52
+ const result = validateOpenApiContract(document);
53
+ if (!result.valid) throw new OpenApiContractValidationError(result);
54
+ }
55
+ function validateOpenApiVersion(value, state) {
56
+ if (typeof value !== "string" || !/^\d+\.\d+\.\d+$/.test(value)) {
57
+ addDiagnostic(state, "invalid-version", "/openapi", "`openapi` must be a stable major.minor.patch version string.");
58
+ return;
59
+ }
60
+ if (!/^3\.(?:0|1|2)\.\d+$/.test(value)) addDiagnostic(state, "unsupported-version", "/openapi", `OpenAPI ${value} is not supported. Supported families are 3.0.x, 3.1.x, and 3.2.x.`);
61
+ return value;
62
+ }
63
+ function validateSwaggerVersion(value, state) {
64
+ if (typeof value !== "string") {
65
+ addDiagnostic(state, "invalid-version", "/swagger", "`swagger` must be the string `2.0`.");
66
+ return;
67
+ }
68
+ if (value !== "2.0") addDiagnostic(state, "unsupported-version", "/swagger", `Swagger ${value} is not supported. The supported Swagger version is 2.0.`);
69
+ return value;
70
+ }
71
+ function inspectPathItemMap(value, pointer, kind, state) {
72
+ if (value === void 0) return;
73
+ if (!isRecord(value)) {
74
+ addDiagnostic(state, kind === "paths" ? "invalid-paths" : kind === "webhooks" ? "invalid-webhooks" : "invalid-callbacks", pointer, `\`${kind}\` must be an object.`);
75
+ return;
76
+ }
77
+ for (const [key, pathItem] of Object.entries(value)) {
78
+ if (key.startsWith("x-")) continue;
79
+ const pathPointer = `${pointer}/${escapeJsonPointer(key)}`;
80
+ if (!isRecord(pathItem)) {
81
+ addDiagnostic(state, "invalid-path-item", pathPointer, "Path items must be objects or Reference Objects.");
82
+ continue;
83
+ }
84
+ inspectPathItem(pathItem, pathPointer, state);
85
+ }
86
+ }
87
+ function inspectPathItem(pathItem, pointer, state) {
88
+ if (state.activePathItems.has(pathItem)) return;
89
+ state.activePathItems.add(pathItem);
90
+ try {
91
+ for (const method of OPENAPI_HTTP_METHODS) {
92
+ const operation = pathItem[method];
93
+ if (operation === void 0) continue;
94
+ const operationPointer = `${pointer}/${method}`;
95
+ if (!isRecord(operation)) {
96
+ addDiagnostic(state, "invalid-operation", operationPointer, `The ${method.toUpperCase()} operation must be an object.`);
97
+ continue;
98
+ }
99
+ state.operationCount += 1;
100
+ inspectOperationId(operation.operationId, `${operationPointer}/operationId`, state);
101
+ inspectCallbacks(operation.callbacks, `${operationPointer}/callbacks`, state);
102
+ }
103
+ } finally {
104
+ state.activePathItems.delete(pathItem);
105
+ }
106
+ }
107
+ function inspectOperationId(value, pointer, state) {
108
+ if (value === void 0) return;
109
+ if (typeof value !== "string" || value.trim().length === 0) {
110
+ addDiagnostic(state, "invalid-operation-id", pointer, "`operationId` must be a non-empty string when provided.");
111
+ return;
112
+ }
113
+ const firstPath = state.operationIds.get(value);
114
+ if (firstPath) {
115
+ addDiagnostic(state, "duplicate-operation-id", pointer, `The operationId \`${value}\` is already used at ${firstPath}.`, firstPath);
116
+ return;
117
+ }
118
+ state.operationIds.set(value, pointer);
119
+ }
120
+ function inspectCallbacks(value, pointer, state) {
121
+ if (value === void 0) return;
122
+ if (!isRecord(value)) {
123
+ addDiagnostic(state, "invalid-callbacks", pointer, "`callbacks` must be an object.");
124
+ return;
125
+ }
126
+ for (const [callbackName, callback] of Object.entries(value)) {
127
+ if (callbackName.startsWith("x-")) continue;
128
+ const callbackPointer = `${pointer}/${escapeJsonPointer(callbackName)}`;
129
+ if (!isRecord(callback)) {
130
+ addDiagnostic(state, "invalid-callbacks", callbackPointer, "Callback entries must be Callback Objects or Reference Objects.");
131
+ continue;
132
+ }
133
+ if (typeof callback.$ref === "string") continue;
134
+ inspectPathItemMap(callback, callbackPointer, "callbacks", state);
135
+ }
136
+ }
137
+ function addDiagnostic(state, code, path, message, relatedPath) {
138
+ state.diagnostics.push({
139
+ severity: "error",
140
+ code,
141
+ path,
142
+ message,
143
+ relatedPath
144
+ });
145
+ }
146
+ function escapeJsonPointer(value) {
147
+ return value.replaceAll("~", "~0").replaceAll("/", "~1");
148
+ }
149
+ function isRecord(value) {
150
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
151
+ }
152
+
153
+ //#endregion
154
+ export { assertValidOpenApiContract, validateOpenApiContract };
@@ -40,4 +40,4 @@ async function validateDocsOpenApiMcpUrl(url, config) {
40
40
  }
41
41
 
42
42
  //#endregion
43
- export { validateDocsOpenApiMcpUrl as t };
43
+ export { validateDocsOpenApiMcpUrl };
@@ -0,0 +1,26 @@
1
+ import { DocsOpenApiMcpConfig } from "./types.mjs";
2
+
3
+ //#region src/openapi-mcp.d.ts
4
+ interface DocsOpenApiMcpParameter {
5
+ name: string;
6
+ in: "path" | "query" | "header" | "cookie";
7
+ required: boolean;
8
+ }
9
+ interface DocsOpenApiMcpOperation {
10
+ toolName: string;
11
+ operationId: string;
12
+ method: string;
13
+ path: string;
14
+ title: string;
15
+ description?: string;
16
+ parameters: DocsOpenApiMcpParameter[];
17
+ security: Array<Record<string, string[]>>;
18
+ securitySchemes: Record<string, unknown>;
19
+ readOnly: boolean;
20
+ destructive: boolean;
21
+ idempotent: boolean;
22
+ }
23
+ declare function resolveDocsOpenApiMcpOperations(document: Record<string, unknown>, config?: DocsOpenApiMcpConfig): DocsOpenApiMcpOperation[];
24
+ declare function resolveDocsOpenApiMcpBaseUrl(document: Record<string, unknown>, config: DocsOpenApiMcpConfig): string | undefined;
25
+ //#endregion
26
+ export { DocsOpenApiMcpOperation, DocsOpenApiMcpParameter, resolveDocsOpenApiMcpBaseUrl, resolveDocsOpenApiMcpOperations };
@@ -0,0 +1,132 @@
1
+ import { buildNormalizedOpenApiModel } from "./openapi-operations.mjs";
2
+
3
+ //#region src/openapi-mcp.ts
4
+ const OPENAPI_RATE_WINDOW_MS = 6e4;
5
+ const openApiRateWindows = /* @__PURE__ */ new Map();
6
+ function acquireDocsOpenApiMcpBudget(key, config, now = Date.now()) {
7
+ const requestsPerMinute = Math.max(1, config.requestsPerMinute ?? 60);
8
+ const maxConcurrentRequests = Math.max(1, config.maxConcurrentRequests ?? 4);
9
+ let window = openApiRateWindows.get(key);
10
+ if (!window || now - window.startedAt >= OPENAPI_RATE_WINDOW_MS) {
11
+ window = {
12
+ startedAt: now,
13
+ count: 0,
14
+ active: window?.active ?? 0
15
+ };
16
+ openApiRateWindows.set(key, window);
17
+ }
18
+ if (window.count >= requestsPerMinute) throw new Error("OpenAPI MCP rate limit exceeded for this principal and operation.");
19
+ if (window.active >= maxConcurrentRequests) throw new Error("OpenAPI MCP concurrency limit exceeded for this principal and operation.");
20
+ window.count += 1;
21
+ window.active += 1;
22
+ let released = false;
23
+ return () => {
24
+ if (released) return;
25
+ released = true;
26
+ window.active = Math.max(0, window.active - 1);
27
+ };
28
+ }
29
+ async function readDocsOpenApiMcpResponse(response, maxBytes = 1e6) {
30
+ const limit = Math.max(1, maxBytes);
31
+ if (!response.body) return {
32
+ text: "",
33
+ truncated: false
34
+ };
35
+ const reader = response.body.getReader();
36
+ const chunks = [];
37
+ let used = 0;
38
+ let truncated = false;
39
+ try {
40
+ while (true) {
41
+ const { done, value } = await reader.read();
42
+ if (done) break;
43
+ if (used + value.byteLength > limit) {
44
+ const remaining = limit - used;
45
+ if (remaining > 0) chunks.push(value.subarray(0, remaining));
46
+ used = limit;
47
+ truncated = true;
48
+ await reader.cancel("OpenAPI MCP response byte limit reached");
49
+ break;
50
+ }
51
+ chunks.push(value);
52
+ used += value.byteLength;
53
+ }
54
+ } finally {
55
+ reader.releaseLock();
56
+ }
57
+ const bytes = new Uint8Array(used);
58
+ let offset = 0;
59
+ for (const chunk of chunks) {
60
+ bytes.set(chunk, offset);
61
+ offset += chunk.byteLength;
62
+ }
63
+ return {
64
+ text: new TextDecoder().decode(bytes),
65
+ truncated
66
+ };
67
+ }
68
+ function asRecord(value) {
69
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
70
+ }
71
+ function sanitizeToolName(value) {
72
+ return `api_${value.trim().replace(/[^a-zA-Z0-9_-]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 56) || "operation"}`;
73
+ }
74
+ function operationExtensionEnabled(operation) {
75
+ const extension = operation.extensions["x-farming-labs-mcp"];
76
+ return extension === true || asRecord(extension)?.enabled === true;
77
+ }
78
+ function resolveDocsOpenApiMcpOperations(document, config) {
79
+ if (!config || config.enabled === false) return [];
80
+ const allow = new Set((config.operations ?? []).map((value) => value.trim()).filter(Boolean));
81
+ const model = buildNormalizedOpenApiModel(document);
82
+ const operations = [];
83
+ const names = /* @__PURE__ */ new Set();
84
+ for (const operation of model.operations) {
85
+ if (operation.method === "TRACE") continue;
86
+ if (!(allow.has(operation.operationId) || allow.has(operation.selector) || operationExtensionEnabled(operation))) continue;
87
+ if (![
88
+ "GET",
89
+ "HEAD",
90
+ "OPTIONS"
91
+ ].includes(operation.method) && config.allowMutations !== true) continue;
92
+ const toolName = sanitizeToolName(operation.operationId);
93
+ if (names.has(toolName)) throw new Error(`OpenAPI MCP tool name collision: ${toolName}`);
94
+ names.add(toolName);
95
+ operations.push({
96
+ toolName,
97
+ operationId: operation.operationId,
98
+ method: operation.method,
99
+ path: operation.path,
100
+ title: operation.title,
101
+ ...operation.description ? { description: operation.description } : {},
102
+ parameters: operation.parameters.flatMap((parameter) => {
103
+ if (parameter.in !== "path" && parameter.in !== "query" && parameter.in !== "header" && parameter.in !== "cookie") return [];
104
+ return [{
105
+ name: parameter.name,
106
+ in: parameter.in,
107
+ required: parameter.required
108
+ }];
109
+ }),
110
+ security: operation.security,
111
+ securitySchemes: operation.securitySchemes,
112
+ readOnly: operation.method === "GET" || operation.method === "HEAD",
113
+ destructive: operation.method === "DELETE",
114
+ idempotent: [
115
+ "GET",
116
+ "HEAD",
117
+ "PUT",
118
+ "DELETE",
119
+ "OPTIONS"
120
+ ].includes(operation.method)
121
+ });
122
+ }
123
+ return operations.sort((left, right) => left.toolName.localeCompare(right.toolName));
124
+ }
125
+ function resolveDocsOpenApiMcpBaseUrl(document, config) {
126
+ const configured = config.baseUrl?.trim();
127
+ if (configured) return configured;
128
+ return buildNormalizedOpenApiModel(document).servers[0];
129
+ }
130
+
131
+ //#endregion
132
+ export { acquireDocsOpenApiMcpBudget, readDocsOpenApiMcpResponse, resolveDocsOpenApiMcpBaseUrl, resolveDocsOpenApiMcpOperations };
@@ -0,0 +1,71 @@
1
+ //#region src/openapi-operations.d.ts
2
+ declare const OPENAPI_OPERATION_METHODS: readonly ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
3
+ type OpenApiOperationMethod = Uppercase<(typeof OPENAPI_OPERATION_METHODS)[number]>;
4
+ interface NormalizedOpenApiExample {
5
+ name: string;
6
+ location: "parameter" | "request" | "response";
7
+ summary?: string;
8
+ description?: string;
9
+ mediaType?: string;
10
+ status?: string;
11
+ value?: unknown;
12
+ externalValue?: string;
13
+ }
14
+ interface NormalizedOpenApiMediaType {
15
+ mediaType: string;
16
+ schema?: unknown;
17
+ examples: NormalizedOpenApiExample[];
18
+ }
19
+ interface NormalizedOpenApiParameter {
20
+ name: string;
21
+ in: string;
22
+ required: boolean;
23
+ description?: string;
24
+ schema?: unknown;
25
+ examples: NormalizedOpenApiExample[];
26
+ }
27
+ interface NormalizedOpenApiRequestBody {
28
+ required: boolean;
29
+ description?: string;
30
+ content: NormalizedOpenApiMediaType[];
31
+ }
32
+ interface NormalizedOpenApiResponse {
33
+ status: string;
34
+ description?: string;
35
+ content: NormalizedOpenApiMediaType[];
36
+ }
37
+ interface NormalizedOpenApiOperation {
38
+ id: string;
39
+ operationId: string;
40
+ operationIdSource: "explicit" | "generated";
41
+ slug: string;
42
+ selector: string;
43
+ pointer: string;
44
+ method: OpenApiOperationMethod;
45
+ path: string;
46
+ title: string;
47
+ summary?: string;
48
+ description?: string;
49
+ tags: string[];
50
+ deprecated: boolean;
51
+ parameters: NormalizedOpenApiParameter[];
52
+ requestBody?: NormalizedOpenApiRequestBody;
53
+ responses: NormalizedOpenApiResponse[];
54
+ examples: NormalizedOpenApiExample[];
55
+ security: Array<Record<string, string[]>>;
56
+ securitySchemes: Record<string, unknown>;
57
+ servers: string[];
58
+ extensions: Record<string, unknown>;
59
+ }
60
+ interface NormalizedOpenApiModel {
61
+ title: string;
62
+ version: string;
63
+ specificationVersion: string;
64
+ servers: string[];
65
+ tags: string[];
66
+ operationCount: number;
67
+ operations: NormalizedOpenApiOperation[];
68
+ }
69
+ declare function buildNormalizedOpenApiModel(document: Record<string, unknown>): NormalizedOpenApiModel;
70
+ //#endregion
71
+ export { NormalizedOpenApiExample, NormalizedOpenApiMediaType, NormalizedOpenApiModel, NormalizedOpenApiOperation, NormalizedOpenApiParameter, NormalizedOpenApiRequestBody, NormalizedOpenApiResponse, OPENAPI_OPERATION_METHODS, OpenApiOperationMethod, buildNormalizedOpenApiModel };
@@ -321,4 +321,4 @@ function escapeJsonPointer(value) {
321
321
  }
322
322
 
323
323
  //#endregion
324
- export { buildNormalizedOpenApiModel as n, OPENAPI_OPERATION_METHODS as t };
324
+ export { OPENAPI_OPERATION_METHODS, buildNormalizedOpenApiModel };