@farming-labs/docs 0.1.36 → 0.1.37
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/cli/index.mjs +1 -1
- package/dist/index.d.mts +179 -3
- package/dist/index.mjs +259 -1
- package/dist/{init-DwUjo2Kv.mjs → init-i5ySLGa2.mjs} +278 -65
- package/dist/mcp.d.mts +1 -1
- package/dist/{search-HA-ofcyh.d.mts → search-BWqFW9rt.d.mts} +1 -1
- package/dist/server.d.mts +2 -2
- package/dist/{types-ByCOEOnE.d.mts → types-CP2NmW5c.d.mts} +4 -4
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -69,7 +69,7 @@ async function main() {
|
|
|
69
69
|
searchApiKey: typeof flags["search-api-key"] === "string" ? flags["search-api-key"] : void 0
|
|
70
70
|
};
|
|
71
71
|
if (!parsedCommand.command || parsedCommand.command === "init") {
|
|
72
|
-
const { init } = await import("../init-
|
|
72
|
+
const { init } = await import("../init-i5ySLGa2.mjs");
|
|
73
73
|
await init(initOptions);
|
|
74
74
|
} else if (parsedCommand.command === "mcp") {
|
|
75
75
|
const { runMcp } = await import("../mcp-DLP94P1H.mjs");
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { $ as SidebarFolderNode, A as DocsSearchQuery, B as McpDocsSearchConfig, C as DocsSearchAdapter, D as DocsSearchConfig, E as DocsSearchChunkingConfig, F as FeedbackConfig, G as OrderingItem, H as OpenDocsConfig, I as FontStyle, J as PageOpenGraph, K as PageActionsConfig, L as GithubConfig, M as DocsSearchResultType, N as DocsSearchSourcePage, O as DocsSearchDocument, P as DocsTheme, Q as SidebarConfig, R as LastUpdatedConfig, S as DocsRelatedItem, T as DocsSearchAdapterFactory, U as OpenDocsProvider, V as OGConfig, W as OpenGraphImage, X as ResolvedDocsRelatedLink, Y as PageTwitter, Z as SidebarComponentProps, _ as DocsI18nConfig, a as ApiReferenceRenderer, at as TypesenseDocsSearchConfig, b as DocsMetadata, c as ChangelogFrontmatter, d as CustomDocsSearchConfig, et as SidebarNode, f as DocsAgentFeedbackContext, g as DocsFeedbackValue, h as DocsFeedbackData, i as ApiReferenceConfig, it as ThemeToggleConfig, j as DocsSearchResult, k as DocsSearchEmbeddingsConfig, l as CodeBlockCopyData, m as DocsConfig, n as AgentFeedbackConfig, nt as SidebarTree, o as BreadcrumbConfig, ot as TypographyConfig, p as DocsAgentFeedbackData, q as PageFrontmatter, r as AlgoliaDocsSearchConfig, rt as SimpleDocsSearchConfig, s as ChangelogConfig, st as UIConfig, t as AIConfig, tt as SidebarPageNode, u as CopyMarkdownConfig, v as DocsMcpConfig, w as DocsSearchAdapterContext, x as DocsNav, y as DocsMcpToolsConfig, z as LlmsTxtConfig } from "./types-
|
|
2
|
-
import {
|
|
1
|
+
import { $ as SidebarFolderNode, A as DocsSearchQuery, B as McpDocsSearchConfig, C as DocsSearchAdapter, D as DocsSearchConfig, E as DocsSearchChunkingConfig, F as FeedbackConfig, G as OrderingItem, H as OpenDocsConfig, I as FontStyle, J as PageOpenGraph, K as PageActionsConfig, L as GithubConfig, M as DocsSearchResultType, N as DocsSearchSourcePage, O as DocsSearchDocument, P as DocsTheme, Q as SidebarConfig, R as LastUpdatedConfig, S as DocsRelatedItem, T as DocsSearchAdapterFactory, U as OpenDocsProvider, V as OGConfig, W as OpenGraphImage, X as ResolvedDocsRelatedLink, Y as PageTwitter, Z as SidebarComponentProps, _ as DocsI18nConfig, a as ApiReferenceRenderer, at as TypesenseDocsSearchConfig, b as DocsMetadata, c as ChangelogFrontmatter, d as CustomDocsSearchConfig, et as SidebarNode, f as DocsAgentFeedbackContext, g as DocsFeedbackValue, h as DocsFeedbackData, i as ApiReferenceConfig, it as ThemeToggleConfig, j as DocsSearchResult, k as DocsSearchEmbeddingsConfig, l as CodeBlockCopyData, m as DocsConfig, n as AgentFeedbackConfig, nt as SidebarTree, o as BreadcrumbConfig, ot as TypographyConfig, p as DocsAgentFeedbackData, q as PageFrontmatter, r as AlgoliaDocsSearchConfig, rt as SimpleDocsSearchConfig, s as ChangelogConfig, st as UIConfig, t as AIConfig, tt as SidebarPageNode, u as CopyMarkdownConfig, v as DocsMcpConfig, w as DocsSearchAdapterContext, x as DocsNav, y as DocsMcpToolsConfig, z as LlmsTxtConfig } from "./types-CP2NmW5c.mjs";
|
|
2
|
+
import { DocsMcpPage, DocsMcpResolvedConfig } from "./mcp.mjs";
|
|
3
|
+
import { a as createSimpleSearchAdapter, c as resolveSearchRequestConfig, i as createMcpSearchAdapter, n as createAlgoliaSearchAdapter, o as createTypesenseSearchAdapter, r as createCustomSearchAdapter, s as performDocsSearch, t as buildDocsSearchDocuments } from "./search-BWqFW9rt.mjs";
|
|
3
4
|
|
|
4
5
|
//#region src/define-docs.d.ts
|
|
5
6
|
/**
|
|
@@ -119,4 +120,179 @@ declare function buildPageTwitter(page: Pick<PageFrontmatter, "title" | "descrip
|
|
|
119
120
|
declare function normalizeDocsRelated(value: unknown): ResolvedDocsRelatedLink[];
|
|
120
121
|
declare function renderDocsRelatedMarkdownLines(related: ResolvedDocsRelatedLink[] | undefined): string[];
|
|
121
122
|
//#endregion
|
|
122
|
-
|
|
123
|
+
//#region src/agent.d.ts
|
|
124
|
+
declare const DEFAULT_DOCS_API_ROUTE = "/api/docs";
|
|
125
|
+
declare const DEFAULT_AGENT_SPEC_ROUTE = "/api/docs/agent/spec";
|
|
126
|
+
declare const DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE = "/.well-known/agent";
|
|
127
|
+
declare const DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE = "/.well-known/agent.json";
|
|
128
|
+
declare const DEFAULT_MCP_ROUTE = "/api/docs/mcp";
|
|
129
|
+
declare const DEFAULT_MCP_PUBLIC_ROUTE = "/mcp";
|
|
130
|
+
declare const DEFAULT_MCP_WELL_KNOWN_ROUTE = "/.well-known/mcp";
|
|
131
|
+
declare const DEFAULT_LLMS_TXT_ROUTE = "/llms.txt";
|
|
132
|
+
declare const DEFAULT_LLMS_FULL_TXT_ROUTE = "/llms-full.txt";
|
|
133
|
+
declare const DEFAULT_LLMS_TXT_WELL_KNOWN_ROUTE = "/.well-known/llms.txt";
|
|
134
|
+
declare const DEFAULT_LLMS_FULL_TXT_WELL_KNOWN_ROUTE = "/.well-known/llms-full.txt";
|
|
135
|
+
declare const DEFAULT_AGENT_FEEDBACK_ROUTE = "/api/docs/agent/feedback";
|
|
136
|
+
interface DocsAgentFeedbackDiscoveryConfig {
|
|
137
|
+
enabled?: boolean;
|
|
138
|
+
route?: string;
|
|
139
|
+
schemaRoute?: string;
|
|
140
|
+
}
|
|
141
|
+
interface DocsLlmsDiscoveryConfig {
|
|
142
|
+
enabled?: boolean;
|
|
143
|
+
baseUrl?: string;
|
|
144
|
+
siteTitle?: string;
|
|
145
|
+
siteDescription?: string;
|
|
146
|
+
}
|
|
147
|
+
interface DocsAgentDiscoverySpecOptions {
|
|
148
|
+
origin: string;
|
|
149
|
+
entry?: string;
|
|
150
|
+
i18n?: ResolvedDocsI18n | null;
|
|
151
|
+
search?: boolean | DocsSearchConfig;
|
|
152
|
+
mcp: DocsMcpResolvedConfig;
|
|
153
|
+
feedback?: DocsAgentFeedbackDiscoveryConfig;
|
|
154
|
+
llms?: DocsLlmsDiscoveryConfig;
|
|
155
|
+
markdown?: {
|
|
156
|
+
acceptHeader?: boolean;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
interface DocsMarkdownPage {
|
|
160
|
+
slug?: string;
|
|
161
|
+
url: string;
|
|
162
|
+
title: string;
|
|
163
|
+
description?: string;
|
|
164
|
+
related?: ResolvedDocsRelatedLink[];
|
|
165
|
+
content: string;
|
|
166
|
+
rawContent?: string;
|
|
167
|
+
agentContent?: string;
|
|
168
|
+
agentRawContent?: string;
|
|
169
|
+
agentFallbackContent?: string;
|
|
170
|
+
agentFallbackRawContent?: string;
|
|
171
|
+
}
|
|
172
|
+
declare function normalizeDocsPathSegment(value: string): string;
|
|
173
|
+
declare function normalizeDocsUrlPath(value: string): string;
|
|
174
|
+
declare function isDocsAgentDiscoveryRequest(url: URL): boolean;
|
|
175
|
+
declare function isDocsMcpRequest(url: URL): boolean;
|
|
176
|
+
declare function isDocsPublicGetRequest(entry: string, url: URL, request: Request): boolean;
|
|
177
|
+
declare function resolveDocsLlmsTxtFormat(url: URL): "llms" | "llms-full" | null;
|
|
178
|
+
declare function resolveDocsMarkdownRequest(entry: string, url: URL, request: Request): {
|
|
179
|
+
requestedPath: string;
|
|
180
|
+
} | null;
|
|
181
|
+
declare function findDocsMarkdownPage<T extends DocsMarkdownPage>(entry: string, pages: T[], requestedPath: string): T | null;
|
|
182
|
+
declare function renderDocsMarkdownDocument(page: DocsMcpPage | DocsSearchSourcePage): string;
|
|
183
|
+
declare function renderDocsMarkdownDocument(page: DocsMarkdownPage): string;
|
|
184
|
+
declare function resolveDocsAgentMdxContent(content: string, audience: "human" | "agent"): string;
|
|
185
|
+
declare function buildDocsAgentDiscoverySpec({
|
|
186
|
+
origin,
|
|
187
|
+
entry,
|
|
188
|
+
i18n,
|
|
189
|
+
search,
|
|
190
|
+
mcp,
|
|
191
|
+
feedback,
|
|
192
|
+
llms,
|
|
193
|
+
markdown
|
|
194
|
+
}: DocsAgentDiscoverySpecOptions): {
|
|
195
|
+
version: string;
|
|
196
|
+
name: string;
|
|
197
|
+
baseUrl: string;
|
|
198
|
+
site: {
|
|
199
|
+
title: string;
|
|
200
|
+
description: string | undefined;
|
|
201
|
+
entry: string;
|
|
202
|
+
baseUrl: string;
|
|
203
|
+
};
|
|
204
|
+
locales: {
|
|
205
|
+
enabled: boolean;
|
|
206
|
+
available: string[];
|
|
207
|
+
default: string | null;
|
|
208
|
+
queryParam: string;
|
|
209
|
+
fallbackQueryParam: string;
|
|
210
|
+
};
|
|
211
|
+
capabilities: {
|
|
212
|
+
markdownRoutes: boolean;
|
|
213
|
+
agentMdOverrides: boolean;
|
|
214
|
+
agentBlocks: boolean;
|
|
215
|
+
llms: boolean;
|
|
216
|
+
skills: boolean;
|
|
217
|
+
mcp: boolean;
|
|
218
|
+
search: boolean;
|
|
219
|
+
agentFeedback: boolean;
|
|
220
|
+
locales: boolean;
|
|
221
|
+
};
|
|
222
|
+
api: {
|
|
223
|
+
docs: string;
|
|
224
|
+
agentSpec: string;
|
|
225
|
+
agentSpecDefault: string;
|
|
226
|
+
agentSpecFallback: string;
|
|
227
|
+
agentSpecWellKnown: string;
|
|
228
|
+
agentSpecWellKnownJson: string;
|
|
229
|
+
agentSpecQuery: string;
|
|
230
|
+
};
|
|
231
|
+
markdown: {
|
|
232
|
+
enabled: boolean;
|
|
233
|
+
acceptHeader: string | null;
|
|
234
|
+
pagePattern: string;
|
|
235
|
+
rootPage: string;
|
|
236
|
+
apiPattern: string;
|
|
237
|
+
resolutionOrder: string[];
|
|
238
|
+
};
|
|
239
|
+
llms: {
|
|
240
|
+
enabled: boolean;
|
|
241
|
+
defaultTxt: string;
|
|
242
|
+
defaultFull: string;
|
|
243
|
+
txt: string;
|
|
244
|
+
full: string;
|
|
245
|
+
publicTxt: string;
|
|
246
|
+
publicFull: string;
|
|
247
|
+
wellKnownTxt: string;
|
|
248
|
+
wellKnownFull: string;
|
|
249
|
+
};
|
|
250
|
+
search: {
|
|
251
|
+
enabled: boolean;
|
|
252
|
+
endpoint: string;
|
|
253
|
+
method: string;
|
|
254
|
+
queryParam: string;
|
|
255
|
+
localeParam: string;
|
|
256
|
+
};
|
|
257
|
+
skills: {
|
|
258
|
+
enabled: boolean;
|
|
259
|
+
registry: string;
|
|
260
|
+
install: string;
|
|
261
|
+
recommended: {
|
|
262
|
+
name: string;
|
|
263
|
+
description: string;
|
|
264
|
+
}[];
|
|
265
|
+
};
|
|
266
|
+
mcp: {
|
|
267
|
+
enabled: boolean;
|
|
268
|
+
endpoint: string;
|
|
269
|
+
defaultEndpoint: string;
|
|
270
|
+
publicEndpoint: string;
|
|
271
|
+
wellKnownEndpoint: string;
|
|
272
|
+
publicEndpoints: string[];
|
|
273
|
+
canonicalEndpoint: string;
|
|
274
|
+
name: string;
|
|
275
|
+
version: string;
|
|
276
|
+
tools: {
|
|
277
|
+
listPages: boolean;
|
|
278
|
+
readPage: boolean;
|
|
279
|
+
searchDocs: boolean;
|
|
280
|
+
getNavigation: boolean;
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
feedback: {
|
|
284
|
+
enabled: boolean;
|
|
285
|
+
schema: string;
|
|
286
|
+
submit: string;
|
|
287
|
+
schemaQuery: string;
|
|
288
|
+
submitQuery: string;
|
|
289
|
+
};
|
|
290
|
+
instructions: {
|
|
291
|
+
preferMarkdownRoutes: boolean;
|
|
292
|
+
useMcpWhenAvailable: boolean;
|
|
293
|
+
readFeedbackSchemaBeforeSubmitting: boolean;
|
|
294
|
+
doNotAssumeFeedbackPayloadShape: boolean;
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
//#endregion
|
|
298
|
+
export { type AIConfig, type AgentFeedbackConfig, type AlgoliaDocsSearchConfig, type ApiReferenceConfig, type ApiReferenceRenderer, type BreadcrumbConfig, type ChangelogConfig, type ChangelogEntrySummary, type ChangelogFrontmatter, type CodeBlockCopyData, type CopyMarkdownConfig, type CustomDocsSearchConfig, DEFAULT_AGENT_FEEDBACK_ROUTE, DEFAULT_AGENT_SPEC_ROUTE, DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE, DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE, DEFAULT_DOCS_API_ROUTE, DEFAULT_LLMS_FULL_TXT_ROUTE, DEFAULT_LLMS_FULL_TXT_WELL_KNOWN_ROUTE, DEFAULT_LLMS_TXT_ROUTE, DEFAULT_LLMS_TXT_WELL_KNOWN_ROUTE, DEFAULT_MCP_PUBLIC_ROUTE, DEFAULT_MCP_ROUTE, DEFAULT_MCP_WELL_KNOWN_ROUTE, type DocsAgentDiscoverySpecOptions, type DocsAgentFeedbackContext, type DocsAgentFeedbackData, type DocsAgentFeedbackDiscoveryConfig, type DocsConfig, type DocsFeedbackData, type DocsFeedbackValue, type DocsI18nConfig, type DocsLlmsDiscoveryConfig, type DocsMarkdownPage, type DocsMcpConfig, type DocsMcpToolsConfig, type DocsMetadata, type DocsNav, type DocsPathMatch, type DocsRelatedItem, type DocsSearchAdapter, type DocsSearchAdapterContext, type DocsSearchAdapterFactory, type DocsSearchChunkingConfig, type DocsSearchConfig, type DocsSearchDocument, type DocsSearchEmbeddingsConfig, type DocsSearchQuery, type DocsSearchResult, type DocsSearchResultType, type DocsSearchSourcePage, type DocsTheme, type FeedbackConfig, type FontStyle, type GithubConfig, type LastUpdatedConfig, type LlmsTxtConfig, type McpDocsSearchConfig, type OGConfig, type OpenDocsConfig, type OpenDocsProvider, type OpenGraphImage, type OrderingItem, type PageActionsConfig, type PageFrontmatter, type PageOpenGraph, type PageTwitter, type ResolvedChangelogConfig, type ResolvedDocsI18n, type ResolvedDocsRelatedLink, type SidebarComponentProps, type SidebarConfig, type SidebarFolderNode, type SidebarNode, type SidebarPageNode, type SidebarTree, type SimpleDocsSearchConfig, type ThemeToggleConfig, type TypesenseDocsSearchConfig, type TypographyConfig, type UIConfig, buildDocsAgentDiscoverySpec, buildDocsSearchDocuments, buildPageOpenGraph, buildPageTwitter, createAlgoliaSearchAdapter, createCustomSearchAdapter, createMcpSearchAdapter, createSimpleSearchAdapter, createTheme, createTypesenseSearchAdapter, deepMerge, defineDocs, extendTheme, findDocsMarkdownPage, isDocsAgentDiscoveryRequest, isDocsMcpRequest, isDocsPublicGetRequest, normalizeDocsPathSegment, normalizeDocsRelated, normalizeDocsUrlPath, performDocsSearch, renderDocsMarkdownDocument, renderDocsRelatedMarkdownLines, resolveChangelogConfig, resolveDocsAgentMdxContent, resolveDocsI18n, resolveDocsLlmsTxtFormat, resolveDocsLocale, resolveDocsMarkdownRequest, resolveDocsPath, resolveOGImage, resolveSearchRequestConfig, resolveTitle };
|
package/dist/index.mjs
CHANGED
|
@@ -266,4 +266,262 @@ function buildPageTwitter(page, ogConfig, baseUrl) {
|
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
//#endregion
|
|
269
|
-
|
|
269
|
+
//#region src/agent.ts
|
|
270
|
+
const DEFAULT_DOCS_API_ROUTE = "/api/docs";
|
|
271
|
+
const DEFAULT_AGENT_SPEC_ROUTE = "/api/docs/agent/spec";
|
|
272
|
+
const DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE = "/.well-known/agent";
|
|
273
|
+
const DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE = "/.well-known/agent.json";
|
|
274
|
+
const DEFAULT_MCP_ROUTE = "/api/docs/mcp";
|
|
275
|
+
const DEFAULT_MCP_PUBLIC_ROUTE = "/mcp";
|
|
276
|
+
const DEFAULT_MCP_WELL_KNOWN_ROUTE = "/.well-known/mcp";
|
|
277
|
+
const DEFAULT_LLMS_TXT_ROUTE = "/llms.txt";
|
|
278
|
+
const DEFAULT_LLMS_FULL_TXT_ROUTE = "/llms-full.txt";
|
|
279
|
+
const DEFAULT_LLMS_TXT_WELL_KNOWN_ROUTE = "/.well-known/llms.txt";
|
|
280
|
+
const DEFAULT_LLMS_FULL_TXT_WELL_KNOWN_ROUTE = "/.well-known/llms-full.txt";
|
|
281
|
+
const DEFAULT_AGENT_FEEDBACK_ROUTE = "/api/docs/agent/feedback";
|
|
282
|
+
function normalizeDocsPathSegment(value) {
|
|
283
|
+
return value.replace(/^\/+|\/+$/g, "");
|
|
284
|
+
}
|
|
285
|
+
function normalizeDocsUrlPath(value) {
|
|
286
|
+
const normalized = value.replace(/\/+/g, "/");
|
|
287
|
+
if (normalized === "/") return normalized;
|
|
288
|
+
return normalized.replace(/\/+$/, "");
|
|
289
|
+
}
|
|
290
|
+
function isDocsAgentDiscoveryRequest(url) {
|
|
291
|
+
const pathname = normalizeDocsUrlPath(url.pathname);
|
|
292
|
+
if (pathname === DEFAULT_DOCS_API_ROUTE && url.searchParams.get("agent")?.trim() === "spec") return true;
|
|
293
|
+
return pathname === DEFAULT_AGENT_SPEC_ROUTE || pathname === DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE || pathname === DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE;
|
|
294
|
+
}
|
|
295
|
+
function isDocsMcpRequest(url) {
|
|
296
|
+
const pathname = normalizeDocsUrlPath(url.pathname);
|
|
297
|
+
return pathname === DEFAULT_MCP_ROUTE || pathname === DEFAULT_MCP_PUBLIC_ROUTE || pathname === DEFAULT_MCP_WELL_KNOWN_ROUTE;
|
|
298
|
+
}
|
|
299
|
+
function isDocsPublicGetRequest(entry, url, request) {
|
|
300
|
+
const pathname = normalizeDocsUrlPath(url.pathname);
|
|
301
|
+
if (pathname === DEFAULT_DOCS_API_ROUTE || pathname === DEFAULT_MCP_ROUTE) return false;
|
|
302
|
+
return isDocsAgentDiscoveryRequest(url) || resolveDocsLlmsTxtFormat(url) !== null || resolveDocsMarkdownRequest(entry, url, request) !== null;
|
|
303
|
+
}
|
|
304
|
+
function resolveDocsLlmsTxtFormat(url) {
|
|
305
|
+
const pathname = normalizeDocsUrlPath(url.pathname);
|
|
306
|
+
if (pathname === DEFAULT_LLMS_TXT_ROUTE || pathname === DEFAULT_LLMS_TXT_WELL_KNOWN_ROUTE) return "llms";
|
|
307
|
+
if (pathname === DEFAULT_LLMS_FULL_TXT_ROUTE || pathname === DEFAULT_LLMS_FULL_TXT_WELL_KNOWN_ROUTE) return "llms-full";
|
|
308
|
+
const format = url.searchParams.get("format");
|
|
309
|
+
return pathname === DEFAULT_DOCS_API_ROUTE && (format === "llms" || format === "llms-full") ? format : null;
|
|
310
|
+
}
|
|
311
|
+
function resolveDocsMarkdownRequest(entry, url, request) {
|
|
312
|
+
const pathname = normalizeDocsUrlPath(url.pathname);
|
|
313
|
+
const format = url.searchParams.get("format")?.trim();
|
|
314
|
+
if (pathname === DEFAULT_DOCS_API_ROUTE && format === "markdown") return { requestedPath: url.searchParams.get("path")?.trim() ?? "" };
|
|
315
|
+
const normalizedEntry = `/${normalizeDocsPathSegment(entry) || "docs"}`;
|
|
316
|
+
if (pathname === `${normalizedEntry}.md`) return { requestedPath: "" };
|
|
317
|
+
const slugPrefix = `${normalizedEntry}/`;
|
|
318
|
+
if (pathname.startsWith(slugPrefix) && pathname.endsWith(".md")) return { requestedPath: pathname.slice(slugPrefix.length, -3) };
|
|
319
|
+
if (acceptsMarkdown(request)) {
|
|
320
|
+
if (pathname === normalizedEntry) return { requestedPath: "" };
|
|
321
|
+
if (pathname.startsWith(slugPrefix)) return { requestedPath: pathname.slice(slugPrefix.length) };
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
function findDocsMarkdownPage(entry, pages, requestedPath) {
|
|
326
|
+
const normalizedRequest = normalizeRequestedMarkdownPath(entry, requestedPath);
|
|
327
|
+
for (const page of pages) if (normalizeDocsUrlPath(page.url) === normalizedRequest) return page;
|
|
328
|
+
const normalizedSlug = normalizeDocsPathSegment(requestedPath.replace(/^\//, "").replace(/\.md$/i, ""));
|
|
329
|
+
for (const page of pages) if (page.slug !== void 0 && normalizeDocsPathSegment(page.slug) === normalizedSlug) return page;
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
function renderDocsMarkdownDocument(page) {
|
|
333
|
+
if (page.agentRawContent !== void 0) return page.agentRawContent;
|
|
334
|
+
const relatedLines = renderDocsRelatedMarkdownLines(page.related);
|
|
335
|
+
const lines = [`# ${page.title}`, `URL: ${page.url}`];
|
|
336
|
+
if (page.description) lines.push(`Description: ${page.description}`);
|
|
337
|
+
lines.push(...relatedLines);
|
|
338
|
+
lines.push("", page.agentFallbackRawContent ?? page.rawContent ?? page.content);
|
|
339
|
+
return lines.join("\n");
|
|
340
|
+
}
|
|
341
|
+
function resolveDocsAgentMdxContent(content, audience) {
|
|
342
|
+
const lines = content.split("\n");
|
|
343
|
+
const output = [];
|
|
344
|
+
let fenceMarker = null;
|
|
345
|
+
let agentDepth = 0;
|
|
346
|
+
for (const line of lines) {
|
|
347
|
+
const trimmed = line.trim();
|
|
348
|
+
const fenceMatch = trimmed.match(/^(`{3,}|~{3,})/);
|
|
349
|
+
if (fenceMatch) {
|
|
350
|
+
if (!fenceMarker) fenceMarker = fenceMatch[1];
|
|
351
|
+
else if (trimmed.startsWith(fenceMarker)) fenceMarker = null;
|
|
352
|
+
if (audience === "agent" || agentDepth === 0) output.push(line);
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (!fenceMarker) {
|
|
356
|
+
if (/^<Agent(?:\s[^>]*)?\/>$/.test(trimmed)) continue;
|
|
357
|
+
const singleLineMatch = line.match(/^(\s*)<Agent(?:\s[^>]*)?>([\s\S]*?)<\/Agent>\s*$/);
|
|
358
|
+
if (singleLineMatch) {
|
|
359
|
+
if (audience === "agent" && singleLineMatch[2]) output.push(`${singleLineMatch[1]}${singleLineMatch[2]}`);
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
if (line.match(/^(\s*)<Agent(?:\s[^>]*)?>\s*$/)) {
|
|
363
|
+
agentDepth += 1;
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
const openWithContentMatch = line.match(/^(\s*)<Agent(?:\s[^>]*)?>(.*)$/);
|
|
367
|
+
if (openWithContentMatch) {
|
|
368
|
+
agentDepth += 1;
|
|
369
|
+
if (audience === "agent" && openWithContentMatch[2]) output.push(`${openWithContentMatch[1]}${openWithContentMatch[2]}`);
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
const closeWithContentMatch = line.match(/^(.*)<\/Agent>\s*$/);
|
|
373
|
+
if (closeWithContentMatch && agentDepth > 0) {
|
|
374
|
+
if (audience === "agent" && closeWithContentMatch[1].trim()) output.push(closeWithContentMatch[1]);
|
|
375
|
+
agentDepth = Math.max(0, agentDepth - 1);
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
if (/^<\/Agent>\s*$/.test(trimmed) && agentDepth > 0) {
|
|
379
|
+
agentDepth = Math.max(0, agentDepth - 1);
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (agentDepth > 0 && audience === "human") continue;
|
|
384
|
+
output.push(line);
|
|
385
|
+
}
|
|
386
|
+
return output.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
387
|
+
}
|
|
388
|
+
function buildDocsAgentDiscoverySpec({ origin, entry = "docs", i18n = null, search, mcp, feedback, llms, markdown }) {
|
|
389
|
+
const normalizedEntry = normalizeDocsPathSegment(entry) || "docs";
|
|
390
|
+
const localesEnabled = i18n !== null;
|
|
391
|
+
const searchEnabled = isSearchEnabled(search);
|
|
392
|
+
const feedbackRoute = feedback?.route ?? DEFAULT_AGENT_FEEDBACK_ROUTE;
|
|
393
|
+
const feedbackSchemaRoute = feedback?.schemaRoute ?? `${feedbackRoute}/schema`;
|
|
394
|
+
const llmsEnabled = llms?.enabled ?? true;
|
|
395
|
+
return {
|
|
396
|
+
version: "1",
|
|
397
|
+
name: "@farming-labs/docs",
|
|
398
|
+
baseUrl: origin,
|
|
399
|
+
site: {
|
|
400
|
+
title: llms?.siteTitle ?? "Documentation",
|
|
401
|
+
description: llms?.siteDescription,
|
|
402
|
+
entry: normalizedEntry,
|
|
403
|
+
baseUrl: llms?.baseUrl ?? origin
|
|
404
|
+
},
|
|
405
|
+
locales: {
|
|
406
|
+
enabled: localesEnabled,
|
|
407
|
+
available: i18n?.locales ?? [],
|
|
408
|
+
default: i18n?.defaultLocale ?? null,
|
|
409
|
+
queryParam: "lang",
|
|
410
|
+
fallbackQueryParam: "locale"
|
|
411
|
+
},
|
|
412
|
+
capabilities: {
|
|
413
|
+
markdownRoutes: true,
|
|
414
|
+
agentMdOverrides: true,
|
|
415
|
+
agentBlocks: true,
|
|
416
|
+
llms: llmsEnabled,
|
|
417
|
+
skills: true,
|
|
418
|
+
mcp: mcp.enabled,
|
|
419
|
+
search: searchEnabled,
|
|
420
|
+
agentFeedback: feedback?.enabled ?? false,
|
|
421
|
+
locales: localesEnabled
|
|
422
|
+
},
|
|
423
|
+
api: {
|
|
424
|
+
docs: DEFAULT_DOCS_API_ROUTE,
|
|
425
|
+
agentSpec: DEFAULT_AGENT_SPEC_ROUTE,
|
|
426
|
+
agentSpecDefault: DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE,
|
|
427
|
+
agentSpecFallback: DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE,
|
|
428
|
+
agentSpecWellKnown: DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE,
|
|
429
|
+
agentSpecWellKnownJson: DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE,
|
|
430
|
+
agentSpecQuery: `${DEFAULT_DOCS_API_ROUTE}?agent=spec`
|
|
431
|
+
},
|
|
432
|
+
markdown: {
|
|
433
|
+
enabled: true,
|
|
434
|
+
acceptHeader: markdown?.acceptHeader === false ? null : "text/markdown",
|
|
435
|
+
pagePattern: `/${normalizedEntry}/{slug}.md`,
|
|
436
|
+
rootPage: `/${normalizedEntry}.md`,
|
|
437
|
+
apiPattern: `${DEFAULT_DOCS_API_ROUTE}?format=markdown&path={slug}`,
|
|
438
|
+
resolutionOrder: [
|
|
439
|
+
"agent.md",
|
|
440
|
+
"Agent blocks",
|
|
441
|
+
"page markdown"
|
|
442
|
+
]
|
|
443
|
+
},
|
|
444
|
+
llms: {
|
|
445
|
+
enabled: llmsEnabled,
|
|
446
|
+
defaultTxt: DEFAULT_LLMS_TXT_ROUTE,
|
|
447
|
+
defaultFull: DEFAULT_LLMS_FULL_TXT_ROUTE,
|
|
448
|
+
txt: `${DEFAULT_DOCS_API_ROUTE}?format=llms`,
|
|
449
|
+
full: `${DEFAULT_DOCS_API_ROUTE}?format=llms-full`,
|
|
450
|
+
publicTxt: DEFAULT_LLMS_TXT_ROUTE,
|
|
451
|
+
publicFull: DEFAULT_LLMS_FULL_TXT_ROUTE,
|
|
452
|
+
wellKnownTxt: DEFAULT_LLMS_TXT_WELL_KNOWN_ROUTE,
|
|
453
|
+
wellKnownFull: DEFAULT_LLMS_FULL_TXT_WELL_KNOWN_ROUTE
|
|
454
|
+
},
|
|
455
|
+
search: {
|
|
456
|
+
enabled: searchEnabled,
|
|
457
|
+
endpoint: `${DEFAULT_DOCS_API_ROUTE}?query={query}`,
|
|
458
|
+
method: "GET",
|
|
459
|
+
queryParam: "query",
|
|
460
|
+
localeParam: "lang"
|
|
461
|
+
},
|
|
462
|
+
skills: {
|
|
463
|
+
enabled: true,
|
|
464
|
+
registry: "skills.sh",
|
|
465
|
+
install: "npx skills add farming-labs/docs",
|
|
466
|
+
recommended: [{
|
|
467
|
+
name: "getting-started",
|
|
468
|
+
description: "Use for installation, init, framework setup, theme CSS, and first docs.config wiring."
|
|
469
|
+
}]
|
|
470
|
+
},
|
|
471
|
+
mcp: {
|
|
472
|
+
enabled: mcp.enabled,
|
|
473
|
+
endpoint: mcp.route,
|
|
474
|
+
defaultEndpoint: DEFAULT_MCP_PUBLIC_ROUTE,
|
|
475
|
+
publicEndpoint: DEFAULT_MCP_PUBLIC_ROUTE,
|
|
476
|
+
wellKnownEndpoint: DEFAULT_MCP_WELL_KNOWN_ROUTE,
|
|
477
|
+
publicEndpoints: [DEFAULT_MCP_PUBLIC_ROUTE, DEFAULT_MCP_WELL_KNOWN_ROUTE],
|
|
478
|
+
canonicalEndpoint: DEFAULT_MCP_ROUTE,
|
|
479
|
+
name: mcp.name,
|
|
480
|
+
version: mcp.version,
|
|
481
|
+
tools: mcp.tools
|
|
482
|
+
},
|
|
483
|
+
feedback: {
|
|
484
|
+
enabled: feedback?.enabled ?? false,
|
|
485
|
+
schema: feedbackSchemaRoute,
|
|
486
|
+
submit: feedbackRoute,
|
|
487
|
+
schemaQuery: `${DEFAULT_DOCS_API_ROUTE}?feedback=agent&schema=1`,
|
|
488
|
+
submitQuery: `${DEFAULT_DOCS_API_ROUTE}?feedback=agent`
|
|
489
|
+
},
|
|
490
|
+
instructions: {
|
|
491
|
+
preferMarkdownRoutes: true,
|
|
492
|
+
useMcpWhenAvailable: true,
|
|
493
|
+
readFeedbackSchemaBeforeSubmitting: true,
|
|
494
|
+
doNotAssumeFeedbackPayloadShape: true
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
function acceptsMarkdown(request) {
|
|
499
|
+
const accept = request.headers.get("accept");
|
|
500
|
+
if (!accept) return false;
|
|
501
|
+
return accept.split(",").map((value) => value.trim()).some((value) => {
|
|
502
|
+
const [mediaType, ...params] = value.split(";").map((part) => part.trim().toLowerCase());
|
|
503
|
+
if (mediaType !== "text/markdown") return false;
|
|
504
|
+
const qualityParam = params.find((param) => param.split("=", 1)[0]?.trim() === "q");
|
|
505
|
+
if (!qualityParam) return true;
|
|
506
|
+
const qualityValue = qualityParam.slice(qualityParam.indexOf("=") + 1).trim();
|
|
507
|
+
const quality = Number.parseFloat(qualityValue);
|
|
508
|
+
return Number.isFinite(quality) ? quality > 0 : true;
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
function normalizeRequestedMarkdownPath(entry, requestedPath) {
|
|
512
|
+
const normalizedEntry = `/${normalizeDocsPathSegment(entry) || "docs"}`;
|
|
513
|
+
const trimmed = requestedPath.trim().replace(/\.md$/i, "");
|
|
514
|
+
if (!trimmed) return normalizedEntry;
|
|
515
|
+
const normalized = normalizeDocsUrlPath(trimmed.startsWith("/") ? trimmed : `/${trimmed}`);
|
|
516
|
+
if (normalized === normalizedEntry || normalized.startsWith(`${normalizedEntry}/`)) return normalized;
|
|
517
|
+
const slug = normalizeDocsPathSegment(trimmed);
|
|
518
|
+
return slug ? normalizeDocsUrlPath(`${normalizedEntry}/${slug}`) : normalizedEntry;
|
|
519
|
+
}
|
|
520
|
+
function isSearchEnabled(search) {
|
|
521
|
+
if (search === false) return false;
|
|
522
|
+
if (search && typeof search === "object" && search.enabled === false) return false;
|
|
523
|
+
return true;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
//#endregion
|
|
527
|
+
export { DEFAULT_AGENT_FEEDBACK_ROUTE, DEFAULT_AGENT_SPEC_ROUTE, DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE, DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE, DEFAULT_DOCS_API_ROUTE, DEFAULT_LLMS_FULL_TXT_ROUTE, DEFAULT_LLMS_FULL_TXT_WELL_KNOWN_ROUTE, DEFAULT_LLMS_TXT_ROUTE, DEFAULT_LLMS_TXT_WELL_KNOWN_ROUTE, DEFAULT_MCP_PUBLIC_ROUTE, DEFAULT_MCP_ROUTE, DEFAULT_MCP_WELL_KNOWN_ROUTE, buildDocsAgentDiscoverySpec, buildDocsSearchDocuments, buildPageOpenGraph, buildPageTwitter, createAlgoliaSearchAdapter, createCustomSearchAdapter, createMcpSearchAdapter, createSimpleSearchAdapter, createTheme, createTypesenseSearchAdapter, deepMerge, defineDocs, extendTheme, findDocsMarkdownPage, isDocsAgentDiscoveryRequest, isDocsMcpRequest, isDocsPublicGetRequest, normalizeDocsPathSegment, normalizeDocsRelated, normalizeDocsUrlPath, performDocsSearch, renderDocsMarkdownDocument, renderDocsRelatedMarkdownLines, resolveChangelogConfig, resolveDocsAgentMdxContent, resolveDocsI18n, resolveDocsLlmsTxtFormat, resolveDocsLocale, resolveDocsMarkdownRequest, resolveDocsPath, resolveOGImage, resolveSearchRequestConfig, resolveTitle };
|
|
@@ -247,6 +247,14 @@ function sveltePageConfigImport(useAlias) {
|
|
|
247
247
|
function svelteLayoutServerImport(useAlias) {
|
|
248
248
|
return useAlias ? "$lib/docs.server" : "../../lib/docs.server";
|
|
249
249
|
}
|
|
250
|
+
function svelteRouteServerImport(filePath, useAlias) {
|
|
251
|
+
if (useAlias) return "$lib/docs.server";
|
|
252
|
+
return relativeImport(filePath, "src/lib/docs.server.ts");
|
|
253
|
+
}
|
|
254
|
+
function svelteRouteConfigImport(filePath, useAlias) {
|
|
255
|
+
if (useAlias) return "$lib/docs.config";
|
|
256
|
+
return relativeImport(filePath, "src/lib/docs.config.ts");
|
|
257
|
+
}
|
|
250
258
|
function astroServerConfigImport(useAlias) {
|
|
251
259
|
return useAlias ? "@/lib/docs.config" : "./docs.config";
|
|
252
260
|
}
|
|
@@ -258,6 +266,14 @@ function astroPageServerImport(useAlias, depth) {
|
|
|
258
266
|
if (useAlias) return "@/lib/docs.server";
|
|
259
267
|
return `${"../".repeat(depth)}lib/docs.server`;
|
|
260
268
|
}
|
|
269
|
+
function astroRouteServerImport(filePath, useAlias) {
|
|
270
|
+
if (useAlias) return "@/lib/docs.server";
|
|
271
|
+
return relativeImport(filePath, "src/lib/docs.server.ts");
|
|
272
|
+
}
|
|
273
|
+
function astroRouteConfigImport(filePath, useAlias) {
|
|
274
|
+
if (useAlias) return "@/lib/docs.config";
|
|
275
|
+
return relativeImport(filePath, "src/lib/docs.config.ts");
|
|
276
|
+
}
|
|
261
277
|
function docsConfigTemplate(cfg) {
|
|
262
278
|
if (cfg.theme === "custom" && cfg.customThemeName) {
|
|
263
279
|
const exportName = getThemeExportName(cfg.customThemeName);
|
|
@@ -811,13 +827,27 @@ function DocsIndexPage() {
|
|
|
811
827
|
}
|
|
812
828
|
function tanstackDocsCatchAllRouteTemplate(opts) {
|
|
813
829
|
const entryUrl = `/${opts.entry.replace(/^\/+|\/+$/g, "")}`;
|
|
830
|
+
const serverImport = opts.useAlias ? "@/lib/docs.server" : relativeImport(opts.filePath, "src/lib/docs.server.ts");
|
|
814
831
|
return `\
|
|
815
832
|
import { createFileRoute, notFound } from "@tanstack/react-router";
|
|
833
|
+
import { isDocsPublicGetRequest } from "@farming-labs/docs";
|
|
816
834
|
import { TanstackDocsPage } from "@farming-labs/tanstack-start/react";
|
|
817
835
|
import { loadDocPage } from "${tanstackDocsFunctionsImport(opts)}";
|
|
836
|
+
import { docsServer } from "${serverImport}";
|
|
818
837
|
import docsConfig from "${tanstackDocsConfigImport(opts.filePath)}";
|
|
819
838
|
|
|
820
839
|
export const Route = createFileRoute("${entryUrl}/$")({
|
|
840
|
+
server: {
|
|
841
|
+
handlers: {
|
|
842
|
+
GET: async ({ request }) => {
|
|
843
|
+
const url = new URL(request.url);
|
|
844
|
+
if (isDocsPublicGetRequest(${JSON.stringify(opts.entry)}, url, request)) {
|
|
845
|
+
return docsServer.GET({ request });
|
|
846
|
+
}
|
|
847
|
+
return undefined;
|
|
848
|
+
},
|
|
849
|
+
},
|
|
850
|
+
},
|
|
821
851
|
loader: async ({ location }) => {
|
|
822
852
|
try {
|
|
823
853
|
return await loadDocPage({ data: { pathname: location.pathname } });
|
|
@@ -865,6 +895,46 @@ export const Route = createFileRoute("/api/docs")({
|
|
|
865
895
|
});
|
|
866
896
|
`;
|
|
867
897
|
}
|
|
898
|
+
function tanstackDocsPublicRouteTemplate(useAlias, filePath, entry) {
|
|
899
|
+
return `\
|
|
900
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
901
|
+
import { isDocsMcpRequest, isDocsPublicGetRequest } from "@farming-labs/docs";
|
|
902
|
+
import { docsServer } from "${useAlias ? "@/lib/docs.server" : relativeImport(filePath, "src/lib/docs.server.ts")}";
|
|
903
|
+
|
|
904
|
+
const docsEntry = ${JSON.stringify(entry)};
|
|
905
|
+
|
|
906
|
+
async function handlePublicDocsRequest(request: Request) {
|
|
907
|
+
const url = new URL(request.url);
|
|
908
|
+
const method = request.method.toUpperCase();
|
|
909
|
+
|
|
910
|
+
if (isDocsMcpRequest(url)) {
|
|
911
|
+
if (method === "POST") return docsServer.MCP.POST({ request });
|
|
912
|
+
if (method === "DELETE") return docsServer.MCP.DELETE({ request });
|
|
913
|
+
if (method === "GET" || method === "HEAD") return docsServer.MCP.GET({ request });
|
|
914
|
+
return new Response("Method Not Allowed", {
|
|
915
|
+
status: 405,
|
|
916
|
+
headers: { Allow: "GET, HEAD, POST, DELETE" },
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
if ((method === "GET" || method === "HEAD") && isDocsPublicGetRequest(docsEntry, url, request)) {
|
|
921
|
+
return docsServer.GET({ request });
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
return new Response("Not Found", { status: 404 });
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
export const Route = createFileRoute("/$")({
|
|
928
|
+
server: {
|
|
929
|
+
handlers: {
|
|
930
|
+
GET: async ({ request }) => handlePublicDocsRequest(request),
|
|
931
|
+
POST: async ({ request }) => handlePublicDocsRequest(request),
|
|
932
|
+
DELETE: async ({ request }) => handlePublicDocsRequest(request),
|
|
933
|
+
},
|
|
934
|
+
},
|
|
935
|
+
});
|
|
936
|
+
`;
|
|
937
|
+
}
|
|
868
938
|
function tanstackApiReferenceRouteTemplate(opts) {
|
|
869
939
|
const routePath = `/${opts.apiReferencePath}${opts.catchAll ? "/$" : "/"}`;
|
|
870
940
|
return `\
|
|
@@ -1038,6 +1108,7 @@ src/lib/docs.functions.ts
|
|
|
1038
1108
|
src/routes/${cfg.entry}/index.tsx
|
|
1039
1109
|
src/routes/${cfg.entry}/$.tsx
|
|
1040
1110
|
src/routes/api/docs.ts
|
|
1111
|
+
src/routes/$.ts
|
|
1041
1112
|
\`\`\`
|
|
1042
1113
|
`;
|
|
1043
1114
|
}
|
|
@@ -1192,7 +1263,7 @@ const contentFiles = import.meta.glob("/${cfg.entry ?? "docs"}/**/*.{md,mdx,svx}
|
|
|
1192
1263
|
eager: true,
|
|
1193
1264
|
}) as Record<string, string>;
|
|
1194
1265
|
|
|
1195
|
-
export const { load, GET, POST } = createDocsServer({
|
|
1266
|
+
export const { load, GET, POST, MCP } = createDocsServer({
|
|
1196
1267
|
...config,
|
|
1197
1268
|
_preloadedContent: contentFiles,
|
|
1198
1269
|
});
|
|
@@ -1237,6 +1308,91 @@ import config from "${useAlias ? "$lib/docs.config" : relativeImport(filePath, "
|
|
|
1237
1308
|
export const GET = createSvelteApiReference(config);
|
|
1238
1309
|
`;
|
|
1239
1310
|
}
|
|
1311
|
+
function svelteDocsApiRouteTemplate(filePath, useAlias) {
|
|
1312
|
+
return `\
|
|
1313
|
+
export { GET, POST } from "${svelteRouteServerImport(filePath, useAlias)}";
|
|
1314
|
+
`;
|
|
1315
|
+
}
|
|
1316
|
+
function svelteDocsPublicHookTemplate(filePath, useAlias) {
|
|
1317
|
+
const serverImport = svelteRouteServerImport(filePath, useAlias);
|
|
1318
|
+
return `\
|
|
1319
|
+
import { isDocsMcpRequest, isDocsPublicGetRequest } from "@farming-labs/docs";
|
|
1320
|
+
import type { Handle } from "@sveltejs/kit";
|
|
1321
|
+
import config from "${svelteRouteConfigImport(filePath, useAlias)}";
|
|
1322
|
+
import { GET, MCP } from "${serverImport}";
|
|
1323
|
+
|
|
1324
|
+
const docsEntry = config.entry ?? "docs";
|
|
1325
|
+
|
|
1326
|
+
export const handle: Handle = async ({ event, resolve }) => {
|
|
1327
|
+
const method = event.request.method.toUpperCase();
|
|
1328
|
+
|
|
1329
|
+
if (isDocsMcpRequest(event.url)) {
|
|
1330
|
+
if (method === "POST") return MCP.POST({ request: event.request });
|
|
1331
|
+
if (method === "DELETE") return MCP.DELETE({ request: event.request });
|
|
1332
|
+
if (method === "GET" || method === "HEAD") return MCP.GET({ request: event.request });
|
|
1333
|
+
return new Response("Method Not Allowed", {
|
|
1334
|
+
status: 405,
|
|
1335
|
+
headers: { Allow: "GET, HEAD, POST, DELETE" },
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
if ((method === "GET" || method === "HEAD") && isDocsPublicGetRequest(docsEntry, event.url, event.request)) {
|
|
1340
|
+
return GET({ url: event.url, request: event.request });
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
return resolve(event);
|
|
1344
|
+
};
|
|
1345
|
+
`;
|
|
1346
|
+
}
|
|
1347
|
+
function injectSvelteDocsPublicHook(content, filePath, useAlias) {
|
|
1348
|
+
if (content.includes("isDocsPublicGetRequest") || content.includes("docsPublicHandle")) return null;
|
|
1349
|
+
if (/export\s*{\s*handle\b/.test(content)) return null;
|
|
1350
|
+
const serverImport = svelteRouteServerImport(filePath, useAlias);
|
|
1351
|
+
const configImport = svelteRouteConfigImport(filePath, useAlias);
|
|
1352
|
+
let next = content.trimEnd();
|
|
1353
|
+
let hasExistingHandle = false;
|
|
1354
|
+
for (const [pattern, replacement] of [
|
|
1355
|
+
[/\bexport\s+const\s+handle(\s*:\s*[^=]+)?\s*=/, "const existingHandle$1 ="],
|
|
1356
|
+
[/\bexport\s+async\s+function\s+handle\b/, "async function existingHandle"],
|
|
1357
|
+
[/\bexport\s+function\s+handle\b/, "function existingHandle"]
|
|
1358
|
+
]) if (pattern.test(next)) {
|
|
1359
|
+
next = next.replace(pattern, replacement);
|
|
1360
|
+
next = next.replace(/const existingHandle(:[^=\n]*?)\s+=/, "const existingHandle$1 =");
|
|
1361
|
+
hasExistingHandle = true;
|
|
1362
|
+
break;
|
|
1363
|
+
}
|
|
1364
|
+
const imports = [
|
|
1365
|
+
"import { isDocsMcpRequest, isDocsPublicGetRequest } from \"@farming-labs/docs\";",
|
|
1366
|
+
...next.includes("Handle") ? [] : ["import type { Handle } from \"@sveltejs/kit\";"],
|
|
1367
|
+
...hasExistingHandle && !next.includes("sequence") ? ["import { sequence } from \"@sveltejs/kit/hooks\";"] : [],
|
|
1368
|
+
`import docsConfig from "${configImport}";`,
|
|
1369
|
+
`import { GET as docsGET, MCP as docsMCP } from "${serverImport}";`
|
|
1370
|
+
];
|
|
1371
|
+
const docsHandle = `\
|
|
1372
|
+
const docsEntry = docsConfig.entry ?? "docs";
|
|
1373
|
+
|
|
1374
|
+
const docsPublicHandle: Handle = async ({ event, resolve }) => {
|
|
1375
|
+
const method = event.request.method.toUpperCase();
|
|
1376
|
+
|
|
1377
|
+
if (isDocsMcpRequest(event.url)) {
|
|
1378
|
+
if (method === "POST") return docsMCP.POST({ request: event.request });
|
|
1379
|
+
if (method === "DELETE") return docsMCP.DELETE({ request: event.request });
|
|
1380
|
+
if (method === "GET" || method === "HEAD") return docsMCP.GET({ request: event.request });
|
|
1381
|
+
return new Response("Method Not Allowed", {
|
|
1382
|
+
status: 405,
|
|
1383
|
+
headers: { Allow: "GET, HEAD, POST, DELETE" },
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
if ((method === "GET" || method === "HEAD") && isDocsPublicGetRequest(docsEntry, event.url, event.request)) {
|
|
1388
|
+
return docsGET({ url: event.url, request: event.request });
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
return resolve(event);
|
|
1392
|
+
};`;
|
|
1393
|
+
const exportLine = hasExistingHandle ? "export const handle = sequence(docsPublicHandle, existingHandle);" : "export const handle = docsPublicHandle;";
|
|
1394
|
+
return `${imports.join("\n")}\n${next}\n\n${docsHandle}\n\n${exportLine}\n`;
|
|
1395
|
+
}
|
|
1240
1396
|
function svelteRootLayoutTemplate(globalCssRelPath) {
|
|
1241
1397
|
let cssImport;
|
|
1242
1398
|
if (globalCssRelPath.startsWith("src/")) cssImport = "./" + globalCssRelPath.slice(4);
|
|
@@ -1354,10 +1510,12 @@ ${cfg.entry}/ # Markdown content
|
|
|
1354
1510
|
quickstart/
|
|
1355
1511
|
page.md # /${cfg.entry}/quickstart
|
|
1356
1512
|
src/
|
|
1513
|
+
hooks.server.ts # Public docs aliases
|
|
1357
1514
|
lib/
|
|
1358
1515
|
docs.config.ts # Docs configuration
|
|
1359
1516
|
docs.server.ts # Server-side docs loader
|
|
1360
1517
|
routes/
|
|
1518
|
+
api/docs/+server.ts # Search/AI API route
|
|
1361
1519
|
${cfg.entry}/
|
|
1362
1520
|
+layout.svelte # Docs layout
|
|
1363
1521
|
+layout.server.js # Layout data loader
|
|
@@ -1509,7 +1667,7 @@ const contentFiles = import.meta.glob("/${cfg.entry ?? "docs"}/**/*.{md,mdx}", {
|
|
|
1509
1667
|
eager: true,
|
|
1510
1668
|
}) as Record<string, string>;
|
|
1511
1669
|
|
|
1512
|
-
export const { load, GET, POST } = createDocsServer({
|
|
1670
|
+
export const { load, GET, POST, MCP } = createDocsServer({
|
|
1513
1671
|
...config,
|
|
1514
1672
|
_preloadedContent: contentFiles,
|
|
1515
1673
|
});
|
|
@@ -1619,6 +1777,86 @@ export const POST: APIRoute = async ({ request }) => {
|
|
|
1619
1777
|
};
|
|
1620
1778
|
`;
|
|
1621
1779
|
}
|
|
1780
|
+
function astroDocsMiddlewareTemplate(filePath, useAlias) {
|
|
1781
|
+
const serverImport = astroRouteServerImport(filePath, useAlias);
|
|
1782
|
+
return `\
|
|
1783
|
+
import { isDocsMcpRequest, isDocsPublicGetRequest } from "@farming-labs/docs";
|
|
1784
|
+
import type { MiddlewareHandler } from "astro";
|
|
1785
|
+
import config from "${astroRouteConfigImport(filePath, useAlias)}";
|
|
1786
|
+
import { GET, MCP } from "${serverImport}";
|
|
1787
|
+
|
|
1788
|
+
const docsEntry = config.entry ?? "docs";
|
|
1789
|
+
|
|
1790
|
+
export const onRequest: MiddlewareHandler = async (context, next) => {
|
|
1791
|
+
const method = context.request.method.toUpperCase();
|
|
1792
|
+
|
|
1793
|
+
if (isDocsMcpRequest(context.url)) {
|
|
1794
|
+
if (method === "POST") return MCP.POST({ request: context.request });
|
|
1795
|
+
if (method === "DELETE") return MCP.DELETE({ request: context.request });
|
|
1796
|
+
if (method === "GET" || method === "HEAD") return MCP.GET({ request: context.request });
|
|
1797
|
+
return new Response("Method Not Allowed", {
|
|
1798
|
+
status: 405,
|
|
1799
|
+
headers: { Allow: "GET, HEAD, POST, DELETE" },
|
|
1800
|
+
});
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
if ((method === "GET" || method === "HEAD") && isDocsPublicGetRequest(docsEntry, context.url, context.request)) {
|
|
1804
|
+
return GET({ request: context.request });
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
return next();
|
|
1808
|
+
};
|
|
1809
|
+
`;
|
|
1810
|
+
}
|
|
1811
|
+
function injectAstroDocsMiddleware(content, filePath, useAlias) {
|
|
1812
|
+
if (content.includes("isDocsPublicGetRequest") || content.includes("docsPublicMiddleware")) return null;
|
|
1813
|
+
if (/export\s*{\s*onRequest\b/.test(content)) return null;
|
|
1814
|
+
const serverImport = astroRouteServerImport(filePath, useAlias);
|
|
1815
|
+
const configImport = astroRouteConfigImport(filePath, useAlias);
|
|
1816
|
+
let next = content.trimEnd();
|
|
1817
|
+
let hasExistingMiddleware = false;
|
|
1818
|
+
for (const [pattern, replacement] of [
|
|
1819
|
+
[/\bexport\s+const\s+onRequest(\s*:\s*[^=]+)?\s*=/, "const existingOnRequest$1 ="],
|
|
1820
|
+
[/\bexport\s+async\s+function\s+onRequest\b/, "async function existingOnRequest"],
|
|
1821
|
+
[/\bexport\s+function\s+onRequest\b/, "function existingOnRequest"]
|
|
1822
|
+
]) if (pattern.test(next)) {
|
|
1823
|
+
next = next.replace(pattern, replacement);
|
|
1824
|
+
next = next.replace(/const existingOnRequest(:[^=\n]*?)\s+=/, "const existingOnRequest$1 =");
|
|
1825
|
+
hasExistingMiddleware = true;
|
|
1826
|
+
break;
|
|
1827
|
+
}
|
|
1828
|
+
const imports = [
|
|
1829
|
+
"import { isDocsMcpRequest, isDocsPublicGetRequest } from \"@farming-labs/docs\";",
|
|
1830
|
+
...next.includes("MiddlewareHandler") ? [] : ["import type { MiddlewareHandler } from \"astro\";"],
|
|
1831
|
+
...hasExistingMiddleware && !next.includes("sequence") ? ["import { sequence } from \"astro:middleware\";"] : [],
|
|
1832
|
+
`import docsConfig from "${configImport}";`,
|
|
1833
|
+
`import { GET as docsGET, MCP as docsMCP } from "${serverImport}";`
|
|
1834
|
+
];
|
|
1835
|
+
const docsMiddleware = `\
|
|
1836
|
+
const docsEntry = docsConfig.entry ?? "docs";
|
|
1837
|
+
|
|
1838
|
+
const docsPublicMiddleware: MiddlewareHandler = async (context, next) => {
|
|
1839
|
+
const method = context.request.method.toUpperCase();
|
|
1840
|
+
|
|
1841
|
+
if (isDocsMcpRequest(context.url)) {
|
|
1842
|
+
if (method === "POST") return docsMCP.POST({ request: context.request });
|
|
1843
|
+
if (method === "DELETE") return docsMCP.DELETE({ request: context.request });
|
|
1844
|
+
if (method === "GET" || method === "HEAD") return docsMCP.GET({ request: context.request });
|
|
1845
|
+
return new Response("Method Not Allowed", {
|
|
1846
|
+
status: 405,
|
|
1847
|
+
headers: { Allow: "GET, HEAD, POST, DELETE" },
|
|
1848
|
+
});
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
if ((method === "GET" || method === "HEAD") && isDocsPublicGetRequest(docsEntry, context.url, context.request)) {
|
|
1852
|
+
return docsGET({ request: context.request });
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
return next();
|
|
1856
|
+
};`;
|
|
1857
|
+
const exportLine = hasExistingMiddleware ? "export const onRequest = sequence(docsPublicMiddleware, existingOnRequest);" : "export const onRequest = docsPublicMiddleware;";
|
|
1858
|
+
return `${imports.join("\n")}\n${next}\n\n${docsMiddleware}\n\n${exportLine}\n`;
|
|
1859
|
+
}
|
|
1622
1860
|
function astroApiReferenceRouteTemplate(filePath) {
|
|
1623
1861
|
return `\
|
|
1624
1862
|
import { createAstroApiReference } from "@farming-labs/astro/api-reference";
|
|
@@ -1730,6 +1968,7 @@ ${cfg.entry}/ # Markdown content
|
|
|
1730
1968
|
quickstart/
|
|
1731
1969
|
page.md # /${cfg.entry}/quickstart
|
|
1732
1970
|
src/
|
|
1971
|
+
middleware.ts # Public docs aliases
|
|
1733
1972
|
lib/
|
|
1734
1973
|
docs.config.ts # Docs configuration
|
|
1735
1974
|
docs.server.ts # Server-side docs loader
|
|
@@ -1862,66 +2101,20 @@ export default defineDocs({
|
|
|
1862
2101
|
});
|
|
1863
2102
|
`;
|
|
1864
2103
|
}
|
|
1865
|
-
function
|
|
1866
|
-
const contentDirName = cfg.entry ?? "docs";
|
|
2104
|
+
function nuxtServerApiDocsRouteTemplate(cfg) {
|
|
1867
2105
|
return `\
|
|
1868
|
-
import {
|
|
2106
|
+
import { defineDocsHandler } from "@farming-labs/nuxt/server";
|
|
1869
2107
|
import config from "${cfg.useAlias ? "~/docs.config" : "../../docs.config"}";
|
|
1870
2108
|
|
|
1871
|
-
|
|
1872
|
-
query: "?raw",
|
|
1873
|
-
import: "default",
|
|
1874
|
-
eager: true,
|
|
1875
|
-
}) as Record<string, string>;
|
|
1876
|
-
|
|
1877
|
-
export const docsServer = createDocsServer({
|
|
1878
|
-
...config,
|
|
1879
|
-
_preloadedContent: contentFiles,
|
|
1880
|
-
});
|
|
1881
|
-
`;
|
|
1882
|
-
}
|
|
1883
|
-
function nuxtServerApiDocsGetTemplate() {
|
|
1884
|
-
return `\
|
|
1885
|
-
import { getRequestURL } from "h3";
|
|
1886
|
-
import { docsServer } from "../utils/docs-server";
|
|
1887
|
-
|
|
1888
|
-
export default defineEventHandler((event) => {
|
|
1889
|
-
const url = getRequestURL(event);
|
|
1890
|
-
const request = new Request(url.href, {
|
|
1891
|
-
method: event.method,
|
|
1892
|
-
headers: event.headers,
|
|
1893
|
-
});
|
|
1894
|
-
return docsServer.GET({ request });
|
|
1895
|
-
});
|
|
1896
|
-
`;
|
|
1897
|
-
}
|
|
1898
|
-
function nuxtServerApiDocsPostTemplate() {
|
|
1899
|
-
return `\
|
|
1900
|
-
import { getRequestURL, readRawBody } from "h3";
|
|
1901
|
-
import { docsServer } from "../utils/docs-server";
|
|
1902
|
-
|
|
1903
|
-
export default defineEventHandler(async (event) => {
|
|
1904
|
-
const url = getRequestURL(event);
|
|
1905
|
-
const body = await readRawBody(event);
|
|
1906
|
-
const request = new Request(url.href, {
|
|
1907
|
-
method: "POST",
|
|
1908
|
-
headers: event.headers,
|
|
1909
|
-
body: body ?? undefined,
|
|
1910
|
-
});
|
|
1911
|
-
return docsServer.POST({ request });
|
|
1912
|
-
});
|
|
2109
|
+
export default defineDocsHandler(config, useStorage);
|
|
1913
2110
|
`;
|
|
1914
2111
|
}
|
|
1915
|
-
function
|
|
2112
|
+
function nuxtServerDocsPublicMiddlewareTemplate(cfg) {
|
|
1916
2113
|
return `\
|
|
1917
|
-
import {
|
|
1918
|
-
import {
|
|
2114
|
+
import { defineDocsPublicHandler } from "@farming-labs/nuxt/server";
|
|
2115
|
+
import config from "${cfg.useAlias ? "~/docs.config" : "../../docs.config"}";
|
|
1919
2116
|
|
|
1920
|
-
export default
|
|
1921
|
-
const query = getQuery(event);
|
|
1922
|
-
const pathname = (query.pathname as string) ?? "/docs";
|
|
1923
|
-
return docsServer.load(pathname);
|
|
1924
|
-
});
|
|
2117
|
+
export default defineDocsPublicHandler(config, useStorage);
|
|
1925
2118
|
`;
|
|
1926
2119
|
}
|
|
1927
2120
|
function nuxtServerApiReferenceRouteTemplate(filePath, useAlias) {
|
|
@@ -1942,7 +2135,7 @@ const route = useRoute();
|
|
|
1942
2135
|
const pathname = computed(() => route.path);
|
|
1943
2136
|
|
|
1944
2137
|
const { data, error } = await useAsyncData(\`docs-\${pathname.value}\`, () =>
|
|
1945
|
-
$fetch("/api/docs
|
|
2138
|
+
$fetch("/api/docs", {
|
|
1946
2139
|
query: { pathname: pathname.value },
|
|
1947
2140
|
})
|
|
1948
2141
|
);
|
|
@@ -1979,6 +2172,7 @@ export default defineNuxtConfig({
|
|
|
1979
2172
|
|
|
1980
2173
|
nitro: {
|
|
1981
2174
|
moduleSideEffects: ["@farming-labs/nuxt/server"],
|
|
2175
|
+
serverAssets: [{ baseName: "${cfg.entry}", dir: "${cfg.entry}" }],
|
|
1982
2176
|
},
|
|
1983
2177
|
});
|
|
1984
2178
|
`;
|
|
@@ -2065,11 +2259,8 @@ ${cfg.entry}/ # Markdown content
|
|
|
2065
2259
|
installation/page.md
|
|
2066
2260
|
quickstart/page.md
|
|
2067
2261
|
server/
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
load.get.ts # Page data API
|
|
2071
|
-
docs.get.ts # Search API
|
|
2072
|
-
docs.post.ts # AI chat API
|
|
2262
|
+
api/docs.ts # Page data, search, and AI chat API
|
|
2263
|
+
middleware/docs-public.ts # llms.txt, .well-known, .md, and MCP aliases
|
|
2073
2264
|
pages/
|
|
2074
2265
|
${cfg.entry}/[[...slug]].vue # Docs catch-all page
|
|
2075
2266
|
docs.config.ts
|
|
@@ -3091,6 +3282,7 @@ function scaffoldTanstackStart(cwd, cfg, globalCssRelPath, write, skipped, writt
|
|
|
3091
3282
|
const docsIndexRoute = `${routeDir}/index.tsx`;
|
|
3092
3283
|
const docsCatchAllRoute = `${routeDir}/$.tsx`;
|
|
3093
3284
|
const apiRoute = "src/routes/api/docs.ts";
|
|
3285
|
+
const publicRoute = "src/routes/$.ts";
|
|
3094
3286
|
write(docsIndexRoute, tanstackDocsIndexRouteTemplate({
|
|
3095
3287
|
entry: cfg.entry,
|
|
3096
3288
|
filePath: docsIndexRoute,
|
|
@@ -3104,6 +3296,7 @@ function scaffoldTanstackStart(cwd, cfg, globalCssRelPath, write, skipped, writt
|
|
|
3104
3296
|
projectName: cfg.projectName
|
|
3105
3297
|
}));
|
|
3106
3298
|
write(apiRoute, tanstackApiDocsRouteTemplate(cfg.useAlias, apiRoute));
|
|
3299
|
+
write(publicRoute, tanstackDocsPublicRouteTemplate(cfg.useAlias, publicRoute, cfg.entry));
|
|
3107
3300
|
if (cfg.apiReference) {
|
|
3108
3301
|
const apiReferenceIndexRoute = `src/routes/${cfg.apiReference.path}.index.ts`;
|
|
3109
3302
|
const apiReferenceCatchAllRoute = `src/routes/${cfg.apiReference.path}.$.ts`;
|
|
@@ -3168,6 +3361,18 @@ function scaffoldSvelteKit(cwd, cfg, globalCssRelPath, write, skipped, written)
|
|
|
3168
3361
|
write(`src/routes/${cfg.entry}/+layout.server.js`, svelteDocsLayoutServerTemplate(cfg));
|
|
3169
3362
|
write(`src/routes/${cfg.entry}/[...slug]/+page.svelte`, svelteDocsPageTemplate(cfg));
|
|
3170
3363
|
if (cfg.i18n?.locales.length) write(`src/routes/${cfg.entry}/+page.svelte`, svelteDocsPageTemplate(cfg));
|
|
3364
|
+
const apiDocsRoute = "src/routes/api/docs/+server.ts";
|
|
3365
|
+
const publicHook = "src/hooks.server.ts";
|
|
3366
|
+
write(apiDocsRoute, svelteDocsApiRouteTemplate(apiDocsRoute, cfg.useAlias));
|
|
3367
|
+
const publicHookPath = path.join(cwd, publicHook);
|
|
3368
|
+
const existingPublicHook = readFileSafe(publicHookPath);
|
|
3369
|
+
if (existingPublicHook) {
|
|
3370
|
+
const injected = injectSvelteDocsPublicHook(existingPublicHook, publicHook, cfg.useAlias);
|
|
3371
|
+
if (injected) {
|
|
3372
|
+
writeFileSafe(publicHookPath, injected, true);
|
|
3373
|
+
written.push(`${publicHook} (composed docs public hook)`);
|
|
3374
|
+
} else skipped.push(`${publicHook} (already configured or could not compose docs public hook)`);
|
|
3375
|
+
} else write(publicHook, svelteDocsPublicHookTemplate(publicHook, cfg.useAlias));
|
|
3171
3376
|
if (cfg.apiReference) {
|
|
3172
3377
|
const apiReferenceIndexRoute = `src/routes/${cfg.apiReference.path}/+server.ts`;
|
|
3173
3378
|
const apiReferenceCatchAllRoute = `src/routes/${cfg.apiReference.path}/[...slug]/+server.ts`;
|
|
@@ -3215,6 +3420,16 @@ function scaffoldAstro(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
|
3215
3420
|
write(`src/pages/${cfg.entry}/index.astro`, astroDocsIndexTemplate(cfg));
|
|
3216
3421
|
write(`src/pages/${cfg.entry}/[...slug].astro`, astroDocsPageTemplate(cfg));
|
|
3217
3422
|
write(`src/pages/api/${cfg.entry}.ts`, astroApiRouteTemplate(cfg));
|
|
3423
|
+
const middleware = "src/middleware.ts";
|
|
3424
|
+
const middlewarePath = path.join(cwd, middleware);
|
|
3425
|
+
const existingMiddleware = readFileSafe(middlewarePath);
|
|
3426
|
+
if (existingMiddleware) {
|
|
3427
|
+
const injected = injectAstroDocsMiddleware(existingMiddleware, middleware, cfg.useAlias);
|
|
3428
|
+
if (injected) {
|
|
3429
|
+
writeFileSafe(middlewarePath, injected, true);
|
|
3430
|
+
written.push(`${middleware} (composed docs public middleware)`);
|
|
3431
|
+
} else skipped.push(`${middleware} (already configured or could not compose docs public middleware)`);
|
|
3432
|
+
} else write(middleware, astroDocsMiddlewareTemplate(middleware, cfg.useAlias));
|
|
3218
3433
|
if (cfg.apiReference) {
|
|
3219
3434
|
const apiReferenceIndexRoute = `src/pages/${cfg.apiReference.path}/index.ts`;
|
|
3220
3435
|
const apiReferenceCatchAllRoute = `src/pages/${cfg.apiReference.path}/[...slug].ts`;
|
|
@@ -3256,10 +3471,8 @@ function scaffoldNuxt(cwd, cfg, globalCssRelPath, write, skipped, written) {
|
|
|
3256
3471
|
write(`themes/${baseName}.css`, customThemeCssTemplate(baseName));
|
|
3257
3472
|
}
|
|
3258
3473
|
write("docs.config.ts", nuxtDocsConfigTemplate(cfg));
|
|
3259
|
-
write("server/
|
|
3260
|
-
write("server/
|
|
3261
|
-
write("server/api/docs.post.ts", nuxtServerApiDocsPostTemplate());
|
|
3262
|
-
write("server/api/docs/load.get.ts", nuxtServerApiDocsLoadTemplate());
|
|
3474
|
+
write("server/api/docs.ts", nuxtServerApiDocsRouteTemplate(cfg));
|
|
3475
|
+
write("server/middleware/docs-public.ts", nuxtServerDocsPublicMiddlewareTemplate(cfg));
|
|
3263
3476
|
write(`pages/${cfg.entry}/[[...slug]].vue`, nuxtDocsPageTemplate(cfg));
|
|
3264
3477
|
if (cfg.apiReference) {
|
|
3265
3478
|
const apiReferenceIndexRoute = `server/routes/${cfg.apiReference.path}/index.ts`;
|
package/dist/mcp.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as DocsSearchConfig, G as OrderingItem, N as DocsSearchSourcePage, v as DocsMcpConfig } from "./types-
|
|
1
|
+
import { D as DocsSearchConfig, G as OrderingItem, N as DocsSearchSourcePage, v as DocsMcpConfig } from "./types-CP2NmW5c.mjs";
|
|
2
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
|
|
4
4
|
//#region src/mcp.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as McpDocsSearchConfig, C as DocsSearchAdapter, D as DocsSearchConfig, E as DocsSearchChunkingConfig, N as DocsSearchSourcePage, O as DocsSearchDocument, T as DocsSearchAdapterFactory, at as TypesenseDocsSearchConfig, d as CustomDocsSearchConfig, j as DocsSearchResult, r as AlgoliaDocsSearchConfig } from "./types-
|
|
1
|
+
import { B as McpDocsSearchConfig, C as DocsSearchAdapter, D as DocsSearchConfig, E as DocsSearchChunkingConfig, N as DocsSearchSourcePage, O as DocsSearchDocument, T as DocsSearchAdapterFactory, at as TypesenseDocsSearchConfig, d as CustomDocsSearchConfig, j as DocsSearchResult, r as AlgoliaDocsSearchConfig } from "./types-CP2NmW5c.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/search.d.ts
|
|
4
4
|
declare function buildDocsSearchDocuments(pages: DocsSearchSourcePage[], chunking?: DocsSearchChunkingConfig): DocsSearchDocument[];
|
package/dist/server.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as DocsSearchQuery, B as McpDocsSearchConfig, C as DocsSearchAdapter, D as DocsSearchConfig, N as DocsSearchSourcePage, O as DocsSearchDocument, T as DocsSearchAdapterFactory, a as ApiReferenceRenderer, j as DocsSearchResult, m as DocsConfig, w as DocsSearchAdapterContext } from "./types-
|
|
2
|
-
import { a as createSimpleSearchAdapter, c as resolveSearchRequestConfig, i as createMcpSearchAdapter, n as createAlgoliaSearchAdapter, o as createTypesenseSearchAdapter, r as createCustomSearchAdapter, s as performDocsSearch, t as buildDocsSearchDocuments } from "./search-HA-ofcyh.mjs";
|
|
1
|
+
import { A as DocsSearchQuery, B as McpDocsSearchConfig, C as DocsSearchAdapter, D as DocsSearchConfig, N as DocsSearchSourcePage, O as DocsSearchDocument, T as DocsSearchAdapterFactory, a as ApiReferenceRenderer, j as DocsSearchResult, m as DocsConfig, w as DocsSearchAdapterContext } from "./types-CP2NmW5c.mjs";
|
|
3
2
|
import { DocsMcpHttpHandlers, DocsMcpNavigationNode, DocsMcpNavigationTree, DocsMcpPage, DocsMcpResolvedConfig, DocsMcpSource, createDocsMcpHttpHandler, createDocsMcpServer, createFilesystemDocsMcpSource, normalizeDocsMcpRoute, resolveDocsMcpConfig, runDocsMcpStdio } from "./mcp.mjs";
|
|
3
|
+
import { a as createSimpleSearchAdapter, c as resolveSearchRequestConfig, i as createMcpSearchAdapter, n as createAlgoliaSearchAdapter, o as createTypesenseSearchAdapter, r as createCustomSearchAdapter, s as performDocsSearch, t as buildDocsSearchDocuments } from "./search-BWqFW9rt.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/api-reference.d.ts
|
|
6
6
|
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD";
|
|
@@ -596,7 +596,7 @@ interface DocsMcpToolsConfig {
|
|
|
596
596
|
* Built-in MCP server configuration.
|
|
597
597
|
*
|
|
598
598
|
* When enabled, adapters can expose a Streamable HTTP endpoint for your docs
|
|
599
|
-
* at `/mcp` and `/.well-known/mcp
|
|
599
|
+
* at `/mcp` and `/.well-known/mcp`, backed by the canonical `/api/docs/mcp` route.
|
|
600
600
|
* The same config is also reused by the local `docs mcp` stdio command.
|
|
601
601
|
*/
|
|
602
602
|
interface DocsMcpConfig {
|
|
@@ -604,7 +604,7 @@ interface DocsMcpConfig {
|
|
|
604
604
|
enabled?: boolean;
|
|
605
605
|
/**
|
|
606
606
|
* Streamable HTTP route for the MCP endpoint.
|
|
607
|
-
* Defaults to `/api/docs/mcp`;
|
|
607
|
+
* Defaults to `/api/docs/mcp`; generated projects can also expose it publicly at `/mcp` and `/.well-known/mcp`.
|
|
608
608
|
*/
|
|
609
609
|
route?: string;
|
|
610
610
|
/**
|
|
@@ -1599,8 +1599,8 @@ interface DocsConfig {
|
|
|
1599
1599
|
/**
|
|
1600
1600
|
* Built-in MCP server for agent/assistant access to your docs content.
|
|
1601
1601
|
*
|
|
1602
|
-
* - omitted → enable the default MCP surface at `/mcp` and `/.well-known/mcp
|
|
1603
|
-
* - `true` → enable the default MCP surface at `/mcp` and `/.well-known/mcp
|
|
1602
|
+
* - omitted → enable the default MCP surface at `/mcp` and `/.well-known/mcp`, backed by `/api/docs/mcp`
|
|
1603
|
+
* - `true` → enable the default MCP surface at `/mcp` and `/.well-known/mcp`, backed by `/api/docs/mcp`
|
|
1604
1604
|
* - `{ route: "/api/docs/mcp" }` → enable with explicit route/config
|
|
1605
1605
|
* - `false` or `{ enabled: false }` → disable MCP explicitly
|
|
1606
1606
|
*/
|