blume 2.0.2 → 2.1.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 (601) hide show
  1. package/AGENTS.md +1 -0
  2. package/CHANGELOG.md +113 -0
  3. package/README.md +1 -1
  4. package/dist/cli/{chunk-6k4ftwze.js → chunk-0gz36akr.js} +18 -2
  5. package/dist/cli/{chunk-6k4ftwze.js.map → chunk-0gz36akr.js.map} +3 -3
  6. package/dist/cli/{chunk-zp79m0ts.js → chunk-1n228xqb.js} +2 -2
  7. package/dist/cli/{chunk-ddndchfr.js → chunk-2f3ndkpw.js} +57 -29
  8. package/dist/cli/chunk-2f3ndkpw.js.map +14 -0
  9. package/dist/cli/{chunk-fsmrqk8a.js → chunk-2f7n4qzt.js} +8 -2
  10. package/dist/cli/{chunk-fsmrqk8a.js.map → chunk-2f7n4qzt.js.map} +3 -3
  11. package/dist/cli/{chunk-ppzjqwx2.js → chunk-2n4ps1b3.js} +17 -18
  12. package/dist/cli/{chunk-ppzjqwx2.js.map → chunk-2n4ps1b3.js.map} +3 -3
  13. package/dist/cli/{chunk-5r8g91qn.js → chunk-43zcf4gz.js} +398 -159
  14. package/dist/cli/chunk-43zcf4gz.js.map +36 -0
  15. package/dist/cli/chunk-4ejxbzee.js +39 -0
  16. package/dist/cli/chunk-4ejxbzee.js.map +10 -0
  17. package/dist/cli/{chunk-hr8ne106.js → chunk-4h8z9vv5.js} +296 -77
  18. package/dist/cli/chunk-4h8z9vv5.js.map +16 -0
  19. package/dist/cli/{chunk-k7pj68a8.js → chunk-5cg2rzgf.js} +18 -16
  20. package/dist/cli/{chunk-k7pj68a8.js.map → chunk-5cg2rzgf.js.map} +2 -2
  21. package/dist/cli/{chunk-h2ez8dzb.js → chunk-5ffywsmb.js} +4 -4
  22. package/dist/cli/{chunk-g698a744.js → chunk-5wj2qwn2.js} +5 -5
  23. package/dist/cli/chunk-6bm0xpgd.js +18 -0
  24. package/dist/cli/chunk-6bm0xpgd.js.map +10 -0
  25. package/dist/cli/{chunk-3yce002v.js → chunk-713mngdq.js} +15 -8
  26. package/dist/cli/chunk-713mngdq.js.map +14 -0
  27. package/dist/cli/{chunk-91ws1n6j.js → chunk-9geymqns.js} +17 -15
  28. package/dist/cli/{chunk-91ws1n6j.js.map → chunk-9geymqns.js.map} +2 -2
  29. package/dist/cli/{chunk-6dtt0zfn.js → chunk-9xr4dgee.js} +27 -18
  30. package/dist/cli/chunk-9xr4dgee.js.map +10 -0
  31. package/dist/cli/{chunk-sqw4ekg1.js → chunk-amrb6hgh.js} +2 -2
  32. package/dist/cli/chunk-cm89scdv.js +443 -0
  33. package/dist/cli/chunk-cm89scdv.js.map +11 -0
  34. package/dist/cli/{chunk-wdrt2k2v.js → chunk-cmtcnh9f.js} +90 -26
  35. package/dist/cli/chunk-cmtcnh9f.js.map +10 -0
  36. package/dist/cli/chunk-cy5bm0j0.js +104 -0
  37. package/dist/cli/chunk-cy5bm0j0.js.map +11 -0
  38. package/dist/cli/{chunk-7mbqtmgb.js → chunk-e7vvk5ya.js} +21 -12
  39. package/dist/cli/chunk-e7vvk5ya.js.map +10 -0
  40. package/dist/cli/{chunk-qkb5a8sa.js → chunk-g2z9x01v.js} +6 -98
  41. package/dist/cli/chunk-g2z9x01v.js.map +10 -0
  42. package/dist/cli/{chunk-273ygyr4.js → chunk-ga0pf4aj.js} +7 -7
  43. package/dist/cli/{chunk-273ygyr4.js.map → chunk-ga0pf4aj.js.map} +3 -3
  44. package/dist/cli/{chunk-h7k3nq3v.js → chunk-gp84za0h.js} +2 -2
  45. package/dist/cli/{chunk-hqp2ajnh.js → chunk-h2a48yhd.js} +195 -73
  46. package/dist/cli/chunk-h2a48yhd.js.map +36 -0
  47. package/dist/cli/{chunk-pbg5a4s3.js → chunk-jnwj5kjj.js} +71 -47
  48. package/dist/cli/chunk-jnwj5kjj.js.map +19 -0
  49. package/dist/cli/chunk-kwrg63tm.js +31 -0
  50. package/dist/cli/chunk-kwrg63tm.js.map +10 -0
  51. package/dist/cli/{chunk-8g8ytmgx.js → chunk-nd1821sk.js} +21 -19
  52. package/dist/cli/{chunk-8g8ytmgx.js.map → chunk-nd1821sk.js.map} +2 -2
  53. package/dist/cli/{chunk-w4bxdvsa.js → chunk-ntv4qrt7.js} +17 -15
  54. package/dist/cli/{chunk-w4bxdvsa.js.map → chunk-ntv4qrt7.js.map} +2 -2
  55. package/dist/cli/{chunk-bfwp9vp6.js → chunk-p804f3pe.js} +7 -7
  56. package/dist/cli/{chunk-4e9b9ra6.js → chunk-py62fewh.js} +6 -6
  57. package/dist/cli/{chunk-4e9b9ra6.js.map → chunk-py62fewh.js.map} +1 -1
  58. package/dist/cli/chunk-q3wxxq39.js +126 -0
  59. package/dist/cli/chunk-q3wxxq39.js.map +11 -0
  60. package/dist/cli/{chunk-j85scx15.js → chunk-rekqz4qg.js} +142 -46
  61. package/dist/cli/chunk-rekqz4qg.js.map +10 -0
  62. package/dist/cli/{chunk-00gs3wqs.js → chunk-ta27feev.js} +1 -1
  63. package/dist/cli/{chunk-v6ya5kcb.js → chunk-xkz5xbtv.js} +4031 -1132
  64. package/dist/cli/chunk-xkz5xbtv.js.map +213 -0
  65. package/dist/cli/{chunk-bbnwccaz.js → chunk-y4ykbark.js} +2 -2
  66. package/dist/cli/{chunk-n1yg3tj3.js → chunk-y5h4r2y0.js} +6 -6
  67. package/dist/cli/{chunk-n1yg3tj3.js.map → chunk-y5h4r2y0.js.map} +3 -3
  68. package/dist/cli/{chunk-nfcyttvj.js → chunk-yj17vs39.js} +9 -9
  69. package/dist/cli/{chunk-nfcyttvj.js.map → chunk-yj17vs39.js.map} +1 -1
  70. package/dist/cli/{chunk-7vtckvaw.js → chunk-yxmk4pec.js} +16 -14
  71. package/dist/cli/{chunk-7vtckvaw.js.map → chunk-yxmk4pec.js.map} +2 -2
  72. package/dist/cli/{chunk-gs7r695n.js → chunk-zccbjcj0.js} +22 -8
  73. package/dist/cli/{chunk-gs7r695n.js.map → chunk-zccbjcj0.js.map} +3 -3
  74. package/dist/cli/{chunk-xh43dwgw.js → chunk-zf748avv.js} +415 -225
  75. package/dist/cli/chunk-zf748avv.js.map +37 -0
  76. package/dist/cli/{chunk-d1v5rhy0.js → chunk-zhvd6adm.js} +16 -14
  77. package/dist/cli/{chunk-d1v5rhy0.js.map → chunk-zhvd6adm.js.map} +2 -2
  78. package/dist/cli/index.js +28 -20
  79. package/dist/cli/index.js.map +5 -5
  80. package/dist/types/ai/agent-surface.d.ts +8 -7
  81. package/dist/types/ai/ai-catalog.d.ts +7 -0
  82. package/dist/types/ai/ask-context.d.ts +22 -0
  83. package/dist/types/ai/ask.d.ts +271 -58
  84. package/dist/types/ai/index.d.ts +2 -2
  85. package/dist/types/ai/link-headers.d.ts +8 -1
  86. package/dist/types/ai/openapi-components.d.ts +5 -2
  87. package/dist/types/ai/relative-links.d.ts +9 -7
  88. package/dist/types/ai/site-skill.d.ts +26 -0
  89. package/dist/types/ai/skills.d.ts +20 -1
  90. package/dist/types/ai/tar.d.ts +1 -3
  91. package/dist/types/analytics/index.d.ts +2 -0
  92. package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
  93. package/dist/types/analytics/schema.d.ts +14 -0
  94. package/dist/types/astro/integration.d.ts +11 -2
  95. package/dist/types/captcha/hcaptcha.d.ts +27 -0
  96. package/dist/types/captcha/index.d.ts +28 -0
  97. package/dist/types/captcha/schema.d.ts +29 -0
  98. package/dist/types/captcha/turnstile.d.ts +28 -0
  99. package/dist/types/components/content/api-field.d.ts +59 -0
  100. package/dist/types/components/content/api-page.d.ts +95 -0
  101. package/dist/types/components/layout/nav-utils.d.ts +26 -0
  102. package/dist/types/components/openapi/helpers.d.ts +137 -0
  103. package/dist/types/components/openapi/security.d.ts +85 -0
  104. package/dist/types/consent/ethyca.d.ts +48 -0
  105. package/dist/types/consent/index.d.ts +37 -0
  106. package/dist/types/consent/native.d.ts +28 -0
  107. package/dist/types/consent/osano.d.ts +42 -0
  108. package/dist/types/consent/schema.d.ts +110 -0
  109. package/dist/types/core/base-path.d.ts +21 -7
  110. package/dist/types/core/config-input.d.ts +196 -27
  111. package/dist/types/core/data.d.ts +49 -4
  112. package/dist/types/core/directive-diagnostics.d.ts +12 -0
  113. package/dist/types/core/footer.d.ts +8 -0
  114. package/dist/types/core/heading-markers.d.ts +5 -7
  115. package/dist/types/core/i18n-ui.d.ts +86 -0
  116. package/dist/types/core/i18n.d.ts +2 -0
  117. package/dist/types/core/includes.d.ts +8 -2
  118. package/dist/types/core/last-modified.d.ts +10 -0
  119. package/dist/types/core/localizable.d.ts +7 -0
  120. package/dist/types/core/meta.d.ts +8 -0
  121. package/dist/types/core/page-modes.d.ts +29 -0
  122. package/dist/types/core/redirect-patterns.d.ts +144 -0
  123. package/dist/types/core/related.d.ts +40 -0
  124. package/dist/types/core/schema.d.ts +558 -56
  125. package/dist/types/core/sources/lower.d.ts +29 -16
  126. package/dist/types/core/sources/normalize.d.ts +13 -1
  127. package/dist/types/core/sources/read.d.ts +5 -0
  128. package/dist/types/core/sources/watch.d.ts +12 -5
  129. package/dist/types/core/standard-schema.d.ts +5 -0
  130. package/dist/types/core/types.d.ts +1 -1
  131. package/dist/types/core/variables.d.ts +42 -0
  132. package/dist/types/deploy/artifacts.d.ts +6 -4
  133. package/dist/types/deploy/headers.d.ts +5 -0
  134. package/dist/types/deploy/node-headers.d.ts +13 -2
  135. package/dist/types/deploy/platforms/cloudflare.d.ts +5 -0
  136. package/dist/types/deploy/platforms/netlify.d.ts +7 -0
  137. package/dist/types/deploy/platforms/types.d.ts +8 -0
  138. package/dist/types/deploy/platforms/vercel.d.ts +6 -0
  139. package/dist/types/deploy/redirects.d.ts +61 -22
  140. package/dist/types/deploy/vercel-negotiation.d.ts +9 -0
  141. package/dist/types/markdown/code-title.d.ts +17 -0
  142. package/dist/types/markdown/directives.d.ts +62 -0
  143. package/dist/types/markdown/features.d.ts +24 -2
  144. package/dist/types/markdown/mdast.d.ts +63 -0
  145. package/dist/types/narration/build.d.ts +70 -0
  146. package/dist/types/narration/provider.d.ts +26 -0
  147. package/dist/types/narration/script.d.ts +154 -0
  148. package/dist/types/openapi/asyncapi.d.ts +4 -2
  149. package/dist/types/openapi/model.d.ts +12 -6
  150. package/dist/types/openapi/overlay.d.ts +54 -0
  151. package/dist/types/openapi/parse.d.ts +13 -0
  152. package/dist/types/openapi/references.d.ts +14 -4
  153. package/dist/types/ratelimit/cloudflare.d.ts +39 -0
  154. package/dist/types/ratelimit/index.d.ts +27 -0
  155. package/dist/types/ratelimit/memory.d.ts +36 -0
  156. package/dist/types/ratelimit/schema.d.ts +111 -0
  157. package/dist/types/ratelimit/upstash.d.ts +21 -0
  158. package/dist/types/ratelimit/wrangler.d.ts +23 -0
  159. package/dist/types/reference/asyncapi.d.ts +10 -10
  160. package/dist/types/reference/graphql.d.ts +13 -10
  161. package/dist/types/reference/openapi.d.ts +33 -12
  162. package/dist/types/reference/options.d.ts +45 -5
  163. package/dist/types/reference/scalar.d.ts +13 -0
  164. package/dist/types/reference/schema.d.ts +60 -36
  165. package/dist/types/search/documents.d.ts +12 -1
  166. package/dist/types/search/orama-index.d.ts +4 -0
  167. package/dist/types/seo/metatags.d.ts +20 -0
  168. package/docs/02-deployment.mdx +44 -6
  169. package/docs/03-upgrading.mdx +4 -4
  170. package/docs/04-migrating.mdx +1 -1
  171. package/docs/08-faq.mdx +1 -1
  172. package/docs/advanced/changelog.mdx +2 -2
  173. package/docs/advanced/custom-pages.mdx +3 -3
  174. package/docs/advanced/skills.mdx +14 -0
  175. package/docs/cli/audit.mdx +38 -2
  176. package/docs/cli/evals.mdx +3 -3
  177. package/docs/cli/index.mdx +1 -0
  178. package/docs/cli/translate.mdx +3 -3
  179. package/docs/cli/version.mdx +1 -1
  180. package/docs/configuration/analytics.mdx +22 -1
  181. package/docs/configuration/assistant.mdx +188 -36
  182. package/docs/configuration/consent.mdx +100 -0
  183. package/docs/configuration/customization.mdx +6 -4
  184. package/docs/configuration/index.mdx +63 -5
  185. package/docs/configuration/meta.ts +3 -0
  186. package/docs/configuration/narration.mdx +119 -0
  187. package/docs/configuration/rate-limiting.mdx +69 -0
  188. package/docs/configuration/search.mdx +30 -2
  189. package/docs/configuration/theming.mdx +3 -1
  190. package/docs/content/components.mdx +107 -1
  191. package/docs/content/frontmatter.mdx +77 -1
  192. package/docs/content/i18n.mdx +40 -3
  193. package/docs/content/includes.mdx +16 -0
  194. package/docs/content/index.mdx +4 -2
  195. package/docs/content/islands.mdx +1 -1
  196. package/docs/content/meta.mdx +4 -1
  197. package/docs/content/meta.ts +1 -0
  198. package/docs/content/navigation.mdx +28 -6
  199. package/docs/content/sources/contentful.mdx +32 -0
  200. package/docs/content/sources/custom.mdx +39 -0
  201. package/docs/content/sources/github-releases.mdx +31 -0
  202. package/docs/content/sources/index.mdx +91 -0
  203. package/docs/content/sources/meta.ts +16 -0
  204. package/docs/content/sources/notion.mdx +32 -0
  205. package/docs/content/sources/obsidian.mdx +37 -0
  206. package/docs/content/sources/payload.mdx +30 -0
  207. package/docs/content/sources/remote-mdx.mdx +40 -0
  208. package/docs/content/sources/sanity.mdx +29 -0
  209. package/docs/content/sources/strapi.mdx +31 -0
  210. package/docs/content/syntax.mdx +81 -2
  211. package/docs/content/variables.mdx +41 -0
  212. package/docs/content/versioning.mdx +1 -1
  213. package/docs/discoverability/agent-discovery.mdx +30 -3
  214. package/docs/discoverability/index.mdx +3 -2
  215. package/docs/discoverability/llms-txt.mdx +1 -1
  216. package/docs/discoverability/markdown.mdx +2 -2
  217. package/docs/discoverability/metadata.mdx +17 -0
  218. package/docs/discoverability/open-graph.mdx +5 -3
  219. package/docs/discoverability/rss.mdx +1 -1
  220. package/docs/references/api-pages.mdx +74 -0
  221. package/docs/references/asyncapi.mdx +2 -2
  222. package/docs/references/graphql.mdx +3 -3
  223. package/docs/references/meta.ts +1 -1
  224. package/docs/references/openapi.mdx +106 -5
  225. package/docs/references/scalar.mdx +3 -1
  226. package/package.json +36 -1
  227. package/skills/blume/SKILL.md +3 -0
  228. package/skills/blume-migrate/SKILL.md +5 -5
  229. package/skills/blume-migrate/references/docusaurus.md +3 -3
  230. package/skills/blume-migrate/references/fumadocs.md +1 -1
  231. package/skills/blume-migrate/references/mintlify.md +37 -19
  232. package/skills/blume-migrate/references/nextra.md +3 -3
  233. package/skills/blume-migrate/references/starlight.md +2 -1
  234. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +67 -16
  235. package/skills/blume-write-skill/SKILL.md +82 -0
  236. package/src/ai/agent-readability.ts +4 -3
  237. package/src/ai/agent-surface.ts +9 -7
  238. package/src/ai/ai-catalog.ts +12 -5
  239. package/src/ai/api/handlers.ts +2 -2
  240. package/src/ai/api/spec.ts +2 -2
  241. package/src/ai/api-catalog.ts +6 -2
  242. package/src/ai/ask-context.ts +73 -20
  243. package/src/ai/ask-data.ts +6 -0
  244. package/src/ai/ask-tools.ts +142 -0
  245. package/src/ai/ask.ts +354 -76
  246. package/src/ai/changelog-markdown.ts +2 -2
  247. package/src/ai/component-markdown.ts +75 -0
  248. package/src/ai/cors.ts +2 -0
  249. package/src/ai/index.ts +12 -0
  250. package/src/ai/link-headers.ts +14 -5
  251. package/src/ai/llms.ts +24 -9
  252. package/src/ai/markdown.ts +2 -1
  253. package/src/ai/mcp/data.ts +6 -0
  254. package/src/ai/mcp/discovery.ts +2 -2
  255. package/src/ai/mcp/query.ts +2 -2
  256. package/src/ai/mcp/server.ts +2 -2
  257. package/src/ai/openapi-components.ts +31 -9
  258. package/src/ai/relative-links.ts +42 -26
  259. package/src/ai/serializers.ts +2 -1
  260. package/src/ai/site-skill.ts +274 -0
  261. package/src/ai/skills.ts +49 -3
  262. package/src/ai/tar.ts +139 -12
  263. package/src/ai/write-skill.ts +97 -0
  264. package/src/analytics/head.ts +4 -0
  265. package/src/analytics/index.ts +5 -0
  266. package/src/analytics/one-dollar-stats.ts +86 -0
  267. package/src/analytics/schema.ts +2 -0
  268. package/src/astro/generate.ts +133 -19
  269. package/src/astro/include-hmr.ts +31 -12
  270. package/src/astro/include-refresh.ts +19 -8
  271. package/src/astro/index.ts +1 -0
  272. package/src/astro/integration.ts +143 -14
  273. package/src/astro/module-types.ts +6 -0
  274. package/src/astro/runtime-modules.ts +28 -13
  275. package/src/astro/templates.ts +364 -67
  276. package/src/astro/variables.ts +31 -0
  277. package/src/audit/catalog.ts +19 -0
  278. package/src/audit/checks/contrast.ts +183 -0
  279. package/src/audit/checks/i18n.ts +2 -3
  280. package/src/audit/checks/indexability.ts +2 -3
  281. package/src/audit/checks/links.ts +13 -13
  282. package/src/audit/checks/sitemap.ts +2 -3
  283. package/src/audit/graph.ts +3 -1
  284. package/src/audit/redirects.ts +46 -15
  285. package/src/audit/run.ts +14 -9
  286. package/src/audit/snapshot.ts +5 -0
  287. package/src/audit/types.ts +2 -1
  288. package/src/blume-modules.d.ts +7 -0
  289. package/src/captcha/client.ts +152 -0
  290. package/src/captcha/hcaptcha.ts +36 -0
  291. package/src/captcha/index.ts +28 -0
  292. package/src/captcha/schema.ts +32 -0
  293. package/src/captcha/turnstile.ts +38 -0
  294. package/src/captcha/verify.ts +71 -0
  295. package/src/cli/args.ts +32 -0
  296. package/src/cli/command-meta.ts +5 -0
  297. package/src/cli/commands/audit.ts +4 -1
  298. package/src/cli/commands/doctor.ts +25 -17
  299. package/src/cli/commands/eval.ts +19 -11
  300. package/src/cli/commands/skill.ts +96 -0
  301. package/src/cli/commands/translate.ts +9 -12
  302. package/src/cli/commands/validate.ts +3 -1
  303. package/src/cli/dev-lock.ts +157 -37
  304. package/src/cli/index.ts +5 -0
  305. package/src/cli/report-format.ts +11 -6
  306. package/src/cli/required-secrets.ts +71 -29
  307. package/src/components/BlumePage.astro +2 -0
  308. package/src/components/colors.ts +19 -0
  309. package/src/components/content/ApiEndpoint.astro +18 -0
  310. package/src/components/content/ApiField.astro +79 -0
  311. package/src/components/content/ApiPlayground.astro +62 -0
  312. package/src/components/content/ApiRail.astro +19 -0
  313. package/src/components/content/Badge.astro +5 -3
  314. package/src/components/content/Color.astro +1 -0
  315. package/src/components/content/Component.astro +2 -2
  316. package/src/components/content/FileTree.astro +1 -0
  317. package/src/components/content/GithubInfo.astro +1 -0
  318. package/src/components/content/Panel.astro +1 -0
  319. package/src/components/content/ParamField.astro +25 -0
  320. package/src/components/content/RequestExample.astro +17 -0
  321. package/src/components/content/ResponseExample.astro +17 -0
  322. package/src/components/content/ResponseField.astro +32 -0
  323. package/src/components/content/Step.astro +1 -0
  324. package/src/components/content/Tab.astro +0 -1
  325. package/src/components/content/Tabs.astro +4 -0
  326. package/src/components/content/Tile.astro +1 -0
  327. package/src/components/content/Tooltip.astro +1 -0
  328. package/src/components/content/Tree.astro +1 -0
  329. package/src/components/content/TypeTable.astro +4 -1
  330. package/src/components/content/View.astro +21 -0
  331. package/src/components/content/ViewSwitcher.astro +168 -0
  332. package/src/components/content/api-field.ts +100 -0
  333. package/src/components/content/api-page.ts +224 -0
  334. package/src/components/content/badge-color.ts +5 -2
  335. package/src/components/content/base-href.ts +13 -36
  336. package/src/components/content/view-switcher.ts +71 -0
  337. package/src/components/index.ts +2 -0
  338. package/src/components/islands/Assistant.astro +10 -1
  339. package/src/components/islands/assistant.tsx +125 -18
  340. package/src/components/islands/base-path.ts +47 -10
  341. package/src/components/islands/code-question.ts +62 -0
  342. package/src/components/islands/hooks.ts +145 -40
  343. package/src/components/islands/support-link.ts +68 -0
  344. package/src/components/islands/webmcp.ts +4 -2
  345. package/src/components/layout/Analytics.astro +11 -2
  346. package/src/components/layout/Banner.astro +14 -10
  347. package/src/components/layout/Breadcrumbs.astro +11 -4
  348. package/src/components/layout/ConsentBanner.astro +62 -0
  349. package/src/components/layout/ConsentHead.astro +38 -0
  350. package/src/components/layout/Directory.astro +94 -0
  351. package/src/components/layout/DiscoveryLinks.astro +9 -5
  352. package/src/components/layout/DrawerSwitchers.astro +51 -0
  353. package/src/components/layout/Empty.astro +2 -2
  354. package/src/components/layout/Header.astro +124 -82
  355. package/src/components/layout/LanguageSwitcher.astro +50 -17
  356. package/src/components/layout/NarrationPlayer.astro +1085 -0
  357. package/src/components/layout/NavSelector.astro +35 -9
  358. package/src/components/layout/NavTabMenu.astro +3 -3
  359. package/src/components/layout/NavTree.astro +16 -6
  360. package/src/components/layout/PageActions.astro +4 -3
  361. package/src/components/layout/PageFeedback.astro +54 -49
  362. package/src/components/layout/PageLayout.astro +78 -9
  363. package/src/components/layout/Pagination.astro +3 -3
  364. package/src/components/layout/ReferenceLayout.astro +17 -6
  365. package/src/components/layout/RelatedPages.astro +42 -0
  366. package/src/components/layout/RootLayout.astro +313 -50
  367. package/src/components/layout/Search.astro +64 -30
  368. package/src/components/layout/SiteFooter.astro +124 -0
  369. package/src/components/layout/SiteMetatags.astro +16 -0
  370. package/src/components/layout/VersionBanner.astro +2 -2
  371. package/src/components/layout/analytics-client.ts +12 -0
  372. package/src/components/layout/consent/native.ts +79 -0
  373. package/src/components/layout/consent/types.ts +37 -0
  374. package/src/components/layout/footer-links.ts +53 -0
  375. package/src/components/layout/footer-socials.ts +87 -0
  376. package/src/components/layout/locale-redirect.ts +107 -0
  377. package/src/components/layout/nav-utils.ts +83 -0
  378. package/src/components/layout/page-feedback.ts +96 -0
  379. package/src/components/layout/search/analytics.ts +98 -0
  380. package/src/components/layout/search/flexsearch.ts +17 -5
  381. package/src/components/layout/search/orama-cloud.ts +26 -14
  382. package/src/components/layout/search/types.ts +20 -0
  383. package/src/components/layout/search/typesense.ts +5 -1
  384. package/src/components/layout/toc-active.ts +41 -0
  385. package/src/components/layout/toc-element.ts +8 -14
  386. package/src/components/openapi/ApiTagOperations.astro +2 -2
  387. package/src/components/openapi/AsyncApiOperation.astro +7 -4
  388. package/src/components/openapi/GraphqlChip.astro +2 -2
  389. package/src/components/openapi/Operation.astro +163 -13
  390. package/src/components/openapi/Playground.astro +4 -4
  391. package/src/components/openapi/RequestBody.astro +6 -4
  392. package/src/components/openapi/RequestPanel.astro +63 -8
  393. package/src/components/openapi/Responses.astro +6 -4
  394. package/src/components/openapi/SchemaTable.astro +7 -0
  395. package/src/components/openapi/async-snippets.ts +4 -4
  396. package/src/components/openapi/async.ts +38 -6
  397. package/src/components/openapi/code-samples.ts +97 -0
  398. package/src/components/openapi/helpers.ts +19 -9
  399. package/src/components/openapi/message-composer.ts +6 -1
  400. package/src/components/openapi/message.ts +17 -2
  401. package/src/components/openapi/operation-model.ts +81 -11
  402. package/src/components/openapi/panel.ts +4 -2
  403. package/src/components/openapi/param-style.ts +181 -0
  404. package/src/components/openapi/playground-client.ts +73 -16
  405. package/src/components/openapi/request.ts +190 -26
  406. package/src/components/openapi/schema-tree.ts +30 -24
  407. package/src/components/openapi/security.ts +6 -3
  408. package/src/components/openapi/snippets.ts +953 -13
  409. package/src/components/openapi/ws-client.ts +18 -2
  410. package/src/components/props.ts +6 -0
  411. package/src/consent/client.ts +95 -0
  412. package/src/consent/clients.ts +19 -0
  413. package/src/consent/ethyca.ts +71 -0
  414. package/src/consent/head.ts +24 -0
  415. package/src/consent/index.ts +37 -0
  416. package/src/consent/init.ts +29 -0
  417. package/src/consent/native.ts +36 -0
  418. package/src/consent/osano.ts +59 -0
  419. package/src/consent/schema.ts +30 -0
  420. package/src/core/base-path.ts +62 -16
  421. package/src/core/builtin-tags.ts +5 -0
  422. package/src/core/client-address.ts +19 -0
  423. package/src/core/config-input.ts +203 -27
  424. package/src/core/data.ts +44 -4
  425. package/src/core/diagnostics.ts +5 -2
  426. package/src/core/directive-diagnostics.ts +99 -0
  427. package/src/core/footer.ts +26 -0
  428. package/src/core/frontmatter.ts +21 -18
  429. package/src/core/graph.ts +39 -36
  430. package/src/core/heading-markers.ts +5 -18
  431. package/src/core/i18n-ui.ts +82 -2
  432. package/src/core/i18n.ts +31 -3
  433. package/src/core/includes.ts +20 -3
  434. package/src/core/last-modified.ts +25 -3
  435. package/src/core/links.ts +16 -2
  436. package/src/core/locale-links.ts +5 -1
  437. package/src/core/localizable.ts +26 -0
  438. package/src/core/meta.ts +33 -19
  439. package/src/core/navigation.ts +71 -20
  440. package/src/core/page-modes.ts +56 -0
  441. package/src/core/project-graph.ts +138 -10
  442. package/src/core/redirect-patterns.ts +491 -0
  443. package/src/core/related.ts +131 -0
  444. package/src/core/schema.ts +342 -68
  445. package/src/core/sources/contentful-rich-text.ts +27 -20
  446. package/src/core/sources/filesystem.ts +20 -2
  447. package/src/core/sources/github-releases.ts +25 -6
  448. package/src/core/sources/lexical.ts +23 -18
  449. package/src/core/sources/lower.ts +201 -34
  450. package/src/core/sources/mdx-remote.ts +51 -16
  451. package/src/core/sources/normalize.ts +327 -91
  452. package/src/core/sources/notion.ts +52 -25
  453. package/src/core/sources/obsidian.ts +23 -6
  454. package/src/core/sources/portable-text.ts +38 -21
  455. package/src/core/sources/read.ts +8 -3
  456. package/src/core/sources/strapi-blocks.ts +20 -16
  457. package/src/core/sources/watch.ts +20 -7
  458. package/src/core/standard-schema.ts +10 -6
  459. package/src/core/types.ts +1 -1
  460. package/src/core/ui-packs/ar.ts +43 -0
  461. package/src/core/ui-packs/bg.ts +45 -0
  462. package/src/core/ui-packs/bn.ts +43 -0
  463. package/src/core/ui-packs/ca.ts +46 -0
  464. package/src/core/ui-packs/cs.ts +44 -0
  465. package/src/core/ui-packs/da.ts +45 -0
  466. package/src/core/ui-packs/de.ts +46 -0
  467. package/src/core/ui-packs/el.ts +45 -0
  468. package/src/core/ui-packs/es.ts +46 -0
  469. package/src/core/ui-packs/fa.ts +45 -0
  470. package/src/core/ui-packs/fi.ts +45 -0
  471. package/src/core/ui-packs/fr.ts +46 -0
  472. package/src/core/ui-packs/he.ts +43 -0
  473. package/src/core/ui-packs/hi.ts +44 -0
  474. package/src/core/ui-packs/hr.ts +45 -0
  475. package/src/core/ui-packs/hu.ts +44 -0
  476. package/src/core/ui-packs/id.ts +45 -0
  477. package/src/core/ui-packs/it.ts +45 -0
  478. package/src/core/ui-packs/ja.ts +45 -0
  479. package/src/core/ui-packs/ko.ts +44 -0
  480. package/src/core/ui-packs/nl.ts +46 -0
  481. package/src/core/ui-packs/no.ts +44 -0
  482. package/src/core/ui-packs/pl.ts +45 -0
  483. package/src/core/ui-packs/pt-br.ts +46 -0
  484. package/src/core/ui-packs/pt.ts +45 -0
  485. package/src/core/ui-packs/ro.ts +45 -0
  486. package/src/core/ui-packs/ru.ts +45 -0
  487. package/src/core/ui-packs/sk.ts +44 -0
  488. package/src/core/ui-packs/sr.ts +45 -0
  489. package/src/core/ui-packs/sv.ts +44 -0
  490. package/src/core/ui-packs/th.ts +43 -0
  491. package/src/core/ui-packs/tr.ts +45 -0
  492. package/src/core/ui-packs/uk.ts +45 -0
  493. package/src/core/ui-packs/vi.ts +45 -0
  494. package/src/core/ui-packs/zh-tw.ts +43 -0
  495. package/src/core/ui-packs/zh.ts +43 -0
  496. package/src/core/variables.ts +103 -0
  497. package/src/core/version-cut.ts +52 -15
  498. package/src/deploy/artifacts.ts +104 -14
  499. package/src/deploy/cloudflare-negotiation.ts +39 -17
  500. package/src/deploy/headers.ts +10 -5
  501. package/src/deploy/node-headers.ts +64 -10
  502. package/src/deploy/platforms/cloudflare.ts +44 -3
  503. package/src/deploy/platforms/netlify.ts +34 -1
  504. package/src/deploy/platforms/node.ts +1 -0
  505. package/src/deploy/platforms/static.ts +1 -0
  506. package/src/deploy/platforms/types.ts +8 -0
  507. package/src/deploy/platforms/vercel.ts +38 -2
  508. package/src/deploy/redirects.ts +139 -36
  509. package/src/deploy/robots.ts +2 -2
  510. package/src/deploy/rss.ts +4 -3
  511. package/src/deploy/sitemap.ts +7 -5
  512. package/src/deploy/vercel-negotiation.ts +36 -0
  513. package/src/markdown/api-rail.ts +259 -0
  514. package/src/markdown/base-links.ts +34 -36
  515. package/src/markdown/code-title.ts +35 -9
  516. package/src/markdown/directives.ts +242 -36
  517. package/src/markdown/features.ts +20 -2
  518. package/src/markdown/fence-meta.ts +2 -0
  519. package/src/markdown/include.ts +11 -1
  520. package/src/markdown/index.ts +35 -11
  521. package/src/markdown/math.ts +4 -4
  522. package/src/markdown/mdast.ts +5 -2
  523. package/src/markdown/relative-links.ts +12 -4
  524. package/src/markdown/variables.ts +56 -0
  525. package/src/markdown/views.ts +82 -0
  526. package/src/narration/build.ts +412 -0
  527. package/src/narration/player.ts +249 -0
  528. package/src/narration/provider.ts +29 -0
  529. package/src/narration/script.ts +592 -0
  530. package/src/og/card.ts +136 -11
  531. package/src/og/derive.ts +41 -31
  532. package/src/og/index.ts +1 -0
  533. package/src/openapi/asyncapi.ts +4 -2
  534. package/src/openapi/model.ts +77 -36
  535. package/src/openapi/overlay.ts +256 -0
  536. package/src/openapi/parse.ts +55 -2
  537. package/src/openapi/proxy.ts +63 -10
  538. package/src/openapi/references.ts +21 -5
  539. package/src/openapi/render-mdx.ts +46 -3
  540. package/src/openapi/scalar.ts +40 -6
  541. package/src/openapi/source.ts +1 -1
  542. package/src/ratelimit/cloudflare.ts +54 -0
  543. package/src/ratelimit/index.ts +30 -0
  544. package/src/ratelimit/memory.ts +45 -0
  545. package/src/ratelimit/runtime.ts +229 -0
  546. package/src/ratelimit/schema.ts +28 -0
  547. package/src/ratelimit/upstash.ts +30 -0
  548. package/src/ratelimit/wrangler.ts +70 -0
  549. package/src/reference/asyncapi.ts +2 -2
  550. package/src/reference/graphql.ts +5 -2
  551. package/src/reference/openapi.ts +21 -7
  552. package/src/reference/options.ts +51 -7
  553. package/src/reference/scalar.ts +33 -8
  554. package/src/registry/eject.ts +201 -28
  555. package/src/registry/registry.ts +7 -0
  556. package/src/search/adapters/version-scope.ts +30 -0
  557. package/src/search/documents.ts +93 -28
  558. package/src/search/orama-index.ts +28 -3
  559. package/src/search/pagefind-ranking.ts +39 -0
  560. package/src/search/popular.ts +2 -1
  561. package/src/search/sync/algolia.ts +15 -4
  562. package/src/search/sync/orama-cloud.ts +3 -0
  563. package/src/search/sync/typesense.ts +5 -0
  564. package/src/seo/jsonld.ts +7 -3
  565. package/src/seo/metatags.ts +67 -0
  566. package/src/theme/chrome-icons.ts +1 -0
  567. package/src/theme/color.ts +500 -0
  568. package/src/theme/entry.ts +56 -3
  569. package/src/theme/palette.ts +121 -45
  570. package/src/translate/meta.ts +68 -24
  571. package/src/translate/prompts.ts +1 -0
  572. package/src/translate/run.ts +3 -3
  573. package/src/translate/validate.ts +12 -3
  574. package/src/translate/work-list.ts +56 -17
  575. package/src/upgrade/upgrade.ts +4 -171
  576. package/dist/cli/chunk-3yce002v.js.map +0 -14
  577. package/dist/cli/chunk-5r8g91qn.js.map +0 -34
  578. package/dist/cli/chunk-6dtt0zfn.js.map +0 -10
  579. package/dist/cli/chunk-7mbqtmgb.js.map +0 -10
  580. package/dist/cli/chunk-ddndchfr.js.map +0 -14
  581. package/dist/cli/chunk-esh98wmb.js +0 -23
  582. package/dist/cli/chunk-esh98wmb.js.map +0 -10
  583. package/dist/cli/chunk-hqp2ajnh.js.map +0 -35
  584. package/dist/cli/chunk-hr8ne106.js.map +0 -13
  585. package/dist/cli/chunk-j85scx15.js.map +0 -10
  586. package/dist/cli/chunk-mqc662a6.js +0 -75
  587. package/dist/cli/chunk-mqc662a6.js.map +0 -11
  588. package/dist/cli/chunk-pbg5a4s3.js.map +0 -19
  589. package/dist/cli/chunk-qkb5a8sa.js.map +0 -10
  590. package/dist/cli/chunk-v6ya5kcb.js.map +0 -189
  591. package/dist/cli/chunk-wdrt2k2v.js.map +0 -10
  592. package/dist/cli/chunk-xh43dwgw.js.map +0 -36
  593. package/docs/content/sources.mdx +0 -338
  594. /package/dist/cli/{chunk-zp79m0ts.js.map → chunk-1n228xqb.js.map} +0 -0
  595. /package/dist/cli/{chunk-h2ez8dzb.js.map → chunk-5ffywsmb.js.map} +0 -0
  596. /package/dist/cli/{chunk-g698a744.js.map → chunk-5wj2qwn2.js.map} +0 -0
  597. /package/dist/cli/{chunk-sqw4ekg1.js.map → chunk-amrb6hgh.js.map} +0 -0
  598. /package/dist/cli/{chunk-h7k3nq3v.js.map → chunk-gp84za0h.js.map} +0 -0
  599. /package/dist/cli/{chunk-bfwp9vp6.js.map → chunk-p804f3pe.js.map} +0 -0
  600. /package/dist/cli/{chunk-00gs3wqs.js.map → chunk-ta27feev.js.map} +0 -0
  601. /package/dist/cli/{chunk-bbnwccaz.js.map → chunk-y4ykbark.js.map} +0 -0
@@ -6,6 +6,7 @@ import {
6
6
  enrichDiagnostic
7
7
  } from "./index.js";
8
8
  import {
9
+ resolveFallbackLocale,
9
10
  OPENAPI_PATH,
10
11
  API_PAGES_PATH,
11
12
  API_PAGE_PATH,
@@ -16,6 +17,7 @@ import {
16
17
  referenceRoutes,
17
18
  hasScalarReferences,
18
19
  builtinProxyReferences,
20
+ apiPagesUseBuiltinProxy,
19
21
  needsPlaygroundProxy,
20
22
  buildMcpDiscovery,
21
23
  buildMcpServerCard,
@@ -26,8 +28,9 @@ import {
26
28
  routeIsTaken,
27
29
  hasGeneratedChangelog,
28
30
  customOgRoutes,
29
- resolveFallbackLocale,
30
31
  resolveAskBackend,
32
+ captchaSettings,
33
+ parseApiEndpoint,
31
34
  GOOGLE_FONTS,
32
35
  isFontSlug,
33
36
  fontLocaleCodes,
@@ -46,25 +49,29 @@ import {
46
49
  renderRssFeed,
47
50
  HTTP_METHODS,
48
51
  withServerDefaults,
52
+ readOverlaidSpec,
49
53
  isOpenApiSource,
50
54
  buildRawMarkdown,
51
55
  markdownRoutePaths
52
- } from "./chunk-v6ya5kcb.js";
56
+ } from "./chunk-xkz5xbtv.js";
53
57
  import {
54
58
  trimChar,
55
59
  normalizeBasePath,
56
60
  withBasePath,
61
+ mountBasePath,
57
62
  siteRoot,
58
63
  absoluteUrl2
59
- } from "./chunk-gs7r695n.js";
64
+ } from "./chunk-zccbjcj0.js";
60
65
  import {
66
+ resolveLocalizable,
61
67
  validateSearchPopularIcons,
62
68
  validateNavTargets
63
- } from "./chunk-5r8g91qn.js";
69
+ } from "./chunk-43zcf4gz.js";
64
70
  import {
71
+ EXPANDABLE_VISIBLE_LINES,
65
72
  buildSearchDocuments,
66
73
  buildMcpData
67
- } from "./chunk-ddndchfr.js";
74
+ } from "./chunk-2f3ndkpw.js";
68
75
  import {
69
76
  planComponentSlots,
70
77
  publishRuntimeModules,
@@ -76,6 +83,7 @@ import {
76
83
  askComponentTemplate,
77
84
  searchEndpointTemplate,
78
85
  featuresTemplate,
86
+ consentClientTemplate,
79
87
  searchClientTemplate,
80
88
  mixedbreadSearchEndpointTemplate,
81
89
  rawMarkdownEndpointTemplate,
@@ -104,32 +112,129 @@ import {
104
112
  examplesPageTemplate,
105
113
  runtimePackageTemplate,
106
114
  runtimeTsconfigTemplate
107
- } from "./chunk-hr8ne106.js";
115
+ } from "./chunk-4h8z9vv5.js";
108
116
  import {
109
117
  emptyComponentOverrides,
110
118
  analyzeComponentOverrides
111
- } from "./chunk-00gs3wqs.js";
119
+ } from "./chunk-ta27feev.js";
112
120
  import {
113
121
  writeTextAtomic
114
122
  } from "./chunk-jq5n4avg.js";
123
+ import {
124
+ resolveAccent,
125
+ resolveRadius,
126
+ buildThemeCss
127
+ } from "./chunk-cm89scdv.js";
115
128
  import {
116
129
  registry
117
- } from "./chunk-fsmrqk8a.js";
130
+ } from "./chunk-2f7n4qzt.js";
118
131
  import {
119
132
  readClientMode,
120
133
  discoverIslands,
121
134
  missingDependencyDiagnostic
122
- } from "./chunk-sqw4ekg1.js";
135
+ } from "./chunk-amrb6hgh.js";
123
136
 
124
137
  // src/astro/integration.ts
125
- import { join as join3, relative, resolve as resolve2 } from "pathe";
138
+ import { join as join4, relative, resolve as resolve2 } from "pathe";
126
139
 
127
140
  // src/deploy/artifacts.ts
128
- import { dirname as dirname2, join as join2, resolve } from "pathe";
141
+ import { dirname as dirname3, join as join3, resolve } from "pathe";
142
+
143
+ // src/narration/build.ts
144
+ import { createGateway, generateSpeech } from "ai";
145
+ import { HTMLElement, parse, TextNode } from "node-html-parser";
146
+ import { dirname, join } from "pathe";
147
+
148
+ // src/narration/script.ts
149
+ var INLINE_TAGS = new Set([
150
+ "a",
151
+ "abbr",
152
+ "audio",
153
+ "button",
154
+ "canvas",
155
+ "embed",
156
+ "iframe",
157
+ "img",
158
+ "input",
159
+ "math",
160
+ "noscript",
161
+ "object",
162
+ "picture",
163
+ "script",
164
+ "select",
165
+ "style",
166
+ "svg",
167
+ "template",
168
+ "textarea",
169
+ "video",
170
+ "b",
171
+ "bdi",
172
+ "bdo",
173
+ "cite",
174
+ "code",
175
+ "data",
176
+ "del",
177
+ "dfn",
178
+ "em",
179
+ "font",
180
+ "i",
181
+ "ins",
182
+ "kbd",
183
+ "label",
184
+ "mark",
185
+ "q",
186
+ "s",
187
+ "samp",
188
+ "small",
189
+ "span",
190
+ "strong",
191
+ "sub",
192
+ "sup",
193
+ "time",
194
+ "u",
195
+ "var",
196
+ "wbr"
197
+ ]);
198
+ var SKIPPED_TAGS = new Set([
199
+ "audio",
200
+ "blume-diff",
201
+ "blume-mermaid",
202
+ "button",
203
+ "canvas",
204
+ "dialog",
205
+ "embed",
206
+ "figure",
207
+ "iframe",
208
+ "img",
209
+ "input",
210
+ "math",
211
+ "nav",
212
+ "noscript",
213
+ "object",
214
+ "picture",
215
+ "pre",
216
+ "script",
217
+ "select",
218
+ "style",
219
+ "svg",
220
+ "table",
221
+ "template",
222
+ "textarea",
223
+ "video"
224
+ ]);
225
+ var CALLOUT_KINDS = new Set([
226
+ "danger",
227
+ "info",
228
+ "note",
229
+ "success",
230
+ "tip",
231
+ "warning"
232
+ ]);
233
+ var DENSE_SCRIPT_LANGS = new Set(["ja", "ko", "zh"]);
129
234
 
130
235
  // src/search/build.ts
131
236
  import { close, createIndex } from "pagefind";
132
- import { dirname, join } from "pathe";
237
+ import { dirname as dirname2, join as join2 } from "pathe";
133
238
 
134
239
  // src/deploy/sitemap.ts
135
240
  import { escape as escapeXml } from "html-escaper";
@@ -156,18 +261,29 @@ var publishDevNegotiation = (negotiation) => {
156
261
  homeLinkHeader: negotiation.homeLinkHeader
157
262
  } : null;
158
263
  };
264
+ var overlayChannelOf = (server) => server?.ws ?? server?.hot;
265
+ var DATA_STORE_MODULE_ID = "\x00astro:data-layer-content";
266
+ var invalidateDataStore = (server) => {
267
+ for (const { moduleGraph } of Object.values(server.environments)) {
268
+ const mod = moduleGraph.getModuleById(DATA_STORE_MODULE_ID);
269
+ if (mod) {
270
+ moduleGraph.invalidateModule(mod);
271
+ }
272
+ }
273
+ overlayChannelOf(server)?.send({ type: "full-reload" });
274
+ };
159
275
  var refreshBlumeContent = async () => {
160
- const { refreshContent } = registry2();
276
+ const { overlay, refreshContent } = registry2();
161
277
  if (!refreshContent) {
162
278
  return false;
163
279
  }
164
280
  await refreshContent({});
281
+ if (overlay) {
282
+ invalidateDataStore(overlay);
283
+ }
165
284
  return true;
166
285
  };
167
- var overlayChannel = () => {
168
- const { overlay } = registry2();
169
- return overlay?.ws ?? overlay?.hot;
170
- };
286
+ var overlayChannel = () => overlayChannelOf(registry2().overlay);
171
287
  var showBlumeErrorOverlay = (diagnostics) => {
172
288
  const errors = [];
173
289
  for (const diagnostic of diagnostics) {
@@ -214,8 +330,8 @@ import {
214
330
  rm,
215
331
  writeFile
216
332
  } from "node:fs/promises";
217
- import { dirname as dirname3, join as join4 } from "pathe";
218
- var ogCacheDir = (context) => existsSync(join4(context.root, "node_modules")) ? join4(context.root, "node_modules", ".cache", "blume", "og") : join4(context.outDir, ".cache", "og");
333
+ import { dirname as dirname4, join as join5 } from "pathe";
334
+ var ogCacheDir = (context) => existsSync(join5(context.root, "node_modules")) ? join5(context.root, "node_modules", ".cache", "blume", "og") : join5(context.outDir, ".cache", "og");
219
335
  var REGISTRY_KEY2 = Symbol.for("blume.og-cache");
220
336
  var registry3 = () => {
221
337
  const host = globalThis;
@@ -233,7 +349,7 @@ var pruneCardCache = async (dir) => {
233
349
  return 0;
234
350
  }
235
351
  const stale = entries.filter((name) => name.endsWith(".tmp") || name.endsWith(".png") && !used.has(name.slice(0, -".png".length)));
236
- await Promise.all(stale.map((name) => rm(join4(dir, name), { force: true })));
352
+ await Promise.all(stale.map((name) => rm(join5(dir, name), { force: true })));
237
353
  return stale.length;
238
354
  };
239
355
  var cardCacheTally = () => {
@@ -256,7 +372,7 @@ import {
256
372
  import { createRequire as createRequire2 } from "node:module";
257
373
  import { pathToFileURL } from "node:url";
258
374
  import pMap2 from "p-map";
259
- import { dirname as dirname7, isAbsolute as isAbsolute6, join as join11, normalize as normalize2, relative as relative5, resolve as resolve6 } from "pathe";
375
+ import { dirname as dirname8, isAbsolute as isAbsolute6, join as join12, normalize as normalize2, relative as relative5, resolve as resolve6 } from "pathe";
260
376
  import { glob as glob2 } from "tinyglobby";
261
377
 
262
378
  // src/ai/api/problem.ts
@@ -774,7 +890,7 @@ var buildApiSpec = (input) => {
774
890
  if (input.site) {
775
891
  document.externalDocs = {
776
892
  description: `${input.name} documentation`,
777
- url: absoluteUrl2(input.site, withBasePath(input.base, "/"))
893
+ url: absoluteUrl2(input.site, mountBasePath(input.base, "/"))
778
894
  };
779
895
  }
780
896
  return document;
@@ -801,6 +917,12 @@ var buildAskData = async (project) => {
801
917
  if (versioned) {
802
918
  document.version = doc.version;
803
919
  }
920
+ if (doc.boost !== undefined) {
921
+ document.boost = doc.boost;
922
+ }
923
+ if (doc.keywords) {
924
+ document.keywords = doc.keywords;
925
+ }
804
926
  return document;
805
927
  }),
806
928
  site: project.config.deployment.options.site ?? null
@@ -853,7 +975,11 @@ var BUILTIN_MDX_TAGS = new Set([
853
975
  "Math",
854
976
  "Operation",
855
977
  "Panel",
978
+ "ParamField",
856
979
  "Prompt",
980
+ "RequestExample",
981
+ "ResponseExample",
982
+ "ResponseField",
857
983
  "Step",
858
984
  "Steps",
859
985
  "Tab",
@@ -862,6 +988,7 @@ var BUILTIN_MDX_TAGS = new Set([
862
988
  "Tooltip",
863
989
  "Tree",
864
990
  "TypeTable",
991
+ "View",
865
992
  "Visibility",
866
993
  "YouTube"
867
994
  ]);
@@ -956,7 +1083,7 @@ var svgDimensions = (svg) => {
956
1083
 
957
1084
  // src/core/tsconfig-aliases.ts
958
1085
  import { existsSync as existsSync2 } from "node:fs";
959
- import { dirname as dirname4, join as join5, resolve as resolve3 } from "pathe";
1086
+ import { dirname as dirname5, join as join6, resolve as resolve3 } from "pathe";
960
1087
  import ts from "typescript";
961
1088
  var PARSE_HOST = {
962
1089
  fileExists: ts.sys.fileExists,
@@ -978,7 +1105,7 @@ var toAlias = (key, value, baseDir) => {
978
1105
  return { find, replacement: resolve3(baseDir, target) };
979
1106
  };
980
1107
  var resolveTsconfigAliases = (root) => {
981
- const entry = ["tsconfig.json", "jsconfig.json"].map((name) => join5(root, name)).find((file) => existsSync2(file));
1108
+ const entry = ["tsconfig.json", "jsconfig.json"].map((name) => join6(root, name)).find((file) => existsSync2(file));
982
1109
  if (!entry) {
983
1110
  return {};
984
1111
  }
@@ -986,7 +1113,7 @@ var resolveTsconfigAliases = (root) => {
986
1113
  if (error) {
987
1114
  return {};
988
1115
  }
989
- const configDir = dirname4(entry);
1116
+ const configDir = dirname5(entry);
990
1117
  const { options } = ts.parseJsonConfigFileContent(config, PARSE_HOST, configDir, undefined, entry);
991
1118
  const { paths } = options;
992
1119
  if (!paths) {
@@ -1139,9 +1266,9 @@ var hasMermaidFence = (text) => MERMAID_FENCE.test(text);
1139
1266
 
1140
1267
  // src/og/derive.ts
1141
1268
  import { existsSync as existsSync3 } from "node:fs";
1142
- import { isAbsolute, join as join6 } from "pathe";
1269
+ import { isAbsolute, join as join7 } from "pathe";
1143
1270
  var CARD_WEIGHTS = [400, 600];
1144
- var absoluteSrc = (root, src) => isAbsolute(src) ? src : join6(root, src);
1271
+ var absoluteSrc = (root, src) => isAbsolute(src) ? src : join7(root, src);
1145
1272
  var isNumericWeight = (weight) => typeof weight === "number";
1146
1273
  var isRangeWeight = (weight) => typeof weight === "string";
1147
1274
  var isFontName = (value) => typeof value === "string";
@@ -1270,10 +1397,14 @@ var localeFamily = (locale) => {
1270
1397
  }
1271
1398
  return localeFontSubsets([locale]).length > 1 ? "Noto Sans" : null;
1272
1399
  };
1273
- var localeOgFonts = (locales) => {
1400
+ var DEFAULT_FALLBACKS = [
1401
+ "Noto Sans",
1402
+ ...new Set(Object.values(SCRIPT_FAMILIES)),
1403
+ "Noto Sans TC"
1404
+ ];
1405
+ var ogFallbackFonts = (locales) => {
1274
1406
  const names = new Set;
1275
- for (const locale of locales) {
1276
- const family = localeFamily(locale);
1407
+ for (const family of [...locales.map(localeFamily), ...DEFAULT_FALLBACKS]) {
1277
1408
  if (family) {
1278
1409
  names.add(family);
1279
1410
  }
@@ -1282,18 +1413,15 @@ var localeOgFonts = (locales) => {
1282
1413
  };
1283
1414
  var isGoogleFamilyName = (font) => typeof font === "string";
1284
1415
  var ogFontName = (font) => isGoogleFamilyName(font) ? font : font.name;
1285
- var withLocaleFonts = (derived, locales) => {
1416
+ var withFallbacks = (derived, locales) => {
1286
1417
  const loaded = new Set(derived.fonts.map(ogFontName));
1287
- const fallbacks = localeOgFonts(locales).filter((font) => !loaded.has(ogFontName(font)));
1288
- if (fallbacks.length === 0) {
1289
- return derived;
1290
- }
1291
1418
  return {
1419
+ fallbacks: ogFallbackFonts(locales).filter((font) => !loaded.has(font.name)),
1292
1420
  families: derived.families ?? {
1293
1421
  body: BUILT_IN_FAMILY,
1294
1422
  title: BUILT_IN_FAMILY
1295
1423
  },
1296
- fonts: [...derived.fonts, ...fallbacks]
1424
+ fonts: derived.fonts
1297
1425
  };
1298
1426
  };
1299
1427
  var resolveOgFontSources = (fonts, root) => fonts.map((font) => isLocalOgFont(font) ? { ...font, src: absoluteSrc(root, font.src) } : font);
@@ -1302,7 +1430,7 @@ var resolveOgFonts = (options, root) => {
1302
1430
  return { fonts: resolveOgFontSources(options.ogFonts, root) };
1303
1431
  }
1304
1432
  const derived = options.themeFontsConfigured ? deriveOgFonts(options.themeFonts, root) : { fonts: [] };
1305
- return withLocaleFonts(derived, options.locales ?? []);
1433
+ return withFallbacks(derived, options.locales ?? []);
1306
1434
  };
1307
1435
  var missingFontFiles = (options, root) => {
1308
1436
  const sources = [];
@@ -1321,98 +1449,22 @@ var missingFontFiles = (options, root) => {
1321
1449
 
1322
1450
  // src/og/logo.ts
1323
1451
  import { existsSync as existsSync4, readFileSync } from "node:fs";
1324
- import { join as join7 } from "pathe";
1452
+ import { join as join8 } from "pathe";
1325
1453
  var resolveOgLogo = (project, source) => {
1326
1454
  if (!source?.toLowerCase().endsWith(".svg")) {
1327
1455
  return;
1328
1456
  }
1329
1457
  const relative = source.replace(/^\//u, "");
1330
1458
  const file = [
1331
- join7(project.context.root, "public", relative),
1332
- join7(project.context.root, relative)
1459
+ join8(project.context.root, "public", relative),
1460
+ join8(project.context.root, relative)
1333
1461
  ].find((path) => existsSync4(path));
1334
1462
  return file ? readFileSync(file, "utf-8") : undefined;
1335
1463
  };
1336
1464
 
1337
1465
  // src/openapi/scalar.ts
1338
1466
  import { readFile as readFile2 } from "node:fs/promises";
1339
- import { isAbsolute as isAbsolute2, join as join8 } from "pathe";
1340
-
1341
- // src/theme/palette.ts
1342
- var FALLBACK_ACCENT = "oklch(0.62 0.16 250)";
1343
- var ACCENTS = {
1344
- blue: FALLBACK_ACCENT,
1345
- green: "oklch(0.6 0.16 150)",
1346
- orange: "oklch(0.68 0.17 50)",
1347
- pink: "oklch(0.65 0.2 350)",
1348
- purple: "oklch(0.58 0.2 290)",
1349
- red: "oklch(0.58 0.22 25)",
1350
- teal: "oklch(0.6 0.12 195)"
1351
- };
1352
- var isAccentPreset = (value) => Object.hasOwn(ACCENTS, value);
1353
- var CSS_COLOR = /^[\w\s#%.,()/+-]+$/u;
1354
- var safeColor = (value, fallback) => CSS_COLOR.test(value.trim()) ? value.trim() : fallback;
1355
- var presetOrColor = (value) => isAccentPreset(value) ? ACCENTS[value] : safeColor(value, FALLBACK_ACCENT);
1356
- var safeColorOrNull = (value) => value && CSS_COLOR.test(value.trim()) ? value.trim() : null;
1357
- var RADII = {
1358
- lg: "0.75rem",
1359
- md: "0.5rem",
1360
- none: "0",
1361
- sm: "0.25rem"
1362
- };
1363
- var cssString = (value) => JSON.stringify(value);
1364
- var backgroundImageCss = (image) => `url(${cssString(image)})`;
1365
- var cssToken = (name, value) => value ? [` ${name}: ${value};`] : [];
1366
- var themeRootCss = (theme, options) => [
1367
- ` --blume-accent: ${options.accent};`,
1368
- ...cssToken("--blume-action", options.action),
1369
- ...cssToken("--blume-action-foreground", options.action ? "oklch(1 0 0)" : null),
1370
- ...cssToken("--blume-background", safeColorOrNull(theme.background?.light)),
1371
- ...cssToken("--blume-background-image", theme.backgroundImage?.light ? backgroundImageCss(theme.backgroundImage.light) : null),
1372
- ` --blume-radius: ${options.radius};`
1373
- ].filter(Boolean).join(`
1374
- `);
1375
- var themeDarkCss = (theme, options) => {
1376
- const tokens = [
1377
- ` --blume-accent: ${options.accent};`,
1378
- " --blume-accent-foreground: oklch(1 0 0);",
1379
- ...cssToken("--blume-action", options.action),
1380
- ...cssToken("--blume-action-foreground", options.action ? "oklch(1 0 0)" : null),
1381
- ...cssToken("--blume-background", safeColorOrNull(theme.background?.dark)),
1382
- ...cssToken("--blume-background-image", theme.backgroundImage?.dark ? backgroundImageCss(theme.backgroundImage.dark) : null)
1383
- ].filter(Boolean);
1384
- return `:root[data-theme="dark"] {
1385
- ${tokens.join(`
1386
- `)}
1387
- }
1388
- `;
1389
- };
1390
- var resolveAccent = (theme) => ({
1391
- dark: presetOrColor(theme.accent.dark),
1392
- light: presetOrColor(theme.accent.light)
1393
- });
1394
- var resolveRadius = (theme) => RADII[theme.radius];
1395
- var buildThemeCss = (theme) => {
1396
- const accent = resolveAccent(theme);
1397
- const action = theme.action ? presetOrColor(theme.action) : null;
1398
- const radius = RADII[theme.radius];
1399
- const root = themeRootCss(theme, {
1400
- accent: accent.light,
1401
- action,
1402
- radius
1403
- });
1404
- const dark = themeDarkCss(theme, {
1405
- accent: accent.dark,
1406
- action
1407
- });
1408
- return `/* Generated by Blume from theme config. */
1409
- :root {
1410
- ${root}
1411
- }
1412
- ${dark}`;
1413
- };
1414
-
1415
- // src/openapi/scalar.ts
1467
+ import { isAbsolute as isAbsolute2, join as join9 } from "pathe";
1416
1468
  var URL_SPEC = /^https?:\/\//u;
1417
1469
  var referencePagePath = (route) => {
1418
1470
  const segments = trimChar(route, "/");
@@ -1428,11 +1480,28 @@ var themeConfiguration = (config, override) => {
1428
1480
  customCss: `:root,.light-mode,.dark-mode{--scalar-color-accent:${accent.light};--scalar-radius:${radius};}.dark-mode{--scalar-color-accent:${accent.dark};}`
1429
1481
  };
1430
1482
  };
1431
- var specConfiguration = async (spec, root) => {
1483
+ var overlaidConfiguration = async (ref, root) => {
1484
+ try {
1485
+ const { text, warnings } = await readOverlaidSpec(ref.spec, root, {
1486
+ overlays: ref.overlays
1487
+ });
1488
+ return { config: { content: text }, warning: warnings[0] };
1489
+ } catch (error) {
1490
+ const { message } = error;
1491
+ return {
1492
+ warning: `API reference ${ref.route} was skipped: its overlays couldn't be applied to "${ref.spec}" (${message}).`
1493
+ };
1494
+ }
1495
+ };
1496
+ var specConfiguration = async (ref, root) => {
1497
+ const { spec } = ref;
1498
+ if (ref.overlays?.length) {
1499
+ return await overlaidConfiguration(ref, root);
1500
+ }
1432
1501
  if (URL_SPEC.test(spec)) {
1433
1502
  return { config: { url: spec } };
1434
1503
  }
1435
- const absolute = isAbsolute2(spec) ? spec : join8(root, spec);
1504
+ const absolute = isAbsolute2(spec) ? spec : join9(root, spec);
1436
1505
  try {
1437
1506
  return { config: { content: await readFile2(absolute, "utf-8") } };
1438
1507
  } catch {
@@ -1470,13 +1539,16 @@ var buildReferenceFiles = async (options) => {
1470
1539
  }
1471
1540
  const built = await Promise.all(accepted.map(async (ref) => ({
1472
1541
  ref,
1473
- spec: await specConfiguration(ref.spec, root)
1542
+ spec: await specConfiguration(ref, root)
1474
1543
  })));
1475
1544
  const files = [];
1476
1545
  for (const { ref, spec } of built) {
1477
1546
  if (spec.warning) {
1478
1547
  warnings.push(spec.warning);
1479
1548
  }
1549
+ if (!spec.config) {
1550
+ continue;
1551
+ }
1480
1552
  const pagePath = referencePagePath(ref.route);
1481
1553
  const { theme, ...passthrough } = ref.scalar ?? {};
1482
1554
  files.push({
@@ -2064,14 +2136,60 @@ ${options.languageIcons ?? ""}
2064
2136
  transparent;
2065
2137
  }
2066
2138
 
2067
- /* Word wrap (markdown.code.wrap): long lines wrap instead of scrolling. The
2068
- attribute is set on <body> from config; default code keeps \`white-space: pre\`. */
2139
+ /* Word wrap: long lines wrap instead of scrolling, on every block
2140
+ (markdown.code.wrap, an attribute on <body>) or on one (\`\`\`ts wrap, which
2141
+ Shiki's fence-meta reader sets as data-wrap). Default code keeps
2142
+ \`white-space: pre\`. */
2069
2143
  [data-blume-code-wrap] pre,
2070
- [data-blume-code-wrap] pre code {
2144
+ [data-blume-code-wrap] pre code,
2145
+ pre[data-wrap],
2146
+ pre[data-wrap] code {
2071
2147
  overflow-wrap: break-word;
2072
2148
  white-space: pre-wrap;
2073
2149
  }
2074
2150
 
2151
+ /* An expandable block (\`\`\`ts expandable) starts collapsed to its first lines,
2152
+ faded out toward the cut, with a toggle under it (added by the layout
2153
+ script). Opened, it shows in full: no height cap and no inner scroll. The
2154
+ collapse needs that script to undo it, so a page without scripting shows
2155
+ the block the ordinary way. */
2156
+ @media (scripting: enabled) {
2157
+ .prose pre[data-expandable]:not([data-expanded]) > code {
2158
+ max-height: calc(${EXPANDABLE_VISIBLE_LINES}lh + ${CODE_SCROLL_INSET_REM}rem);
2159
+ mask-image: linear-gradient(to bottom, #000 calc(100% - 3lh), transparent);
2160
+ overflow-y: hidden;
2161
+ }
2162
+ }
2163
+
2164
+ .prose pre[data-expandable][data-expanded] > code {
2165
+ max-height: none;
2166
+ }
2167
+
2168
+ [data-blume-code-expand] {
2169
+ align-items: center;
2170
+ color: var(--blume-muted-foreground);
2171
+ display: flex;
2172
+ font-family: var(--font-sans);
2173
+ font-size: 0.75rem;
2174
+ font-weight: 500;
2175
+ gap: 0.25rem;
2176
+ justify-content: center;
2177
+ padding-top: 0.5rem;
2178
+ width: 100%;
2179
+ }
2180
+
2181
+ [data-blume-code-expand]:hover {
2182
+ color: var(--blume-foreground);
2183
+ }
2184
+
2185
+ [data-blume-code-expand] svg {
2186
+ transition: transform 150ms;
2187
+ }
2188
+
2189
+ [data-blume-code-expand][aria-expanded="true"] svg {
2190
+ transform: rotate(180deg);
2191
+ }
2192
+
2075
2193
  .prose :where(table) {
2076
2194
  font-size: 0.8125rem;
2077
2195
  }
@@ -2183,6 +2301,12 @@ blume-tabs pre[data-language],
2183
2301
  padding-inline-end: 3.5rem;
2184
2302
  }
2185
2303
 
2304
+ /* With the assistant on, an Ask button sits beside the copy button, so the
2305
+ line's tail clears both. */
2306
+ .prose :is(blume-tabs pre, .not-prose pre, pre:not([data-language])):not(.twoslash, .twoslash pre, blume-panel-tabs *):has(> [data-blume-ask]) > code {
2307
+ padding-inline-end: 5.75rem;
2308
+ }
2309
+
2186
2310
  blume-tabs pre[data-language]::before,
2187
2311
  .not-prose pre[data-language]::before {
2188
2312
  content: none;
@@ -2433,10 +2557,10 @@ ${options.userCss}
2433
2557
  `;
2434
2558
 
2435
2559
  // src/theme/sources.ts
2436
- import { dirname as dirname5, isAbsolute as isAbsolute3, relative as relative2, resolve as resolve4 } from "pathe";
2560
+ import { dirname as dirname6, isAbsolute as isAbsolute3, relative as relative2, resolve as resolve4 } from "pathe";
2437
2561
  var SOURCE_DIRECTIVE = /@source(?<not>\s+not)?\s+(?<quote>["'])(?<path>[^"']+)\k<quote>/gu;
2438
2562
  var rebaseSourceDirectives = (css, options) => {
2439
- const base = dirname5(options.from);
2563
+ const base = dirname6(options.from);
2440
2564
  return css.replace(SOURCE_DIRECTIVE, (directive, not, quote, path) => {
2441
2565
  if (isAbsolute3(path)) {
2442
2566
  return directive;
@@ -2531,7 +2655,7 @@ ${OVERRIDES}`;
2531
2655
  // src/astro/examples.ts
2532
2656
  import { readFile as readFile3 } from "node:fs/promises";
2533
2657
  import pMap from "p-map";
2534
- import { isAbsolute as isAbsolute4, join as join9, relative as relative3 } from "pathe";
2658
+ import { isAbsolute as isAbsolute4, join as join10, relative as relative3 } from "pathe";
2535
2659
  import { glob } from "tinyglobby";
2536
2660
  var FRAMEWORK_BY_EXT = {
2537
2661
  astro: "astro",
@@ -2560,7 +2684,7 @@ var splitGlobBase = (pattern) => {
2560
2684
  };
2561
2685
  var discoverExamples = async (root, pattern = "examples") => {
2562
2686
  const { base, rest } = GLOB_MAGIC.test(pattern) ? splitGlobBase(pattern) : { base: pattern, rest: DEFAULT_EXAMPLE_GLOB };
2563
- const dir = join9(root, base);
2687
+ const dir = join10(root, base);
2564
2688
  const matches = await glob([rest], {
2565
2689
  absolute: true,
2566
2690
  cwd: dir,
@@ -2609,26 +2733,26 @@ var exampleMarkdownLookup = (examples) => Object.fromEntries(examples.map((examp
2609
2733
  import { existsSync as existsSync5, realpathSync } from "node:fs";
2610
2734
  import {
2611
2735
  basename,
2612
- dirname as dirname6,
2736
+ dirname as dirname7,
2613
2737
  isAbsolute as isAbsolute5,
2614
- join as join10,
2738
+ join as join11,
2615
2739
  normalize,
2616
2740
  relative as relative4,
2617
2741
  resolve as resolve5
2618
2742
  } from "pathe";
2619
2743
  var depsCandidates = (pkgDir) => [
2620
- join10(pkgDir, "node_modules"),
2621
- dirname6(pkgDir)
2744
+ join11(pkgDir, "node_modules"),
2745
+ dirname7(pkgDir)
2622
2746
  ];
2623
- var candidateHolding = (pkgDir, ...segments) => depsCandidates(pkgDir).find((dir) => existsSync5(join10(dir, ...segments))) ?? null;
2747
+ var candidateHolding = (pkgDir, ...segments) => depsCandidates(pkgDir).find((dir) => existsSync5(join11(dir, ...segments))) ?? null;
2624
2748
  var packageDirFrom = (name, fromDir) => {
2625
2749
  let dir = normalize(fromDir);
2626
2750
  while (true) {
2627
- const candidate = join10(dir, "node_modules", name);
2628
- if (existsSync5(join10(candidate, "package.json"))) {
2751
+ const candidate = join11(dir, "node_modules", name);
2752
+ if (existsSync5(join11(candidate, "package.json"))) {
2629
2753
  return normalize(realpathSync(candidate));
2630
2754
  }
2631
- const parent = dirname6(dir);
2755
+ const parent = dirname7(dir);
2632
2756
  if (parent === dir) {
2633
2757
  return null;
2634
2758
  }
@@ -2637,13 +2761,13 @@ var packageDirFrom = (name, fromDir) => {
2637
2761
  };
2638
2762
 
2639
2763
  // src/astro/generate.ts
2640
- var BLUME_SRC = join11(packageRoot(), "src");
2764
+ var BLUME_SRC = join12(packageRoot(), "src");
2641
2765
  var resolveReactCompiler = (config, needsReact, pkgDir = packageRoot()) => {
2642
2766
  if (!(needsReact && config.react.compiler)) {
2643
2767
  return null;
2644
2768
  }
2645
2769
  try {
2646
- return createRequire2(pathToFileURL(join11(pkgDir, "_.js")).href).resolve("babel-plugin-react-compiler");
2770
+ return createRequire2(pathToFileURL(join12(pkgDir, "_.js")).href).resolve("babel-plugin-react-compiler");
2647
2771
  } catch {
2648
2772
  return null;
2649
2773
  }
@@ -2653,7 +2777,7 @@ var reactCompilerWarnings = (config, needsReact, compilerPath) => needsReact &&
2653
2777
  ] : [];
2654
2778
  var resolveAstroPackageJson = (modulesDir) => {
2655
2779
  try {
2656
- return realpathSync2(join11(modulesDir, "astro", "package.json"));
2780
+ return realpathSync2(join12(modulesDir, "astro", "package.json"));
2657
2781
  } catch {
2658
2782
  return null;
2659
2783
  }
@@ -2661,12 +2785,12 @@ var resolveAstroPackageJson = (modulesDir) => {
2661
2785
  var resolvedAstroHit = (fromDir) => {
2662
2786
  let dir = normalize2(fromDir);
2663
2787
  while (true) {
2664
- const modulesDir = join11(dir, "node_modules");
2788
+ const modulesDir = join12(dir, "node_modules");
2665
2789
  const pkg = resolveAstroPackageJson(modulesDir);
2666
2790
  if (pkg) {
2667
2791
  return { modulesDir, pkg };
2668
2792
  }
2669
- const parent = dirname7(dir);
2793
+ const parent = dirname8(dir);
2670
2794
  if (parent === dir) {
2671
2795
  return null;
2672
2796
  }
@@ -2699,13 +2823,13 @@ var linkDepsJunction = async (link, depsDir) => {
2699
2823
  return;
2700
2824
  }
2701
2825
  try {
2702
- if (resolve6(dirname7(link), await readlink(link)) === resolve6(depsDir)) {
2826
+ if (resolve6(dirname8(link), await readlink(link)) === resolve6(depsDir)) {
2703
2827
  return;
2704
2828
  }
2705
2829
  } catch {}
2706
2830
  await rm2(link, { force: true });
2707
2831
  }
2708
- await mkdir2(dirname7(link), { recursive: true });
2832
+ await mkdir2(dirname8(link), { recursive: true });
2709
2833
  await symlinkDir(depsDir, link);
2710
2834
  };
2711
2835
  var readPkgVersion = (pkgJsonPath) => {
@@ -2738,7 +2862,7 @@ var dropStaleDepsLink = async (link, pkgDir) => {
2738
2862
  let linkedBlume;
2739
2863
  let runningBlume;
2740
2864
  try {
2741
- linkedBlume = await realpath(join11(link, "blume"));
2865
+ linkedBlume = await realpath(join12(link, "blume"));
2742
2866
  runningBlume = await realpath(pkgDir);
2743
2867
  } catch {
2744
2868
  return;
@@ -2754,7 +2878,7 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
2754
2878
  }
2755
2879
  const mdxDir = candidateHolding(pkgDir, "@astrojs", "mdx");
2756
2880
  const blumeAstro = resolveAstroPackageJson(astroDir);
2757
- await dropStaleDepsLink(join11(outDir, "node_modules"), pkgDir);
2881
+ await dropStaleDepsLink(join12(outDir, "node_modules"), pkgDir);
2758
2882
  const outDirHit = resolvedAstroHit(outDir);
2759
2883
  const astroCorrect = blumeAstro !== null && outDirHit?.pkg === blumeAstro;
2760
2884
  const walkLandsInDeps = astroCorrect && outDirHit !== null && sameRealDir(outDirHit.modulesDir, astroDir);
@@ -2762,16 +2886,16 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
2762
2886
  return null;
2763
2887
  }
2764
2888
  if (mdxDir && (mdxDir === astroDir || astroCorrect)) {
2765
- await linkDepsJunction(join11(outDir, "node_modules"), mdxDir);
2889
+ await linkDepsJunction(join12(outDir, "node_modules"), mdxDir);
2766
2890
  return null;
2767
2891
  }
2768
2892
  return astroConflictWarning(blumeAstro, outDirHit?.pkg ?? null);
2769
2893
  };
2770
- var examplesCssFile = (root, config) => config.examples.css ? join11(root, config.examples.css) : null;
2894
+ var examplesCssFile = (root, config) => config.examples.css ? join12(root, config.examples.css) : null;
2771
2895
  var writeExamplesPreview = async (options) => {
2772
2896
  const { config, hasExamples, root, srcDir, write } = options;
2773
2897
  if (hasExamples) {
2774
- await write(join11(srcDir, "pages", ...config.basePath.split("/").filter(Boolean), "blume-examples", "[...path].astro"), examplesPageTemplate());
2898
+ await write(join12(srcDir, "pages", ...config.basePath.split("/").filter(Boolean), "blume-examples", "[...path].astro"), examplesPageTemplate());
2775
2899
  }
2776
2900
  const cssFile = examplesCssFile(root, config);
2777
2901
  return cssFile && !existsSync6(cssFile) ? [
@@ -2808,7 +2932,7 @@ var detectUsesMath = async (root, staged = []) => {
2808
2932
  ignore: ["**/node_modules/**", "**/.blume/**", "**/dist/**"],
2809
2933
  onlyFiles: true
2810
2934
  });
2811
- const contents = await pMap2(files, (file) => readOptional(join11(root, file)), {
2935
+ const contents = await pMap2(files, (file) => readOptional(join12(root, file)), {
2812
2936
  concurrency: READ_CONCURRENCY2
2813
2937
  });
2814
2938
  return [...contents, ...staged].some(containsMath);
@@ -2870,7 +2994,7 @@ var writeStagedContent = async (out, staged) => {
2870
2994
  const contentDir = stagedContentDir(out);
2871
2995
  const written = new Set;
2872
2996
  await Promise.all([...staged].map(async ([entryId, text]) => {
2873
- const path = join11(contentDir, entryId);
2997
+ const path = join12(contentDir, entryId);
2874
2998
  written.add(normalize2(path));
2875
2999
  await writeIfChanged(path, text);
2876
3000
  }));
@@ -2885,13 +3009,13 @@ var readLogoSvg = (project, source) => {
2885
3009
  }
2886
3010
  const rel = source.replace(/^\//u, "");
2887
3011
  const file = [
2888
- join11(project.context.root, "public", rel),
2889
- join11(project.context.root, rel)
3012
+ join12(project.context.root, "public", rel),
3013
+ join12(project.context.root, rel)
2890
3014
  ].find((path) => existsSync6(path));
2891
3015
  return file ? readFileSync3(file, "utf-8") : undefined;
2892
3016
  };
2893
3017
  var isStringShorthand = (value) => typeof value === "string";
2894
- var headerRepoUrl = (repo, derived) => {
3018
+ var footerRepoUrl = (repo, derived) => {
2895
3019
  if (isStringShorthand(repo)) {
2896
3020
  return repo;
2897
3021
  }
@@ -2942,10 +3066,10 @@ var faviconType = (name) => {
2942
3066
  var inlineDataUri = (file, type) => `data:${type};base64,${readFileSync3(file).toString("base64")}`;
2943
3067
  var defaultFavicon = () => ({
2944
3068
  dark: {
2945
- href: inlineDataUri(join11(BLUME_SRC, "assets", "icon-dark.png"), "image/png"),
3069
+ href: inlineDataUri(join12(BLUME_SRC, "assets", "icon-dark.png"), "image/png"),
2946
3070
  type: "image/png"
2947
3071
  },
2948
- href: inlineDataUri(join11(BLUME_SRC, "assets", "icon.png"), "image/png"),
3072
+ href: inlineDataUri(join12(BLUME_SRC, "assets", "icon.png"), "image/png"),
2949
3073
  type: "image/png"
2950
3074
  });
2951
3075
  var APPLE_ICON_CANDIDATES = [
@@ -2957,12 +3081,12 @@ var APPLE_ICON_CANDIDATES = [
2957
3081
  var resolveIconFile = (project, candidates) => {
2958
3082
  const { root } = project.context;
2959
3083
  for (const name of candidates) {
2960
- if (existsSync6(join11(root, "public", name))) {
3084
+ if (existsSync6(join12(root, "public", name))) {
2961
3085
  return { href: `/${name}`, type: faviconType(name) };
2962
3086
  }
2963
3087
  }
2964
3088
  for (const name of candidates) {
2965
- const file = join11(root, name);
3089
+ const file = join12(root, name);
2966
3090
  if (existsSync6(file)) {
2967
3091
  const type = faviconType(name);
2968
3092
  return { href: inlineDataUri(file, type ?? "image/x-icon"), type };
@@ -2973,18 +3097,18 @@ var resolveIconFile = (project, candidates) => {
2973
3097
  var resolveFavicon = (project) => {
2974
3098
  const { root } = project.context;
2975
3099
  for (const name of FAVICON_CANDIDATES) {
2976
- if (existsSync6(join11(root, "public", name))) {
3100
+ if (existsSync6(join12(root, "public", name))) {
2977
3101
  const type = faviconType(name);
2978
3102
  const sibling = darkSibling(name);
2979
- return existsSync6(join11(root, "public", sibling)) ? { dark: { href: `/${sibling}`, type }, href: `/${name}`, type } : { href: `/${name}`, type };
3103
+ return existsSync6(join12(root, "public", sibling)) ? { dark: { href: `/${sibling}`, type }, href: `/${name}`, type } : { href: `/${name}`, type };
2980
3104
  }
2981
3105
  }
2982
3106
  for (const name of FAVICON_CANDIDATES) {
2983
- const file = join11(root, name);
3107
+ const file = join12(root, name);
2984
3108
  if (existsSync6(file)) {
2985
3109
  const type = faviconType(name);
2986
3110
  const mime = type ?? "image/x-icon";
2987
- const siblingFile = join11(root, darkSibling(name));
3111
+ const siblingFile = join12(root, darkSibling(name));
2988
3112
  return existsSync6(siblingFile) ? {
2989
3113
  dark: { href: inlineDataUri(siblingFile, mime), type },
2990
3114
  href: inlineDataUri(file, mime),
@@ -3006,10 +3130,31 @@ var resolveBanner = (config) => {
3006
3130
  return {
3007
3131
  content: banner.content,
3008
3132
  dismissible: banner.dismissible,
3009
- key: banner.id ?? banner.content,
3133
+ key: banner.id ?? resolveLocalizable(banner.content, undefined, config.i18n?.defaultLocale),
3010
3134
  link: banner.link
3011
3135
  };
3012
3136
  };
3137
+ var playgroundProxyPattern = (config) => withBasePath(config.basePath, "/_api-proxy");
3138
+ var resolveApiPages = (config) => {
3139
+ const { auth, playground, server } = config.api;
3140
+ const resolved = {
3141
+ playground: {
3142
+ enabled: playground.enabled,
3143
+ proxy: playground.proxy === true ? playgroundProxyPattern(config) : playground.proxy
3144
+ }
3145
+ };
3146
+ if (auth) {
3147
+ resolved.auth = auth;
3148
+ }
3149
+ if (server) {
3150
+ resolved.server = server;
3151
+ }
3152
+ return resolved;
3153
+ };
3154
+ var resolveFooter = (config) => {
3155
+ const { footer } = config;
3156
+ return footer && (footer.links.length > 0 || Object.keys(footer.socials).length > 0) ? footer : null;
3157
+ };
3013
3158
  var resolveOgMark = (project, siteLogo) => {
3014
3159
  const configured = project.config.seo.og.logo;
3015
3160
  if (configured === false) {
@@ -3043,6 +3188,18 @@ var resolveGithubData = (github) => github ? {
3043
3188
  owner: github.owner,
3044
3189
  repo: github.repo
3045
3190
  } : null;
3191
+ var resolveAssistant = (config) => {
3192
+ const { assistant } = config.ai;
3193
+ if (!assistant?.enabled) {
3194
+ return null;
3195
+ }
3196
+ return {
3197
+ captcha: assistant.captcha ? captchaSettings(assistant.captcha) : null,
3198
+ endpoint: assistant.endpoint ?? null,
3199
+ suggestions: assistant.suggestions,
3200
+ support: assistant.support ?? null
3201
+ };
3202
+ };
3046
3203
  var buildRuntimeData = (project) => {
3047
3204
  const { config, context, graph, manifest } = project;
3048
3205
  const { github } = config;
@@ -3056,14 +3213,14 @@ var buildRuntimeData = (project) => {
3056
3213
  }
3057
3214
  const rel = relative5(context.root, sourcePath).split("\\").join("/");
3058
3215
  const editDir = trimChar(github?.dir ?? "", "/");
3059
- const editPath = normalize2(editDir ? join11(editDir, rel) : rel);
3216
+ const editPath = normalize2(editDir ? join12(editDir, rel) : rel);
3060
3217
  if (editPath.startsWith("..") || isAbsolute6(editPath)) {
3061
3218
  return null;
3062
3219
  }
3063
3220
  return `${editBase}/${editPath}`;
3064
3221
  };
3065
3222
  const { i18n } = config;
3066
- const markUrl = headerRepoUrl(config.navigation.repo, repoUrl2);
3223
+ const markUrl = footerRepoUrl(config.navigation.repo, repoUrl2);
3067
3224
  const withRepoUrl = (nav) => ({
3068
3225
  ...nav,
3069
3226
  repoUrl: markUrl
@@ -3093,15 +3250,14 @@ var buildRuntimeData = (project) => {
3093
3250
  const data = {
3094
3251
  config: {
3095
3252
  analytics: config.analytics,
3253
+ api: resolveApiPages(config),
3096
3254
  appleIcon: resolveAppleIcon(project),
3097
- assistant: config.ai.assistant?.enabled ? {
3098
- endpoint: config.ai.assistant.endpoint ?? null,
3099
- suggestions: config.ai.assistant.suggestions
3100
- } : null,
3255
+ assistant: resolveAssistant(config),
3101
3256
  banner: resolveBanner(config),
3102
3257
  basePath: config.basePath,
3103
3258
  codeThemes: config.markdown.code.theme,
3104
3259
  codeWrap: config.markdown.code.wrap,
3260
+ consent: config.consent,
3105
3261
  dateFormat: config.dateFormat,
3106
3262
  description: config.description,
3107
3263
  discovery: {
@@ -3112,7 +3268,9 @@ var buildRuntimeData = (project) => {
3112
3268
  sitemap: config.seo.sitemap && Boolean(config.deployment.options.site)
3113
3269
  },
3114
3270
  favicon: resolveFavicon(project),
3115
- feedback: config.feedback,
3271
+ feedback: config.feedback.enabled,
3272
+ feedbackComments: config.feedback.comments,
3273
+ footer: resolveFooter(config),
3116
3274
  github: resolveGithubData(github),
3117
3275
  i18n: i18n ? {
3118
3276
  defaultLocale: i18n.defaultLocale,
@@ -3122,7 +3280,8 @@ var buildRuntimeData = (project) => {
3122
3280
  code,
3123
3281
  dir,
3124
3282
  label
3125
- }))
3283
+ })),
3284
+ routeByBrowserLanguage: i18n.routeByBrowserLanguage
3126
3285
  } : null,
3127
3286
  identity: config.seo.organization || config.seo.software ? {
3128
3287
  organization: config.seo.organization,
@@ -3134,6 +3293,8 @@ var buildRuntimeData = (project) => {
3134
3293
  name: config.agents.mcp.name ?? config.title,
3135
3294
  route: config.agents.mcp.route
3136
3295
  } : null,
3296
+ metatags: config.seo.metatags ?? null,
3297
+ narration: config.narration.enabled ? { generated: config.narration.provider !== null } : null,
3137
3298
  og: {
3138
3299
  description: resolveOgDescription(config),
3139
3300
  enabled: config.seo.og.enabled ?? false,
@@ -3202,7 +3363,7 @@ var buildRuntimeData = (project) => {
3202
3363
  var planMcp = (project, srcDir, userPages) => {
3203
3364
  const { config } = project;
3204
3365
  const { route } = config.agents.mcp;
3205
- const dir = join11(srcDir, "blume-mcp");
3366
+ const dir = join12(srcDir, "blume-mcp");
3206
3367
  const base = {
3207
3368
  dir,
3208
3369
  discoveryPages: [],
@@ -3226,11 +3387,11 @@ var planMcp = (project, srcDir, userPages) => {
3226
3387
  ...base,
3227
3388
  discoveryPages: [
3228
3389
  {
3229
- entrypoint: join11(dir, "discovery.ts"),
3390
+ entrypoint: join12(dir, "discovery.ts"),
3230
3391
  pattern: "/.well-known/mcp.json"
3231
3392
  },
3232
3393
  {
3233
- entrypoint: join11(dir, "server-card.ts"),
3394
+ entrypoint: join12(dir, "server-card.ts"),
3234
3395
  pattern: "/.well-known/mcp/server-card.json"
3235
3396
  }
3236
3397
  ],
@@ -3257,9 +3418,9 @@ var writeMcpFiles = async (plan, write, data) => {
3257
3418
  version: data.version
3258
3419
  };
3259
3420
  await Promise.all([
3260
- write(join11(plan.srcDir, "pages", mcpPageFile(plan.route)), mcpEndpointTemplate()),
3261
- write(join11(plan.dir, "discovery.ts"), staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput))),
3262
- write(join11(plan.dir, "server-card.ts"), staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput)))
3421
+ write(join12(plan.srcDir, "pages", mcpPageFile(plan.route)), mcpEndpointTemplate()),
3422
+ write(join12(plan.dir, "discovery.ts"), staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput))),
3423
+ write(join12(plan.dir, "server-card.ts"), staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput)))
3263
3424
  ]);
3264
3425
  };
3265
3426
  var ownsApiRest = (page) => page.pattern.startsWith("/api/[");
@@ -3271,7 +3432,7 @@ var planApi = (project, srcDir, userPages) => {
3271
3432
  catchAll: server && !userPages.some(ownsApiRest) && !project.graph.pages.some(contentUnderApi),
3272
3433
  enabled: config.agents.api,
3273
3434
  server,
3274
- spec: !routeIsTaken(userPages, project.graph.pages, OPENAPI_PATH) && !existsSync6(join11(context.root, "public", "openapi.json")),
3435
+ spec: !routeIsTaken(userPages, project.graph.pages, OPENAPI_PATH) && !existsSync6(join12(context.root, "public", "openapi.json")),
3275
3436
  srcDir
3276
3437
  };
3277
3438
  };
@@ -3281,20 +3442,20 @@ var writeApiFiles = async (project, plan, write, data, mcp) => {
3281
3442
  }
3282
3443
  const { config } = project;
3283
3444
  const mcpRoute = mcp.enabled ? mcp.route : null;
3284
- const apiDir = join11(plan.srcDir, "pages", "api");
3445
+ const apiDir = join12(plan.srcDir, "pages", "api");
3285
3446
  const writes = [
3286
- write(join11(apiDir, "docs", "pages.json.ts"), apiPagesIndexTemplate()),
3287
- write(join11(apiDir, "docs", "pages", "[...route].json.ts"), apiPageTemplate()),
3288
- write(join11(apiDir, "docs", "navigation.json.ts"), apiNavigationTemplate())
3447
+ write(join12(apiDir, "docs", "pages.json.ts"), apiPagesIndexTemplate()),
3448
+ write(join12(apiDir, "docs", "pages", "[...route].json.ts"), apiPageTemplate()),
3449
+ write(join12(apiDir, "docs", "navigation.json.ts"), apiNavigationTemplate())
3289
3450
  ];
3290
3451
  if (plan.server) {
3291
- writes.push(write(join11(apiDir, "docs", "search.ts"), apiSearchTemplate()));
3452
+ writes.push(write(join12(apiDir, "docs", "search.ts"), apiSearchTemplate()));
3292
3453
  }
3293
3454
  if (plan.catchAll) {
3294
- writes.push(write(join11(apiDir, "[...path].ts"), apiNotFoundTemplate({ base: data.base, site: data.site })));
3455
+ writes.push(write(join12(apiDir, "[...path].ts"), apiNotFoundTemplate({ base: data.base, site: data.site })));
3295
3456
  }
3296
3457
  if (plan.spec) {
3297
- writes.push(write(join11(plan.srcDir, "pages", "openapi.json.ts"), staticJsonEndpointTemplate(buildApiSpec({
3458
+ writes.push(write(join12(plan.srcDir, "pages", "openapi.json.ts"), staticJsonEndpointTemplate(buildApiSpec({
3298
3459
  agentReadability: config.agents.agentReadability,
3299
3460
  base: data.base,
3300
3461
  description: config.description,
@@ -3308,11 +3469,10 @@ var writeApiFiles = async (project, plan, write, data, mcp) => {
3308
3469
  }
3309
3470
  await Promise.all(writes);
3310
3471
  };
3311
- var PLAYGROUND_PROXY_ENTRY = join11("blume-openapi", "api-proxy.ts");
3312
- var playgroundProxyPattern = (config) => withBasePath(config.basePath, "/_api-proxy");
3472
+ var PLAYGROUND_PROXY_ENTRY = join12("blume-openapi", "api-proxy.ts");
3313
3473
  var planPlaygroundProxy = (config, srcDir) => ({
3314
3474
  enabled: needsPlaygroundProxy(config),
3315
- entrypoint: join11(srcDir, PLAYGROUND_PROXY_ENTRY),
3475
+ entrypoint: join12(srcDir, PLAYGROUND_PROXY_ENTRY),
3316
3476
  pattern: playgroundProxyPattern(config)
3317
3477
  });
3318
3478
  var specOriginsOf = (spec) => {
@@ -3344,6 +3504,27 @@ var specOriginsOf = (spec) => {
3344
3504
  return [...origins];
3345
3505
  };
3346
3506
  var specOrigins = (data) => [...new Set(Object.values(data).flatMap(specOriginsOf))].toSorted();
3507
+ var originOf = (url) => {
3508
+ try {
3509
+ return new URL(url).origin;
3510
+ } catch {
3511
+ return null;
3512
+ }
3513
+ };
3514
+ var apiPageOrigins = (project) => {
3515
+ const { config } = project;
3516
+ if (!apiPagesUseBuiltinProxy(config)) {
3517
+ return [];
3518
+ }
3519
+ const targets = project.graph.pages.map((page) => parseApiEndpoint(page.meta.api ?? "")?.target ?? "");
3520
+ return [config.api.server ?? "", ...targets].flatMap((target) => {
3521
+ const origin = originOf(target);
3522
+ return origin ? [origin] : [];
3523
+ });
3524
+ };
3525
+ var apiPageProxyWarnings = (project) => apiPagesUseBuiltinProxy(project.config) && apiPageOrigins(project).length === 0 ? [
3526
+ "api.playground.proxy is true, but api.server isn't an absolute URL and no page's api frontmatter names one, so the built-in proxy has no origin to allow and will refuse every request the endpoint pages send. Set api.server to the API's URL, like https://api.acme.com/v1."
3527
+ ] : [];
3347
3528
  var proxyAllowlistWarnings = (config, data) => {
3348
3529
  const proxied = new Set(builtinProxyReferences(config).map((reference) => reference.slug));
3349
3530
  const warnings = [];
@@ -3364,10 +3545,13 @@ var writeAskFiles = async (project, srcDir, write, modules) => {
3364
3545
  if (backend.grounded) {
3365
3546
  modules.set("blume:ask-data", JSON.stringify(await buildAskData(project)));
3366
3547
  }
3367
- await write(join11(srcDir, "pages", "api", "ask.ts"), askEndpointTemplate(backend, {
3548
+ await write(join12(srcDir, "pages", "api", "ask.ts"), askEndpointTemplate(backend, {
3549
+ captcha: assistant.captcha,
3368
3550
  cors: assistant.cors,
3369
3551
  instructions: assistant.instructions,
3370
- retrieval: assistant.retrieval
3552
+ rateLimit: project.config.rateLimit,
3553
+ retrieval: assistant.retrieval,
3554
+ tools: assistant.tools ?? backend.toolsByDefault
3371
3555
  }));
3372
3556
  };
3373
3557
  var writeNotFoundPage = async (write, srcDir, pages, contentPages) => {
@@ -3375,9 +3559,9 @@ var writeNotFoundPage = async (write, srcDir, pages, contentPages) => {
3375
3559
  return;
3376
3560
  }
3377
3561
  await Promise.all([
3378
- write(join11(srcDir, "pages", "404.astro"), notFoundPageTemplate()),
3379
- write(join11(srcDir, "pages", "404.md.ts"), notFoundMarkdownTemplate()),
3380
- write(join11(srcDir, "pages", "404.json.ts"), notFoundJsonTemplate())
3562
+ write(join12(srcDir, "pages", "404.astro"), notFoundPageTemplate()),
3563
+ write(join12(srcDir, "pages", "404.md.ts"), notFoundMarkdownTemplate()),
3564
+ write(join12(srcDir, "pages", "404.json.ts"), notFoundJsonTemplate())
3381
3565
  ]);
3382
3566
  };
3383
3567
  var diagnosticWarning = (diagnostic) => diagnostic.suggestion ? `${diagnostic.message} ${diagnostic.suggestion}` : diagnostic.message;
@@ -3420,20 +3604,21 @@ var languageIconCssFrom = (project, rawMarkdown) => languageIconCss(languageIcon
3420
3604
  ].join(`
3421
3605
  `)));
3422
3606
  var languageIconCssFor = async (project) => languageIconCssFrom(project, await buildRawMarkdown(project));
3423
- var writeNavFragments = (write, srcDir, navFragments) => navFragments ? write(join11(srcDir, "pages", "blume-nav", "[version]", "[locale]", "[id].astro"), navFragmentTemplate()) : Promise.resolve(false);
3607
+ var writeNavFragments = (write, srcDir, navFragments) => navFragments ? write(join12(srcDir, "pages", "blume-nav", "[version]", "[locale]", "[id].astro"), navFragmentTemplate()) : Promise.resolve(false);
3424
3608
  var clientFeaturesFor = async (project) => clientFeaturesFrom(project, await buildRawMarkdown(project));
3425
3609
  var generateRuntime = async (project) => {
3426
3610
  const { context, config } = project;
3427
3611
  assertFontFilesExist(project);
3428
3612
  const out = context.outDir;
3429
- const srcDir = join11(out, "src");
3430
- const generatedDir = join11(srcDir, "generated");
3431
- const askPath = join11(srcDir, "generated", "Ask.astro");
3432
- const themePath = join11(srcDir, "generated", "app.css");
3433
- const searchClientPath = join11(srcDir, "generated", "search-client.ts");
3434
- const featuresPath = join11(srcDir, "generated", "features.ts");
3435
- const examplesPath = join11(srcDir, "generated", "examples.ts");
3436
- const examplesThemePath = join11(srcDir, "generated", "examples.css");
3613
+ const srcDir = join12(out, "src");
3614
+ const generatedDir = join12(srcDir, "generated");
3615
+ const askPath = join12(srcDir, "generated", "Ask.astro");
3616
+ const themePath = join12(srcDir, "generated", "app.css");
3617
+ const searchClientPath = join12(srcDir, "generated", "search-client.ts");
3618
+ const consentClientPath = join12(srcDir, "generated", "consent-client.ts");
3619
+ const featuresPath = join12(srcDir, "generated", "features.ts");
3620
+ const examplesPath = join12(srcDir, "generated", "examples.ts");
3621
+ const examplesThemePath = join12(srcDir, "generated", "examples.css");
3437
3622
  const written = new Set;
3438
3623
  const write = (path, content) => {
3439
3624
  written.add(normalize2(path));
@@ -3442,7 +3627,7 @@ var generateRuntime = async (project) => {
3442
3627
  const modules = new Map;
3443
3628
  const depsLinkWarning = await ensureDepsLink(out);
3444
3629
  const contentRoutes = markdownRoutePaths(project);
3445
- const homeLinkHeader = buildHomeLinkHeader(config, contentRoutes) ?? undefined;
3630
+ const homeLinkHeader = buildHomeLinkHeader(config, contentRoutes, "dev") ?? undefined;
3446
3631
  const assistantEnabled = config.ai.assistant?.enabled ?? false;
3447
3632
  const exportPdf = config.export.pdf;
3448
3633
  const exportEpub = config.export.epub;
@@ -3500,16 +3685,19 @@ var generateRuntime = async (project) => {
3500
3685
  pattern: playgroundProxy.pattern
3501
3686
  });
3502
3687
  }
3503
- const proxyOrigins = specOrigins(openApiData);
3688
+ const proxyOrigins = [
3689
+ ...new Set([...specOrigins(openApiData), ...apiPageOrigins(project)])
3690
+ ].toSorted();
3504
3691
  const hasStaged = staged.size > 0;
3505
3692
  const hasFilesystemSource = project.sources.some((source) => !source.staged);
3506
3693
  const docsCollection = resolveDocsCollection(config, context.root);
3507
3694
  const [structural] = await Promise.all([
3508
3695
  Promise.all([
3509
- write(join11(out, "astro.config.mjs"), astroConfigTemplate({
3696
+ write(join12(out, "astro.config.mjs"), astroConfigTemplate({
3510
3697
  aliases: resolveTsconfigAliases(context.root),
3511
3698
  askPath,
3512
3699
  config,
3700
+ consentClientPath,
3513
3701
  contentRoot: docsCollection.base,
3514
3702
  contentRoutes,
3515
3703
  context,
@@ -3526,16 +3714,16 @@ var generateRuntime = async (project) => {
3526
3714
  searchClientPath,
3527
3715
  themePath
3528
3716
  })),
3529
- write(join11(out, "package.json"), runtimePackageTemplate(runtimeDependencies({ config, needsReact, needsSvelte, needsVue }))),
3530
- write(join11(out, "tsconfig.json"), runtimeTsconfigTemplate()),
3531
- write(join11(srcDir, "content.config.ts"), contentConfigTemplate({
3717
+ write(join12(out, "package.json"), runtimePackageTemplate(runtimeDependencies({ config, needsReact, needsSvelte, needsVue }))),
3718
+ write(join12(out, "tsconfig.json"), runtimeTsconfigTemplate()),
3719
+ write(join12(srcDir, "content.config.ts"), contentConfigTemplate({
3532
3720
  collection: docsCollection,
3533
3721
  config,
3534
3722
  context,
3535
3723
  filesystem: hasFilesystemSource,
3536
3724
  staged: hasStaged
3537
3725
  })),
3538
- write(join11(srcDir, "pages", "[...slug].astro"), catchAllPageTemplate({
3726
+ write(join12(srcDir, "pages", "[...slug].astro"), catchAllPageTemplate({
3539
3727
  exportEpub,
3540
3728
  exportPdf,
3541
3729
  mathEnabled: usesMath,
@@ -3544,8 +3732,8 @@ var generateRuntime = async (project) => {
3544
3732
  })),
3545
3733
  writeNavFragments(write, srcDir, navFragments),
3546
3734
  write(askPath, askComponentTemplate(assistantEnabled)),
3547
- write(join11(srcDir, "generated", "components.ts"), slotPlan.module),
3548
- write(join11(srcDir, "generated", "examples.ts"), exampleMapTemplate(exampleDiscovery.examples, config.basePath)),
3735
+ write(join12(srcDir, "generated", "components.ts"), slotPlan.module),
3736
+ write(join12(srcDir, "generated", "examples.ts"), exampleMapTemplate(exampleDiscovery.examples, config.basePath)),
3549
3737
  write(examplesThemePath, examplesEntryTemplate({
3550
3738
  configTokens: buildThemeCss(config.theme),
3551
3739
  sources: exampleScanRoots(context.root, exampleDiscovery.dir).map((dir) => `${dir}/${EXAMPLE_SCAN_GLOB}`),
@@ -3562,15 +3750,15 @@ var generateRuntime = async (project) => {
3562
3750
  userTheme
3563
3751
  }))
3564
3752
  ]),
3565
- Promise.all(slotPlan.wrappers.map((wrapper) => write(join11(srcDir, "generated", "component-slots", `${wrapper.name}.astro`), wrapper.content))),
3566
- Promise.all(exampleDiscovery.examples.map((example) => write(join11(srcDir, "generated", "examples", `${exampleSlug(example.path)}.astro`), exampleWrapperTemplate(example)))),
3753
+ Promise.all(slotPlan.wrappers.map((wrapper) => write(join12(srcDir, "generated", "component-slots", `${wrapper.name}.astro`), wrapper.content))),
3754
+ Promise.all(exampleDiscovery.examples.map((example) => write(join12(srcDir, "generated", "examples", `${exampleSlug(example.path)}.astro`), exampleWrapperTemplate(example)))),
3567
3755
  writeAskFiles(project, srcDir, write, modules),
3568
3756
  writeMcpFiles(mcp, write, agentData),
3569
3757
  writeApiFiles(project, api, write, agentData, mcp),
3570
3758
  playgroundProxy.enabled ? write(playgroundProxy.entrypoint, playgroundProxyTemplate(proxyOrigins)) : Promise.resolve(false)
3571
3759
  ]);
3572
3760
  if (config.seo.og.enabled) {
3573
- await write(join11(srcDir, "pages", "og", "[...slug].png.ts"), ogEndpointTemplate(ogRoutes, {
3761
+ await write(join12(srcDir, "pages", "og", "[...slug].png.ts"), ogEndpointTemplate(ogRoutes, {
3574
3762
  ...projectOgFonts(project),
3575
3763
  cache: {
3576
3764
  dir: ogCacheDir(project.context),
@@ -3580,7 +3768,7 @@ var generateRuntime = async (project) => {
3580
3768
  }, changelogIndex));
3581
3769
  }
3582
3770
  if (changelogIndex) {
3583
- await write(join11(srcDir, "pages", "changelog.astro"), changelogIndexTemplate({
3771
+ await write(join12(srcDir, "pages", "changelog.astro"), changelogIndexTemplate({
3584
3772
  exportEpub,
3585
3773
  exportPdf,
3586
3774
  needsReact,
@@ -3597,36 +3785,38 @@ var generateRuntime = async (project) => {
3597
3785
  }),
3598
3786
  writeNotFoundPage(write, srcDir, pages, project.graph.pages),
3599
3787
  write(searchClientPath, searchClientTemplate(config)),
3788
+ write(consentClientPath, consentClientTemplate(config.consent)),
3600
3789
  write(featuresPath, featuresTemplate(clientFeatures))
3601
3790
  ]);
3602
3791
  const searchAdapter = config.search.provider;
3603
3792
  if (searchAdapter.mode === "static") {
3604
3793
  const documents = await buildSearchDocuments(project);
3605
3794
  modules.set("blume:search-index", JSON.stringify(documents));
3606
- await write(join11(srcDir, "pages", "blume-search.json.ts"), searchEndpointTemplate());
3795
+ await write(join12(srcDir, "pages", "blume-search.json.ts"), searchEndpointTemplate());
3607
3796
  }
3608
3797
  if (searchAdapter.kind === "mixedbread") {
3609
- await write(join11(srcDir, "pages", "api", "search.ts"), mixedbreadSearchEndpointTemplate(searchAdapter.options));
3798
+ await write(join12(srcDir, "pages", "api", "search.ts"), mixedbreadSearchEndpointTemplate(searchAdapter.options));
3610
3799
  }
3611
- await write(join11(srcDir, "generated", "includes.json"), `${JSON.stringify(buildIncludeGraph(project.graph.pages))}
3800
+ await write(join12(srcDir, "generated", "includes.json"), `${JSON.stringify(buildIncludeGraph(project.graph.pages))}
3612
3801
  `);
3613
3802
  modules.set("blume:raw-markdown", JSON.stringify(rawMarkdown));
3614
3803
  const contentAssets = await collectContentAssets(project);
3615
3804
  modules.set("blume:content-assets", JSON.stringify(contentAssets));
3616
3805
  await Promise.all([
3617
- write(join11(srcDir, "pages", "[...slug].md.ts"), rawMarkdownEndpointTemplate("md")),
3618
- write(join11(srcDir, "pages", "[...slug].mdx.ts"), rawMarkdownEndpointTemplate("mdx")),
3619
- write(join11(srcDir, "pages", "blume-assets", "[...asset].ts"), contentAssetsEndpointTemplate(join11(project.context.outDir, "public", "blume-assets")))
3806
+ write(join12(srcDir, "pages", "[...slug].md.ts"), rawMarkdownEndpointTemplate("md")),
3807
+ write(join12(srcDir, "pages", "[...slug].mdx.ts"), rawMarkdownEndpointTemplate("mdx")),
3808
+ write(join12(srcDir, "pages", "blume-assets", "[...asset].ts"), contentAssetsEndpointTemplate(join12(project.context.outDir, "public", "blume-assets")))
3620
3809
  ]);
3621
3810
  const feeds = buildRssFeeds(project);
3622
3811
  if (feeds.length > 0) {
3623
3812
  const feedXml = Object.fromEntries(feeds.map((feed) => [feed.type, renderRssFeed(feed)]));
3624
3813
  modules.set("blume:rss", JSON.stringify(feedXml));
3625
- await write(join11(srcDir, "pages", "[section]", "rss.xml.ts"), rssEndpointTemplate());
3814
+ await write(join12(srcDir, "pages", "[section]", "rss.xml.ts"), rssEndpointTemplate());
3626
3815
  }
3627
3816
  const warnings = [
3628
3817
  ...depsLinkWarning ? [depsLinkWarning] : [],
3629
3818
  ...proxyAllowlistWarnings(config, openApiData),
3819
+ ...apiPageProxyWarnings(project),
3630
3820
  ...reactCompilerWarnings(config, needsReact, reactCompilerPath),
3631
3821
  ...mcp.warnings,
3632
3822
  ...islandDiscovery.warnings,
@@ -3658,12 +3848,12 @@ var generateRuntime = async (project) => {
3658
3848
  root: context.root
3659
3849
  });
3660
3850
  warnings.push(...references.warnings);
3661
- await Promise.all(references.files.map((file) => write(join11(srcDir, "pages", file.pagePath), file.content)));
3851
+ await Promise.all(references.files.map((file) => write(join12(srcDir, "pages", file.pagePath), file.content)));
3662
3852
  }
3663
3853
  modules.set("blume:data", buildRuntimeData(project));
3664
3854
  modules.set("blume:openapi", JSON.stringify(openApiData));
3665
3855
  await Promise.all([
3666
- write(join11(out, "blume.manifest.json"), `${JSON.stringify(project.manifest, null, 2)}
3856
+ write(join12(out, "blume.manifest.json"), `${JSON.stringify(project.manifest, null, 2)}
3667
3857
  `),
3668
3858
  writeStagedContent(out, staged)
3669
3859
  ]);
@@ -3673,7 +3863,7 @@ var generateRuntime = async (project) => {
3673
3863
  return { structuralChange: structural.some(Boolean), warnings };
3674
3864
  };
3675
3865
 
3676
- export { publishBuildProject, refreshBlumeContent, showBlumeErrorOverlay, ogCacheDir, pruneCardCache, cardCacheTally, buildAskData, buildThemeCss, buildReferenceFiles, tailwindEntryTemplate, examplesEntryTemplate, rebaseSourceDirectives, twoslashCss, EXAMPLE_SCAN_GLOB, exampleScanRoots, discoverExamples, exampleMarkdownLookup, packageDirFrom, detectNeedsReact, detectUsesMath, collectStaged, buildRuntimeData, PLAYGROUND_PROXY_ENTRY, playgroundProxyPattern, specOrigins, proxyAllowlistWarnings, analyzeComponentsFile, languageIconCssFor, clientFeaturesFor, generateRuntime };
3866
+ export { publishBuildProject, refreshBlumeContent, showBlumeErrorOverlay, ogCacheDir, pruneCardCache, cardCacheTally, buildApiSpec, buildAskData, resolveOgFonts, buildReferenceFiles, tailwindEntryTemplate, examplesEntryTemplate, rebaseSourceDirectives, twoslashCss, EXAMPLE_SCAN_GLOB, exampleScanRoots, discoverExamples, exampleMarkdownLookup, packageDirFrom, detectNeedsReact, detectUsesMath, collectStaged, playgroundProxyPattern, buildRuntimeData, PLAYGROUND_PROXY_ENTRY, specOrigins, proxyAllowlistWarnings, analyzeComponentsFile, languageIconCssFor, clientFeaturesFor, generateRuntime };
3677
3867
 
3678
- //# debugId=0D8B04D4ECFE76CE64756E2164756E21
3679
- //# sourceMappingURL=chunk-xh43dwgw.js.map
3868
+ //# debugId=168B822A64F4126564756E2164756E21
3869
+ //# sourceMappingURL=chunk-zf748avv.js.map