@farming-labs/docs 0.2.104 → 0.2.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-NerpHcQB.mjs → agent-CaCWThBY.mjs} +4 -4
- package/dist/{agent-PSrgiJD8.mjs → agent-DCTGj6J7.mjs} +48 -12
- package/dist/{agent-evals-U9d_db2u.mjs → agent-evals-D-sPJfXz.mjs} +5 -5
- package/dist/{agent-export-DlBUKkTt.mjs → agent-export-GcTZPLfB.mjs} +19 -17
- package/dist/agent-feedback-evaluations-DQCTFegz.mjs +240 -0
- package/dist/agent-maintenance-CuZ7iAKq.mjs +289 -0
- package/dist/agent-skills-bundle.d.mts +1 -1
- package/dist/{agent-skills-progressive-disclosure-CfIsq4Ew.mjs → agent-skills-progressive-disclosure-DL-q4JZo.mjs} +1 -1
- package/dist/{agent-skills-server-CIoL58X7.d.mts → agent-skills-server-D34054x5.d.mts} +2 -2
- package/dist/{agent-skills-server-DFqQyO_V.mjs → agent-skills-server-Ddbf15pY.mjs} +1 -1
- package/dist/agent-skills-vite.d.mts +3 -3
- package/dist/agent-skills-vite.mjs +2 -2
- package/dist/{agents-D3SLnQet.mjs → agents-e1SYT64z.mjs} +11 -11
- package/dist/{analytics-Bx44lg6d.mjs → analytics-CqfcIBdg.mjs} +1 -1
- package/dist/{analytics-B-jz7re8.d.mts → analytics-aeXwEvQX.d.mts} +1 -1
- package/dist/{authoring-BsWXMH43.mjs → authoring-Do87QzBd.mjs} +6 -6
- package/dist/{authoring-mcp-BCM5CJbJ.mjs → authoring-mcp-Be7quE5R.mjs} +2 -2
- package/dist/browser.d.mts +3 -3
- package/dist/browser.mjs +2 -2
- package/dist/cli/index.mjs +71 -35
- package/dist/client/react.d.mts +1 -1
- package/dist/client/react.mjs +1 -1
- package/dist/{cloud-BLxt_HYO.mjs → cloud-Bvof6mET.mjs} +3 -3
- package/dist/{cloud-ask-ai-19G2HJ62.d.mts → cloud-ask-ai-BqfiQaNZ.d.mts} +1 -1
- package/dist/{cloud-ask-ai-DeojA5lB.mjs → cloud-ask-ai-CK2qlNns.mjs} +1 -1
- package/dist/{codeblocks-qHdKGVaE.mjs → codeblocks-C911CdyJ.mjs} +2 -2
- package/dist/{agent-C9IdC__R.d.mts → content-change-hydration-CoYRs3pC.d.mts} +704 -678
- package/dist/{dev-B0iHJjTz.mjs → dev-Bx0JNglW.mjs} +2 -2
- package/dist/docs-cloud-server.d.mts +2 -2
- package/dist/docs-cloud-server.mjs +2 -2
- package/dist/{doctor-x3k6aE2I.mjs → doctor-CtK1CRPj.mjs} +17 -17
- package/dist/{downgrade-Dd3vvVdD.mjs → downgrade-BXmQMkMy.mjs} +2 -2
- package/dist/{feedback-DdWc33oO.mjs → feedback-DWVUMrxy.mjs} +1 -1
- package/dist/feedback-evals-k0sFDdms.mjs +146 -0
- package/dist/{golden-evaluations-7k7Akp3R.mjs → golden-evaluations-De4KwoYr.mjs} +3 -3
- package/dist/index.d.mts +174 -9
- package/dist/index.mjs +14 -11
- package/dist/{init-DKukQdOQ.mjs → init-CCV2eRNB.mjs} +3 -3
- package/dist/markdown-rendering.mjs +1 -1
- package/dist/{markdown-sections-7OoA7ylx.mjs → markdown-sections-BKy4labo.mjs} +110 -2
- package/dist/{mcp-B6ZZdp6F.mjs → mcp-DsjWxF7g.mjs} +11 -11
- package/dist/mcp.d.mts +5 -3
- package/dist/mcp.mjs +92 -29
- package/dist/{metadata-D4v_R1t5.mjs → metadata-7htr-Xj_.mjs} +1 -1
- package/dist/{openapi-mcp-B7u7Y0gB.mjs → openapi-mcp-DQ3xptKo.mjs} +68 -4
- package/dist/openapi-mcp-node-vO3IXVGI.mjs +43 -0
- package/dist/{package-version-P4TT_9IO.mjs → package-version-Ci99L0yo.mjs} +1 -1
- package/dist/{prompt-references-Ca2Rcrpw.mjs → prompt-references-1Wce71c7.mjs} +3 -3
- package/dist/propose-DJOiHu9Y.mjs +73 -0
- package/dist/retrieval-digest-B-SgtXKK.mjs +177 -0
- package/dist/retrieval-digest-DyNRD-mt.d.mts +467 -0
- package/dist/{review-DgaNTtP0.mjs → review-XI9FXeos.mjs} +12 -12
- package/dist/{robots-DNod0XKB.mjs → robots-BOjWB1ky.mjs} +2 -2
- package/dist/{robots-msD1xoH5.mjs → robots-CzKesbdX.mjs} +6 -6
- package/dist/{search-CNzq9S5S.mjs → search-DwAoC9X7.mjs} +12 -12
- package/dist/server.d.mts +6 -308
- package/dist/server.mjs +13 -12
- package/dist/{sidebar-DmXRpAAK.d.mts → sidebar-CJze8SBi.d.mts} +1 -1
- package/dist/{sitemap-CHvips7o.mjs → sitemap-DOaJIKJf.mjs} +11 -11
- package/dist/{sitemap-server-C2TauhKa.mjs → sitemap-server-NeVu8W38.mjs} +1 -1
- package/dist/{skills-aaE5L1go.mjs → skills-BILSESek.mjs} +11 -11
- package/dist/{standards-discovery-Ckx0tN7B.mjs → standards-discovery-Bpz90VYq.mjs} +2 -177
- package/dist/{standards-discovery-Cqq8QmlH.d.mts → standards-discovery-Xm84bS4M.d.mts} +1 -1
- package/dist/{types-BthCiAD9.d.mts → types-QhYMnKvb.d.mts} +35 -2
- package/dist/{upgrade-B0OA_7jE.mjs → upgrade-B92U83xo.mjs} +2 -2
- package/package.json +1 -1
- package/styles/themes/shadcn.css +232 -38
- package/dist/retrieval-digest-DT9Ktc4C.d.mts +0 -164
- /package/dist/{agent-feedback-loop-CGrc-gDW.mjs → agent-feedback-loop-vaC-M1sx.mjs} +0 -0
- /package/dist/{audience-exposure-BW13cI2O.d.mts → audience-exposure-CkNZNeVX.d.mts} +0 -0
- /package/dist/{cloud-analytics-CSyFE6SS.mjs → cloud-analytics-Ci1yiwD8.mjs} +0 -0
- /package/dist/{code-blocks-c3nIrWOM.mjs → code-blocks-D90CCJFs.mjs} +0 -0
- /package/dist/{config-BhF6J2N4.mjs → config-DrZ3fXgf.mjs} +0 -0
- /package/dist/{errors-B5KTe1Xo.mjs → errors-BDmra6mz.mjs} +0 -0
- /package/dist/{i18n-B3BIxShC.mjs → i18n-B1gJ9EW0.mjs} +0 -0
- /package/dist/{sidebar-IcpElOVH.mjs → sidebar-3W51s2sF.mjs} +0 -0
- /package/dist/{templates-m_j4ARnu.mjs → templates-DdB4BBGq.mjs} +0 -0
- /package/dist/{utils-DcCUwxqS.mjs → utils-Cc1SrVza.mjs} +0 -0
|
@@ -3,6 +3,61 @@ import { slug } from "github-slugger";
|
|
|
3
3
|
import { parseEntities } from "parse-entities";
|
|
4
4
|
import remarkGfm from "remark-gfm";
|
|
5
5
|
|
|
6
|
+
//#region src/access.ts
|
|
7
|
+
function isRecord$1(value) {
|
|
8
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9
|
+
}
|
|
10
|
+
function normalizeStrings(value) {
|
|
11
|
+
if (!Array.isArray(value)) return void 0;
|
|
12
|
+
const strings = Array.from(new Set(value.flatMap((item) => typeof item === "string" && item.trim() ? [item.trim()] : [])));
|
|
13
|
+
return strings.length > 0 ? strings : void 0;
|
|
14
|
+
}
|
|
15
|
+
function normalizeClaimValue(value) {
|
|
16
|
+
if (typeof value === "string") return value.trim() || void 0;
|
|
17
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
18
|
+
if (typeof value === "boolean") return value;
|
|
19
|
+
return normalizeStrings(value);
|
|
20
|
+
}
|
|
21
|
+
function normalizeDocsPageAccessPolicy(value) {
|
|
22
|
+
if (!isRecord$1(value)) return void 0;
|
|
23
|
+
const visibility = value.visibility === "public" || value.visibility === "authenticated" ? value.visibility : void 0;
|
|
24
|
+
const scopes = normalizeStrings(value.scopes);
|
|
25
|
+
const rawClaims = isRecord$1(value.claims) ? value.claims : void 0;
|
|
26
|
+
const claims = rawClaims ? Object.fromEntries(Object.entries(rawClaims).flatMap(([name, rawValue]) => {
|
|
27
|
+
const normalizedName = name.trim();
|
|
28
|
+
const normalizedValue = normalizeClaimValue(rawValue);
|
|
29
|
+
return normalizedName && normalizedValue !== void 0 ? [[normalizedName, normalizedValue]] : [];
|
|
30
|
+
})) : void 0;
|
|
31
|
+
const normalizedClaims = claims && Object.keys(claims).length > 0 ? claims : void 0;
|
|
32
|
+
if (!visibility && !scopes && !normalizedClaims) return void 0;
|
|
33
|
+
return {
|
|
34
|
+
...visibility ? { visibility } : {},
|
|
35
|
+
...scopes ? { scopes } : {},
|
|
36
|
+
...normalizedClaims ? { claims: normalizedClaims } : {}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function claimMatches(expected, actual) {
|
|
40
|
+
const expectedValues = Array.isArray(expected) ? expected : [expected];
|
|
41
|
+
const actualValues = Array.isArray(actual) ? actual : [actual];
|
|
42
|
+
return expectedValues.some((expectedValue) => actualValues.some((actualValue) => actualValue === expectedValue));
|
|
43
|
+
}
|
|
44
|
+
function isDocsPageAccessAllowed(policy, principal) {
|
|
45
|
+
if (!policy) return true;
|
|
46
|
+
if (!(policy.visibility !== "public" || Boolean(policy.scopes?.length) || Boolean(policy.claims && Object.keys(policy.claims).length > 0))) return true;
|
|
47
|
+
if (!principal) return false;
|
|
48
|
+
const scopes = new Set(principal.scopes ?? []);
|
|
49
|
+
if (policy.scopes?.some((scope) => !scopes.has(scope))) return false;
|
|
50
|
+
for (const [name, expected] of Object.entries(policy.claims ?? {})) if (!claimMatches(expected, principal.claims?.[name])) return false;
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
function isDocsAgentPageAccessible(page, principal) {
|
|
54
|
+
return isDocsPageAccessAllowed(page.agent?.access, principal);
|
|
55
|
+
}
|
|
56
|
+
function filterDocsPagesByAccess(pages, principal) {
|
|
57
|
+
return pages.filter((page) => isDocsAgentPageAccessible(page, principal));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
6
61
|
//#region src/agent-contract.ts
|
|
7
62
|
const PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS = [
|
|
8
63
|
"task",
|
|
@@ -16,9 +71,14 @@ const PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS = [
|
|
|
16
71
|
"rollback",
|
|
17
72
|
"failureModes"
|
|
18
73
|
];
|
|
19
|
-
const PAGE_AGENT_CONTRACT_FIELDS = [
|
|
74
|
+
const PAGE_AGENT_CONTRACT_FIELDS = [
|
|
75
|
+
"tokenBudget",
|
|
76
|
+
"access",
|
|
77
|
+
...PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS
|
|
78
|
+
];
|
|
20
79
|
const PAGE_AGENT_CONTRACT_FIELD_SCHEMA = {
|
|
21
80
|
tokenBudget: "number",
|
|
81
|
+
access: "{visibility?,scopes?,claims?}",
|
|
22
82
|
task: "string",
|
|
23
83
|
outcome: "string",
|
|
24
84
|
appliesTo: {
|
|
@@ -50,6 +110,11 @@ const VERIFICATION_FIELDS = [
|
|
|
50
110
|
"expect"
|
|
51
111
|
];
|
|
52
112
|
const FAILURE_MODE_FIELDS = ["symptom", "resolution"];
|
|
113
|
+
const ACCESS_FIELDS = [
|
|
114
|
+
"visibility",
|
|
115
|
+
"scopes",
|
|
116
|
+
"claims"
|
|
117
|
+
];
|
|
53
118
|
const PAGE_AGENT_CONTRACT_START_MARKER = "<!-- farming-labs:agent-contract:start -->";
|
|
54
119
|
const PAGE_AGENT_CONTRACT_END_MARKER = "<!-- farming-labs:agent-contract:end -->";
|
|
55
120
|
function isRecord(value) {
|
|
@@ -163,6 +228,7 @@ function normalizeTokenBudget(value) {
|
|
|
163
228
|
function normalizePageAgentFrontmatter(value) {
|
|
164
229
|
if (!isRecord(value)) return void 0;
|
|
165
230
|
const tokenBudget = normalizeTokenBudget(value.tokenBudget);
|
|
231
|
+
const access = "access" in value ? normalizeDocsPageAccessPolicy(value.access) ?? { visibility: "authenticated" } : void 0;
|
|
166
232
|
const task = normalizeString(value.task);
|
|
167
233
|
const outcome = normalizeString(value.outcome);
|
|
168
234
|
const appliesTo = normalizeAppliesTo(value.appliesTo);
|
|
@@ -175,6 +241,7 @@ function normalizePageAgentFrontmatter(value) {
|
|
|
175
241
|
const failureModes = normalizeFailureModes(value.failureModes);
|
|
176
242
|
const normalized = {
|
|
177
243
|
...tokenBudget !== void 0 ? { tokenBudget } : {},
|
|
244
|
+
...access ? { access } : {},
|
|
178
245
|
...task ? { task } : {},
|
|
179
246
|
...outcome ? { outcome } : {},
|
|
180
247
|
...appliesTo ? { appliesTo } : {},
|
|
@@ -258,6 +325,35 @@ function getPageAgentFrontmatterIssues(value) {
|
|
|
258
325
|
path: "agent.tokenBudget",
|
|
259
326
|
message: "must be a positive finite number"
|
|
260
327
|
});
|
|
328
|
+
if ("access" in value) if (!isRecord(value.access)) issues.push({
|
|
329
|
+
path: "agent.access",
|
|
330
|
+
message: "must be an object"
|
|
331
|
+
});
|
|
332
|
+
else {
|
|
333
|
+
addUnknownKeyIssues(issues, value.access, ACCESS_FIELDS, "agent.access");
|
|
334
|
+
if ("visibility" in value.access && value.access.visibility !== "public" && value.access.visibility !== "authenticated") issues.push({
|
|
335
|
+
path: "agent.access.visibility",
|
|
336
|
+
message: "must be \"public\" or \"authenticated\""
|
|
337
|
+
});
|
|
338
|
+
if ("scopes" in value.access && !normalizeStringList(value.access.scopes)) issues.push({
|
|
339
|
+
path: "agent.access.scopes",
|
|
340
|
+
message: "must be a non-empty string array"
|
|
341
|
+
});
|
|
342
|
+
if ("claims" in value.access) {
|
|
343
|
+
if (!isRecord(value.access.claims) || Object.keys(value.access.claims).length === 0) issues.push({
|
|
344
|
+
path: "agent.access.claims",
|
|
345
|
+
message: "must be a non-empty object"
|
|
346
|
+
});
|
|
347
|
+
else for (const [name, claim] of Object.entries(value.access.claims)) if (!name.trim() || normalizeDocsPageAccessPolicy({ claims: { [name]: claim } }) === void 0) issues.push({
|
|
348
|
+
path: `agent.access.claims.${name || "<empty>"}`,
|
|
349
|
+
message: "must be a string, number, boolean, or non-empty string array"
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
if (!normalizeDocsPageAccessPolicy(value.access)) issues.push({
|
|
353
|
+
path: "agent.access",
|
|
354
|
+
message: "must include a valid visibility, scope, or claim"
|
|
355
|
+
});
|
|
356
|
+
}
|
|
261
357
|
addStringIssue(issues, value, "task");
|
|
262
358
|
addStringIssue(issues, value, "outcome");
|
|
263
359
|
if ("appliesTo" in value) if (!isRecord(value.appliesTo)) issues.push({
|
|
@@ -415,6 +511,18 @@ function renderPageAgentFrontmatterYamlLines(value, indentation = 0) {
|
|
|
415
511
|
const child = `${indent} `;
|
|
416
512
|
const lines = [`${indent}agent:`];
|
|
417
513
|
if (agent.tokenBudget !== void 0) lines.push(`${child}tokenBudget: ${agent.tokenBudget}`);
|
|
514
|
+
if (agent.access) {
|
|
515
|
+
lines.push(`${child}access:`);
|
|
516
|
+
const accessIndent = `${child} `;
|
|
517
|
+
if (agent.access.visibility) lines.push(`${accessIndent}visibility: ${agent.access.visibility}`);
|
|
518
|
+
if (agent.access.scopes) renderYamlStringList(lines, accessIndent, "scopes", [...agent.access.scopes]);
|
|
519
|
+
if (agent.access.claims) {
|
|
520
|
+
lines.push(`${accessIndent}claims:`);
|
|
521
|
+
const claimsIndent = `${accessIndent} `;
|
|
522
|
+
for (const [name, claim] of Object.entries(agent.access.claims).sort(([left], [right]) => left.localeCompare(right))) if (Array.isArray(claim)) renderYamlStringList(lines, claimsIndent, yamlString(name), [...claim]);
|
|
523
|
+
else lines.push(`${claimsIndent}${yamlString(name)}: ${typeof claim === "string" ? yamlString(claim) : claim}`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
418
526
|
if (agent.task) lines.push(`${child}task: ${yamlString(agent.task)}`);
|
|
419
527
|
if (agent.outcome) lines.push(`${child}outcome: ${yamlString(agent.outcome)}`);
|
|
420
528
|
if (agent.appliesTo) {
|
|
@@ -1489,4 +1597,4 @@ function findDocsMarkdownSection(markdown, requestedSection) {
|
|
|
1489
1597
|
}
|
|
1490
1598
|
|
|
1491
1599
|
//#endregion
|
|
1492
|
-
export { upsertPageAgentContractMarkdown as S, hasStructuredPageAgentContract as _, findDocsGeneratedAgentContractRanges as a, renderPageAgentFrontmatterYamlLines as b, slugifyDocsMarkdownHeading as c, PAGE_AGENT_CONTRACT_END_MARKER as d, PAGE_AGENT_CONTRACT_FIELDS as f, getPageAgentFrontmatterIssues as g, PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS as h, createDocsRenderedHeadingAnchorResolver as i, stripDocsGeneratedAgentContractMarkers as l, PAGE_AGENT_CONTRACT_START_MARKER as m, cleanDocsRenderedHeadingLabel as n, findDocsMarkdownSection as o, PAGE_AGENT_CONTRACT_FIELD_SCHEMA as p, createDocsMarkdownHeadingAnchorResolver as r, parseDocsMarkdownSections as s, applyDocsMarkdownHeadingAnchors as t, withDocsMarkdownRenderableHeadings as u, normalizePageAgentFrontmatter as v, stripGeneratedPageAgentContractMarkdown as x, renderPageAgentContractMarkdown as y };
|
|
1600
|
+
export { filterDocsPagesByAccess as C, normalizeDocsPageAccessPolicy as E, upsertPageAgentContractMarkdown as S, isDocsPageAccessAllowed as T, hasStructuredPageAgentContract as _, findDocsGeneratedAgentContractRanges as a, renderPageAgentFrontmatterYamlLines as b, slugifyDocsMarkdownHeading as c, PAGE_AGENT_CONTRACT_END_MARKER as d, PAGE_AGENT_CONTRACT_FIELDS as f, getPageAgentFrontmatterIssues as g, PAGE_AGENT_STRUCTURED_CONTRACT_FIELDS as h, createDocsRenderedHeadingAnchorResolver as i, stripDocsGeneratedAgentContractMarkers as l, PAGE_AGENT_CONTRACT_START_MARKER as m, cleanDocsRenderedHeadingLabel as n, findDocsMarkdownSection as o, PAGE_AGENT_CONTRACT_FIELD_SCHEMA as p, createDocsMarkdownHeadingAnchorResolver as r, parseDocsMarkdownSections as s, applyDocsMarkdownHeadingAnchors as t, withDocsMarkdownRenderableHeadings as u, normalizePageAgentFrontmatter as v, isDocsAgentPageAccessible as w, stripGeneratedPageAgentContractMarkdown as x, renderPageAgentContractMarkdown as y };
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import "./
|
|
3
|
-
import { L as resolveDocsPublishedAgentSkill } from "./standards-discovery-
|
|
4
|
-
import "./openapi-mcp-
|
|
5
|
-
import { a as resolveDocsMetadataBaseUrl } from "./metadata-
|
|
6
|
-
import "./sitemap-server-
|
|
7
|
-
import { r as resolveConfiguredAgentSkills } from "./agent-skills-server-
|
|
8
|
-
import "./agent-evals-
|
|
1
|
+
import "./markdown-sections-BKy4labo.mjs";
|
|
2
|
+
import "./agent-DCTGj6J7.mjs";
|
|
3
|
+
import { L as resolveDocsPublishedAgentSkill } from "./standards-discovery-Bpz90VYq.mjs";
|
|
4
|
+
import "./openapi-mcp-DQ3xptKo.mjs";
|
|
5
|
+
import { a as resolveDocsMetadataBaseUrl } from "./metadata-7htr-Xj_.mjs";
|
|
6
|
+
import "./sitemap-server-NeVu8W38.mjs";
|
|
7
|
+
import { r as resolveConfiguredAgentSkills } from "./agent-skills-server-Ddbf15pY.mjs";
|
|
8
|
+
import "./agent-evals-D-sPJfXz.mjs";
|
|
9
9
|
import { createFilesystemDocsMcpSource, resolveDocsMcpConfig, runDocsMcpStdio } from "./mcp.mjs";
|
|
10
|
-
import "./authoring-mcp-
|
|
11
|
-
import "./code-blocks-
|
|
10
|
+
import "./authoring-mcp-Be7quE5R.mjs";
|
|
11
|
+
import "./code-blocks-D90CCJFs.mjs";
|
|
12
12
|
import "./server.mjs";
|
|
13
|
-
import { _ as resolveDocsContentDir, d as readNavTitle, g as resolveDocsConfigPath, i as hasTopLevelProperty, l as readBooleanProperty, n as extractObjectLiteral, o as loadDocsConfigModuleResult, p as readStringProperty, t as extractNestedObjectLiteral } from "./config-
|
|
13
|
+
import { _ as resolveDocsContentDir, d as readNavTitle, g as resolveDocsConfigPath, i as hasTopLevelProperty, l as readBooleanProperty, n as extractObjectLiteral, o as loadDocsConfigModuleResult, p as readStringProperty, t as extractNestedObjectLiteral } from "./config-DrZ3fXgf.mjs";
|
|
14
14
|
import { existsSync, readFileSync } from "node:fs";
|
|
15
15
|
import path from "node:path";
|
|
16
16
|
import pc from "picocolors";
|
package/dist/mcp.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { z as DocsPublishedAgentSkill } from "./standards-discovery-
|
|
3
|
-
import {
|
|
1
|
+
import { $t as DocsMcpAuthPrincipal, Er as FeedbackConfig, Hr as OrderingItem, K as DocsAgentEvaluationsConfig, Kn as DocsSearchConfig, L as DocsAgentContentChangesConfig, On as DocsRetrievalSourceProvenance, Qt as DocsMcpAllowedOrigins, Sn as DocsOpenApiMcpConfig, Xr as PageAgentFrontmatter, bn as DocsOkfTrustMetadataInput, en as DocsMcpAuthenticate, fn as DocsObservabilityConfig, gn as DocsOkfConfig, mr as DocsSearchSourcePage, mt as DocsAnalyticsConfig, rn as DocsMcpConfig, wr as DocsTelemetryFramework, yr as DocsTelemetryConfig } from "./types-QhYMnKvb.mjs";
|
|
2
|
+
import { z as DocsPublishedAgentSkill } from "./standards-discovery-Xm84bS4M.mjs";
|
|
3
|
+
import { a as DocsContentChangeHydrationResponse, c as HydrateDocsContentChangesOptions, d as hydrateDocsContentChanges, h as DocsContentChangeFeed, i as DocsContentChangeHydrationContent, l as MAX_DOCS_CONTENT_CHANGE_HYDRATION_TOKEN_BUDGET, n as DOCS_CONTENT_CHANGE_HYDRATION_FORMAT, o as DocsContentChangeHydrationSection, r as DocsContentChangeHydrationBudget, s as DocsContentChangeHydrationTombstone, sn as DocsMarkdownSectionIndex, t as DEFAULT_DOCS_CONTENT_CHANGE_HYDRATION_TOKEN_BUDGET, u as MIN_DOCS_CONTENT_CHANGE_HYDRATION_TOKEN_BUDGET } from "./content-change-hydration-CoYRs3pC.mjs";
|
|
4
4
|
import { McpServer } from "@modelcontextprotocol/server";
|
|
5
5
|
|
|
6
6
|
//#region src/mcp.d.ts
|
|
@@ -188,6 +188,8 @@ interface DocsMcpContextResult {
|
|
|
188
188
|
}
|
|
189
189
|
interface DocsMcpContextOptions {
|
|
190
190
|
pages: readonly DocsMcpPage[];
|
|
191
|
+
/** Authenticated identity used to retain authorized pages during retrieval. */
|
|
192
|
+
principal?: DocsMcpAuthPrincipal;
|
|
191
193
|
query: string;
|
|
192
194
|
framework?: string;
|
|
193
195
|
version?: string;
|
package/dist/mcp.mjs
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import { n as
|
|
1
|
+
import { C as filterDocsPagesByAccess, S as upsertPageAgentContractMarkdown, _ as hasStructuredPageAgentContract, o as findDocsMarkdownSection, s as parseDocsMarkdownSections, v as normalizePageAgentFrontmatter, y as renderPageAgentContractMarkdown } from "./markdown-sections-BKy4labo.mjs";
|
|
2
|
+
import { a as emitDocsAnalyticsEvent, i as emitDocsAgentTraceEvent, n as createDocsAgentTraceContext, r as createDocsAgentTraceId } from "./analytics-CqfcIBdg.mjs";
|
|
3
|
+
import { $n as normalizeDocsMcpEndpointPath, An as normalizeAgentFramework, E as DOCS_MARKDOWN_SECTION_INDEX_FORMAT, En as resolveDocsAudienceMdxContent, Et as validateDocsAgentFeedbackPayload, Gt as createDocsContentChangeFeed, In as paginateDocsItems, Jn as isDocsMcpOAuthScopeToken, Mn as normalizeAgentScopeValues, On as agentVersionConstraintMatches, P as buildDocsMarkdownSectionIndex, Pn as DocsPaginationCursorError, Qn as normalizeDocsMcpAuthorizationServerUrls, Rn as normalizeDocsRelated, Tt as toDocsMarkdownUrl, Wt as DocsContentChangesRequestError, Yn as isDocsMcpProtectedResourceMetadataPath, Yt as resolveDocsContentChangesConfig, Zn as isDocsMcpResourcePath, ar as buildDocsOkfBundle, bn as resolveLocalDocsMcpSearchConfig, dn as normalizeDocsSearchFilters, er as resolveDocsMcpProtectedResourceMetadataLocation, fn as performDocsSearch, jn as normalizeAgentLocale, kn as agentVersionConstraintsOverlap, nn as buildDocsSearchFacets, or as normalizeDocsOkfTrustMetadataInput, pn as performDocsSearchWithMetadata, qt as isDocsContentChangeGeneration, sr as resolveDocsOkfConfig, tr as resolveDocsMcpResourceLocation, ut as resolveDocsAgentFeedbackConfig, zn as renderDocsRelatedMarkdownLines } from "./agent-DCTGj6J7.mjs";
|
|
4
|
+
import { r as isDocsRetrievalCanonicalUrl } from "./retrieval-digest-B-SgtXKK.mjs";
|
|
5
|
+
import "./standards-discovery-Bpz90VYq.mjs";
|
|
6
|
+
import { _ as emitDocsTelemetryAgentSurfaceEvent, a as DEFAULT_DOCS_CONTENT_CHANGE_HYDRATION_TOKEN_BUDGET, b as emitDocsTelemetryProjectEvent, c as MIN_DOCS_CONTENT_CHANGE_HYDRATION_TOKEN_BUDGET, g as stripGeneratedAgentProvenance, i as resolveDocsOpenApiMcpOperations, l as hydrateDocsContentChanges, n as readDocsOpenApiMcpResponse, o as DOCS_CONTENT_CHANGE_HYDRATION_FORMAT, r as resolveDocsOpenApiMcpBaseUrl, s as MAX_DOCS_CONTENT_CHANGE_HYDRATION_TOKEN_BUDGET, t as acquireDocsOpenApiMcpBudget, y as emitDocsTelemetryMcpToolEvent } from "./openapi-mcp-DQ3xptKo.mjs";
|
|
7
|
+
import { n as resolvePageSidebarFolderIndexBehavior } from "./sidebar-3W51s2sF.mjs";
|
|
8
|
+
import { t as validateDocsOpenApiMcpUrl } from "./openapi-mcp-node-vO3IXVGI.mjs";
|
|
7
9
|
import matter from "gray-matter";
|
|
8
10
|
import fs from "node:fs";
|
|
9
11
|
import path from "node:path";
|
|
@@ -12,6 +14,23 @@ import { InMemoryServerEventBus, McpServer, ProtocolError, ProtocolErrorCode, Re
|
|
|
12
14
|
import * as z from "zod/v4";
|
|
13
15
|
|
|
14
16
|
//#region src/mcp.ts
|
|
17
|
+
function filterDocsMcpNavigation(tree, allowedUrls) {
|
|
18
|
+
const filterNodes = (nodes) => nodes.flatMap((node) => {
|
|
19
|
+
if (node.type === "page") return allowedUrls.has(node.url) ? [node] : [];
|
|
20
|
+
const children = filterNodes(node.children);
|
|
21
|
+
const index = node.index && allowedUrls.has(node.index.url) ? node.index : void 0;
|
|
22
|
+
const { index: _unfilteredIndex, ...folder } = node;
|
|
23
|
+
return children.length > 0 || index ? [{
|
|
24
|
+
...folder,
|
|
25
|
+
...index ? { index } : {},
|
|
26
|
+
children
|
|
27
|
+
}] : [];
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
...tree,
|
|
31
|
+
children: filterNodes(tree.children)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
15
34
|
const DEFAULT_MCP_VERSION = "0.0.0";
|
|
16
35
|
const DEFAULT_MCP_NAME = "@farming-labs/docs";
|
|
17
36
|
const DOCS_MCP_DISCOVERY_CACHE_TTL_MS = 300 * 1e3;
|
|
@@ -2687,6 +2706,7 @@ const openApiOperationOutputSchema = z.object({
|
|
|
2687
2706
|
status: z.number().int(),
|
|
2688
2707
|
ok: z.boolean(),
|
|
2689
2708
|
contentType: z.string().optional(),
|
|
2709
|
+
responseTruncated: z.boolean().optional(),
|
|
2690
2710
|
body: z.unknown()
|
|
2691
2711
|
});
|
|
2692
2712
|
const readPagesOutputSchema = z.object({
|
|
@@ -3319,11 +3339,16 @@ async function createDocsMcpServer(options) {
|
|
|
3319
3339
|
search: options.search
|
|
3320
3340
|
};
|
|
3321
3341
|
const telemetryFramework = options.telemetryFramework ?? "mcp";
|
|
3322
|
-
function getSourcePages(locale) {
|
|
3323
|
-
return
|
|
3342
|
+
async function getSourcePages(locale) {
|
|
3343
|
+
return getResolvedSourcePages(resolveSourceLocale(locale));
|
|
3324
3344
|
}
|
|
3325
|
-
function
|
|
3326
|
-
return options.source.
|
|
3345
|
+
async function getResolvedSourcePages(locale) {
|
|
3346
|
+
return filterDocsPagesByAccess(await options.source.getPages(locale, options.requestContext), options.requestContext?.auth);
|
|
3347
|
+
}
|
|
3348
|
+
async function getSourceNavigation(locale) {
|
|
3349
|
+
const resolvedLocale = resolveSourceLocale(locale);
|
|
3350
|
+
const [tree, pages] = await Promise.all([options.source.getNavigation(resolvedLocale, options.requestContext), getResolvedSourcePages(resolvedLocale)]);
|
|
3351
|
+
return filterDocsMcpNavigation(tree, new Set(pages.map((page) => page.url)));
|
|
3327
3352
|
}
|
|
3328
3353
|
function resolveSourceLocale(locale) {
|
|
3329
3354
|
return options.source.resolveLocale ? options.source.resolveLocale(locale, options.requestContext) : locale;
|
|
@@ -3420,7 +3445,11 @@ async function createDocsMcpServer(options) {
|
|
|
3420
3445
|
}
|
|
3421
3446
|
const requestUrl = new URL(requestPath.replace(/^\/+/, ""), `${baseUrl.replace(/\/+$/u, "")}/`);
|
|
3422
3447
|
for (const [name, value] of query) requestUrl.searchParams.append(name, value);
|
|
3423
|
-
|
|
3448
|
+
try {
|
|
3449
|
+
await validateDocsOpenApiMcpUrl(requestUrl, openapiConfig);
|
|
3450
|
+
} catch (error) {
|
|
3451
|
+
throw new ProtocolError(ProtocolErrorCode.InvalidParams, error instanceof Error ? error.message : "OpenAPI MCP destination was blocked.");
|
|
3452
|
+
}
|
|
3424
3453
|
const configuredHeaders = typeof openapiConfig.headers === "function" ? await openapiConfig.headers({
|
|
3425
3454
|
operationId: operation.operationId,
|
|
3426
3455
|
method: operation.method,
|
|
@@ -3432,17 +3461,42 @@ async function createDocsMcpServer(options) {
|
|
|
3432
3461
|
if (body !== void 0) requestHeaders.set("Content-Type", "application/json");
|
|
3433
3462
|
const controller = new AbortController();
|
|
3434
3463
|
const timeout = setTimeout(() => controller.abort(), openapiConfig.timeoutMs ?? 1e4);
|
|
3464
|
+
const budgetKey = `${options.requestContext?.auth?.id ?? "anonymous"}:${operation.operationId}`;
|
|
3465
|
+
let releaseBudget;
|
|
3435
3466
|
try {
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3467
|
+
releaseBudget = acquireDocsOpenApiMcpBudget(budgetKey, openapiConfig);
|
|
3468
|
+
let response;
|
|
3469
|
+
let destination = requestUrl;
|
|
3470
|
+
const maxRedirects = Math.max(0, openapiConfig.maxRedirects ?? 0);
|
|
3471
|
+
for (let redirectCount = 0; redirectCount <= maxRedirects; redirectCount += 1) {
|
|
3472
|
+
response = await fetch(destination, {
|
|
3473
|
+
method: operation.method,
|
|
3474
|
+
headers: requestHeaders,
|
|
3475
|
+
...body !== void 0 ? { body: JSON.stringify(body) } : {},
|
|
3476
|
+
redirect: "manual",
|
|
3477
|
+
signal: controller.signal
|
|
3478
|
+
});
|
|
3479
|
+
if (![
|
|
3480
|
+
301,
|
|
3481
|
+
302,
|
|
3482
|
+
303,
|
|
3483
|
+
307,
|
|
3484
|
+
308
|
|
3485
|
+
].includes(response.status)) break;
|
|
3486
|
+
const location = response.headers.get("location");
|
|
3487
|
+
if (!location || redirectCount >= maxRedirects) throw new ProtocolError(ProtocolErrorCode.InvalidRequest, "OpenAPI MCP redirect blocked. Increase maxRedirects to follow validated redirects.");
|
|
3488
|
+
destination = new URL(location, destination);
|
|
3489
|
+
try {
|
|
3490
|
+
await validateDocsOpenApiMcpUrl(destination, openapiConfig);
|
|
3491
|
+
} catch (error) {
|
|
3492
|
+
throw new ProtocolError(ProtocolErrorCode.InvalidRequest, error instanceof Error ? error.message : "OpenAPI MCP redirect was blocked.");
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
if (!response) throw new ProtocolError(ProtocolErrorCode.InternalError, "No API response.");
|
|
3442
3496
|
const contentType = response.headers.get("content-type") ?? void 0;
|
|
3443
|
-
const text =
|
|
3497
|
+
const { text, truncated } = await readDocsOpenApiMcpResponse(response, openapiConfig.maxResponseBytes);
|
|
3444
3498
|
let responseBody = text;
|
|
3445
|
-
if (contentType?.includes("json") && text) try {
|
|
3499
|
+
if (contentType?.includes("json") && text && !truncated) try {
|
|
3446
3500
|
responseBody = JSON.parse(text);
|
|
3447
3501
|
} catch {
|
|
3448
3502
|
responseBody = text;
|
|
@@ -3452,6 +3506,7 @@ async function createDocsMcpServer(options) {
|
|
|
3452
3506
|
status: response.status,
|
|
3453
3507
|
ok: response.ok,
|
|
3454
3508
|
...contentType ? { contentType } : {},
|
|
3509
|
+
...truncated ? { responseTruncated: true } : {},
|
|
3455
3510
|
body: responseBody
|
|
3456
3511
|
};
|
|
3457
3512
|
trackMcpTool(operation.toolName, { resultCount: 1 });
|
|
@@ -3460,6 +3515,7 @@ async function createDocsMcpServer(options) {
|
|
|
3460
3515
|
...response.ok ? {} : { isError: true }
|
|
3461
3516
|
};
|
|
3462
3517
|
} finally {
|
|
3518
|
+
releaseBudget?.();
|
|
3463
3519
|
clearTimeout(timeout);
|
|
3464
3520
|
}
|
|
3465
3521
|
});
|
|
@@ -3521,11 +3577,12 @@ async function createDocsMcpServer(options) {
|
|
|
3521
3577
|
if (!contentChangesEnabled) throw new ProtocolError(ProtocolErrorCode.MethodNotFound, "Content changes are disabled.");
|
|
3522
3578
|
if (since && !isDocsContentChangeGeneration(since)) throw new ProtocolError(ProtocolErrorCode.InvalidParams, "Content-change `since` must be a SHA-256 index generation.");
|
|
3523
3579
|
const resolvedLocale = resolveSourceLocale(locale);
|
|
3524
|
-
const pages = dedupePages(await
|
|
3580
|
+
const pages = dedupePages(await getResolvedSourcePages(resolvedLocale));
|
|
3525
3581
|
try {
|
|
3526
3582
|
return {
|
|
3527
3583
|
result: await contentChangeFeed.resolve({
|
|
3528
3584
|
pages: toSearchSourcePages(pages),
|
|
3585
|
+
principal: options.requestContext?.auth,
|
|
3529
3586
|
search: options.search,
|
|
3530
3587
|
audience: "agent",
|
|
3531
3588
|
locale: resolvedLocale,
|
|
@@ -3713,7 +3770,7 @@ async function createDocsMcpServer(options) {
|
|
|
3713
3770
|
metadata: { tool: "list_pages" }
|
|
3714
3771
|
});
|
|
3715
3772
|
try {
|
|
3716
|
-
const page = paginateDocsMcpItems(toPageSummaries(dedupePages(await
|
|
3773
|
+
const page = paginateDocsMcpItems(toPageSummaries(dedupePages(await getResolvedSourcePages(resolvedLocale))).sort(compareDocsMcpPageSummaries), {
|
|
3717
3774
|
kind: "mcp.tool/list_pages",
|
|
3718
3775
|
scope: stableDocsMcpPaginationScope({ locale: resolvedLocale ?? null }),
|
|
3719
3776
|
cursor
|
|
@@ -3808,7 +3865,7 @@ async function createDocsMcpServer(options) {
|
|
|
3808
3865
|
metadata: { tool: "list_docs" }
|
|
3809
3866
|
});
|
|
3810
3867
|
try {
|
|
3811
|
-
const docs = paginateDocsMcpDocsList(listDocsBySection(dedupePages(await
|
|
3868
|
+
const docs = paginateDocsMcpDocsList(listDocsBySection(dedupePages(await getResolvedSourcePages(resolvedLocale)), {
|
|
3812
3869
|
section,
|
|
3813
3870
|
entry: options.source.entry
|
|
3814
3871
|
}), {
|
|
@@ -3906,7 +3963,7 @@ async function createDocsMcpServer(options) {
|
|
|
3906
3963
|
metadata: { tool: "list_tasks" }
|
|
3907
3964
|
});
|
|
3908
3965
|
try {
|
|
3909
|
-
const page = paginateDocsMcpItems(listDocsTasks(dedupePages(await
|
|
3966
|
+
const page = paginateDocsMcpItems(listDocsTasks(dedupePages(await getResolvedSourcePages(resolvedLocale)), {
|
|
3910
3967
|
query,
|
|
3911
3968
|
framework,
|
|
3912
3969
|
version,
|
|
@@ -4330,7 +4387,8 @@ async function createDocsMcpServer(options) {
|
|
|
4330
4387
|
});
|
|
4331
4388
|
try {
|
|
4332
4389
|
const facets = await buildDocsSearchFacets({
|
|
4333
|
-
pages: toSearchSourcePages(dedupePages(await
|
|
4390
|
+
pages: toSearchSourcePages(dedupePages(await getResolvedSourcePages(resolvedLocale))),
|
|
4391
|
+
principal: options.requestContext?.auth,
|
|
4334
4392
|
search: toolSearchConfig ?? true,
|
|
4335
4393
|
audience: resolvedAudience,
|
|
4336
4394
|
filters,
|
|
@@ -4438,7 +4496,8 @@ async function createDocsMcpServer(options) {
|
|
|
4438
4496
|
});
|
|
4439
4497
|
try {
|
|
4440
4498
|
const searchResponse = await performDocsSearchWithMetadata({
|
|
4441
|
-
pages: toSearchSourcePages(dedupePages(await
|
|
4499
|
+
pages: toSearchSourcePages(dedupePages(await getResolvedSourcePages(resolvedLocale))),
|
|
4500
|
+
principal: options.requestContext?.auth,
|
|
4442
4501
|
query,
|
|
4443
4502
|
search: toolSearchConfig ?? true,
|
|
4444
4503
|
audience: resolvedAudience,
|
|
@@ -4644,7 +4703,8 @@ async function createDocsMcpServer(options) {
|
|
|
4644
4703
|
});
|
|
4645
4704
|
try {
|
|
4646
4705
|
const result = await buildDocsMcpContext({
|
|
4647
|
-
pages: dedupePages(await
|
|
4706
|
+
pages: dedupePages(await getResolvedSourcePages(resolvedLocale)),
|
|
4707
|
+
principal: options.requestContext?.auth,
|
|
4648
4708
|
query,
|
|
4649
4709
|
framework,
|
|
4650
4710
|
version,
|
|
@@ -4752,7 +4812,7 @@ async function createDocsMcpServer(options) {
|
|
|
4752
4812
|
metadata: { tool: "list_page_sections" }
|
|
4753
4813
|
});
|
|
4754
4814
|
try {
|
|
4755
|
-
const page = findDocsPage(dedupePages(await
|
|
4815
|
+
const page = findDocsPage(dedupePages(await getResolvedSourcePages(resolvedLocale)), requestedPath, options.source.entry);
|
|
4756
4816
|
if (!page) {
|
|
4757
4817
|
const elapsed = durationMs(startedAt);
|
|
4758
4818
|
await emitDocsAnalyticsEvent(options.analytics, {
|
|
@@ -5275,9 +5335,10 @@ function createDocsMcpHttpHandler(options) {
|
|
|
5275
5335
|
const contentChangePollIntervalMs = typeof configuredPollInterval === "number" && Number.isFinite(configuredPollInterval) && configuredPollInterval >= 10 ? Math.floor(configuredPollInterval) : DEFAULT_DOCS_MCP_CONTENT_CHANGE_POLL_INTERVAL_MS;
|
|
5276
5336
|
async function readMonitoredState(context) {
|
|
5277
5337
|
const locale = options.source.resolveLocale?.(void 0, context);
|
|
5278
|
-
const pages = dedupePages(await options.source.getPages(locale, context));
|
|
5338
|
+
const pages = dedupePages(filterDocsPagesByAccess(await options.source.getPages(locale, context), context.auth));
|
|
5279
5339
|
const result = await contentChangeFeed.resolve({
|
|
5280
5340
|
pages: toSearchSourcePages(pages),
|
|
5341
|
+
principal: context.auth,
|
|
5281
5342
|
search: options.search,
|
|
5282
5343
|
audience: "agent",
|
|
5283
5344
|
locale,
|
|
@@ -5436,9 +5497,10 @@ async function runDocsMcpStdio(options) {
|
|
|
5436
5497
|
if (!contentChangesEnabled) return server;
|
|
5437
5498
|
const readState = async () => {
|
|
5438
5499
|
const locale = options.source.resolveLocale?.(void 0, requestContext);
|
|
5439
|
-
const pages = dedupePages(await options.source.getPages(locale, requestContext));
|
|
5500
|
+
const pages = dedupePages(filterDocsPagesByAccess(await options.source.getPages(locale, requestContext), requestContext.auth));
|
|
5440
5501
|
const result = await contentChangeFeed.resolve({
|
|
5441
5502
|
pages: toSearchSourcePages(pages),
|
|
5503
|
+
principal: requestContext.auth,
|
|
5442
5504
|
search: options.search,
|
|
5443
5505
|
audience: "agent",
|
|
5444
5506
|
locale,
|
|
@@ -6689,6 +6751,7 @@ async function buildDocsMcpContext(options) {
|
|
|
6689
6751
|
const orderedResults = [...await performDocsSearch({
|
|
6690
6752
|
pages: scopedPages.map((page) => searchPageBySource.get(page)),
|
|
6691
6753
|
generationPages: allSearchPages,
|
|
6754
|
+
principal: options.principal,
|
|
6692
6755
|
query: options.query,
|
|
6693
6756
|
search: {
|
|
6694
6757
|
enabled: true,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as hasStructuredPageAgentContract, v as normalizePageAgentFrontmatter } from "./markdown-sections-
|
|
1
|
+
import { _ as hasStructuredPageAgentContract, v as normalizePageAgentFrontmatter } from "./markdown-sections-BKy4labo.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/metadata.ts
|
|
4
4
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { s as parseDocsMarkdownSections } from "./markdown-sections-BKy4labo.mjs";
|
|
2
|
+
import { $ as isDocsSkillRequest, Fn as createDocsPaginationCursor, Jt as isDocsContentChangesRequest, K as isDocsAgentDiscoveryRequest, Ln as resolveDocsPaginationOffset, Pn as DocsPaginationCursorError, St as resolveDocsSkillFormat, Yt as resolveDocsContentChangesConfig, dt as resolveDocsAgentFeedbackRequest, en as buildDocsRetrievalDigestProjection, ft as resolveDocsAgentsFormat, mt as resolveDocsLlmsTxtRequest, q as isDocsAgentsRequest, ut as resolveDocsAgentFeedbackConfig, vt as resolveDocsMarkdownRequest } from "./agent-DCTGj6J7.mjs";
|
|
3
|
+
import { n as digestDocsRetrievalContent } from "./retrieval-digest-B-SgtXKK.mjs";
|
|
4
4
|
import matter from "gray-matter";
|
|
5
5
|
|
|
6
6
|
//#region src/telemetry.ts
|
|
@@ -615,6 +615,70 @@ const HTTP_METHODS = [
|
|
|
615
615
|
"options",
|
|
616
616
|
"head"
|
|
617
617
|
];
|
|
618
|
+
const OPENAPI_RATE_WINDOW_MS = 6e4;
|
|
619
|
+
const openApiRateWindows = /* @__PURE__ */ new Map();
|
|
620
|
+
function acquireDocsOpenApiMcpBudget(key, config, now = Date.now()) {
|
|
621
|
+
const requestsPerMinute = Math.max(1, config.requestsPerMinute ?? 60);
|
|
622
|
+
const maxConcurrentRequests = Math.max(1, config.maxConcurrentRequests ?? 4);
|
|
623
|
+
let window = openApiRateWindows.get(key);
|
|
624
|
+
if (!window || now - window.startedAt >= OPENAPI_RATE_WINDOW_MS) {
|
|
625
|
+
window = {
|
|
626
|
+
startedAt: now,
|
|
627
|
+
count: 0,
|
|
628
|
+
active: window?.active ?? 0
|
|
629
|
+
};
|
|
630
|
+
openApiRateWindows.set(key, window);
|
|
631
|
+
}
|
|
632
|
+
if (window.count >= requestsPerMinute) throw new Error("OpenAPI MCP rate limit exceeded for this principal and operation.");
|
|
633
|
+
if (window.active >= maxConcurrentRequests) throw new Error("OpenAPI MCP concurrency limit exceeded for this principal and operation.");
|
|
634
|
+
window.count += 1;
|
|
635
|
+
window.active += 1;
|
|
636
|
+
let released = false;
|
|
637
|
+
return () => {
|
|
638
|
+
if (released) return;
|
|
639
|
+
released = true;
|
|
640
|
+
window.active = Math.max(0, window.active - 1);
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
async function readDocsOpenApiMcpResponse(response, maxBytes = 1e6) {
|
|
644
|
+
const limit = Math.max(1, maxBytes);
|
|
645
|
+
if (!response.body) return {
|
|
646
|
+
text: "",
|
|
647
|
+
truncated: false
|
|
648
|
+
};
|
|
649
|
+
const reader = response.body.getReader();
|
|
650
|
+
const chunks = [];
|
|
651
|
+
let used = 0;
|
|
652
|
+
let truncated = false;
|
|
653
|
+
try {
|
|
654
|
+
while (true) {
|
|
655
|
+
const { done, value } = await reader.read();
|
|
656
|
+
if (done) break;
|
|
657
|
+
if (used + value.byteLength > limit) {
|
|
658
|
+
const remaining = limit - used;
|
|
659
|
+
if (remaining > 0) chunks.push(value.subarray(0, remaining));
|
|
660
|
+
used = limit;
|
|
661
|
+
truncated = true;
|
|
662
|
+
await reader.cancel("OpenAPI MCP response byte limit reached");
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
665
|
+
chunks.push(value);
|
|
666
|
+
used += value.byteLength;
|
|
667
|
+
}
|
|
668
|
+
} finally {
|
|
669
|
+
reader.releaseLock();
|
|
670
|
+
}
|
|
671
|
+
const bytes = new Uint8Array(used);
|
|
672
|
+
let offset = 0;
|
|
673
|
+
for (const chunk of chunks) {
|
|
674
|
+
bytes.set(chunk, offset);
|
|
675
|
+
offset += chunk.byteLength;
|
|
676
|
+
}
|
|
677
|
+
return {
|
|
678
|
+
text: new TextDecoder().decode(bytes),
|
|
679
|
+
truncated
|
|
680
|
+
};
|
|
681
|
+
}
|
|
618
682
|
function asRecord(value) {
|
|
619
683
|
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
620
684
|
}
|
|
@@ -719,4 +783,4 @@ function resolveDocsOpenApiMcpBaseUrl(document, config) {
|
|
|
719
783
|
}
|
|
720
784
|
|
|
721
785
|
//#endregion
|
|
722
|
-
export {
|
|
786
|
+
export { isLocalDocsTelemetryOrigin as C, inferDocsTelemetryAgentSurface as S, resolveDocsTelemetryConfig as T, emitDocsTelemetryAgentSurfaceEvent as _, DEFAULT_DOCS_CONTENT_CHANGE_HYDRATION_TOKEN_BUDGET as a, emitDocsTelemetryProjectEvent as b, MIN_DOCS_CONTENT_CHANGE_HYDRATION_TOKEN_BUDGET as c, GENERATED_AGENT_PROVENANCE_VERSION as d, hashGeneratedAgentContent as f, stripGeneratedAgentProvenance as g, serializeGeneratedAgentDocument as h, resolveDocsOpenApiMcpOperations as i, hydrateDocsContentChanges as l, parseGeneratedAgentDocument as m, readDocsOpenApiMcpResponse as n, DOCS_CONTENT_CHANGE_HYDRATION_FORMAT as o, normalizeGeneratedAgentContent as p, resolveDocsOpenApiMcpBaseUrl as r, MAX_DOCS_CONTENT_CHANGE_HYDRATION_TOKEN_BUDGET as s, acquireDocsOpenApiMcpBudget as t, GENERATED_AGENT_PROVENANCE_MARKER as u, emitDocsTelemetryEvent as v, normalizeDocsTelemetryOrigin as w, getDocsTelemetryFeatures as x, emitDocsTelemetryMcpToolEvent as y };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { lookup } from "node:dns/promises";
|
|
2
|
+
import { isIP } from "node:net";
|
|
3
|
+
|
|
4
|
+
//#region src/openapi-mcp-node.ts
|
|
5
|
+
function isPrivateIpv4(address) {
|
|
6
|
+
const octets = address.split(".").map(Number);
|
|
7
|
+
if (octets.length !== 4 || octets.some((octet) => !Number.isInteger(octet))) return true;
|
|
8
|
+
const [a, b] = octets;
|
|
9
|
+
return a === 0 || a === 10 || a === 127 || a === 100 && b >= 64 && b <= 127 || a === 169 && b === 254 || a === 172 && b >= 16 && b <= 31 || a === 192 && (b === 0 || b === 168) || a === 198 && (b === 18 || b === 19) || a >= 224;
|
|
10
|
+
}
|
|
11
|
+
function isDocsOpenApiMcpPrivateAddress(address) {
|
|
12
|
+
const normalized = address.trim().toLowerCase().replace(/^\[|\]$/gu, "");
|
|
13
|
+
const family = isIP(normalized);
|
|
14
|
+
if (family === 4) return isPrivateIpv4(normalized);
|
|
15
|
+
if (family !== 6) return true;
|
|
16
|
+
const mappedIpv4 = normalized.match(/^(?:::ffff:)(\d+\.\d+\.\d+\.\d+)$/u)?.[1];
|
|
17
|
+
if (mappedIpv4) return isPrivateIpv4(mappedIpv4);
|
|
18
|
+
return normalized === "::" || normalized === "::1" || normalized.startsWith("fc") || normalized.startsWith("fd") || /^fe[89ab]/u.test(normalized) || normalized.startsWith("ff");
|
|
19
|
+
}
|
|
20
|
+
async function defaultResolveHost(hostname) {
|
|
21
|
+
if (isIP(hostname)) return [hostname];
|
|
22
|
+
return (await lookup(hostname, {
|
|
23
|
+
all: true,
|
|
24
|
+
verbatim: true
|
|
25
|
+
})).map((entry) => entry.address);
|
|
26
|
+
}
|
|
27
|
+
async function validateDocsOpenApiMcpUrl(url, config) {
|
|
28
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && config.allowInsecureHttp)) throw new Error("OpenAPI MCP destinations must use HTTPS unless allowInsecureHttp is enabled.");
|
|
29
|
+
if (url.username || url.password) throw new Error("OpenAPI MCP destinations cannot contain URL credentials.");
|
|
30
|
+
if (config.allowPrivateNetwork) return;
|
|
31
|
+
const hostname = url.hostname.toLowerCase().replace(/^\[|\]$/gu, "");
|
|
32
|
+
if (hostname === "localhost" || hostname.endsWith(".localhost") || hostname.endsWith(".local") || hostname.endsWith(".internal") || hostname === "metadata.google.internal") throw new Error(`OpenAPI MCP blocked private destination: ${hostname}`);
|
|
33
|
+
let addresses;
|
|
34
|
+
try {
|
|
35
|
+
addresses = await (config.resolveHost ?? defaultResolveHost)(hostname);
|
|
36
|
+
} catch {
|
|
37
|
+
throw new Error(`OpenAPI MCP could not safely resolve destination: ${hostname}`);
|
|
38
|
+
}
|
|
39
|
+
if (addresses.length === 0 || addresses.some(isDocsOpenApiMcpPrivateAddress)) throw new Error(`OpenAPI MCP blocked private or unresolved destination: ${hostname}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
export { validateDocsOpenApiMcpUrl as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as detectPackageManagerFromProject, l as formatPackageManagerDetection, t as detectFramework, u as installCommand } from "./utils-
|
|
1
|
+
import { i as detectPackageManagerFromProject, l as formatPackageManagerDetection, t as detectFramework, u as installCommand } from "./utils-Cc1SrVza.mjs";
|
|
2
2
|
import pc from "picocolors";
|
|
3
3
|
import * as p from "@clack/prompts";
|
|
4
4
|
|