@farming-labs/docs 0.2.120 → 0.2.122

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
@@ -0,0 +1,132 @@
1
+ //#region src/prompt-references.ts
2
+ function isDocsMarkdownPromptNode(node) {
3
+ return (node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement") && node.name === "Prompt";
4
+ }
5
+ function normalizeDocsMarkdownReferenceIdentifier(value) {
6
+ return typeof value === "string" ? value.trim().replace(/\s+/gu, " ").toLowerCase() : "";
7
+ }
8
+ function readDocsMarkdownPromptReferenceSource(value) {
9
+ const source = typeof value === "string" ? value : value instanceof Uint8Array ? new TextDecoder().decode(value) : void 0;
10
+ if (source === void 0) return void 0;
11
+ return source.startsWith("") ? source.slice(1) : source;
12
+ }
13
+ function sliceDocsMarkdownPromptReferenceSource(node, source) {
14
+ if (source === void 0) return void 0;
15
+ const start = node.position?.start?.offset;
16
+ const end = node.position?.end?.offset;
17
+ if (typeof start !== "number" || typeof end !== "number" || !Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start || end > source.length) return;
18
+ return source.slice(start, end);
19
+ }
20
+ function sliceDocsMarkdownPromptChildrenSource(node, source) {
21
+ const nodeSource = sliceDocsMarkdownPromptReferenceSource(node, source);
22
+ if (nodeSource === void 0) return void 0;
23
+ const closingStart = nodeSource.lastIndexOf("</Prompt");
24
+ if (closingStart < 0) return void 0;
25
+ const children = node.children ?? [];
26
+ const isolatedChild = children.length === 1 ? children[0] : void 0;
27
+ if (isolatedChild?.type === "text" && typeof isolatedChild.value === "string" && isolatedChild.position === void 0) return isolatedChild.value;
28
+ const nodeStart = node.position?.start?.offset;
29
+ if (typeof nodeStart !== "number") return void 0;
30
+ let firstChildStart;
31
+ for (const child of children) {
32
+ const childStart = child.position?.start?.offset;
33
+ if (typeof childStart === "number" && Number.isInteger(childStart) && childStart >= nodeStart && (firstChildStart === void 0 || childStart - nodeStart < firstChildStart)) firstChildStart = childStart - nodeStart;
34
+ }
35
+ if (children.length > 0 && firstChildStart === void 0) return void 0;
36
+ const openingEnd = nodeSource.lastIndexOf(">", (firstChildStart ?? closingStart) - 1);
37
+ if (openingEnd < 0 || openingEnd >= closingStart) return void 0;
38
+ return nodeSource.slice(openingEnd + 1, closingStart);
39
+ }
40
+ function flattenDocsMarkdownPromptReferenceNode(node) {
41
+ if (typeof node.value === "string") return node.value;
42
+ return (node.children ?? []).map((child) => flattenDocsMarkdownPromptReferenceNode(child)).join("");
43
+ }
44
+ function formatDocsMarkdownPromptReference(node) {
45
+ const image = node.type === "imageReference";
46
+ const visibleLabel = image ? typeof node.alt === "string" ? node.alt : "" : flattenDocsMarkdownPromptReferenceNode(node);
47
+ const referenceLabel = typeof node.label === "string" ? node.label : typeof node.identifier === "string" ? node.identifier : visibleLabel;
48
+ const prefix = image ? "!" : "";
49
+ if (node.referenceType === "collapsed") return `${prefix}[${visibleLabel}][]`;
50
+ if (node.referenceType === "shortcut") return `${prefix}[${visibleLabel}]`;
51
+ return `${prefix}[${visibleLabel}][${referenceLabel}]`;
52
+ }
53
+ function formatDocsMarkdownPromptDefinition(node) {
54
+ const label = typeof node.label === "string" ? node.label : typeof node.identifier === "string" ? node.identifier : "";
55
+ const rawUrl = typeof node.url === "string" ? node.url : "";
56
+ return `[${label}]: ${/[<>\s]/u.test(rawUrl) ? `<${rawUrl.replace(/>/gu, "\\>")}>` : rawUrl}${typeof node.title === "string" ? ` "${node.title.replace(/"/gu, "\\\"")}"` : ""}`;
57
+ }
58
+ function createDocsMarkdownPromptReferenceText(node, source) {
59
+ return {
60
+ type: "text",
61
+ value: sliceDocsMarkdownPromptReferenceSource(node, source) ?? formatDocsMarkdownPromptReference(node),
62
+ position: node.position
63
+ };
64
+ }
65
+ function createDocsMarkdownPromptDefinitionParagraph(node, source) {
66
+ return {
67
+ type: "paragraph",
68
+ children: [{
69
+ type: "text",
70
+ value: sliceDocsMarkdownPromptReferenceSource(node, source) ?? formatDocsMarkdownPromptDefinition(node),
71
+ position: node.position
72
+ }],
73
+ position: node.position
74
+ };
75
+ }
76
+ /**
77
+ * Keep `<Prompt>` children literal before Markdown reference definitions are
78
+ * resolved by the MDX compiler.
79
+ *
80
+ * Definitions inside Prompt are copyable source, not page-level definitions.
81
+ * References inside Prompt always remain source text, while references outside
82
+ * Prompt only remain live when they have a definition outside Prompt.
83
+ */
84
+ function isolateDocsMarkdownPromptReferences(root, value) {
85
+ if (!root || typeof root !== "object") return;
86
+ const source = readDocsMarkdownPromptReferenceSource(value);
87
+ const promptDefinitions = /* @__PURE__ */ new Set();
88
+ const pageDefinitions = /* @__PURE__ */ new Set();
89
+ let hasPrompt = false;
90
+ const collectDefinitions = (node, insidePrompt) => {
91
+ const prompt = isDocsMarkdownPromptNode(node);
92
+ const literal = insidePrompt || prompt;
93
+ if (prompt) hasPrompt = true;
94
+ if (node.type === "definition") {
95
+ const identifier = normalizeDocsMarkdownReferenceIdentifier(node.identifier);
96
+ if (identifier) (literal ? promptDefinitions : pageDefinitions).add(identifier);
97
+ }
98
+ for (const child of node.children ?? []) collectDefinitions(child, literal);
99
+ };
100
+ collectDefinitions(root, false);
101
+ if (!hasPrompt) return;
102
+ const isolateReferences = (node, insidePrompt) => {
103
+ const prompt = isDocsMarkdownPromptNode(node);
104
+ if (prompt) {
105
+ const promptSource = sliceDocsMarkdownPromptChildrenSource(node, source);
106
+ if (promptSource !== void 0) {
107
+ node.children = [{
108
+ type: "text",
109
+ value: promptSource
110
+ }];
111
+ return;
112
+ }
113
+ }
114
+ const literal = insidePrompt || prompt;
115
+ const children = node.children;
116
+ if (!children) return;
117
+ node.children = children.map((child) => {
118
+ const childInsidePrompt = literal || isDocsMarkdownPromptNode(child);
119
+ if (childInsidePrompt && child.type === "definition") return createDocsMarkdownPromptDefinitionParagraph(child, source);
120
+ if (child.type === "linkReference" || child.type === "imageReference") {
121
+ const identifier = normalizeDocsMarkdownReferenceIdentifier(child.identifier);
122
+ if (childInsidePrompt || promptDefinitions.has(identifier) && !pageDefinitions.has(identifier)) return createDocsMarkdownPromptReferenceText(child, source);
123
+ }
124
+ isolateReferences(child, childInsidePrompt);
125
+ return child;
126
+ });
127
+ };
128
+ isolateReferences(root, false);
129
+ }
130
+
131
+ //#endregion
132
+ export { isolateDocsMarkdownPromptReferences };
@@ -0,0 +1,36 @@
1
+ import { OpenDocsProvider, OpenDocsTarget } from "./types.mjs";
2
+
3
+ //#region src/prompt-utils.d.ts
4
+ type PromptAction = "copy" | "open";
5
+ interface SerializedOpenDocsProvider {
6
+ name: string;
7
+ iconHtml?: string;
8
+ urlTemplate: string;
9
+ promptUrlTemplate?: string;
10
+ target?: OpenDocsTarget;
11
+ prompt?: string;
12
+ }
13
+ interface PromptProviderChoice {
14
+ name: string;
15
+ iconHtml?: string;
16
+ urlTemplate: string;
17
+ }
18
+ type PromptProviderInput = Pick<SerializedOpenDocsProvider, "name" | "iconHtml"> & Partial<Pick<SerializedOpenDocsProvider, "promptUrlTemplate" | "urlTemplate">>;
19
+ interface SerializeOpenDocsProviderOptions {
20
+ target?: OpenDocsTarget;
21
+ prompt?: string;
22
+ }
23
+ declare const DEFAULT_PROMPT_PROVIDER_TEMPLATES: Record<string, string>;
24
+ declare const DEFAULT_OPEN_DOCS_TARGET: OpenDocsTarget;
25
+ declare const DEFAULT_OPEN_DOCS_PROMPT = "Read this documentation: {url}";
26
+ declare const DEFAULT_OPEN_DOCS_PROVIDER_IDS: readonly ["chatgpt", "claude"];
27
+ declare function normalizePromptProviderName(name: string): string;
28
+ declare function serializeDocsIcon(icon: unknown): string | undefined;
29
+ declare function serializeDocsIconRegistry(icons?: Record<string, unknown>): Record<string, string> | undefined;
30
+ declare function serializeOpenDocsProviders(providers?: OpenDocsProvider[], options?: SerializeOpenDocsProviderOptions): SerializedOpenDocsProvider[] | undefined;
31
+ declare function serializeOpenDocsProvider(provider: OpenDocsProvider, options?: SerializeOpenDocsProviderOptions): SerializedOpenDocsProvider | undefined;
32
+ declare function parsePromptStringArray(value: unknown): string[] | undefined;
33
+ declare function resolvePromptProviderChoices(availableProviders?: PromptProviderInput[], preferredNames?: string[]): PromptProviderChoice[];
34
+ declare function sanitizePromptText(text: string): string;
35
+ //#endregion
36
+ export { DEFAULT_OPEN_DOCS_PROMPT, DEFAULT_OPEN_DOCS_PROVIDER_IDS, DEFAULT_OPEN_DOCS_TARGET, DEFAULT_PROMPT_PROVIDER_TEMPLATES, PromptAction, PromptProviderChoice, SerializeOpenDocsProviderOptions, SerializedOpenDocsProvider, normalizePromptProviderName, parsePromptStringArray, resolvePromptProviderChoices, sanitizePromptText, serializeDocsIcon, serializeDocsIconRegistry, serializeOpenDocsProvider, serializeOpenDocsProviders };
@@ -1,61 +1,5 @@
1
1
  import { createRequire } from "node:module";
2
2
 
3
- //#region src/code-group-mdx.ts
4
- const codeGroupTitleAttributes = [
5
- "title",
6
- "filename",
7
- "file",
8
- "name",
9
- "label"
10
- ];
11
- const ignoredBareMetaTokens = new Set([
12
- "copy",
13
- "no-copy",
14
- "nocopy",
15
- "line-numbers",
16
- "linenumbers",
17
- "runnable",
18
- "show-line-numbers",
19
- "showlinenumbers",
20
- "wrap"
21
- ]);
22
- function escapeMetaAttribute(value) {
23
- return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
24
- }
25
- function readCodeGroupTitleAttribute(meta) {
26
- for (const name of codeGroupTitleAttributes) {
27
- const match = meta.match(new RegExp(`(?:^|\\s)${name}=["']([^"']+)["']`));
28
- if (match?.[1]?.trim()) return match[1].trim();
29
- }
30
- }
31
- function readBareCodeGroupTitle(meta) {
32
- return meta.replace(/\{[^}]*\}/g, " ").split(/\s+/).find((part) => part && !part.includes("=") && !ignoredBareMetaTokens.has(part.toLowerCase()))?.replace(/^["']|["']$/g, "");
33
- }
34
- function resolveCodeGroupCodeTitle(meta) {
35
- const trimmed = meta?.trim();
36
- if (!trimmed) return void 0;
37
- return readCodeGroupTitleAttribute(trimmed) ?? readBareCodeGroupTitle(trimmed);
38
- }
39
- function ensureCodeGroupCodeTitle(node) {
40
- const title = resolveCodeGroupCodeTitle(node.meta);
41
- if (!title) return;
42
- const meta = node.meta?.trim() ?? "";
43
- if (/(?:^|\s)title=["']/.test(meta)) return;
44
- node.meta = `title="${escapeMetaAttribute(title)}"${meta ? ` ${meta}` : ""}`;
45
- }
46
- function visitCodeGroups(node) {
47
- if (node.type === "mdxJsxFlowElement" && node.name === "CodeGroup") {
48
- for (const child of node.children ?? []) if (child.type === "code") ensureCodeGroupCodeTitle(child);
49
- }
50
- for (const child of node.children ?? []) visitCodeGroups(child);
51
- }
52
- function remarkCodeGroup() {
53
- return (tree) => {
54
- visitCodeGroups(tree);
55
- };
56
- }
57
-
58
- //#endregion
59
3
  //#region src/prompt-utils.ts
60
4
  const DEFAULT_PROMPT_PROVIDER_TEMPLATES = {
61
5
  chatgpt: "https://chatgpt.com/?q={prompt}",
@@ -216,4 +160,4 @@ function sanitizePromptText(text) {
216
160
  }
217
161
 
218
162
  //#endregion
219
- export { normalizePromptProviderName as a, sanitizePromptText as c, serializeOpenDocsProvider as d, serializeOpenDocsProviders as f, DEFAULT_PROMPT_PROVIDER_TEMPLATES as i, serializeDocsIcon as l, DEFAULT_OPEN_DOCS_PROVIDER_IDS as n, parsePromptStringArray as o, remarkCodeGroup as p, DEFAULT_OPEN_DOCS_TARGET as r, resolvePromptProviderChoices as s, DEFAULT_OPEN_DOCS_PROMPT as t, serializeDocsIconRegistry as u };
163
+ export { DEFAULT_OPEN_DOCS_PROMPT, DEFAULT_OPEN_DOCS_PROVIDER_IDS, DEFAULT_OPEN_DOCS_TARGET, DEFAULT_PROMPT_PROVIDER_TEMPLATES, normalizePromptProviderName, parsePromptStringArray, resolvePromptProviderChoices, sanitizePromptText, serializeDocsIcon, serializeDocsIconRegistry, serializeOpenDocsProvider, serializeOpenDocsProviders };
@@ -0,0 +1,23 @@
1
+ import { PageFrontmatter, ReadingTimeConfig, ReadingTimeFormat } from "./types.mjs";
2
+
3
+ //#region src/reading-time.d.ts
4
+ interface ResolvedReadingTimeOptions {
5
+ enabled: boolean;
6
+ wordsPerMinute?: number;
7
+ format: ReadingTimeFormat;
8
+ includeCode: boolean;
9
+ }
10
+ interface ReadingTimeEstimateOptions {
11
+ includeCode?: boolean;
12
+ }
13
+ declare function estimateReadingTimeMinutes(content: string, wordsPerMinute?: number, options?: ReadingTimeEstimateOptions): number;
14
+ declare function resolveReadingTimeOptions(readingTime: boolean | ReadingTimeConfig | null | undefined): ResolvedReadingTimeOptions;
15
+ declare function resolveReadingTimeFromContent(frontmatter: Partial<PageFrontmatter> | undefined, content: string, wordsPerMinute?: number, options?: ReadingTimeEstimateOptions): number | null;
16
+ declare function resolvePageReadingTime(frontmatter: Partial<PageFrontmatter> | undefined, content: string, options?: {
17
+ enabledByDefault?: boolean;
18
+ wordsPerMinute?: number;
19
+ includeCode?: boolean;
20
+ }): number | null | undefined;
21
+ declare function resolveReadingTimeFromSource(source: string, wordsPerMinute?: number, options?: ReadingTimeEstimateOptions): number | null;
22
+ //#endregion
23
+ export { estimateReadingTimeMinutes, resolvePageReadingTime, resolveReadingTimeFromContent, resolveReadingTimeFromSource, resolveReadingTimeOptions };
@@ -0,0 +1,58 @@
1
+ import matter from "gray-matter";
2
+
3
+ //#region src/reading-time.ts
4
+ function hasExplicitReadingTime(frontmatter) {
5
+ return Object.prototype.hasOwnProperty.call(frontmatter ?? {}, "readingTime");
6
+ }
7
+ function normalizeWordsPerMinute(wordsPerMinute) {
8
+ if (typeof wordsPerMinute !== "number" || !Number.isFinite(wordsPerMinute)) return 220;
9
+ return Math.max(1, Math.floor(wordsPerMinute));
10
+ }
11
+ function stripNonReadingContent(content, options) {
12
+ const includeCode = options?.includeCode === true;
13
+ return (includeCode ? content.replace(/^(`{3,}|~{3,})[^\n]*$/gm, " ").replace(/`([^`\n]+)`/g, " $1 ") : content.replace(/(`{3,})[^\n]*\n[\s\S]*?\1/g, " ").replace(/(~{3,})[^\n]*\n[\s\S]*?\1/g, " ").replace(/`[^`\n]+`/g, " ")).replace(/!\[[^\]]*\]\([^)]+\)/g, " ").replace(/\[([^\]]+)\]\([^)]+\)/g, " $1 ").replace(/<[^>]+>/g, " ").replace(includeCode ? /[{}]/g : /\{[^{}]*\}/g, " ").replace(/https?:\/\/\S+/g, " ").replace(/[#>*_~|]/g, " ");
14
+ }
15
+ function estimateReadingTimeMinutes(content, wordsPerMinute, options) {
16
+ const wordCount = stripNonReadingContent(content, options).match(/\b[\p{L}\p{N}][\p{L}\p{N}'’-]*\b/gu)?.length ?? 0;
17
+ return Math.max(1, Math.ceil(wordCount / normalizeWordsPerMinute(wordsPerMinute)));
18
+ }
19
+ function resolveReadingTimeOptions(readingTime) {
20
+ if (readingTime === true) return {
21
+ enabled: true,
22
+ format: "long",
23
+ includeCode: false
24
+ };
25
+ if (readingTime === false || readingTime === void 0 || readingTime === null) return {
26
+ enabled: false,
27
+ format: "long",
28
+ includeCode: false
29
+ };
30
+ if (typeof readingTime !== "object") return {
31
+ enabled: false,
32
+ format: "long",
33
+ includeCode: false
34
+ };
35
+ return {
36
+ enabled: readingTime.enabled === true,
37
+ wordsPerMinute: typeof readingTime.wordsPerMinute === "number" && Number.isFinite(readingTime.wordsPerMinute) ? readingTime.wordsPerMinute : void 0,
38
+ format: readingTime.format === "short" ? "short" : "long",
39
+ includeCode: readingTime.includeCode === true
40
+ };
41
+ }
42
+ function resolveReadingTimeFromContent(frontmatter, content, wordsPerMinute, options) {
43
+ const pageData = frontmatter ?? {};
44
+ if (pageData.readingTime === false) return null;
45
+ if (typeof pageData.readingTime === "number" && Number.isFinite(pageData.readingTime)) return Math.max(1, Math.ceil(pageData.readingTime));
46
+ return estimateReadingTimeMinutes(content, wordsPerMinute, options);
47
+ }
48
+ function resolvePageReadingTime(frontmatter, content, options) {
49
+ if (!(options?.enabledByDefault ?? false) && !hasExplicitReadingTime(frontmatter)) return;
50
+ return resolveReadingTimeFromContent(frontmatter, content, options?.wordsPerMinute, { includeCode: options?.includeCode });
51
+ }
52
+ function resolveReadingTimeFromSource(source, wordsPerMinute, options) {
53
+ const { data, content } = matter(source);
54
+ return resolveReadingTimeFromContent(data, content, wordsPerMinute, options);
55
+ }
56
+
57
+ //#endregion
58
+ export { estimateReadingTimeMinutes, resolvePageReadingTime, resolveReadingTimeFromContent, resolveReadingTimeFromSource, resolveReadingTimeOptions };
@@ -0,0 +1,7 @@
1
+ import { ResolvedDocsRelatedLink } from "./types.mjs";
2
+
3
+ //#region src/related.d.ts
4
+ declare function normalizeDocsRelated(value: unknown): ResolvedDocsRelatedLink[];
5
+ declare function renderDocsRelatedMarkdownLines(related: ResolvedDocsRelatedLink[] | undefined): string[];
6
+ //#endregion
7
+ export { normalizeDocsRelated, renderDocsRelatedMarkdownLines };
@@ -0,0 +1,50 @@
1
+ //#region src/related.ts
2
+ function normalizeDocsRelated(value) {
3
+ if (!Array.isArray(value)) return [];
4
+ const seen = /* @__PURE__ */ new Set();
5
+ const links = [];
6
+ for (const item of value) {
7
+ const parsed = parseRelatedInput(item);
8
+ if (!parsed) continue;
9
+ const dedupeKey = normalizeRelatedLookupPath(parsed.href) ?? parsed.href;
10
+ if (seen.has(dedupeKey)) continue;
11
+ seen.add(dedupeKey);
12
+ links.push({ href: parsed.href });
13
+ }
14
+ return links;
15
+ }
16
+ function renderDocsRelatedMarkdownLines(related) {
17
+ if (!related?.length) return [];
18
+ return [`Related: ${related.map((link) => normalizeInlineText(link.href)).join(", ")}`];
19
+ }
20
+ function parseRelatedInput(value) {
21
+ if (typeof value === "string") {
22
+ const href = cleanString(value);
23
+ return href ? { href } : null;
24
+ }
25
+ return null;
26
+ }
27
+ function cleanString(value) {
28
+ if (typeof value !== "string") return void 0;
29
+ return value.trim() || void 0;
30
+ }
31
+ function normalizeRelatedLookupPath(value) {
32
+ const trimmed = value.trim();
33
+ if (!trimmed) return null;
34
+ let pathname = trimmed;
35
+ try {
36
+ pathname = new URL(trimmed, "https://docs.local").pathname;
37
+ } catch {
38
+ pathname = trimmed.split(/[?#]/, 1)[0] ?? trimmed;
39
+ }
40
+ pathname = pathname.replace(/\/+/g, "/").replace(/\.md$/i, "");
41
+ if (!pathname.startsWith("/")) pathname = `/${pathname}`;
42
+ if (pathname !== "/") pathname = pathname.replace(/\/+$/, "");
43
+ return pathname;
44
+ }
45
+ function normalizeInlineText(value) {
46
+ return value.replace(/\s+/g, " ").trim();
47
+ }
48
+
49
+ //#endregion
50
+ export { normalizeDocsRelated, renderDocsRelatedMarkdownLines };
@@ -0,0 +1,16 @@
1
+ //#region src/retrieval-digest.d.ts
2
+ /** Validate the bounded HTTP(S) URL or root-relative URI reference used by provenance. */
3
+ declare function isDocsRetrievalCanonicalUrl(value: string): boolean;
4
+ /** Hash exact bytes with portable SHA-256 in Node, edge, and browser runtimes. */
5
+ declare function sha256DocsContent(value: string | Uint8Array): string;
6
+ /** Hash exact message-content bytes with portable SHA-256. */
7
+ declare function digestDocsContent(value: string | Uint8Array): `sha256:${string}`;
8
+ /**
9
+ * Hash the normalized retrieval projection used by search provenance.
10
+ *
11
+ * The projection removes one leading BOM, normalizes line endings to LF, and trims
12
+ * trailing whitespace. This deliberately differs from HTTP digests over exact bytes.
13
+ */
14
+ declare function digestDocsRetrievalContent(value: string): `sha256:${string}`;
15
+ //#endregion
16
+ export { digestDocsContent, digestDocsRetrievalContent, isDocsRetrievalCanonicalUrl, sha256DocsContent };
@@ -174,4 +174,4 @@ function digestDocsRetrievalContent(value) {
174
174
  }
175
175
 
176
176
  //#endregion
177
- export { sha256DocsContent as i, digestDocsRetrievalContent as n, isDocsRetrievalCanonicalUrl as r, digestDocsContent as t };
177
+ export { digestDocsContent, digestDocsRetrievalContent, isDocsRetrievalCanonicalUrl, sha256DocsContent };
@@ -0,0 +1,69 @@
1
+ import { DocsConfig, DocsReviewCiMode, DocsReviewConfig, DocsReviewRulesConfig } from "./types.mjs";
2
+
3
+ //#region src/review.d.ts
4
+ declare const DEFAULT_DOCS_REVIEW_WORKFLOW_PATH = ".github/workflows/docs-review.yml";
5
+ declare const DEFAULT_DOCS_REVIEW_SCORE_THRESHOLD = 80;
6
+ interface ResolvedDocsReviewConfig {
7
+ enabled: boolean;
8
+ ci: {
9
+ enabled: boolean;
10
+ name: string;
11
+ mode: DocsReviewCiMode;
12
+ annotations: boolean;
13
+ comment: boolean;
14
+ };
15
+ score: {
16
+ threshold: number;
17
+ weights: {
18
+ error: number;
19
+ warn: number;
20
+ suggestion: number;
21
+ };
22
+ };
23
+ rules: Required<DocsReviewRulesConfig>;
24
+ }
25
+ interface DocsReviewWorkflowOptions {
26
+ packageManager?: "npm" | "pnpm" | "yarn" | "bun";
27
+ ciName?: string;
28
+ reusableWorkflow?: string;
29
+ pnpmVersion?: string;
30
+ projectDir?: string;
31
+ configPath?: string;
32
+ buildCommand?: string;
33
+ reviewCommand?: string;
34
+ pathFilters?: string[];
35
+ }
36
+ interface EnsureDocsReviewWorkflowOptions {
37
+ rootDir: string;
38
+ config?: DocsConfig;
39
+ configPath?: string;
40
+ configContent?: string;
41
+ workflowPath?: string;
42
+ log?: (message: string) => void;
43
+ }
44
+ type EnsureDocsReviewWorkflowResult = {
45
+ status: "created";
46
+ path: string;
47
+ relativePath: string;
48
+ } | {
49
+ status: "exists";
50
+ path: string;
51
+ relativePath: string;
52
+ } | {
53
+ status: "disabled";
54
+ path: string;
55
+ relativePath: string;
56
+ };
57
+ declare function resolveDocsReviewConfig(review?: boolean | DocsReviewConfig): ResolvedDocsReviewConfig;
58
+ declare function buildDocsReviewWorkflow(options?: DocsReviewWorkflowOptions): string;
59
+ declare function ensureDocsReviewWorkflow(options: EnsureDocsReviewWorkflowOptions): EnsureDocsReviewWorkflowResult;
60
+ declare function readDocsReviewConfigFromSource(content?: string): boolean | DocsReviewConfig | undefined;
61
+ declare function buildDocsReviewWorkflowPathFilters(options: {
62
+ rootDir: string;
63
+ repoRoot?: string;
64
+ config?: DocsConfig;
65
+ configPath?: string;
66
+ configContent?: string;
67
+ }): string[];
68
+ //#endregion
69
+ export { DEFAULT_DOCS_REVIEW_SCORE_THRESHOLD, DEFAULT_DOCS_REVIEW_WORKFLOW_PATH, ResolvedDocsReviewConfig, buildDocsReviewWorkflow, buildDocsReviewWorkflowPathFilters, ensureDocsReviewWorkflow, readDocsReviewConfigFromSource, resolveDocsReviewConfig };