@farming-labs/docs 0.2.41 → 0.2.43

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 (42) hide show
  1. package/dist/{agent-WcXCJ4EN.mjs → agent-DXDOMJBw.mjs} +6 -6
  2. package/dist/{agents-BjTEkCsY.mjs → agents-DjhjZaNP.mjs} +5 -5
  3. package/dist/analytics-BZEwTK-8.mjs +177 -0
  4. package/dist/cli/index.mjs +27 -27
  5. package/dist/client/react.d.mts +45 -0
  6. package/dist/client/react.mjs +223 -0
  7. package/dist/{cloud-wcDf1YC0.mjs → cloud-Bk-eppay.mjs} +158 -14
  8. package/dist/cloud-analytics-Dlk_byos.mjs +132 -0
  9. package/dist/cloud-ask-ai-Cl-xaV8j.mjs +382 -0
  10. package/dist/cloud-ask-ai-DcMe6xOf.d.mts +23 -0
  11. package/dist/{codeblocks-DTlvGTH4.mjs → codeblocks-z9iT794h.mjs} +3 -3
  12. package/dist/{dev-DxVevOP_.mjs → dev-CBha7knT.mjs} +2 -2
  13. package/dist/docs-cloud-server.d.mts +70 -0
  14. package/dist/docs-cloud-server.mjs +310 -0
  15. package/dist/{doctor-VwhpJct8.mjs → doctor-O9o9kjN8.mjs} +7 -7
  16. package/dist/{downgrade-ghVFFHKi.mjs → downgrade-7PGER59g.mjs} +2 -2
  17. package/dist/index.d.mts +2 -2
  18. package/dist/index.mjs +4 -3
  19. package/dist/{init-DkcasCws.mjs → init-Ds7QM9po.mjs} +3 -3
  20. package/dist/{mcp-DfJiBC0f.mjs → mcp-DuCPNHS-.mjs} +4 -4
  21. package/dist/mcp.d.mts +1 -1
  22. package/dist/mcp.mjs +3 -2
  23. package/dist/{package-version-CeNAB4NZ.mjs → package-version-DPQSBBsX.mjs} +1 -1
  24. package/dist/{review-Bnd4NH9y.mjs → review-lm3dt7yy.mjs} +2 -2
  25. package/dist/{robots-BrBGgn1w.mjs → robots-DV7u4Ire.mjs} +4 -4
  26. package/dist/{robots-CVoC0w0i.mjs → robots-XVPs9lVz.mjs} +1 -1
  27. package/dist/{search-CA3H4Dfv.mjs → search-B6nEkx86.mjs} +4 -4
  28. package/dist/{search-BuOU4idW.mjs → search-BWuU70B0.mjs} +2 -306
  29. package/dist/{search-BEe1Gdu7.d.mts → search-DFEhf9-s.d.mts} +1 -1
  30. package/dist/server.d.mts +5 -23
  31. package/dist/server.mjs +8 -5
  32. package/dist/{sitemap-CUtSSoGG.mjs → sitemap-BEiKy4Iy.mjs} +5 -5
  33. package/dist/{sitemap-server-PLcNxmtk.mjs → sitemap-server-xEHtDUDB.mjs} +2 -382
  34. package/dist/{types-DKCNILor.d.mts → types-XqGLsmOD.d.mts} +17 -0
  35. package/dist/{upgrade-aexO-zom.mjs → upgrade-CkdKWRlk.mjs} +2 -2
  36. package/package.json +21 -1
  37. /package/dist/{agent-B6szuz_8.mjs → agent-CaOBIVFy.mjs} +0 -0
  38. /package/dist/{config-De5z-2LK.mjs → config-tiQCZ46q.mjs} +0 -0
  39. /package/dist/{errors-Dw5gMhEZ.mjs → errors-CW1LnxaQ.mjs} +0 -0
  40. /package/dist/{review-CJD85JTm.mjs → review-B7goPYUb.mjs} +0 -0
  41. /package/dist/{templates-BOoV0cIR.mjs → templates-CEcOVbV0.mjs} +0 -0
  42. /package/dist/{utils-CoHZJ1i4.mjs → utils-D-xTRNuh.mjs} +0 -0
@@ -1,5 +1,4 @@
1
- import { F as emitDocsAnalyticsEvent } from "./search-BuOU4idW.mjs";
2
- import { kt as resolveDocsSitemapConfig } from "./agent-B6szuz_8.mjs";
1
+ import { kt as resolveDocsSitemapConfig } from "./agent-CaOBIVFy.mjs";
3
2
  import { createRequire } from "node:module";
4
3
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
5
4
  import path, { basename, join, relative } from "node:path";
@@ -959,385 +958,6 @@ function humanizeSegment(value) {
959
958
  return value.replace(/^\{/, "").replace(/\}$/, "").replace(/^\[\[?\.{3}/, "").replace(/^\[/, "").replace(/\]\]?$/, "").replace(/^\$/, "").replace(/-/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
960
959
  }
961
960
 
962
- //#endregion
963
- //#region src/cloud-ask-ai.ts
964
- const DEFAULT_DOCS_CLOUD_API_BASE_URL = "https://api.farming-labs.dev";
965
- const DEFAULT_DOCS_CLOUD_API_KEY_ENV = "DOCS_CLOUD_API_KEY";
966
- const DOCS_CLOUD_PROJECT_ID_ENVS = [
967
- "PUBLIC_DOCS_CLOUD_PROJECT_ID",
968
- "DOCS_CLOUD_PROJECT_ID",
969
- "NEXT_PUBLIC_DOCS_CLOUD_PROJECT_ID"
970
- ];
971
- const DOCS_CLOUD_API_BASE_URL_ENVS = [
972
- "DOCS_CLOUD_API_BASE_URL",
973
- "DOCS_CLOUD_API_URL",
974
- "PUBLIC_DOCS_CLOUD_URL",
975
- "NEXT_PUBLIC_DOCS_CLOUD_URL"
976
- ];
977
- const DOCS_CLOUD_FOOTER_GUARD_CHARS = 256;
978
- const docsCloudRelevantDocsPattern = /\n{2,}(?:-{3,}|\*{3,}|_{3,})[ \t]*\n{1,3}(?:#{1,6}[ \t]+)?(?:\*\*)?Relevant docs(?:\*\*)?[ \t]*/i;
979
- const docsCloudThematicBreakPattern = /^[ \t]*(?:-{3,}|\*{3,}|_{3,})[ \t]*$/gm;
980
- function isPlainObject(value) {
981
- return typeof value === "object" && value !== null && !Array.isArray(value);
982
- }
983
- function readEnv(name, env) {
984
- const trimmed = (env?.[name] ?? (typeof process !== "undefined" ? process.env?.[name] : void 0))?.trim();
985
- return trimmed ? trimmed : void 0;
986
- }
987
- function readFirstEnv(names, env) {
988
- for (const name of names) {
989
- const value = readEnv(name, env);
990
- if (value) return value;
991
- }
992
- }
993
- function resolveDocsCloudApiBaseUrl(env) {
994
- return (readFirstEnv(DOCS_CLOUD_API_BASE_URL_ENVS, env) ?? DEFAULT_DOCS_CLOUD_API_BASE_URL).replace(/\/+$/, "");
995
- }
996
- function resolveDocsCloudProjectId(env) {
997
- return readFirstEnv(DOCS_CLOUD_PROJECT_ID_ENVS, env);
998
- }
999
- function resolveDocsCloudApiKey(cloudConfig, env) {
1000
- const envName = cloudConfig?.apiKey?.env?.trim() || DEFAULT_DOCS_CLOUD_API_KEY_ENV;
1001
- return {
1002
- envName,
1003
- apiKey: readEnv(envName, env)
1004
- };
1005
- }
1006
- function jsonError(message, status) {
1007
- return Response.json({ error: message }, { status });
1008
- }
1009
- function textFromMessageContent(content) {
1010
- if (typeof content === "string") return content;
1011
- if (!Array.isArray(content)) return "";
1012
- return content.map((part) => {
1013
- if (typeof part === "string") return part;
1014
- if (!isPlainObject(part)) return "";
1015
- if (typeof part.text === "string") return part.text;
1016
- if (typeof part.content === "string") return part.content;
1017
- return "";
1018
- }).filter(Boolean).join("\n");
1019
- }
1020
- function lastUserQuestion(messages) {
1021
- if (!Array.isArray(messages)) return "";
1022
- return textFromMessageContent([...messages].reverse().find((message) => message?.role === "user")?.content).trim();
1023
- }
1024
- function resolveQuestion(body) {
1025
- return typeof body.question === "string" && body.question.trim() ? body.question.trim() : lastUserQuestion(body.messages);
1026
- }
1027
- function shouldStreamResponse(request, body, aiConfig) {
1028
- if (typeof body.stream === "boolean") return body.stream;
1029
- if (aiConfig?.stream === false) return false;
1030
- const accept = request.headers.get("accept")?.toLowerCase();
1031
- return !accept || accept.includes("text/event-stream") || accept.includes("*/*");
1032
- }
1033
- function stripRelevantDocsFooter(content) {
1034
- return content.replace(new RegExp(`${docsCloudRelevantDocsPattern.source}[\\s\\S]*$`, "i"), "").trimEnd();
1035
- }
1036
- function stripMarkdownThematicBreaks(content) {
1037
- return content.replace(docsCloudThematicBreakPattern, "").replace(/\n{3,}/g, "\n\n").trimEnd();
1038
- }
1039
- function cleanDocsCloudAnswer(content) {
1040
- return stripMarkdownThematicBreaks(stripRelevantDocsFooter(content));
1041
- }
1042
- function safeDocsCloudContent(content, final = false) {
1043
- const footerStart = content.search(docsCloudRelevantDocsPattern);
1044
- if (footerStart >= 0) return stripMarkdownThematicBreaks(content.slice(0, footerStart));
1045
- if (final) return cleanDocsCloudAnswer(content);
1046
- return stripMarkdownThematicBreaks(content.slice(0, Math.max(0, content.length - DOCS_CLOUD_FOOTER_GUARD_CHARS)));
1047
- }
1048
- function createOpenAICompatibleSseChunk(content) {
1049
- return `data: ${JSON.stringify({ choices: [{ delta: { content } }] })}\n\n`;
1050
- }
1051
- function createOpenAICompatibleSseResponse(content) {
1052
- const encoder = new TextEncoder();
1053
- const stream = new ReadableStream({ start(controller) {
1054
- if (content) controller.enqueue(encoder.encode(createOpenAICompatibleSseChunk(content)));
1055
- controller.enqueue(encoder.encode("data: [DONE]\n\n"));
1056
- controller.close();
1057
- } });
1058
- return new Response(stream, { headers: {
1059
- "Content-Type": "text/event-stream",
1060
- "Cache-Control": "no-cache, no-transform",
1061
- Connection: "keep-alive"
1062
- } });
1063
- }
1064
- function openAICompatibleDeltaContent(value) {
1065
- if (!isPlainObject(value)) return void 0;
1066
- const firstChoice = Array.isArray(value.choices) ? value.choices[0] : void 0;
1067
- if (!isPlainObject(firstChoice) || !isPlainObject(firstChoice.delta)) return void 0;
1068
- return typeof firstChoice.delta.content === "string" ? firstChoice.delta.content : void 0;
1069
- }
1070
- function docsCloudStreamContent(value) {
1071
- if (typeof value === "string") return value;
1072
- if (!isPlainObject(value)) return void 0;
1073
- for (const key of [
1074
- "content",
1075
- "text",
1076
- "answer",
1077
- "delta"
1078
- ]) {
1079
- const content = value[key];
1080
- if (typeof content === "string") return content;
1081
- }
1082
- }
1083
- function docsCloudAnswerFromPayload(payload) {
1084
- if (!isPlainObject(payload)) return "";
1085
- for (const key of [
1086
- "answer",
1087
- "text",
1088
- "content"
1089
- ]) {
1090
- const content = payload[key];
1091
- if (typeof content === "string") return content;
1092
- }
1093
- return "";
1094
- }
1095
- function createCleanDocsCloudSseResponse(upstream) {
1096
- if (!upstream.ok || !upstream.body) return new Response(upstream.body, {
1097
- status: upstream.status,
1098
- statusText: upstream.statusText,
1099
- headers: {
1100
- "Content-Type": upstream.headers.get("Content-Type") ?? "text/event-stream",
1101
- "Cache-Control": upstream.headers.get("Cache-Control") ?? "no-cache, no-transform",
1102
- Connection: upstream.headers.get("Connection") ?? "keep-alive"
1103
- }
1104
- });
1105
- const decoder = new TextDecoder();
1106
- const encoder = new TextEncoder();
1107
- const stream = new ReadableStream({ async start(controller) {
1108
- const reader = upstream.body.getReader();
1109
- let buffer = "";
1110
- let content = "";
1111
- let emittedLength = 0;
1112
- const enqueue = (chunk) => {
1113
- controller.enqueue(encoder.encode(chunk));
1114
- };
1115
- const emitSafeContent = (final = false) => {
1116
- const safeContent = safeDocsCloudContent(content, final);
1117
- if (safeContent.length <= emittedLength) return;
1118
- enqueue(createOpenAICompatibleSseChunk(safeContent.slice(emittedLength)));
1119
- emittedLength = safeContent.length;
1120
- };
1121
- const flushEvent = (event) => {
1122
- const data = event.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim()).filter(Boolean).join("\n").trim();
1123
- if (!data) return;
1124
- if (data === "[DONE]") return;
1125
- try {
1126
- const parsed = JSON.parse(data);
1127
- const delta = openAICompatibleDeltaContent(parsed) ?? docsCloudStreamContent(parsed);
1128
- if (delta) {
1129
- content += delta;
1130
- emitSafeContent();
1131
- }
1132
- } catch {
1133
- content += data;
1134
- emitSafeContent();
1135
- }
1136
- };
1137
- try {
1138
- while (true) {
1139
- const { value, done } = await reader.read();
1140
- if (done) break;
1141
- buffer += decoder.decode(value, { stream: true });
1142
- const events = buffer.split(/\r?\n\r?\n/);
1143
- buffer = events.pop() ?? "";
1144
- for (const event of events) flushEvent(event);
1145
- }
1146
- buffer += decoder.decode();
1147
- if (buffer.trim()) flushEvent(buffer);
1148
- } catch {}
1149
- emitSafeContent(true);
1150
- enqueue("data: [DONE]\n\n");
1151
- controller.close();
1152
- } });
1153
- return new Response(stream, {
1154
- status: upstream.status,
1155
- statusText: upstream.statusText,
1156
- headers: {
1157
- "Content-Type": "text/event-stream",
1158
- "Cache-Control": upstream.headers.get("Cache-Control") ?? "no-cache, no-transform",
1159
- Connection: upstream.headers.get("Connection") ?? "keep-alive"
1160
- }
1161
- });
1162
- }
1163
- function analyticsProperties(request) {
1164
- const userAgent = request.headers.get("user-agent")?.trim();
1165
- return userAgent ? { userAgent } : {};
1166
- }
1167
- function isDocsCloudAskAIProvider(config) {
1168
- return config?.enabled === true && config.provider === "docs-cloud";
1169
- }
1170
- async function createDocsCloudAskAIResponse(request, options = {}) {
1171
- const config = options.config;
1172
- const aiConfig = config?.ai;
1173
- const analytics = config?.analytics;
1174
- const requestUrl = new URL(request.url);
1175
- const requestStartedAt = Date.now();
1176
- const requestProperties = analyticsProperties(request);
1177
- let body;
1178
- try {
1179
- body = await request.json();
1180
- } catch {
1181
- await emitDocsAnalyticsEvent(analytics, {
1182
- type: "api_ai_error",
1183
- source: "server",
1184
- url: request.url,
1185
- path: requestUrl.pathname,
1186
- locale: options.locale,
1187
- properties: {
1188
- ...requestProperties,
1189
- reason: "invalid_json",
1190
- provider: "docs-cloud",
1191
- durationMs: Math.max(0, Date.now() - requestStartedAt)
1192
- }
1193
- });
1194
- return jsonError("Invalid JSON body. Expected { messages: [...] }.", 400);
1195
- }
1196
- const question = resolveQuestion(body);
1197
- const messages = Array.isArray(body.messages) ? body.messages : void 0;
1198
- if (!question) {
1199
- await emitDocsAnalyticsEvent(analytics, {
1200
- type: "api_ai_error",
1201
- source: "server",
1202
- url: request.url,
1203
- path: requestUrl.pathname,
1204
- locale: options.locale,
1205
- properties: {
1206
- ...requestProperties,
1207
- reason: "missing_user_message",
1208
- provider: "docs-cloud",
1209
- durationMs: Math.max(0, Date.now() - requestStartedAt)
1210
- }
1211
- });
1212
- return jsonError("At least one user message is required.", 400);
1213
- }
1214
- const projectId = resolveDocsCloudProjectId(options.env);
1215
- const { envName, apiKey } = resolveDocsCloudApiKey(config?.cloud, options.env);
1216
- if (!projectId || !apiKey) {
1217
- const reason = !projectId ? "missing_docs_cloud_project_id" : "missing_docs_cloud_api_key";
1218
- await emitDocsAnalyticsEvent(analytics, {
1219
- type: "api_ai_error",
1220
- source: "server",
1221
- url: request.url,
1222
- path: requestUrl.pathname,
1223
- locale: options.locale,
1224
- input: { question },
1225
- properties: {
1226
- ...requestProperties,
1227
- reason,
1228
- provider: "docs-cloud",
1229
- envName: !apiKey ? envName : void 0,
1230
- durationMs: Math.max(0, Date.now() - requestStartedAt)
1231
- }
1232
- });
1233
- return jsonError(!projectId ? `Docs Cloud Ask AI is missing ${DOCS_CLOUD_PROJECT_ID_ENVS.join(" or ")}. Add the project id to the deployment environment.` : `Docs Cloud Ask AI is missing ${envName}. Add it to the deployment environment.`, 500);
1234
- }
1235
- const stream = shouldStreamResponse(request, body, aiConfig);
1236
- const apiBaseUrl = resolveDocsCloudApiBaseUrl(options.env);
1237
- const publicBaseUrl = aiConfig?.docsUrl ?? options.publicBaseUrl ?? requestUrl.origin;
1238
- const requestedModel = typeof body.model === "string" && body.model.trim() ? body.model.trim() : void 0;
1239
- await emitDocsAnalyticsEvent(analytics, {
1240
- type: "api_ai_request",
1241
- source: "server",
1242
- url: request.url,
1243
- path: requestUrl.pathname,
1244
- locale: options.locale,
1245
- input: { question },
1246
- properties: {
1247
- ...requestProperties,
1248
- provider: "docs-cloud",
1249
- messageCount: messages?.length,
1250
- questionLength: question.length,
1251
- model: requestedModel ?? "docs-cloud"
1252
- }
1253
- });
1254
- let upstream;
1255
- try {
1256
- upstream = await (options.fetch ?? fetch)(`${apiBaseUrl}/v1/projects/${encodeURIComponent(projectId)}/knowledge/ask`, {
1257
- method: "POST",
1258
- headers: {
1259
- Accept: stream ? "text/event-stream, application/json" : "application/json",
1260
- Authorization: `Bearer ${apiKey}`,
1261
- "Content-Type": "application/json",
1262
- "X-Docs-Cloud-Public-Base-Url": publicBaseUrl
1263
- },
1264
- body: JSON.stringify({
1265
- messages,
1266
- question,
1267
- answerMode: "auto",
1268
- answerStyle: "public",
1269
- modelPreference: requestedModel,
1270
- stream,
1271
- publicBaseUrl
1272
- })
1273
- });
1274
- } catch {
1275
- await emitDocsAnalyticsEvent(analytics, {
1276
- type: "api_ai_error",
1277
- source: "server",
1278
- url: request.url,
1279
- path: requestUrl.pathname,
1280
- locale: options.locale,
1281
- input: { question },
1282
- properties: {
1283
- ...requestProperties,
1284
- reason: "docs_cloud_fetch_error",
1285
- provider: "docs-cloud",
1286
- durationMs: Math.max(0, Date.now() - requestStartedAt)
1287
- }
1288
- });
1289
- return jsonError("Docs Cloud Ask AI request failed.", 502);
1290
- }
1291
- if (!upstream.ok) {
1292
- await upstream.text().catch(() => "");
1293
- await emitDocsAnalyticsEvent(analytics, {
1294
- type: "api_ai_error",
1295
- source: "server",
1296
- url: request.url,
1297
- path: requestUrl.pathname,
1298
- locale: options.locale,
1299
- input: { question },
1300
- properties: {
1301
- ...requestProperties,
1302
- reason: "docs_cloud_error",
1303
- provider: "docs-cloud",
1304
- status: upstream.status,
1305
- durationMs: Math.max(0, Date.now() - requestStartedAt)
1306
- }
1307
- });
1308
- return jsonError(`Docs Cloud Ask AI error (${upstream.status}).`, 502);
1309
- }
1310
- await emitDocsAnalyticsEvent(analytics, {
1311
- type: "api_ai_response",
1312
- source: "server",
1313
- url: request.url,
1314
- path: requestUrl.pathname,
1315
- locale: options.locale,
1316
- input: { question },
1317
- properties: {
1318
- ...requestProperties,
1319
- provider: "docs-cloud",
1320
- status: upstream.status,
1321
- durationMs: Math.max(0, Date.now() - requestStartedAt)
1322
- }
1323
- });
1324
- const contentType = upstream.headers.get("Content-Type") ?? "";
1325
- if (stream && contentType.includes("text/event-stream")) return createCleanDocsCloudSseResponse(upstream);
1326
- const upstreamBody = await upstream.text();
1327
- let payload;
1328
- let answer = upstreamBody;
1329
- try {
1330
- payload = JSON.parse(upstreamBody);
1331
- answer = docsCloudAnswerFromPayload(payload) || answer;
1332
- } catch {}
1333
- const cleanAnswer = cleanDocsCloudAnswer(answer);
1334
- if (stream) return createOpenAICompatibleSseResponse(cleanAnswer);
1335
- return Response.json(isPlainObject(payload) ? {
1336
- ...payload,
1337
- answer: cleanAnswer
1338
- } : { answer: cleanAnswer });
1339
- }
1340
-
1341
961
  //#endregion
1342
962
  //#region src/prompt-utils.ts
1343
963
  const require = createRequire(import.meta.url);
@@ -1513,4 +1133,4 @@ function readDocsSitemapManifest(rootDir, sitemap) {
1513
1133
  }
1514
1134
 
1515
1135
  //#endregion
1516
- export { isApiReferenceOpenApiRequest as C, remarkCodeGroup as D, resolveApiReferenceRenderer as E, buildApiReferenceScalarCss as S, resolveApiReferenceOpenApiDiscovery as T, buildApiReferenceHtmlDocument as _, DEFAULT_PROMPT_PROVIDER_TEMPLATES as a, buildApiReferenceOpenApiDocumentAsync as b, resolvePromptProviderChoices as c, serializeDocsIconRegistry as d, serializeOpenDocsProvider as f, DEFAULT_API_REFERENCE_OPENAPI_ROUTE as g, isDocsCloudAskAIProvider as h, DEFAULT_OPEN_DOCS_TARGET as i, sanitizePromptText as l, createDocsCloudAskAIResponse as m, DEFAULT_OPEN_DOCS_PROMPT as n, normalizePromptProviderName as o, serializeOpenDocsProviders as p, DEFAULT_OPEN_DOCS_PROVIDER_IDS as r, parsePromptStringArray as s, readDocsSitemapManifest as t, serializeDocsIcon as u, buildApiReferenceHtmlDocumentAsync as v, resolveApiReferenceConfig as w, buildApiReferencePageTitle as x, buildApiReferenceOpenApiDocument as y };
1136
+ export { resolveApiReferenceOpenApiDiscovery as C, resolveApiReferenceConfig as S, remarkCodeGroup as T, buildApiReferenceOpenApiDocument as _, DEFAULT_PROMPT_PROVIDER_TEMPLATES as a, buildApiReferenceScalarCss as b, resolvePromptProviderChoices as c, serializeDocsIconRegistry as d, serializeOpenDocsProvider as f, buildApiReferenceHtmlDocumentAsync as g, buildApiReferenceHtmlDocument as h, DEFAULT_OPEN_DOCS_TARGET as i, sanitizePromptText as l, DEFAULT_API_REFERENCE_OPENAPI_ROUTE as m, DEFAULT_OPEN_DOCS_PROMPT as n, normalizePromptProviderName as o, serializeOpenDocsProviders as p, DEFAULT_OPEN_DOCS_PROVIDER_IDS as r, parsePromptStringArray as s, readDocsSitemapManifest as t, serializeDocsIcon as u, buildApiReferenceOpenApiDocumentAsync as v, resolveApiReferenceRenderer as w, isApiReferenceOpenApiRequest as x, buildApiReferencePageTitle as y };
@@ -766,6 +766,12 @@ interface DocsAnalyticsConfig {
766
766
  includeInputs?: boolean;
767
767
  /** Callback fired for every emitted event. */
768
768
  onEvent?: (event: DocsAnalyticsEvent) => void | Promise<void>;
769
+ /**
770
+ * Forward events to Docs Cloud when project env vars are available.
771
+ *
772
+ * @default true
773
+ */
774
+ cloud?: boolean;
769
775
  }
770
776
  type DocsTelemetryFramework = "next" | "tanstack-start" | "sveltekit" | "astro" | "nuxt" | "mcp" | (string & {});
771
777
  type DocsTelemetryEventType = "project_detected" | "agent_surface_used" | "mcp_request" | "mcp_tool_used" | (string & {});
@@ -873,6 +879,17 @@ interface DocsCloudConfig {
873
879
  enabled?: boolean;
874
880
  /** API key lookup used by `docs deploy` and other cloud CLI commands. */
875
881
  apiKey?: DocsCloudApiKeyConfig;
882
+ /**
883
+ * Same-origin route for the generated Docs API handler.
884
+ *
885
+ * Next.js layouts use this as the default client analytics proxy when no
886
+ * hosted analytics endpoint env is configured. Set it when the route is
887
+ * mounted somewhere other than `/api/docs`, or when a deployment uses a
888
+ * public base path.
889
+ *
890
+ * @default "/api/docs"
891
+ */
892
+ apiRoute?: string;
876
893
  /** Legacy hosted preview deployment settings. Prefer `deploy` in new configs. */
877
894
  preview?: DocsCloudPreviewConfig;
878
895
  /** Generated docs publishing settings. */
@@ -1,5 +1,5 @@
1
- import { c as fileExists, o as exec } from "./utils-CoHZJ1i4.mjs";
2
- import { a as getPackagesForFramework, c as resolveDocsPackageManager, i as frameworkFromPreset, l as validateUpgradeVersion, n as PRESETS, o as presetFromFramework, r as buildDocsPackageInstallCommand, s as resolveDocsPackageFramework, t as PACKAGES_BY_FRAMEWORK } from "./package-version-CeNAB4NZ.mjs";
1
+ import { c as fileExists, o as exec } from "./utils-D-xTRNuh.mjs";
2
+ import { a as getPackagesForFramework, c as resolveDocsPackageManager, i as frameworkFromPreset, l as validateUpgradeVersion, n as PRESETS, o as presetFromFramework, r as buildDocsPackageInstallCommand, s as resolveDocsPackageFramework, t as PACKAGES_BY_FRAMEWORK } from "./package-version-DPQSBBsX.mjs";
3
3
  import path from "node:path";
4
4
  import pc from "picocolors";
5
5
  import * as p from "@clack/prompts";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/docs",
3
- "version": "0.2.41",
3
+ "version": "0.2.43",
4
4
  "description": "Modern, flexible MDX-based docs framework — core types, config, and CLI",
5
5
  "keywords": [
6
6
  "docs",
@@ -30,6 +30,16 @@
30
30
  "import": "./dist/server.mjs",
31
31
  "default": "./dist/server.mjs"
32
32
  },
33
+ "./cloud/server": {
34
+ "types": "./dist/docs-cloud-server.d.mts",
35
+ "import": "./dist/docs-cloud-server.mjs",
36
+ "default": "./dist/docs-cloud-server.mjs"
37
+ },
38
+ "./client/react": {
39
+ "types": "./dist/client/react.d.mts",
40
+ "import": "./dist/client/react.mjs",
41
+ "default": "./dist/client/react.mjs"
42
+ },
33
43
  "./mcp": {
34
44
  "types": "./dist/mcp.d.mts",
35
45
  "import": "./dist/mcp.mjs",
@@ -46,8 +56,18 @@
46
56
  "picocolors": "^1.1.1",
47
57
  "zod": "^4.3.6"
48
58
  },
59
+ "peerDependencies": {
60
+ "react": ">=19.2.0"
61
+ },
62
+ "peerDependenciesMeta": {
63
+ "react": {
64
+ "optional": true
65
+ }
66
+ },
49
67
  "devDependencies": {
50
68
  "@types/node": "^22.10.0",
69
+ "@types/react": "^19.2.2",
70
+ "react": "^19.2.0",
51
71
  "tsdown": "^0.20.3",
52
72
  "typescript": "^5.9.3",
53
73
  "vitest": "^4.1.8"
File without changes
File without changes