blume 1.7.2 → 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 (677) hide show
  1. package/AGENTS.md +19 -0
  2. package/CHANGELOG.md +227 -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-xhtpx3ff.js → chunk-1w8dp3qb.js} +17 -16
  7. package/dist/cli/{chunk-xhtpx3ff.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-9he6crym.js → chunk-6k8vp3ta.js} +25 -13
  15. package/dist/cli/{chunk-9he6crym.js.map → chunk-6k8vp3ta.js.map} +4 -4
  16. package/dist/cli/{chunk-mt76t7dj.js → chunk-79njf86q.js} +133 -54
  17. package/dist/cli/chunk-79njf86q.js.map +11 -0
  18. package/dist/cli/{chunk-3w7b2vcx.js → chunk-7ez8ny0t.js} +2 -2
  19. package/dist/cli/{chunk-688e0dde.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-hs3gbh8p.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-9bkjd11x.js → chunk-bw22s759.js} +15 -5
  33. package/dist/cli/{chunk-9bkjd11x.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-t3tj0dgr.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-exeeb35e.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-12dxjqk7.js → chunk-fh5hj5jt.js} +44 -21
  48. package/dist/cli/chunk-fh5hj5jt.js.map +10 -0
  49. package/dist/cli/{chunk-8cd8tj54.js → chunk-j8mw0za6.js} +86 -57
  50. package/dist/cli/chunk-j8mw0za6.js.map +35 -0
  51. package/dist/cli/chunk-jts8mvcz.js +106 -0
  52. package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
  53. package/dist/cli/{chunk-ejjx8znq.js → chunk-mnqj32sj.js} +505 -536
  54. package/dist/cli/chunk-mnqj32sj.js.map +12 -0
  55. package/dist/cli/{chunk-196vjxp9.js → chunk-mwt1k8n7.js} +100 -372
  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-n9sra6sy.js → chunk-pat2zzwc.js} +10 -14
  60. package/dist/cli/{chunk-n9sra6sy.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-cvky9gb2.js → chunk-sqn5t4q0.js} +81 -87
  64. package/dist/cli/chunk-sqn5t4q0.js.map +10 -0
  65. package/dist/cli/{chunk-eevwt1sc.js → chunk-tzne8qfq.js} +15 -15
  66. package/dist/cli/{chunk-eevwt1sc.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-5n7t497w.js → chunk-z1f5arsg.js} +247 -755
  74. package/dist/cli/chunk-z1f5arsg.js.map +36 -0
  75. package/dist/cli/{chunk-hdm2dkd2.js → chunk-zg2gtj10.js} +1086 -2596
  76. package/dist/cli/chunk-zg2gtj10.js.map +35 -0
  77. package/dist/cli/{chunk-ppfvdcd4.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 +209 -505
  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 +28 -11
  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 +2291 -441
  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 +20 -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 +176 -61
  290. package/docs/configuration/customization.mdx +15 -9
  291. package/docs/configuration/index.mdx +52 -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 +37 -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 +12 -7
  303. package/docs/content/sources.mdx +145 -50
  304. package/docs/content/syntax.mdx +26 -12
  305. package/docs/content/versioning.mdx +3 -3
  306. package/docs/discoverability/agent-discovery.mdx +91 -10
  307. package/docs/discoverability/index.mdx +5 -5
  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 +26 -22
  329. package/src/ai/ai-catalog.ts +259 -0
  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 +19 -6
  338. package/src/ai/llms.ts +26 -15
  339. package/src/ai/markdown.ts +35 -5
  340. package/src/ai/mcp/data.ts +9 -5
  341. package/src/ai/mcp/discovery.ts +1 -1
  342. package/src/ai/openapi-components.ts +4 -1
  343. package/src/ai/relative-links.ts +170 -0
  344. package/src/ai/serializers.ts +2 -2
  345. package/src/ai/skills.ts +1 -1
  346. package/src/ai/web-bot-auth.ts +2 -2
  347. package/src/analytics/adobe.ts +46 -0
  348. package/src/analytics/amplitude.ts +79 -0
  349. package/src/analytics/clarity.ts +46 -0
  350. package/src/analytics/clearbit.ts +47 -0
  351. package/src/analytics/cloudflare.ts +67 -0
  352. package/src/analytics/fathom.ts +64 -0
  353. package/src/analytics/google-analytics.ts +84 -0
  354. package/src/analytics/google-tag-manager.ts +61 -0
  355. package/src/analytics/head.ts +130 -0
  356. package/src/analytics/heap.ts +65 -0
  357. package/src/analytics/hightouch.ts +77 -0
  358. package/src/analytics/hotjar.ts +47 -0
  359. package/src/analytics/index.ts +71 -0
  360. package/src/analytics/inline.ts +21 -0
  361. package/src/analytics/logrocket.ts +71 -0
  362. package/src/analytics/mixpanel.ts +92 -0
  363. package/src/analytics/pirsch.ts +66 -0
  364. package/src/analytics/plausible.ts +83 -0
  365. package/src/analytics/posthog.ts +78 -0
  366. package/src/analytics/schema.ts +60 -0
  367. package/src/analytics/script.ts +60 -0
  368. package/src/analytics/segment.ts +85 -0
  369. package/src/analytics/vercel.ts +50 -0
  370. package/src/astro/adapter-root.ts +7 -9
  371. package/src/astro/component-slots.ts +131 -91
  372. package/src/astro/generate.ts +114 -345
  373. package/src/astro/integration.ts +2 -6
  374. package/src/astro/pages.ts +13 -101
  375. package/src/astro/render-deps.ts +379 -0
  376. package/src/astro/runtime-deps.ts +201 -0
  377. package/src/astro/templates.ts +554 -541
  378. package/src/audit/agent.ts +24 -0
  379. package/src/audit/catalog.ts +2 -2
  380. package/src/audit/checks/assets.ts +2 -2
  381. package/src/audit/checks/dns-aid.ts +1 -1
  382. package/src/audit/checks/duplicates.ts +3 -1
  383. package/src/audit/checks/i18n.ts +1 -1
  384. package/src/audit/checks/indexability.ts +7 -7
  385. package/src/audit/checks/links.ts +2 -2
  386. package/src/audit/checks/llms.ts +6 -6
  387. package/src/audit/checks/network.ts +3 -3
  388. package/src/audit/checks/og-image.ts +2 -2
  389. package/src/audit/checks/robots.ts +1 -1
  390. package/src/audit/checks/sitemap.ts +2 -2
  391. package/src/audit/checks/social.ts +1 -1
  392. package/src/audit/run.ts +4 -3
  393. package/src/audit/terms.ts +31 -0
  394. package/src/audit/url.ts +13 -13
  395. package/src/cli/command-meta.ts +10 -0
  396. package/src/cli/commands/audit.ts +39 -20
  397. package/src/cli/commands/build.ts +71 -314
  398. package/src/cli/commands/check.ts +1 -0
  399. package/src/cli/commands/dev.ts +40 -1
  400. package/src/cli/commands/doctor.ts +90 -14
  401. package/src/cli/commands/eject.ts +44 -7
  402. package/src/cli/commands/eval.ts +2 -2
  403. package/src/cli/commands/init.ts +161 -41
  404. package/src/cli/commands/migrate.ts +121 -0
  405. package/src/cli/commands/preview.ts +7 -1
  406. package/src/cli/commands/translate.ts +2 -2
  407. package/src/cli/commands/upgrade.ts +141 -0
  408. package/src/cli/commands/version.ts +57 -44
  409. package/src/cli/eject-scripts.ts +121 -6
  410. package/src/cli/index.ts +11 -1
  411. package/src/cli/init/install.ts +70 -0
  412. package/src/cli/init/questions.ts +7 -0
  413. package/src/cli/init/scaffold.ts +459 -75
  414. package/src/cli/lazy-command.ts +37 -1
  415. package/src/cli/prepare.ts +40 -6
  416. package/src/cli/required-secrets.ts +38 -11
  417. package/src/cli/unknown-flags.ts +266 -0
  418. package/src/cli/yarn-pnp.ts +52 -0
  419. package/src/components/content/AccordionItem.astro +7 -1
  420. package/src/components/content/Card.astro +4 -3
  421. package/src/components/content/ColorItem.astro +22 -4
  422. package/src/components/content/GithubInfo.astro +2 -2
  423. package/src/components/content/Prompt.astro +25 -25
  424. package/src/components/content/Tabs.astro +3 -1
  425. package/src/components/content/Tile.astro +2 -3
  426. package/src/components/content/Tooltip.astro +57 -9
  427. package/src/components/content/content-strings.ts +34 -0
  428. package/src/components/content/diff.ts +1 -1
  429. package/src/components/content/mermaid-element.ts +13 -2
  430. package/src/components/content/prompt-markdown.ts +292 -0
  431. package/src/components/content/tooltip-id.ts +41 -0
  432. package/src/components/islands/hooks.ts +75 -3
  433. package/src/components/layout/Analytics.astro +21 -79
  434. package/src/components/layout/Banner.astro +3 -1
  435. package/src/components/layout/DiscoveryLinks.astro +69 -0
  436. package/src/components/layout/Header.astro +83 -20
  437. package/src/components/layout/LanguageSwitcher.astro +4 -1
  438. package/src/components/layout/Logo.astro +23 -2
  439. package/src/components/layout/NavSelector.astro +13 -2
  440. package/src/components/layout/NavTree.astro +12 -3
  441. package/src/components/layout/NavTreeScript.astro +17 -3
  442. package/src/components/layout/PageActions.astro +3 -3
  443. package/src/components/layout/PageFeedback.astro +11 -1
  444. package/src/components/layout/PageLayout.astro +52 -5
  445. package/src/components/layout/ReferenceLayout.astro +21 -12
  446. package/src/components/layout/RootLayout.astro +69 -43
  447. package/src/components/layout/Search.astro +30 -6
  448. package/src/components/layout/WebMcp.astro +1 -1
  449. package/src/components/layout/analytics-client.ts +101 -15
  450. package/src/components/layout/drawer-inert.ts +113 -15
  451. package/src/components/layout/dropdown-clamp.ts +105 -0
  452. package/src/components/layout/head-scripts.ts +15 -6
  453. package/src/components/layout/nav-utils.ts +17 -0
  454. package/src/components/layout/search/algolia.ts +8 -8
  455. package/src/components/layout/search/orama-cloud.ts +9 -7
  456. package/src/components/layout/search/typesense.ts +11 -17
  457. package/src/components/openapi/MessageComposer.astro +2 -2
  458. package/src/components/openapi/Playground.astro +2 -2
  459. package/src/components/openapi/playground-client.ts +79 -10
  460. package/src/core/changelog-index.ts +24 -0
  461. package/src/core/component-overrides.ts +399 -154
  462. package/src/core/config-input.ts +212 -543
  463. package/src/core/config.ts +130 -41
  464. package/src/core/custom-pages.ts +105 -0
  465. package/src/core/data.ts +32 -11
  466. package/src/core/define-components.ts +12 -9
  467. package/src/core/deployment-env.ts +18 -74
  468. package/src/core/diagnostics.ts +14 -7
  469. package/src/core/graph.ts +69 -25
  470. package/src/core/i18n-ui.ts +6 -2
  471. package/src/core/i18n.ts +17 -0
  472. package/src/core/includes.ts +156 -38
  473. package/src/core/last-modified.ts +6 -11
  474. package/src/core/links.ts +166 -2
  475. package/src/core/manifest.ts +10 -3
  476. package/src/core/navigation.ts +137 -19
  477. package/src/core/new-tab.ts +35 -0
  478. package/src/core/node-require.ts +21 -0
  479. package/src/core/project-graph.ts +42 -26
  480. package/src/core/project.ts +9 -4
  481. package/src/core/request-body.ts +61 -0
  482. package/src/core/safe-href.ts +28 -0
  483. package/src/core/safe-links.ts +68 -0
  484. package/src/core/schema.ts +531 -721
  485. package/src/core/server-features.ts +8 -9
  486. package/src/core/sources/assets.ts +47 -11
  487. package/src/core/sources/collection.ts +67 -0
  488. package/src/core/sources/contentful-rich-text.ts +285 -0
  489. package/src/core/sources/contentful.ts +173 -0
  490. package/src/core/sources/github-releases.ts +51 -1
  491. package/src/core/sources/json.ts +71 -0
  492. package/src/core/sources/lexical.ts +195 -0
  493. package/src/core/sources/lower.ts +226 -0
  494. package/src/core/sources/normalize.ts +52 -2
  495. package/src/core/sources/notion.ts +39 -28
  496. package/src/core/sources/payload.ts +135 -0
  497. package/src/core/sources/portable-text.ts +11 -16
  498. package/src/core/sources/remote.ts +226 -0
  499. package/src/core/sources/resolve.ts +104 -166
  500. package/src/core/sources/sanity.ts +16 -49
  501. package/src/core/sources/strapi-blocks.ts +124 -0
  502. package/src/core/sources/strapi.ts +191 -0
  503. package/src/core/sources/types.ts +12 -1
  504. package/src/core/types.ts +20 -1
  505. package/src/core/ui-packs/ar.ts +6 -2
  506. package/src/core/ui-packs/bg.ts +6 -2
  507. package/src/core/ui-packs/bn.ts +6 -2
  508. package/src/core/ui-packs/ca.ts +3 -1
  509. package/src/core/ui-packs/cs.ts +6 -2
  510. package/src/core/ui-packs/da.ts +6 -2
  511. package/src/core/ui-packs/de.ts +6 -2
  512. package/src/core/ui-packs/el.ts +3 -1
  513. package/src/core/ui-packs/es.ts +3 -1
  514. package/src/core/ui-packs/fa.ts +6 -2
  515. package/src/core/ui-packs/fi.ts +6 -2
  516. package/src/core/ui-packs/fr.ts +3 -1
  517. package/src/core/ui-packs/he.ts +6 -2
  518. package/src/core/ui-packs/hi.ts +6 -2
  519. package/src/core/ui-packs/hr.ts +6 -2
  520. package/src/core/ui-packs/hu.ts +6 -2
  521. package/src/core/ui-packs/id.ts +6 -2
  522. package/src/core/ui-packs/it.ts +3 -1
  523. package/src/core/ui-packs/ja.ts +3 -1
  524. package/src/core/ui-packs/ko.ts +3 -1
  525. package/src/core/ui-packs/nl.ts +6 -2
  526. package/src/core/ui-packs/no.ts +6 -2
  527. package/src/core/ui-packs/pl.ts +6 -2
  528. package/src/core/ui-packs/pt-br.ts +3 -1
  529. package/src/core/ui-packs/pt.ts +3 -1
  530. package/src/core/ui-packs/ro.ts +6 -2
  531. package/src/core/ui-packs/ru.ts +6 -2
  532. package/src/core/ui-packs/sk.ts +6 -2
  533. package/src/core/ui-packs/sr.ts +6 -2
  534. package/src/core/ui-packs/sv.ts +6 -2
  535. package/src/core/ui-packs/th.ts +3 -1
  536. package/src/core/ui-packs/tr.ts +6 -2
  537. package/src/core/ui-packs/uk.ts +6 -2
  538. package/src/core/ui-packs/vi.ts +3 -1
  539. package/src/core/ui-packs/zh-tw.ts +3 -1
  540. package/src/core/ui-packs/zh.ts +3 -1
  541. package/src/core/unrecognized-keys.ts +10 -0
  542. package/src/core/version-cut.ts +116 -8
  543. package/src/deploy/adapter-output.ts +57 -97
  544. package/src/deploy/adapters/cloudflare.ts +39 -0
  545. package/src/deploy/adapters/index.ts +41 -0
  546. package/src/deploy/adapters/netlify.ts +34 -0
  547. package/src/deploy/adapters/node.ts +34 -0
  548. package/src/deploy/adapters/registry.ts +127 -0
  549. package/src/deploy/adapters/types.ts +92 -0
  550. package/src/deploy/adapters/vercel.ts +35 -0
  551. package/src/deploy/artifacts.ts +67 -28
  552. package/src/deploy/cloudflare-negotiation.ts +179 -100
  553. package/src/deploy/function-bundle.ts +18 -3
  554. package/src/deploy/headers.ts +129 -22
  555. package/src/deploy/node-headers.ts +198 -0
  556. package/src/deploy/platforms/cloudflare.ts +312 -0
  557. package/src/deploy/platforms/index.ts +67 -0
  558. package/src/deploy/platforms/netlify.ts +52 -0
  559. package/src/deploy/platforms/node.ts +40 -0
  560. package/src/deploy/platforms/paths.ts +42 -0
  561. package/src/deploy/platforms/static.ts +29 -0
  562. package/src/deploy/platforms/types.ts +112 -0
  563. package/src/deploy/platforms/vercel.ts +193 -0
  564. package/src/deploy/redirects.ts +30 -18
  565. package/src/deploy/robots.ts +3 -3
  566. package/src/deploy/rss.ts +2 -2
  567. package/src/deploy/sitemap.ts +2 -2
  568. package/src/deploy/vercel-negotiation.ts +27 -4
  569. package/src/eval/agents.ts +32 -1
  570. package/src/eval/findings.ts +19 -11
  571. package/src/eval/report.ts +10 -2
  572. package/src/markdown/external-links.ts +65 -0
  573. package/src/markdown/include.ts +45 -27
  574. package/src/markdown/index.ts +34 -9
  575. package/src/markdown/inline-code.ts +12 -6
  576. package/src/markdown/relative-links.ts +324 -0
  577. package/src/markdown/themes.ts +3 -3
  578. package/src/migrate/migrate.ts +149 -0
  579. package/src/openapi/parse.ts +64 -16
  580. package/src/openapi/proxy.ts +62 -10
  581. package/src/openapi/references.ts +147 -147
  582. package/src/openapi/render-mdx.ts +32 -10
  583. package/src/openapi/scalar.ts +15 -13
  584. package/src/openapi/sentence.ts +14 -0
  585. package/src/openapi/source.ts +37 -21
  586. package/src/openapi/spec-dependency-error.ts +15 -0
  587. package/src/reference/asyncapi.ts +83 -0
  588. package/src/reference/graphql.ts +89 -0
  589. package/src/reference/index.ts +40 -0
  590. package/src/reference/openapi.ts +83 -0
  591. package/src/reference/options.ts +201 -0
  592. package/src/reference/scalar.ts +136 -0
  593. package/src/reference/schema.ts +88 -0
  594. package/src/registry/eject.ts +97 -42
  595. package/src/search/adapters/algolia.ts +46 -0
  596. package/src/search/adapters/flexsearch.ts +29 -0
  597. package/src/search/adapters/index.ts +39 -0
  598. package/src/search/adapters/mixedbread.ts +39 -0
  599. package/src/search/adapters/orama-cloud.ts +51 -0
  600. package/src/search/adapters/orama.ts +24 -0
  601. package/src/search/adapters/pagefind.ts +27 -0
  602. package/src/search/adapters/registry.ts +131 -0
  603. package/src/search/adapters/types.ts +46 -0
  604. package/src/search/adapters/typesense.ts +57 -0
  605. package/src/search/build.ts +33 -7
  606. package/src/search/documents.ts +6 -0
  607. package/src/search/sync/algolia.ts +12 -11
  608. package/src/search/sync/index.ts +35 -20
  609. package/src/search/sync/orama-cloud.ts +12 -9
  610. package/src/search/sync/typesense.ts +15 -13
  611. package/src/sources/contentful.ts +63 -0
  612. package/src/sources/custom.ts +38 -0
  613. package/src/sources/filesystem.ts +51 -0
  614. package/src/sources/github-releases.ts +52 -0
  615. package/src/sources/index.ts +60 -0
  616. package/src/sources/mdx-remote.ts +76 -0
  617. package/src/sources/notion.ts +63 -0
  618. package/src/sources/obsidian.ts +38 -0
  619. package/src/sources/payload.ts +60 -0
  620. package/src/sources/registry.ts +182 -0
  621. package/src/sources/sanity.ts +66 -0
  622. package/src/sources/shared.ts +52 -0
  623. package/src/sources/strapi.ts +58 -0
  624. package/src/theme/entry.ts +47 -2
  625. package/src/translate/report.ts +40 -7
  626. package/src/upgrade/upgrade.ts +499 -0
  627. package/dist/cli/chunk-12dxjqk7.js.map +0 -10
  628. package/dist/cli/chunk-196vjxp9.js.map +0 -13
  629. package/dist/cli/chunk-2mzebbbz.js +0 -69
  630. package/dist/cli/chunk-2z47ypj8.js.map +0 -11
  631. package/dist/cli/chunk-30e87n55.js +0 -108
  632. package/dist/cli/chunk-30e87n55.js.map +0 -10
  633. package/dist/cli/chunk-450a7rcr.js +0 -185
  634. package/dist/cli/chunk-450a7rcr.js.map +0 -11
  635. package/dist/cli/chunk-5n7t497w.js.map +0 -40
  636. package/dist/cli/chunk-61j18dwk.js +0 -5342
  637. package/dist/cli/chunk-61j18dwk.js.map +0 -58
  638. package/dist/cli/chunk-88by27n5.js +0 -17
  639. package/dist/cli/chunk-88by27n5.js.map +0 -10
  640. package/dist/cli/chunk-8cd8tj54.js.map +0 -34
  641. package/dist/cli/chunk-aztttvb3.js +0 -381
  642. package/dist/cli/chunk-aztttvb3.js.map +0 -12
  643. package/dist/cli/chunk-cvky9gb2.js.map +0 -11
  644. package/dist/cli/chunk-ejjx8znq.js.map +0 -15
  645. package/dist/cli/chunk-fmceyezb.js +0 -1007
  646. package/dist/cli/chunk-fmceyezb.js.map +0 -13
  647. package/dist/cli/chunk-hdm2dkd2.js.map +0 -48
  648. package/dist/cli/chunk-hs3gbh8p.js.map +0 -10
  649. package/dist/cli/chunk-jbj4qhfw.js +0 -30
  650. package/dist/cli/chunk-jbj4qhfw.js.map +0 -10
  651. package/dist/cli/chunk-mqb2ka8m.js +0 -68
  652. package/dist/cli/chunk-mqb2ka8m.js.map +0 -10
  653. package/dist/cli/chunk-mt76t7dj.js.map +0 -11
  654. package/dist/cli/chunk-q4rae3bg.js +0 -60
  655. package/dist/cli/chunk-q4rae3bg.js.map +0 -10
  656. package/dist/cli/chunk-ra1v2nc2.js +0 -35
  657. package/dist/cli/chunk-ra1v2nc2.js.map +0 -10
  658. package/dist/cli/chunk-t3tj0dgr.js.map +0 -15
  659. package/dist/cli/chunk-tqa1s0k8.js +0 -69
  660. package/dist/cli/chunk-tqa1s0k8.js.map +0 -11
  661. package/dist/cli/chunk-vh9w1sgp.js +0 -73
  662. package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
  663. package/dist/cli/chunk-vkrsvbr5.js +0 -107
  664. package/dist/cli/chunk-vkrsvbr5.js.map +0 -11
  665. package/dist/cli/chunk-vrfp10qk.js +0 -81
  666. package/dist/cli/chunk-vrfp10qk.js.map +0 -10
  667. package/dist/cli/chunk-wjt80jps.js +0 -1049
  668. package/dist/cli/chunk-wjt80jps.js.map +0 -24
  669. package/docs/advanced/api-reference.mdx +0 -240
  670. package/docs/reference/cli.mdx +0 -197
  671. package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
  672. package/src/components/content/changelog-element.ts +0 -69
  673. package/src/search/providers.ts +0 -91
  674. /package/dist/cli/{chunk-3w7b2vcx.js.map → chunk-7ez8ny0t.js.map} +0 -0
  675. /package/dist/cli/{chunk-688e0dde.js.map → chunk-88cpgt6h.js.map} +0 -0
  676. /package/dist/cli/{chunk-exeeb35e.js.map → chunk-f7t03s3g.js.map} +0 -0
  677. /package/dist/cli/{chunk-ppfvdcd4.js.map → chunk-zxccj738.js.map} +0 -0
@@ -1,167 +1,121 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- OPENAPI_PATH,
4
- API_CATALOG_PATH,
5
- hasApiCatalog
6
- } from "./chunk-tqa1s0k8.js";
3
+ trimChar,
4
+ normalizeBasePath
5
+ } from "./chunk-jts8mvcz.js";
7
6
  import {
8
- hasScalarReferences,
7
+ buildHomeLinkHeader,
8
+ resolveDocsCollection,
9
+ TOC_HIDDEN_KEY,
10
+ deployPassthrough,
9
11
  fontLocaleCodes,
10
- buildFontEntries
11
- } from "./chunk-61j18dwk.js";
12
+ buildFontEntries,
13
+ applyBaseToAstroRedirects,
14
+ distDir,
15
+ adapterRoot,
16
+ SVG_ASSET_POLICY,
17
+ deployPlatform
18
+ } from "./chunk-xaz13gwg.js";
12
19
  import {
13
- searchProviderMeta
14
- } from "./chunk-q4rae3bg.js";
15
- import {
16
- TOC_HIDDEN_KEY,
17
20
  BLUME_IGNORE_DIRS
18
- } from "./chunk-hdm2dkd2.js";
19
- import {
20
- trimChar,
21
- normalizeBasePath,
22
- withBasePath,
23
- withComposedBasePath
24
- } from "./chunk-2mzebbbz.js";
25
-
26
- // src/deploy/adapter-output.ts
27
- import { existsSync } from "node:fs";
28
- import { cp, mkdir, rm } from "node:fs/promises";
29
- import { dirname, join } from "pathe";
30
- var ADAPTER_IGNORE_DIRS = {
31
- netlify: ".netlify/",
32
- vercel: ".vercel/"
33
- };
34
- var ADAPTER_OUTPUT_PATHS = {
35
- netlify: ".netlify/v1"
36
- };
37
- var servesClientSubdir = (deployment) => deployment.output === "server" && (deployment.adapter === "node" || deployment.adapter === "cloudflare");
38
- var deployStaticDir = (config, context) => {
39
- const { adapter, output } = config.deployment;
40
- if (output === "server" && adapter === "vercel") {
41
- return join(context.root, ".vercel", "output", "static");
42
- }
43
- const dist = context.distDir ?? join(context.root, "dist");
44
- if (servesClientSubdir(config.deployment)) {
45
- return join(dist, "client");
46
- }
47
- return dist;
48
- };
49
- var surfaceAdapterOutput = async (config, context) => {
50
- const { adapter, output } = config.deployment;
51
- if (output !== "server" || !adapter) {
52
- return { moved: false };
53
- }
54
- const rel = ADAPTER_OUTPUT_PATHS[adapter];
55
- if (!rel) {
56
- return { moved: false };
57
- }
58
- const from = join(context.outDir, rel);
59
- const to = join(context.root, rel);
60
- if (!existsSync(from)) {
61
- return { moved: false };
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
+ }
62
45
  }
63
- await mkdir(dirname(to), { recursive: true });
64
- await rm(to, { force: true, recursive: true });
65
- await cp(from, to, { recursive: true, verbatimSymlinks: true });
66
- await rm(from, { force: true, recursive: true });
67
- return { from, moved: true, to };
68
46
  };
69
-
70
- // src/ai/link-headers.ts
71
- var buildHomeLinkHeader = (config, routePaths) => {
72
- const deployBase = normalizeBasePath(config.deployment.base);
73
- const links = [];
74
- if (hasApiCatalog(config)) {
75
- links.push(`<${deployBase}${API_CATALOG_PATH}>; rel="api-catalog"; type="application/linkset+json"`);
76
- }
77
- if (config.ai.api) {
78
- links.push(`<${deployBase}${OPENAPI_PATH}>; rel="service-desc"; type="application/json"`);
47
+ var importSpecifier = (path, fromDir) => {
48
+ if (fromDir === undefined || !isAbsolute(path)) {
49
+ return path;
79
50
  }
80
- if (config.seo.agentReadability) {
81
- links.push(`<${deployBase}/agent-readability.json>; rel="describedby"; type="application/json"`);
51
+ const specifier = relative(fromDir, path);
52
+ if (isAbsolute(specifier) || specifier.startsWith("../")) {
53
+ return specifier;
82
54
  }
83
- if (config.ai.llmsTxt.enabled) {
84
- links.push(`<${deployBase}/llms.txt>; rel="describedby"; type="text/plain"`);
85
- }
86
- if (routePaths.includes("/")) {
87
- links.push(`<${deployBase}/index.md>; rel="alternate"; type="text/markdown"`);
88
- }
89
- return links.length > 0 ? links.join(", ") : null;
55
+ return `./${specifier}`;
90
56
  };
91
-
92
- // src/deploy/redirects.ts
93
- var applyBaseToAstroRedirects = (redirects, basePath, deployBase) => {
94
- const base = normalizeBasePath(deployBase);
95
- return basePath || base ? redirects.map((redirect) => ({
96
- ...redirect,
97
- from: withBasePath(basePath, redirect.from),
98
- to: withComposedBasePath(base, basePath, redirect.to)
99
- })) : redirects;
100
- };
101
- var applyBaseToPlatformRedirects = (redirects, basePath, deployBase) => {
102
- const base = normalizeBasePath(deployBase);
103
- return basePath || base ? redirects.map((redirect) => ({
104
- ...redirect,
105
- from: withComposedBasePath(base, basePath, redirect.from),
106
- to: withComposedBasePath(base, basePath, redirect.to)
107
- })) : redirects;
108
- };
109
- var platformRedirects = (config) => applyBaseToPlatformRedirects(config.redirects, config.basePath, config.deployment.base ?? "");
110
-
111
- // src/ai/ask.ts
112
- var OPENAI_COMPATIBLE = "openai-compatible";
113
- var OPENAI_COMPATIBLE_DEP = "@ai-sdk/openai-compatible";
114
- var ASK_PRESETS = {
115
- inkeep: {
116
- apiKeyEnv: "INKEEP_API_KEY",
117
- baseUrl: "https://api.inkeep.com/v1",
118
- kind: OPENAI_COMPATIBLE,
119
- name: "inkeep",
120
- runtimeDep: OPENAI_COMPATIBLE_DEP
121
- },
122
- llmgateway: {
123
- apiKeyEnv: "LLMGATEWAY_API_KEY",
124
- baseUrl: "https://api.llmgateway.io/v1",
125
- kind: OPENAI_COMPATIBLE,
126
- name: "llmgateway",
127
- runtimeDep: OPENAI_COMPATIBLE_DEP
128
- },
129
- openrouter: {
130
- apiKeyEnv: "OPENROUTER_API_KEY",
131
- kind: "openrouter",
132
- name: "openrouter",
133
- runtimeDep: "@openrouter/ai-sdk-provider"
134
- }
135
- };
136
- var DEFAULT_MODEL = "openai/gpt-5.5";
137
- var askHeadersField = (ask) => ask?.headers && Object.keys(ask.headers).length > 0 ? { headers: ask.headers } : {};
138
- var resolveAskBackend = (ask) => {
139
- const provider = ask?.provider ?? "gateway";
140
- const model = ask?.model ?? DEFAULT_MODEL;
141
- const headers = askHeadersField(ask);
142
- if (provider === "gateway") {
143
- return { ...headers, kind: "gateway", model };
144
- }
145
- const preset = ASK_PRESETS[provider];
146
- const apiKeyEnv = ask?.apiKeyEnv ?? preset?.apiKeyEnv ?? "API_KEY";
147
- if (provider === "openrouter") {
148
- return { apiKeyEnv, ...headers, kind: "openrouter", model };
149
- }
150
- return {
151
- apiKeyEnv,
152
- baseUrl: ask?.baseUrl ?? preset?.baseUrl ?? "",
153
- ...headers,
154
- kind: OPENAI_COMPATIBLE,
155
- model,
156
- 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;
157
108
  };
158
- };
159
- var askBackendRuntimeDep = (ask) => {
160
- const provider = ask?.provider ?? "gateway";
161
- if (provider === "gateway") {
162
- return;
163
- }
164
- 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 };
165
119
  };
166
120
 
167
121
  // src/astro/runtime-modules.ts
@@ -214,9 +168,9 @@ var publishRuntimeModules = (modules) => {
214
168
  };
215
169
 
216
170
  // src/astro/templates.ts
217
- import { existsSync as existsSync2, readFileSync } from "node:fs";
171
+ import { existsSync, readFileSync } from "node:fs";
218
172
  import { pathToFileURL } from "node:url";
219
- 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";
220
174
  var WORKSPACE_MARKERS = [
221
175
  ".git",
222
176
  "bun.lock",
@@ -227,7 +181,7 @@ var WORKSPACE_MARKERS = [
227
181
  "yarn.lock"
228
182
  ];
229
183
  var hasWorkspacesField = (pkgPath) => {
230
- if (!existsSync2(pkgPath)) {
184
+ if (!existsSync(pkgPath)) {
231
185
  return false;
232
186
  }
233
187
  try {
@@ -237,51 +191,42 @@ var hasWorkspacesField = (pkgPath) => {
237
191
  return false;
238
192
  }
239
193
  };
240
- 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)));
241
195
  var findWorkspaceRoot = (start) => {
242
196
  let dir = start;
243
197
  for (;; ) {
244
198
  if (hasWorkspaceMarker(dir)) {
245
199
  return dir;
246
200
  }
247
- const parent = dirname2(dir);
201
+ const parent = dirname(dir);
248
202
  if (parent === dir) {
249
203
  return start;
250
204
  }
251
205
  dir = parent;
252
206
  }
253
207
  };
254
- var ADAPTER_IMPORTS = {
255
- cloudflare: "@astrojs/cloudflare",
256
- netlify: "@astrojs/netlify",
257
- node: "@astrojs/node",
258
- vercel: "@astrojs/vercel"
259
- };
260
- var ADAPTER_OPTIONS = new Map([
261
- ["node", '{ mode: "standalone" }']
262
- ]);
263
- var WRANGLER_CONFIG_FILES = [
264
- "wrangler.jsonc",
265
- "wrangler.json",
266
- "wrangler.toml"
267
- ];
268
- var resolveCloudflareAdapterArgs = (context) => {
269
- const args = [
270
- 'prerenderEnvironment: "node"',
271
- 'imageService: "compile"'
272
- ];
273
- const wranglerPath = WRANGLER_CONFIG_FILES.map((file) => join2(context.root, file)).find((file) => existsSync2(file));
274
- if (wranglerPath) {
275
- let configPath = relative(context.outDir, wranglerPath);
276
- if (!configPath.startsWith(".") && !configPath.startsWith("/")) {
277
- configPath = `./${configPath}`;
278
- }
279
- 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: "" };
280
212
  }
281
- 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
+ };
282
229
  };
283
- var resolveSessionOption = (deployment) => deployment.output === "server" && deployment.adapter === "cloudflare" ? `
284
- session: false,` : "";
285
230
  var astroFontWeights = (weights) => JSON.stringify(weights).replaceAll(/(?<min>\d+)\.\.(?<max>\d+)/gu, "$<min> $<max>");
286
231
  var astroConfigImportLine = (options) => {
287
232
  const names = ["defineConfig"];
@@ -302,23 +247,18 @@ var runtimeDependencies = (options) => {
302
247
  if (needsSvelte) {
303
248
  deps.push("@astrojs/svelte");
304
249
  }
305
- if (hasScalarReferences(config)) {
306
- deps.push("@scalar/astro");
307
- }
308
- deps.push(...searchProviderMeta(config.search.provider).runtimeDeps);
309
- if (config.ai.ask?.enabled && !config.ai.ask.endpoint) {
310
- const askDep = askBackendRuntimeDep(config.ai.ask);
311
- if (askDep) {
312
- 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
+ }
313
256
  }
314
257
  }
315
- const { deployment } = config;
316
- if (deployment.output === "server" && deployment.adapter) {
317
- const adapter = ADAPTER_IMPORTS[deployment.adapter];
318
- if (adapter) {
319
- deps.push(adapter);
320
- }
258
+ if (config.ai.ask?.enabled && !config.ai.ask.endpoint) {
259
+ deps.push(...config.ai.ask.provider.runtimeDeps);
321
260
  }
261
+ deps.push(...config.deployment.runtimeDeps);
322
262
  return deps;
323
263
  };
324
264
  var RENDER_EXTERNAL_DEPS = [
@@ -338,8 +278,6 @@ var RENDER_EXTERNAL_DEPS = [
338
278
  ];
339
279
  var renderUserAliases = (aliases) => Object.entries(aliases ?? {}).toSorted(([a], [b]) => b.length - a.length).map(([find, replacement]) => `
340
280
  ${JSON.stringify(find)}: ${JSON.stringify(replacement)},`).join("");
341
- var astroOutDir = (context) => context.distDir ?? `${context.root}/dist`;
342
- var adapterRoot = (context) => dirname2(astroOutDir(context));
343
281
  var REACT_EXCLUDE = String.raw`exclude: [/\/node_modules\/\.vite\//, /\/\.cache\/vite\//]`;
344
282
  var runtimeCacheOptions = (context, generatedModulesDir) => {
345
283
  if (generatedModulesDir !== undefined) {
@@ -393,6 +331,17 @@ var resolveOptimizeDeps = (options) => {
393
331
  ];
394
332
  return { optimizeDepsEntries, optimizeDepsInclude };
395
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
+ }`;
396
345
  var renderRuntimeModuleWiring = (generatedModulesDir) => {
397
346
  if (generatedModulesDir === undefined) {
398
347
  return {
@@ -402,7 +351,7 @@ var renderRuntimeModuleWiring = (generatedModulesDir) => {
402
351
  };
403
352
  }
404
353
  const aliasLines = [...RUNTIME_MODULE_FILES].map(([id, file]) => `
405
- ${JSON.stringify(id)}: ${JSON.stringify(`${generatedModulesDir}/${file}`)},`).join("");
354
+ ${JSON.stringify(id)}: ${configPath(`${generatedModulesDir}/${file}`, true)},`).join("");
406
355
  return { aliasLines, imports: [], pluginEntry: "" };
407
356
  };
408
357
  var blumeIntegrationOptions = (options) => options.ejected ? {
@@ -426,6 +375,7 @@ var astroConfigTemplate = (options) => {
426
375
  needsVue,
427
376
  searchClientPath
428
377
  } = options;
378
+ const ejected = generatedModulesDir !== undefined;
429
379
  const {
430
380
  aliasLines: runtimeModuleAliasLines,
431
381
  imports: runtimeModuleImports,
@@ -433,7 +383,6 @@ var astroConfigTemplate = (options) => {
433
383
  } = renderRuntimeModuleWiring(generatedModulesDir);
434
384
  const { deployment } = config;
435
385
  const userAliasLines = renderUserAliases(options.aliases);
436
- const server = deployment.output === "server";
437
386
  const fsAllow = [...new Set([findWorkspaceRoot(context.root), context.root])];
438
387
  const { optimizeDepsEntries, optimizeDepsInclude } = resolveOptimizeDeps({
439
388
  aliases: options.aliases,
@@ -442,25 +391,15 @@ var astroConfigTemplate = (options) => {
442
391
  needsReact,
443
392
  reactCompilerPath: options.reactCompilerPath
444
393
  });
445
- const adapterImport = server && deployment.adapter ? `import adapter from "${ADAPTER_IMPORTS[deployment.adapter]}";
446
- ` : "";
447
- const adapterArgs = (() => {
448
- if (!server || !deployment.adapter) {
449
- return "";
450
- }
451
- if (deployment.adapter === "cloudflare") {
452
- return resolveCloudflareAdapterArgs(context);
453
- }
454
- return ADAPTER_OPTIONS.get(deployment.adapter) ?? "";
455
- })();
456
- const adapterExpr = deployment.adapter === "vercel" ? `withAdapterRoot(adapter(${adapterArgs}), ${JSON.stringify(adapterRoot(context))})` : `adapter(${adapterArgs})`;
457
- const adapterOption = server && deployment.adapter ? `
458
- adapter: ${adapterExpr},` : "";
459
- const sessionOption = resolveSessionOption(deployment);
460
- const siteOption = deployment.site ? `
461
- site: ${JSON.stringify(deployment.site)},` : "";
462
- const baseOption = deployment.base ? `
463
- 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)},` : "";
464
403
  const imageOption = renderImageOption(config);
465
404
  const i18nOption = config.i18n ? `
466
405
  i18n: ${JSON.stringify({
@@ -470,7 +409,7 @@ var astroConfigTemplate = (options) => {
470
409
  prefixDefaultLocale: !config.i18n.hideDefaultLocalePrefix
471
410
  }
472
411
  })},` : "";
473
- const basedRedirects = applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.base ?? "");
412
+ const basedRedirects = applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.options.base ?? "");
474
413
  const redirectsOption = basedRedirects.length > 0 ? `
475
414
  redirects: ${JSON.stringify(Object.fromEntries(basedRedirects.map((redirect) => [
476
415
  redirect.from,
@@ -489,7 +428,7 @@ var astroConfigTemplate = (options) => {
489
428
  return {
490
429
  ...face,
491
430
  src: [
492
- isAbsolute(variant.src) ? variant.src : join2(context.root, variant.src)
431
+ isAbsolute2(variant.src) ? variant.src : join2(context.root, variant.src)
493
432
  ]
494
433
  };
495
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(", ")}],` : "";
@@ -512,15 +451,18 @@ var astroConfigTemplate = (options) => {
512
451
  const blumeImport = `import { ${blumeImports.join(", ")} } from "blume/astro";
513
452
  `;
514
453
  const twoslashTransformer = "blumeTwoslashTransformer(), ";
515
- 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)} }`;
516
464
  const integrations = [
517
- `mdx({ processor: blumeMdxProcessor(${JSON.stringify({
518
- basePath: config.basePath,
519
- codeThemes: config.markdown.codeBlocks.theme,
520
- contentRoot: options.contentRoot,
521
- deployBase,
522
- headingAnchors: config.markdown.headingAnchors
523
- })}) })`
465
+ `mdx({ processor: blumeMdxProcessor(${processorOptions}) })`
524
466
  ];
525
467
  if (needsReact) {
526
468
  integrations.push(reactIntegration(options.reactCompilerPath));
@@ -534,7 +476,7 @@ var astroConfigTemplate = (options) => {
534
476
  integrations.push(`blumeIntegration(${JSON.stringify(blumeIntegrationOptions({
535
477
  config,
536
478
  contentRoutes,
537
- ejected: generatedModulesDir !== undefined,
479
+ ejected,
538
480
  pages
539
481
  }))})`);
540
482
  const {
@@ -543,9 +485,11 @@ var astroConfigTemplate = (options) => {
543
485
  userConfigSetup,
544
486
  userIntegrationSpread
545
487
  } = renderIntegrationBridge(options.integrationBridge);
546
- 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)}
547
491
  ${configSourceMarker}${userConfigImports}import { availableParallelism } from "node:os";
548
- ${defineConfigImport}
492
+ ${fileUrlImport}${defineConfigImport}
549
493
  import mdx from "@astrojs/mdx";
550
494
  import tailwindcss from "@tailwindcss/vite";
551
495
  import { blumeMarkdownProcessor, blumeMdxProcessor, blumeShikiTransformers, blumeTwoslashTransformer } from "blume/markdown";
@@ -553,22 +497,16 @@ ${reactImport}${vueImport}${svelteImport}${blumeImport}${adapterImport}
553
497
  ${userConfigSetup}export default defineConfig({
554
498
  root: ${JSON.stringify(context.outDir)},
555
499
  srcDir: ${JSON.stringify(`${context.outDir}/src`)},
556
- outDir: ${JSON.stringify(astroOutDir(context))},
500
+ outDir: ${JSON.stringify(distDir(context))},
557
501
  publicDir: ${JSON.stringify(`${context.root}/public`)},${cacheOptions}
558
- 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}
559
503
  integrations: [${integrations.join(", ")}${userIntegrationSpread}],
560
504
  markdown: {
561
- processor: blumeMarkdownProcessor(${JSON.stringify({
562
- basePath: config.basePath,
563
- codeThemes: config.markdown.codeBlocks.theme,
564
- contentRoot: options.contentRoot,
565
- deployBase,
566
- headingAnchors: config.markdown.headingAnchors
567
- })}),
505
+ processor: blumeMarkdownProcessor(${processorOptions}),
568
506
  shikiConfig: {
569
507
  themes: {
570
- light: ${JSON.stringify(config.markdown.codeBlocks.theme.light)},
571
- 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)},
572
510
  },
573
511
  defaultColor: false,
574
512
  transformers: [${twoslashTransformer}...blumeShikiTransformers(${JSON.stringify({ icons: config.markdown.code.icons })})],
@@ -595,7 +533,12 @@ ${userConfigSetup}export default defineConfig({
595
533
  // the overlap only adds memory.
596
534
  build: { concurrency: Math.min(8, availableParallelism()) },
597
535
  vite: {${viteCacheOption}
598
- 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
+ },
599
542
  // Everything hydration can reach must be part of the dev dep optimizer's
600
543
  // FIRST run. The Vite root is the generated runtime, so user pages,
601
544
  // islands, and aliased components live outside it and are only crawled
@@ -641,12 +584,12 @@ ${userConfigSetup}export default defineConfig({
641
584
  },
642
585
  resolve: {
643
586
  alias: {
644
- "blume:ask": ${JSON.stringify(askPath)},
645
- "blume:examples": ${JSON.stringify(examplesPath)},
646
- "blume:examples-theme": ${JSON.stringify(examplesThemePath)},
647
- "blume:features": ${JSON.stringify(featuresPath)},
648
- "blume:search-client": ${JSON.stringify(searchClientPath)},
649
- "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}
650
593
  },
651
594
  },
652
595
  server: {
@@ -660,16 +603,17 @@ ${userConfigSetup}export default defineConfig({
660
603
  };
661
604
  var stagedContentDir = (outDir) => join2(outDir, "content");
662
605
  var runtimeDirWithin = (base, outDir) => {
663
- const rel = relative(base, outDir);
664
- return rel && !rel.startsWith("..") && !isAbsolute(rel) ? rel : null;
606
+ const rel = relative2(base, outDir);
607
+ return rel && !rel.startsWith("..") && !isAbsolute2(rel) ? rel : null;
665
608
  };
666
- var astroGlobBase = (base) => isAbsolute(base) ? pathToFileURL(base).href : base;
609
+ var astroGlobBase = (base) => isAbsolute2(base) ? pathToFileURL(base).href : base;
667
610
  var contentConfigTemplate = (options) => {
668
611
  const { context, config } = options;
669
612
  const stagedBase = options.stagedBase ?? stagedContentDir(context.outDir);
670
- const collectionBase = options.collection?.base ?? context.contentRoot;
671
- const includeGlobs = options.collection?.include ?? config.content.include;
672
- 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;
673
617
  const outDirRel = runtimeDirWithin(collectionBase, context.outDir);
674
618
  const outDirIgnore = outDirRel ? [`!${outDirRel}/**`] : [];
675
619
  const filesystem = options.filesystem ?? true;
@@ -728,47 +672,20 @@ export const OPTIONS: APIRoute = ({ request }) =>
728
672
  preflightResponse(request, ALLOWED_ORIGINS);
729
673
  `
730
674
  } : { close: "};", imports: [], open: "async ({ request }) => {", setup: "" };
731
- var askEndpointTemplate = (backend, grounded, options) => {
732
- 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;
733
679
  const fallbackPrompt = instructions ? `${ASK_FALLBACK_PROMPT}
734
680
 
735
681
  ${instructions}` : ASK_FALLBACK_PROMPT;
736
682
  const imports = [
737
683
  'import type { APIRoute } from "astro";',
738
684
  'import { getSecret } from "astro:env/server";',
739
- 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
740
687
  ];
741
- let setup = "";
742
- let modelExpr = JSON.stringify(backend.model);
743
- const headersField = backend.headers ? `
744
- headers: ${JSON.stringify(backend.headers)},` : "";
745
- if (backend.kind === "gateway") {
746
- setup = `
747
- const gateway = createGateway({
748
- apiKey: getSecret("AI_GATEWAY_API_KEY"),${headersField}
749
- });
750
- `;
751
- modelExpr = `gateway(${JSON.stringify(backend.model)})`;
752
- } else if (backend.kind === "openrouter") {
753
- imports.push('import { createOpenRouter } from "@openrouter/ai-sdk-provider";');
754
- setup = `
755
- const openrouter = createOpenRouter({
756
- apiKey: getSecret(${JSON.stringify(backend.apiKeyEnv)}),${headersField}
757
- });
758
- `;
759
- const settings = reasoning ? `, { reasoning: { effort: ${JSON.stringify(reasoning)} } }` : "";
760
- modelExpr = `openrouter(${JSON.stringify(backend.model)}${settings})`;
761
- } else if (backend.kind === "openai-compatible") {
762
- imports.push('import { createOpenAICompatible } from "@ai-sdk/openai-compatible";');
763
- setup = `
764
- const provider = createOpenAICompatible({
765
- apiKey: getSecret(${JSON.stringify(backend.apiKeyEnv)}),
766
- baseURL: ${JSON.stringify(backend.baseUrl)},${headersField}
767
- name: ${JSON.stringify(backend.name)},
768
- });
769
- `;
770
- modelExpr = `provider(${JSON.stringify(backend.model)})`;
771
- }
688
+ let { setup } = backend.template;
772
689
  if (grounded) {
773
690
  imports.push('import { createAskContext } from "blume/ai/ask-context.ts";', 'import askData from "blume:ask-data";');
774
691
  const groundFields = [];
@@ -785,7 +702,18 @@ const ground = createAskContext(askData${groundOptions});
785
702
  }
786
703
  const cors = askCorsTemplate(options?.cors);
787
704
  imports.push(...cors.imports);
788
- 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
+ }
789
717
  const raw = body?.messages;
790
718
  const valid =
791
719
  Array.isArray(raw) &&
@@ -810,30 +738,17 @@ const ground = createAskContext(askData${groundOptions});
810
738
  content: m.content,
811
739
  role: m.role,
812
740
  }));`;
813
- const keyCheck = backend.kind === "gateway" ? ` // The AI Gateway authenticates with an API key or Vercel's OIDC token.
814
- if (!(getSecret("AI_GATEWAY_API_KEY") || getSecret("VERCEL_OIDC_TOKEN"))) {
815
- return new Response(
816
- "Ask AI is not configured: set AI_GATEWAY_API_KEY (or deploy on Vercel with OIDC).",
817
- { status: 500 }
818
- );
819
- }` : ` if (!getSecret(${JSON.stringify(backend.apiKeyEnv)})) {
820
- return new Response(
821
- ${JSON.stringify(`Ask AI is not configured: set ${backend.apiKeyEnv}.`)},
822
- { status: 500 }
823
- );
824
- }`;
741
+ const { keyCheck } = backend.template;
825
742
  const onError = ` onError({ error }) {
826
743
  console.error("Ask AI provider error:", error);
827
744
  },`;
828
745
  const streamFields = [
829
- `model: ${modelExpr}`,
746
+ `model: ${backend.template.model}`,
830
747
  grounded ? "instructions" : `instructions:
831
748
  ${JSON.stringify(fallbackPrompt)}`,
832
- "messages"
749
+ "messages",
750
+ ...backend.template.fields
833
751
  ];
834
- if (reasoning && backend.kind !== "openrouter") {
835
- streamFields.push(`reasoning: ${JSON.stringify(reasoning)}`);
836
- }
837
752
  const call = ` const result = streamText({
838
753
  ${streamFields.join(`,
839
754
  `)},
@@ -848,7 +763,9 @@ ${validate}
848
763
  ${keyCheck}
849
764
  try {
850
765
  ${stream}
851
- return result.toTextStreamResponse();
766
+ return createTextStreamResponse({
767
+ stream: toTextStream({ stream: result.stream }),
768
+ });
852
769
  } catch {
853
770
  return new Response("Failed to generate a response.", { status: 500 });
854
771
  }
@@ -904,31 +821,9 @@ const indexUrl = joinBase(import.meta.env.BASE_URL, "blume-search.json");
904
821
 
905
822
  export const createSearch = () => create({ indexUrl${locale ? `, locale: ${JSON.stringify(locale)}` : ""} });
906
823
  `;
907
- var hostedSearchClient = (module, options) => `${SEARCH_CLIENT_HEADER}${searchClientImport(module)}
908
- 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)});
909
826
  `;
910
- var hostedSearchOptions = (search) => {
911
- switch (search.provider) {
912
- case "algolia": {
913
- return { module: "algolia", options: { ...search.algolia } };
914
- }
915
- case "orama-cloud": {
916
- return {
917
- module: "orama-cloud",
918
- options: {
919
- apiKey: search.oramaCloud?.apiKey,
920
- endpoint: search.oramaCloud?.endpoint
921
- }
922
- };
923
- }
924
- case "typesense": {
925
- return { module: "typesense", options: { ...search.typesense } };
926
- }
927
- default: {
928
- return null;
929
- }
930
- }
931
- };
932
827
  var featuresTemplate = (features) => `// Generated by Blume. Do not edit.
933
828
  //
934
829
  // The client features this site uses. A feature no page needs stays out of
@@ -944,61 +839,86 @@ export const loadEpub:
944
839
  | null = ${features.epub ? '() => import("epub-gen-memory/bundle")' : "null"};
945
840
  `;
946
841
  var searchClientTemplate = (config) => {
947
- const { search } = config;
948
- if (search.provider === "orama" || search.provider === "flexsearch") {
949
- const locale = search.provider === "orama" ? config.i18n?.defaultLocale : undefined;
950
- return staticSearchClient(search.provider, locale);
951
- }
952
- const hosted = hostedSearchOptions(search);
953
- if (hosted) {
954
- return hostedSearchClient(hosted.module, hosted.options);
955
- }
956
- if (search.provider === "mixedbread") {
957
- 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}
958
853
  const api = joinBase(import.meta.env.BASE_URL, "api/search");
959
854
 
960
855
  export const createSearch = () => create({ api });
961
856
  `;
962
- }
963
- if (search.provider === "pagefind") {
964
- return `${SEARCH_CLIENT_HEADER}${searchClientImport("pagefind")}${SEARCH_BASE_IMPORT}
857
+ }
858
+ case "pagefind": {
859
+ return `${SEARCH_CLIENT_HEADER}${searchClientImport("pagefind")}${SEARCH_BASE_IMPORT}
965
860
  const url = joinBase(import.meta.env.BASE_URL, "pagefind/pagefind.js");
966
861
 
967
862
  export const createSearch = () => create({ url });
968
863
  `;
969
- }
970
- return `${SEARCH_CLIENT_HEADER}export const createSearch = () => () =>
864
+ }
865
+ default: {
866
+ return `${SEARCH_CLIENT_HEADER}export const createSearch = () => () =>
971
867
  Promise.resolve({ hits: [], sections: [] });
972
868
  `;
869
+ }
870
+ }
973
871
  };
974
- var mixedbreadSearchEndpointTemplate = (storeId) => `// Generated by Blume. Do not edit.
872
+ var mixedbreadSearchEndpointTemplate = (options) => `// Generated by Blume. Do not edit.
975
873
  import type { APIRoute } from "astro";
976
874
  import { getSecret } from "astro:env/server";
977
875
  import Mixedbread from "@mixedbread/sdk";
876
+ import { readCappedText } from "blume/core/request-body.ts";
978
877
 
979
878
  export const prerender = false;
980
879
 
981
880
  const client = new Mixedbread({ apiKey: getSecret("MIXEDBREAD_API_KEY") ?? "" });
982
- 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;
983
884
 
984
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
+ }
985
894
  // The endpoint is public: a malformed body must 200-empty, not 500.
986
- const body = await request.json().catch(() => null);
895
+ let body = null;
896
+ try {
897
+ body = JSON.parse(text);
898
+ } catch {
899
+ body = null;
900
+ }
987
901
  const query = body?.query;
988
902
  if (!query || typeof query !== "string") {
989
903
  return new Response("[]", {
990
904
  headers: { "Content-Type": "application/json" },
991
905
  });
992
906
  }
907
+ // \`top_k\` defaults to 8 unless an option sets it; the query and store
908
+ // always come from the request and \`storeId\`.
993
909
  const response = await client.stores.search({
910
+ top_k: 8,
911
+ ...SEARCH_OPTIONS,
994
912
  query,
995
913
  store_identifiers: [STORE_ID],
996
- top_k: 8,
997
914
  });
998
915
  const hits = (response.data ?? []).map((chunk) => {
999
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;
1000
920
  return {
1001
- excerpt: chunk.text ?? meta.excerpt ?? "",
921
+ excerpt: text ?? meta.excerpt ?? "",
1002
922
  title: meta.title ?? chunk.filename ?? "",
1003
923
  url: meta.url ?? "",
1004
924
  };
@@ -1114,9 +1034,15 @@ export const GET: APIRoute = async ({ params }) => {
1114
1034
  return new Response(null, { status: 404 });
1115
1035
  }
1116
1036
  const body = await readFile(path);
1117
- return new Response(new Uint8Array(body), {
1118
- headers: { "Content-Type": contentType(path) },
1119
- });
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 });
1120
1046
  };
1121
1047
  `;
1122
1048
  var mcpPageFile = (route) => `${trimChar(route, "/")}.ts`;
@@ -1193,7 +1119,9 @@ export function getStaticPaths() {
1193
1119
  return navVariants(data, hiddenDefaultLocale(data.config.i18n)).flatMap(
1194
1120
  ({ locale, navigation, version }) =>
1195
1121
  [...navGroupIds(navigation.sidebar)]
1196
- .filter(([node]) => (node.display ?? "flat") !== "flat")
1122
+ .filter(
1123
+ ([node]) => node.kind === "group" && (node.display ?? "flat") !== "flat"
1124
+ )
1197
1125
  .map(([, id]) => ({ params: { id, locale, version } }))
1198
1126
  );
1199
1127
  }
@@ -1412,8 +1340,7 @@ import LocaleLinks from "blume/components/layout/LocaleLinks.astro";
1412
1340
  import ApiOverview from "blume/components/openapi/ApiOverview.astro";
1413
1341
  import ApiTagOperations from "blume/components/openapi/ApiTagOperations.astro";
1414
1342
  import Operation from "blume/components/openapi/Operation.astro";
1415
- ${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../generated/components.ts";
1416
- import { islandComponents } from "../generated/islands.ts";`,
1343
+ ${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../generated/components.ts";`,
1417
1344
  map: `{
1418
1345
  Accordion,
1419
1346
  AccordionItem,
@@ -1449,8 +1376,7 @@ import { islandComponents } from "../generated/islands.ts";`,
1449
1376
  TypeTable,
1450
1377
  Visibility,
1451
1378
  YouTube,
1452
- ${mathEntry}...islandComponents,
1453
- ...userMdx,
1379
+ ${mathEntry}...userMdx,
1454
1380
  }`
1455
1381
  };
1456
1382
  };
@@ -1492,6 +1418,7 @@ export function getStaticPaths() {
1492
1418
  indexable: route.indexable,
1493
1419
  lastModified: route.lastModified,
1494
1420
  locale: route.locale,
1421
+ monolingual: route.monolingual,
1495
1422
  route: route.path,
1496
1423
  title: route.title,
1497
1424
  version: route.version,
@@ -1500,7 +1427,7 @@ export function getStaticPaths() {
1500
1427
  }));
1501
1428
  }
1502
1429
 
1503
- 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;
1504
1431
  const entry = await getEntry(collection as CollectionKey, entryId);
1505
1432
  if (!entry) {
1506
1433
  return new Response(null, { status: 404 });
@@ -1592,13 +1519,32 @@ const contentDir = i18n
1592
1519
  // hreflang URLs byte-match the sitemap's <loc> for the home page.
1593
1520
  const absolute = (path: string) => base + withBase(path);
1594
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;
1595
1539
  // An archived page defaults its canonical to the same page in the latest docs
1596
1540
  // when that page still exists — search engines treat the live page as
1597
1541
  // authoritative without deindexing version-only content. A page's own
1598
1542
  // \`seo.canonical\` always wins, and \`canonical: "self"\` keeps the default.
1599
1543
  const canonical =
1600
1544
  seo.canonical ??
1601
- (archived && archived.canonical === "latest" && latestVersionAlt && base
1545
+ (fallbackTarget && base
1546
+ ? absolute(fallbackTarget.path)
1547
+ : archived && archived.canonical === "latest" && latestVersionAlt && base
1602
1548
  ? absolute(latestVersionAlt.path)
1603
1549
  : base
1604
1550
  ? \`\${base}\${basedRoute === "/" ? "/" : encodeURI(basedRoute)}\`
@@ -1628,7 +1574,9 @@ const mountLocalized = (logical: string, codeArg: string) =>
1628
1574
  const logicalRoute = i18n
1629
1575
  ? stripLocale(stripBasePath(data.config.basePath, route), locale)
1630
1576
  : route;
1631
- 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
1632
1580
  ? i18n.locales.map((l) => {
1633
1581
  const alt = (alternates ?? []).find((x) => x.locale === l.code);
1634
1582
  return {
@@ -1725,6 +1673,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
1725
1673
  locale={htmlLang}
1726
1674
  dir={dir}
1727
1675
  contentDir={contentDir}
1676
+ contentLocale={contentLocale}
1728
1677
  ui={ui}
1729
1678
  localeAlternates={localeAlternates}
1730
1679
  xDefault={xDefault}
@@ -1772,38 +1721,28 @@ var changelogIndexTemplate = (options) => {
1772
1721
  clientData={{ config: data.config, navigation: data.navigation, page: { route: "/changelog", title: pageTitle } }}` : "";
1773
1722
  const stagedSpread = options.staged ? `
1774
1723
  ...(await getCollection("staged")),` : "";
1775
- const { imports: componentImports, map: componentMap } = contentComponentsSource(options.mathEnabled);
1776
1724
  return `---
1777
1725
  // Generated by Blume. Do not edit.
1778
- import { getCollection, render } from "astro:content";
1726
+ import { getCollection } from "astro:content";
1779
1727
  import RootLayout from "blume/components/layout/RootLayout.astro";
1780
- import Update from "blume/components/content/Update.astro";
1781
1728
  import { withBase } from "blume/components/islands/base-path.ts";
1782
1729
  import { resolveSlot } from "blume/components/layout/overrides.ts";
1783
1730
  import { resolveDateFormatOptions } from "blume/core/date-format.ts";
1784
- ${componentImports}
1731
+ import { layoutOverrides } from "../generated/components.ts";
1785
1732
  import data from "blume:data";
1786
1733
 
1787
- const Color = Object.assign(ColorRoot, { Item: ColorItem, Row: ColorRow });
1788
- const Tree = Object.assign(TreeRoot, { File: TreeFile, Folder: TreeFolder });
1789
-
1790
1734
  export const prerender = true;
1791
1735
 
1792
- // Entry bodies are MDX rendered outside the catch-all, so they need the same
1793
- // component map: a \`:::\` callout or \`<Steps>\` in a release note otherwise
1794
- // throws "Expected component ... to be defined" at build time.
1795
- const components = ${componentMap};
1796
-
1797
1736
  const entryDate = (entry: {
1798
1737
  data: { date?: string | null; changelog?: { date?: string | null } | null };
1799
1738
  }) => entry.data.date ?? entry.data.changelog?.date ?? null;
1800
1739
 
1801
- const toTime = (value: string | null | undefined) => {
1740
+ const parseDate = (value: string | null | undefined) => {
1802
1741
  if (!value) {
1803
- return 0;
1742
+ return null;
1804
1743
  }
1805
1744
  const date = new Date(value);
1806
- return Number.isNaN(date.getTime()) ? 0 : date.getTime();
1745
+ return Number.isNaN(date.getTime()) ? null : date;
1807
1746
  };
1808
1747
 
1809
1748
  // The changelog is an unlocalized route, so its chrome renders in the default
@@ -1818,34 +1757,45 @@ const htmlLang = i18n ? i18n.defaultLocale : "en";
1818
1757
 
1819
1758
  // Formatted in the same locale as the chrome, and with the configured
1820
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.
1821
1762
  const dateFormatOptions = resolveDateFormatOptions(data.config.dateFormat);
1822
- const formatDate = (value: string | null | undefined) => {
1823
- if (!value) {
1824
- return;
1825
- }
1826
- const date = new Date(value);
1827
- return Number.isNaN(date.getTime())
1828
- ? undefined
1829
- : new Intl.DateTimeFormat(htmlLang, dateFormatOptions).format(date);
1830
- };
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);
1831
1778
 
1832
1779
  const slugify = (text: string) =>
1833
1780
  text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") ||
1834
1781
  "update";
1835
1782
 
1836
- // The major of a version's embedded semver (\`1.2.3\` -> 1, \`pkg@2.0.0\` -> 2), or
1837
- // null when there is no full major.minor.patch to key on. Drives the changelog's
1838
- // group-by-major pagination, so it tolerates the scoped tags monorepos publish.
1839
- const majorVersion = (version: string | null | undefined) => {
1840
- const match = /(\\d+)\\.\\d+\\.\\d+/.exec(String(version ?? ""));
1841
- return match ? Number(match[1]) : null;
1842
- };
1843
-
1844
- // Map each entry to its own generated page so the timeline heading can deep-link
1845
- // to it. The collection entry id matches the route manifest's \`entryId\`.
1846
- const routeByEntry = new Map(
1847
- data.routes.map((route) => [route.entryId, route.path])
1848
- );
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
+ }
1849
1799
 
1850
1800
  const changelogEntries = [
1851
1801
  ...(await getCollection("docs")),${stagedSpread}
@@ -1854,35 +1804,37 @@ const changelogEntries = [
1854
1804
  (entry) =>
1855
1805
  entry.data.type === "changelog" &&
1856
1806
  !entry.data.draft &&
1857
- !entry.data.sidebar?.hidden
1807
+ !entry.data.sidebar?.hidden &&
1808
+ (defaultLocale === null || routeByEntry.has(entry.id))
1858
1809
  )
1859
- .toSorted((a, b) => toTime(entryDate(b)) - toTime(entryDate(a)));
1860
-
1861
- const items = await Promise.all(
1862
- changelogEntries.map(async (entry) => {
1863
- const label =
1864
- entry.data.title ??
1865
- (entry.data.changelog?.version
1866
- ? "v" + entry.data.changelog.version
1867
- : "Update");
1868
- return {
1869
- Content: (await render(entry)).Content,
1870
- date: formatDate(entryDate(entry)),
1871
- href: routeByEntry.get(entry.id) ?? undefined,
1872
- id: slugify(label),
1873
- label,
1874
- major: majorVersion(entry.data.changelog?.version),
1875
- tags: entry.data.changelog?.category
1876
- ? [entry.data.changelog.category]
1877
- : [],
1878
- };
1879
- })
1880
- );
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
+ });
1881
1834
 
1882
1835
  // Repeated labels slug to the same id (e.g. two entries with neither a title
1883
1836
  // nor a version both falling back to "update"); suffix the later ones -2, -3,
1884
- // ... so every heading deep-links to its own entry. The first keeps the plain
1885
- // 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.
1886
1838
  const seenIds = new Set();
1887
1839
  for (const item of items) {
1888
1840
  let uniqueId = item.id;
@@ -1893,26 +1845,18 @@ for (const item of items) {
1893
1845
  item.id = uniqueId;
1894
1846
  }
1895
1847
 
1896
- // A changelog is semver-paginated only when every visible release parses as
1897
- // semver and they span more than one major line. Older majors then collapse
1898
- // into groups the reader reveals one at a time; otherwise the timeline is flat.
1899
- const majors = items.every((item) => item.major !== null)
1900
- ? [...new Set(items.map((item) => item.major))]
1901
- .filter((major): major is number => major !== null)
1902
- .toSorted((a, b) => b - a)
1903
- : [];
1904
- const paginate = majors.length > 1;
1905
- const majorGroups = majors.map((major) => ({
1906
- items: items.filter((item) => item.major === major),
1907
- label: major + ".x",
1908
- major,
1909
- }));
1910
-
1911
- const headings = items.map((item) => ({
1912
- depth: 2,
1913
- slug: item.id,
1914
- text: item.label,
1915
- }));
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
+ }
1916
1860
 
1917
1861
  const base = data.config.site ? data.config.site.replace(/\\/$/, "") : null;
1918
1862
  // The canonical URL carries the deployment base (the page is served under it),
@@ -1926,9 +1870,9 @@ const canonical = base ? base + basedRoute : null;
1926
1870
  const ogPath = data.config.og.enabled ? withBase("/og/changelog.png") : null;
1927
1871
  const ogImage = ogPath && base ? base + ogPath : ogPath;
1928
1872
 
1929
- // The page chrome (h1, title, description) comes from the same translatable
1930
- // \`changelog\` group as the reveal button; optional chaining tolerates a
1931
- // 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.
1932
1876
  const changelogTitle = data.ui.changelog?.title ?? "Changelog";
1933
1877
  const changelogDescription =
1934
1878
  data.ui.changelog?.description ??
@@ -1961,7 +1905,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
1961
1905
  description: changelogDescription,
1962
1906
  route: "/changelog",
1963
1907
  }}
1964
- headings={headings}
1908
+ headings={[]}
1965
1909
  toc={data.config.toc}
1966
1910
  contentLayout="bare"
1967
1911
  themeMode={data.config.theme.mode}
@@ -1982,56 +1926,52 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
1982
1926
  structuredDataEnabled={data.config.structuredData}
1983
1927
  >
1984
1928
  <h1>{changelogTitle}</h1>
1929
+ <p class="text-lg text-muted-foreground">{changelogDescription}</p>
1985
1930
  {
1986
1931
  items.length === 0 ? (
1987
1932
  <p>No changelog entries yet.</p>
1988
- ) : paginate ? (
1989
- <blume-changelog
1990
- class="not-prose mt-8 block"
1991
- data-i18n-more={data.ui.changelog?.showReleases}
1992
- >
1993
- {majorGroups[0].items.map(({ Content, href, id, label, date, tags }) => (
1994
- <Update description={date} href={href} id={id} label={label} tags={tags}>
1995
- <Content components={components} />
1996
- </Update>
1997
- ))}
1998
- {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) => (
1999
1936
  <section
2000
- aria-label={group.label + " releases"}
2001
- data-changelog-label={group.label}
2002
- 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"
2003
1939
  >
2004
- {group.items.map(({ Content, href, id, label, date, tags }) => (
2005
- <Update description={date} href={href} id={id} label={label} tags={tags}>
2006
- <Content components={components} />
2007
- </Update>
2008
- ))}
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>
2009
1970
  </section>
2010
1971
  ))}
2011
- <div class="mt-10 flex justify-center">
2012
- <button
2013
- 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"
2014
- data-changelog-more
2015
- hidden
2016
- type="button"
2017
- >
2018
- Show older releases
2019
- </button>
2020
- </div>
2021
- </blume-changelog>
2022
- ) : (
2023
- <div class="not-prose mt-8">
2024
- {items.map(({ Content, href, id, label, date, tags }) => (
2025
- <Update description={date} href={href} id={id} label={label} tags={tags}>
2026
- <Content components={components} />
2027
- </Update>
2028
- ))}
2029
1972
  </div>
2030
1973
  )
2031
1974
  }
2032
- <script>
2033
- import "blume/components/content/changelog-element.ts";
2034
- </script>
2035
1975
  </LayoutComponent>
2036
1976
  `;
2037
1977
  };
@@ -2059,7 +1999,7 @@ const htmlLang = i18n ? i18n.defaultLocale : "en";
2059
1999
  // Recovery links, so a reader — or an agent that followed a stale URL — can
2060
2000
  // get back on track without guessing: every top-level section, then the
2061
2001
  // machine-readable indexes the build emits (the sitemap only exists with a
2062
- // \`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
2063
2003
  // their resolved target when the section has no index page of its own.
2064
2004
  const suggestions = [
2065
2005
  ...data.navigation.tabs.map((tab) => ({
@@ -2073,6 +2013,31 @@ const suggestions = [
2073
2013
  ? [{ href: withBase("/llms.txt"), label: nf.llms }]
2074
2014
  : []),
2075
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");
2076
2041
  ---
2077
2042
 
2078
2043
  <PageLayout
@@ -2094,6 +2059,8 @@ const suggestions = [
2094
2059
  >
2095
2060
  <div
2096
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
2097
2064
  >
2098
2065
  <div class="flex flex-col items-start">
2099
2066
  <p
@@ -2103,24 +2070,26 @@ const suggestions = [
2103
2070
  </p>
2104
2071
  <h1
2105
2072
  class="mt-4 text-balance text-4xl font-semibold tracking-tight text-foreground sm:text-5xl"
2073
+ data-nf="title"
2106
2074
  >
2107
2075
  {nf.title}
2108
2076
  </h1>
2109
- <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">
2110
2078
  {nf.description}
2111
2079
  </p>
2112
2080
  <a
2113
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
2114
2083
  href={withBase("/")}
2115
2084
  >
2116
2085
  <Icon class="rtl:-scale-x-100" name="arrow-left" size={14} />
2117
- {nf.home}
2086
+ <span data-nf="home">{nf.home}</span>
2118
2087
  </a>
2119
2088
  </div>
2120
2089
  {
2121
2090
  suggestions.length > 0 && (
2122
- <nav aria-label={nf.suggestions} class="md:border-s md:border-border md:ps-12 lg:ps-16">
2123
- <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">
2124
2093
  {nf.suggestions}
2125
2094
  </h2>
2126
2095
  <ul class="mt-4 divide-y divide-border border-y border-border">
@@ -2144,6 +2113,37 @@ const suggestions = [
2144
2113
  )
2145
2114
  }
2146
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>
2147
2147
  </PageLayout>
2148
2148
  `;
2149
2149
  var notFoundMarkdownTemplate = () => `// Generated by Blume. Do not edit. Override by adding \`pages/404.astro\`.
@@ -2312,37 +2312,6 @@ const context = ${JSON.stringify(context)};
2312
2312
 
2313
2313
  export const ALL: APIRoute = ({ request }) => apiNotFoundResponse(request, context);
2314
2314
  `;
2315
- var islandDirective = (spec) => spec.client === "only" ? `client:only="${spec.framework}"` : `client:${spec.client}`;
2316
- var wrapperPropsType = (name) => `type Props = typeof ${name} extends (
2317
- props: infer P extends object,
2318
- ...rest: never[]
2319
- ) => unknown
2320
- ? P
2321
- : Record<string, unknown>;`;
2322
- var islandWrapperTemplate = (spec) => `---
2323
- // Generated by Blume. Do not edit.
2324
- import Island from ${JSON.stringify(spec.file)};
2325
- ${wrapperPropsType("Island")}
2326
- ---
2327
- <Island ${islandDirective(spec)} {...Astro.props}><slot /></Island>
2328
- `;
2329
- var islandMapTemplate = (specs) => {
2330
- if (specs.length === 0) {
2331
- return `// Generated by Blume. Do not edit.
2332
- export const islandComponents = {};
2333
- `;
2334
- }
2335
- const imports = specs.map((spec, index) => `import I${index} from "./islands/${spec.name}.astro";`).join(`
2336
- `);
2337
- const entries = specs.map((spec, index) => ` ${spec.name}: I${index},`).join(`
2338
- `);
2339
- return `// Generated by Blume. Do not edit.
2340
- ${imports}
2341
- export const islandComponents = {
2342
- ${entries}
2343
- };
2344
- `;
2345
- };
2346
2315
  var exampleDirective = (spec) => {
2347
2316
  if (spec.framework === "astro" || !spec.client) {
2348
2317
  return "";
@@ -2350,9 +2319,9 @@ var exampleDirective = (spec) => {
2350
2319
  return spec.client === "only" ? `client:only="${spec.framework}" ` : `client:${spec.client} `;
2351
2320
  };
2352
2321
  var exampleSlug = (path) => path.replaceAll(/[^a-zA-Z0-9]/gu, (char) => `_${(char.codePointAt(0) ?? 0).toString(16)}_`);
2353
- var exampleWrapperTemplate = (spec) => `---
2322
+ var exampleWrapperTemplate = (spec, fromDir) => `---
2354
2323
  // Generated by Blume. Do not edit.
2355
- import Example from ${JSON.stringify(spec.file)};
2324
+ import Example from ${JSON.stringify(importSpecifier(spec.file, fromDir))};
2356
2325
  ${wrapperPropsType("Example")}
2357
2326
  ---
2358
2327
  <Example ${exampleDirective(spec)}{...Astro.props}><slot /></Example>
@@ -2496,7 +2465,7 @@ var runtimeTsconfigTemplate = () => `${JSON.stringify({
2496
2465
  }, null, 2)}
2497
2466
  `;
2498
2467
 
2499
- 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 };
2500
2469
 
2501
- //# debugId=53365D3EDA449FFB64756E2164756E21
2502
- //# sourceMappingURL=chunk-ejjx8znq.js.map
2470
+ //# debugId=9E2BF1A2CC0BBFF264756E2164756E21
2471
+ //# sourceMappingURL=chunk-mnqj32sj.js.map