blume 1.7.3 → 2.0.0

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 (673) hide show
  1. package/AGENTS.md +19 -0
  2. package/CHANGELOG.md +217 -0
  3. package/README.md +34 -21
  4. package/dist/cli/chunk-11j0384y.js +148 -0
  5. package/dist/cli/chunk-11j0384y.js.map +10 -0
  6. package/dist/cli/{chunk-rqy0s5wh.js → chunk-1w8dp3qb.js} +17 -16
  7. package/dist/cli/{chunk-rqy0s5wh.js.map → chunk-1w8dp3qb.js.map} +3 -3
  8. package/dist/cli/chunk-2q1dwty4.js +75 -0
  9. package/dist/cli/chunk-2q1dwty4.js.map +11 -0
  10. package/dist/cli/chunk-41za066z.js +122 -0
  11. package/dist/cli/chunk-41za066z.js.map +11 -0
  12. package/dist/cli/chunk-5a2z0198.js +133 -0
  13. package/dist/cli/chunk-5a2z0198.js.map +10 -0
  14. package/dist/cli/{chunk-5g0w1e2c.js → chunk-6k8vp3ta.js} +25 -13
  15. package/dist/cli/{chunk-5g0w1e2c.js.map → chunk-6k8vp3ta.js.map} +4 -4
  16. package/dist/cli/{chunk-5qk08vmp.js → chunk-79njf86q.js} +133 -54
  17. package/dist/cli/chunk-79njf86q.js.map +11 -0
  18. package/dist/cli/{chunk-e7f42gdj.js → chunk-7ez8ny0t.js} +2 -2
  19. package/dist/cli/{chunk-nn13znc2.js → chunk-88cpgt6h.js} +1 -1
  20. package/dist/cli/chunk-a9kptbw5.js +361 -0
  21. package/dist/cli/chunk-a9kptbw5.js.map +14 -0
  22. package/dist/cli/chunk-abh8yjkn.js +31 -0
  23. package/dist/cli/chunk-abh8yjkn.js.map +10 -0
  24. package/dist/cli/chunk-b5aj94ah.js +91 -0
  25. package/dist/cli/chunk-b5aj94ah.js.map +10 -0
  26. package/dist/cli/{chunk-b27xqwn9.js → chunk-bctazmbk.js} +9 -5
  27. package/dist/cli/chunk-bctazmbk.js.map +10 -0
  28. package/dist/cli/chunk-beat36xx.js +279 -0
  29. package/dist/cli/chunk-beat36xx.js.map +10 -0
  30. package/dist/cli/chunk-bnbmcwfb.js +145 -0
  31. package/dist/cli/chunk-bnbmcwfb.js.map +11 -0
  32. package/dist/cli/{chunk-0xjyb285.js → chunk-bw22s759.js} +15 -5
  33. package/dist/cli/{chunk-0xjyb285.js.map → chunk-bw22s759.js.map} +4 -4
  34. package/dist/cli/chunk-by2290sx.js +39 -0
  35. package/dist/cli/chunk-by2290sx.js.map +10 -0
  36. package/dist/cli/chunk-d1tadaw7.js +79 -0
  37. package/dist/cli/chunk-d1tadaw7.js.map +10 -0
  38. package/dist/cli/{chunk-ahnw3kxw.js → chunk-d80hr03s.js} +24 -19
  39. package/dist/cli/chunk-d80hr03s.js.map +15 -0
  40. package/dist/cli/chunk-ernrthtr.js +97 -0
  41. package/dist/cli/chunk-ernrthtr.js.map +10 -0
  42. package/dist/cli/chunk-f2972sbt.js +374 -0
  43. package/dist/cli/chunk-f2972sbt.js.map +10 -0
  44. package/dist/cli/{chunk-vacwm2hv.js → chunk-f7t03s3g.js} +2 -2
  45. package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
  46. package/dist/cli/chunk-fa25z98p.js.map +11 -0
  47. package/dist/cli/{chunk-cjtn640a.js → chunk-fh5hj5jt.js} +43 -20
  48. package/dist/cli/chunk-fh5hj5jt.js.map +10 -0
  49. package/dist/cli/{chunk-yg63d42r.js → chunk-j8mw0za6.js} +86 -57
  50. package/dist/cli/chunk-j8mw0za6.js.map +35 -0
  51. package/dist/cli/{chunk-ct47dqpx.js → chunk-jts8mvcz.js} +67 -7
  52. package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
  53. package/dist/cli/{chunk-ps4m1xh4.js → chunk-mnqj32sj.js} +505 -542
  54. package/dist/cli/chunk-mnqj32sj.js.map +12 -0
  55. package/dist/cli/{chunk-8cjtbafj.js → chunk-mwt1k8n7.js} +100 -374
  56. package/dist/cli/chunk-mwt1k8n7.js.map +10 -0
  57. package/dist/cli/chunk-nk3ts2xk.js +51 -0
  58. package/dist/cli/chunk-nk3ts2xk.js.map +10 -0
  59. package/dist/cli/{chunk-3r45185y.js → chunk-pat2zzwc.js} +9 -11
  60. package/dist/cli/{chunk-3r45185y.js.map → chunk-pat2zzwc.js.map} +2 -2
  61. package/dist/cli/chunk-pnnvybbk.js +176 -0
  62. package/dist/cli/chunk-pnnvybbk.js.map +11 -0
  63. package/dist/cli/{chunk-4x36ddpw.js → chunk-sqn5t4q0.js} +81 -87
  64. package/dist/cli/chunk-sqn5t4q0.js.map +10 -0
  65. package/dist/cli/{chunk-bvwwhd84.js → chunk-tzne8qfq.js} +15 -15
  66. package/dist/cli/{chunk-bvwwhd84.js.map → chunk-tzne8qfq.js.map} +1 -1
  67. package/dist/cli/chunk-xaz13gwg.js +12449 -0
  68. package/dist/cli/chunk-xaz13gwg.js.map +182 -0
  69. package/dist/cli/chunk-y3e45rc8.js +102 -0
  70. package/dist/cli/chunk-y3e45rc8.js.map +10 -0
  71. package/dist/cli/chunk-z01ze5c1.js +261 -0
  72. package/dist/cli/chunk-z01ze5c1.js.map +10 -0
  73. package/dist/cli/{chunk-k79xp7av.js → chunk-z1f5arsg.js} +219 -689
  74. package/dist/cli/chunk-z1f5arsg.js.map +36 -0
  75. package/dist/cli/{chunk-1jefwnfs.js → chunk-zg2gtj10.js} +1076 -2592
  76. package/dist/cli/chunk-zg2gtj10.js.map +35 -0
  77. package/dist/cli/{chunk-dwgcp5sm.js → chunk-zxccj738.js} +1 -1
  78. package/dist/cli/index.js +214 -57
  79. package/dist/cli/index.js.map +8 -7
  80. package/dist/types/ai/agent-readability.d.ts +52 -0
  81. package/dist/types/ai/ai-catalog.d.ts +42 -0
  82. package/dist/types/ai/api/paths.d.ts +17 -0
  83. package/dist/types/ai/api-catalog.d.ts +18 -0
  84. package/dist/types/ai/ask.d.ts +368 -0
  85. package/dist/types/ai/changelog-markdown.d.ts +2 -0
  86. package/dist/types/ai/component-markdown.d.ts +2 -2
  87. package/dist/types/ai/index.d.ts +24 -0
  88. package/dist/types/ai/link-headers.d.ts +24 -0
  89. package/dist/types/ai/llms.d.ts +25 -0
  90. package/dist/types/ai/markdown.d.ts +45 -0
  91. package/dist/types/ai/mcp/discovery.d.ts +68 -0
  92. package/dist/types/ai/mcp/tools.d.ts +16 -0
  93. package/dist/types/ai/openapi-components.d.ts +43 -0
  94. package/dist/types/ai/relative-links.d.ts +26 -0
  95. package/dist/types/ai/serializers.d.ts +15 -0
  96. package/dist/types/ai/skills.d.ts +42 -0
  97. package/dist/types/ai/tar.d.ts +25 -0
  98. package/dist/types/ai/visibility.d.ts +17 -0
  99. package/dist/types/ai/web-bot-auth.d.ts +16 -0
  100. package/dist/types/analytics/adobe.d.ts +35 -0
  101. package/dist/types/analytics/amplitude.d.ts +50 -0
  102. package/dist/types/analytics/clarity.d.ts +31 -0
  103. package/dist/types/analytics/clearbit.d.ts +29 -0
  104. package/dist/types/analytics/cloudflare.d.ts +41 -0
  105. package/dist/types/analytics/fathom.d.ts +41 -0
  106. package/dist/types/analytics/google-analytics.d.ts +44 -0
  107. package/dist/types/analytics/google-tag-manager.d.ts +40 -0
  108. package/dist/types/analytics/head.d.ts +30 -0
  109. package/dist/types/analytics/heap.d.ts +40 -0
  110. package/dist/types/analytics/hightouch.d.ts +44 -0
  111. package/dist/types/analytics/hotjar.d.ts +33 -0
  112. package/dist/types/analytics/index.d.ts +61 -0
  113. package/dist/types/analytics/inline.d.ts +17 -0
  114. package/dist/types/analytics/logrocket.d.ts +44 -0
  115. package/dist/types/analytics/mixpanel.d.ts +67 -0
  116. package/dist/types/analytics/pirsch.d.ts +42 -0
  117. package/dist/types/analytics/plausible.d.ts +56 -0
  118. package/dist/types/analytics/posthog.d.ts +45 -0
  119. package/dist/types/analytics/schema.d.ts +320 -0
  120. package/dist/types/analytics/script.d.ts +46 -0
  121. package/dist/types/analytics/segment.d.ts +50 -0
  122. package/dist/types/analytics/vercel.d.ts +48 -0
  123. package/dist/types/astro/integration.d.ts +76 -0
  124. package/dist/types/astro/markdown-negotiation.d.ts +23 -0
  125. package/dist/types/astro/module-types.d.ts +14 -0
  126. package/dist/types/astro/pages.d.ts +44 -0
  127. package/dist/types/cli/env.d.ts +12 -0
  128. package/dist/types/cli/init/scaffold.d.ts +154 -0
  129. package/dist/types/components/layout/nav-utils.d.ts +11 -0
  130. package/dist/types/core/adapter.d.ts +47 -0
  131. package/dist/types/core/api-name.d.ts +7 -0
  132. package/dist/types/core/changelog-index.d.ts +13 -0
  133. package/dist/types/core/config-input.d.ts +186 -515
  134. package/dist/types/core/config.d.ts +60 -34
  135. package/dist/types/core/content-assets.d.ts +76 -0
  136. package/dist/types/core/custom-pages.d.ts +33 -0
  137. package/dist/types/core/data.d.ts +27 -12
  138. package/dist/types/core/define-components.d.ts +12 -9
  139. package/dist/types/core/deployment-env.d.ts +6 -11
  140. package/dist/types/core/frontmatter.d.ts +10 -0
  141. package/dist/types/core/graph.d.ts +18 -0
  142. package/dist/types/core/heading-markers.d.ts +54 -0
  143. package/dist/types/core/i18n-ui.d.ts +6 -2
  144. package/dist/types/core/i18n.d.ts +87 -0
  145. package/dist/types/core/includes.d.ts +138 -0
  146. package/dist/types/core/last-modified.d.ts +47 -0
  147. package/dist/types/core/links.d.ts +95 -0
  148. package/dist/types/core/locale-links.d.ts +60 -0
  149. package/dist/types/core/manifest.d.ts +17 -0
  150. package/dist/types/core/meta.d.ts +38 -0
  151. package/dist/types/core/nav-diagnostics.d.ts +26 -0
  152. package/dist/types/core/navigation.d.ts +6 -0
  153. package/dist/types/core/node-require.d.ts +19 -0
  154. package/dist/types/core/package-json.d.ts +13 -0
  155. package/dist/types/core/probe.d.ts +42 -0
  156. package/dist/types/core/project-graph.d.ts +51 -0
  157. package/dist/types/core/project.d.ts +2 -0
  158. package/dist/types/core/safe-href.d.ts +2 -0
  159. package/dist/types/core/safe-links.d.ts +26 -0
  160. package/dist/types/core/schema.d.ts +2282 -452
  161. package/dist/types/core/site-url.d.ts +16 -0
  162. package/dist/types/core/sources/assets.d.ts +36 -0
  163. package/dist/types/core/sources/cache.d.ts +37 -0
  164. package/dist/types/core/sources/collection.d.ts +28 -0
  165. package/dist/types/core/sources/contentful-rich-text.d.ts +31 -0
  166. package/dist/types/core/sources/contentful.d.ts +40 -0
  167. package/dist/types/core/sources/filesystem.d.ts +24 -0
  168. package/dist/types/core/sources/github-releases.d.ts +31 -0
  169. package/dist/types/core/sources/json.d.ts +30 -0
  170. package/dist/types/core/sources/lexical.d.ts +19 -0
  171. package/dist/types/core/sources/lower.d.ts +75 -0
  172. package/dist/types/core/sources/mdx-remote.d.ts +28 -0
  173. package/dist/types/core/sources/normalize.d.ts +147 -0
  174. package/dist/types/core/sources/notion.d.ts +131 -0
  175. package/dist/types/core/sources/obsidian.d.ts +46 -0
  176. package/dist/types/core/sources/payload.d.ts +39 -0
  177. package/dist/types/core/sources/portable-text.d.ts +42 -0
  178. package/dist/types/core/sources/read.d.ts +23 -0
  179. package/dist/types/core/sources/remote.d.ts +74 -0
  180. package/dist/types/core/sources/resolve.d.ts +19 -0
  181. package/dist/types/core/sources/sanity.d.ts +43 -0
  182. package/dist/types/core/sources/strapi-blocks.d.ts +12 -0
  183. package/dist/types/core/sources/strapi.d.ts +33 -0
  184. package/dist/types/core/sources/types.d.ts +7 -0
  185. package/dist/types/core/sources/watch.d.ts +45 -0
  186. package/dist/types/core/text-width.d.ts +11 -0
  187. package/dist/types/core/types.d.ts +15 -1
  188. package/dist/types/core/unrecognized-keys.d.ts +7 -0
  189. package/dist/types/core/versions.d.ts +72 -0
  190. package/dist/types/core/yaml.d.ts +9 -0
  191. package/dist/types/deploy/adapter-output.d.ts +45 -0
  192. package/dist/types/deploy/adapters/cloudflare.d.ts +40 -0
  193. package/dist/types/deploy/adapters/index.d.ts +29 -0
  194. package/dist/types/deploy/adapters/netlify.d.ts +37 -0
  195. package/dist/types/deploy/adapters/node.d.ts +37 -0
  196. package/dist/types/deploy/adapters/registry.d.ts +133 -0
  197. package/dist/types/deploy/adapters/types.d.ts +71 -0
  198. package/dist/types/deploy/adapters/vercel.d.ts +38 -0
  199. package/dist/types/deploy/artifacts.d.ts +65 -0
  200. package/dist/types/deploy/cloudflare-negotiation.d.ts +196 -0
  201. package/dist/types/deploy/function-bundle.d.ts +80 -0
  202. package/dist/types/deploy/headers.d.ts +50 -0
  203. package/dist/types/deploy/node-headers.d.ts +42 -0
  204. package/dist/types/deploy/platforms/cloudflare.d.ts +40 -0
  205. package/dist/types/deploy/platforms/index.d.ts +18 -0
  206. package/dist/types/deploy/platforms/netlify.d.ts +13 -0
  207. package/dist/types/deploy/platforms/node.d.ts +11 -0
  208. package/dist/types/deploy/platforms/paths.d.ts +27 -0
  209. package/dist/types/deploy/platforms/static.d.ts +10 -0
  210. package/dist/types/deploy/platforms/types.d.ts +104 -0
  211. package/dist/types/deploy/platforms/vercel.d.ts +32 -0
  212. package/dist/types/deploy/redirects.d.ts +53 -0
  213. package/dist/types/deploy/robots.d.ts +8 -0
  214. package/dist/types/deploy/rss.d.ts +31 -0
  215. package/dist/types/deploy/sitemap.d.ts +21 -0
  216. package/dist/types/deploy/vercel-negotiation.d.ts +109 -0
  217. package/dist/types/markdown/code-title.d.ts +32 -0
  218. package/dist/types/markdown/fence-meta.d.ts +23 -0
  219. package/dist/types/markdown/themes.d.ts +3 -3
  220. package/dist/types/openapi/asyncapi.d.ts +129 -0
  221. package/dist/types/openapi/graphql-build.d.ts +8 -0
  222. package/dist/types/openapi/graphql.d.ts +122 -0
  223. package/dist/types/openapi/model.d.ts +158 -0
  224. package/dist/types/openapi/parse.d.ts +57 -0
  225. package/dist/types/openapi/references.d.ts +37 -25
  226. package/dist/types/openapi/render-mdx.d.ts +33 -0
  227. package/dist/types/openapi/sentence.d.ts +7 -0
  228. package/dist/types/openapi/signature.d.ts +10 -0
  229. package/dist/types/openapi/source.d.ts +22 -0
  230. package/dist/types/openapi/spec-dependency-error.d.ts +10 -0
  231. package/dist/types/reference/asyncapi.d.ts +166 -0
  232. package/dist/types/reference/graphql.d.ts +181 -0
  233. package/dist/types/reference/index.d.ts +32 -0
  234. package/dist/types/reference/openapi.d.ts +165 -0
  235. package/dist/types/reference/options.d.ts +157 -0
  236. package/dist/types/reference/scalar.d.ts +136 -0
  237. package/dist/types/reference/schema.d.ts +630 -0
  238. package/dist/types/search/adapters/algolia.d.ts +32 -0
  239. package/dist/types/search/adapters/flexsearch.d.ts +12 -0
  240. package/dist/types/search/adapters/index.d.ts +31 -0
  241. package/dist/types/search/adapters/mixedbread.d.ts +22 -0
  242. package/dist/types/search/adapters/orama-cloud.d.ts +33 -0
  243. package/dist/types/search/adapters/orama.d.ts +13 -0
  244. package/dist/types/search/adapters/pagefind.d.ts +12 -0
  245. package/dist/types/search/adapters/registry.d.ts +228 -0
  246. package/dist/types/search/adapters/types.d.ts +34 -0
  247. package/dist/types/search/adapters/typesense.d.ts +42 -0
  248. package/dist/types/search/build.d.ts +23 -0
  249. package/dist/types/search/documents.d.ts +90 -0
  250. package/dist/types/search/facets.d.ts +3 -0
  251. package/dist/types/search/sync/algolia.d.ts +14 -0
  252. package/dist/types/search/sync/index.d.ts +14 -0
  253. package/dist/types/search/sync/orama-cloud.d.ts +10 -0
  254. package/dist/types/search/sync/typesense.d.ts +14 -0
  255. package/dist/types/sources/contentful.d.ts +68 -0
  256. package/dist/types/sources/custom.d.ts +20 -0
  257. package/dist/types/sources/filesystem.d.ts +42 -0
  258. package/dist/types/sources/github-releases.d.ts +46 -0
  259. package/dist/types/sources/index.d.ts +48 -0
  260. package/dist/types/sources/mdx-remote.d.ts +63 -0
  261. package/dist/types/sources/notion.d.ts +65 -0
  262. package/dist/types/sources/obsidian.d.ts +34 -0
  263. package/dist/types/sources/payload.d.ts +68 -0
  264. package/dist/types/sources/registry.d.ts +1414 -0
  265. package/dist/types/sources/sanity.d.ts +69 -0
  266. package/dist/types/sources/shared.d.ts +46 -0
  267. package/dist/types/sources/strapi.d.ts +66 -0
  268. package/dist/types/theme/icon-kind.d.ts +11 -0
  269. package/dist/types/theme/icons.d.ts +20 -0
  270. package/docs/01-quickstart.mdx +18 -18
  271. package/docs/02-deployment.mdx +50 -26
  272. package/docs/03-upgrading.mdx +351 -0
  273. package/docs/04-migrating.mdx +58 -0
  274. package/docs/08-faq.mdx +3 -3
  275. package/docs/advanced/blog.mdx +13 -6
  276. package/docs/advanced/changelog.mdx +23 -35
  277. package/docs/advanced/custom-pages.mdx +20 -8
  278. package/docs/advanced/meta.ts +1 -8
  279. package/docs/advanced/skills.mdx +8 -0
  280. package/docs/cli/audit.mdx +646 -0
  281. package/docs/cli/doctor.mdx +29 -0
  282. package/docs/{reference/eval.mdx → cli/evals.mdx} +9 -8
  283. package/docs/cli/index.mdx +105 -0
  284. package/docs/cli/meta.ts +7 -0
  285. package/docs/{reference → cli}/translate.mdx +1 -1
  286. package/docs/cli/validate.mdx +41 -0
  287. package/docs/cli/version.mdx +40 -0
  288. package/docs/configuration/analytics.mdx +350 -59
  289. package/docs/configuration/ask-ai.mdx +162 -61
  290. package/docs/configuration/customization.mdx +15 -9
  291. package/docs/configuration/index.mdx +50 -31
  292. package/docs/configuration/search.mdx +75 -54
  293. package/docs/configuration/theming.mdx +24 -15
  294. package/docs/content/components.mdx +21 -5
  295. package/docs/{reference → content}/frontmatter.mdx +35 -1
  296. package/docs/content/i18n.mdx +8 -6
  297. package/docs/content/includes.mdx +2 -4
  298. package/docs/content/index.mdx +1 -1
  299. package/docs/content/islands.mdx +10 -5
  300. package/docs/content/meta.mdx +1 -1
  301. package/docs/content/meta.ts +1 -0
  302. package/docs/content/navigation.mdx +9 -7
  303. package/docs/content/sources.mdx +145 -50
  304. package/docs/content/syntax.mdx +16 -12
  305. package/docs/content/versioning.mdx +3 -3
  306. package/docs/discoverability/agent-discovery.mdx +11 -11
  307. package/docs/discoverability/index.mdx +4 -4
  308. package/docs/discoverability/json-api.mdx +4 -4
  309. package/docs/discoverability/llms-txt.mdx +6 -6
  310. package/docs/discoverability/markdown.mdx +4 -4
  311. package/docs/discoverability/mcp.mdx +11 -11
  312. package/docs/discoverability/sitemap-and-robots.mdx +3 -3
  313. package/docs/index.mdx +2 -2
  314. package/docs/references/asyncapi.mdx +59 -0
  315. package/docs/{advanced → references}/graphql.mdx +45 -32
  316. package/docs/{reference → references}/meta.ts +2 -2
  317. package/docs/references/openapi.mdx +171 -0
  318. package/docs/references/scalar.mdx +64 -0
  319. package/package.json +42 -8
  320. package/skills/blume/SKILL.md +21 -8
  321. package/skills/blume-migrate/SKILL.md +22 -21
  322. package/skills/blume-migrate/assets/oxfmt@0.67.0.patch +49 -0
  323. package/skills/blume-migrate/references/docusaurus.md +5 -4
  324. package/skills/blume-migrate/references/fumadocs.md +4 -4
  325. package/skills/blume-migrate/references/mintlify.md +23 -8
  326. package/skills/blume-migrate/references/monorepo.md +6 -6
  327. package/skills/blume-migrate/references/starlight.md +4 -4
  328. package/src/ai/agent-readability.ts +21 -22
  329. package/src/ai/ai-catalog.ts +50 -32
  330. package/src/ai/api/handlers.ts +46 -11
  331. package/src/ai/api-catalog.ts +8 -8
  332. package/src/ai/ask-data.ts +1 -1
  333. package/src/ai/ask.ts +624 -100
  334. package/src/ai/changelog-markdown.ts +91 -0
  335. package/src/ai/component-markdown.ts +328 -12
  336. package/src/ai/index.ts +45 -0
  337. package/src/ai/link-headers.ts +7 -6
  338. package/src/ai/llms.ts +20 -15
  339. package/src/ai/markdown.ts +35 -5
  340. package/src/ai/mcp/data.ts +9 -5
  341. package/src/ai/openapi-components.ts +4 -1
  342. package/src/ai/relative-links.ts +170 -0
  343. package/src/ai/serializers.ts +2 -2
  344. package/src/ai/skills.ts +1 -1
  345. package/src/ai/web-bot-auth.ts +2 -2
  346. package/src/analytics/adobe.ts +46 -0
  347. package/src/analytics/amplitude.ts +79 -0
  348. package/src/analytics/clarity.ts +46 -0
  349. package/src/analytics/clearbit.ts +47 -0
  350. package/src/analytics/cloudflare.ts +67 -0
  351. package/src/analytics/fathom.ts +64 -0
  352. package/src/analytics/google-analytics.ts +84 -0
  353. package/src/analytics/google-tag-manager.ts +61 -0
  354. package/src/analytics/head.ts +130 -0
  355. package/src/analytics/heap.ts +65 -0
  356. package/src/analytics/hightouch.ts +77 -0
  357. package/src/analytics/hotjar.ts +47 -0
  358. package/src/analytics/index.ts +71 -0
  359. package/src/analytics/inline.ts +21 -0
  360. package/src/analytics/logrocket.ts +71 -0
  361. package/src/analytics/mixpanel.ts +92 -0
  362. package/src/analytics/pirsch.ts +66 -0
  363. package/src/analytics/plausible.ts +83 -0
  364. package/src/analytics/posthog.ts +78 -0
  365. package/src/analytics/schema.ts +60 -0
  366. package/src/analytics/script.ts +60 -0
  367. package/src/analytics/segment.ts +85 -0
  368. package/src/analytics/vercel.ts +50 -0
  369. package/src/astro/adapter-root.ts +7 -9
  370. package/src/astro/component-slots.ts +131 -91
  371. package/src/astro/generate.ts +112 -345
  372. package/src/astro/integration.ts +2 -6
  373. package/src/astro/pages.ts +13 -101
  374. package/src/astro/render-deps.ts +379 -0
  375. package/src/astro/runtime-deps.ts +201 -0
  376. package/src/astro/templates.ts +554 -541
  377. package/src/audit/agent.ts +24 -0
  378. package/src/audit/catalog.ts +2 -2
  379. package/src/audit/checks/assets.ts +2 -2
  380. package/src/audit/checks/dns-aid.ts +1 -1
  381. package/src/audit/checks/duplicates.ts +3 -1
  382. package/src/audit/checks/i18n.ts +1 -1
  383. package/src/audit/checks/indexability.ts +7 -7
  384. package/src/audit/checks/links.ts +2 -2
  385. package/src/audit/checks/llms.ts +6 -6
  386. package/src/audit/checks/network.ts +3 -3
  387. package/src/audit/checks/og-image.ts +2 -2
  388. package/src/audit/checks/robots.ts +1 -1
  389. package/src/audit/checks/sitemap.ts +2 -2
  390. package/src/audit/checks/social.ts +1 -1
  391. package/src/audit/run.ts +4 -3
  392. package/src/audit/terms.ts +31 -0
  393. package/src/audit/url.ts +13 -13
  394. package/src/cli/command-meta.ts +10 -0
  395. package/src/cli/commands/audit.ts +39 -20
  396. package/src/cli/commands/build.ts +71 -316
  397. package/src/cli/commands/check.ts +1 -0
  398. package/src/cli/commands/dev.ts +40 -1
  399. package/src/cli/commands/doctor.ts +90 -14
  400. package/src/cli/commands/eject.ts +44 -7
  401. package/src/cli/commands/eval.ts +2 -2
  402. package/src/cli/commands/init.ts +161 -41
  403. package/src/cli/commands/migrate.ts +121 -0
  404. package/src/cli/commands/preview.ts +7 -1
  405. package/src/cli/commands/translate.ts +2 -2
  406. package/src/cli/commands/upgrade.ts +141 -0
  407. package/src/cli/commands/version.ts +57 -44
  408. package/src/cli/eject-scripts.ts +121 -6
  409. package/src/cli/index.ts +11 -1
  410. package/src/cli/init/install.ts +70 -0
  411. package/src/cli/init/questions.ts +7 -0
  412. package/src/cli/init/scaffold.ts +459 -75
  413. package/src/cli/lazy-command.ts +37 -1
  414. package/src/cli/prepare.ts +40 -6
  415. package/src/cli/required-secrets.ts +38 -11
  416. package/src/cli/unknown-flags.ts +266 -0
  417. package/src/cli/yarn-pnp.ts +52 -0
  418. package/src/components/content/AccordionItem.astro +7 -1
  419. package/src/components/content/Card.astro +4 -3
  420. package/src/components/content/ColorItem.astro +22 -4
  421. package/src/components/content/GithubInfo.astro +2 -2
  422. package/src/components/content/Prompt.astro +25 -25
  423. package/src/components/content/Tabs.astro +3 -1
  424. package/src/components/content/Tile.astro +2 -3
  425. package/src/components/content/Tooltip.astro +57 -9
  426. package/src/components/content/content-strings.ts +34 -0
  427. package/src/components/content/diff.ts +1 -1
  428. package/src/components/content/mermaid-element.ts +13 -2
  429. package/src/components/content/prompt-markdown.ts +292 -0
  430. package/src/components/content/tooltip-id.ts +41 -0
  431. package/src/components/islands/hooks.ts +25 -2
  432. package/src/components/layout/Analytics.astro +21 -79
  433. package/src/components/layout/Banner.astro +3 -1
  434. package/src/components/layout/DiscoveryLinks.astro +69 -0
  435. package/src/components/layout/Header.astro +83 -20
  436. package/src/components/layout/LanguageSwitcher.astro +4 -1
  437. package/src/components/layout/Logo.astro +23 -2
  438. package/src/components/layout/NavSelector.astro +13 -2
  439. package/src/components/layout/NavTree.astro +12 -3
  440. package/src/components/layout/NavTreeScript.astro +17 -3
  441. package/src/components/layout/PageActions.astro +3 -3
  442. package/src/components/layout/PageFeedback.astro +11 -1
  443. package/src/components/layout/PageLayout.astro +52 -5
  444. package/src/components/layout/ReferenceLayout.astro +21 -12
  445. package/src/components/layout/RootLayout.astro +69 -66
  446. package/src/components/layout/Search.astro +30 -6
  447. package/src/components/layout/WebMcp.astro +1 -1
  448. package/src/components/layout/analytics-client.ts +72 -15
  449. package/src/components/layout/drawer-inert.ts +113 -15
  450. package/src/components/layout/dropdown-clamp.ts +105 -0
  451. package/src/components/layout/head-scripts.ts +15 -6
  452. package/src/components/layout/nav-utils.ts +17 -0
  453. package/src/components/layout/search/algolia.ts +8 -8
  454. package/src/components/layout/search/orama-cloud.ts +9 -7
  455. package/src/components/layout/search/typesense.ts +11 -17
  456. package/src/components/openapi/MessageComposer.astro +2 -2
  457. package/src/components/openapi/Playground.astro +2 -2
  458. package/src/components/openapi/playground-client.ts +79 -10
  459. package/src/core/changelog-index.ts +24 -0
  460. package/src/core/component-overrides.ts +399 -154
  461. package/src/core/config-input.ts +188 -553
  462. package/src/core/config.ts +130 -41
  463. package/src/core/custom-pages.ts +105 -0
  464. package/src/core/data.ts +31 -12
  465. package/src/core/define-components.ts +12 -9
  466. package/src/core/deployment-env.ts +18 -74
  467. package/src/core/diagnostics.ts +14 -7
  468. package/src/core/graph.ts +69 -25
  469. package/src/core/i18n-ui.ts +6 -2
  470. package/src/core/i18n.ts +17 -0
  471. package/src/core/includes.ts +156 -38
  472. package/src/core/last-modified.ts +6 -11
  473. package/src/core/links.ts +166 -2
  474. package/src/core/manifest.ts +10 -3
  475. package/src/core/navigation.ts +115 -16
  476. package/src/core/new-tab.ts +35 -0
  477. package/src/core/node-require.ts +21 -0
  478. package/src/core/project-graph.ts +42 -26
  479. package/src/core/project.ts +9 -4
  480. package/src/core/request-body.ts +61 -0
  481. package/src/core/safe-href.ts +28 -0
  482. package/src/core/safe-links.ts +68 -0
  483. package/src/core/schema.ts +517 -739
  484. package/src/core/server-features.ts +8 -9
  485. package/src/core/sources/assets.ts +47 -11
  486. package/src/core/sources/collection.ts +67 -0
  487. package/src/core/sources/contentful-rich-text.ts +285 -0
  488. package/src/core/sources/contentful.ts +173 -0
  489. package/src/core/sources/github-releases.ts +51 -1
  490. package/src/core/sources/json.ts +71 -0
  491. package/src/core/sources/lexical.ts +195 -0
  492. package/src/core/sources/lower.ts +226 -0
  493. package/src/core/sources/normalize.ts +52 -2
  494. package/src/core/sources/notion.ts +39 -28
  495. package/src/core/sources/payload.ts +135 -0
  496. package/src/core/sources/portable-text.ts +11 -16
  497. package/src/core/sources/remote.ts +226 -0
  498. package/src/core/sources/resolve.ts +104 -166
  499. package/src/core/sources/sanity.ts +16 -49
  500. package/src/core/sources/strapi-blocks.ts +124 -0
  501. package/src/core/sources/strapi.ts +191 -0
  502. package/src/core/sources/types.ts +12 -1
  503. package/src/core/types.ts +15 -1
  504. package/src/core/ui-packs/ar.ts +6 -2
  505. package/src/core/ui-packs/bg.ts +6 -2
  506. package/src/core/ui-packs/bn.ts +6 -2
  507. package/src/core/ui-packs/ca.ts +3 -1
  508. package/src/core/ui-packs/cs.ts +6 -2
  509. package/src/core/ui-packs/da.ts +6 -2
  510. package/src/core/ui-packs/de.ts +6 -2
  511. package/src/core/ui-packs/el.ts +3 -1
  512. package/src/core/ui-packs/es.ts +3 -1
  513. package/src/core/ui-packs/fa.ts +6 -2
  514. package/src/core/ui-packs/fi.ts +6 -2
  515. package/src/core/ui-packs/fr.ts +3 -1
  516. package/src/core/ui-packs/he.ts +6 -2
  517. package/src/core/ui-packs/hi.ts +6 -2
  518. package/src/core/ui-packs/hr.ts +6 -2
  519. package/src/core/ui-packs/hu.ts +6 -2
  520. package/src/core/ui-packs/id.ts +6 -2
  521. package/src/core/ui-packs/it.ts +3 -1
  522. package/src/core/ui-packs/ja.ts +3 -1
  523. package/src/core/ui-packs/ko.ts +3 -1
  524. package/src/core/ui-packs/nl.ts +6 -2
  525. package/src/core/ui-packs/no.ts +6 -2
  526. package/src/core/ui-packs/pl.ts +6 -2
  527. package/src/core/ui-packs/pt-br.ts +3 -1
  528. package/src/core/ui-packs/pt.ts +3 -1
  529. package/src/core/ui-packs/ro.ts +6 -2
  530. package/src/core/ui-packs/ru.ts +6 -2
  531. package/src/core/ui-packs/sk.ts +6 -2
  532. package/src/core/ui-packs/sr.ts +6 -2
  533. package/src/core/ui-packs/sv.ts +6 -2
  534. package/src/core/ui-packs/th.ts +3 -1
  535. package/src/core/ui-packs/tr.ts +6 -2
  536. package/src/core/ui-packs/uk.ts +6 -2
  537. package/src/core/ui-packs/vi.ts +3 -1
  538. package/src/core/ui-packs/zh-tw.ts +3 -1
  539. package/src/core/ui-packs/zh.ts +3 -1
  540. package/src/core/unrecognized-keys.ts +10 -0
  541. package/src/core/version-cut.ts +116 -8
  542. package/src/deploy/adapter-output.ts +57 -97
  543. package/src/deploy/adapters/cloudflare.ts +39 -0
  544. package/src/deploy/adapters/index.ts +41 -0
  545. package/src/deploy/adapters/netlify.ts +34 -0
  546. package/src/deploy/adapters/node.ts +34 -0
  547. package/src/deploy/adapters/registry.ts +127 -0
  548. package/src/deploy/adapters/types.ts +92 -0
  549. package/src/deploy/adapters/vercel.ts +35 -0
  550. package/src/deploy/artifacts.ts +55 -27
  551. package/src/deploy/cloudflare-negotiation.ts +179 -100
  552. package/src/deploy/function-bundle.ts +18 -3
  553. package/src/deploy/headers.ts +124 -23
  554. package/src/deploy/node-headers.ts +198 -0
  555. package/src/deploy/platforms/cloudflare.ts +312 -0
  556. package/src/deploy/platforms/index.ts +67 -0
  557. package/src/deploy/platforms/netlify.ts +52 -0
  558. package/src/deploy/platforms/node.ts +40 -0
  559. package/src/deploy/platforms/paths.ts +42 -0
  560. package/src/deploy/platforms/static.ts +29 -0
  561. package/src/deploy/platforms/types.ts +112 -0
  562. package/src/deploy/platforms/vercel.ts +193 -0
  563. package/src/deploy/redirects.ts +30 -18
  564. package/src/deploy/robots.ts +3 -3
  565. package/src/deploy/rss.ts +2 -2
  566. package/src/deploy/sitemap.ts +2 -2
  567. package/src/deploy/vercel-negotiation.ts +2 -2
  568. package/src/eval/agents.ts +32 -1
  569. package/src/eval/findings.ts +19 -11
  570. package/src/eval/report.ts +10 -2
  571. package/src/markdown/external-links.ts +65 -0
  572. package/src/markdown/include.ts +45 -27
  573. package/src/markdown/index.ts +34 -9
  574. package/src/markdown/inline-code.ts +12 -6
  575. package/src/markdown/relative-links.ts +324 -0
  576. package/src/markdown/themes.ts +3 -3
  577. package/src/migrate/migrate.ts +149 -0
  578. package/src/openapi/parse.ts +64 -16
  579. package/src/openapi/proxy.ts +62 -10
  580. package/src/openapi/references.ts +147 -147
  581. package/src/openapi/render-mdx.ts +32 -10
  582. package/src/openapi/scalar.ts +15 -13
  583. package/src/openapi/sentence.ts +14 -0
  584. package/src/openapi/source.ts +37 -21
  585. package/src/openapi/spec-dependency-error.ts +15 -0
  586. package/src/reference/asyncapi.ts +83 -0
  587. package/src/reference/graphql.ts +89 -0
  588. package/src/reference/index.ts +40 -0
  589. package/src/reference/openapi.ts +83 -0
  590. package/src/reference/options.ts +201 -0
  591. package/src/reference/scalar.ts +136 -0
  592. package/src/reference/schema.ts +88 -0
  593. package/src/registry/eject.ts +97 -42
  594. package/src/search/adapters/algolia.ts +46 -0
  595. package/src/search/adapters/flexsearch.ts +29 -0
  596. package/src/search/adapters/index.ts +39 -0
  597. package/src/search/adapters/mixedbread.ts +39 -0
  598. package/src/search/adapters/orama-cloud.ts +51 -0
  599. package/src/search/adapters/orama.ts +24 -0
  600. package/src/search/adapters/pagefind.ts +27 -0
  601. package/src/search/adapters/registry.ts +131 -0
  602. package/src/search/adapters/types.ts +46 -0
  603. package/src/search/adapters/typesense.ts +57 -0
  604. package/src/search/build.ts +8 -4
  605. package/src/search/documents.ts +6 -0
  606. package/src/search/sync/algolia.ts +12 -11
  607. package/src/search/sync/index.ts +35 -20
  608. package/src/search/sync/orama-cloud.ts +12 -9
  609. package/src/search/sync/typesense.ts +15 -13
  610. package/src/sources/contentful.ts +63 -0
  611. package/src/sources/custom.ts +38 -0
  612. package/src/sources/filesystem.ts +51 -0
  613. package/src/sources/github-releases.ts +52 -0
  614. package/src/sources/index.ts +60 -0
  615. package/src/sources/mdx-remote.ts +76 -0
  616. package/src/sources/notion.ts +63 -0
  617. package/src/sources/obsidian.ts +38 -0
  618. package/src/sources/payload.ts +60 -0
  619. package/src/sources/registry.ts +182 -0
  620. package/src/sources/sanity.ts +66 -0
  621. package/src/sources/shared.ts +52 -0
  622. package/src/sources/strapi.ts +58 -0
  623. package/src/theme/entry.ts +24 -2
  624. package/src/translate/report.ts +40 -7
  625. package/src/upgrade/upgrade.ts +499 -0
  626. package/dist/cli/chunk-0qymqwzz.js +0 -164
  627. package/dist/cli/chunk-0qymqwzz.js.map +0 -15
  628. package/dist/cli/chunk-1jefwnfs.js.map +0 -48
  629. package/dist/cli/chunk-2mzebbbz.js +0 -69
  630. package/dist/cli/chunk-2z47ypj8.js.map +0 -11
  631. package/dist/cli/chunk-4x36ddpw.js.map +0 -11
  632. package/dist/cli/chunk-5093q3n7.js +0 -68
  633. package/dist/cli/chunk-5093q3n7.js.map +0 -10
  634. package/dist/cli/chunk-5qk08vmp.js.map +0 -11
  635. package/dist/cli/chunk-7s8hm3b6.js +0 -5347
  636. package/dist/cli/chunk-7s8hm3b6.js.map +0 -58
  637. package/dist/cli/chunk-8cjtbafj.js.map +0 -13
  638. package/dist/cli/chunk-97r59kpr.js +0 -381
  639. package/dist/cli/chunk-97r59kpr.js.map +0 -12
  640. package/dist/cli/chunk-ahnw3kxw.js.map +0 -15
  641. package/dist/cli/chunk-b27xqwn9.js.map +0 -10
  642. package/dist/cli/chunk-bf6bt1xt.js +0 -185
  643. package/dist/cli/chunk-bf6bt1xt.js.map +0 -11
  644. package/dist/cli/chunk-cjtn640a.js.map +0 -10
  645. package/dist/cli/chunk-ct47dqpx.js.map +0 -11
  646. package/dist/cli/chunk-esphfr8p.js +0 -107
  647. package/dist/cli/chunk-esphfr8p.js.map +0 -11
  648. package/dist/cli/chunk-ex56aa81.js +0 -1016
  649. package/dist/cli/chunk-ex56aa81.js.map +0 -13
  650. package/dist/cli/chunk-garjf5z9.js +0 -30
  651. package/dist/cli/chunk-garjf5z9.js.map +0 -10
  652. package/dist/cli/chunk-js7saxwm.js +0 -1045
  653. package/dist/cli/chunk-js7saxwm.js.map +0 -22
  654. package/dist/cli/chunk-k79xp7av.js.map +0 -39
  655. package/dist/cli/chunk-ps4m1xh4.js.map +0 -15
  656. package/dist/cli/chunk-q4rae3bg.js +0 -60
  657. package/dist/cli/chunk-q4rae3bg.js.map +0 -10
  658. package/dist/cli/chunk-rz9jmfhz.js +0 -108
  659. package/dist/cli/chunk-rz9jmfhz.js.map +0 -10
  660. package/dist/cli/chunk-vh9w1sgp.js +0 -73
  661. package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
  662. package/dist/cli/chunk-vrfp10qk.js +0 -81
  663. package/dist/cli/chunk-vrfp10qk.js.map +0 -10
  664. package/dist/cli/chunk-yg63d42r.js.map +0 -34
  665. package/docs/advanced/api-reference.mdx +0 -240
  666. package/docs/reference/cli.mdx +0 -197
  667. package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
  668. package/src/components/content/changelog-element.ts +0 -69
  669. package/src/search/providers.ts +0 -91
  670. /package/dist/cli/{chunk-e7f42gdj.js.map → chunk-7ez8ny0t.js.map} +0 -0
  671. /package/dist/cli/{chunk-nn13znc2.js.map → chunk-88cpgt6h.js.map} +0 -0
  672. /package/dist/cli/{chunk-vacwm2hv.js.map → chunk-f7t03s3g.js.map} +0 -0
  673. /package/dist/cli/{chunk-dwgcp5sm.js.map → chunk-zxccj738.js.map} +0 -0
@@ -1,173 +1,121 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- OPENAPI_PATH,
4
- API_CATALOG_PATH,
5
- hasApiCatalog,
6
- AI_CATALOG_PATH,
7
- AI_CATALOG_TYPE,
8
- hasAiCatalog
9
- } from "./chunk-0qymqwzz.js";
3
+ trimChar,
4
+ normalizeBasePath
5
+ } from "./chunk-jts8mvcz.js";
10
6
  import {
7
+ buildHomeLinkHeader,
8
+ resolveDocsCollection,
11
9
  TOC_HIDDEN_KEY,
12
- BLUME_IGNORE_DIRS
13
- } from "./chunk-1jefwnfs.js";
14
- import {
15
- hasScalarReferences,
10
+ deployPassthrough,
16
11
  fontLocaleCodes,
17
- buildFontEntries
18
- } from "./chunk-7s8hm3b6.js";
19
- import {
20
- searchProviderMeta
21
- } from "./chunk-q4rae3bg.js";
12
+ buildFontEntries,
13
+ applyBaseToAstroRedirects,
14
+ distDir,
15
+ adapterRoot,
16
+ SVG_ASSET_POLICY,
17
+ deployPlatform
18
+ } from "./chunk-xaz13gwg.js";
22
19
  import {
23
- trimChar,
24
- normalizeBasePath,
25
- withBasePath,
26
- withComposedBasePath
27
- } from "./chunk-2mzebbbz.js";
28
-
29
- // src/deploy/adapter-output.ts
30
- import { existsSync } from "node:fs";
31
- import { cp, mkdir, rm } from "node:fs/promises";
32
- import { dirname, join } from "pathe";
33
- var ADAPTER_IGNORE_DIRS = {
34
- netlify: ".netlify/",
35
- vercel: ".vercel/"
36
- };
37
- var ADAPTER_OUTPUT_PATHS = {
38
- netlify: ".netlify/v1"
39
- };
40
- var servesClientSubdir = (deployment) => deployment.output === "server" && (deployment.adapter === "node" || deployment.adapter === "cloudflare");
41
- var deployStaticDir = (config, context) => {
42
- const { adapter, output } = config.deployment;
43
- if (output === "server" && adapter === "vercel") {
44
- return join(context.root, ".vercel", "output", "static");
45
- }
46
- const dist = context.distDir ?? join(context.root, "dist");
47
- if (servesClientSubdir(config.deployment)) {
48
- return join(dist, "client");
49
- }
50
- return dist;
51
- };
52
- var surfaceAdapterOutput = async (config, context) => {
53
- const { adapter, output } = config.deployment;
54
- if (output !== "server" || !adapter) {
55
- return { moved: false };
56
- }
57
- const rel = ADAPTER_OUTPUT_PATHS[adapter];
58
- if (!rel) {
59
- return { moved: false };
60
- }
61
- const from = join(context.outDir, rel);
62
- const to = join(context.root, rel);
63
- if (!existsSync(from)) {
64
- return { moved: false };
20
+ BLUME_IGNORE_DIRS
21
+ } from "./chunk-abh8yjkn.js";
22
+
23
+ // src/astro/component-slots.ts
24
+ import { isAbsolute, join, relative } from "pathe";
25
+ var attributeValue = (value) => value.replaceAll(/["\n\r]/gu, " ").trim();
26
+ var CLIENT_LOAD = "client:load";
27
+ var directiveFor = (override) => {
28
+ const { framework } = override.source;
29
+ switch (override.client) {
30
+ case "idle": {
31
+ return "client:idle";
32
+ }
33
+ case "visible": {
34
+ return "client:visible";
35
+ }
36
+ case "media": {
37
+ return override.media ? `client:media="${attributeValue(override.media)}"` : CLIENT_LOAD;
38
+ }
39
+ case "only": {
40
+ return framework ? `client:only="${attributeValue(framework)}"` : CLIENT_LOAD;
41
+ }
42
+ default: {
43
+ return CLIENT_LOAD;
44
+ }
65
45
  }
66
- await mkdir(dirname(to), { recursive: true });
67
- await rm(to, { force: true, recursive: true });
68
- await cp(from, to, { recursive: true, verbatimSymlinks: true });
69
- await rm(from, { force: true, recursive: true });
70
- return { from, moved: true, to };
71
46
  };
72
-
73
- // src/ai/link-headers.ts
74
- var buildHomeLinkHeader = (config, routePaths) => {
75
- const deployBase = normalizeBasePath(config.deployment.base);
76
- const links = [];
77
- if (hasApiCatalog(config)) {
78
- links.push(`<${deployBase}${API_CATALOG_PATH}>; rel="api-catalog"; type="application/linkset+json"`);
79
- }
80
- if (hasAiCatalog(config)) {
81
- links.push(`<${deployBase}${AI_CATALOG_PATH}>; rel="ai-catalog"; type="${AI_CATALOG_TYPE}"`);
82
- }
83
- if (config.ai.api) {
84
- links.push(`<${deployBase}${OPENAPI_PATH}>; rel="service-desc"; type="application/json"`);
85
- }
86
- if (config.seo.agentReadability) {
87
- links.push(`<${deployBase}/agent-readability.json>; rel="describedby"; type="application/json"`);
88
- }
89
- if (config.ai.llmsTxt.enabled) {
90
- links.push(`<${deployBase}/llms.txt>; rel="describedby"; type="text/plain"`);
47
+ var importSpecifier = (path, fromDir) => {
48
+ if (fromDir === undefined || !isAbsolute(path)) {
49
+ return path;
91
50
  }
92
- if (routePaths.includes("/")) {
93
- links.push(`<${deployBase}/index.md>; rel="alternate"; type="text/markdown"`);
51
+ const specifier = relative(fromDir, path);
52
+ if (isAbsolute(specifier) || specifier.startsWith("../")) {
53
+ return specifier;
94
54
  }
95
- return links.length > 0 ? links.join(", ") : null;
55
+ return `./${specifier}`;
96
56
  };
97
-
98
- // src/deploy/redirects.ts
99
- var applyBaseToAstroRedirects = (redirects, basePath, deployBase) => {
100
- const base = normalizeBasePath(deployBase);
101
- return basePath || base ? redirects.map((redirect) => ({
102
- ...redirect,
103
- from: withBasePath(basePath, redirect.from),
104
- to: withComposedBasePath(base, basePath, redirect.to)
105
- })) : redirects;
106
- };
107
- var applyBaseToPlatformRedirects = (redirects, basePath, deployBase) => {
108
- const base = normalizeBasePath(deployBase);
109
- return basePath || base ? redirects.map((redirect) => ({
110
- ...redirect,
111
- from: withComposedBasePath(base, basePath, redirect.from),
112
- to: withComposedBasePath(base, basePath, redirect.to)
113
- })) : redirects;
114
- };
115
- var platformRedirects = (config) => applyBaseToPlatformRedirects(config.redirects, config.basePath, config.deployment.base ?? "");
116
-
117
- // src/ai/ask.ts
118
- var OPENAI_COMPATIBLE = "openai-compatible";
119
- var OPENAI_COMPATIBLE_DEP = "@ai-sdk/openai-compatible";
120
- var ASK_PRESETS = {
121
- inkeep: {
122
- apiKeyEnv: "INKEEP_API_KEY",
123
- baseUrl: "https://api.inkeep.com/v1",
124
- kind: OPENAI_COMPATIBLE,
125
- name: "inkeep",
126
- runtimeDep: OPENAI_COMPATIBLE_DEP
127
- },
128
- llmgateway: {
129
- apiKeyEnv: "LLMGATEWAY_API_KEY",
130
- baseUrl: "https://api.llmgateway.io/v1",
131
- kind: OPENAI_COMPATIBLE,
132
- name: "llmgateway",
133
- runtimeDep: OPENAI_COMPATIBLE_DEP
134
- },
135
- openrouter: {
136
- apiKeyEnv: "OPENROUTER_API_KEY",
137
- kind: "openrouter",
138
- name: "openrouter",
139
- runtimeDep: "@openrouter/ai-sdk-provider"
140
- }
141
- };
142
- var DEFAULT_MODEL = "openai/gpt-5.5";
143
- var askHeadersField = (ask) => ask?.headers && Object.keys(ask.headers).length > 0 ? { headers: ask.headers } : {};
144
- var resolveAskBackend = (ask) => {
145
- const provider = ask?.provider ?? "gateway";
146
- const model = ask?.model ?? DEFAULT_MODEL;
147
- const headers = askHeadersField(ask);
148
- if (provider === "gateway") {
149
- return { ...headers, kind: "gateway", model };
150
- }
151
- const preset = ASK_PRESETS[provider];
152
- const apiKeyEnv = ask?.apiKeyEnv ?? preset?.apiKeyEnv ?? "API_KEY";
153
- if (provider === "openrouter") {
154
- return { apiKeyEnv, ...headers, kind: "openrouter", model };
155
- }
156
- return {
157
- apiKeyEnv,
158
- baseUrl: ask?.baseUrl ?? preset?.baseUrl ?? "",
159
- ...headers,
160
- kind: OPENAI_COMPATIBLE,
161
- model,
162
- name: preset?.name ?? OPENAI_COMPATIBLE
57
+ var importClause = (variable, name, path) => name === "default" ? `import ${variable} from ${JSON.stringify(path)};` : `import { ${name} as ${variable} } from ${JSON.stringify(path)};`;
58
+ var wrapperPropsType = (name) => `type Props = typeof ${name} extends (
59
+ props: infer P extends object,
60
+ ...rest: never[]
61
+ ) => unknown
62
+ ? P
63
+ : Record<string, unknown>;`;
64
+ var wrapperContent = (override, fromDir) => `---
65
+ // Generated by Blume. Do not edit.
66
+ ${importClause("Component", override.source.name, importSpecifier(override.source.path, fromDir))}
67
+ ${wrapperPropsType("Component")}
68
+ ---
69
+ <Component ${directiveFor(override)} {...Astro.props}><slot /></Component>
70
+ `;
71
+ var sanitize = (value) => value.replaceAll(/[^A-Za-z0-9]/gu, (char) => `_${(char.codePointAt(0) ?? 0).toString(16)}_`);
72
+ var islandOverride = (island) => ({
73
+ client: island.client,
74
+ key: island.name,
75
+ source: { framework: island.framework, name: "default", path: island.file }
76
+ });
77
+ var record = (entries) => entries.length ? `{ ${entries.join(", ")} }` : "{}";
78
+ var planComponentSlots = (islands, analysis, options = {}) => {
79
+ const { relativeTo } = options;
80
+ const wrapperDir = relativeTo === undefined ? undefined : join(relativeTo, "component-slots");
81
+ const frameworks = new Set;
82
+ const wrappers = [];
83
+ const importLines = [];
84
+ let counter = 0;
85
+ const plan = (overrides, group) => {
86
+ const byKey = new Map;
87
+ for (const override of overrides) {
88
+ byKey.set(override.key, override);
89
+ }
90
+ const entries = [];
91
+ for (const override of byKey.values()) {
92
+ const { source } = override;
93
+ if (source.framework) {
94
+ frameworks.add(source.framework);
95
+ }
96
+ const variable = `__blumeSlot${counter}`;
97
+ counter += 1;
98
+ if (override.client) {
99
+ const name = `${group}-${sanitize(override.key)}`;
100
+ wrappers.push({ content: wrapperContent(override, wrapperDir), name });
101
+ importLines.push(importClause(variable, "default", `./component-slots/${name}.astro`));
102
+ } else {
103
+ importLines.push(importClause(variable, source.name, importSpecifier(source.path, relativeTo)));
104
+ }
105
+ entries.push(`${JSON.stringify(override.key)}: ${variable}`);
106
+ }
107
+ return entries;
163
108
  };
164
- };
165
- var askBackendRuntimeDep = (ask) => {
166
- const provider = ask?.provider ?? "gateway";
167
- if (provider === "gateway") {
168
- return;
169
- }
170
- return ASK_PRESETS[provider]?.runtimeDep ?? OPENAI_COMPATIBLE_DEP;
109
+ const mdxEntries = plan([...islands.map(islandOverride), ...analysis.mdx], "mdx");
110
+ const layoutEntries = plan(analysis.layout, "layout");
111
+ const module = `// Generated by Blume. Do not edit.
112
+ import type { ComponentOverride } from "blume/core/define-components.ts";
113
+ ${importLines.join(`
114
+ `)}${importLines.length ? `
115
+ ` : ""}export const mdxComponents: Record<string, ComponentOverride> = ${record(mdxEntries)};
116
+ export const layoutOverrides: Record<string, ComponentOverride> = ${record(layoutEntries)};
117
+ `;
118
+ return { frameworks, module, wrappers };
171
119
  };
172
120
 
173
121
  // src/astro/runtime-modules.ts
@@ -220,9 +168,9 @@ var publishRuntimeModules = (modules) => {
220
168
  };
221
169
 
222
170
  // src/astro/templates.ts
223
- import { existsSync as existsSync2, readFileSync } from "node:fs";
171
+ import { existsSync, readFileSync } from "node:fs";
224
172
  import { pathToFileURL } from "node:url";
225
- import { dirname as dirname2, isAbsolute, join as join2, relative } from "pathe";
173
+ import { dirname, isAbsolute as isAbsolute2, join as join2, relative as relative2 } from "pathe";
226
174
  var WORKSPACE_MARKERS = [
227
175
  ".git",
228
176
  "bun.lock",
@@ -233,7 +181,7 @@ var WORKSPACE_MARKERS = [
233
181
  "yarn.lock"
234
182
  ];
235
183
  var hasWorkspacesField = (pkgPath) => {
236
- if (!existsSync2(pkgPath)) {
184
+ if (!existsSync(pkgPath)) {
237
185
  return false;
238
186
  }
239
187
  try {
@@ -243,51 +191,42 @@ var hasWorkspacesField = (pkgPath) => {
243
191
  return false;
244
192
  }
245
193
  };
246
- var hasWorkspaceMarker = (dir) => hasWorkspacesField(join2(dir, "package.json")) || WORKSPACE_MARKERS.some((marker) => existsSync2(join2(dir, marker)));
194
+ var hasWorkspaceMarker = (dir) => hasWorkspacesField(join2(dir, "package.json")) || WORKSPACE_MARKERS.some((marker) => existsSync(join2(dir, marker)));
247
195
  var findWorkspaceRoot = (start) => {
248
196
  let dir = start;
249
197
  for (;; ) {
250
198
  if (hasWorkspaceMarker(dir)) {
251
199
  return dir;
252
200
  }
253
- const parent = dirname2(dir);
201
+ const parent = dirname(dir);
254
202
  if (parent === dir) {
255
203
  return start;
256
204
  }
257
205
  dir = parent;
258
206
  }
259
207
  };
260
- var ADAPTER_IMPORTS = {
261
- cloudflare: "@astrojs/cloudflare",
262
- netlify: "@astrojs/netlify",
263
- node: "@astrojs/node",
264
- vercel: "@astrojs/vercel"
265
- };
266
- var ADAPTER_OPTIONS = new Map([
267
- ["node", '{ mode: "standalone" }']
268
- ]);
269
- var WRANGLER_CONFIG_FILES = [
270
- "wrangler.jsonc",
271
- "wrangler.json",
272
- "wrangler.toml"
273
- ];
274
- var resolveCloudflareAdapterArgs = (context) => {
275
- const args = [
276
- 'prerenderEnvironment: "node"',
277
- 'imageService: "compile"'
278
- ];
279
- const wranglerPath = WRANGLER_CONFIG_FILES.map((file) => join2(context.root, file)).find((file) => existsSync2(file));
280
- if (wranglerPath) {
281
- let configPath = relative(context.outDir, wranglerPath);
282
- if (!configPath.startsWith(".") && !configPath.startsWith("/")) {
283
- configPath = `./${configPath}`;
284
- }
285
- args.push(`configPath: ${JSON.stringify(configPath)}`);
208
+ var renderAstroAdapter = (deployment, context, ejected) => {
209
+ const platform = deployPlatform(deployment);
210
+ if (deployment.options.output !== "server" || !platform.astro) {
211
+ return { configEntries: "", importLine: "", option: "" };
286
212
  }
287
- return `{ ${args.join(", ")} }`;
213
+ const { astro } = platform;
214
+ const args = {
215
+ ...astro.options(context),
216
+ ...deployPassthrough(deployment.options)
217
+ };
218
+ const argsLiteral = Object.keys(args).length > 0 ? JSON.stringify(args) : "";
219
+ const construct = `adapter(${argsLiteral})`;
220
+ const expression = platform.hiddenRuntime.showProjectRoot && !ejected ? `withAdapterRoot(${construct}, ${JSON.stringify(adapterRoot(context))})` : construct;
221
+ return {
222
+ configEntries: Object.entries(astro.config).map(([key, value]) => `
223
+ ${key}: ${JSON.stringify(value)},`).join(""),
224
+ importLine: `import adapter from "${astro.package}";
225
+ `,
226
+ option: `
227
+ adapter: ${expression},`
228
+ };
288
229
  };
289
- var resolveSessionOption = (deployment) => deployment.output === "server" && deployment.adapter === "cloudflare" ? `
290
- session: false,` : "";
291
230
  var astroFontWeights = (weights) => JSON.stringify(weights).replaceAll(/(?<min>\d+)\.\.(?<max>\d+)/gu, "$<min> $<max>");
292
231
  var astroConfigImportLine = (options) => {
293
232
  const names = ["defineConfig"];
@@ -308,23 +247,18 @@ var runtimeDependencies = (options) => {
308
247
  if (needsSvelte) {
309
248
  deps.push("@astrojs/svelte");
310
249
  }
311
- if (hasScalarReferences(config)) {
312
- deps.push("@scalar/astro");
313
- }
314
- deps.push(...searchProviderMeta(config.search.provider).runtimeDeps);
315
- if (config.ai.ask?.enabled && !config.ai.ask.endpoint) {
316
- const askDep = askBackendRuntimeDep(config.ai.ask);
317
- if (askDep) {
318
- deps.push(askDep);
250
+ deps.push(...new Set(config.reference.flatMap((adapter) => adapter.runtimeDeps)), ...config.search.provider.runtimeDeps, ...config.analytics.flatMap((adapter) => adapter.runtimeDeps));
251
+ for (const source of config.content.sources) {
252
+ for (const dep of source.runtimeDeps) {
253
+ if (!deps.includes(dep)) {
254
+ deps.push(dep);
255
+ }
319
256
  }
320
257
  }
321
- const { deployment } = config;
322
- if (deployment.output === "server" && deployment.adapter) {
323
- const adapter = ADAPTER_IMPORTS[deployment.adapter];
324
- if (adapter) {
325
- deps.push(adapter);
326
- }
258
+ if (config.ai.ask?.enabled && !config.ai.ask.endpoint) {
259
+ deps.push(...config.ai.ask.provider.runtimeDeps);
327
260
  }
261
+ deps.push(...config.deployment.runtimeDeps);
328
262
  return deps;
329
263
  };
330
264
  var RENDER_EXTERNAL_DEPS = [
@@ -344,8 +278,6 @@ var RENDER_EXTERNAL_DEPS = [
344
278
  ];
345
279
  var renderUserAliases = (aliases) => Object.entries(aliases ?? {}).toSorted(([a], [b]) => b.length - a.length).map(([find, replacement]) => `
346
280
  ${JSON.stringify(find)}: ${JSON.stringify(replacement)},`).join("");
347
- var astroOutDir = (context) => context.distDir ?? `${context.root}/dist`;
348
- var adapterRoot = (context) => dirname2(astroOutDir(context));
349
281
  var REACT_EXCLUDE = String.raw`exclude: [/\/node_modules\/\.vite\//, /\/\.cache\/vite\//]`;
350
282
  var runtimeCacheOptions = (context, generatedModulesDir) => {
351
283
  if (generatedModulesDir !== undefined) {
@@ -399,6 +331,17 @@ var resolveOptimizeDeps = (options) => {
399
331
  ];
400
332
  return { optimizeDepsEntries, optimizeDepsInclude };
401
333
  };
334
+ var configPath = (path, ejected) => ejected ? `fileURLToPath(new URL(${JSON.stringify(path)}, import.meta.url))` : JSON.stringify(path);
335
+ var EJECTED_CONFIG_HEADER = "// Written by `blume eject`. This is your Astro config now: edit it freely.";
336
+ var astroConfigHeader = (ejected) => ejected ? EJECTED_CONFIG_HEADER : "// Generated by Blume. Do not edit; this file is recreated on each run.";
337
+ var MERMAID_CHUNK_LIMIT = `
338
+ chunkSizeWarningLimit: 2048,`;
339
+ var ROLLDOWN_ON_LOG = `onLog(level, log, handler) {
340
+ if (log.code === "MODULE_LEVEL_DIRECTIVE" && String(log.message).includes("use astro:head-inject")) {
341
+ return;
342
+ }
343
+ handler(level, log);
344
+ }`;
402
345
  var renderRuntimeModuleWiring = (generatedModulesDir) => {
403
346
  if (generatedModulesDir === undefined) {
404
347
  return {
@@ -408,7 +351,7 @@ var renderRuntimeModuleWiring = (generatedModulesDir) => {
408
351
  };
409
352
  }
410
353
  const aliasLines = [...RUNTIME_MODULE_FILES].map(([id, file]) => `
411
- ${JSON.stringify(id)}: ${JSON.stringify(`${generatedModulesDir}/${file}`)},`).join("");
354
+ ${JSON.stringify(id)}: ${configPath(`${generatedModulesDir}/${file}`, true)},`).join("");
412
355
  return { aliasLines, imports: [], pluginEntry: "" };
413
356
  };
414
357
  var blumeIntegrationOptions = (options) => options.ejected ? {
@@ -432,6 +375,7 @@ var astroConfigTemplate = (options) => {
432
375
  needsVue,
433
376
  searchClientPath
434
377
  } = options;
378
+ const ejected = generatedModulesDir !== undefined;
435
379
  const {
436
380
  aliasLines: runtimeModuleAliasLines,
437
381
  imports: runtimeModuleImports,
@@ -439,7 +383,6 @@ var astroConfigTemplate = (options) => {
439
383
  } = renderRuntimeModuleWiring(generatedModulesDir);
440
384
  const { deployment } = config;
441
385
  const userAliasLines = renderUserAliases(options.aliases);
442
- const server = deployment.output === "server";
443
386
  const fsAllow = [...new Set([findWorkspaceRoot(context.root), context.root])];
444
387
  const { optimizeDepsEntries, optimizeDepsInclude } = resolveOptimizeDeps({
445
388
  aliases: options.aliases,
@@ -448,25 +391,15 @@ var astroConfigTemplate = (options) => {
448
391
  needsReact,
449
392
  reactCompilerPath: options.reactCompilerPath
450
393
  });
451
- const adapterImport = server && deployment.adapter ? `import adapter from "${ADAPTER_IMPORTS[deployment.adapter]}";
452
- ` : "";
453
- const adapterArgs = (() => {
454
- if (!server || !deployment.adapter) {
455
- return "";
456
- }
457
- if (deployment.adapter === "cloudflare") {
458
- return resolveCloudflareAdapterArgs(context);
459
- }
460
- return ADAPTER_OPTIONS.get(deployment.adapter) ?? "";
461
- })();
462
- const adapterExpr = deployment.adapter === "vercel" ? `withAdapterRoot(adapter(${adapterArgs}), ${JSON.stringify(adapterRoot(context))})` : `adapter(${adapterArgs})`;
463
- const adapterOption = server && deployment.adapter ? `
464
- adapter: ${adapterExpr},` : "";
465
- const sessionOption = resolveSessionOption(deployment);
466
- const siteOption = deployment.site ? `
467
- site: ${JSON.stringify(deployment.site)},` : "";
468
- const baseOption = deployment.base ? `
469
- base: ${JSON.stringify(deployment.base)},` : "";
394
+ const {
395
+ configEntries: adapterConfigEntries,
396
+ importLine: adapterImport,
397
+ option: adapterOption
398
+ } = renderAstroAdapter(deployment, context, ejected);
399
+ const siteOption = deployment.options.site ? `
400
+ site: ${JSON.stringify(deployment.options.site)},` : "";
401
+ const baseOption = deployment.options.base ? `
402
+ base: ${JSON.stringify(deployment.options.base)},` : "";
470
403
  const imageOption = renderImageOption(config);
471
404
  const i18nOption = config.i18n ? `
472
405
  i18n: ${JSON.stringify({
@@ -476,7 +409,7 @@ var astroConfigTemplate = (options) => {
476
409
  prefixDefaultLocale: !config.i18n.hideDefaultLocalePrefix
477
410
  }
478
411
  })},` : "";
479
- const basedRedirects = applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.base ?? "");
412
+ const basedRedirects = applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.options.base ?? "");
480
413
  const redirectsOption = basedRedirects.length > 0 ? `
481
414
  redirects: ${JSON.stringify(Object.fromEntries(basedRedirects.map((redirect) => [
482
415
  redirect.from,
@@ -495,7 +428,7 @@ var astroConfigTemplate = (options) => {
495
428
  return {
496
429
  ...face,
497
430
  src: [
498
- isAbsolute(variant.src) ? variant.src : join2(context.root, variant.src)
431
+ isAbsolute2(variant.src) ? variant.src : join2(context.root, variant.src)
499
432
  ]
500
433
  };
501
434
  }))} } }` : `{ provider: fontProviders.${font.provider}(), name: ${JSON.stringify(font.name)}, cssVariable: ${JSON.stringify(font.cssVariable)}, weights: ${astroFontWeights(font.weights)}, subsets: ${JSON.stringify(font.subsets)}, fallbacks: ${JSON.stringify(font.fallbacks)} }`).join(", ")}],` : "";
@@ -518,15 +451,18 @@ var astroConfigTemplate = (options) => {
518
451
  const blumeImport = `import { ${blumeImports.join(", ")} } from "blume/astro";
519
452
  `;
520
453
  const twoslashTransformer = "blumeTwoslashTransformer(), ";
521
- const deployBase = normalizeBasePath(deployment.base);
454
+ const deployBase = normalizeBasePath(deployment.options.base);
455
+ const processorLiteral = JSON.stringify({
456
+ basePath: config.basePath,
457
+ codeThemes: config.markdown.code.theme,
458
+ contentRoot: options.contentRoot,
459
+ deployBase,
460
+ externalLinks: config.markdown.externalLinks,
461
+ headingAnchors: config.markdown.headingAnchors
462
+ });
463
+ const processorOptions = options.generatedModulesDir === undefined ? processorLiteral : `{ ...${processorLiteral}, dataFile: ${configPath(`${options.generatedModulesDir}/data.json`, true)} }`;
522
464
  const integrations = [
523
- `mdx({ processor: blumeMdxProcessor(${JSON.stringify({
524
- basePath: config.basePath,
525
- codeThemes: config.markdown.codeBlocks.theme,
526
- contentRoot: options.contentRoot,
527
- deployBase,
528
- headingAnchors: config.markdown.headingAnchors
529
- })}) })`
465
+ `mdx({ processor: blumeMdxProcessor(${processorOptions}) })`
530
466
  ];
531
467
  if (needsReact) {
532
468
  integrations.push(reactIntegration(options.reactCompilerPath));
@@ -540,7 +476,7 @@ var astroConfigTemplate = (options) => {
540
476
  integrations.push(`blumeIntegration(${JSON.stringify(blumeIntegrationOptions({
541
477
  config,
542
478
  contentRoutes,
543
- ejected: generatedModulesDir !== undefined,
479
+ ejected,
544
480
  pages
545
481
  }))})`);
546
482
  const {
@@ -549,9 +485,11 @@ var astroConfigTemplate = (options) => {
549
485
  userConfigSetup,
550
486
  userIntegrationSpread
551
487
  } = renderIntegrationBridge(options.integrationBridge);
552
- return `// Generated by Blume. Do not edit; this file is recreated on each run.
488
+ const fileUrlImport = ejected ? `import { fileURLToPath } from "node:url";
489
+ ` : "";
490
+ return `${astroConfigHeader(ejected)}
553
491
  ${configSourceMarker}${userConfigImports}import { availableParallelism } from "node:os";
554
- ${defineConfigImport}
492
+ ${fileUrlImport}${defineConfigImport}
555
493
  import mdx from "@astrojs/mdx";
556
494
  import tailwindcss from "@tailwindcss/vite";
557
495
  import { blumeMarkdownProcessor, blumeMdxProcessor, blumeShikiTransformers, blumeTwoslashTransformer } from "blume/markdown";
@@ -559,22 +497,16 @@ ${reactImport}${vueImport}${svelteImport}${blumeImport}${adapterImport}
559
497
  ${userConfigSetup}export default defineConfig({
560
498
  root: ${JSON.stringify(context.outDir)},
561
499
  srcDir: ${JSON.stringify(`${context.outDir}/src`)},
562
- outDir: ${JSON.stringify(astroOutDir(context))},
500
+ outDir: ${JSON.stringify(distDir(context))},
563
501
  publicDir: ${JSON.stringify(`${context.root}/public`)},${cacheOptions}
564
- output: ${JSON.stringify(deployment.output)},${adapterOption}${sessionOption}${siteOption}${baseOption}${imageOption}${redirectsOption}${i18nOption}${fontsOption}
502
+ output: ${JSON.stringify(deployment.options.output)},${adapterOption}${adapterConfigEntries}${siteOption}${baseOption}${imageOption}${redirectsOption}${i18nOption}${fontsOption}
565
503
  integrations: [${integrations.join(", ")}${userIntegrationSpread}],
566
504
  markdown: {
567
- processor: blumeMarkdownProcessor(${JSON.stringify({
568
- basePath: config.basePath,
569
- codeThemes: config.markdown.codeBlocks.theme,
570
- contentRoot: options.contentRoot,
571
- deployBase,
572
- headingAnchors: config.markdown.headingAnchors
573
- })}),
505
+ processor: blumeMarkdownProcessor(${processorOptions}),
574
506
  shikiConfig: {
575
507
  themes: {
576
- light: ${JSON.stringify(config.markdown.codeBlocks.theme.light)},
577
- dark: ${JSON.stringify(config.markdown.codeBlocks.theme.dark)},
508
+ light: ${JSON.stringify(config.markdown.code.theme.light)},
509
+ dark: ${JSON.stringify(config.markdown.code.theme.dark)},
578
510
  },
579
511
  defaultColor: false,
580
512
  transformers: [${twoslashTransformer}...blumeShikiTransformers(${JSON.stringify({ icons: config.markdown.code.icons })})],
@@ -601,7 +533,12 @@ ${userConfigSetup}export default defineConfig({
601
533
  // the overlap only adds memory.
602
534
  build: { concurrency: Math.min(8, availableParallelism()) },
603
535
  vite: {${viteCacheOption}
604
- plugins: [${runtimeModulesPluginEntry}tailwindcss(), includeHmrPlugin(${JSON.stringify(`${context.outDir}/src/generated/includes.json`)}), prerenderDepsPlugin()],
536
+ plugins: [${runtimeModulesPluginEntry}tailwindcss(), includeHmrPlugin(${configPath(`${context.outDir}/src/generated/includes.json`, ejected)}), prerenderDepsPlugin()],
537
+ build: {${features.mermaid ? MERMAID_CHUNK_LIMIT : ""}
538
+ rolldownOptions: {
539
+ ${ROLLDOWN_ON_LOG},
540
+ },
541
+ },
605
542
  // Everything hydration can reach must be part of the dev dep optimizer's
606
543
  // FIRST run. The Vite root is the generated runtime, so user pages,
607
544
  // islands, and aliased components live outside it and are only crawled
@@ -647,12 +584,12 @@ ${userConfigSetup}export default defineConfig({
647
584
  },
648
585
  resolve: {
649
586
  alias: {
650
- "blume:ask": ${JSON.stringify(askPath)},
651
- "blume:examples": ${JSON.stringify(examplesPath)},
652
- "blume:examples-theme": ${JSON.stringify(examplesThemePath)},
653
- "blume:features": ${JSON.stringify(featuresPath)},
654
- "blume:search-client": ${JSON.stringify(searchClientPath)},
655
- "blume:theme": ${JSON.stringify(themePath)},${runtimeModuleAliasLines}${userAliasLines}
587
+ "blume:ask": ${configPath(askPath, ejected)},
588
+ "blume:examples": ${configPath(examplesPath, ejected)},
589
+ "blume:examples-theme": ${configPath(examplesThemePath, ejected)},
590
+ "blume:features": ${configPath(featuresPath, ejected)},
591
+ "blume:search-client": ${configPath(searchClientPath, ejected)},
592
+ "blume:theme": ${configPath(themePath, ejected)},${runtimeModuleAliasLines}${userAliasLines}
656
593
  },
657
594
  },
658
595
  server: {
@@ -666,16 +603,17 @@ ${userConfigSetup}export default defineConfig({
666
603
  };
667
604
  var stagedContentDir = (outDir) => join2(outDir, "content");
668
605
  var runtimeDirWithin = (base, outDir) => {
669
- const rel = relative(base, outDir);
670
- return rel && !rel.startsWith("..") && !isAbsolute(rel) ? rel : null;
606
+ const rel = relative2(base, outDir);
607
+ return rel && !rel.startsWith("..") && !isAbsolute2(rel) ? rel : null;
671
608
  };
672
- var astroGlobBase = (base) => isAbsolute(base) ? pathToFileURL(base).href : base;
609
+ var astroGlobBase = (base) => isAbsolute2(base) ? pathToFileURL(base).href : base;
673
610
  var contentConfigTemplate = (options) => {
674
611
  const { context, config } = options;
675
612
  const stagedBase = options.stagedBase ?? stagedContentDir(context.outDir);
676
- const collectionBase = options.collection?.base ?? context.contentRoot;
677
- const includeGlobs = options.collection?.include ?? config.content.include;
678
- const excludeGlobs = options.collection?.exclude ?? config.content.exclude;
613
+ const collection = options.collection ?? resolveDocsCollection(config, context.root);
614
+ const collectionBase = collection.base;
615
+ const includeGlobs = collection.include;
616
+ const excludeGlobs = collection.exclude;
679
617
  const outDirRel = runtimeDirWithin(collectionBase, context.outDir);
680
618
  const outDirIgnore = outDirRel ? [`!${outDirRel}/**`] : [];
681
619
  const filesystem = options.filesystem ?? true;
@@ -734,47 +672,20 @@ export const OPTIONS: APIRoute = ({ request }) =>
734
672
  preflightResponse(request, ALLOWED_ORIGINS);
735
673
  `
736
674
  } : { close: "};", imports: [], open: "async ({ request }) => {", setup: "" };
737
- var askEndpointTemplate = (backend, grounded, options) => {
738
- const { instructions, reasoning, retrieval } = options ?? {};
675
+ var ASK_BODY_LIMIT_BYTES = 65536;
676
+ var askEndpointTemplate = (backend, options) => {
677
+ const { instructions, retrieval } = options ?? {};
678
+ const { grounded } = backend;
739
679
  const fallbackPrompt = instructions ? `${ASK_FALLBACK_PROMPT}
740
680
 
741
681
  ${instructions}` : ASK_FALLBACK_PROMPT;
742
682
  const imports = [
743
683
  'import type { APIRoute } from "astro";',
744
684
  'import { getSecret } from "astro:env/server";',
745
- backend.kind === "gateway" ? 'import { createGateway, streamText } from "ai";' : 'import { streamText } from "ai";'
685
+ 'import { readCappedText } from "blume/core/request-body.ts";',
686
+ ...backend.template.imports
746
687
  ];
747
- let setup = "";
748
- let modelExpr = JSON.stringify(backend.model);
749
- const headersField = backend.headers ? `
750
- headers: ${JSON.stringify(backend.headers)},` : "";
751
- if (backend.kind === "gateway") {
752
- setup = `
753
- const gateway = createGateway({
754
- apiKey: getSecret("AI_GATEWAY_API_KEY"),${headersField}
755
- });
756
- `;
757
- modelExpr = `gateway(${JSON.stringify(backend.model)})`;
758
- } else if (backend.kind === "openrouter") {
759
- imports.push('import { createOpenRouter } from "@openrouter/ai-sdk-provider";');
760
- setup = `
761
- const openrouter = createOpenRouter({
762
- apiKey: getSecret(${JSON.stringify(backend.apiKeyEnv)}),${headersField}
763
- });
764
- `;
765
- const settings = reasoning ? `, { reasoning: { effort: ${JSON.stringify(reasoning)} } }` : "";
766
- modelExpr = `openrouter(${JSON.stringify(backend.model)}${settings})`;
767
- } else if (backend.kind === "openai-compatible") {
768
- imports.push('import { createOpenAICompatible } from "@ai-sdk/openai-compatible";');
769
- setup = `
770
- const provider = createOpenAICompatible({
771
- apiKey: getSecret(${JSON.stringify(backend.apiKeyEnv)}),
772
- baseURL: ${JSON.stringify(backend.baseUrl)},${headersField}
773
- name: ${JSON.stringify(backend.name)},
774
- });
775
- `;
776
- modelExpr = `provider(${JSON.stringify(backend.model)})`;
777
- }
688
+ let { setup } = backend.template;
778
689
  if (grounded) {
779
690
  imports.push('import { createAskContext } from "blume/ai/ask-context.ts";', 'import askData from "blume:ask-data";');
780
691
  const groundFields = [];
@@ -791,7 +702,18 @@ const ground = createAskContext(askData${groundOptions});
791
702
  }
792
703
  const cors = askCorsTemplate(options?.cors);
793
704
  imports.push(...cors.imports);
794
- const validate = ` const body = await request.json().catch(() => null);
705
+ const validate = ` const text = await readCappedText(request, ${ASK_BODY_LIMIT_BYTES});
706
+ if (text === undefined) {
707
+ return new Response("Request too large: the body must be at most 64 KB.", {
708
+ status: 413,
709
+ });
710
+ }
711
+ let body;
712
+ try {
713
+ body = JSON.parse(text);
714
+ } catch {
715
+ body = null;
716
+ }
795
717
  const raw = body?.messages;
796
718
  const valid =
797
719
  Array.isArray(raw) &&
@@ -816,30 +738,17 @@ const ground = createAskContext(askData${groundOptions});
816
738
  content: m.content,
817
739
  role: m.role,
818
740
  }));`;
819
- const keyCheck = backend.kind === "gateway" ? ` // The AI Gateway authenticates with an API key or Vercel's OIDC token.
820
- if (!(getSecret("AI_GATEWAY_API_KEY") || getSecret("VERCEL_OIDC_TOKEN"))) {
821
- return new Response(
822
- "Ask AI is not configured: set AI_GATEWAY_API_KEY (or deploy on Vercel with OIDC).",
823
- { status: 500 }
824
- );
825
- }` : ` if (!getSecret(${JSON.stringify(backend.apiKeyEnv)})) {
826
- return new Response(
827
- ${JSON.stringify(`Ask AI is not configured: set ${backend.apiKeyEnv}.`)},
828
- { status: 500 }
829
- );
830
- }`;
741
+ const { keyCheck } = backend.template;
831
742
  const onError = ` onError({ error }) {
832
743
  console.error("Ask AI provider error:", error);
833
744
  },`;
834
745
  const streamFields = [
835
- `model: ${modelExpr}`,
746
+ `model: ${backend.template.model}`,
836
747
  grounded ? "instructions" : `instructions:
837
748
  ${JSON.stringify(fallbackPrompt)}`,
838
- "messages"
749
+ "messages",
750
+ ...backend.template.fields
839
751
  ];
840
- if (reasoning && backend.kind !== "openrouter") {
841
- streamFields.push(`reasoning: ${JSON.stringify(reasoning)}`);
842
- }
843
752
  const call = ` const result = streamText({
844
753
  ${streamFields.join(`,
845
754
  `)},
@@ -854,7 +763,9 @@ ${validate}
854
763
  ${keyCheck}
855
764
  try {
856
765
  ${stream}
857
- return result.toTextStreamResponse();
766
+ return createTextStreamResponse({
767
+ stream: toTextStream({ stream: result.stream }),
768
+ });
858
769
  } catch {
859
770
  return new Response("Failed to generate a response.", { status: 500 });
860
771
  }
@@ -910,31 +821,9 @@ const indexUrl = joinBase(import.meta.env.BASE_URL, "blume-search.json");
910
821
 
911
822
  export const createSearch = () => create({ indexUrl${locale ? `, locale: ${JSON.stringify(locale)}` : ""} });
912
823
  `;
913
- var hostedSearchClient = (module, options) => `${SEARCH_CLIENT_HEADER}${searchClientImport(module)}
914
- export const createSearch = () => create(${JSON.stringify(options)});
824
+ var hostedSearchClient = (provider) => `${SEARCH_CLIENT_HEADER}${searchClientImport(provider.kind)}
825
+ export const createSearch = () => create(${JSON.stringify(provider.options)});
915
826
  `;
916
- var hostedSearchOptions = (search) => {
917
- switch (search.provider) {
918
- case "algolia": {
919
- return { module: "algolia", options: { ...search.algolia } };
920
- }
921
- case "orama-cloud": {
922
- return {
923
- module: "orama-cloud",
924
- options: {
925
- apiKey: search.oramaCloud?.apiKey,
926
- endpoint: search.oramaCloud?.endpoint
927
- }
928
- };
929
- }
930
- case "typesense": {
931
- return { module: "typesense", options: { ...search.typesense } };
932
- }
933
- default: {
934
- return null;
935
- }
936
- }
937
- };
938
827
  var featuresTemplate = (features) => `// Generated by Blume. Do not edit.
939
828
  //
940
829
  // The client features this site uses. A feature no page needs stays out of
@@ -950,61 +839,86 @@ export const loadEpub:
950
839
  | null = ${features.epub ? '() => import("epub-gen-memory/bundle")' : "null"};
951
840
  `;
952
841
  var searchClientTemplate = (config) => {
953
- const { search } = config;
954
- if (search.provider === "orama" || search.provider === "flexsearch") {
955
- const locale = search.provider === "orama" ? config.i18n?.defaultLocale : undefined;
956
- return staticSearchClient(search.provider, locale);
957
- }
958
- const hosted = hostedSearchOptions(search);
959
- if (hosted) {
960
- return hostedSearchClient(hosted.module, hosted.options);
961
- }
962
- if (search.provider === "mixedbread") {
963
- return `${SEARCH_CLIENT_HEADER}${searchClientImport("endpoint")}${SEARCH_BASE_IMPORT}
842
+ const { provider } = config.search;
843
+ switch (provider.mode) {
844
+ case "static": {
845
+ const locale = provider.kind === "orama" ? config.i18n?.defaultLocale : undefined;
846
+ return staticSearchClient(provider.kind, locale);
847
+ }
848
+ case "hosted": {
849
+ return hostedSearchClient(provider);
850
+ }
851
+ case "server": {
852
+ return `${SEARCH_CLIENT_HEADER}${searchClientImport("endpoint")}${SEARCH_BASE_IMPORT}
964
853
  const api = joinBase(import.meta.env.BASE_URL, "api/search");
965
854
 
966
855
  export const createSearch = () => create({ api });
967
856
  `;
968
- }
969
- if (search.provider === "pagefind") {
970
- return `${SEARCH_CLIENT_HEADER}${searchClientImport("pagefind")}${SEARCH_BASE_IMPORT}
857
+ }
858
+ case "pagefind": {
859
+ return `${SEARCH_CLIENT_HEADER}${searchClientImport("pagefind")}${SEARCH_BASE_IMPORT}
971
860
  const url = joinBase(import.meta.env.BASE_URL, "pagefind/pagefind.js");
972
861
 
973
862
  export const createSearch = () => create({ url });
974
863
  `;
975
- }
976
- return `${SEARCH_CLIENT_HEADER}export const createSearch = () => () =>
864
+ }
865
+ default: {
866
+ return `${SEARCH_CLIENT_HEADER}export const createSearch = () => () =>
977
867
  Promise.resolve({ hits: [], sections: [] });
978
868
  `;
869
+ }
870
+ }
979
871
  };
980
- var mixedbreadSearchEndpointTemplate = (storeId) => `// Generated by Blume. Do not edit.
872
+ var mixedbreadSearchEndpointTemplate = (options) => `// Generated by Blume. Do not edit.
981
873
  import type { APIRoute } from "astro";
982
874
  import { getSecret } from "astro:env/server";
983
875
  import Mixedbread from "@mixedbread/sdk";
876
+ import { readCappedText } from "blume/core/request-body.ts";
984
877
 
985
878
  export const prerender = false;
986
879
 
987
880
  const client = new Mixedbread({ apiKey: getSecret("MIXEDBREAD_API_KEY") ?? "" });
988
- const STORE_ID = ${JSON.stringify(storeId)};
881
+ const OPTIONS = ${JSON.stringify(options)};
882
+ // Every option besides the store reaches the search call verbatim.
883
+ const { storeId: STORE_ID, ...SEARCH_OPTIONS } = OPTIONS;
989
884
 
990
885
  export const POST: APIRoute = async ({ request }) => {
886
+ // A search body is one short query: read it under a 16 KB cap, so a
887
+ // self-hosted server never buffers an arbitrarily large POST first.
888
+ const text = await readCappedText(request, 16_384);
889
+ if (text === undefined) {
890
+ return new Response("Request too large: the body must be at most 16 KB.", {
891
+ status: 413,
892
+ });
893
+ }
991
894
  // The endpoint is public: a malformed body must 200-empty, not 500.
992
- const body = await request.json().catch(() => null);
895
+ let body = null;
896
+ try {
897
+ body = JSON.parse(text);
898
+ } catch {
899
+ body = null;
900
+ }
993
901
  const query = body?.query;
994
902
  if (!query || typeof query !== "string") {
995
903
  return new Response("[]", {
996
904
  headers: { "Content-Type": "application/json" },
997
905
  });
998
906
  }
907
+ // \`top_k\` defaults to 8 unless an option sets it; the query and store
908
+ // always come from the request and \`storeId\`.
999
909
  const response = await client.stores.search({
910
+ top_k: 8,
911
+ ...SEARCH_OPTIONS,
1000
912
  query,
1001
913
  store_identifiers: [STORE_ID],
1002
- top_k: 8,
1003
914
  });
1004
915
  const hits = (response.data ?? []).map((chunk) => {
1005
916
  const meta = chunk.generated_metadata ?? {};
917
+ // Only a text chunk carries \`text\`; image, audio, and video chunks fall
918
+ // back to the excerpt the store generated for them.
919
+ const text = "text" in chunk ? chunk.text : undefined;
1006
920
  return {
1007
- excerpt: chunk.text ?? meta.excerpt ?? "",
921
+ excerpt: text ?? meta.excerpt ?? "",
1008
922
  title: meta.title ?? chunk.filename ?? "",
1009
923
  url: meta.url ?? "",
1010
924
  };
@@ -1120,9 +1034,15 @@ export const GET: APIRoute = async ({ params }) => {
1120
1034
  return new Response(null, { status: 404 });
1121
1035
  }
1122
1036
  const body = await readFile(path);
1123
- return new Response(new Uint8Array(body), {
1124
- headers: { "Content-Type": contentType(path) },
1125
- });
1037
+ const type = contentType(path);
1038
+ // An SVG opened directly is a document that can run script; the sandbox
1039
+ // keeps an uploaded one inert on the docs origin. Static hosts get the same
1040
+ // header from the build's header rules.
1041
+ const headers: Record<string, string> =
1042
+ type === "image/svg+xml"
1043
+ ? { "Content-Security-Policy": ${JSON.stringify(SVG_ASSET_POLICY)}, "Content-Type": type }
1044
+ : { "Content-Type": type };
1045
+ return new Response(new Uint8Array(body), { headers });
1126
1046
  };
1127
1047
  `;
1128
1048
  var mcpPageFile = (route) => `${trimChar(route, "/")}.ts`;
@@ -1199,7 +1119,9 @@ export function getStaticPaths() {
1199
1119
  return navVariants(data, hiddenDefaultLocale(data.config.i18n)).flatMap(
1200
1120
  ({ locale, navigation, version }) =>
1201
1121
  [...navGroupIds(navigation.sidebar)]
1202
- .filter(([node]) => (node.display ?? "flat") !== "flat")
1122
+ .filter(
1123
+ ([node]) => node.kind === "group" && (node.display ?? "flat") !== "flat"
1124
+ )
1203
1125
  .map(([, id]) => ({ params: { id, locale, version } }))
1204
1126
  );
1205
1127
  }
@@ -1418,8 +1340,7 @@ import LocaleLinks from "blume/components/layout/LocaleLinks.astro";
1418
1340
  import ApiOverview from "blume/components/openapi/ApiOverview.astro";
1419
1341
  import ApiTagOperations from "blume/components/openapi/ApiTagOperations.astro";
1420
1342
  import Operation from "blume/components/openapi/Operation.astro";
1421
- ${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../generated/components.ts";
1422
- import { islandComponents } from "../generated/islands.ts";`,
1343
+ ${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../generated/components.ts";`,
1423
1344
  map: `{
1424
1345
  Accordion,
1425
1346
  AccordionItem,
@@ -1455,8 +1376,7 @@ import { islandComponents } from "../generated/islands.ts";`,
1455
1376
  TypeTable,
1456
1377
  Visibility,
1457
1378
  YouTube,
1458
- ${mathEntry}...islandComponents,
1459
- ...userMdx,
1379
+ ${mathEntry}...userMdx,
1460
1380
  }`
1461
1381
  };
1462
1382
  };
@@ -1498,6 +1418,7 @@ export function getStaticPaths() {
1498
1418
  indexable: route.indexable,
1499
1419
  lastModified: route.lastModified,
1500
1420
  locale: route.locale,
1421
+ monolingual: route.monolingual,
1501
1422
  route: route.path,
1502
1423
  title: route.title,
1503
1424
  version: route.version,
@@ -1506,7 +1427,7 @@ export function getStaticPaths() {
1506
1427
  }));
1507
1428
  }
1508
1429
 
1509
- const { entryId, collection, route, title, indexable, editUrl, lastModified, locale, alternates, fallback, version, versionAlternates } = Astro.props;
1430
+ const { entryId, collection, route, title, indexable, editUrl, lastModified, locale, alternates, fallback, monolingual, version, versionAlternates } = Astro.props;
1510
1431
  const entry = await getEntry(collection as CollectionKey, entryId);
1511
1432
  if (!entry) {
1512
1433
  return new Response(null, { status: 404 });
@@ -1598,13 +1519,32 @@ const contentDir = i18n
1598
1519
  // hreflang URLs byte-match the sitemap's <loc> for the home page.
1599
1520
  const absolute = (path: string) => base + withBase(path);
1600
1521
 
1522
+ // A fallback page renders the fallback locale's page at this locale's URL, so
1523
+ // its canonical names the page it copies, and search engines never rank the
1524
+ // copy against the original.
1525
+ const fallbackSource =
1526
+ fallback && i18n?.fallbackLocale
1527
+ ? (alternates ?? []).find((alt) => alt.locale === i18n.fallbackLocale)
1528
+ : undefined;
1529
+ // The page it copies, when that page is archived too, points on to the latest
1530
+ // docs; the copy names that final page directly, the fallback locale's
1531
+ // version of the latest one, so the canonical is never a chain.
1532
+ const fallbackLatest =
1533
+ fallbackSource && archived && archived.canonical === "latest" && latestVersionAlt
1534
+ ? (data.routes.find((entry) => entry.path === latestVersionAlt.path)?.alternates ?? []).find(
1535
+ (alt) => alt.locale === i18n?.fallbackLocale
1536
+ )
1537
+ : undefined;
1538
+ const fallbackTarget = fallbackLatest ?? fallbackSource;
1601
1539
  // An archived page defaults its canonical to the same page in the latest docs
1602
1540
  // when that page still exists — search engines treat the live page as
1603
1541
  // authoritative without deindexing version-only content. A page's own
1604
1542
  // \`seo.canonical\` always wins, and \`canonical: "self"\` keeps the default.
1605
1543
  const canonical =
1606
1544
  seo.canonical ??
1607
- (archived && archived.canonical === "latest" && latestVersionAlt && base
1545
+ (fallbackTarget && base
1546
+ ? absolute(fallbackTarget.path)
1547
+ : archived && archived.canonical === "latest" && latestVersionAlt && base
1608
1548
  ? absolute(latestVersionAlt.path)
1609
1549
  : base
1610
1550
  ? \`\${base}\${basedRoute === "/" ? "/" : encodeURI(basedRoute)}\`
@@ -1634,7 +1574,9 @@ const mountLocalized = (logical: string, codeArg: string) =>
1634
1574
  const logicalRoute = i18n
1635
1575
  ? stripLocale(stripBasePath(data.config.basePath, route), locale)
1636
1576
  : route;
1637
- const localeSwitch = i18n
1577
+ // A page from a one-language source (GitHub Releases) gets no switcher: every
1578
+ // other locale would only repeat the same text.
1579
+ const localeSwitch = i18n && !monolingual
1638
1580
  ? i18n.locales.map((l) => {
1639
1581
  const alt = (alternates ?? []).find((x) => x.locale === l.code);
1640
1582
  return {
@@ -1731,6 +1673,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
1731
1673
  locale={htmlLang}
1732
1674
  dir={dir}
1733
1675
  contentDir={contentDir}
1676
+ contentLocale={contentLocale}
1734
1677
  ui={ui}
1735
1678
  localeAlternates={localeAlternates}
1736
1679
  xDefault={xDefault}
@@ -1778,38 +1721,28 @@ var changelogIndexTemplate = (options) => {
1778
1721
  clientData={{ config: data.config, navigation: data.navigation, page: { route: "/changelog", title: pageTitle } }}` : "";
1779
1722
  const stagedSpread = options.staged ? `
1780
1723
  ...(await getCollection("staged")),` : "";
1781
- const { imports: componentImports, map: componentMap } = contentComponentsSource(options.mathEnabled);
1782
1724
  return `---
1783
1725
  // Generated by Blume. Do not edit.
1784
- import { getCollection, render } from "astro:content";
1726
+ import { getCollection } from "astro:content";
1785
1727
  import RootLayout from "blume/components/layout/RootLayout.astro";
1786
- import Update from "blume/components/content/Update.astro";
1787
1728
  import { withBase } from "blume/components/islands/base-path.ts";
1788
1729
  import { resolveSlot } from "blume/components/layout/overrides.ts";
1789
1730
  import { resolveDateFormatOptions } from "blume/core/date-format.ts";
1790
- ${componentImports}
1731
+ import { layoutOverrides } from "../generated/components.ts";
1791
1732
  import data from "blume:data";
1792
1733
 
1793
- const Color = Object.assign(ColorRoot, { Item: ColorItem, Row: ColorRow });
1794
- const Tree = Object.assign(TreeRoot, { File: TreeFile, Folder: TreeFolder });
1795
-
1796
1734
  export const prerender = true;
1797
1735
 
1798
- // Entry bodies are MDX rendered outside the catch-all, so they need the same
1799
- // component map: a \`:::\` callout or \`<Steps>\` in a release note otherwise
1800
- // throws "Expected component ... to be defined" at build time.
1801
- const components = ${componentMap};
1802
-
1803
1736
  const entryDate = (entry: {
1804
1737
  data: { date?: string | null; changelog?: { date?: string | null } | null };
1805
1738
  }) => entry.data.date ?? entry.data.changelog?.date ?? null;
1806
1739
 
1807
- const toTime = (value: string | null | undefined) => {
1740
+ const parseDate = (value: string | null | undefined) => {
1808
1741
  if (!value) {
1809
- return 0;
1742
+ return null;
1810
1743
  }
1811
1744
  const date = new Date(value);
1812
- return Number.isNaN(date.getTime()) ? 0 : date.getTime();
1745
+ return Number.isNaN(date.getTime()) ? null : date;
1813
1746
  };
1814
1747
 
1815
1748
  // The changelog is an unlocalized route, so its chrome renders in the default
@@ -1824,34 +1757,45 @@ const htmlLang = i18n ? i18n.defaultLocale : "en";
1824
1757
 
1825
1758
  // Formatted in the same locale as the chrome, and with the configured
1826
1759
  // \`dateFormat\` (UTC by default), to match the per-page "last updated" stamp.
1760
+ // The year heads each group, so a row shows the rest of the date: a preset
1761
+ // style keeps its month wording, a component format simply drops the year.
1827
1762
  const dateFormatOptions = resolveDateFormatOptions(data.config.dateFormat);
1828
- const formatDate = (value: string | null | undefined) => {
1829
- if (!value) {
1830
- return;
1831
- }
1832
- const date = new Date(value);
1833
- return Number.isNaN(date.getTime())
1834
- ? undefined
1835
- : new Intl.DateTimeFormat(htmlLang, dateFormatOptions).format(date);
1836
- };
1763
+ const { dateStyle, year: _year, ...dateComponents } = dateFormatOptions;
1764
+ const rowDateFormat: Intl.DateTimeFormatOptions = dateStyle
1765
+ ? {
1766
+ ...dateComponents,
1767
+ day: "numeric",
1768
+ month: dateStyle === "medium" ? "short" : "long",
1769
+ }
1770
+ : dateComponents;
1771
+ const formatRowDate = (date: Date) =>
1772
+ new Intl.DateTimeFormat(htmlLang, rowDateFormat).format(date);
1773
+ const formatYear = (date: Date) =>
1774
+ new Intl.DateTimeFormat(htmlLang, {
1775
+ timeZone: dateFormatOptions.timeZone,
1776
+ year: "numeric",
1777
+ }).format(date);
1837
1778
 
1838
1779
  const slugify = (text: string) =>
1839
1780
  text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") ||
1840
1781
  "update";
1841
1782
 
1842
- // The major of a version's embedded semver (\`1.2.3\` -> 1, \`pkg@2.0.0\` -> 2), or
1843
- // null when there is no full major.minor.patch to key on. Drives the changelog's
1844
- // group-by-major pagination, so it tolerates the scoped tags monorepos publish.
1845
- const majorVersion = (version: string | null | undefined) => {
1846
- const match = /(\\d+)\\.\\d+\\.\\d+/.exec(String(version ?? ""));
1847
- return match ? Number(match[1]) : null;
1848
- };
1849
-
1850
- // Map each entry to its own generated page so the timeline heading can deep-link
1851
- // to it. The collection entry id matches the route manifest's \`entryId\`.
1852
- const routeByEntry = new Map(
1853
- data.routes.map((route) => [route.entryId, route.path])
1854
- );
1783
+ // Map each entry to its own generated page so the row can link to it. The
1784
+ // collection entry id matches the route manifest's \`entryId\` — and under
1785
+ // i18n every locale serves a page for it (its translations plus fallback
1786
+ // copies of an untranslated one), all sharing that id, so a map over every
1787
+ // route would keep whichever locale came last: a Portuguese permalink on an
1788
+ // unlocalized index. Only the default locale's routes are kept, and an entry
1789
+ // is listed only when it has one, so a translated changelog file (a distinct
1790
+ // entry that lives under its own locale) does not add a second row for the
1791
+ // same release.
1792
+ const defaultLocale = i18n ? i18n.defaultLocale : null;
1793
+ const routeByEntry = new Map<string, string>();
1794
+ for (const route of data.routes) {
1795
+ if (defaultLocale === null || route.locale === defaultLocale) {
1796
+ routeByEntry.set(route.entryId, route.path);
1797
+ }
1798
+ }
1855
1799
 
1856
1800
  const changelogEntries = [
1857
1801
  ...(await getCollection("docs")),${stagedSpread}
@@ -1860,35 +1804,37 @@ const changelogEntries = [
1860
1804
  (entry) =>
1861
1805
  entry.data.type === "changelog" &&
1862
1806
  !entry.data.draft &&
1863
- !entry.data.sidebar?.hidden
1807
+ !entry.data.sidebar?.hidden &&
1808
+ (defaultLocale === null || routeByEntry.has(entry.id))
1864
1809
  )
1865
- .toSorted((a, b) => toTime(entryDate(b)) - toTime(entryDate(a)));
1866
-
1867
- const items = await Promise.all(
1868
- changelogEntries.map(async (entry) => {
1869
- const label =
1870
- entry.data.title ??
1871
- (entry.data.changelog?.version
1872
- ? "v" + entry.data.changelog.version
1873
- : "Update");
1874
- return {
1875
- Content: (await render(entry)).Content,
1876
- date: formatDate(entryDate(entry)),
1877
- href: routeByEntry.get(entry.id) ?? undefined,
1878
- id: slugify(label),
1879
- label,
1880
- major: majorVersion(entry.data.changelog?.version),
1881
- tags: entry.data.changelog?.category
1882
- ? [entry.data.changelog.category]
1883
- : [],
1884
- };
1885
- })
1886
- );
1810
+ .toSorted(
1811
+ (a, b) =>
1812
+ (parseDate(entryDate(b))?.getTime() ?? 0) -
1813
+ (parseDate(entryDate(a))?.getTime() ?? 0)
1814
+ );
1815
+
1816
+ const items = changelogEntries.map((entry) => {
1817
+ const label =
1818
+ entry.data.title ??
1819
+ (entry.data.changelog?.version
1820
+ ? "v" + entry.data.changelog.version
1821
+ : "Update");
1822
+ const date = parseDate(entryDate(entry));
1823
+ const route = routeByEntry.get(entry.id);
1824
+ return {
1825
+ date: date ? formatRowDate(date) : null,
1826
+ dateTime: date ? date.toISOString().slice(0, 10) : null,
1827
+ href: route ? withBase(route) : null,
1828
+ id: slugify(label),
1829
+ label,
1830
+ tag: entry.data.changelog?.category ?? null,
1831
+ year: date ? formatYear(date) : null,
1832
+ };
1833
+ });
1887
1834
 
1888
1835
  // Repeated labels slug to the same id (e.g. two entries with neither a title
1889
1836
  // nor a version both falling back to "update"); suffix the later ones -2, -3,
1890
- // ... so every heading deep-links to its own entry. The first keeps the plain
1891
- // slug, and the rendered ids stay in lockstep with the \`headings\` list below.
1837
+ // ... so every row keeps its own hash anchor. The first keeps the plain slug.
1892
1838
  const seenIds = new Set();
1893
1839
  for (const item of items) {
1894
1840
  let uniqueId = item.id;
@@ -1899,26 +1845,18 @@ for (const item of items) {
1899
1845
  item.id = uniqueId;
1900
1846
  }
1901
1847
 
1902
- // A changelog is semver-paginated only when every visible release parses as
1903
- // semver and they span more than one major line. Older majors then collapse
1904
- // into groups the reader reveals one at a time; otherwise the timeline is flat.
1905
- const majors = items.every((item) => item.major !== null)
1906
- ? [...new Set(items.map((item) => item.major))]
1907
- .filter((major): major is number => major !== null)
1908
- .toSorted((a, b) => b - a)
1909
- : [];
1910
- const paginate = majors.length > 1;
1911
- const majorGroups = majors.map((major) => ({
1912
- items: items.filter((item) => item.major === major),
1913
- label: major + ".x",
1914
- major,
1915
- }));
1916
-
1917
- const headings = items.map((item) => ({
1918
- depth: 2,
1919
- slug: item.id,
1920
- text: item.label,
1921
- }));
1848
+ // Consecutive releases from the same year share a group, so the list reads as
1849
+ // a year rail beside the rows; undated entries (sorted last) form a final
1850
+ // group with no year label.
1851
+ const groups: { items: typeof items; year: string | null }[] = [];
1852
+ for (const item of items) {
1853
+ const last = groups[groups.length - 1];
1854
+ if (last && last.year === item.year) {
1855
+ last.items.push(item);
1856
+ } else {
1857
+ groups.push({ items: [item], year: item.year });
1858
+ }
1859
+ }
1922
1860
 
1923
1861
  const base = data.config.site ? data.config.site.replace(/\\/$/, "") : null;
1924
1862
  // The canonical URL carries the deployment base (the page is served under it),
@@ -1932,9 +1870,9 @@ const canonical = base ? base + basedRoute : null;
1932
1870
  const ogPath = data.config.og.enabled ? withBase("/og/changelog.png") : null;
1933
1871
  const ogImage = ogPath && base ? base + ogPath : ogPath;
1934
1872
 
1935
- // The page chrome (h1, title, description) comes from the same translatable
1936
- // \`changelog\` group as the reveal button; optional chaining tolerates a
1937
- // not-yet-regenerated data snapshot from before these keys existed.
1873
+ // The page chrome (h1, title, description) comes from the translatable
1874
+ // \`changelog\` group; optional chaining tolerates a not-yet-regenerated data
1875
+ // snapshot from before these keys existed.
1938
1876
  const changelogTitle = data.ui.changelog?.title ?? "Changelog";
1939
1877
  const changelogDescription =
1940
1878
  data.ui.changelog?.description ??
@@ -1967,7 +1905,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
1967
1905
  description: changelogDescription,
1968
1906
  route: "/changelog",
1969
1907
  }}
1970
- headings={headings}
1908
+ headings={[]}
1971
1909
  toc={data.config.toc}
1972
1910
  contentLayout="bare"
1973
1911
  themeMode={data.config.theme.mode}
@@ -1988,56 +1926,52 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
1988
1926
  structuredDataEnabled={data.config.structuredData}
1989
1927
  >
1990
1928
  <h1>{changelogTitle}</h1>
1929
+ <p class="text-lg text-muted-foreground">{changelogDescription}</p>
1991
1930
  {
1992
1931
  items.length === 0 ? (
1993
1932
  <p>No changelog entries yet.</p>
1994
- ) : paginate ? (
1995
- <blume-changelog
1996
- class="not-prose mt-8 block"
1997
- data-i18n-more={data.ui.changelog?.showReleases}
1998
- >
1999
- {majorGroups[0].items.map(({ Content, href, id, label, date, tags }) => (
2000
- <Update description={date} href={href} id={id} label={label} tags={tags}>
2001
- <Content components={components} />
2002
- </Update>
2003
- ))}
2004
- {majorGroups.slice(1).map((group) => (
1933
+ ) : (
1934
+ <div class="not-prose mt-10 divide-y divide-border border-border border-y">
1935
+ {groups.map((group) => (
2005
1936
  <section
2006
- aria-label={group.label + " releases"}
2007
- data-changelog-label={group.label}
2008
- data-changelog-major={group.major}
1937
+ aria-label={group.year ?? undefined}
1938
+ class="grid md:grid-cols-[6rem_minmax(0,1fr)] md:gap-x-8"
2009
1939
  >
2010
- {group.items.map(({ Content, href, id, label, date, tags }) => (
2011
- <Update description={date} href={href} id={id} label={label} tags={tags}>
2012
- <Content components={components} />
2013
- </Update>
2014
- ))}
1940
+ <h2 class="mt-0! pt-3! font-medium! text-muted-foreground text-sm! leading-5! tabular-nums max-md:pb-1">
1941
+ {group.year}
1942
+ </h2>
1943
+ <ul class="m-0! list-none divide-y divide-border p-0!">
1944
+ {group.items.map((item) => (
1945
+ <li class="m-0! p-0!" id={item.id}>
1946
+ <a
1947
+ class="group/release flex items-baseline gap-4 py-3 no-underline! hover:no-underline!"
1948
+ href={item.href ?? "#" + item.id}
1949
+ >
1950
+ <span class="min-w-0 flex-1 font-medium text-foreground text-sm transition-colors group-hover/release:text-accent">
1951
+ {item.label}
1952
+ </span>
1953
+ {item.tag && (
1954
+ <span class="shrink-0 rounded-full bg-muted px-2 py-0.5 font-medium text-[0.65rem] text-muted-foreground">
1955
+ {item.tag}
1956
+ </span>
1957
+ )}
1958
+ {item.date && (
1959
+ <time
1960
+ class="shrink-0 font-mono text-muted-foreground text-xs tabular-nums"
1961
+ datetime={item.dateTime}
1962
+ >
1963
+ {item.date}
1964
+ </time>
1965
+ )}
1966
+ </a>
1967
+ </li>
1968
+ ))}
1969
+ </ul>
2015
1970
  </section>
2016
1971
  ))}
2017
- <div class="mt-10 flex justify-center">
2018
- <button
2019
- class="inline-flex items-center gap-2 rounded-full border border-border bg-background px-4 py-2 font-medium text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground"
2020
- data-changelog-more
2021
- hidden
2022
- type="button"
2023
- >
2024
- Show older releases
2025
- </button>
2026
- </div>
2027
- </blume-changelog>
2028
- ) : (
2029
- <div class="not-prose mt-8">
2030
- {items.map(({ Content, href, id, label, date, tags }) => (
2031
- <Update description={date} href={href} id={id} label={label} tags={tags}>
2032
- <Content components={components} />
2033
- </Update>
2034
- ))}
2035
1972
  </div>
2036
1973
  )
2037
1974
  }
2038
- <script>
2039
- import "blume/components/content/changelog-element.ts";
2040
- </script>
2041
1975
  </LayoutComponent>
2042
1976
  `;
2043
1977
  };
@@ -2065,7 +1999,7 @@ const htmlLang = i18n ? i18n.defaultLocale : "en";
2065
1999
  // Recovery links, so a reader — or an agent that followed a stale URL — can
2066
2000
  // get back on track without guessing: every top-level section, then the
2067
2001
  // machine-readable indexes the build emits (the sitemap only exists with a
2068
- // \`deployment.site\`; llms.txt only when \`ai.llmsTxt\` is on). Tabs link to
2002
+ // \`deployment.site\`; llms.txt only when \`agents.llmsTxt\` is on). Tabs link to
2069
2003
  // their resolved target when the section has no index page of its own.
2070
2004
  const suggestions = [
2071
2005
  ...data.navigation.tabs.map((tab) => ({
@@ -2079,6 +2013,31 @@ const suggestions = [
2079
2013
  ? [{ href: withBase("/llms.txt"), label: nf.llms }]
2080
2014
  : []),
2081
2015
  ];
2016
+
2017
+ // Every host serves this one page for any missing URL, so a reader who
2018
+ // mistyped \`/ar/…\` would get the default locale's message. The other locales'
2019
+ // copy rides along, and the script below swaps it in when the URL's first
2020
+ // segment names one of them — the message, its language and direction, the
2021
+ // tab title, and the home link (to that locale's root).
2022
+ const localized = Object.fromEntries(
2023
+ (i18n?.locales ?? [])
2024
+ .filter((l) => l.code !== i18n?.defaultLocale && data.uiByLocale[l.code])
2025
+ .map((l) => {
2026
+ const strings = data.uiByLocale[l.code].notFound;
2027
+ return [
2028
+ l.code,
2029
+ {
2030
+ description: strings.description,
2031
+ dir: l.dir ?? "ltr",
2032
+ home: strings.home,
2033
+ homeHref: withBase("/" + l.code),
2034
+ suggestions: strings.suggestions,
2035
+ title: strings.title,
2036
+ },
2037
+ ];
2038
+ })
2039
+ );
2040
+ const localizedJson = JSON.stringify(localized).replaceAll("<", "\\\\u003c");
2082
2041
  ---
2083
2042
 
2084
2043
  <PageLayout
@@ -2100,6 +2059,8 @@ const suggestions = [
2100
2059
  >
2101
2060
  <div
2102
2061
  class="mx-auto grid w-full max-w-5xl gap-12 px-6 py-20 sm:py-28 md:grid-cols-[3fr_2fr] md:gap-16 lg:gap-24 lg:py-36"
2062
+ data-base={withBase("/")}
2063
+ data-blume-not-found
2103
2064
  >
2104
2065
  <div class="flex flex-col items-start">
2105
2066
  <p
@@ -2109,24 +2070,26 @@ const suggestions = [
2109
2070
  </p>
2110
2071
  <h1
2111
2072
  class="mt-4 text-balance text-4xl font-semibold tracking-tight text-foreground sm:text-5xl"
2073
+ data-nf="title"
2112
2074
  >
2113
2075
  {nf.title}
2114
2076
  </h1>
2115
- <p class="mt-4 max-w-md text-pretty text-lg text-muted-foreground">
2077
+ <p class="mt-4 max-w-md text-pretty text-lg text-muted-foreground" data-nf="description">
2116
2078
  {nf.description}
2117
2079
  </p>
2118
2080
  <a
2119
2081
  class="mt-8 inline-flex items-center gap-1.5 rounded-full bg-accent py-2 pe-4 ps-3.5 text-sm font-medium text-accent-foreground transition-opacity hover:opacity-90"
2082
+ data-nf-home
2120
2083
  href={withBase("/")}
2121
2084
  >
2122
2085
  <Icon class="rtl:-scale-x-100" name="arrow-left" size={14} />
2123
- {nf.home}
2086
+ <span data-nf="home">{nf.home}</span>
2124
2087
  </a>
2125
2088
  </div>
2126
2089
  {
2127
2090
  suggestions.length > 0 && (
2128
- <nav aria-label={nf.suggestions} class="md:border-s md:border-border md:ps-12 lg:ps-16">
2129
- <h2 class="text-xs font-medium uppercase tracking-widest text-muted-foreground">
2091
+ <nav aria-label={nf.suggestions} class="md:border-s md:border-border md:ps-12 lg:ps-16" data-nf-suggestions>
2092
+ <h2 class="text-xs font-medium uppercase tracking-widest text-muted-foreground" data-nf="suggestions">
2130
2093
  {nf.suggestions}
2131
2094
  </h2>
2132
2095
  <ul class="mt-4 divide-y divide-border border-y border-border">
@@ -2150,6 +2113,37 @@ const suggestions = [
2150
2113
  )
2151
2114
  }
2152
2115
  </div>
2116
+ <script id="blume-not-found-locales" is:inline type="application/json" set:html={localizedJson} />
2117
+ <script is:inline>
2118
+ (() => {
2119
+ const apply = () => {
2120
+ const root = document.querySelector("[data-blume-not-found]");
2121
+ const source = document.getElementById("blume-not-found-locales");
2122
+ if (!root || !source) {
2123
+ return;
2124
+ }
2125
+ const base = root.getAttribute("data-base") || "/";
2126
+ const path = location.pathname.startsWith(base)
2127
+ ? location.pathname.slice(base.length)
2128
+ : location.pathname.replace(/^\\/+/, "");
2129
+ const code = path.split("/")[0];
2130
+ const entry = JSON.parse(source.textContent || "{}")[code];
2131
+ if (!entry) {
2132
+ return;
2133
+ }
2134
+ root.setAttribute("lang", code);
2135
+ root.setAttribute("dir", entry.dir);
2136
+ for (const el of root.querySelectorAll("[data-nf]")) {
2137
+ el.textContent = entry[el.getAttribute("data-nf")];
2138
+ }
2139
+ root.querySelector("[data-nf-home]")?.setAttribute("href", entry.homeHref);
2140
+ root.querySelector("[data-nf-suggestions]")?.setAttribute("aria-label", entry.suggestions);
2141
+ document.title = entry.title;
2142
+ };
2143
+ apply();
2144
+ document.addEventListener("astro:page-load", apply);
2145
+ })();
2146
+ </script>
2153
2147
  </PageLayout>
2154
2148
  `;
2155
2149
  var notFoundMarkdownTemplate = () => `// Generated by Blume. Do not edit. Override by adding \`pages/404.astro\`.
@@ -2318,37 +2312,6 @@ const context = ${JSON.stringify(context)};
2318
2312
 
2319
2313
  export const ALL: APIRoute = ({ request }) => apiNotFoundResponse(request, context);
2320
2314
  `;
2321
- var islandDirective = (spec) => spec.client === "only" ? `client:only="${spec.framework}"` : `client:${spec.client}`;
2322
- var wrapperPropsType = (name) => `type Props = typeof ${name} extends (
2323
- props: infer P extends object,
2324
- ...rest: never[]
2325
- ) => unknown
2326
- ? P
2327
- : Record<string, unknown>;`;
2328
- var islandWrapperTemplate = (spec) => `---
2329
- // Generated by Blume. Do not edit.
2330
- import Island from ${JSON.stringify(spec.file)};
2331
- ${wrapperPropsType("Island")}
2332
- ---
2333
- <Island ${islandDirective(spec)} {...Astro.props}><slot /></Island>
2334
- `;
2335
- var islandMapTemplate = (specs) => {
2336
- if (specs.length === 0) {
2337
- return `// Generated by Blume. Do not edit.
2338
- export const islandComponents = {};
2339
- `;
2340
- }
2341
- const imports = specs.map((spec, index) => `import I${index} from "./islands/${spec.name}.astro";`).join(`
2342
- `);
2343
- const entries = specs.map((spec, index) => ` ${spec.name}: I${index},`).join(`
2344
- `);
2345
- return `// Generated by Blume. Do not edit.
2346
- ${imports}
2347
- export const islandComponents = {
2348
- ${entries}
2349
- };
2350
- `;
2351
- };
2352
2315
  var exampleDirective = (spec) => {
2353
2316
  if (spec.framework === "astro" || !spec.client) {
2354
2317
  return "";
@@ -2356,9 +2319,9 @@ var exampleDirective = (spec) => {
2356
2319
  return spec.client === "only" ? `client:only="${spec.framework}" ` : `client:${spec.client} `;
2357
2320
  };
2358
2321
  var exampleSlug = (path) => path.replaceAll(/[^a-zA-Z0-9]/gu, (char) => `_${(char.codePointAt(0) ?? 0).toString(16)}_`);
2359
- var exampleWrapperTemplate = (spec) => `---
2322
+ var exampleWrapperTemplate = (spec, fromDir) => `---
2360
2323
  // Generated by Blume. Do not edit.
2361
- import Example from ${JSON.stringify(spec.file)};
2324
+ import Example from ${JSON.stringify(importSpecifier(spec.file, fromDir))};
2362
2325
  ${wrapperPropsType("Example")}
2363
2326
  ---
2364
2327
  <Example ${exampleDirective(spec)}{...Astro.props}><slot /></Example>
@@ -2502,7 +2465,7 @@ var runtimeTsconfigTemplate = () => `${JSON.stringify({
2502
2465
  }, null, 2)}
2503
2466
  `;
2504
2467
 
2505
- export { ADAPTER_IGNORE_DIRS, servesClientSubdir, deployStaticDir, surfaceAdapterOutput, resolveAskBackend, askBackendRuntimeDep, buildHomeLinkHeader, platformRedirects, publishRuntimeModules, runtimeDependencies, astroConfigTemplate, stagedContentDir, contentConfigTemplate, askEndpointTemplate, askComponentTemplate, searchEndpointTemplate, featuresTemplate, searchClientTemplate, mixedbreadSearchEndpointTemplate, rawMarkdownEndpointTemplate, contentAssetsEndpointTemplate, mcpPageFile, mcpEndpointTemplate, playgroundProxyTemplate, staticJsonEndpointTemplate, rssEndpointTemplate, navFragmentTemplate, ogEndpointTemplate, scalarReferenceTemplate, catchAllPageTemplate, changelogIndexTemplate, notFoundPageTemplate, notFoundMarkdownTemplate, notFoundJsonTemplate, apiPagesIndexTemplate, apiPageTemplate, apiNavigationTemplate, apiSearchTemplate, apiNotFoundTemplate, islandWrapperTemplate, islandMapTemplate, exampleSlug, exampleWrapperTemplate, examplesRouteBase, exampleMapTemplate, examplesPageTemplate, runtimePackageTemplate, runtimeTsconfigTemplate };
2468
+ export { planComponentSlots, publishRuntimeModules, runtimeDependencies, EJECTED_CONFIG_HEADER, astroConfigTemplate, stagedContentDir, contentConfigTemplate, askEndpointTemplate, askComponentTemplate, searchEndpointTemplate, featuresTemplate, searchClientTemplate, mixedbreadSearchEndpointTemplate, rawMarkdownEndpointTemplate, contentAssetsEndpointTemplate, mcpPageFile, mcpEndpointTemplate, playgroundProxyTemplate, staticJsonEndpointTemplate, rssEndpointTemplate, navFragmentTemplate, ogEndpointTemplate, scalarReferenceTemplate, catchAllPageTemplate, changelogIndexTemplate, notFoundPageTemplate, notFoundMarkdownTemplate, notFoundJsonTemplate, apiPagesIndexTemplate, apiPageTemplate, apiNavigationTemplate, apiSearchTemplate, apiNotFoundTemplate, exampleSlug, exampleWrapperTemplate, examplesRouteBase, exampleMapTemplate, examplesPageTemplate, runtimePackageTemplate, runtimeTsconfigTemplate };
2506
2469
 
2507
- //# debugId=27833C6A2810E0DD64756E2164756E21
2508
- //# sourceMappingURL=chunk-ps4m1xh4.js.map
2470
+ //# debugId=9E2BF1A2CC0BBFF264756E2164756E21
2471
+ //# sourceMappingURL=chunk-mnqj32sj.js.map