@farming-labs/docs 0.2.62 → 0.2.63

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 (58) hide show
  1. package/dist/agent-CQTH7NFu.mjs +624 -0
  2. package/dist/agent-DKKptIgy.mjs +4365 -0
  3. package/dist/agent-evals-B7MIxuEX.mjs +2144 -0
  4. package/dist/agent-export-CBgWgPvH.mjs +910 -0
  5. package/dist/agent-scope-C_U--OZ7.mjs +283 -0
  6. package/dist/agent-skills-bundle.d.mts +13 -0
  7. package/dist/agent-skills-bundle.mjs +12 -0
  8. package/dist/agent-skills-server-CPja6Syt.d.mts +14 -0
  9. package/dist/agent-skills-server-DraIb6FV.mjs +415 -0
  10. package/dist/agent-skills-vite.d.mts +31 -0
  11. package/dist/agent-skills-vite.mjs +70 -0
  12. package/dist/agents-XWZBub6f.mjs +221 -0
  13. package/dist/analytics-Bx44lg6d.mjs +177 -0
  14. package/dist/cli/index.d.mts +15 -0
  15. package/dist/cli/index.mjs +452 -0
  16. package/dist/client/react.d.mts +45 -0
  17. package/dist/client/react.mjs +223 -0
  18. package/dist/cloud-analytics-CSyFE6SS.mjs +132 -0
  19. package/dist/cloud-ask-ai-sbpjOR2K.mjs +382 -0
  20. package/dist/cloud-ask-ai-zpwkdwnF.d.mts +23 -0
  21. package/dist/cloud-pdNC-tyj.mjs +1615 -0
  22. package/dist/code-blocks-DnNVNK2M.mjs +871 -0
  23. package/dist/codeblocks-CFuurVIH.mjs +250 -0
  24. package/dist/config-Wcdj-D0a.mjs +369 -0
  25. package/dist/dev-Cmy6DtdF.mjs +1333 -0
  26. package/dist/docs-cloud-server.d.mts +70 -0
  27. package/dist/docs-cloud-server.mjs +310 -0
  28. package/dist/doctor-CJqtzKZT.mjs +2036 -0
  29. package/dist/downgrade-w7e6Se0L.mjs +184 -0
  30. package/dist/errors-DbOhkE1h.mjs +20 -0
  31. package/dist/golden-evaluations-Dsvh0etV.mjs +1503 -0
  32. package/dist/i18n-CCaFUnAN.mjs +40 -0
  33. package/dist/index.d.mts +1150 -0
  34. package/dist/index.mjs +10 -0
  35. package/dist/init-CQY0Woe3.mjs +1264 -0
  36. package/dist/mcp-B9dcsivk.mjs +156 -0
  37. package/dist/mcp.d.mts +298 -0
  38. package/dist/mcp.mjs +4430 -0
  39. package/dist/metadata-DWExHQnx.mjs +237 -0
  40. package/dist/package-version-n5AFur8a.mjs +128 -0
  41. package/dist/reading-time-CYZ5VvKU.mjs +742 -0
  42. package/dist/review-Fndl5brR.mjs +673 -0
  43. package/dist/robots-BIpC4j4P.mjs +201 -0
  44. package/dist/robots-CUTahhoY.mjs +179 -0
  45. package/dist/search-B6V6qtiI.mjs +1826 -0
  46. package/dist/search-CaSyi6H6.d.mts +279 -0
  47. package/dist/search-DSjCeOk7.mjs +104 -0
  48. package/dist/server.d.mts +343 -0
  49. package/dist/server.mjs +14 -0
  50. package/dist/sitemap-Cykpe3Tz.mjs +249 -0
  51. package/dist/sitemap-server-C_6Wes83.mjs +1137 -0
  52. package/dist/standards-discovery-C4HUqMd2.d.mts +227 -0
  53. package/dist/standards-discovery-jkykaXq1.mjs +519 -0
  54. package/dist/templates-Bq_P7ctv.mjs +2465 -0
  55. package/dist/types-lMBIdZg0.d.mts +3315 -0
  56. package/dist/upgrade-oz-GChgt.mjs +56 -0
  57. package/dist/utils-DpiIioYb.mjs +225 -0
  58. package/package.json +1 -1
@@ -0,0 +1,382 @@
1
+ import { a as emitDocsAnalyticsEvent } from "./analytics-Bx44lg6d.mjs";
2
+
3
+ //#region src/cloud-ask-ai.ts
4
+ const DEFAULT_DOCS_CLOUD_API_BASE_URL = "https://api.farming-labs.dev";
5
+ const DEFAULT_DOCS_CLOUD_API_KEY_ENV = "DOCS_CLOUD_API_KEY";
6
+ const DOCS_CLOUD_PROJECT_ID_ENVS = [
7
+ "PUBLIC_DOCS_CLOUD_PROJECT_ID",
8
+ "DOCS_CLOUD_PROJECT_ID",
9
+ "NEXT_PUBLIC_DOCS_CLOUD_PROJECT_ID"
10
+ ];
11
+ const DOCS_CLOUD_API_BASE_URL_ENVS = [
12
+ "DOCS_CLOUD_API_BASE_URL",
13
+ "DOCS_CLOUD_API_URL",
14
+ "PUBLIC_DOCS_CLOUD_URL",
15
+ "NEXT_PUBLIC_DOCS_CLOUD_URL"
16
+ ];
17
+ const DOCS_CLOUD_FOOTER_GUARD_CHARS = 256;
18
+ const docsCloudRelevantDocsPattern = /\n{2,}(?:-{3,}|\*{3,}|_{3,})[ \t]*\n{1,3}(?:#{1,6}[ \t]+)?(?:\*\*)?Relevant docs(?:\*\*)?[ \t]*/i;
19
+ const docsCloudThematicBreakPattern = /^[ \t]*(?:-{3,}|\*{3,}|_{3,})[ \t]*$/gm;
20
+ function isPlainObject(value) {
21
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22
+ }
23
+ function readEnv(name, env) {
24
+ const trimmed = (env?.[name] ?? (typeof process !== "undefined" ? process.env?.[name] : void 0))?.trim();
25
+ return trimmed ? trimmed : void 0;
26
+ }
27
+ function readFirstEnv(names, env) {
28
+ for (const name of names) {
29
+ const value = readEnv(name, env);
30
+ if (value) return value;
31
+ }
32
+ }
33
+ function resolveDocsCloudApiBaseUrl(env) {
34
+ return (readFirstEnv(DOCS_CLOUD_API_BASE_URL_ENVS, env) ?? DEFAULT_DOCS_CLOUD_API_BASE_URL).replace(/\/+$/, "");
35
+ }
36
+ function resolveDocsCloudProjectId(env) {
37
+ return readFirstEnv(DOCS_CLOUD_PROJECT_ID_ENVS, env);
38
+ }
39
+ function resolveDocsCloudApiKey(cloudConfig, env) {
40
+ const envName = cloudConfig?.apiKey?.env?.trim() || DEFAULT_DOCS_CLOUD_API_KEY_ENV;
41
+ return {
42
+ envName,
43
+ apiKey: readEnv(envName, env)
44
+ };
45
+ }
46
+ function jsonError(message, status) {
47
+ return Response.json({ error: message }, { status });
48
+ }
49
+ function textFromMessageContent(content) {
50
+ if (typeof content === "string") return content;
51
+ if (!Array.isArray(content)) return "";
52
+ return content.map((part) => {
53
+ if (typeof part === "string") return part;
54
+ if (!isPlainObject(part)) return "";
55
+ if (typeof part.text === "string") return part.text;
56
+ if (typeof part.content === "string") return part.content;
57
+ return "";
58
+ }).filter(Boolean).join("\n");
59
+ }
60
+ function lastUserQuestion(messages) {
61
+ if (!Array.isArray(messages)) return "";
62
+ return textFromMessageContent([...messages].reverse().find((message) => message?.role === "user")?.content).trim();
63
+ }
64
+ function resolveQuestion(body) {
65
+ return typeof body.question === "string" && body.question.trim() ? body.question.trim() : lastUserQuestion(body.messages);
66
+ }
67
+ function shouldStreamResponse(request, body, aiConfig) {
68
+ if (typeof body.stream === "boolean") return body.stream;
69
+ if (aiConfig?.stream === false) return false;
70
+ const accept = request.headers.get("accept")?.toLowerCase();
71
+ return !accept || accept.includes("text/event-stream") || accept.includes("*/*");
72
+ }
73
+ function stripRelevantDocsFooter(content) {
74
+ return content.replace(new RegExp(`${docsCloudRelevantDocsPattern.source}[\\s\\S]*$`, "i"), "").trimEnd();
75
+ }
76
+ function stripMarkdownThematicBreaks(content) {
77
+ return content.replace(docsCloudThematicBreakPattern, "").replace(/\n{3,}/g, "\n\n").trimEnd();
78
+ }
79
+ function cleanDocsCloudAnswer(content) {
80
+ return stripMarkdownThematicBreaks(stripRelevantDocsFooter(content));
81
+ }
82
+ function safeDocsCloudContent(content, final = false) {
83
+ const footerStart = content.search(docsCloudRelevantDocsPattern);
84
+ if (footerStart >= 0) return stripMarkdownThematicBreaks(content.slice(0, footerStart));
85
+ if (final) return cleanDocsCloudAnswer(content);
86
+ return stripMarkdownThematicBreaks(content.slice(0, Math.max(0, content.length - DOCS_CLOUD_FOOTER_GUARD_CHARS)));
87
+ }
88
+ function createOpenAICompatibleSseChunk(content) {
89
+ return `data: ${JSON.stringify({ choices: [{ delta: { content } }] })}\n\n`;
90
+ }
91
+ function createOpenAICompatibleSseResponse(content) {
92
+ const encoder = new TextEncoder();
93
+ const stream = new ReadableStream({ start(controller) {
94
+ if (content) controller.enqueue(encoder.encode(createOpenAICompatibleSseChunk(content)));
95
+ controller.enqueue(encoder.encode("data: [DONE]\n\n"));
96
+ controller.close();
97
+ } });
98
+ return new Response(stream, { headers: {
99
+ "Content-Type": "text/event-stream",
100
+ "Cache-Control": "no-cache, no-transform",
101
+ Connection: "keep-alive"
102
+ } });
103
+ }
104
+ function openAICompatibleDeltaContent(value) {
105
+ if (!isPlainObject(value)) return void 0;
106
+ const firstChoice = Array.isArray(value.choices) ? value.choices[0] : void 0;
107
+ if (!isPlainObject(firstChoice) || !isPlainObject(firstChoice.delta)) return void 0;
108
+ return typeof firstChoice.delta.content === "string" ? firstChoice.delta.content : void 0;
109
+ }
110
+ function docsCloudStreamContent(value) {
111
+ if (typeof value === "string") return value;
112
+ if (!isPlainObject(value)) return void 0;
113
+ for (const key of [
114
+ "content",
115
+ "text",
116
+ "answer",
117
+ "delta"
118
+ ]) {
119
+ const content = value[key];
120
+ if (typeof content === "string") return content;
121
+ }
122
+ }
123
+ function docsCloudAnswerFromPayload(payload) {
124
+ if (!isPlainObject(payload)) return "";
125
+ for (const key of [
126
+ "answer",
127
+ "text",
128
+ "content"
129
+ ]) {
130
+ const content = payload[key];
131
+ if (typeof content === "string") return content;
132
+ }
133
+ return "";
134
+ }
135
+ function createCleanDocsCloudSseResponse(upstream) {
136
+ if (!upstream.ok || !upstream.body) return new Response(upstream.body, {
137
+ status: upstream.status,
138
+ statusText: upstream.statusText,
139
+ headers: {
140
+ "Content-Type": upstream.headers.get("Content-Type") ?? "text/event-stream",
141
+ "Cache-Control": upstream.headers.get("Cache-Control") ?? "no-cache, no-transform",
142
+ Connection: upstream.headers.get("Connection") ?? "keep-alive"
143
+ }
144
+ });
145
+ const decoder = new TextDecoder();
146
+ const encoder = new TextEncoder();
147
+ const stream = new ReadableStream({ async start(controller) {
148
+ const reader = upstream.body.getReader();
149
+ let buffer = "";
150
+ let content = "";
151
+ let emittedLength = 0;
152
+ const enqueue = (chunk) => {
153
+ controller.enqueue(encoder.encode(chunk));
154
+ };
155
+ const emitSafeContent = (final = false) => {
156
+ const safeContent = safeDocsCloudContent(content, final);
157
+ if (safeContent.length <= emittedLength) return;
158
+ enqueue(createOpenAICompatibleSseChunk(safeContent.slice(emittedLength)));
159
+ emittedLength = safeContent.length;
160
+ };
161
+ const flushEvent = (event) => {
162
+ const data = event.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim()).filter(Boolean).join("\n").trim();
163
+ if (!data) return;
164
+ if (data === "[DONE]") return;
165
+ try {
166
+ const parsed = JSON.parse(data);
167
+ const delta = openAICompatibleDeltaContent(parsed) ?? docsCloudStreamContent(parsed);
168
+ if (delta) {
169
+ content += delta;
170
+ emitSafeContent();
171
+ }
172
+ } catch {
173
+ content += data;
174
+ emitSafeContent();
175
+ }
176
+ };
177
+ try {
178
+ while (true) {
179
+ const { value, done } = await reader.read();
180
+ if (done) break;
181
+ buffer += decoder.decode(value, { stream: true });
182
+ const events = buffer.split(/\r?\n\r?\n/);
183
+ buffer = events.pop() ?? "";
184
+ for (const event of events) flushEvent(event);
185
+ }
186
+ buffer += decoder.decode();
187
+ if (buffer.trim()) flushEvent(buffer);
188
+ } catch {}
189
+ emitSafeContent(true);
190
+ enqueue("data: [DONE]\n\n");
191
+ controller.close();
192
+ } });
193
+ return new Response(stream, {
194
+ status: upstream.status,
195
+ statusText: upstream.statusText,
196
+ headers: {
197
+ "Content-Type": "text/event-stream",
198
+ "Cache-Control": upstream.headers.get("Cache-Control") ?? "no-cache, no-transform",
199
+ Connection: upstream.headers.get("Connection") ?? "keep-alive"
200
+ }
201
+ });
202
+ }
203
+ function analyticsProperties(request) {
204
+ const userAgent = request.headers.get("user-agent")?.trim();
205
+ return userAgent ? { userAgent } : {};
206
+ }
207
+ function isDocsCloudAskAIProvider(config) {
208
+ return config?.enabled === true && config.provider === "docs-cloud";
209
+ }
210
+ async function createDocsCloudAskAIResponse(request, options = {}) {
211
+ const config = options.config;
212
+ const aiConfig = config?.ai;
213
+ const analytics = config?.analytics;
214
+ const requestUrl = new URL(request.url);
215
+ const requestStartedAt = Date.now();
216
+ const requestProperties = analyticsProperties(request);
217
+ let body;
218
+ try {
219
+ body = await request.json();
220
+ } catch {
221
+ await emitDocsAnalyticsEvent(analytics, {
222
+ type: "api_ai_error",
223
+ source: "server",
224
+ url: request.url,
225
+ path: requestUrl.pathname,
226
+ locale: options.locale,
227
+ properties: {
228
+ ...requestProperties,
229
+ reason: "invalid_json",
230
+ provider: "docs-cloud",
231
+ durationMs: Math.max(0, Date.now() - requestStartedAt)
232
+ }
233
+ });
234
+ return jsonError("Invalid JSON body. Expected { messages: [...] }.", 400);
235
+ }
236
+ const question = resolveQuestion(body);
237
+ const messages = Array.isArray(body.messages) ? body.messages : void 0;
238
+ if (!question) {
239
+ await emitDocsAnalyticsEvent(analytics, {
240
+ type: "api_ai_error",
241
+ source: "server",
242
+ url: request.url,
243
+ path: requestUrl.pathname,
244
+ locale: options.locale,
245
+ properties: {
246
+ ...requestProperties,
247
+ reason: "missing_user_message",
248
+ provider: "docs-cloud",
249
+ durationMs: Math.max(0, Date.now() - requestStartedAt)
250
+ }
251
+ });
252
+ return jsonError("At least one user message is required.", 400);
253
+ }
254
+ const projectId = resolveDocsCloudProjectId(options.env);
255
+ const { envName, apiKey } = resolveDocsCloudApiKey(config?.cloud, options.env);
256
+ if (!projectId || !apiKey) {
257
+ const reason = !projectId ? "missing_docs_cloud_project_id" : "missing_docs_cloud_api_key";
258
+ await emitDocsAnalyticsEvent(analytics, {
259
+ type: "api_ai_error",
260
+ source: "server",
261
+ url: request.url,
262
+ path: requestUrl.pathname,
263
+ locale: options.locale,
264
+ input: { question },
265
+ properties: {
266
+ ...requestProperties,
267
+ reason,
268
+ provider: "docs-cloud",
269
+ envName: !apiKey ? envName : void 0,
270
+ durationMs: Math.max(0, Date.now() - requestStartedAt)
271
+ }
272
+ });
273
+ 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);
274
+ }
275
+ const stream = shouldStreamResponse(request, body, aiConfig);
276
+ const apiBaseUrl = resolveDocsCloudApiBaseUrl(options.env);
277
+ const publicBaseUrl = aiConfig?.docsUrl ?? options.publicBaseUrl ?? requestUrl.origin;
278
+ const requestedModel = typeof body.model === "string" && body.model.trim() ? body.model.trim() : void 0;
279
+ await emitDocsAnalyticsEvent(analytics, {
280
+ type: "api_ai_request",
281
+ source: "server",
282
+ url: request.url,
283
+ path: requestUrl.pathname,
284
+ locale: options.locale,
285
+ input: { question },
286
+ properties: {
287
+ ...requestProperties,
288
+ provider: "docs-cloud",
289
+ messageCount: messages?.length,
290
+ questionLength: question.length,
291
+ model: requestedModel ?? "docs-cloud"
292
+ }
293
+ });
294
+ let upstream;
295
+ try {
296
+ upstream = await (options.fetch ?? fetch)(`${apiBaseUrl}/v1/projects/${encodeURIComponent(projectId)}/knowledge/ask`, {
297
+ method: "POST",
298
+ headers: {
299
+ Accept: stream ? "text/event-stream, application/json" : "application/json",
300
+ Authorization: `Bearer ${apiKey}`,
301
+ "Content-Type": "application/json",
302
+ "X-Docs-Cloud-Public-Base-Url": publicBaseUrl
303
+ },
304
+ body: JSON.stringify({
305
+ messages,
306
+ question,
307
+ answerMode: "auto",
308
+ answerStyle: "public",
309
+ modelPreference: requestedModel,
310
+ stream,
311
+ publicBaseUrl
312
+ })
313
+ });
314
+ } catch {
315
+ await emitDocsAnalyticsEvent(analytics, {
316
+ type: "api_ai_error",
317
+ source: "server",
318
+ url: request.url,
319
+ path: requestUrl.pathname,
320
+ locale: options.locale,
321
+ input: { question },
322
+ properties: {
323
+ ...requestProperties,
324
+ reason: "docs_cloud_fetch_error",
325
+ provider: "docs-cloud",
326
+ durationMs: Math.max(0, Date.now() - requestStartedAt)
327
+ }
328
+ });
329
+ return jsonError("Docs Cloud Ask AI request failed.", 502);
330
+ }
331
+ if (!upstream.ok) {
332
+ await upstream.text().catch(() => "");
333
+ await emitDocsAnalyticsEvent(analytics, {
334
+ type: "api_ai_error",
335
+ source: "server",
336
+ url: request.url,
337
+ path: requestUrl.pathname,
338
+ locale: options.locale,
339
+ input: { question },
340
+ properties: {
341
+ ...requestProperties,
342
+ reason: "docs_cloud_error",
343
+ provider: "docs-cloud",
344
+ status: upstream.status,
345
+ durationMs: Math.max(0, Date.now() - requestStartedAt)
346
+ }
347
+ });
348
+ return jsonError(`Docs Cloud Ask AI error (${upstream.status}).`, 502);
349
+ }
350
+ await emitDocsAnalyticsEvent(analytics, {
351
+ type: "api_ai_response",
352
+ source: "server",
353
+ url: request.url,
354
+ path: requestUrl.pathname,
355
+ locale: options.locale,
356
+ input: { question },
357
+ properties: {
358
+ ...requestProperties,
359
+ provider: "docs-cloud",
360
+ status: upstream.status,
361
+ durationMs: Math.max(0, Date.now() - requestStartedAt)
362
+ }
363
+ });
364
+ const contentType = upstream.headers.get("Content-Type") ?? "";
365
+ if (stream && contentType.includes("text/event-stream")) return createCleanDocsCloudSseResponse(upstream);
366
+ const upstreamBody = await upstream.text();
367
+ let payload;
368
+ let answer = upstreamBody;
369
+ try {
370
+ payload = JSON.parse(upstreamBody);
371
+ answer = docsCloudAnswerFromPayload(payload) || answer;
372
+ } catch {}
373
+ const cleanAnswer = cleanDocsCloudAnswer(answer);
374
+ if (stream) return createOpenAICompatibleSseResponse(cleanAnswer);
375
+ return Response.json(isPlainObject(payload) ? {
376
+ ...payload,
377
+ answer: cleanAnswer
378
+ } : { answer: cleanAnswer });
379
+ }
380
+
381
+ //#endregion
382
+ export { isDocsCloudAskAIProvider as n, createDocsCloudAskAIResponse as t };
@@ -0,0 +1,23 @@
1
+ import { Q as DocsCloudConfig, R as DocsAnalyticsConfig, t as AIConfig } from "./types-lMBIdZg0.mjs";
2
+
3
+ //#region src/cloud-ask-ai.d.ts
4
+ interface DocsCloudAskAIConfig {
5
+ ai?: Pick<AIConfig, "docsUrl" | "enabled" | "provider" | "stream">;
6
+ analytics?: boolean | DocsAnalyticsConfig;
7
+ cloud?: DocsCloudConfig;
8
+ }
9
+ interface DocsCloudAskAIResponseOptions {
10
+ config?: DocsCloudAskAIConfig;
11
+ /**
12
+ * Runtime env map for frameworks that expose environment variables outside
13
+ * `process.env`, for example SvelteKit's `$env/dynamic/private`.
14
+ */
15
+ env?: Record<string, string | undefined>;
16
+ fetch?: typeof fetch;
17
+ publicBaseUrl?: string;
18
+ locale?: string;
19
+ }
20
+ declare function isDocsCloudAskAIProvider(config: Pick<AIConfig, "enabled" | "provider"> | undefined): boolean;
21
+ declare function createDocsCloudAskAIResponse(request: Request, options?: DocsCloudAskAIResponseOptions): Promise<Response>;
22
+ //#endregion
23
+ export { isDocsCloudAskAIProvider as i, DocsCloudAskAIResponseOptions as n, createDocsCloudAskAIResponse as r, DocsCloudAskAIConfig as t };