reroute-js 1.0.0-alpha.7 → 1.0.0-alpha.9

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 (209) hide show
  1. package/README.md +2 -0
  2. package/cli/bin.d.ts +1 -1
  3. package/cli/bin.js +198 -36
  4. package/cli/bin.js.map +12 -11
  5. package/cli/index.d.ts +1 -1
  6. package/cli/index.js +4 -4
  7. package/cli/index.js.map +1 -1
  8. package/cli/src/cli.d.ts +1 -1
  9. package/cli/src/commands/analyze.d.ts +1 -1
  10. package/cli/src/commands/build.d.ts +1 -1
  11. package/cli/src/commands/dev.d.ts +1 -1
  12. package/cli/src/commands/gen.d.ts +1 -1
  13. package/cli/src/commands/index.d.ts +1 -1
  14. package/cli/src/commands/init.d.ts +1 -1
  15. package/cli/src/commands/lib/assets.d.ts +1 -1
  16. package/cli/src/commands/lib/bundler.d.ts +1 -1
  17. package/cli/src/commands/lib/command.d.ts +1 -1
  18. package/cli/src/commands/lib/env.d.ts +1 -1
  19. package/cli/src/commands/lib/index.d.ts +1 -1
  20. package/cli/src/commands/lib/log.d.ts +1 -1
  21. package/cli/src/commands/lib/markdown/availability.d.ts +1 -1
  22. package/cli/src/commands/lib/markdown/index.d.ts +1 -1
  23. package/cli/src/commands/lib/markdown/processor.d.ts +1 -1
  24. package/cli/src/commands/lib/production.d.ts +1 -1
  25. package/cli/src/commands/lib/server.d.ts +1 -1
  26. package/cli/src/commands/lib/streaming/analyzer.d.ts +1 -1
  27. package/cli/src/commands/lib/streaming/suspense.d.ts +1 -1
  28. package/cli/src/commands/lib/terminal-ui.d.ts +1 -1
  29. package/cli/src/commands/lib/theme.d.ts +1 -1
  30. package/cli/src/commands/lib/version.d.ts +1 -1
  31. package/cli/src/commands/og.d.ts +1 -1
  32. package/cli/src/commands/start.d.ts +1 -1
  33. package/cli/src/index.d.ts +1 -1
  34. package/core/index.d.ts +1 -1
  35. package/core/index.js +194 -32
  36. package/core/index.js.map +12 -11
  37. package/core/src/bundler/hash.d.ts +1 -1
  38. package/core/src/bundler/index.d.ts +1 -1
  39. package/core/src/config.d.ts +26 -2
  40. package/core/src/config.d.ts.map +1 -1
  41. package/core/src/content/discovery.d.ts +1 -1
  42. package/core/src/content/index.d.ts +1 -1
  43. package/core/src/content/metadata.d.ts +1 -1
  44. package/core/src/i18n/catalog.d.ts +1 -1
  45. package/core/src/i18n/discover.d.ts +1 -1
  46. package/core/src/i18n/index.d.ts +1 -1
  47. package/core/src/i18n/messages.d.ts +1 -1
  48. package/core/src/i18n/negotiate.d.ts +1 -1
  49. package/core/src/i18n/pathname.d.ts +1 -1
  50. package/core/src/i18n/resolve.d.ts +1 -1
  51. package/core/src/i18n/types.d.ts +1 -1
  52. package/core/src/index.d.ts +1 -1
  53. package/core/src/llms/discovery.d.ts +35 -0
  54. package/core/src/llms/discovery.d.ts.map +1 -0
  55. package/core/src/llms/extractor.d.ts +1 -1
  56. package/core/src/llms/formatter.d.ts +1 -1
  57. package/core/src/llms/full-generator.d.ts +1 -1
  58. package/core/src/llms/index-generator.d.ts +1 -1
  59. package/core/src/llms/index.d.ts +4 -1
  60. package/core/src/llms/index.d.ts.map +1 -1
  61. package/core/src/og/discovery.d.ts +1 -1
  62. package/core/src/og/index.d.ts +1 -1
  63. package/core/src/og/meta.d.ts +1 -1
  64. package/core/src/og/render.d.ts +1 -1
  65. package/core/src/og/types.d.ts +1 -1
  66. package/core/src/robots/discovery.d.ts +1 -1
  67. package/core/src/robots/generator.d.ts +1 -1
  68. package/core/src/robots/generator.d.ts.map +1 -1
  69. package/core/src/robots/index.d.ts +1 -1
  70. package/core/src/robots/policies.d.ts +1 -1
  71. package/core/src/rss/discovery.d.ts +1 -1
  72. package/core/src/rss/generator.d.ts +1 -1
  73. package/core/src/rss/index.d.ts +1 -1
  74. package/core/src/sitemap/discovery.d.ts +1 -1
  75. package/core/src/sitemap/generator.d.ts +1 -1
  76. package/core/src/sitemap/index.d.ts +1 -1
  77. package/core/src/ssr/index.d.ts +1 -1
  78. package/core/src/ssr/lib/cache.d.ts +1 -1
  79. package/core/src/ssr/lib/cleanup.d.ts +1 -1
  80. package/core/src/ssr/lib/collections.d.ts +17 -1
  81. package/core/src/ssr/lib/collections.d.ts.map +1 -1
  82. package/core/src/ssr/lib/compression.d.ts +1 -1
  83. package/core/src/ssr/lib/compute/content.d.ts +1 -1
  84. package/core/src/ssr/lib/compute/index.d.ts +1 -1
  85. package/core/src/ssr/lib/compute/layouts.d.ts +1 -1
  86. package/core/src/ssr/lib/compute/routes.d.ts +1 -1
  87. package/core/src/ssr/lib/content-path.d.ts +1 -1
  88. package/core/src/ssr/lib/data.d.ts +1 -1
  89. package/core/src/ssr/lib/html.d.ts +1 -1
  90. package/core/src/ssr/lib/imports.d.ts +1 -1
  91. package/core/src/ssr/lib/index.d.ts +1 -1
  92. package/core/src/ssr/lib/layouts.d.ts +1 -1
  93. package/core/src/ssr/lib/metadata.d.ts +1 -1
  94. package/core/src/ssr/lib/mime.d.ts +1 -1
  95. package/core/src/ssr/lib/modules.d.ts +1 -1
  96. package/core/src/ssr/lib/path.d.ts +1 -1
  97. package/core/src/ssr/lib/preload.d.ts +1 -1
  98. package/core/src/ssr/lib/route-match.d.ts +1 -1
  99. package/core/src/ssr/lib/scripts/collections.d.ts +2 -2
  100. package/core/src/ssr/lib/scripts/collections.d.ts.map +1 -1
  101. package/core/src/ssr/lib/scripts/data.d.ts +1 -1
  102. package/core/src/ssr/lib/scripts/escape.d.ts +1 -1
  103. package/core/src/ssr/lib/scripts/feeds.d.ts +1 -1
  104. package/core/src/ssr/lib/scripts/index.d.ts +1 -1
  105. package/core/src/ssr/lib/seed.d.ts +1 -1
  106. package/core/src/ssr/lib/serialize.d.ts +1 -1
  107. package/core/src/ssr/lib/setup.d.ts +2 -2
  108. package/core/src/ssr/lib/setup.d.ts.map +1 -1
  109. package/core/src/ssr/lib/styles.d.ts +1 -1
  110. package/core/src/ssr/lib/template.d.ts +1 -1
  111. package/core/src/ssr/lib/types.d.ts +1 -1
  112. package/core/src/ssr/render.d.ts +1 -1
  113. package/core/src/ssr/render.d.ts.map +1 -1
  114. package/core/src/ssr/stream.d.ts +1 -1
  115. package/core/src/ssr/stream.d.ts.map +1 -1
  116. package/elysia/index.d.ts +1 -1
  117. package/elysia/index.js +222 -50
  118. package/elysia/index.js.map +15 -14
  119. package/elysia/src/index.d.ts +1 -1
  120. package/elysia/src/libs/assets.d.ts +1 -1
  121. package/elysia/src/libs/cache.d.ts +1 -1
  122. package/elysia/src/libs/caching.d.ts +1 -1
  123. package/elysia/src/libs/http.d.ts +1 -1
  124. package/elysia/src/libs/i18n.d.ts +1 -1
  125. package/elysia/src/libs/image.d.ts +1 -1
  126. package/elysia/src/libs/index.d.ts +1 -1
  127. package/elysia/src/libs/llms.d.ts +1 -1
  128. package/elysia/src/libs/response.d.ts +1 -1
  129. package/elysia/src/libs/serving.d.ts +1 -1
  130. package/elysia/src/plugin.d.ts +1 -1
  131. package/elysia/src/plugin.d.ts.map +1 -1
  132. package/elysia/src/routes/artifacts.d.ts +1 -1
  133. package/elysia/src/routes/content.d.ts +1 -1
  134. package/elysia/src/routes/image.d.ts +1 -1
  135. package/elysia/src/routes/index.d.ts +1 -1
  136. package/elysia/src/routes/internal.d.ts +1 -1
  137. package/elysia/src/routes/llms.d.ts +1 -1
  138. package/elysia/src/routes/llms.d.ts.map +1 -1
  139. package/elysia/src/routes/og.d.ts +1 -1
  140. package/elysia/src/routes/redirects.d.ts +1 -1
  141. package/elysia/src/routes/robots.d.ts +1 -1
  142. package/elysia/src/routes/rss.d.ts +1 -1
  143. package/elysia/src/routes/search.d.ts +1 -1
  144. package/elysia/src/routes/sitemap.d.ts +1 -1
  145. package/elysia/src/routes/ssr.d.ts +4 -2
  146. package/elysia/src/routes/ssr.d.ts.map +1 -1
  147. package/elysia/src/routes/static.d.ts +1 -1
  148. package/elysia/src/routes/themeCssRefresh.d.ts +1 -1
  149. package/elysia/src/types.d.ts +1 -1
  150. package/package.json +1 -1
  151. package/react/index.d.ts +1 -1
  152. package/react/index.js +8 -5
  153. package/react/index.js.map +3 -3
  154. package/react/src/components/ClientOnly.d.ts +1 -1
  155. package/react/src/components/ContentRoute.d.ts +1 -1
  156. package/react/src/components/Image.d.ts +1 -1
  157. package/react/src/components/LazyRoute.d.ts +1 -1
  158. package/react/src/components/Link.d.ts +1 -1
  159. package/react/src/components/Markdown.d.ts +1 -1
  160. package/react/src/components/Outlet.d.ts +1 -1
  161. package/react/src/components/index.d.ts +1 -1
  162. package/react/src/hooks/index.d.ts +1 -1
  163. package/react/src/hooks/useContent.d.ts +1 -1
  164. package/react/src/hooks/useContent.d.ts.map +1 -1
  165. package/react/src/hooks/useData.d.ts +1 -1
  166. package/react/src/hooks/useFeed.d.ts +1 -1
  167. package/react/src/hooks/useLayoutData.d.ts +1 -1
  168. package/react/src/hooks/useLlms.d.ts +1 -1
  169. package/react/src/hooks/useNavigate.d.ts +1 -1
  170. package/react/src/hooks/useParams.d.ts +1 -1
  171. package/react/src/hooks/useRouter.d.ts +1 -1
  172. package/react/src/hooks/useSearch.d.ts +1 -1
  173. package/react/src/hooks/useSearchParams.d.ts +1 -1
  174. package/react/src/hooks/useToc.d.ts +1 -1
  175. package/react/src/i18n/LocaleProvider.d.ts +1 -1
  176. package/react/src/i18n/helpers.d.ts +1 -1
  177. package/react/src/i18n/index.d.ts +1 -1
  178. package/react/src/index.d.ts +1 -1
  179. package/react/src/lib/collection.d.ts +1 -1
  180. package/react/src/lib/content.d.ts +1 -1
  181. package/react/src/lib/head.d.ts +1 -1
  182. package/react/src/lib/index.d.ts +1 -1
  183. package/react/src/lib/lazy-route.d.ts +1 -1
  184. package/react/src/lib/route-loader.d.ts +1 -1
  185. package/react/src/providers/ContentProvider.d.ts +1 -1
  186. package/react/src/providers/RerouteProvider.d.ts +1 -1
  187. package/react/src/providers/RouterProvider.d.ts +1 -1
  188. package/react/src/providers/index.d.ts +1 -1
  189. package/react/src/types/any.d.ts +1 -1
  190. package/react/src/types/index.d.ts +1 -1
  191. package/react/src/types/router.d.ts +1 -1
  192. package/telemetry/react.d.ts +1 -1
  193. package/telemetry/react.js +2 -2
  194. package/telemetry/react.js.map +1 -1
  195. package/telemetry/server.d.ts +1 -1
  196. package/telemetry/server.js +25 -10
  197. package/telemetry/server.js.map +11 -9
  198. package/telemetry/src/react/api.d.ts +1 -1
  199. package/telemetry/src/react/context.d.ts +1 -1
  200. package/telemetry/src/react/index.d.ts +1 -1
  201. package/telemetry/src/react/telemetry.d.ts +1 -1
  202. package/telemetry/src/server/context.d.ts +1 -1
  203. package/telemetry/src/server/headers/extractor.d.ts +1 -1
  204. package/telemetry/src/server/headers/index.d.ts +1 -1
  205. package/telemetry/src/server/headers/presets.d.ts +1 -1
  206. package/telemetry/src/server/index.d.ts +1 -1
  207. package/telemetry/src/server/instrumentation.d.ts +1 -1
  208. package/telemetry/src/server/plugin.d.ts +1 -1
  209. package/telemetry/src/server/sourcemap.d.ts +1 -1
package/README.md CHANGED
@@ -1169,6 +1169,7 @@ Your site now supports:
1169
1169
  - Accept header content negotiation (`Accept: text/plain`, `Accept: text/markdown`)
1170
1170
  - `/llms.txt` - Index of all content: title, description, and link per page
1171
1171
  - `/llms-full.txt` - Complete site content in one file (optional; large)
1172
+ - HTML discovery: `Link: rel=alternate` + `<link type="text/markdown">` pointing at the `.md` twin, `Link: rel=llms-txt`, `Vary: Accept`, and `Content-Signal` (also a `Content-Signal:` line in `robots.txt` when robots is enabled)
1172
1173
 
1173
1174
  #### How It Works
1174
1175
 
@@ -1201,6 +1202,7 @@ curl -H "Accept: text/html" https://example.com/blog/hello-world # Default
1201
1202
  - **Flexible exclusions** - Strings, RegExp, or custom functions
1202
1203
  - **Works everywhere** - Collections, SSR routes, static pages
1203
1204
  - **Auto-discovery** - All content automatically indexed
1205
+ - **Crawler hints** - HTML `Link` / `<link rel="alternate">`, `Content-Signal`, `Vary: Accept`
1204
1206
 
1205
1207
  #### Discovering LLM Files in Your UI
1206
1208
 
package/cli/bin.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * reroute-js v1.0.0-alpha.7
2
+ * reroute-js v1.0.0-alpha.9
3
3
  *
4
4
  * @license MIT
5
5
  * @copyright 2026 stewones <hi@stewan.io>
package/cli/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
3
  /**
4
- * reroute-js v1.0.0-alpha.7
4
+ * reroute-js v1.0.0-alpha.9
5
5
  *
6
6
  * @license MIT
7
7
  * @copyright 2026 stewones <hi@stewan.io>
@@ -68,7 +68,7 @@ async function getVersionString() {
68
68
  }
69
69
  async function getVersion() {
70
70
  if (true) {
71
- return "1.0.0-alpha.7";
71
+ return "1.0.0-alpha.9";
72
72
  }
73
73
  const possiblePaths = [
74
74
  path.join(import.meta.dir, "../../../../package.json"),
@@ -86,7 +86,7 @@ async function getVersion() {
86
86
  }
87
87
  async function getCommit() {
88
88
  if (true) {
89
- return "19dcaf7";
89
+ return "f5dd5ea";
90
90
  }
91
91
  return "dev";
92
92
  }
@@ -1488,6 +1488,21 @@ function setGlobalCollections(byCollectionForSSR) {
1488
1488
  globalThis.__REROUTE_COLLECTIONS__ = byCollectionForSSR;
1489
1489
  } catch {}
1490
1490
  }
1491
+ function resetSSRContentResults() {
1492
+ try {
1493
+ globalThis.__REROUTE_SSR_RESULTS__ = {};
1494
+ } catch {}
1495
+ }
1496
+ function takeSSRContentResults() {
1497
+ try {
1498
+ const g = globalThis;
1499
+ const results = g.__REROUTE_SSR_RESULTS__;
1500
+ g.__REROUTE_SSR_RESULTS__ = {};
1501
+ return results;
1502
+ } catch {
1503
+ return;
1504
+ }
1505
+ }
1491
1506
  var init_collections = __esm(() => {
1492
1507
  init_imports();
1493
1508
  });
@@ -3608,23 +3623,34 @@ function parseAccessTracking(accessedCollections) {
3608
3623
  }
3609
3624
  return usage;
3610
3625
  }
3611
- function processCollections(accessedCollections, byCollectionForSSR) {
3626
+ function processCapturedResults(capturedResults, byCollectionForSSR) {
3612
3627
  const subset = {};
3613
3628
  const partial = {};
3614
3629
  try {
3615
3630
  const g = globalThis;
3616
- const ssrResults = g.__REROUTE_SSR_RESULTS__;
3617
- if (ssrResults && typeof ssrResults === "object") {
3618
- for (const [collection, items] of Object.entries(ssrResults)) {
3619
- if (Array.isArray(items) && items.length > 0) {
3620
- subset[collection] = items;
3621
- const full = byCollectionForSSR?.[collection] || [];
3622
- partial[collection] = items.length < full.length;
3623
- }
3631
+ const ssrResults = capturedResults ?? g.__REROUTE_SSR_RESULTS__;
3632
+ if (!ssrResults || typeof ssrResults !== "object")
3633
+ return;
3634
+ for (const [collection, items] of Object.entries(ssrResults)) {
3635
+ if (Array.isArray(items) && items.length > 0) {
3636
+ subset[collection] = items;
3637
+ const full = byCollectionForSSR?.[collection] || [];
3638
+ partial[collection] = items.length < full.length;
3624
3639
  }
3625
- return { subset, partial };
3626
3640
  }
3627
- } catch {}
3641
+ } catch {
3642
+ return;
3643
+ }
3644
+ if (Object.keys(subset).length === 0)
3645
+ return;
3646
+ return { subset, partial };
3647
+ }
3648
+ function processCollections(accessedCollections, byCollectionForSSR, capturedResults) {
3649
+ const captured = processCapturedResults(capturedResults, byCollectionForSSR);
3650
+ if (captured)
3651
+ return captured;
3652
+ const subset = {};
3653
+ const partial = {};
3628
3654
  const sortByDate = (order) => (a, b) => {
3629
3655
  const da = a?.meta?.date ? Date.parse(String(a.meta.date)) : 0;
3630
3656
  const db = b?.meta?.date ? Date.parse(String(b.meta.date)) : 0;
@@ -3913,6 +3939,7 @@ async function performSSRSetupInternal(options, streaming, timeoutState) {
3913
3939
  });
3914
3940
  assertNotTimedOut();
3915
3941
  resetSSRAccessTracking();
3942
+ resetSSRContentResults();
3916
3943
  const bundlePreload = createBundlePreload(bundleUrl);
3917
3944
  const preloadResult = await withSpan("ssr.preload", async (span) => {
3918
3945
  span.setAttribute("pathname", pathname);
@@ -3988,12 +4015,12 @@ async function performSSRSetupInternal(options, streaming, timeoutState) {
3988
4015
  pending: computeResult.pending
3989
4016
  };
3990
4017
  }
3991
- function generateCollectionScripts(byCollectionForSSR) {
4018
+ function generateCollectionScripts(byCollectionForSSR, capturedResults) {
3992
4019
  try {
3993
4020
  const g = globalThis;
3994
4021
  const acc = g.__REROUTE_SSR_ACCESSED__;
3995
4022
  if (acc) {
3996
- const { subset, partial } = processCollections(acc, byCollectionForSSR);
4023
+ const { subset, partial } = processCollections(acc, byCollectionForSSR, capturedResults);
3997
4024
  if (Object.keys(subset).length > 0) {
3998
4025
  return createCollectionScript(subset, partial);
3999
4026
  }
@@ -4145,13 +4172,16 @@ async function renderSSRDocument(options) {
4145
4172
  }, false);
4146
4173
  const duplicatedData = duplicateQueryParamData(setup2.ssrData);
4147
4174
  setGlobalSSRData(duplicatedData);
4175
+ let capturedResults;
4148
4176
  const appHtml = await withSpan("ssr.render.react", async (span) => {
4149
4177
  const componentWithPathname = cloneElement(rootComponent, {
4150
4178
  pathname,
4151
4179
  searchParams
4152
4180
  });
4153
4181
  span.setAttribute("reroute.pathname", pathname);
4182
+ resetSSRContentResults();
4154
4183
  const html3 = renderToString(componentWithPathname);
4184
+ capturedResults = takeSSRContentResults();
4155
4185
  span.setAttribute("reroute.html.final.size", html3.length);
4156
4186
  return html3;
4157
4187
  });
@@ -4160,7 +4190,7 @@ async function renderSSRDocument(options) {
4160
4190
  span.setAttribute("reroute.template.size", template2.length);
4161
4191
  return template2;
4162
4192
  });
4163
- const collectionScripts = generateCollectionScripts(setup2.byCollectionForSSR);
4193
+ const collectionScripts = generateCollectionScripts(setup2.byCollectionForSSR, capturedResults);
4164
4194
  const config = await loadConfig(cwd);
4165
4195
  const browserTelemetryConfigRaw = config.telemetry?.browser;
4166
4196
  const { serializeBrowserTelemetryConfig: serializeBrowserTelemetryConfig2 } = await Promise.resolve().then(() => exports_serialize);
@@ -4178,7 +4208,7 @@ async function renderSSRDocument(options) {
4178
4208
  if (setup2.metadataResult.statusOverride !== undefined) {
4179
4209
  statusOverride = setup2.metadataResult.statusOverride;
4180
4210
  }
4181
- const extraHead = setup2.bundlePreload + setup2.preloadExtraHead;
4211
+ const extraHead = appendLlmsAlternateHead(setup2.bundlePreload + setup2.preloadExtraHead, pathname, statusOverride || 200, config.llms);
4182
4212
  const combinedHead = dedent([
4183
4213
  dedent(head) || "",
4184
4214
  dedent(extraHead),
@@ -4208,6 +4238,7 @@ async function renderSSRDocument(options) {
4208
4238
  var init_render = __esm(() => {
4209
4239
  init_server2();
4210
4240
  init_config();
4241
+ init_discovery3();
4211
4242
  init_lib();
4212
4243
  init_html();
4213
4244
  });
@@ -4534,6 +4565,112 @@ var init_extractor = __esm(() => {
4534
4565
  init_render();
4535
4566
  });
4536
4567
 
4568
+ // packages/core/src/llms/discovery.ts
4569
+ function yesNo(value) {
4570
+ return value === false ? "no" : "yes";
4571
+ }
4572
+ function formatContentSignal(policy, whenUndefined = "omit") {
4573
+ if (policy === false)
4574
+ return;
4575
+ if (policy === undefined && whenUndefined === "omit")
4576
+ return;
4577
+ const resolved = {
4578
+ search: true,
4579
+ aiInput: true,
4580
+ aiTrain: true,
4581
+ ...policy
4582
+ };
4583
+ return `ai-train=${yesNo(resolved.aiTrain)}, search=${yesNo(resolved.search)}, ai-input=${yesNo(resolved.aiInput)}`;
4584
+ }
4585
+ function markdownTwinPath(pathname) {
4586
+ const path3 = pathname.split("?")[0];
4587
+ if (path3 === "/" || path3 === "")
4588
+ return "/index.md";
4589
+ return `${path3.replace(/\/$/, "")}.md`;
4590
+ }
4591
+ function shouldAdvertiseMarkdownTwin(pathname, llmsConfig) {
4592
+ if (!llmsConfig?.enabled)
4593
+ return false;
4594
+ if (llmsConfig.enableMarkdownExtension === false)
4595
+ return false;
4596
+ if (shouldExcludeRoute(pathname, llmsConfig.excludeRoutes))
4597
+ return false;
4598
+ return true;
4599
+ }
4600
+ function llmsAlternateLinkTag(pathname, llmsConfig) {
4601
+ if (!shouldAdvertiseMarkdownTwin(pathname, llmsConfig))
4602
+ return "";
4603
+ return `<link rel="alternate" type="text/markdown" href="${markdownTwinPath(pathname)}" />`;
4604
+ }
4605
+ function mergeVary(existing, token) {
4606
+ const parts = (existing ?? "").split(",").map((part) => part.trim()).filter(Boolean);
4607
+ if (!parts.some((part) => part.toLowerCase() === token.toLowerCase())) {
4608
+ parts.push(token);
4609
+ }
4610
+ return parts.join(", ");
4611
+ }
4612
+ function appendLinkValues(existing, values) {
4613
+ const current = (existing ?? "").split(",").map((part) => part.trim()).filter(Boolean);
4614
+ for (const value of values) {
4615
+ if (!current.includes(value))
4616
+ current.push(value);
4617
+ }
4618
+ return current.join(", ");
4619
+ }
4620
+ function buildLlmsDiscovery(pathname, llmsConfig) {
4621
+ if (!llmsConfig?.enabled)
4622
+ return null;
4623
+ const linkValues = [];
4624
+ if (shouldAdvertiseMarkdownTwin(pathname, llmsConfig)) {
4625
+ linkValues.push(`<${markdownTwinPath(pathname)}>; rel="alternate"; type="text/markdown"`);
4626
+ }
4627
+ if (llmsConfig.enableIndex !== false) {
4628
+ linkValues.push('</llms.txt>; rel="llms-txt"');
4629
+ }
4630
+ const contentSignal = formatContentSignal(llmsConfig.contentSignal, "default");
4631
+ const vary = llmsConfig.enableContentNegotiation !== false ? "Accept" : undefined;
4632
+ if (linkValues.length === 0 && !contentSignal && !vary)
4633
+ return null;
4634
+ return { linkValues, contentSignal, vary };
4635
+ }
4636
+ function writeHeader(headers2, canonical, value) {
4637
+ const lower = canonical.toLowerCase();
4638
+ if (headers2[lower] !== undefined)
4639
+ headers2[lower] = value;
4640
+ if (headers2[canonical] !== undefined || headers2[lower] === undefined) {
4641
+ headers2[canonical] = value;
4642
+ }
4643
+ }
4644
+ function readHeader(headers2, canonical) {
4645
+ return headers2[canonical] ?? headers2[canonical.toLowerCase()];
4646
+ }
4647
+ function applyLlmsDiscoveryHeaders(headers2, pathname, llmsConfig, status = 200) {
4648
+ if (status < 200 || status >= 300)
4649
+ return;
4650
+ const discovery2 = buildLlmsDiscovery(pathname, llmsConfig);
4651
+ if (!discovery2)
4652
+ return;
4653
+ if (discovery2.linkValues.length > 0) {
4654
+ writeHeader(headers2, "Link", appendLinkValues(readHeader(headers2, "Link"), discovery2.linkValues));
4655
+ }
4656
+ if (discovery2.contentSignal) {
4657
+ writeHeader(headers2, "Content-Signal", discovery2.contentSignal);
4658
+ }
4659
+ if (discovery2.vary) {
4660
+ writeHeader(headers2, "Vary", mergeVary(readHeader(headers2, "Vary"), discovery2.vary));
4661
+ }
4662
+ }
4663
+ function appendLlmsAlternateHead(extraHead, pathname, status, llmsConfig) {
4664
+ if (status !== 200)
4665
+ return extraHead;
4666
+ const tag = llmsAlternateLinkTag(pathname, llmsConfig);
4667
+ return tag ? `${extraHead}
4668
+ ${tag}` : extraHead;
4669
+ }
4670
+ var init_discovery3 = __esm(() => {
4671
+ init_extractor();
4672
+ });
4673
+
4537
4674
  // packages/core/src/llms/index-generator.ts
4538
4675
  var exports_index_generator = {};
4539
4676
  __export(exports_index_generator, {
@@ -5036,6 +5173,7 @@ var init_full_generator = __esm(() => {
5036
5173
 
5037
5174
  // packages/core/src/llms/index.ts
5038
5175
  var init_llms = __esm(() => {
5176
+ init_discovery3();
5039
5177
  init_extractor();
5040
5178
  init_full_generator();
5041
5179
  init_index_generator();
@@ -5202,7 +5340,7 @@ async function discoverRobotsData(cwd, isWatchMode, robotsConfig, sitemapConfig,
5202
5340
  redirectSourcePaths
5203
5341
  };
5204
5342
  }
5205
- var init_discovery3 = () => {};
5343
+ var init_discovery4 = () => {};
5206
5344
 
5207
5345
  // packages/core/src/robots/generator.ts
5208
5346
  function getEffectivePolicies(policies) {
@@ -5245,8 +5383,16 @@ function addDisallowDirectives(lines, policy, autoDisallows) {
5245
5383
  }
5246
5384
  }
5247
5385
  }
5248
- function addPolicyBlock(lines, policy, autoDisallows) {
5386
+ function addContentSignalLine(lines, policy, robotsConfig) {
5387
+ if (policy.userAgent !== "*")
5388
+ return;
5389
+ const value = formatContentSignal(robotsConfig.contentSignal);
5390
+ if (value)
5391
+ lines.push(`Content-Signal: ${value}`);
5392
+ }
5393
+ function addPolicyBlock(lines, policy, autoDisallows, robotsConfig) {
5249
5394
  lines.push(`User-agent: ${policy.userAgent}`);
5395
+ addContentSignalLine(lines, policy, robotsConfig);
5250
5396
  addAllowDirectives(lines, policy);
5251
5397
  addDisallowDirectives(lines, policy, autoDisallows);
5252
5398
  if (policy.crawlDelay !== undefined) {
@@ -5272,7 +5418,7 @@ function generateRobots(discovery2, robotsConfig, sitemapEnabled) {
5272
5418
  const effectivePolicies = getEffectivePolicies(policies);
5273
5419
  const autoDisallows = getAutoDisallows(discovery2);
5274
5420
  for (const policy of effectivePolicies) {
5275
- addPolicyBlock(lines, policy, autoDisallows);
5421
+ addPolicyBlock(lines, policy, autoDisallows, robotsConfig);
5276
5422
  }
5277
5423
  addGlobalCrawlDelay(lines, crawlDelay, effectivePolicies);
5278
5424
  if (customRules) {
@@ -5284,6 +5430,9 @@ function generateRobots(discovery2, robotsConfig, sitemapEnabled) {
5284
5430
  `).trim()}
5285
5431
  `;
5286
5432
  }
5433
+ var init_generator = __esm(() => {
5434
+ init_discovery3();
5435
+ });
5287
5436
 
5288
5437
  // packages/core/src/robots/policies.ts
5289
5438
  function blockAICrawlers(crawlers) {
@@ -5354,7 +5503,8 @@ var init_policies = __esm(() => {
5354
5503
 
5355
5504
  // packages/core/src/robots/index.ts
5356
5505
  var init_robots = __esm(() => {
5357
- init_discovery3();
5506
+ init_discovery4();
5507
+ init_generator();
5358
5508
  init_policies();
5359
5509
  });
5360
5510
 
@@ -5687,7 +5837,7 @@ async function discoverSitemapData(cwd, collections2, baseUrl, isWatchMode, site
5687
5837
  ssrDataRoutes
5688
5838
  };
5689
5839
  }
5690
- var init_discovery4 = () => {};
5840
+ var init_discovery5 = () => {};
5691
5841
 
5692
5842
  // packages/core/src/rss/discovery.ts
5693
5843
  import { pathToFileURL as pathToFileURL7 } from "node:url";
@@ -5955,7 +6105,7 @@ async function discoverRSSData(cwd, collections2, baseUrl, isWatchMode, rssConfi
5955
6105
  }
5956
6106
  const ssrDataFeeds = new Map;
5957
6107
  const bundledRoutes = globalThis.__REROUTE_ROUTES__;
5958
- const { discoverRoutes: discoverRoutes2 } = await Promise.resolve().then(() => (init_discovery4(), exports_discovery));
6108
+ const { discoverRoutes: discoverRoutes2 } = await Promise.resolve().then(() => (init_discovery5(), exports_discovery));
5959
6109
  const { staticRoutes } = await discoverRoutes2(cwd, isWatchMode);
5960
6110
  if (bundledRoutes && Array.isArray(bundledRoutes)) {
5961
6111
  const routePromises = staticRoutes.map(async (route) => {
@@ -6012,7 +6162,7 @@ async function discoverRSSData(cwd, collections2, baseUrl, isWatchMode, rssConfi
6012
6162
  ssrDataFeeds
6013
6163
  };
6014
6164
  }
6015
- var init_discovery5 = () => {};
6165
+ var init_discovery6 = () => {};
6016
6166
 
6017
6167
  // packages/core/src/rss/generator.ts
6018
6168
  function generateRSSXML(feed, options = {}) {
@@ -6125,7 +6275,7 @@ function escapeXml(unsafe) {
6125
6275
 
6126
6276
  // packages/core/src/rss/index.ts
6127
6277
  var init_rss = __esm(() => {
6128
- init_discovery5();
6278
+ init_discovery6();
6129
6279
  });
6130
6280
 
6131
6281
  // packages/core/src/sitemap/generator.ts
@@ -6270,12 +6420,12 @@ function escapeXml2(unsafe) {
6270
6420
  return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
6271
6421
  }
6272
6422
  var DEFAULT_MAX_URLS = 50000;
6273
- var init_generator = () => {};
6423
+ var init_generator2 = () => {};
6274
6424
 
6275
6425
  // packages/core/src/sitemap/index.ts
6276
6426
  var init_sitemap = __esm(() => {
6277
- init_discovery4();
6278
- init_generator();
6427
+ init_discovery5();
6428
+ init_generator2();
6279
6429
  });
6280
6430
 
6281
6431
  // packages/core/src/ssr/stream.ts
@@ -6353,15 +6503,16 @@ async function renderSSRDocumentStream(options) {
6353
6503
  const newAttrs = hasLang ? attrs.replace(/lang\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/i, `lang="${pageLang}"`) : `${attrs} lang="${pageLang}"`;
6354
6504
  return `<html${newAttrs}>`;
6355
6505
  });
6356
- const extraHead = setup2.bundlePreload + setup2.preloadExtraHead + setup2.metadataResult.perPageHead;
6357
- if (/<title[\s\S]*?<\/title>/i.test(extraHead)) {
6506
+ const extraHeadBase = setup2.bundlePreload + setup2.preloadExtraHead + setup2.metadataResult.perPageHead;
6507
+ if (/<title[\s\S]*?<\/title>/i.test(extraHeadBase)) {
6358
6508
  headWithLang = headWithLang.replace(/<title[\s\S]*?<\/title>/i, "");
6359
6509
  }
6360
- if (/<meta\s+name\s*=\s*['"]description['"][^>]*>/i.test(extraHead)) {
6510
+ if (/<meta\s+name\s*=\s*['"]description['"][^>]*>/i.test(extraHeadBase)) {
6361
6511
  headWithLang = headWithLang.replace(/<meta\s+name\s*=\s*['"]description['"][^>]*>/i, "");
6362
6512
  }
6363
- headWithLang = removeOverriddenMetaTags(headWithLang, extraHead);
6513
+ headWithLang = removeOverriddenMetaTags(headWithLang, extraHeadBase);
6364
6514
  const config = await loadConfig(cwd);
6515
+ const extraHead = appendLlmsAlternateHead(extraHeadBase, pathname, statusOverride || 200, config.llms);
6365
6516
  const browserTelemetryConfigRaw = config.telemetry?.browser;
6366
6517
  const { serializeBrowserTelemetryConfig: serializeBrowserTelemetryConfig2 } = await Promise.resolve().then(() => exports_serialize);
6367
6518
  const browserTelemetryConfig = serializeBrowserTelemetryConfig2(browserTelemetryConfigRaw);
@@ -6619,6 +6770,7 @@ function unescapeHtmlEntities(str) {
6619
6770
  var init_stream = __esm(() => {
6620
6771
  init_server2();
6621
6772
  init_config();
6773
+ init_discovery3();
6622
6774
  init_lib();
6623
6775
  init_html();
6624
6776
  init_imports();
@@ -6661,12 +6813,15 @@ __export(exports_core, {
6661
6813
  acceptsGzip: () => acceptsGzip,
6662
6814
  allowAICrawlers: () => allowAICrawlers,
6663
6815
  allowSearchCrawlers: () => allowSearchCrawlers,
6816
+ appendLlmsAlternateHead: () => appendLlmsAlternateHead,
6664
6817
  applyIndexTemplate: () => applyIndexTemplate,
6818
+ applyLlmsDiscoveryHeaders: () => applyLlmsDiscoveryHeaders,
6665
6819
  basename: () => basename,
6666
6820
  blockAICrawlers: () => blockAICrawlers,
6667
6821
  blockAITrainingCrawlers: () => blockAITrainingCrawlers,
6668
6822
  blockSearchCrawlers: () => blockSearchCrawlers,
6669
6823
  buildHeadFromMeta: () => buildHeadFromMeta,
6824
+ buildLlmsDiscovery: () => buildLlmsDiscovery,
6670
6825
  buildLocaleCookie: () => buildLocaleCookie,
6671
6826
  cleanupPathScopedSSRData: () => cleanupPathScopedSSRData,
6672
6827
  clearSSRModuleStores: () => clearSSRModuleStores,
@@ -6712,6 +6867,7 @@ __export(exports_core, {
6712
6867
  findOGImageForPath: () => findOGImageForPath,
6713
6868
  formatAsMarkdown: () => formatAsMarkdown,
6714
6869
  formatAsText: () => formatAsText,
6870
+ formatContentSignal: () => formatContentSignal,
6715
6871
  formatMessage: () => formatMessage,
6716
6872
  generateAtomXML: () => generateAtomXML,
6717
6873
  generateCollectionScripts: () => generateCollectionScripts,
@@ -6743,6 +6899,7 @@ __export(exports_core, {
6743
6899
  isThenable: () => isThenable,
6744
6900
  join: () => join2,
6745
6901
  listContentFiles: () => listContentFiles,
6902
+ llmsAlternateLinkTag: () => llmsAlternateLinkTag,
6746
6903
  loadCollections: () => loadCollections,
6747
6904
  loadConfig: () => loadConfig,
6748
6905
  loadIndexHtml: () => loadIndexHtml,
@@ -6752,9 +6909,11 @@ __export(exports_core, {
6752
6909
  localizeHref: () => localizeHref,
6753
6910
  looksLikeLocale: () => looksLikeLocale,
6754
6911
  lookupMessage: () => lookupMessage,
6912
+ markdownTwinPath: () => markdownTwinPath,
6755
6913
  matchRoutePattern: () => matchRoutePattern,
6756
6914
  matchRoutes: () => matchRoutes,
6757
6915
  mergeLayoutData: () => mergeLayoutData,
6916
+ mergeVary: () => mergeVary,
6758
6917
  negotiateLocale: () => negotiateLocale,
6759
6918
  normalizePathname: () => normalizePathname,
6760
6919
  parseContentPath: () => parseContentPath,
@@ -6767,10 +6926,12 @@ __export(exports_core, {
6767
6926
  renderSSRDocument: () => renderSSRDocument,
6768
6927
  renderSSRDocumentStream: () => renderSSRDocumentStream,
6769
6928
  resetSSRAccessTracking: () => resetSSRAccessTracking,
6929
+ resetSSRContentResults: () => resetSSRContentResults,
6770
6930
  resolveLocale: () => resolveLocale,
6771
6931
  seedSSRModuleForPath: () => seedSSRModuleForPath,
6772
6932
  setGlobalCollections: () => setGlobalCollections,
6773
6933
  setGlobalSSRData: () => setGlobalSSRData,
6934
+ shouldAdvertiseMarkdownTwin: () => shouldAdvertiseMarkdownTwin,
6774
6935
  shouldExcludeRoute: () => shouldExcludeRoute,
6775
6936
  splitTemplate: () => splitTemplate,
6776
6937
  ssrCache: () => ssrCache,
@@ -6778,6 +6939,7 @@ __export(exports_core, {
6778
6939
  stripEnd: () => stripEnd,
6779
6940
  stripHtmlTags: () => stripHtmlTags,
6780
6941
  stripStart: () => stripStart,
6942
+ takeSSRContentResults: () => takeSSRContentResults,
6781
6943
  toBytes: () => toBytes,
6782
6944
  toOgLocale: () => toOgLocale,
6783
6945
  toPromise: () => toPromise
@@ -107156,7 +107318,7 @@ async function getVersionString2() {
107156
107318
  }
107157
107319
  async function getVersion2() {
107158
107320
  if (true) {
107159
- return "1.0.0-alpha.7";
107321
+ return "1.0.0-alpha.9";
107160
107322
  }
107161
107323
  const possiblePaths = [
107162
107324
  path3.join(import.meta.dir, "../../../package.json"),
@@ -107173,10 +107335,10 @@ async function getVersion2() {
107173
107335
  }
107174
107336
  async function getCommit2() {
107175
107337
  if (true) {
107176
- return "19dcaf7";
107338
+ return "f5dd5ea";
107177
107339
  }
107178
107340
  return "dev";
107179
107341
  }
107180
107342
  main();
107181
107343
 
107182
- //# debugId=958B942751A1FF3B64756E2164756E21
107344
+ //# debugId=621D582CE8E376F164756E2164756E21