@farming-labs/docs 0.2.131 → 0.2.132

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.
@@ -1,3 +1,4 @@
1
+ import { toPublicDocsSourcePath } from "./public-source-path.mjs";
1
2
  import { upsertPageAgentContractMarkdown } from "./agent-contract.mjs";
2
3
  import { findDocsMarkdownSection, stripDocsGeneratedAgentContractMarkers } from "./markdown-sections.mjs";
3
4
  import { digestDocsRetrievalContent } from "./retrieval-digest.mjs";
@@ -571,7 +572,7 @@ function hydrateDocsEvaluationSearchSource(result, index, pagesByUrl, contentMod
571
572
  url,
572
573
  section: pageSection?.title ?? result.section,
573
574
  anchor: pageSection?.anchor ?? anchor,
574
- sourcePath: page?.sourcePath,
575
+ sourcePath: toPublicDocsSourcePath(page?.sourcePath),
575
576
  lastModified: result.source?.lastModified ?? page?.lastModified,
576
577
  locale: scope?.locale[0] ?? provenanceScope?.locale?.[0],
577
578
  framework: scope?.framework[0] ?? provenanceScope?.framework?.[0],
@@ -590,7 +590,7 @@ function buildApiReferenceOpenApiDocument(config, options) {
590
590
  if (overlays.some((overlay) => !isLocalSpecSource(overlay))) throw new Error("Remote OpenAPI overlays require the async API reference builder.");
591
591
  return normalizeConfiguredOpenApiDocument(readLocalOpenApiDocument(specUrl, options.rootDir, overlays), config, options.baseUrl, specUrl, selectedVersion);
592
592
  } catch (error) {
593
- return buildUnavailableOpenApiDocument(config, `Unable to load the configured OpenAPI document. ${error instanceof Error ? error.message : "Unknown error"}`);
593
+ return buildUnavailableOpenApiDocument(config, `Unable to load the configured OpenAPI document. ${redactProjectRoot(error instanceof Error ? error.message : "Unknown error", options.rootDir)}`);
594
594
  }
595
595
  return buildUnavailableOpenApiDocument(config, `Remote OpenAPI specs require the async API reference builder. Use the framework route helper or buildApiReferenceOpenApiDocumentAsync().`);
596
596
  }
@@ -601,9 +601,18 @@ async function buildApiReferenceOpenApiDocumentAsync(config, options) {
601
601
  try {
602
602
  return await loadApiReferenceOpenApiDocumentAsync(config, options);
603
603
  } catch (error) {
604
- return buildUnavailableOpenApiDocument(config, `Unable to load the configured OpenAPI document. ${error instanceof Error ? error.message : "Unknown error"}`);
604
+ return buildUnavailableOpenApiDocument(config, `Unable to load the configured OpenAPI document. ${redactProjectRoot(error instanceof Error ? error.message : "Unknown error", options.rootDir)}`);
605
605
  }
606
606
  }
607
+ function redactProjectRoot(message, rootDir = process.cwd()) {
608
+ const roots = new Set([resolve(rootDir)]);
609
+ try {
610
+ roots.add(realpathSync(resolve(rootDir)));
611
+ } catch {}
612
+ let redacted = message;
613
+ for (const root of [...roots].sort((left, right) => right.length - left.length)) redacted = redacted.split(`${root}${sep}`).join("").split(root).join(".");
614
+ return redacted;
615
+ }
607
616
  /**
608
617
  * Load the resolved OpenAPI document without replacing diagnostics with an unavailable schema.
609
618
  * This is used by CLI health checks that need the original parsing, reference, and overlay error.
package/dist/mcp.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { filterDocsPagesByAccess } from "./access.mjs";
2
2
  import { createDocsAgentTraceContext, createDocsAgentTraceId, emitDocsAgentTraceEvent, emitDocsAnalyticsEvent } from "./analytics.mjs";
3
3
  import { toDocsMarkdownUrl } from "./urls.mjs";
4
+ import { toPublicDocsSourcePath } from "./public-source-path.mjs";
4
5
  import { buildDocsOkfBundle, normalizeDocsOkfTrustMetadataInput, resolveDocsOkfConfig } from "./okf.mjs";
5
6
  import { isDocsMcpOAuthScopeToken, isDocsMcpProtectedResourceMetadataPath, isDocsMcpResourcePath, normalizeDocsMcpAuthorizationServerUrls, normalizeDocsMcpEndpointPath, resolveDocsMcpProtectedResourceMetadataLocation, resolveDocsMcpResourceLocation } from "./mcp-auth.mjs";
6
7
  import { hasStructuredPageAgentContract, normalizePageAgentFrontmatter, renderPageAgentContractMarkdown, upsertPageAgentContractMarkdown } from "./agent-contract.mjs";
@@ -4276,7 +4277,7 @@ async function createDocsMcpServer(options) {
4276
4277
  url: page.url,
4277
4278
  title: page.title,
4278
4279
  ...page.description ? { description: page.description } : {},
4279
- ...page.sourcePath ? { sourcePath: page.sourcePath } : {},
4280
+ ...toPublicDocsSourcePath(page.sourcePath) ? { sourcePath: toPublicDocsSourcePath(page.sourcePath) } : {},
4280
4281
  ...page.lastModified ? { lastModified: page.lastModified } : {}
4281
4282
  },
4282
4283
  contract
@@ -6405,7 +6406,7 @@ function toDocsListPageSummary(page) {
6405
6406
  description: page.description,
6406
6407
  agent: toAgentContractSummary(page.agent),
6407
6408
  icon: page.icon,
6408
- sourcePath: page.sourcePath,
6409
+ sourcePath: toPublicDocsSourcePath(page.sourcePath),
6409
6410
  lastModified: page.lastModified
6410
6411
  };
6411
6412
  }
@@ -6703,7 +6704,7 @@ function extractDocsMcpCodeExamples(page) {
6703
6704
  url: page.url,
6704
6705
  title: page.title,
6705
6706
  description: page.description,
6706
- sourcePath: page.sourcePath,
6707
+ sourcePath: toPublicDocsSourcePath(page.sourcePath),
6707
6708
  lastModified: page.lastModified
6708
6709
  },
6709
6710
  language: parsed.language,
@@ -6777,7 +6778,7 @@ function getCodeExampleSearchText(example) {
6777
6778
  example.page.url,
6778
6779
  example.page.title,
6779
6780
  example.page.description,
6780
- example.page.sourcePath,
6781
+ toPublicDocsSourcePath(example.page.sourcePath),
6781
6782
  example.language,
6782
6783
  example.title,
6783
6784
  example.framework,
@@ -6885,7 +6886,7 @@ function toStructuredDocsMcpPage(page) {
6885
6886
  description: page.description,
6886
6887
  related: page.related,
6887
6888
  icon: page.icon,
6888
- sourcePath: page.sourcePath,
6889
+ sourcePath: toPublicDocsSourcePath(page.sourcePath),
6889
6890
  lastModified: page.lastModified,
6890
6891
  locale: page.locale,
6891
6892
  framework: page.framework,
@@ -7079,7 +7080,7 @@ async function buildDocsMcpContext(options) {
7079
7080
  url: sourceUrl,
7080
7081
  section: selectedSection?.title,
7081
7082
  anchor,
7082
- sourcePath: page.sourcePath,
7083
+ sourcePath: toPublicDocsSourcePath(page.sourcePath),
7083
7084
  lastModified: result.source?.lastModified ?? page.lastModified,
7084
7085
  locale: scope.locale,
7085
7086
  framework: scope.framework,
package/dist/okf.mjs CHANGED
@@ -1,3 +1,5 @@
1
+ import { toPublicDocsSourcePath } from "./public-source-path.mjs";
2
+
1
3
  //#region src/okf.ts
2
4
  const DOCS_OKF_VERSION = "0.2";
3
5
  const DOCS_OKF_BUNDLE_FORMAT = "open-knowledge-format.v0.2";
@@ -102,12 +104,15 @@ function resolveDocsOkfTrustMetadata(page, value, now = /* @__PURE__ */ new Date
102
104
  at: bestTimestamp ?? "1970-01-01T00:00:00.000Z"
103
105
  };
104
106
  const sources = [...authored.sources ?? config.sources ?? []];
105
- if (sources.length === 0) sources.push({
106
- resource: page.canonicalUrl ?? page.url,
107
- ...page.sourcePath ? { id: page.sourcePath } : {},
108
- title: page.title,
109
- ...bestTimestamp ? { last_modified: bestTimestamp } : {}
110
- });
107
+ if (sources.length === 0) {
108
+ const sourcePath = toPublicDocsSourcePath(page.sourcePath);
109
+ sources.push({
110
+ resource: page.canonicalUrl ?? page.url,
111
+ ...sourcePath ? { id: sourcePath } : {},
112
+ title: page.title,
113
+ ...bestTimestamp ? { last_modified: bestTimestamp } : {}
114
+ });
115
+ }
111
116
  const verified = [...authored.verified ?? config.verified ?? []];
112
117
  const staleAfter = authored.stale_after ?? config.stale_after ?? (config.staleAfterDays && bestTimestamp ? addDays(bestTimestamp, config.staleAfterDays) : void 0);
113
118
  return {
@@ -123,7 +128,7 @@ function resolveDocsOkfTrustMetadata(page, value, now = /* @__PURE__ */ new Date
123
128
  function buildDocsOkfBundle(pages, value) {
124
129
  const config = resolveDocsOkfConfig(value);
125
130
  const documents = pages.map((page) => ({
126
- id: page.sourcePath ?? page.url,
131
+ id: toPublicDocsSourcePath(page.sourcePath) ?? page.url,
127
132
  url: page.canonicalUrl ?? page.url,
128
133
  title: page.title,
129
134
  ...page.content ? { content: page.content } : {},
@@ -0,0 +1,17 @@
1
+ //#region src/public-source-path.ts
2
+ /**
3
+ * A page's `sourcePath` is whatever the loading server used to read the file.
4
+ * Absolute filesystem paths (`/var/task/...`, `C:\...`, UNC shares, `file:` URLs)
5
+ * and paths that climb out of the content tree describe the deployment rather
6
+ * than the docs, so agent-facing output only keeps content-relative paths.
7
+ */
8
+ const NON_PUBLIC_SOURCE_PATH = /^(?:[\\/]|[a-z]:(?:[\\/]|$)|file:|\.\.(?:[\\/]|$))/i;
9
+ function toPublicDocsSourcePath(value) {
10
+ if (typeof value !== "string") return void 0;
11
+ const normalized = value.trim().replace(/\\/g, "/").replace(/^\.\/+/, "");
12
+ if (!normalized || NON_PUBLIC_SOURCE_PATH.test(normalized)) return void 0;
13
+ return normalized;
14
+ }
15
+
16
+ //#endregion
17
+ export { toPublicDocsSourcePath };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/docs",
3
- "version": "0.2.131",
3
+ "version": "0.2.132",
4
4
  "description": "Modern, flexible MDX-based docs framework — core types, config, and CLI",
5
5
  "keywords": [
6
6
  "docs",