blume 2.1.0 → 2.1.2

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 (450) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/dist/cli/{chunk-ga0pf4aj.js → chunk-0n9xkp3d.js} +12 -3
  3. package/dist/cli/{chunk-ga0pf4aj.js.map → chunk-0n9xkp3d.js.map} +3 -3
  4. package/dist/cli/{chunk-43zcf4gz.js → chunk-0pmb4tr4.js} +541 -368
  5. package/dist/cli/chunk-0pmb4tr4.js.map +35 -0
  6. package/dist/cli/{chunk-9geymqns.js → chunk-0w6hs479.js} +15 -15
  7. package/dist/cli/{chunk-xkz5xbtv.js → chunk-124fvmzq.js} +2802 -1422
  8. package/dist/cli/chunk-124fvmzq.js.map +220 -0
  9. package/dist/cli/chunk-150jk7km.js +52 -0
  10. package/dist/cli/chunk-150jk7km.js.map +10 -0
  11. package/dist/cli/{chunk-y4ykbark.js → chunk-1f882900.js} +2 -2
  12. package/dist/cli/{chunk-5ffywsmb.js → chunk-297ajdcv.js} +8 -6
  13. package/dist/cli/{chunk-5ffywsmb.js.map → chunk-297ajdcv.js.map} +3 -3
  14. package/dist/cli/{chunk-h2a48yhd.js → chunk-32khwcb6.js} +120 -16
  15. package/dist/cli/{chunk-h2a48yhd.js.map → chunk-32khwcb6.js.map} +10 -10
  16. package/dist/cli/{chunk-5cg2rzgf.js → chunk-36bxs9c7.js} +20 -49
  17. package/dist/cli/{chunk-5cg2rzgf.js.map → chunk-36bxs9c7.js.map} +4 -5
  18. package/dist/cli/{chunk-py62fewh.js → chunk-53jqw8z0.js} +3 -3
  19. package/dist/cli/{chunk-5wj2qwn2.js → chunk-58bt3hag.js} +4 -4
  20. package/dist/cli/{chunk-e7vvk5ya.js → chunk-5cmts6dv.js} +3 -3
  21. package/dist/cli/{chunk-y5h4r2y0.js → chunk-60hz265r.js} +15 -5
  22. package/dist/cli/chunk-60hz265r.js.map +10 -0
  23. package/dist/cli/chunk-74wfhv79.js +65 -0
  24. package/dist/cli/chunk-74wfhv79.js.map +10 -0
  25. package/dist/cli/{chunk-g2z9x01v.js → chunk-9qzgg6mj.js} +3 -3
  26. package/dist/cli/{chunk-q3wxxq39.js → chunk-a57yh0h9.js} +5 -5
  27. package/dist/cli/{chunk-713mngdq.js → chunk-ave1wcbr.js} +76 -10
  28. package/dist/cli/chunk-ave1wcbr.js.map +14 -0
  29. package/dist/cli/{chunk-2n4ps1b3.js → chunk-bqxaqn5p.js} +40 -22
  30. package/dist/cli/chunk-bqxaqn5p.js.map +15 -0
  31. package/dist/cli/{chunk-jnwj5kjj.js → chunk-bxwhtvw8.js} +20 -7
  32. package/dist/cli/{chunk-jnwj5kjj.js.map → chunk-bxwhtvw8.js.map} +3 -3
  33. package/dist/cli/chunk-ckrcm08h.js +324 -0
  34. package/dist/cli/chunk-ckrcm08h.js.map +14 -0
  35. package/dist/cli/{chunk-2f3ndkpw.js → chunk-desvm72z.js} +3 -3
  36. package/dist/cli/{chunk-gp84za0h.js → chunk-dhwtqnnd.js} +2 -2
  37. package/dist/cli/{chunk-4h8z9vv5.js → chunk-dpy8qdjf.js} +93 -47
  38. package/dist/cli/chunk-dpy8qdjf.js.map +17 -0
  39. package/dist/cli/{chunk-2f7n4qzt.js → chunk-dqhg54mr.js} +1 -1
  40. package/dist/cli/{chunk-0gz36akr.js → chunk-dv2z0rzf.js} +21 -5
  41. package/dist/cli/chunk-dv2z0rzf.js.map +12 -0
  42. package/dist/cli/{chunk-cm89scdv.js → chunk-es8h0v3j.js} +9 -11
  43. package/dist/cli/{chunk-cm89scdv.js.map → chunk-es8h0v3j.js.map} +3 -3
  44. package/dist/cli/{chunk-zhvd6adm.js → chunk-gfc5fqvf.js} +14 -14
  45. package/dist/cli/{chunk-nd1821sk.js → chunk-gxtg6ed2.js} +33 -19
  46. package/dist/cli/chunk-gxtg6ed2.js.map +10 -0
  47. package/dist/cli/{chunk-p804f3pe.js → chunk-hvcxng5f.js} +6 -6
  48. package/dist/cli/{chunk-ta27feev.js → chunk-j1x92mx9.js} +21 -2
  49. package/dist/cli/chunk-j1x92mx9.js.map +10 -0
  50. package/dist/cli/{chunk-rekqz4qg.js → chunk-k3gr1nm9.js} +19 -16
  51. package/dist/cli/chunk-k3gr1nm9.js.map +10 -0
  52. package/dist/cli/{chunk-1n228xqb.js → chunk-kdpzw38a.js} +2 -2
  53. package/dist/cli/{chunk-cy5bm0j0.js → chunk-ms9z66nz.js} +2 -2
  54. package/dist/cli/{chunk-cy5bm0j0.js.map → chunk-ms9z66nz.js.map} +2 -2
  55. package/dist/cli/{chunk-zf748avv.js → chunk-nbyvgnnm.js} +193 -286
  56. package/dist/cli/chunk-nbyvgnnm.js.map +36 -0
  57. package/dist/cli/{chunk-6bm0xpgd.js → chunk-s0bdnc7v.js} +2 -2
  58. package/dist/cli/{chunk-yxmk4pec.js → chunk-sc93apfs.js} +17 -16
  59. package/dist/cli/{chunk-yxmk4pec.js.map → chunk-sc93apfs.js.map} +3 -3
  60. package/dist/cli/{chunk-cmtcnh9f.js → chunk-tfycddbt.js} +2 -2
  61. package/dist/cli/{chunk-9xr4dgee.js → chunk-twy7psdz.js} +29 -16
  62. package/dist/cli/chunk-twy7psdz.js.map +10 -0
  63. package/dist/cli/{chunk-ntv4qrt7.js → chunk-y4msrwm9.js} +15 -15
  64. package/dist/cli/{chunk-yj17vs39.js → chunk-ydp3065p.js} +5 -5
  65. package/dist/cli/index.js +24 -19
  66. package/dist/cli/index.js.map +3 -3
  67. package/dist/types/ai/ask-context.d.ts +6 -2
  68. package/dist/types/ai/ask.d.ts +24 -5
  69. package/dist/types/ai/component-markdown.d.ts +2 -0
  70. package/dist/types/ai/openapi-components.d.ts +4 -1
  71. package/dist/types/analytics/clics.d.ts +37 -0
  72. package/dist/types/analytics/index.d.ts +2 -0
  73. package/dist/types/analytics/schema.d.ts +18 -0
  74. package/dist/types/astro/integration.d.ts +11 -4
  75. package/dist/types/astro/markdown-negotiation.d.ts +3 -0
  76. package/dist/types/astro/pages.d.ts +10 -0
  77. package/dist/types/cli/init/scaffold.d.ts +1 -1
  78. package/dist/types/components/content/api-field.d.ts +4 -1
  79. package/dist/types/components/content/api-page.d.ts +6 -1
  80. package/dist/types/components/openapi/code-samples.d.ts +29 -0
  81. package/dist/types/components/openapi/helpers.d.ts +22 -1
  82. package/dist/types/components/openapi/security.d.ts +10 -0
  83. package/dist/types/components/openapi/snippets.d.ts +60 -0
  84. package/dist/types/core/changelog-index.d.ts +8 -0
  85. package/dist/types/core/config-input.d.ts +37 -6
  86. package/dist/types/core/data.d.ts +4 -0
  87. package/dist/types/core/i18n-ui.d.ts +2 -0
  88. package/dist/types/core/links.d.ts +8 -0
  89. package/dist/types/core/powered-by.d.ts +12 -0
  90. package/dist/types/core/probe.d.ts +2 -0
  91. package/dist/types/core/project-graph.d.ts +6 -0
  92. package/dist/types/core/redirect-patterns.d.ts +11 -3
  93. package/dist/types/core/schema.d.ts +228 -3
  94. package/dist/types/core/sources/cache.d.ts +3 -0
  95. package/dist/types/core/sources/contentful-rich-text.d.ts +11 -2
  96. package/dist/types/core/sources/contentful.d.ts +17 -1
  97. package/dist/types/core/sources/lexical.d.ts +5 -0
  98. package/dist/types/core/sources/lower.d.ts +10 -2
  99. package/dist/types/core/sources/normalize.d.ts +20 -1
  100. package/dist/types/core/sources/notion.d.ts +8 -0
  101. package/dist/types/core/sources/remote.d.ts +37 -10
  102. package/dist/types/core/sources/sanity.d.ts +1 -1
  103. package/dist/types/core/types.d.ts +17 -0
  104. package/dist/types/deploy/adapter-output.d.ts +2 -1
  105. package/dist/types/deploy/adapters/cloudflare.d.ts +7 -5
  106. package/dist/types/deploy/adapters/node.d.ts +58 -23
  107. package/dist/types/deploy/adapters/registry.d.ts +10 -0
  108. package/dist/types/deploy/adapters/types.d.ts +3 -2
  109. package/dist/types/deploy/cloudflare-negotiation.d.ts +5 -2
  110. package/dist/types/deploy/node-headers.d.ts +12 -4
  111. package/dist/types/deploy/platforms/cloudflare.d.ts +10 -7
  112. package/dist/types/deploy/platforms/node.d.ts +3 -1
  113. package/dist/types/deploy/platforms/types.d.ts +18 -7
  114. package/dist/types/deploy/platforms/vercel.d.ts +21 -2
  115. package/dist/types/deploy/redirects.d.ts +17 -1
  116. package/dist/types/deploy/sitemap.d.ts +2 -1
  117. package/dist/types/deploy/vercel-negotiation.d.ts +44 -21
  118. package/dist/types/narration/build.d.ts +34 -12
  119. package/dist/types/narration/provider.d.ts +96 -8
  120. package/dist/types/openapi/checks.d.ts +27 -0
  121. package/dist/types/openapi/graphql.d.ts +6 -0
  122. package/dist/types/openapi/model.d.ts +15 -4
  123. package/dist/types/openapi/parse.d.ts +3 -0
  124. package/dist/types/openapi/references.d.ts +16 -0
  125. package/dist/types/openapi/sentence.d.ts +11 -1
  126. package/dist/types/ratelimit/index.d.ts +1 -1
  127. package/dist/types/ratelimit/schema.d.ts +8 -0
  128. package/dist/types/ratelimit/upstash.d.ts +39 -14
  129. package/dist/types/reference/graphql.d.ts +76 -1
  130. package/dist/types/reference/index.d.ts +1 -1
  131. package/dist/types/reference/openapi.d.ts +2 -2
  132. package/dist/types/reference/options.d.ts +37 -1
  133. package/dist/types/reference/schema.d.ts +84 -0
  134. package/dist/types/search/adapters/registry.d.ts +3 -0
  135. package/dist/types/search/adapters/typesense.d.ts +14 -4
  136. package/dist/types/search/build.d.ts +3 -1
  137. package/dist/types/search/orama-index.d.ts +9 -9
  138. package/dist/types/search/sync/algolia.d.ts +5 -2
  139. package/dist/types/search/sync/index.d.ts +3 -1
  140. package/dist/types/search/sync/typesense.d.ts +11 -7
  141. package/dist/types/seo/jsonld.d.ts +11 -6
  142. package/dist/types/sources/contentful.d.ts +16 -0
  143. package/dist/types/sources/github-releases.d.ts +8 -1
  144. package/dist/types/sources/notion.d.ts +8 -0
  145. package/dist/types/sources/payload.d.ts +2 -0
  146. package/dist/types/sources/registry.d.ts +63 -0
  147. package/dist/types/sources/shared.d.ts +3 -0
  148. package/dist/types/sources/strapi.d.ts +2 -0
  149. package/docs/01-quickstart.mdx +4 -2
  150. package/docs/02-deployment.mdx +59 -13
  151. package/docs/03-upgrading.mdx +2 -1
  152. package/docs/04-migrating.mdx +9 -9
  153. package/docs/08-faq.mdx +12 -12
  154. package/docs/advanced/changelog.mdx +30 -2
  155. package/docs/advanced/custom-pages.mdx +1 -1
  156. package/docs/advanced/skills.mdx +1 -1
  157. package/docs/cli/audit.mdx +30 -7
  158. package/docs/cli/doctor.mdx +6 -2
  159. package/docs/cli/evals.mdx +4 -4
  160. package/docs/cli/translate.mdx +1 -0
  161. package/docs/cli/validate.mdx +4 -3
  162. package/docs/configuration/analytics.mdx +19 -1
  163. package/docs/configuration/assistant.mdx +6 -2
  164. package/docs/configuration/customization.mdx +4 -2
  165. package/docs/configuration/export.mdx +5 -3
  166. package/docs/configuration/index.mdx +4 -2
  167. package/docs/configuration/narration.mdx +43 -6
  168. package/docs/configuration/rate-limiting.mdx +23 -2
  169. package/docs/configuration/search.mdx +37 -14
  170. package/docs/content/components.mdx +2 -2
  171. package/docs/content/frontmatter.mdx +5 -3
  172. package/docs/content/i18n.mdx +2 -2
  173. package/docs/content/includes.mdx +1 -1
  174. package/docs/content/navigation.mdx +8 -6
  175. package/docs/content/sources/contentful.mdx +9 -4
  176. package/docs/content/sources/custom.mdx +7 -3
  177. package/docs/content/sources/github-releases.mdx +12 -2
  178. package/docs/content/sources/index.mdx +3 -3
  179. package/docs/content/sources/notion.mdx +17 -2
  180. package/docs/content/sources/obsidian.mdx +3 -1
  181. package/docs/content/sources/payload.mdx +5 -2
  182. package/docs/content/sources/remote-mdx.mdx +6 -0
  183. package/docs/content/sources/sanity.mdx +4 -2
  184. package/docs/content/sources/strapi.mdx +5 -2
  185. package/docs/content/syntax.mdx +2 -2
  186. package/docs/discoverability/agent-discovery.mdx +1 -1
  187. package/docs/discoverability/index.mdx +1 -1
  188. package/docs/discoverability/json-api.mdx +2 -0
  189. package/docs/discoverability/llms-txt.mdx +1 -1
  190. package/docs/discoverability/markdown.mdx +3 -1
  191. package/docs/discoverability/mcp.mdx +6 -0
  192. package/docs/discoverability/sitemap-and-robots.mdx +1 -1
  193. package/docs/discoverability/structured-data.mdx +8 -6
  194. package/docs/references/api-pages.mdx +1 -1
  195. package/docs/references/asyncapi.mdx +5 -1
  196. package/docs/references/graphql.mdx +15 -1
  197. package/docs/references/openapi.mdx +64 -8
  198. package/package.json +9 -9
  199. package/skills/blume/SKILL.md +1 -1
  200. package/skills/blume-migrate/SKILL.md +2 -2
  201. package/skills/blume-migrate/assets/{oxfmt@0.67.0.patch → oxfmt@0.71.0.patch} +7 -7
  202. package/skills/blume-migrate/references/docusaurus.md +4 -4
  203. package/skills/blume-migrate/references/fumadocs.md +17 -13
  204. package/skills/blume-migrate/references/monorepo.md +5 -5
  205. package/skills/blume-migrate/references/nextra.md +8 -5
  206. package/skills/blume-migrate/references/starlight.md +9 -7
  207. package/src/ai/ask-context.ts +33 -3
  208. package/src/ai/ask-limits.ts +13 -0
  209. package/src/ai/ask.ts +24 -6
  210. package/src/ai/changelog-markdown.ts +11 -6
  211. package/src/ai/component-markdown.ts +1 -1
  212. package/src/ai/cors.ts +12 -3
  213. package/src/ai/mcp/query.ts +14 -6
  214. package/src/ai/openapi-components.ts +28 -4
  215. package/src/ai/relative-links.ts +4 -38
  216. package/src/analytics/clics.ts +58 -0
  217. package/src/analytics/head.ts +5 -0
  218. package/src/analytics/index.ts +2 -0
  219. package/src/analytics/schema.ts +2 -0
  220. package/src/astro/generate.ts +91 -56
  221. package/src/astro/integration.ts +72 -22
  222. package/src/astro/markdown-negotiation.ts +3 -0
  223. package/src/astro/module-types.ts +3 -1
  224. package/src/astro/pages.ts +23 -0
  225. package/src/astro/render-deps.ts +10 -5
  226. package/src/astro/runtime-deps.ts +23 -2
  227. package/src/astro/templates.ts +129 -81
  228. package/src/audit/catalog.ts +19 -3
  229. package/src/audit/checks/links.ts +14 -1
  230. package/src/audit/checks/network.ts +110 -6
  231. package/src/audit/checks/redirects.ts +6 -4
  232. package/src/audit/checks/robots.ts +58 -2
  233. package/src/audit/run.ts +3 -0
  234. package/src/audit/types.ts +2 -0
  235. package/src/audit/url.ts +14 -5
  236. package/src/blume-modules.d.ts +5 -1
  237. package/src/cli/args.ts +51 -0
  238. package/src/cli/build-failure.ts +23 -0
  239. package/src/cli/commands/audit.ts +10 -1
  240. package/src/cli/commands/dev.ts +18 -2
  241. package/src/cli/commands/doctor.ts +45 -12
  242. package/src/cli/commands/eval.ts +36 -4
  243. package/src/cli/commands/init.ts +6 -4
  244. package/src/cli/commands/validate.ts +10 -1
  245. package/src/cli/init/scaffold.ts +9 -6
  246. package/src/cli/prepare.ts +6 -3
  247. package/src/cli/required-secrets.ts +3 -2
  248. package/src/components/content/ApiPlayground.astro +6 -2
  249. package/src/components/content/api-field.ts +4 -1
  250. package/src/components/content/api-page.ts +31 -7
  251. package/src/components/content/mermaid-element.ts +15 -1
  252. package/src/components/content/view-switcher.ts +7 -4
  253. package/src/components/islands/hooks.ts +27 -1
  254. package/src/components/layout/NavTree.astro +49 -5
  255. package/src/components/layout/NavTreeScript.astro +18 -0
  256. package/src/components/layout/PageActions.astro +139 -24
  257. package/src/components/layout/PageLayout.astro +13 -3
  258. package/src/components/layout/RootLayout.astro +27 -14
  259. package/src/components/layout/Search.astro +17 -3
  260. package/src/components/layout/TableOfContents.astro +24 -17
  261. package/src/components/layout/analytics-client.ts +8 -8
  262. package/src/components/layout/head-scripts.ts +6 -1
  263. package/src/components/layout/search/algolia.ts +10 -1
  264. package/src/components/layout/search/analytics.ts +42 -14
  265. package/src/components/layout/search/endpoint.ts +48 -5
  266. package/src/components/layout/search/pagefind.ts +114 -5
  267. package/src/components/layout/search/types.ts +12 -0
  268. package/src/components/layout/search/typesense.ts +18 -6
  269. package/src/components/openapi/AsyncApiOperation.astro +14 -7
  270. package/src/components/openapi/Authorization.astro +10 -0
  271. package/src/components/openapi/GraphqlOperation.astro +5 -0
  272. package/src/components/openapi/Operation.astro +24 -1
  273. package/src/components/openapi/ParametersTable.astro +8 -4
  274. package/src/components/openapi/Playground.astro +7 -1
  275. package/src/components/openapi/RequestBody.astro +19 -2
  276. package/src/components/openapi/Responses.astro +1 -0
  277. package/src/components/openapi/SchemaTable.astro +15 -3
  278. package/src/components/openapi/async-snippets.ts +61 -5
  279. package/src/components/openapi/async.ts +123 -29
  280. package/src/components/openapi/graphql-helpers.ts +35 -12
  281. package/src/components/openapi/helpers.ts +36 -2
  282. package/src/components/openapi/message-model.ts +54 -11
  283. package/src/components/openapi/message.ts +14 -4
  284. package/src/components/openapi/operation-model.ts +16 -7
  285. package/src/components/openapi/playground-client.ts +77 -58
  286. package/src/components/openapi/playground-schema.ts +1 -1
  287. package/src/components/openapi/schema-tree.ts +44 -14
  288. package/src/components/openapi/security.ts +10 -0
  289. package/src/components/openapi/snippets.ts +5 -3
  290. package/src/components/openapi/validate-json.ts +4 -3
  291. package/src/components/powered-by-middleware.ts +33 -0
  292. package/src/core/changelog-index.ts +31 -1
  293. package/src/core/component-diagnostics.ts +53 -0
  294. package/src/core/component-overrides.ts +32 -0
  295. package/src/core/config-input.ts +42 -6
  296. package/src/core/data.ts +2 -0
  297. package/src/core/diagnostics.ts +5 -0
  298. package/src/core/i18n-ui.ts +2 -0
  299. package/src/core/includes.ts +1 -1
  300. package/src/core/links.ts +47 -17
  301. package/src/core/powered-by.ts +12 -0
  302. package/src/core/probe.ts +26 -6
  303. package/src/core/project-graph.ts +59 -18
  304. package/src/core/redirect-patterns.ts +36 -7
  305. package/src/core/schema.ts +26 -6
  306. package/src/core/sources/cache.ts +6 -0
  307. package/src/core/sources/contentful-rich-text.ts +29 -6
  308. package/src/core/sources/contentful.ts +135 -25
  309. package/src/core/sources/filesystem.ts +26 -4
  310. package/src/core/sources/github-releases.ts +12 -1
  311. package/src/core/sources/lexical.ts +15 -10
  312. package/src/core/sources/lower.ts +19 -3
  313. package/src/core/sources/mdx-remote.ts +62 -10
  314. package/src/core/sources/normalize.ts +227 -41
  315. package/src/core/sources/notion.ts +34 -10
  316. package/src/core/sources/obsidian.ts +16 -3
  317. package/src/core/sources/payload.ts +38 -15
  318. package/src/core/sources/remote.ts +72 -15
  319. package/src/core/sources/resolve.ts +11 -1
  320. package/src/core/sources/sanity.ts +43 -25
  321. package/src/core/sources/strapi.ts +2 -2
  322. package/src/core/types.ts +18 -0
  323. package/src/core/ui-packs/ar.ts +1 -0
  324. package/src/core/ui-packs/bg.ts +1 -0
  325. package/src/core/ui-packs/bn.ts +1 -0
  326. package/src/core/ui-packs/ca.ts +1 -0
  327. package/src/core/ui-packs/cs.ts +1 -0
  328. package/src/core/ui-packs/da.ts +1 -0
  329. package/src/core/ui-packs/de.ts +1 -0
  330. package/src/core/ui-packs/el.ts +1 -0
  331. package/src/core/ui-packs/es.ts +1 -0
  332. package/src/core/ui-packs/fa.ts +1 -0
  333. package/src/core/ui-packs/fi.ts +1 -0
  334. package/src/core/ui-packs/fr.ts +1 -0
  335. package/src/core/ui-packs/he.ts +1 -0
  336. package/src/core/ui-packs/hi.ts +1 -0
  337. package/src/core/ui-packs/hr.ts +1 -0
  338. package/src/core/ui-packs/hu.ts +1 -0
  339. package/src/core/ui-packs/id.ts +1 -0
  340. package/src/core/ui-packs/it.ts +1 -0
  341. package/src/core/ui-packs/ja.ts +1 -0
  342. package/src/core/ui-packs/ko.ts +1 -0
  343. package/src/core/ui-packs/nl.ts +1 -0
  344. package/src/core/ui-packs/no.ts +1 -0
  345. package/src/core/ui-packs/pl.ts +1 -0
  346. package/src/core/ui-packs/pt-br.ts +1 -0
  347. package/src/core/ui-packs/pt.ts +1 -0
  348. package/src/core/ui-packs/ro.ts +1 -0
  349. package/src/core/ui-packs/ru.ts +1 -0
  350. package/src/core/ui-packs/sk.ts +1 -0
  351. package/src/core/ui-packs/sr.ts +1 -0
  352. package/src/core/ui-packs/sv.ts +1 -0
  353. package/src/core/ui-packs/th.ts +1 -0
  354. package/src/core/ui-packs/tr.ts +1 -0
  355. package/src/core/ui-packs/uk.ts +1 -0
  356. package/src/core/ui-packs/vi.ts +1 -0
  357. package/src/core/ui-packs/zh-tw.ts +1 -0
  358. package/src/core/ui-packs/zh.ts +1 -0
  359. package/src/deploy/adapter-output.ts +7 -2
  360. package/src/deploy/adapters/cloudflare.ts +7 -5
  361. package/src/deploy/adapters/node.ts +47 -9
  362. package/src/deploy/adapters/types.ts +7 -3
  363. package/src/deploy/artifacts.ts +2 -1
  364. package/src/deploy/cloudflare-negotiation.ts +36 -7
  365. package/src/deploy/headers.ts +15 -1
  366. package/src/deploy/node-headers.ts +32 -20
  367. package/src/deploy/platforms/cloudflare.ts +14 -9
  368. package/src/deploy/platforms/netlify.ts +2 -1
  369. package/src/deploy/platforms/node.ts +12 -2
  370. package/src/deploy/platforms/types.ts +21 -7
  371. package/src/deploy/platforms/vercel.ts +115 -17
  372. package/src/deploy/redirects.ts +66 -6
  373. package/src/deploy/rss.ts +3 -1
  374. package/src/deploy/sitemap.ts +39 -5
  375. package/src/deploy/vercel-negotiation.ts +325 -103
  376. package/src/eval/agents.ts +18 -1
  377. package/src/eval/prompts.ts +6 -3
  378. package/src/eval/report.ts +34 -13
  379. package/src/eval/run.ts +5 -0
  380. package/src/markdown/base-links.ts +15 -14
  381. package/src/markdown/package-commands.ts +9 -8
  382. package/src/markdown/relative-links.ts +3 -2
  383. package/src/narration/build.ts +218 -40
  384. package/src/narration/provider.ts +89 -9
  385. package/src/openapi/checks.ts +273 -0
  386. package/src/openapi/graphql-build.ts +21 -0
  387. package/src/openapi/graphql.ts +11 -0
  388. package/src/openapi/model.ts +15 -3
  389. package/src/openapi/parse.ts +127 -2
  390. package/src/openapi/references.ts +43 -3
  391. package/src/openapi/render-mdx.ts +68 -8
  392. package/src/openapi/sentence.ts +29 -2
  393. package/src/openapi/source.ts +39 -14
  394. package/src/ratelimit/index.ts +1 -1
  395. package/src/ratelimit/runtime.ts +37 -19
  396. package/src/ratelimit/upstash.ts +40 -10
  397. package/src/reference/graphql.ts +15 -1
  398. package/src/reference/index.ts +1 -0
  399. package/src/reference/openapi.ts +2 -2
  400. package/src/reference/options.ts +29 -1
  401. package/src/registry/eject.ts +8 -2
  402. package/src/search/adapters/locale-scope.ts +30 -0
  403. package/src/search/adapters/typesense.ts +14 -4
  404. package/src/search/build.ts +21 -3
  405. package/src/search/orama-index.ts +163 -31
  406. package/src/search/source-pages.ts +29 -0
  407. package/src/search/sync/algolia.ts +99 -9
  408. package/src/search/sync/index.ts +52 -13
  409. package/src/search/sync/typesense.ts +72 -27
  410. package/src/seo/jsonld.ts +38 -20
  411. package/src/sources/contentful.ts +12 -0
  412. package/src/sources/github-releases.ts +7 -1
  413. package/src/sources/notion.ts +7 -0
  414. package/src/sources/shared.ts +3 -0
  415. package/src/theme/color.ts +9 -10
  416. package/src/theme/entry.ts +43 -6
  417. package/src/translate/validate.ts +23 -1
  418. package/dist/cli/chunk-0gz36akr.js.map +0 -12
  419. package/dist/cli/chunk-2n4ps1b3.js.map +0 -15
  420. package/dist/cli/chunk-43zcf4gz.js.map +0 -36
  421. package/dist/cli/chunk-4ejxbzee.js +0 -39
  422. package/dist/cli/chunk-4ejxbzee.js.map +0 -10
  423. package/dist/cli/chunk-4h8z9vv5.js.map +0 -16
  424. package/dist/cli/chunk-713mngdq.js.map +0 -14
  425. package/dist/cli/chunk-9xr4dgee.js.map +0 -10
  426. package/dist/cli/chunk-amrb6hgh.js +0 -145
  427. package/dist/cli/chunk-amrb6hgh.js.map +0 -11
  428. package/dist/cli/chunk-nd1821sk.js.map +0 -10
  429. package/dist/cli/chunk-rekqz4qg.js.map +0 -10
  430. package/dist/cli/chunk-ta27feev.js.map +0 -10
  431. package/dist/cli/chunk-xkz5xbtv.js.map +0 -213
  432. package/dist/cli/chunk-y5h4r2y0.js.map +0 -10
  433. package/dist/cli/chunk-zf748avv.js.map +0 -37
  434. /package/dist/cli/{chunk-9geymqns.js.map → chunk-0w6hs479.js.map} +0 -0
  435. /package/dist/cli/{chunk-y4ykbark.js.map → chunk-1f882900.js.map} +0 -0
  436. /package/dist/cli/{chunk-py62fewh.js.map → chunk-53jqw8z0.js.map} +0 -0
  437. /package/dist/cli/{chunk-5wj2qwn2.js.map → chunk-58bt3hag.js.map} +0 -0
  438. /package/dist/cli/{chunk-e7vvk5ya.js.map → chunk-5cmts6dv.js.map} +0 -0
  439. /package/dist/cli/{chunk-g2z9x01v.js.map → chunk-9qzgg6mj.js.map} +0 -0
  440. /package/dist/cli/{chunk-q3wxxq39.js.map → chunk-a57yh0h9.js.map} +0 -0
  441. /package/dist/cli/{chunk-2f3ndkpw.js.map → chunk-desvm72z.js.map} +0 -0
  442. /package/dist/cli/{chunk-gp84za0h.js.map → chunk-dhwtqnnd.js.map} +0 -0
  443. /package/dist/cli/{chunk-2f7n4qzt.js.map → chunk-dqhg54mr.js.map} +0 -0
  444. /package/dist/cli/{chunk-zhvd6adm.js.map → chunk-gfc5fqvf.js.map} +0 -0
  445. /package/dist/cli/{chunk-p804f3pe.js.map → chunk-hvcxng5f.js.map} +0 -0
  446. /package/dist/cli/{chunk-1n228xqb.js.map → chunk-kdpzw38a.js.map} +0 -0
  447. /package/dist/cli/{chunk-6bm0xpgd.js.map → chunk-s0bdnc7v.js.map} +0 -0
  448. /package/dist/cli/{chunk-cmtcnh9f.js.map → chunk-tfycddbt.js.map} +0 -0
  449. /package/dist/cli/{chunk-ntv4qrt7.js.map → chunk-y4msrwm9.js.map} +0 -0
  450. /package/dist/cli/{chunk-yj17vs39.js.map → chunk-ydp3065p.js.map} +0 -0
@@ -14,7 +14,6 @@ import {
14
14
  API_SEARCH_PATH,
15
15
  apiNamePhrase,
16
16
  resolveReferences,
17
- referenceRoutes,
18
17
  hasScalarReferences,
19
18
  builtinProxyReferences,
20
19
  apiPagesUseBuiltinProxy,
@@ -23,10 +22,13 @@ import {
23
22
  buildMcpServerCard,
24
23
  hasAiCatalog,
25
24
  buildHomeLinkHeader,
25
+ resolveLocalizable,
26
26
  resolveDocsCollection,
27
+ withChangelogIndexText,
27
28
  discoverPages,
28
29
  routeIsTaken,
29
30
  hasGeneratedChangelog,
31
+ navTargetRoutes,
30
32
  customOgRoutes,
31
33
  resolveAskBackend,
32
34
  captchaSettings,
@@ -53,7 +55,7 @@ import {
53
55
  isOpenApiSource,
54
56
  buildRawMarkdown,
55
57
  markdownRoutePaths
56
- } from "./chunk-xkz5xbtv.js";
58
+ } from "./chunk-124fvmzq.js";
57
59
  import {
58
60
  trimChar,
59
61
  normalizeBasePath,
@@ -63,15 +65,14 @@ import {
63
65
  absoluteUrl2
64
66
  } from "./chunk-zccbjcj0.js";
65
67
  import {
66
- resolveLocalizable,
67
68
  validateSearchPopularIcons,
68
69
  validateNavTargets
69
- } from "./chunk-43zcf4gz.js";
70
+ } from "./chunk-0pmb4tr4.js";
70
71
  import {
71
72
  EXPANDABLE_VISIBLE_LINES,
72
73
  buildSearchDocuments,
73
74
  buildMcpData
74
- } from "./chunk-2f3ndkpw.js";
75
+ } from "./chunk-desvm72z.js";
75
76
  import {
76
77
  planComponentSlots,
77
78
  publishRuntimeModules,
@@ -112,11 +113,21 @@ import {
112
113
  examplesPageTemplate,
113
114
  runtimePackageTemplate,
114
115
  runtimeTsconfigTemplate
115
- } from "./chunk-4h8z9vv5.js";
116
+ } from "./chunk-dpy8qdjf.js";
117
+ import {
118
+ validateUsedComponents,
119
+ missingExampleDiagnostics,
120
+ discoverIslands,
121
+ EXAMPLE_SCAN_GLOB,
122
+ exampleScanRoots,
123
+ discoverExamples,
124
+ exampleMarkdownLookup,
125
+ missingDependencyDiagnostic
126
+ } from "./chunk-ckrcm08h.js";
116
127
  import {
117
128
  emptyComponentOverrides,
118
129
  analyzeComponentOverrides
119
- } from "./chunk-ta27feev.js";
130
+ } from "./chunk-j1x92mx9.js";
120
131
  import {
121
132
  writeTextAtomic
122
133
  } from "./chunk-jq5n4avg.js";
@@ -124,15 +135,10 @@ import {
124
135
  resolveAccent,
125
136
  resolveRadius,
126
137
  buildThemeCss
127
- } from "./chunk-cm89scdv.js";
138
+ } from "./chunk-es8h0v3j.js";
128
139
  import {
129
140
  registry
130
- } from "./chunk-2f7n4qzt.js";
131
- import {
132
- readClientMode,
133
- discoverIslands,
134
- missingDependencyDiagnostic
135
- } from "./chunk-amrb6hgh.js";
141
+ } from "./chunk-dqhg54mr.js";
136
142
 
137
143
  // src/astro/integration.ts
138
144
  import { join as join4, relative, resolve as resolve2 } from "pathe";
@@ -236,6 +242,10 @@ var DENSE_SCRIPT_LANGS = new Set(["ja", "ko", "zh"]);
236
242
  import { close, createIndex } from "pagefind";
237
243
  import { dirname as dirname2, join as join2 } from "pathe";
238
244
 
245
+ // src/search/sync/algolia.ts
246
+ var jsonBytes = (value) => Buffer.byteLength(JSON.stringify(value), "utf-8");
247
+ var WIDEST_CHARACTER = jsonBytes("\x00");
248
+
239
249
  // src/deploy/sitemap.ts
240
250
  import { escape as escapeXml } from "html-escaper";
241
251
  var ERROR_ROUTES = new Set(["/404", "/500"]);
@@ -363,7 +373,7 @@ import { existsSync as existsSync6, readFileSync as readFileSync3, realpathSync
363
373
  import {
364
374
  lstat,
365
375
  mkdir as mkdir2,
366
- readFile as readFile4,
376
+ readFile as readFile3,
367
377
  readlink,
368
378
  realpath,
369
379
  rm as rm2,
@@ -371,9 +381,9 @@ import {
371
381
  } from "node:fs/promises";
372
382
  import { createRequire as createRequire2 } from "node:module";
373
383
  import { pathToFileURL } from "node:url";
374
- import pMap2 from "p-map";
375
- import { dirname as dirname8, isAbsolute as isAbsolute6, join as join12, normalize as normalize2, relative as relative5, resolve as resolve6 } from "pathe";
376
- import { glob as glob2 } from "tinyglobby";
384
+ import pMap from "p-map";
385
+ import { dirname as dirname8, isAbsolute as isAbsolute5, join as join11, normalize as normalize2, relative as relative5, resolve as resolve6 } from "pathe";
386
+ import { glob } from "tinyglobby";
377
387
 
378
388
  // src/ai/api/problem.ts
379
389
  var PROBLEM_TYPE = "application/problem+json";
@@ -949,75 +959,6 @@ var navVariants = (data, hiddenDefault = null) => [
949
959
  })))
950
960
  ];
951
961
 
952
- // src/core/builtin-tags.ts
953
- var BUILTIN_MDX_TAGS = new Set([
954
- "Accordion",
955
- "AccordionItem",
956
- "ApiOverview",
957
- "ApiTagOperations",
958
- "AutoTypeTable",
959
- "Badge",
960
- "Callout",
961
- "Card",
962
- "CardGroup",
963
- "CodeBlock",
964
- "CodeGroup",
965
- "Color",
966
- "Column",
967
- "Columns",
968
- "Component",
969
- "Diff",
970
- "Expandable",
971
- "FileTree",
972
- "Frame",
973
- "GithubInfo",
974
- "Icon",
975
- "Math",
976
- "Operation",
977
- "Panel",
978
- "ParamField",
979
- "Prompt",
980
- "RequestExample",
981
- "ResponseExample",
982
- "ResponseField",
983
- "Step",
984
- "Steps",
985
- "Tab",
986
- "Tabs",
987
- "Tile",
988
- "Tooltip",
989
- "Tree",
990
- "TypeTable",
991
- "View",
992
- "Visibility",
993
- "YouTube"
994
- ]);
995
-
996
- // src/core/component-diagnostics.ts
997
- var toKebab = (tag) => tag.replaceAll(/(?<lower>[a-z0-9])(?<upper>[A-Z])/gu, "$<lower>-$<upper>").toLowerCase();
998
- var validateUsedComponents = (pages, extraTags, registryNames) => {
999
- const diagnostics = [];
1000
- const seen = new Set;
1001
- for (const page of pages) {
1002
- for (const tag of page.componentsUsed ?? []) {
1003
- if (BUILTIN_MDX_TAGS.has(tag) || extraTags.has(tag) || seen.has(tag)) {
1004
- continue;
1005
- }
1006
- seen.add(tag);
1007
- const name = toKebab(tag);
1008
- const suggestion = registryNames.has(name) ? `Run \`blume add ${name}\` to install it, or register <${tag}> in components.ts (mdx).` : `Register <${tag}> in components.ts (mdx), or add an islands/${tag}.tsx component.`;
1009
- diagnostics.push({
1010
- code: "BLUME_UNKNOWN_COMPONENT",
1011
- file: page.sourcePath ?? page.id,
1012
- message: `<${tag}> is used in ${page.route} but isn't a known component.`,
1013
- severity: "warning",
1014
- suggestion
1015
- });
1016
- }
1017
- }
1018
- return diagnostics;
1019
- };
1020
-
1021
962
  // src/core/svg-dimensions.ts
1022
963
  var ROOT = /<svg\s(?:[^>"']|"[^"]*"|'[^']*')*>/u;
1023
964
  var WIDTH = /\swidth=(?<quote>['"])(?<value>[^%]+?)\k<quote>/u;
@@ -1580,6 +1521,15 @@ var resolveSearchPopular = (popular, basePath) => popular.map(({ href, icon, lab
1580
1521
  return page;
1581
1522
  });
1582
1523
 
1524
+ // src/search/source-pages.ts
1525
+ import { relative as relative2 } from "pathe";
1526
+ var sourcePages = (project) => project.manifest.routes.flatMap((route) => route.indexable && route.sourcePath ? [
1527
+ [
1528
+ relative2(project.context.root, route.sourcePath),
1529
+ { title: route.title, url: route.path }
1530
+ ]
1531
+ ] : []);
1532
+
1583
1533
  // src/theme/code-block-padding.ts
1584
1534
  var CODE_PADDING_BLOCK_REM = 1;
1585
1535
 
@@ -1797,13 +1747,24 @@ ${THEME_MAPPING}
1797
1747
  so a large site's HTML is mostly this markup — one utility per row kind
1798
1748
  instead of the dozen classes each expands to keeps every page (and the
1799
1749
  build's HTML output) small. Kept in sync with NavTree.astro: a page row,
1800
- a page-mode group's drill-in button, a collapsible group's summary and
1801
- the link inside it, and a flat group's heading and the link inside it. */
1750
+ a page-mode group's drill-in row (or, when the group has a page, the
1751
+ link and chevron button it splits into), a collapsible group's summary
1752
+ and the link inside it, and a flat group's heading and the link inside
1753
+ it. */
1802
1754
  @utility blume-nav-link {
1803
1755
  @apply block rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:bg-muted aria-[current=page]:font-medium aria-[current=page]:text-foreground;
1804
1756
  }
1805
1757
  @utility blume-nav-drill {
1806
- @apply flex w-full items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 text-start font-medium text-foreground text-sm transition-colors hover:bg-muted;
1758
+ @apply flex w-full items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 text-start font-medium text-foreground text-sm transition-colors hover:bg-muted aria-[current]:bg-muted;
1759
+ }
1760
+ /* A routed drill row's label and chevron are separate pills, like a panel's
1761
+ back button and title, so each shows which one the pointer is on. The
1762
+ chevron's padding matches the drill row's, so chevrons line up. */
1763
+ @utility blume-nav-drill-link {
1764
+ @apply flex min-w-0 flex-1 items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 font-medium text-foreground text-sm transition-colors hover:bg-muted aria-[current]:bg-muted;
1765
+ }
1766
+ @utility blume-nav-drill-toggle {
1767
+ @apply flex shrink-0 items-center justify-center self-stretch rounded-[0.65rem] px-2.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground;
1807
1768
  }
1808
1769
  @utility blume-nav-summary {
1809
1770
  @apply flex cursor-pointer list-none items-center gap-1.5 rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground [&::-webkit-details-marker]:hidden;
@@ -2474,8 +2435,11 @@ pre:has(.line.focused):hover .line:not(.focused) {
2474
2435
  Strip the surrounding chrome so the printout is just the article. Scoped to
2475
2436
  the chrome itself, never bare \`header\`/\`aside\`: content renders those too
2476
2437
  (every Callout and Panel is an <aside>, every changelog Update has a
2477
- <header>), and they belong in the printout. \`body > header\` keeps a
2478
- \`layout.Header\` override out as well. */
2438
+ <header>), and they belong in the printout. \`body > header\` and
2439
+ \`body > footer\` keep \`layout.Header\` and \`layout.Footer\` overrides out
2440
+ as well. Everything after the article (directory and related-page cards,
2441
+ last updated, feedback, prev/next) is page chrome too, and so are the
2442
+ copy, ask, and expand buttons on code blocks. */
2479
2443
  @media print {
2480
2444
  [data-blume-banner],
2481
2445
  [data-blume-header],
@@ -2485,7 +2449,13 @@ pre:has(.line.focused):hover .line:not(.focused) {
2485
2449
  [data-blume-assistant-panel],
2486
2450
  [data-blume-page-actions],
2487
2451
  #blume-content > nav,
2488
- #blume-content > details {
2452
+ #blume-content > details,
2453
+ [data-blume-page-end],
2454
+ [data-blume-footer],
2455
+ body > footer,
2456
+ [data-blume-copy],
2457
+ [data-blume-ask],
2458
+ [data-blume-code-expand] {
2489
2459
  display: none !important;
2490
2460
  }
2491
2461
 
@@ -2496,6 +2466,23 @@ pre:has(.line.focused):hover .line:not(.focused) {
2496
2466
  overflow: visible;
2497
2467
  }
2498
2468
 
2469
+ /* A collapsed \`expandable\` block prints open: its toggle is hidden above,
2470
+ so the collapse would cut the block off at its first lines. Same
2471
+ selector as the collapse, so this later rule wins. */
2472
+ .prose pre[data-expandable]:not([data-expanded]) > code {
2473
+ mask-image: none;
2474
+ max-height: none;
2475
+ overflow-y: visible;
2476
+ }
2477
+
2478
+ /* The theme script switches a dark page to light for printing
2479
+ (\`beforeprint\`); a color transition would print mid-fade. */
2480
+ *,
2481
+ *::before,
2482
+ *::after {
2483
+ transition: none !important;
2484
+ }
2485
+
2499
2486
  #blume-content {
2500
2487
  padding: 0 !important;
2501
2488
  }
@@ -2557,7 +2544,7 @@ ${options.userCss}
2557
2544
  `;
2558
2545
 
2559
2546
  // src/theme/sources.ts
2560
- import { dirname as dirname6, isAbsolute as isAbsolute3, relative as relative2, resolve as resolve4 } from "pathe";
2547
+ import { dirname as dirname6, isAbsolute as isAbsolute3, relative as relative3, resolve as resolve4 } from "pathe";
2561
2548
  var SOURCE_DIRECTIVE = /@source(?<not>\s+not)?\s+(?<quote>["'])(?<path>[^"']+)\k<quote>/gu;
2562
2549
  var rebaseSourceDirectives = (css, options) => {
2563
2550
  const base = dirname6(options.from);
@@ -2565,7 +2552,7 @@ var rebaseSourceDirectives = (css, options) => {
2565
2552
  if (isAbsolute3(path)) {
2566
2553
  return directive;
2567
2554
  }
2568
- const rebased = relative2(options.to, resolve4(base, path));
2555
+ const rebased = relative3(options.to, resolve4(base, path));
2569
2556
  return `@source${not ?? ""} ${quote}${rebased}${quote}`;
2570
2557
  });
2571
2558
  };
@@ -2652,104 +2639,27 @@ var twoslashCss = () => {
2652
2639
  ${OVERRIDES}`;
2653
2640
  };
2654
2641
 
2655
- // src/astro/examples.ts
2656
- import { readFile as readFile3 } from "node:fs/promises";
2657
- import pMap from "p-map";
2658
- import { isAbsolute as isAbsolute4, join as join10, relative as relative3 } from "pathe";
2659
- import { glob } from "tinyglobby";
2660
- var FRAMEWORK_BY_EXT = {
2661
- astro: "astro",
2662
- jsx: "react",
2663
- svelte: "svelte",
2664
- tsx: "react",
2665
- vue: "vue"
2666
- };
2667
- var EXAMPLE_FILE = /\.(?<ext>astro|jsx|svelte|tsx|vue)$/u;
2668
- var DEFAULT_EXAMPLE_GLOB = "**/*.{astro,jsx,svelte,tsx,vue}";
2669
- var READ_CONCURRENCY = 16;
2670
- var EXAMPLE_SCAN_GLOB = "**/*.{astro,jsx,svelte,ts,tsx,vue}";
2671
- var exampleScanRoots = (root, examplesDir) => {
2672
- const path = relative3(root, examplesDir);
2673
- const outside = path.startsWith("..") || isAbsolute4(path);
2674
- return outside ? [root, examplesDir] : [root];
2675
- };
2676
- var GLOB_MAGIC = /[!*?[\]{}]/u;
2677
- var splitGlobBase = (pattern) => {
2678
- const segments = pattern.split("/");
2679
- const firstMagic = segments.findIndex((segment) => GLOB_MAGIC.test(segment));
2680
- return {
2681
- base: segments.slice(0, firstMagic).join("/"),
2682
- rest: segments.slice(firstMagic).join("/")
2683
- };
2684
- };
2685
- var discoverExamples = async (root, pattern = "examples") => {
2686
- const { base, rest } = GLOB_MAGIC.test(pattern) ? splitGlobBase(pattern) : { base: pattern, rest: DEFAULT_EXAMPLE_GLOB };
2687
- const dir = join10(root, base);
2688
- const matches = await glob([rest], {
2689
- absolute: true,
2690
- cwd: dir,
2691
- onlyFiles: true
2692
- });
2693
- const files = matches.toSorted();
2694
- const sources = await pMap(files, (file) => readFile3(file, "utf-8"), {
2695
- concurrency: READ_CONCURRENCY
2696
- });
2697
- const examples = [];
2698
- const warnings = [];
2699
- const seen = new Map;
2700
- const collectExample = (file, source) => {
2701
- const ext = file.match(EXAMPLE_FILE)?.groups?.ext;
2702
- const framework = ext ? FRAMEWORK_BY_EXT[ext] : undefined;
2703
- if (!(ext && framework)) {
2704
- return;
2705
- }
2706
- const path = relative3(dir, file).slice(0, -(ext.length + 1));
2707
- const existing = seen.get(path);
2708
- if (existing) {
2709
- warnings.push(`Two examples both resolve to "${path}" ("${existing}" and "${file}"); ignoring the second. Give them distinct paths.`);
2710
- return;
2711
- }
2712
- seen.set(path, file);
2713
- examples.push({
2714
- client: framework === "astro" ? undefined : readClientMode(source, file, warnings),
2715
- file,
2716
- framework,
2717
- lang: ext,
2718
- path,
2719
- source
2720
- });
2721
- };
2722
- for (const [index, file] of files.entries()) {
2723
- collectExample(file, sources[index] ?? "");
2724
- }
2725
- return { dir, examples, warnings };
2726
- };
2727
- var exampleMarkdownLookup = (examples) => Object.fromEntries(examples.map((example) => [
2728
- example.path,
2729
- { lang: example.lang, source: example.source }
2730
- ]));
2731
-
2732
2642
  // src/astro/render-deps.ts
2733
2643
  import { existsSync as existsSync5, realpathSync } from "node:fs";
2734
2644
  import {
2735
2645
  basename,
2736
2646
  dirname as dirname7,
2737
- isAbsolute as isAbsolute5,
2738
- join as join11,
2647
+ isAbsolute as isAbsolute4,
2648
+ join as join10,
2739
2649
  normalize,
2740
2650
  relative as relative4,
2741
2651
  resolve as resolve5
2742
2652
  } from "pathe";
2743
2653
  var depsCandidates = (pkgDir) => [
2744
- join11(pkgDir, "node_modules"),
2654
+ join10(pkgDir, "node_modules"),
2745
2655
  dirname7(pkgDir)
2746
2656
  ];
2747
- var candidateHolding = (pkgDir, ...segments) => depsCandidates(pkgDir).find((dir) => existsSync5(join11(dir, ...segments))) ?? null;
2657
+ var candidateHolding = (pkgDir, ...segments) => depsCandidates(pkgDir).find((dir) => existsSync5(join10(dir, ...segments))) ?? null;
2748
2658
  var packageDirFrom = (name, fromDir) => {
2749
2659
  let dir = normalize(fromDir);
2750
2660
  while (true) {
2751
- const candidate = join11(dir, "node_modules", name);
2752
- if (existsSync5(join11(candidate, "package.json"))) {
2661
+ const candidate = join10(dir, "node_modules", name);
2662
+ if (existsSync5(join10(candidate, "package.json"))) {
2753
2663
  return normalize(realpathSync(candidate));
2754
2664
  }
2755
2665
  const parent = dirname7(dir);
@@ -2761,23 +2671,26 @@ var packageDirFrom = (name, fromDir) => {
2761
2671
  };
2762
2672
 
2763
2673
  // src/astro/generate.ts
2764
- var BLUME_SRC = join12(packageRoot(), "src");
2674
+ var BLUME_SRC = join11(packageRoot(), "src");
2765
2675
  var resolveReactCompiler = (config, needsReact, pkgDir = packageRoot()) => {
2766
2676
  if (!(needsReact && config.react.compiler)) {
2767
- return null;
2677
+ return false;
2768
2678
  }
2769
2679
  try {
2770
- return createRequire2(pathToFileURL(join12(pkgDir, "_.js")).href).resolve("babel-plugin-react-compiler");
2680
+ const astroReact = createRequire2(pathToFileURL(join11(pkgDir, "_.js")).href).resolve("@astrojs/react");
2681
+ const pluginReact = createRequire2(astroReact).resolve("@vitejs/plugin-react");
2682
+ createRequire2(pluginReact).resolve("oxc-transform-react");
2683
+ return true;
2771
2684
  } catch {
2772
- return null;
2685
+ return false;
2773
2686
  }
2774
2687
  };
2775
- var reactCompilerWarnings = (config, needsReact, compilerPath) => needsReact && config.react.compiler && !compilerPath ? [
2776
- "React Compiler is enabled but `babel-plugin-react-compiler` could not be resolved; falling back to an uncompiled build. Reinstall Blume, or set `react: { compiler: false }` to silence this."
2688
+ var reactCompilerWarnings = (config, needsReact, compiler) => needsReact && config.react.compiler && !compiler ? [
2689
+ "React Compiler is enabled but `oxc-transform-react` could not be resolved; falling back to an uncompiled build. Reinstall Blume, or set `react: { compiler: false }` to silence this."
2777
2690
  ] : [];
2778
2691
  var resolveAstroPackageJson = (modulesDir) => {
2779
2692
  try {
2780
- return realpathSync2(join12(modulesDir, "astro", "package.json"));
2693
+ return realpathSync2(join11(modulesDir, "astro", "package.json"));
2781
2694
  } catch {
2782
2695
  return null;
2783
2696
  }
@@ -2785,7 +2698,7 @@ var resolveAstroPackageJson = (modulesDir) => {
2785
2698
  var resolvedAstroHit = (fromDir) => {
2786
2699
  let dir = normalize2(fromDir);
2787
2700
  while (true) {
2788
- const modulesDir = join12(dir, "node_modules");
2701
+ const modulesDir = join11(dir, "node_modules");
2789
2702
  const pkg = resolveAstroPackageJson(modulesDir);
2790
2703
  if (pkg) {
2791
2704
  return { modulesDir, pkg };
@@ -2862,7 +2775,7 @@ var dropStaleDepsLink = async (link, pkgDir) => {
2862
2775
  let linkedBlume;
2863
2776
  let runningBlume;
2864
2777
  try {
2865
- linkedBlume = await realpath(join12(link, "blume"));
2778
+ linkedBlume = await realpath(join11(link, "blume"));
2866
2779
  runningBlume = await realpath(pkgDir);
2867
2780
  } catch {
2868
2781
  return;
@@ -2878,7 +2791,7 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
2878
2791
  }
2879
2792
  const mdxDir = candidateHolding(pkgDir, "@astrojs", "mdx");
2880
2793
  const blumeAstro = resolveAstroPackageJson(astroDir);
2881
- await dropStaleDepsLink(join12(outDir, "node_modules"), pkgDir);
2794
+ await dropStaleDepsLink(join11(outDir, "node_modules"), pkgDir);
2882
2795
  const outDirHit = resolvedAstroHit(outDir);
2883
2796
  const astroCorrect = blumeAstro !== null && outDirHit?.pkg === blumeAstro;
2884
2797
  const walkLandsInDeps = astroCorrect && outDirHit !== null && sameRealDir(outDirHit.modulesDir, astroDir);
@@ -2886,16 +2799,16 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
2886
2799
  return null;
2887
2800
  }
2888
2801
  if (mdxDir && (mdxDir === astroDir || astroCorrect)) {
2889
- await linkDepsJunction(join12(outDir, "node_modules"), mdxDir);
2802
+ await linkDepsJunction(join11(outDir, "node_modules"), mdxDir);
2890
2803
  return null;
2891
2804
  }
2892
2805
  return astroConflictWarning(blumeAstro, outDirHit?.pkg ?? null);
2893
2806
  };
2894
- var examplesCssFile = (root, config) => config.examples.css ? join12(root, config.examples.css) : null;
2807
+ var examplesCssFile = (root, config) => config.examples.css ? join11(root, config.examples.css) : null;
2895
2808
  var writeExamplesPreview = async (options) => {
2896
2809
  const { config, hasExamples, root, srcDir, write } = options;
2897
2810
  if (hasExamples) {
2898
- await write(join12(srcDir, "pages", ...config.basePath.split("/").filter(Boolean), "blume-examples", "[...path].astro"), examplesPageTemplate());
2811
+ await write(join11(srcDir, "pages", ...config.basePath.split("/").filter(Boolean), "blume-examples", "[...path].astro"), examplesPageTemplate());
2899
2812
  }
2900
2813
  const cssFile = examplesCssFile(root, config);
2901
2814
  return cssFile && !existsSync6(cssFile) ? [
@@ -2907,7 +2820,7 @@ var readOptional = async (path) => {
2907
2820
  return "";
2908
2821
  }
2909
2822
  try {
2910
- return await readFile4(path, "utf-8");
2823
+ return await readFile3(path, "utf-8");
2911
2824
  } catch {
2912
2825
  return "";
2913
2826
  }
@@ -2917,7 +2830,7 @@ var readUserCss = async (file, outputDir) => {
2917
2830
  return file ? rebaseSourceDirectives(css, { from: file, to: outputDir }) : css;
2918
2831
  };
2919
2832
  var detectNeedsReact = async (root) => {
2920
- const matches = await glob2(["**/*.{tsx,jsx}"], {
2833
+ const matches = await glob(["**/*.{tsx,jsx}"], {
2921
2834
  cwd: root,
2922
2835
  ignore: ["**/node_modules/**", "**/.blume/**", "**/dist/**"],
2923
2836
  onlyFiles: true
@@ -2925,15 +2838,15 @@ var detectNeedsReact = async (root) => {
2925
2838
  return matches.length > 0;
2926
2839
  };
2927
2840
  var containsMath = (content) => content.includes("$$") || content.includes("<Math");
2928
- var READ_CONCURRENCY2 = 16;
2841
+ var READ_CONCURRENCY = 16;
2929
2842
  var detectUsesMath = async (root, staged = []) => {
2930
- const files = await glob2(["**/*.{md,mdx}"], {
2843
+ const files = await glob(["**/*.{md,mdx}"], {
2931
2844
  cwd: root,
2932
2845
  ignore: ["**/node_modules/**", "**/.blume/**", "**/dist/**"],
2933
2846
  onlyFiles: true
2934
2847
  });
2935
- const contents = await pMap2(files, (file) => readOptional(join12(root, file)), {
2936
- concurrency: READ_CONCURRENCY2
2848
+ const contents = await pMap(files, (file) => readOptional(join11(root, file)), {
2849
+ concurrency: READ_CONCURRENCY
2937
2850
  });
2938
2851
  return [...contents, ...staged].some(containsMath);
2939
2852
  };
@@ -2950,7 +2863,7 @@ var loadIntegrationBridge = async (config, context) => {
2950
2863
  var writeIfChanged = async (path, content) => {
2951
2864
  let existing = null;
2952
2865
  try {
2953
- existing = await readFile4(path, "utf-8");
2866
+ existing = await readFile3(path, "utf-8");
2954
2867
  } catch {
2955
2868
  existing = null;
2956
2869
  }
@@ -2961,7 +2874,7 @@ var writeIfChanged = async (path, content) => {
2961
2874
  return true;
2962
2875
  };
2963
2876
  var pruneOrphans = async (srcDir, written) => {
2964
- const existing = await glob2("**/*", {
2877
+ const existing = await glob("**/*", {
2965
2878
  absolute: true,
2966
2879
  cwd: srcDir,
2967
2880
  onlyFiles: true
@@ -2994,7 +2907,7 @@ var writeStagedContent = async (out, staged) => {
2994
2907
  const contentDir = stagedContentDir(out);
2995
2908
  const written = new Set;
2996
2909
  await Promise.all([...staged].map(async ([entryId, text]) => {
2997
- const path = join12(contentDir, entryId);
2910
+ const path = join11(contentDir, entryId);
2998
2911
  written.add(normalize2(path));
2999
2912
  await writeIfChanged(path, text);
3000
2913
  }));
@@ -3009,8 +2922,8 @@ var readLogoSvg = (project, source) => {
3009
2922
  }
3010
2923
  const rel = source.replace(/^\//u, "");
3011
2924
  const file = [
3012
- join12(project.context.root, "public", rel),
3013
- join12(project.context.root, rel)
2925
+ join11(project.context.root, "public", rel),
2926
+ join11(project.context.root, rel)
3014
2927
  ].find((path) => existsSync6(path));
3015
2928
  return file ? readFileSync3(file, "utf-8") : undefined;
3016
2929
  };
@@ -3066,10 +2979,10 @@ var faviconType = (name) => {
3066
2979
  var inlineDataUri = (file, type) => `data:${type};base64,${readFileSync3(file).toString("base64")}`;
3067
2980
  var defaultFavicon = () => ({
3068
2981
  dark: {
3069
- href: inlineDataUri(join12(BLUME_SRC, "assets", "icon-dark.png"), "image/png"),
2982
+ href: inlineDataUri(join11(BLUME_SRC, "assets", "icon-dark.png"), "image/png"),
3070
2983
  type: "image/png"
3071
2984
  },
3072
- href: inlineDataUri(join12(BLUME_SRC, "assets", "icon.png"), "image/png"),
2985
+ href: inlineDataUri(join11(BLUME_SRC, "assets", "icon.png"), "image/png"),
3073
2986
  type: "image/png"
3074
2987
  });
3075
2988
  var APPLE_ICON_CANDIDATES = [
@@ -3081,12 +2994,12 @@ var APPLE_ICON_CANDIDATES = [
3081
2994
  var resolveIconFile = (project, candidates) => {
3082
2995
  const { root } = project.context;
3083
2996
  for (const name of candidates) {
3084
- if (existsSync6(join12(root, "public", name))) {
2997
+ if (existsSync6(join11(root, "public", name))) {
3085
2998
  return { href: `/${name}`, type: faviconType(name) };
3086
2999
  }
3087
3000
  }
3088
3001
  for (const name of candidates) {
3089
- const file = join12(root, name);
3002
+ const file = join11(root, name);
3090
3003
  if (existsSync6(file)) {
3091
3004
  const type = faviconType(name);
3092
3005
  return { href: inlineDataUri(file, type ?? "image/x-icon"), type };
@@ -3097,18 +3010,18 @@ var resolveIconFile = (project, candidates) => {
3097
3010
  var resolveFavicon = (project) => {
3098
3011
  const { root } = project.context;
3099
3012
  for (const name of FAVICON_CANDIDATES) {
3100
- if (existsSync6(join12(root, "public", name))) {
3013
+ if (existsSync6(join11(root, "public", name))) {
3101
3014
  const type = faviconType(name);
3102
3015
  const sibling = darkSibling(name);
3103
- return existsSync6(join12(root, "public", sibling)) ? { dark: { href: `/${sibling}`, type }, href: `/${name}`, type } : { href: `/${name}`, type };
3016
+ return existsSync6(join11(root, "public", sibling)) ? { dark: { href: `/${sibling}`, type }, href: `/${name}`, type } : { href: `/${name}`, type };
3104
3017
  }
3105
3018
  }
3106
3019
  for (const name of FAVICON_CANDIDATES) {
3107
- const file = join12(root, name);
3020
+ const file = join11(root, name);
3108
3021
  if (existsSync6(file)) {
3109
3022
  const type = faviconType(name);
3110
3023
  const mime = type ?? "image/x-icon";
3111
- const siblingFile = join12(root, darkSibling(name));
3024
+ const siblingFile = join11(root, darkSibling(name));
3112
3025
  return existsSync6(siblingFile) ? {
3113
3026
  dark: { href: inlineDataUri(siblingFile, mime), type },
3114
3027
  href: inlineDataUri(file, mime),
@@ -3213,8 +3126,8 @@ var buildRuntimeData = (project) => {
3213
3126
  }
3214
3127
  const rel = relative5(context.root, sourcePath).split("\\").join("/");
3215
3128
  const editDir = trimChar(github?.dir ?? "", "/");
3216
- const editPath = normalize2(editDir ? join12(editDir, rel) : rel);
3217
- if (editPath.startsWith("..") || isAbsolute6(editPath)) {
3129
+ const editPath = normalize2(editDir ? join11(editDir, rel) : rel);
3130
+ if (editPath.startsWith("..") || isAbsolute5(editPath)) {
3218
3131
  return null;
3219
3132
  }
3220
3133
  return `${editBase}/${editPath}`;
@@ -3227,15 +3140,15 @@ var buildRuntimeData = (project) => {
3227
3140
  });
3228
3141
  const uiByLocale = i18n ? Object.fromEntries(i18n.locales.map(({ code }) => [
3229
3142
  code,
3230
- resolveUIStrings(code, {
3143
+ withChangelogIndexText(config, resolveUIStrings(code, {
3231
3144
  defaultLocale: i18n.defaultLocale,
3232
3145
  overrides: i18n.ui
3233
- })
3146
+ }), code)
3234
3147
  ])) : {};
3235
- const defaultUi = i18n ? resolveUIStrings(i18n.defaultLocale, {
3148
+ const defaultUi = withChangelogIndexText(config, i18n ? resolveUIStrings(i18n.defaultLocale, {
3236
3149
  defaultLocale: i18n.defaultLocale,
3237
3150
  overrides: i18n.ui
3238
- }) : EN_UI;
3151
+ }) : EN_UI, i18n?.defaultLocale);
3239
3152
  const navigationByLocale = i18n ? Object.fromEntries(i18n.locales.map(({ code }) => [
3240
3153
  code,
3241
3154
  withRepoUrl(graph.navigationByLocale[code] ?? {
@@ -3305,6 +3218,7 @@ var buildRuntimeData = (project) => {
3305
3218
  openInChat: config.ai.openInChat,
3306
3219
  repoUrl: repoUrl2,
3307
3220
  search: {
3221
+ analytics: config.search.analytics,
3308
3222
  enabled: config.search.provider.mode !== "none",
3309
3223
  popular: resolveSearchPopular(config.search.popular, config.basePath),
3310
3224
  provider: config.search.provider.kind
@@ -3363,7 +3277,7 @@ var buildRuntimeData = (project) => {
3363
3277
  var planMcp = (project, srcDir, userPages) => {
3364
3278
  const { config } = project;
3365
3279
  const { route } = config.agents.mcp;
3366
- const dir = join12(srcDir, "blume-mcp");
3280
+ const dir = join11(srcDir, "blume-mcp");
3367
3281
  const base = {
3368
3282
  dir,
3369
3283
  discoveryPages: [],
@@ -3387,11 +3301,11 @@ var planMcp = (project, srcDir, userPages) => {
3387
3301
  ...base,
3388
3302
  discoveryPages: [
3389
3303
  {
3390
- entrypoint: join12(dir, "discovery.ts"),
3304
+ entrypoint: join11(dir, "discovery.ts"),
3391
3305
  pattern: "/.well-known/mcp.json"
3392
3306
  },
3393
3307
  {
3394
- entrypoint: join12(dir, "server-card.ts"),
3308
+ entrypoint: join11(dir, "server-card.ts"),
3395
3309
  pattern: "/.well-known/mcp/server-card.json"
3396
3310
  }
3397
3311
  ],
@@ -3418,9 +3332,9 @@ var writeMcpFiles = async (plan, write, data) => {
3418
3332
  version: data.version
3419
3333
  };
3420
3334
  await Promise.all([
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)))
3335
+ write(join11(plan.srcDir, "pages", mcpPageFile(plan.route)), mcpEndpointTemplate()),
3336
+ write(join11(plan.dir, "discovery.ts"), staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput))),
3337
+ write(join11(plan.dir, "server-card.ts"), staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput)))
3424
3338
  ]);
3425
3339
  };
3426
3340
  var ownsApiRest = (page) => page.pattern.startsWith("/api/[");
@@ -3432,7 +3346,7 @@ var planApi = (project, srcDir, userPages) => {
3432
3346
  catchAll: server && !userPages.some(ownsApiRest) && !project.graph.pages.some(contentUnderApi),
3433
3347
  enabled: config.agents.api,
3434
3348
  server,
3435
- spec: !routeIsTaken(userPages, project.graph.pages, OPENAPI_PATH) && !existsSync6(join12(context.root, "public", "openapi.json")),
3349
+ spec: !routeIsTaken(userPages, project.graph.pages, OPENAPI_PATH) && !existsSync6(join11(context.root, "public", "openapi.json")),
3436
3350
  srcDir
3437
3351
  };
3438
3352
  };
@@ -3442,20 +3356,20 @@ var writeApiFiles = async (project, plan, write, data, mcp) => {
3442
3356
  }
3443
3357
  const { config } = project;
3444
3358
  const mcpRoute = mcp.enabled ? mcp.route : null;
3445
- const apiDir = join12(plan.srcDir, "pages", "api");
3359
+ const apiDir = join11(plan.srcDir, "pages", "api");
3446
3360
  const writes = [
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())
3361
+ write(join11(apiDir, "docs", "pages.json.ts"), apiPagesIndexTemplate()),
3362
+ write(join11(apiDir, "docs", "pages", "[...route].json.ts"), apiPageTemplate()),
3363
+ write(join11(apiDir, "docs", "navigation.json.ts"), apiNavigationTemplate())
3450
3364
  ];
3451
3365
  if (plan.server) {
3452
- writes.push(write(join12(apiDir, "docs", "search.ts"), apiSearchTemplate()));
3366
+ writes.push(write(join11(apiDir, "docs", "search.ts"), apiSearchTemplate()));
3453
3367
  }
3454
3368
  if (plan.catchAll) {
3455
- writes.push(write(join12(apiDir, "[...path].ts"), apiNotFoundTemplate({ base: data.base, site: data.site })));
3369
+ writes.push(write(join11(apiDir, "[...path].ts"), apiNotFoundTemplate({ base: data.base, site: data.site })));
3456
3370
  }
3457
3371
  if (plan.spec) {
3458
- writes.push(write(join12(plan.srcDir, "pages", "openapi.json.ts"), staticJsonEndpointTemplate(buildApiSpec({
3372
+ writes.push(write(join11(plan.srcDir, "pages", "openapi.json.ts"), staticJsonEndpointTemplate(buildApiSpec({
3459
3373
  agentReadability: config.agents.agentReadability,
3460
3374
  base: data.base,
3461
3375
  description: config.description,
@@ -3469,10 +3383,10 @@ var writeApiFiles = async (project, plan, write, data, mcp) => {
3469
3383
  }
3470
3384
  await Promise.all(writes);
3471
3385
  };
3472
- var PLAYGROUND_PROXY_ENTRY = join12("blume-openapi", "api-proxy.ts");
3386
+ var PLAYGROUND_PROXY_ENTRY = join11("blume-openapi", "api-proxy.ts");
3473
3387
  var planPlaygroundProxy = (config, srcDir) => ({
3474
3388
  enabled: needsPlaygroundProxy(config),
3475
- entrypoint: join12(srcDir, PLAYGROUND_PROXY_ENTRY),
3389
+ entrypoint: join11(srcDir, PLAYGROUND_PROXY_ENTRY),
3476
3390
  pattern: playgroundProxyPattern(config)
3477
3391
  });
3478
3392
  var specOriginsOf = (spec) => {
@@ -3545,7 +3459,7 @@ var writeAskFiles = async (project, srcDir, write, modules) => {
3545
3459
  if (backend.grounded) {
3546
3460
  modules.set("blume:ask-data", JSON.stringify(await buildAskData(project)));
3547
3461
  }
3548
- await write(join12(srcDir, "pages", "api", "ask.ts"), askEndpointTemplate(backend, {
3462
+ await write(join11(srcDir, "pages", "api", "ask.ts"), askEndpointTemplate(backend, {
3549
3463
  captcha: assistant.captcha,
3550
3464
  cors: assistant.cors,
3551
3465
  instructions: assistant.instructions,
@@ -3559,15 +3473,16 @@ var writeNotFoundPage = async (write, srcDir, pages, contentPages) => {
3559
3473
  return;
3560
3474
  }
3561
3475
  await Promise.all([
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())
3476
+ write(join11(srcDir, "pages", "404.astro"), notFoundPageTemplate()),
3477
+ write(join11(srcDir, "pages", "404.md.ts"), notFoundMarkdownTemplate()),
3478
+ write(join11(srcDir, "pages", "404.json.ts"), notFoundJsonTemplate())
3565
3479
  ]);
3566
3480
  };
3567
3481
  var diagnosticWarning = (diagnostic) => diagnostic.suggestion ? `${diagnostic.message} ${diagnostic.suggestion}` : diagnostic.message;
3568
3482
  var dependencyPreflight = async (project, frameworks) => {
3569
3483
  const build = project.mode === "build";
3570
- const diagnostic = await missingDependencyDiagnostic(project.config, project.context.root, build ? "error" : "warning", frameworks);
3484
+ const { config } = project;
3485
+ const diagnostic = await missingDependencyDiagnostic(build ? config : { ...config, narration: { ...config.narration, provider: null } }, project.context.root, build ? "error" : "warning", frameworks);
3571
3486
  if (!diagnostic) {
3572
3487
  return [];
3573
3488
  }
@@ -3576,7 +3491,7 @@ var dependencyPreflight = async (project, frameworks) => {
3576
3491
  }
3577
3492
  return [diagnosticWarning(diagnostic)];
3578
3493
  };
3579
- var analyzeComponentsFile = async (componentsFile) => componentsFile ? analyzeComponentOverrides(await readFile4(componentsFile, "utf-8"), componentsFile) : emptyComponentOverrides();
3494
+ var analyzeComponentsFile = async (componentsFile) => componentsFile ? analyzeComponentOverrides(await readFile3(componentsFile, "utf-8"), componentsFile) : emptyComponentOverrides();
3580
3495
  var projectOgFonts = (project) => resolveOgFonts({
3581
3496
  locales: fontLocaleCodes(project.config.i18n),
3582
3497
  ogFonts: project.config.seo.og.fonts,
@@ -3604,21 +3519,21 @@ var languageIconCssFrom = (project, rawMarkdown) => languageIconCss(languageIcon
3604
3519
  ].join(`
3605
3520
  `)));
3606
3521
  var languageIconCssFor = async (project) => languageIconCssFrom(project, await buildRawMarkdown(project));
3607
- var writeNavFragments = (write, srcDir, navFragments) => navFragments ? write(join12(srcDir, "pages", "blume-nav", "[version]", "[locale]", "[id].astro"), navFragmentTemplate()) : Promise.resolve(false);
3522
+ var writeNavFragments = (write, srcDir, navFragments) => navFragments ? write(join11(srcDir, "pages", "blume-nav", "[version]", "[locale]", "[id].astro"), navFragmentTemplate()) : Promise.resolve(false);
3608
3523
  var clientFeaturesFor = async (project) => clientFeaturesFrom(project, await buildRawMarkdown(project));
3609
3524
  var generateRuntime = async (project) => {
3610
3525
  const { context, config } = project;
3611
3526
  assertFontFilesExist(project);
3612
3527
  const out = context.outDir;
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");
3528
+ const srcDir = join11(out, "src");
3529
+ const generatedDir = join11(srcDir, "generated");
3530
+ const askPath = join11(srcDir, "generated", "Ask.astro");
3531
+ const themePath = join11(srcDir, "generated", "app.css");
3532
+ const searchClientPath = join11(srcDir, "generated", "search-client.ts");
3533
+ const consentClientPath = join11(srcDir, "generated", "consent-client.ts");
3534
+ const featuresPath = join11(srcDir, "generated", "features.ts");
3535
+ const examplesPath = join11(srcDir, "generated", "examples.ts");
3536
+ const examplesThemePath = join11(srcDir, "generated", "examples.css");
3622
3537
  const written = new Set;
3623
3538
  const write = (path, content) => {
3624
3539
  written.add(normalize2(path));
@@ -3669,7 +3584,7 @@ var generateRuntime = async (project) => {
3669
3584
  const needsReact = detectedReact || assistantEnabled || frameworks.has("react");
3670
3585
  const needsVue = frameworks.has("vue");
3671
3586
  const needsSvelte = frameworks.has("svelte");
3672
- const reactCompilerPath = resolveReactCompiler(config, needsReact);
3587
+ const reactCompiler = resolveReactCompiler(config, needsReact);
3673
3588
  const ogRoutes = customOgRoutes(pages, config.title, config.seo.og.titles);
3674
3589
  const changelogIndex = hasGeneratedChangelog(project, pages);
3675
3590
  const mcp = planMcp(project, srcDir, pages);
@@ -3693,7 +3608,7 @@ var generateRuntime = async (project) => {
3693
3608
  const docsCollection = resolveDocsCollection(config, context.root);
3694
3609
  const [structural] = await Promise.all([
3695
3610
  Promise.all([
3696
- write(join12(out, "astro.config.mjs"), astroConfigTemplate({
3611
+ write(join11(out, "astro.config.mjs"), astroConfigTemplate({
3697
3612
  aliases: resolveTsconfigAliases(context.root),
3698
3613
  askPath,
3699
3614
  config,
@@ -3710,20 +3625,20 @@ var generateRuntime = async (project) => {
3710
3625
  needsSvelte,
3711
3626
  needsVue,
3712
3627
  pages,
3713
- reactCompilerPath,
3628
+ reactCompiler,
3714
3629
  searchClientPath,
3715
3630
  themePath
3716
3631
  })),
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({
3632
+ write(join11(out, "package.json"), runtimePackageTemplate(runtimeDependencies({ config, needsReact, needsSvelte, needsVue }))),
3633
+ write(join11(out, "tsconfig.json"), runtimeTsconfigTemplate()),
3634
+ write(join11(srcDir, "content.config.ts"), contentConfigTemplate({
3720
3635
  collection: docsCollection,
3721
3636
  config,
3722
3637
  context,
3723
3638
  filesystem: hasFilesystemSource,
3724
3639
  staged: hasStaged
3725
3640
  })),
3726
- write(join12(srcDir, "pages", "[...slug].astro"), catchAllPageTemplate({
3641
+ write(join11(srcDir, "pages", "[...slug].astro"), catchAllPageTemplate({
3727
3642
  exportEpub,
3728
3643
  exportPdf,
3729
3644
  mathEnabled: usesMath,
@@ -3732,8 +3647,8 @@ var generateRuntime = async (project) => {
3732
3647
  })),
3733
3648
  writeNavFragments(write, srcDir, navFragments),
3734
3649
  write(askPath, askComponentTemplate(assistantEnabled)),
3735
- write(join12(srcDir, "generated", "components.ts"), slotPlan.module),
3736
- write(join12(srcDir, "generated", "examples.ts"), exampleMapTemplate(exampleDiscovery.examples, config.basePath)),
3650
+ write(join11(srcDir, "generated", "components.ts"), slotPlan.module),
3651
+ write(join11(srcDir, "generated", "examples.ts"), exampleMapTemplate(exampleDiscovery.examples, config.basePath)),
3737
3652
  write(examplesThemePath, examplesEntryTemplate({
3738
3653
  configTokens: buildThemeCss(config.theme),
3739
3654
  sources: exampleScanRoots(context.root, exampleDiscovery.dir).map((dir) => `${dir}/${EXAMPLE_SCAN_GLOB}`),
@@ -3744,21 +3659,21 @@ var generateRuntime = async (project) => {
3744
3659
  languageIcons,
3745
3660
  sources: [
3746
3661
  `${BLUME_SRC}/**/*.{astro,ts,tsx}`,
3747
- `${context.root}/**/*.{astro,mdx,ts,tsx}`
3662
+ `${context.root}/**/*.{astro,jsx,mdx,ts,tsx}`
3748
3663
  ],
3749
3664
  twoslashCss: twoslashCss(),
3750
3665
  userTheme
3751
3666
  }))
3752
3667
  ]),
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)))),
3668
+ Promise.all(slotPlan.wrappers.map((wrapper) => write(join11(srcDir, "generated", "component-slots", `${wrapper.name}.astro`), wrapper.content))),
3669
+ Promise.all(exampleDiscovery.examples.map((example) => write(join11(srcDir, "generated", "examples", `${exampleSlug(example.path)}.astro`), exampleWrapperTemplate(example)))),
3755
3670
  writeAskFiles(project, srcDir, write, modules),
3756
3671
  writeMcpFiles(mcp, write, agentData),
3757
3672
  writeApiFiles(project, api, write, agentData, mcp),
3758
- playgroundProxy.enabled ? write(playgroundProxy.entrypoint, playgroundProxyTemplate(proxyOrigins)) : Promise.resolve(false)
3673
+ playgroundProxy.enabled ? write(playgroundProxy.entrypoint, playgroundProxyTemplate(proxyOrigins, config.rateLimit)) : Promise.resolve(false)
3759
3674
  ]);
3760
3675
  if (config.seo.og.enabled) {
3761
- await write(join12(srcDir, "pages", "og", "[...slug].png.ts"), ogEndpointTemplate(ogRoutes, {
3676
+ await write(join11(srcDir, "pages", "og", "[...slug].png.ts"), ogEndpointTemplate(ogRoutes, {
3762
3677
  ...projectOgFonts(project),
3763
3678
  cache: {
3764
3679
  dir: ogCacheDir(project.context),
@@ -3768,7 +3683,7 @@ var generateRuntime = async (project) => {
3768
3683
  }, changelogIndex));
3769
3684
  }
3770
3685
  if (changelogIndex) {
3771
- await write(join12(srcDir, "pages", "changelog.astro"), changelogIndexTemplate({
3686
+ await write(join11(srcDir, "pages", "changelog.astro"), changelogIndexTemplate({
3772
3687
  exportEpub,
3773
3688
  exportPdf,
3774
3689
  needsReact,
@@ -3792,55 +3707,47 @@ var generateRuntime = async (project) => {
3792
3707
  if (searchAdapter.mode === "static") {
3793
3708
  const documents = await buildSearchDocuments(project);
3794
3709
  modules.set("blume:search-index", JSON.stringify(documents));
3795
- await write(join12(srcDir, "pages", "blume-search.json.ts"), searchEndpointTemplate());
3710
+ await write(join11(srcDir, "pages", "blume-search.json.ts"), searchEndpointTemplate());
3796
3711
  }
3797
3712
  if (searchAdapter.kind === "mixedbread") {
3798
- await write(join12(srcDir, "pages", "api", "search.ts"), mixedbreadSearchEndpointTemplate(searchAdapter.options));
3713
+ await write(join11(srcDir, "pages", "api", "search.ts"), mixedbreadSearchEndpointTemplate(searchAdapter.options, sourcePages(project), config.rateLimit));
3799
3714
  }
3800
- await write(join12(srcDir, "generated", "includes.json"), `${JSON.stringify(buildIncludeGraph(project.graph.pages))}
3715
+ await write(join11(srcDir, "generated", "includes.json"), `${JSON.stringify(buildIncludeGraph(project.graph.pages))}
3801
3716
  `);
3802
3717
  modules.set("blume:raw-markdown", JSON.stringify(rawMarkdown));
3803
3718
  const contentAssets = await collectContentAssets(project);
3804
3719
  modules.set("blume:content-assets", JSON.stringify(contentAssets));
3805
3720
  await Promise.all([
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")))
3721
+ write(join11(srcDir, "pages", "[...slug].md.ts"), rawMarkdownEndpointTemplate("md")),
3722
+ write(join11(srcDir, "pages", "[...slug].mdx.ts"), rawMarkdownEndpointTemplate("mdx")),
3723
+ write(join11(srcDir, "pages", "blume-assets", "[...asset].ts"), contentAssetsEndpointTemplate(join11(project.context.outDir, "public", "blume-assets")))
3809
3724
  ]);
3810
3725
  const feeds = buildRssFeeds(project);
3811
3726
  if (feeds.length > 0) {
3812
3727
  const feedXml = Object.fromEntries(feeds.map((feed) => [feed.type, renderRssFeed(feed)]));
3813
3728
  modules.set("blume:rss", JSON.stringify(feedXml));
3814
- await write(join12(srcDir, "pages", "[section]", "rss.xml.ts"), rssEndpointTemplate());
3729
+ await write(join11(srcDir, "pages", "[section]", "rss.xml.ts"), rssEndpointTemplate());
3815
3730
  }
3816
3731
  const warnings = [
3817
3732
  ...depsLinkWarning ? [depsLinkWarning] : [],
3818
3733
  ...proxyAllowlistWarnings(config, openApiData),
3819
3734
  ...apiPageProxyWarnings(project),
3820
- ...reactCompilerWarnings(config, needsReact, reactCompilerPath),
3735
+ ...reactCompilerWarnings(config, needsReact, reactCompiler),
3821
3736
  ...mcp.warnings,
3822
3737
  ...islandDiscovery.warnings,
3823
3738
  ...exampleDiscovery.warnings,
3824
3739
  ...examplesWarnings,
3825
3740
  ...overrideWarnings
3826
3741
  ];
3827
- const navTargetRoutes = new Set([
3828
- ...project.graph.routes.keys(),
3829
- ...pages.map((page) => page.pattern),
3830
- ...referenceRoutes(config)
3831
- ]);
3832
- if (changelogIndex) {
3833
- navTargetRoutes.add("/changelog");
3834
- }
3835
3742
  warnings.push(...[
3836
- ...validateNavTargets(project.graph.navigation, navTargetRoutes),
3743
+ ...validateNavTargets(project.graph.navigation, navTargetRoutes(project, pages)),
3837
3744
  ...validateSearchPopularIcons(config.search.popular)
3838
3745
  ].map(diagnosticWarning));
3839
3746
  const knownComponentTags = new Set([
3840
3747
  ...islandDiscovery.islands.map((island) => island.name),
3841
3748
  ...overrideAnalysis.mdx.map((entry) => entry.key)
3842
3749
  ]);
3843
- warnings.push(...validateUsedComponents(project.graph.pages, knownComponentTags, new Set(registry.map((item) => item.name))).map(diagnosticWarning), ...dependencyWarnings);
3750
+ warnings.push(...validateUsedComponents(project.graph.pages, knownComponentTags, new Set(registry.map((item) => item.name))).map(diagnosticWarning), ...missingExampleDiagnostics(project.graph.pages, exampleDiscovery, context.root, knownComponentTags).map(diagnosticWarning), ...dependencyWarnings);
3844
3751
  if (hasScalarReferences(config)) {
3845
3752
  const references = await buildReferenceFiles({
3846
3753
  config,
@@ -3848,12 +3755,12 @@ var generateRuntime = async (project) => {
3848
3755
  root: context.root
3849
3756
  });
3850
3757
  warnings.push(...references.warnings);
3851
- await Promise.all(references.files.map((file) => write(join12(srcDir, "pages", file.pagePath), file.content)));
3758
+ await Promise.all(references.files.map((file) => write(join11(srcDir, "pages", file.pagePath), file.content)));
3852
3759
  }
3853
3760
  modules.set("blume:data", buildRuntimeData(project));
3854
3761
  modules.set("blume:openapi", JSON.stringify(openApiData));
3855
3762
  await Promise.all([
3856
- write(join12(out, "blume.manifest.json"), `${JSON.stringify(project.manifest, null, 2)}
3763
+ write(join11(out, "blume.manifest.json"), `${JSON.stringify(project.manifest, null, 2)}
3857
3764
  `),
3858
3765
  writeStagedContent(out, staged)
3859
3766
  ]);
@@ -3863,7 +3770,7 @@ var generateRuntime = async (project) => {
3863
3770
  return { structuralChange: structural.some(Boolean), warnings };
3864
3771
  };
3865
3772
 
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 };
3773
+ export { publishBuildProject, refreshBlumeContent, showBlumeErrorOverlay, ogCacheDir, pruneCardCache, cardCacheTally, buildApiSpec, buildAskData, resolveOgFonts, buildReferenceFiles, sourcePages, tailwindEntryTemplate, examplesEntryTemplate, rebaseSourceDirectives, twoslashCss, packageDirFrom, detectNeedsReact, detectUsesMath, collectStaged, playgroundProxyPattern, buildRuntimeData, PLAYGROUND_PROXY_ENTRY, specOrigins, proxyAllowlistWarnings, analyzeComponentsFile, languageIconCssFor, clientFeaturesFor, generateRuntime };
3867
3774
 
3868
- //# debugId=168B822A64F4126564756E2164756E21
3869
- //# sourceMappingURL=chunk-zf748avv.js.map
3775
+ //# debugId=02FADD64003B143964756E2164756E21
3776
+ //# sourceMappingURL=chunk-nbyvgnnm.js.map