@farming-labs/theme 0.2.60 → 0.2.61

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.
@@ -78,6 +78,8 @@ interface DocsAPIOptions {
78
78
  apiReference?: DocsConfig["apiReference"];
79
79
  /** Metadata used in generated OpenAPI documents. */
80
80
  metadata?: DocsConfig["metadata"];
81
+ /** Reusable skill publication and optional real A2A service metadata. */
82
+ agent?: DocsConfig["agent"];
81
83
  }
82
84
  interface DocsMCPAPIOptions {
83
85
  rootDir?: string;
@@ -92,6 +94,7 @@ interface DocsMCPAPIOptions {
92
94
  analytics?: boolean | DocsAnalyticsConfig;
93
95
  telemetry?: boolean | DocsTelemetryConfig;
94
96
  observability?: boolean | DocsObservabilityConfig;
97
+ agent?: DocsConfig["agent"];
95
98
  }
96
99
  type LlmsTxtOptions = LlmsTxtConfig;
97
100
  /**
package/dist/docs-api.mjs CHANGED
@@ -4,8 +4,8 @@ import { BoundedRouteCache } from "./bounded-route-cache.mjs";
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
6
  import matter from "gray-matter";
7
- import { DEFAULT_AGENT_SKILLS_INDEX_ROUTE, DEFAULT_AGENT_SKILLS_ROUTE_PREFIX, DEFAULT_API_CATALOG_ROUTE, DEFAULT_SITEMAP_MD_DOCS_ROUTE, acceptsDocsMarkdown, buildDocsAskAIContext, buildDocsConfigMap, buildDocsDiagnostics, createDocsAgentTraceContext, createDocsAgentTraceId, createDocsMarkdownResponse, createDocsRobotsResponse, createDocsSitemapResponse, createDocsStandardsDiscoveryResponse, detectDocsMarkdownAgentRequest, emitDocsAgentTraceEvent, emitDocsAnalyticsEvent, emitDocsTelemetryAgentSurfaceEvent, emitDocsTelemetryProjectEvent, formatDocsAskAIPackageHints, getDocsDiscoveryLinkHeader, getDocsLlmsTxtMaxCharsIssue, hasDocsMarkdownSignatureAgent, inferDocsTelemetryAgentSurface, isDocsConfigRequest, isDocsDiagnosticsRequest, normalizeDocsRelated, normalizePageAgentFrontmatter, performDocsSearch, renderDocsLlmsTxt, renderDocsMarkdownDocument, resolveAskAISearchRequestConfig, resolveChangelogConfig, resolveDocsAgentContractMcpTools, resolveDocsAudienceMdxContent, resolveDocsI18n, resolveDocsLlmsTxtRequest, resolveDocsLlmsTxtSections, resolveDocsLocale, resolveDocsMetadataBaseUrl, resolveDocsRequestApiRoute, resolveDocsSitemapConfig, resolveDocsStandardsDiscoveryRequest, resolvePageSidebarFolderIndexBehavior, resolveSearchRequestConfig, selectDocsLlmsTxtContent, stripGeneratedAgentProvenance } from "@farming-labs/docs";
8
- import { buildApiReferenceOpenApiDocumentAsync, createDocsMcpHttpHandler, createFilesystemDocsMcpSource, readDocsSitemapManifest, resolveApiReferenceConfig, resolveDocsMcpConfig } from "@farming-labs/docs/server";
7
+ import { DEFAULT_A2A_AGENT_CARD_ROUTE, DEFAULT_AGENT_SKILLS_ARCHIVE_ROUTE_PATTERN, DEFAULT_AGENT_SKILLS_INDEX_ROUTE, DEFAULT_AGENT_SKILLS_ROUTE_PREFIX, DEFAULT_API_CATALOG_ROUTE, DEFAULT_LEGACY_SKILLS_INDEX_ROUTE, DEFAULT_SITEMAP_MD_DOCS_ROUTE, acceptsDocsMarkdown, buildDocsAskAIContext, buildDocsConfigMap, buildDocsDiagnostics, createDocsAgentTraceContext, createDocsAgentTraceId, createDocsMarkdownResponse, createDocsRobotsResponse, createDocsSitemapResponse, createDocsStandardsDiscoveryResponse, detectDocsMarkdownAgentRequest, emitDocsAgentTraceEvent, emitDocsAnalyticsEvent, emitDocsTelemetryAgentSurfaceEvent, emitDocsTelemetryProjectEvent, formatDocsAskAIPackageHints, getDocsDiscoveryLinkHeader, getDocsLlmsTxtMaxCharsIssue, getDocsMcpProtectedResourceMetadataRoutes, hasDocsMarkdownSignatureAgent, inferDocsTelemetryAgentSurface, isDocsConfigRequest, isDocsDiagnosticsRequest, normalizeDocsRelated, normalizePageAgentFrontmatter, performDocsSearch, renderDocsLlmsTxt, renderDocsMarkdownDocument, resolveAskAISearchRequestConfig, resolveChangelogConfig, resolveDocsAgentContractMcpTools, resolveDocsAudienceMdxContent, resolveDocsI18n, resolveDocsLlmsTxtRequest, resolveDocsLlmsTxtSections, resolveDocsLocale, resolveDocsMetadataBaseUrl, resolveDocsPublishedAgentSkill, resolveDocsRequestApiRoute, resolveDocsSitemapConfig, resolveDocsStandardsDiscoveryRequest, resolvePageSidebarFolderIndexBehavior, resolveSearchRequestConfig, selectDocsLlmsTxtContent, stripGeneratedAgentProvenance } from "@farming-labs/docs";
8
+ import { buildApiReferenceOpenApiDocumentAsync, createDocsMcpHttpHandler, createFilesystemDocsMcpSource, readDocsSitemapManifest, resolveApiReferenceConfig, resolveConfiguredAgentSkills, resolveDocsMcpConfig } from "@farming-labs/docs/server";
9
9
 
10
10
  //#region src/docs-api.ts
11
11
  /**
@@ -42,7 +42,6 @@ const DEFAULT_DOCS_CLOUD_API_KEY_ENV = "DOCS_CLOUD_API_KEY";
42
42
  const DEFAULT_AGENT_SPEC_ROUTE = "/api/docs/agent/spec";
43
43
  const DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE = "/.well-known/agent";
44
44
  const DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE = "/.well-known/agent.json";
45
- const DEFAULT_MCP_ROUTE = "/api/docs/mcp";
46
45
  const DEFAULT_MCP_PUBLIC_ROUTE = "/mcp";
47
46
  const DEFAULT_MCP_WELL_KNOWN_ROUTE = "/.well-known/mcp";
48
47
  const DEFAULT_LLMS_TXT_ROUTE = "/llms.txt";
@@ -210,7 +209,7 @@ function resolveApiReferenceOpenApiDiscovery(value) {
210
209
  apiReferencePath: `/${apiReference.path}`
211
210
  };
212
211
  }
213
- function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp, feedback, llms, sitemap, robots, openapi }) {
212
+ function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp, feedback, llms, sitemap, robots, openapi, publishedSkills = [], agentCard }) {
214
213
  const normalizedEntry = normalizePathSegment(entry) || "docs";
215
214
  const localesEnabled = i18n !== null;
216
215
  const searchEnabled = isSearchEnabled(search);
@@ -218,6 +217,8 @@ function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp
218
217
  const robotsEnabled = isRobotsDiscoveryEnabled(robots);
219
218
  const llmsSections = resolveDocsLlmsTxtSections(llms);
220
219
  const agentContractMcpTools = resolveDocsAgentContractMcpTools(mcp);
220
+ const protectedResource = mcp.enabled && mcp.security?.authenticate ? mcp.security.protectedResource : void 0;
221
+ const protectedResourceMetadataRoutes = protectedResource ? getDocsMcpProtectedResourceMetadataRoutes(mcp.route) : [];
221
222
  const agentSpecRoute = apiRoute === DEFAULT_DOCS_API_ROUTE ? DEFAULT_AGENT_SPEC_ROUTE : `${apiRoute}?agent=spec`;
222
223
  return {
223
224
  version: "1",
@@ -272,7 +273,9 @@ function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp
272
273
  apiCatalog: DEFAULT_API_CATALOG_ROUTE,
273
274
  apiCatalogQuery: `${apiRoute}?format=api-catalog`
274
275
  } : {},
275
- agentSkillsIndex: DEFAULT_AGENT_SKILLS_INDEX_ROUTE
276
+ agentSkillsIndex: DEFAULT_AGENT_SKILLS_INDEX_ROUTE,
277
+ legacySkillsIndex: DEFAULT_LEGACY_SKILLS_INDEX_ROUTE,
278
+ ...agentCard ? { agentCard: DEFAULT_A2A_AGENT_CARD_ROUTE } : {}
276
279
  },
277
280
  apiCatalog: {
278
281
  enabled: apiCatalog,
@@ -414,10 +417,26 @@ function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp
414
417
  schema: "https://schemas.agentskills.io/discovery/0.2.0/schema.json",
415
418
  index: DEFAULT_AGENT_SKILLS_INDEX_ROUTE,
416
419
  artifact: `${DEFAULT_AGENT_SKILLS_ROUTE_PREFIX}/{name}/SKILL.md`,
420
+ archive: DEFAULT_AGENT_SKILLS_ARCHIVE_ROUTE_PATTERN,
421
+ file: `${DEFAULT_AGENT_SKILLS_ROUTE_PREFIX}/{name}/{path}`,
422
+ legacyIndex: DEFAULT_LEGACY_SKILLS_INDEX_ROUTE,
417
423
  apiIndex: `${apiRoute}?format=agent-skills`,
418
424
  apiArtifact: `${apiRoute}?format=agent-skill&name={name}`,
425
+ apiFile: `${apiRoute}?format=agent-skill-file&name={name}&path={path}`,
419
426
  digest: "sha256"
420
427
  },
428
+ published: publishedSkills.map((skill) => ({
429
+ name: skill.name,
430
+ description: skill.description,
431
+ type: skill.type,
432
+ url: skill.url,
433
+ digest: skill.digest,
434
+ files: skill.files.map((file) => ({
435
+ path: file.path,
436
+ url: file.url,
437
+ digest: file.digest
438
+ }))
439
+ })),
421
440
  registry: "skills.sh",
422
441
  install: "npx skills add farming-labs/docs",
423
442
  recommended: [{
@@ -432,10 +451,16 @@ function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp
432
451
  publicEndpoint: DEFAULT_MCP_PUBLIC_ROUTE,
433
452
  wellKnownEndpoint: DEFAULT_MCP_WELL_KNOWN_ROUTE,
434
453
  publicEndpoints: [DEFAULT_MCP_PUBLIC_ROUTE, DEFAULT_MCP_WELL_KNOWN_ROUTE],
435
- canonicalEndpoint: DEFAULT_MCP_ROUTE,
454
+ canonicalEndpoint: mcp.route,
436
455
  name: mcp.name,
437
456
  version: mcp.version,
438
- tools: mcp.tools
457
+ tools: mcp.tools,
458
+ ...protectedResource ? { protectedResource: {
459
+ metadataEndpoints: protectedResourceMetadataRoutes,
460
+ authorizationServers: protectedResource.authorizationServers,
461
+ scopesSupported: protectedResource.scopesSupported,
462
+ requiredScopes: protectedResource.requiredScopes
463
+ } } : {}
439
464
  },
440
465
  feedback: {
441
466
  enabled: feedback.enabled,
@@ -2434,6 +2459,7 @@ function generateLlmsTxt(indexes, options) {
2434
2459
  */
2435
2460
  function createDocsAPI(options) {
2436
2461
  const root = options?.rootDir ?? process.cwd();
2462
+ const publishedAgentSkills = resolveConfiguredAgentSkills(options?.agent?.skills, { rootDir: root });
2437
2463
  const entry = options?.entry ?? readEntry(root);
2438
2464
  const docsPath = normalizeDocsPublicPath(options?.docsPath ?? readDocsPath(root), entry);
2439
2465
  const analytics = options?.analytics;
@@ -2474,7 +2500,10 @@ function createDocsAPI(options) {
2474
2500
  const openapiDiscovery = resolveApiReferenceOpenApiDiscovery(apiReferenceConfig);
2475
2501
  const rawMcpConfig = options?.mcp ?? readMcpConfig(root);
2476
2502
  const mcpConfig = resolveDocsMcpConfig(rawMcpConfig, { defaultName: llmsConfig.siteTitle ?? "Documentation" });
2477
- const discoveryLinkHeader = getDocsDiscoveryLinkHeader({ includeApiCatalog: apiCatalogEnabled });
2503
+ const discoveryLinkHeader = getDocsDiscoveryLinkHeader({
2504
+ includeApiCatalog: apiCatalogEnabled,
2505
+ includeAgentCard: Boolean(options?.agent?.a2a)
2506
+ });
2478
2507
  const telemetryConfig = {
2479
2508
  entry,
2480
2509
  docsPath,
@@ -2710,6 +2739,8 @@ function createDocsAPI(options) {
2710
2739
  request,
2711
2740
  preferredSkillDocument: needsSkill ? readRootSkillDocument(root) : null,
2712
2741
  fallbackSkillDocument,
2742
+ publishedSkills: await publishedAgentSkills,
2743
+ agentCard: options?.agent?.a2a,
2713
2744
  origin: url.origin,
2714
2745
  entry,
2715
2746
  docsPath,
@@ -2787,7 +2818,25 @@ function createDocsAPI(options) {
2787
2818
  llms: llmsConfig,
2788
2819
  sitemap: sitemapConfig,
2789
2820
  robots: robotsConfig,
2790
- openapi: openapiDiscovery
2821
+ openapi: openapiDiscovery,
2822
+ publishedSkills: [await resolveDocsPublishedAgentSkill({
2823
+ preferredDocument: readRootSkillDocument(root),
2824
+ fallbackDocument: renderSkillDocument({
2825
+ origin: url.origin,
2826
+ entry,
2827
+ apiRoute: requestApiRoute,
2828
+ apiCatalog: apiCatalogEnabled,
2829
+ i18n,
2830
+ search: searchConfig,
2831
+ mcp: mcpConfig,
2832
+ feedback: agentFeedbackConfig,
2833
+ llms: llmsConfig,
2834
+ sitemap: sitemapConfig,
2835
+ robots: robotsConfig,
2836
+ openapi: openapiDiscovery
2837
+ })
2838
+ }), ...await publishedAgentSkills],
2839
+ agentCard: options?.agent?.a2a
2791
2840
  }), { headers: {
2792
2841
  "Cache-Control": "public, max-age=0, s-maxage=3600",
2793
2842
  Link: discoveryLinkHeader,
@@ -2905,6 +2954,7 @@ function createDocsAPI(options) {
2905
2954
  } });
2906
2955
  }
2907
2956
  const robotsResponse = createDocsRobotsResponse({
2957
+ agentCard: Boolean(options?.agent?.a2a),
2908
2958
  request,
2909
2959
  entry,
2910
2960
  apiCatalog: apiCatalogEnabled,
@@ -3218,13 +3268,22 @@ function createDocsMCPAPI(options = {}) {
3218
3268
  const mcpConfig = options.mcp ?? readMcpConfig(rootDir, { rejectRuntimeSecurity: true });
3219
3269
  const navTitle = typeof options.nav?.title === "string" && options.nav.title.trim().length > 0 ? options.nav.title : "Documentation";
3220
3270
  const handlers = createDocsMcpHttpHandler({
3221
- source: createFilesystemDocsMcpSource({
3222
- rootDir,
3223
- entry,
3224
- contentDir,
3225
- siteTitle: navTitle,
3226
- ordering: options.ordering
3227
- }),
3271
+ source: {
3272
+ ...createFilesystemDocsMcpSource({
3273
+ rootDir,
3274
+ entry,
3275
+ contentDir,
3276
+ siteTitle: navTitle,
3277
+ ordering: options.ordering
3278
+ }),
3279
+ async getSkills() {
3280
+ const configured = await resolveConfiguredAgentSkills(options.agent?.skills, { rootDir });
3281
+ return [await resolveDocsPublishedAgentSkill({
3282
+ preferredDocument: readRootSkillDocument(rootDir),
3283
+ fallbackDocument: `---\nname: docs\ndescription: Use the project documentation through MCP resources and tools.\n---\n\n# Documentation\n`
3284
+ }), ...configured];
3285
+ }
3286
+ },
3228
3287
  mcp: mcpConfig,
3229
3288
  search: options.search,
3230
3289
  analytics: options.analytics,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/theme",
3
- "version": "0.2.60",
3
+ "version": "0.2.61",
4
4
  "description": "Theme package for @farming-labs/docs — layout, provider, MDX components, and styles",
5
5
  "keywords": [
6
6
  "docs",
@@ -146,7 +146,7 @@
146
146
  "tsdown": "^0.20.3",
147
147
  "typescript": "^5.9.3",
148
148
  "vitest": "^4.1.8",
149
- "@farming-labs/docs": "0.2.60"
149
+ "@farming-labs/docs": "0.2.61"
150
150
  },
151
151
  "peerDependencies": {
152
152
  "@farming-labs/docs": ">=0.0.1",