blume 2.1.0 → 2.1.1

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 (397) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/dist/cli/{chunk-5cg2rzgf.js → chunk-073rdvgb.js} +19 -48
  3. package/dist/cli/{chunk-5cg2rzgf.js.map → chunk-073rdvgb.js.map} +4 -5
  4. package/dist/cli/{chunk-ga0pf4aj.js → chunk-0n9xkp3d.js} +12 -3
  5. package/dist/cli/{chunk-ga0pf4aj.js.map → chunk-0n9xkp3d.js.map} +3 -3
  6. package/dist/cli/chunk-150jk7km.js +52 -0
  7. package/dist/cli/chunk-150jk7km.js.map +10 -0
  8. package/dist/cli/{chunk-rekqz4qg.js → chunk-313vnn40.js} +16 -15
  9. package/dist/cli/chunk-313vnn40.js.map +10 -0
  10. package/dist/cli/{chunk-gp84za0h.js → chunk-3v3ffbrj.js} +2 -2
  11. package/dist/cli/{chunk-9xr4dgee.js → chunk-3x6x3pph.js} +29 -16
  12. package/dist/cli/chunk-3x6x3pph.js.map +10 -0
  13. package/dist/cli/{chunk-0gz36akr.js → chunk-42t4jxdx.js} +21 -5
  14. package/dist/cli/chunk-42t4jxdx.js.map +12 -0
  15. package/dist/cli/{chunk-ta27feev.js → chunk-54ztw1nj.js} +21 -2
  16. package/dist/cli/chunk-54ztw1nj.js.map +10 -0
  17. package/dist/cli/{chunk-jnwj5kjj.js → chunk-5vjtgs6e.js} +20 -7
  18. package/dist/cli/{chunk-jnwj5kjj.js.map → chunk-5vjtgs6e.js.map} +3 -3
  19. package/dist/cli/chunk-66w9j7p6.js +322 -0
  20. package/dist/cli/chunk-66w9j7p6.js.map +14 -0
  21. package/dist/cli/{chunk-nd1821sk.js → chunk-7ppf1rva.js} +32 -18
  22. package/dist/cli/chunk-7ppf1rva.js.map +10 -0
  23. package/dist/cli/{chunk-p804f3pe.js → chunk-8y2kmjv8.js} +6 -6
  24. package/dist/cli/{chunk-2f7n4qzt.js → chunk-c1y538kd.js} +1 -1
  25. package/dist/cli/{chunk-1n228xqb.js → chunk-c887fj0s.js} +2 -2
  26. package/dist/cli/{chunk-y5h4r2y0.js → chunk-cfyg47zg.js} +15 -5
  27. package/dist/cli/chunk-cfyg47zg.js.map +10 -0
  28. package/dist/cli/{chunk-cmtcnh9f.js → chunk-dzwehpy7.js} +2 -2
  29. package/dist/cli/{chunk-h2a48yhd.js → chunk-e6atmn4h.js} +119 -15
  30. package/dist/cli/{chunk-h2a48yhd.js.map → chunk-e6atmn4h.js.map} +10 -10
  31. package/dist/cli/{chunk-5ffywsmb.js → chunk-e8xw9qkh.js} +8 -6
  32. package/dist/cli/{chunk-5ffywsmb.js.map → chunk-e8xw9qkh.js.map} +3 -3
  33. package/dist/cli/{chunk-ntv4qrt7.js → chunk-e9q7a2ak.js} +14 -14
  34. package/dist/cli/{chunk-xkz5xbtv.js → chunk-ehweg4fr.js} +2366 -1114
  35. package/dist/cli/chunk-ehweg4fr.js.map +218 -0
  36. package/dist/cli/{chunk-zf748avv.js → chunk-ep6nd0rn.js} +176 -281
  37. package/dist/cli/{chunk-zf748avv.js.map → chunk-ep6nd0rn.js.map} +11 -12
  38. package/dist/cli/{chunk-yxmk4pec.js → chunk-fdrkhpjy.js} +16 -15
  39. package/dist/cli/{chunk-yxmk4pec.js.map → chunk-fdrkhpjy.js.map} +3 -3
  40. package/dist/cli/{chunk-5wj2qwn2.js → chunk-ft9vfys6.js} +4 -4
  41. package/dist/cli/{chunk-4h8z9vv5.js → chunk-gb420vvz.js} +89 -46
  42. package/dist/cli/chunk-gb420vvz.js.map +17 -0
  43. package/dist/cli/{chunk-713mngdq.js → chunk-hebn0tpx.js} +76 -10
  44. package/dist/cli/chunk-hebn0tpx.js.map +14 -0
  45. package/dist/cli/{chunk-2n4ps1b3.js → chunk-htrwgabr.js} +40 -22
  46. package/dist/cli/chunk-htrwgabr.js.map +15 -0
  47. package/dist/cli/{chunk-zhvd6adm.js → chunk-hx3xqnk9.js} +13 -13
  48. package/dist/cli/chunk-j134vrp2.js +65 -0
  49. package/dist/cli/chunk-j134vrp2.js.map +10 -0
  50. package/dist/cli/{chunk-y4ykbark.js → chunk-kma9f6sf.js} +2 -2
  51. package/dist/cli/{chunk-py62fewh.js → chunk-mrcccgnh.js} +3 -3
  52. package/dist/cli/{chunk-2f3ndkpw.js → chunk-n0v7m8ry.js} +3 -3
  53. package/dist/cli/{chunk-43zcf4gz.js → chunk-ncj7w596.js} +522 -353
  54. package/dist/cli/chunk-ncj7w596.js.map +35 -0
  55. package/dist/cli/{chunk-9geymqns.js → chunk-nq1d20w2.js} +14 -14
  56. package/dist/cli/{chunk-g2z9x01v.js → chunk-nrns10mj.js} +3 -3
  57. package/dist/cli/{chunk-e7vvk5ya.js → chunk-sds923fa.js} +3 -3
  58. package/dist/cli/{chunk-cy5bm0j0.js → chunk-t2m5j4pr.js} +2 -2
  59. package/dist/cli/{chunk-cy5bm0j0.js.map → chunk-t2m5j4pr.js.map} +1 -1
  60. package/dist/cli/{chunk-yj17vs39.js → chunk-tdqhyxfz.js} +5 -5
  61. package/dist/cli/{chunk-q3wxxq39.js → chunk-tphac74f.js} +5 -5
  62. package/dist/cli/{chunk-6bm0xpgd.js → chunk-w1r4vase.js} +2 -2
  63. package/dist/cli/index.js +24 -19
  64. package/dist/cli/index.js.map +3 -3
  65. package/dist/types/ai/ask-context.d.ts +6 -2
  66. package/dist/types/ai/component-markdown.d.ts +2 -0
  67. package/dist/types/ai/openapi-components.d.ts +4 -1
  68. package/dist/types/astro/integration.d.ts +5 -4
  69. package/dist/types/astro/markdown-negotiation.d.ts +3 -0
  70. package/dist/types/astro/pages.d.ts +10 -0
  71. package/dist/types/cli/init/scaffold.d.ts +1 -1
  72. package/dist/types/components/content/api-field.d.ts +4 -1
  73. package/dist/types/components/content/api-page.d.ts +6 -1
  74. package/dist/types/components/openapi/code-samples.d.ts +29 -0
  75. package/dist/types/components/openapi/helpers.d.ts +22 -1
  76. package/dist/types/components/openapi/security.d.ts +10 -0
  77. package/dist/types/components/openapi/snippets.d.ts +60 -0
  78. package/dist/types/core/changelog-index.d.ts +8 -0
  79. package/dist/types/core/config-input.d.ts +30 -3
  80. package/dist/types/core/data.d.ts +4 -0
  81. package/dist/types/core/i18n-ui.d.ts +2 -0
  82. package/dist/types/core/links.d.ts +8 -0
  83. package/dist/types/core/probe.d.ts +2 -0
  84. package/dist/types/core/project-graph.d.ts +6 -0
  85. package/dist/types/core/redirect-patterns.d.ts +11 -3
  86. package/dist/types/core/schema.d.ts +119 -0
  87. package/dist/types/core/sources/cache.d.ts +3 -0
  88. package/dist/types/core/sources/contentful-rich-text.d.ts +11 -2
  89. package/dist/types/core/sources/contentful.d.ts +17 -1
  90. package/dist/types/core/sources/lexical.d.ts +5 -0
  91. package/dist/types/core/sources/normalize.d.ts +20 -1
  92. package/dist/types/core/sources/remote.d.ts +37 -10
  93. package/dist/types/core/sources/sanity.d.ts +1 -1
  94. package/dist/types/core/types.d.ts +17 -0
  95. package/dist/types/deploy/adapter-output.d.ts +2 -1
  96. package/dist/types/deploy/adapters/cloudflare.d.ts +7 -5
  97. package/dist/types/deploy/adapters/node.d.ts +58 -23
  98. package/dist/types/deploy/adapters/registry.d.ts +10 -0
  99. package/dist/types/deploy/adapters/types.d.ts +3 -2
  100. package/dist/types/deploy/platforms/cloudflare.d.ts +10 -7
  101. package/dist/types/deploy/platforms/node.d.ts +3 -1
  102. package/dist/types/deploy/platforms/types.d.ts +18 -7
  103. package/dist/types/deploy/platforms/vercel.d.ts +20 -1
  104. package/dist/types/deploy/redirects.d.ts +17 -1
  105. package/dist/types/deploy/sitemap.d.ts +2 -1
  106. package/dist/types/deploy/vercel-negotiation.d.ts +42 -21
  107. package/dist/types/openapi/checks.d.ts +27 -0
  108. package/dist/types/openapi/graphql.d.ts +6 -0
  109. package/dist/types/openapi/model.d.ts +15 -4
  110. package/dist/types/openapi/parse.d.ts +3 -0
  111. package/dist/types/openapi/references.d.ts +16 -0
  112. package/dist/types/ratelimit/index.d.ts +1 -1
  113. package/dist/types/ratelimit/schema.d.ts +8 -0
  114. package/dist/types/ratelimit/upstash.d.ts +39 -14
  115. package/dist/types/reference/graphql.d.ts +76 -1
  116. package/dist/types/reference/index.d.ts +1 -1
  117. package/dist/types/reference/openapi.d.ts +2 -2
  118. package/dist/types/reference/options.d.ts +37 -1
  119. package/dist/types/reference/schema.d.ts +84 -0
  120. package/dist/types/search/adapters/registry.d.ts +3 -0
  121. package/dist/types/search/adapters/typesense.d.ts +14 -4
  122. package/dist/types/search/build.d.ts +3 -1
  123. package/dist/types/search/orama-index.d.ts +9 -9
  124. package/dist/types/search/sync/algolia.d.ts +5 -2
  125. package/dist/types/search/sync/index.d.ts +3 -1
  126. package/dist/types/search/sync/typesense.d.ts +11 -7
  127. package/dist/types/sources/contentful.d.ts +16 -0
  128. package/dist/types/sources/github-releases.d.ts +8 -1
  129. package/dist/types/sources/payload.d.ts +2 -0
  130. package/dist/types/sources/registry.d.ts +54 -0
  131. package/dist/types/sources/shared.d.ts +3 -0
  132. package/dist/types/sources/strapi.d.ts +2 -0
  133. package/docs/01-quickstart.mdx +4 -2
  134. package/docs/02-deployment.mdx +31 -13
  135. package/docs/advanced/changelog.mdx +11 -0
  136. package/docs/advanced/skills.mdx +1 -1
  137. package/docs/cli/audit.mdx +30 -7
  138. package/docs/cli/doctor.mdx +5 -1
  139. package/docs/cli/evals.mdx +4 -4
  140. package/docs/cli/translate.mdx +1 -0
  141. package/docs/cli/validate.mdx +4 -3
  142. package/docs/configuration/analytics.mdx +1 -1
  143. package/docs/configuration/assistant.mdx +6 -2
  144. package/docs/configuration/customization.mdx +4 -2
  145. package/docs/configuration/export.mdx +5 -3
  146. package/docs/configuration/index.mdx +3 -2
  147. package/docs/configuration/rate-limiting.mdx +23 -2
  148. package/docs/configuration/search.mdx +37 -14
  149. package/docs/content/components.mdx +2 -2
  150. package/docs/content/frontmatter.mdx +5 -3
  151. package/docs/content/i18n.mdx +2 -2
  152. package/docs/content/includes.mdx +1 -1
  153. package/docs/content/navigation.mdx +4 -4
  154. package/docs/content/sources/contentful.mdx +7 -4
  155. package/docs/content/sources/custom.mdx +7 -3
  156. package/docs/content/sources/github-releases.mdx +10 -2
  157. package/docs/content/sources/index.mdx +3 -3
  158. package/docs/content/sources/notion.mdx +1 -1
  159. package/docs/content/sources/obsidian.mdx +1 -1
  160. package/docs/content/sources/payload.mdx +3 -2
  161. package/docs/content/sources/remote-mdx.mdx +4 -0
  162. package/docs/content/sources/sanity.mdx +2 -2
  163. package/docs/content/sources/strapi.mdx +3 -2
  164. package/docs/content/syntax.mdx +2 -2
  165. package/docs/discoverability/agent-discovery.mdx +1 -1
  166. package/docs/discoverability/index.mdx +1 -1
  167. package/docs/discoverability/json-api.mdx +2 -0
  168. package/docs/discoverability/llms-txt.mdx +1 -1
  169. package/docs/discoverability/markdown.mdx +3 -1
  170. package/docs/discoverability/mcp.mdx +4 -0
  171. package/docs/discoverability/sitemap-and-robots.mdx +1 -1
  172. package/docs/references/api-pages.mdx +1 -1
  173. package/docs/references/asyncapi.mdx +3 -1
  174. package/docs/references/graphql.mdx +13 -1
  175. package/docs/references/openapi.mdx +50 -8
  176. package/package.json +9 -9
  177. package/skills/blume-migrate/SKILL.md +1 -1
  178. package/skills/blume-migrate/references/docusaurus.md +4 -4
  179. package/skills/blume-migrate/references/fumadocs.md +17 -13
  180. package/skills/blume-migrate/references/nextra.md +8 -5
  181. package/skills/blume-migrate/references/starlight.md +9 -7
  182. package/src/ai/ask-context.ts +33 -3
  183. package/src/ai/ask-limits.ts +13 -0
  184. package/src/ai/changelog-markdown.ts +11 -6
  185. package/src/ai/component-markdown.ts +1 -1
  186. package/src/ai/cors.ts +12 -3
  187. package/src/ai/mcp/query.ts +14 -6
  188. package/src/ai/openapi-components.ts +28 -4
  189. package/src/ai/relative-links.ts +4 -38
  190. package/src/astro/generate.ts +78 -48
  191. package/src/astro/integration.ts +16 -13
  192. package/src/astro/markdown-negotiation.ts +3 -0
  193. package/src/astro/module-types.ts +3 -1
  194. package/src/astro/pages.ts +23 -0
  195. package/src/astro/templates.ts +125 -80
  196. package/src/audit/catalog.ts +19 -3
  197. package/src/audit/checks/links.ts +14 -1
  198. package/src/audit/checks/network.ts +110 -6
  199. package/src/audit/checks/redirects.ts +6 -4
  200. package/src/audit/checks/robots.ts +58 -2
  201. package/src/audit/run.ts +3 -0
  202. package/src/audit/types.ts +2 -0
  203. package/src/audit/url.ts +14 -5
  204. package/src/blume-modules.d.ts +5 -1
  205. package/src/cli/args.ts +51 -0
  206. package/src/cli/build-failure.ts +23 -0
  207. package/src/cli/commands/audit.ts +10 -1
  208. package/src/cli/commands/dev.ts +18 -2
  209. package/src/cli/commands/doctor.ts +45 -12
  210. package/src/cli/commands/eval.ts +36 -4
  211. package/src/cli/commands/init.ts +6 -4
  212. package/src/cli/commands/validate.ts +10 -1
  213. package/src/cli/init/scaffold.ts +3 -3
  214. package/src/cli/prepare.ts +6 -3
  215. package/src/cli/required-secrets.ts +1 -1
  216. package/src/components/content/ApiPlayground.astro +6 -2
  217. package/src/components/content/api-field.ts +4 -1
  218. package/src/components/content/api-page.ts +31 -7
  219. package/src/components/content/mermaid-element.ts +15 -1
  220. package/src/components/islands/hooks.ts +27 -1
  221. package/src/components/layout/PageActions.astro +139 -24
  222. package/src/components/layout/RootLayout.astro +10 -2
  223. package/src/components/layout/Search.astro +17 -3
  224. package/src/components/layout/TableOfContents.astro +24 -17
  225. package/src/components/layout/head-scripts.ts +6 -1
  226. package/src/components/layout/search/algolia.ts +10 -1
  227. package/src/components/layout/search/analytics.ts +42 -14
  228. package/src/components/layout/search/endpoint.ts +48 -5
  229. package/src/components/layout/search/pagefind.ts +114 -5
  230. package/src/components/layout/search/types.ts +12 -0
  231. package/src/components/layout/search/typesense.ts +18 -6
  232. package/src/components/openapi/AsyncApiOperation.astro +14 -7
  233. package/src/components/openapi/Authorization.astro +10 -0
  234. package/src/components/openapi/GraphqlOperation.astro +5 -0
  235. package/src/components/openapi/Operation.astro +24 -1
  236. package/src/components/openapi/ParametersTable.astro +8 -4
  237. package/src/components/openapi/Playground.astro +7 -1
  238. package/src/components/openapi/RequestBody.astro +19 -2
  239. package/src/components/openapi/Responses.astro +1 -0
  240. package/src/components/openapi/SchemaTable.astro +15 -3
  241. package/src/components/openapi/async-snippets.ts +61 -5
  242. package/src/components/openapi/async.ts +123 -29
  243. package/src/components/openapi/graphql-helpers.ts +35 -12
  244. package/src/components/openapi/helpers.ts +36 -2
  245. package/src/components/openapi/message-model.ts +54 -11
  246. package/src/components/openapi/message.ts +14 -4
  247. package/src/components/openapi/operation-model.ts +16 -7
  248. package/src/components/openapi/playground-client.ts +24 -5
  249. package/src/components/openapi/playground-schema.ts +1 -1
  250. package/src/components/openapi/schema-tree.ts +44 -14
  251. package/src/components/openapi/security.ts +10 -0
  252. package/src/components/openapi/snippets.ts +5 -3
  253. package/src/components/openapi/validate-json.ts +4 -3
  254. package/src/core/changelog-index.ts +31 -1
  255. package/src/core/component-diagnostics.ts +53 -0
  256. package/src/core/component-overrides.ts +32 -0
  257. package/src/core/config-input.ts +31 -3
  258. package/src/core/data.ts +2 -0
  259. package/src/core/diagnostics.ts +5 -0
  260. package/src/core/i18n-ui.ts +2 -0
  261. package/src/core/includes.ts +1 -1
  262. package/src/core/links.ts +47 -17
  263. package/src/core/probe.ts +26 -6
  264. package/src/core/project-graph.ts +59 -18
  265. package/src/core/redirect-patterns.ts +36 -7
  266. package/src/core/schema.ts +21 -2
  267. package/src/core/sources/cache.ts +6 -0
  268. package/src/core/sources/contentful-rich-text.ts +29 -6
  269. package/src/core/sources/contentful.ts +135 -25
  270. package/src/core/sources/filesystem.ts +26 -4
  271. package/src/core/sources/github-releases.ts +12 -1
  272. package/src/core/sources/lexical.ts +15 -10
  273. package/src/core/sources/mdx-remote.ts +62 -10
  274. package/src/core/sources/normalize.ts +227 -41
  275. package/src/core/sources/notion.ts +7 -1
  276. package/src/core/sources/obsidian.ts +16 -3
  277. package/src/core/sources/payload.ts +38 -15
  278. package/src/core/sources/remote.ts +72 -15
  279. package/src/core/sources/resolve.ts +11 -1
  280. package/src/core/sources/sanity.ts +43 -25
  281. package/src/core/sources/strapi.ts +2 -2
  282. package/src/core/types.ts +18 -0
  283. package/src/core/ui-packs/ar.ts +1 -0
  284. package/src/core/ui-packs/bg.ts +1 -0
  285. package/src/core/ui-packs/bn.ts +1 -0
  286. package/src/core/ui-packs/ca.ts +1 -0
  287. package/src/core/ui-packs/cs.ts +1 -0
  288. package/src/core/ui-packs/da.ts +1 -0
  289. package/src/core/ui-packs/de.ts +1 -0
  290. package/src/core/ui-packs/el.ts +1 -0
  291. package/src/core/ui-packs/es.ts +1 -0
  292. package/src/core/ui-packs/fa.ts +1 -0
  293. package/src/core/ui-packs/fi.ts +1 -0
  294. package/src/core/ui-packs/fr.ts +1 -0
  295. package/src/core/ui-packs/he.ts +1 -0
  296. package/src/core/ui-packs/hi.ts +1 -0
  297. package/src/core/ui-packs/hr.ts +1 -0
  298. package/src/core/ui-packs/hu.ts +1 -0
  299. package/src/core/ui-packs/id.ts +1 -0
  300. package/src/core/ui-packs/it.ts +1 -0
  301. package/src/core/ui-packs/ja.ts +1 -0
  302. package/src/core/ui-packs/ko.ts +1 -0
  303. package/src/core/ui-packs/nl.ts +1 -0
  304. package/src/core/ui-packs/no.ts +1 -0
  305. package/src/core/ui-packs/pl.ts +1 -0
  306. package/src/core/ui-packs/pt-br.ts +1 -0
  307. package/src/core/ui-packs/pt.ts +1 -0
  308. package/src/core/ui-packs/ro.ts +1 -0
  309. package/src/core/ui-packs/ru.ts +1 -0
  310. package/src/core/ui-packs/sk.ts +1 -0
  311. package/src/core/ui-packs/sr.ts +1 -0
  312. package/src/core/ui-packs/sv.ts +1 -0
  313. package/src/core/ui-packs/th.ts +1 -0
  314. package/src/core/ui-packs/tr.ts +1 -0
  315. package/src/core/ui-packs/uk.ts +1 -0
  316. package/src/core/ui-packs/vi.ts +1 -0
  317. package/src/core/ui-packs/zh-tw.ts +1 -0
  318. package/src/core/ui-packs/zh.ts +1 -0
  319. package/src/deploy/adapter-output.ts +7 -2
  320. package/src/deploy/adapters/cloudflare.ts +7 -5
  321. package/src/deploy/adapters/node.ts +47 -9
  322. package/src/deploy/adapters/types.ts +7 -3
  323. package/src/deploy/artifacts.ts +2 -1
  324. package/src/deploy/platforms/cloudflare.ts +13 -9
  325. package/src/deploy/platforms/netlify.ts +2 -1
  326. package/src/deploy/platforms/node.ts +12 -2
  327. package/src/deploy/platforms/types.ts +21 -7
  328. package/src/deploy/platforms/vercel.ts +113 -16
  329. package/src/deploy/redirects.ts +66 -6
  330. package/src/deploy/rss.ts +3 -1
  331. package/src/deploy/sitemap.ts +39 -5
  332. package/src/deploy/vercel-negotiation.ts +290 -102
  333. package/src/eval/agents.ts +18 -1
  334. package/src/eval/prompts.ts +6 -3
  335. package/src/eval/report.ts +34 -13
  336. package/src/eval/run.ts +5 -0
  337. package/src/markdown/relative-links.ts +3 -2
  338. package/src/openapi/checks.ts +273 -0
  339. package/src/openapi/graphql-build.ts +21 -0
  340. package/src/openapi/graphql.ts +11 -0
  341. package/src/openapi/model.ts +15 -3
  342. package/src/openapi/parse.ts +127 -2
  343. package/src/openapi/references.ts +43 -3
  344. package/src/openapi/source.ts +39 -14
  345. package/src/ratelimit/index.ts +1 -1
  346. package/src/ratelimit/runtime.ts +37 -19
  347. package/src/ratelimit/upstash.ts +40 -10
  348. package/src/reference/graphql.ts +15 -1
  349. package/src/reference/index.ts +1 -0
  350. package/src/reference/openapi.ts +2 -2
  351. package/src/reference/options.ts +29 -1
  352. package/src/registry/eject.ts +3 -1
  353. package/src/search/adapters/locale-scope.ts +30 -0
  354. package/src/search/adapters/typesense.ts +14 -4
  355. package/src/search/build.ts +21 -3
  356. package/src/search/orama-index.ts +163 -31
  357. package/src/search/source-pages.ts +29 -0
  358. package/src/search/sync/algolia.ts +99 -9
  359. package/src/search/sync/index.ts +52 -13
  360. package/src/search/sync/typesense.ts +72 -27
  361. package/src/sources/contentful.ts +12 -0
  362. package/src/sources/github-releases.ts +7 -1
  363. package/src/sources/shared.ts +3 -0
  364. package/src/theme/entry.ts +29 -3
  365. package/src/translate/validate.ts +23 -1
  366. package/dist/cli/chunk-0gz36akr.js.map +0 -12
  367. package/dist/cli/chunk-2n4ps1b3.js.map +0 -15
  368. package/dist/cli/chunk-43zcf4gz.js.map +0 -36
  369. package/dist/cli/chunk-4ejxbzee.js +0 -39
  370. package/dist/cli/chunk-4ejxbzee.js.map +0 -10
  371. package/dist/cli/chunk-4h8z9vv5.js.map +0 -16
  372. package/dist/cli/chunk-713mngdq.js.map +0 -14
  373. package/dist/cli/chunk-9xr4dgee.js.map +0 -10
  374. package/dist/cli/chunk-amrb6hgh.js +0 -145
  375. package/dist/cli/chunk-amrb6hgh.js.map +0 -11
  376. package/dist/cli/chunk-nd1821sk.js.map +0 -10
  377. package/dist/cli/chunk-rekqz4qg.js.map +0 -10
  378. package/dist/cli/chunk-ta27feev.js.map +0 -10
  379. package/dist/cli/chunk-xkz5xbtv.js.map +0 -213
  380. package/dist/cli/chunk-y5h4r2y0.js.map +0 -10
  381. /package/dist/cli/{chunk-gp84za0h.js.map → chunk-3v3ffbrj.js.map} +0 -0
  382. /package/dist/cli/{chunk-p804f3pe.js.map → chunk-8y2kmjv8.js.map} +0 -0
  383. /package/dist/cli/{chunk-2f7n4qzt.js.map → chunk-c1y538kd.js.map} +0 -0
  384. /package/dist/cli/{chunk-1n228xqb.js.map → chunk-c887fj0s.js.map} +0 -0
  385. /package/dist/cli/{chunk-cmtcnh9f.js.map → chunk-dzwehpy7.js.map} +0 -0
  386. /package/dist/cli/{chunk-ntv4qrt7.js.map → chunk-e9q7a2ak.js.map} +0 -0
  387. /package/dist/cli/{chunk-5wj2qwn2.js.map → chunk-ft9vfys6.js.map} +0 -0
  388. /package/dist/cli/{chunk-zhvd6adm.js.map → chunk-hx3xqnk9.js.map} +0 -0
  389. /package/dist/cli/{chunk-y4ykbark.js.map → chunk-kma9f6sf.js.map} +0 -0
  390. /package/dist/cli/{chunk-py62fewh.js.map → chunk-mrcccgnh.js.map} +0 -0
  391. /package/dist/cli/{chunk-2f3ndkpw.js.map → chunk-n0v7m8ry.js.map} +0 -0
  392. /package/dist/cli/{chunk-9geymqns.js.map → chunk-nq1d20w2.js.map} +0 -0
  393. /package/dist/cli/{chunk-g2z9x01v.js.map → chunk-nrns10mj.js.map} +0 -0
  394. /package/dist/cli/{chunk-e7vvk5ya.js.map → chunk-sds923fa.js.map} +0 -0
  395. /package/dist/cli/{chunk-yj17vs39.js.map → chunk-tdqhyxfz.js.map} +0 -0
  396. /package/dist/cli/{chunk-q3wxxq39.js.map → chunk-tphac74f.js.map} +0 -0
  397. /package/dist/cli/{chunk-6bm0xpgd.js.map → chunk-w1r4vase.js.map} +0 -0
@@ -16,31 +16,31 @@ import {
16
16
  applyPlan,
17
17
  readExistingPackage,
18
18
  nextSteps
19
- } from "./chunk-xkz5xbtv.js";
19
+ } from "./chunk-ehweg4fr.js";
20
20
  import"./chunk-zccbjcj0.js";
21
- import"./chunk-zf748avv.js";
21
+ import"./chunk-ep6nd0rn.js";
22
22
  import {
23
23
  commandMeta,
24
24
  logger
25
25
  } from "./index.js";
26
- import"./chunk-2f3ndkpw.js";
27
- import"./chunk-43zcf4gz.js";
28
- import"./chunk-4h8z9vv5.js";
29
- import"./chunk-amrb6hgh.js";
30
- import"./chunk-ta27feev.js";
26
+ import"./chunk-n0v7m8ry.js";
27
+ import"./chunk-ncj7w596.js";
28
+ import"./chunk-gb420vvz.js";
29
+ import"./chunk-66w9j7p6.js";
30
+ import"./chunk-54ztw1nj.js";
31
31
  import"./chunk-jq5n4avg.js";
32
32
  import"./chunk-cm89scdv.js";
33
- import"./chunk-2f7n4qzt.js";
33
+ import"./chunk-c1y538kd.js";
34
34
  import {
35
35
  eject
36
- } from "./chunk-rekqz4qg.js";
36
+ } from "./chunk-313vnn40.js";
37
37
  import {
38
38
  updatePackageScripts
39
- } from "./chunk-py62fewh.js";
39
+ } from "./chunk-mrcccgnh.js";
40
40
  import {
41
41
  installDependencies
42
- } from "./chunk-gp84za0h.js";
43
- import"./chunk-6bm0xpgd.js";
42
+ } from "./chunk-3v3ffbrj.js";
43
+ import"./chunk-w1r4vase.js";
44
44
 
45
45
  // src/cli/commands/init.ts
46
46
  import * as clack from "@clack/prompts";
@@ -301,7 +301,8 @@ var initCommand = defineCommand({
301
301
  const ignored = await ensureGitignore(root, [
302
302
  "node_modules/",
303
303
  ".blume/",
304
- "dist/"
304
+ "dist/",
305
+ ".env.local"
305
306
  ]);
306
307
  if (ignored.length > 0) {
307
308
  sink.success(`Added ${ignored.join(", ")} to .gitignore`);
@@ -330,5 +331,5 @@ export {
330
331
  initCommand
331
332
  };
332
333
 
333
- //# debugId=E14485B14C8DBCED64756E2164756E21
334
- //# sourceMappingURL=chunk-yxmk4pec.js.map
334
+ //# debugId=937A77D93EDC0DE164756E2164756E21
335
+ //# sourceMappingURL=chunk-fdrkhpjy.js.map
@@ -2,10 +2,10 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/cli/commands/init.ts", "../src/cli/init/questions.ts"],
4
4
  "sourcesContent": [
5
- "import * as clack from \"@clack/prompts\";\nimport { defineCommand } from \"citty\";\nimport { resolve } from \"pathe\";\n\nimport { ensureGitignore } from \"../../core/gitignore.ts\";\nimport { eject } from \"../../registry/eject.ts\";\nimport { commandMeta } from \"../command-meta.ts\";\nimport { updatePackageScripts } from \"../eject-scripts.ts\";\nimport { installDependencies } from \"../init/install.ts\";\nimport { collectAnswers } from \"../init/questions.ts\";\nimport {\n applyPlan,\n buildPlan,\n cdCommand,\n commandsFor,\n detectPackageManager,\n nextSteps,\n outsidePnpmWorkspace,\n PACKAGE_MANAGERS,\n readExistingPackage,\n TEMPLATES,\n validateContentDir,\n workspaceNote,\n} from \"../init/scaffold.ts\";\nimport type { InitAnswers } from \"../init/scaffold.ts\";\nimport { logger } from \"../log.ts\";\n\n/** The `cd` line that opens every next-steps hint, when one is needed. */\nconst cdStep = (answers: InitAnswers): string[] =>\n answers.directory === \".\" ? [] : [cdCommand(answers.directory)];\n\n/**\n * Install the scaffolded project's dependencies. Interactive runs hide the\n * package manager's output behind a spinner; `--yes`/CI runs stream it. On\n * failure the scaffold is left intact and the exact retry command is printed\n * before exiting non-zero, so a CI wrapper can tell the two outcomes apart.\n */\nconst installScaffold = async (\n root: string,\n answers: InitAnswers,\n interactive: boolean\n): Promise<void> => {\n const command = commandsFor(answers.packageManager).install;\n const spinner = interactive ? clack.spinner() : undefined;\n if (spinner) {\n spinner.start(`Installing dependencies (${command})`);\n } else {\n logger.info(`Installing dependencies (${command})…`);\n }\n const outcome = await installDependencies(root, answers.packageManager, {\n quiet: interactive,\n });\n if (outcome.failure === undefined) {\n if (spinner) {\n spinner.stop(\"Installed dependencies\");\n } else {\n logger.success(\"Installed dependencies\");\n }\n return;\n }\n const retry = [...cdStep(answers), command];\n const hint = `Project created successfully, but dependency installation failed.\\n\\nRetry with:\\n\\n ${retry.join(\"\\n \")}\\n`;\n if (spinner) {\n spinner.stop(\"Dependency installation failed\");\n clack.log.error(outcome.failure);\n clack.note(hint.trimEnd());\n clack.outro(\"Scaffolded without dependencies.\");\n } else {\n logger.error(outcome.failure);\n logger.box(hint.trimEnd());\n }\n process.exit(1);\n};\n\n/**\n * Eject the freshly scaffolded project, or print the install-then-eject path.\n * Eject jiti-loads the scaffolded blume.config.ts, whose `import { defineConfig }\n * from \"blume\"` only resolves once dependencies are installed (or blume is\n * hoisted from an ancestor node_modules, as in a monorepo) — so the fallback\n * below is the common path when the install step was skipped.\n */\nconst ejectScaffold = async (\n root: string,\n answers: InitAnswers,\n needsInstall: boolean\n): Promise<void> => {\n const commands = commandsFor(answers.packageManager);\n const cd = cdStep(answers);\n const install = needsInstall ? [commands.install] : [];\n try {\n const { dependencies } = await eject(root);\n // The scaffolded scripts point at the Blume CLI; the ejected app runs\n // Astro directly (mirroring the standalone `blume eject` command).\n const added = await updatePackageScripts(root, dependencies);\n logger.success(\"Ejected to a standalone Astro project.\");\n // The packages eject added aren't installed yet, even when the scaffold's\n // own install already ran, so install comes first either way.\n const ejectInstall = added.length > 0 ? [commands.install] : install;\n const steps = [...cd, ...ejectInstall, commands.dev];\n logger.box(`Next steps:\\n\\n ${steps.join(\"\\n \")}`);\n } catch (error) {\n // SAFETY: eject and the script rewrite throw Error instances; only the\n // message is surfaced in the fallback hint.\n const { message } = error as Error;\n // Only a skipped install explains the failure; after an install that ran,\n // the error itself is the reason.\n logger.warn(\n needsInstall\n ? `Scaffolded, but eject needs the project's dependencies installed to load blume.config.ts: ${message}`\n : `Scaffolded, but eject failed: ${message}`\n );\n const steps = [...cd, ...install, `${commands.exec} blume eject --yes`];\n logger.box(`Next steps:\\n\\n ${steps.join(\"\\n \")}`);\n }\n};\n\n/**\n * Print the closing next steps. An existing package.json was left alone, so\n * the steps add what it lacks; a workspace `note` already printed ahead of an\n * install that ran, so it closes the steps only when the install is still the\n * user's to run.\n */\nconst printNextSteps = async (\n root: string,\n answers: InitAnswers,\n outcome: {\n createdPackage: boolean;\n interactive: boolean;\n needsInstall: boolean;\n note: string | undefined;\n }\n): Promise<void> => {\n const existing = outcome.createdPackage\n ? undefined\n : await readExistingPackage(root);\n const steps = nextSteps(\n answers,\n outcome.needsInstall,\n existing,\n outcome.needsInstall ? outcome.note : undefined\n );\n if (outcome.interactive) {\n clack.note(steps.trimEnd());\n clack.outro(\"You're all set.\");\n } else {\n // consola's box pads its content itself; a trailing newline would add\n // blank rows at the bottom.\n logger.box(steps.trimEnd());\n }\n};\n\n/**\n * Validate the enum-valued flags up front, exiting with the accepted values\n * on a typo so a bad flag never reaches the prompts.\n */\nconst resolveFlags = (args: {\n \"package-manager\"?: string;\n template?: string;\n}) => {\n const template = TEMPLATES.find((candidate) => candidate === args.template);\n if (args.template !== undefined && template === undefined) {\n logger.error(\n `Unknown template \"${args.template}\" (use ${TEMPLATES.join(\" | \")}).`\n );\n process.exit(1);\n }\n const pm = PACKAGE_MANAGERS.find(\n (candidate) => candidate === args[\"package-manager\"]\n );\n if (args[\"package-manager\"] !== undefined && pm === undefined) {\n logger.error(\n `Unknown package manager \"${args[\"package-manager\"]}\" (use ${PACKAGE_MANAGERS.join(\" | \")}).`\n );\n process.exit(1);\n }\n return { pm, template };\n};\n\nexport const initCommand = defineCommand({\n args: {\n \"content-dir\": {\n description: \"Content directory.\",\n type: \"string\",\n },\n dir: {\n description: \"Directory to scaffold into (default: current directory).\",\n required: false,\n type: \"positional\",\n },\n eject: {\n description: \"Eject to a standalone Astro project after scaffolding.\",\n type: \"boolean\",\n },\n install: {\n default: true,\n description: \"Install dependencies after scaffolding.\",\n negativeDescription: \"Skip installing dependencies after scaffolding.\",\n type: \"boolean\",\n },\n \"package-manager\": {\n description:\n \"Package manager to install with and print in the next steps (npm|pnpm|yarn|bun).\",\n type: \"string\",\n },\n template: {\n description: \"Starter template: docs | api | sdk | changelog.\",\n type: \"string\",\n },\n yes: {\n description: \"Skip prompts and scaffold with defaults.\",\n type: \"boolean\",\n },\n },\n meta: commandMeta.init,\n async run({ args }) {\n const cwd = process.cwd();\n const { pm, template } = resolveFlags(args);\n\n const interactive =\n !args.yes &&\n process.stdin.isTTY === true &&\n clack.isTTY(process.stdout) &&\n !clack.isCI();\n\n let answers: InitAnswers;\n if (interactive) {\n clack.intro(\"blume init\");\n const collected = await collectAnswers(\n clack,\n {\n contentDir: args[\"content-dir\"],\n directory: args.dir,\n packageManager: pm,\n template,\n },\n { cwd, userAgent: process.env.npm_config_user_agent }\n );\n if (collected === null) {\n clack.cancel(\"Canceled — nothing was written.\");\n process.exit(0);\n }\n answers = collected;\n } else {\n answers = {\n contentDir: args[\"content-dir\"] ?? \"docs\",\n directory: args.dir ?? \".\",\n packageManager:\n pm ?? detectPackageManager(process.env.npm_config_user_agent),\n sources: [\"filesystem\"],\n template: template ?? \"docs\",\n title: \"My Docs\",\n };\n }\n\n const root = resolve(cwd, answers.directory);\n // Interactive runs validate this inline, but an explicit --content-dir\n // flag skips that prompt, so guard here in both modes.\n if (validateContentDir(root, answers.contentDir) !== undefined) {\n logger.error(\n `Invalid --content-dir \"${answers.contentDir}\" (must be a path inside the project).`\n );\n process.exit(1);\n }\n\n const sink = interactive ? clack.log : logger;\n const env = { userAgent: process.env.npm_config_user_agent };\n const { createdPackage } = await applyPlan(\n buildPlan(root, answers, env),\n sink\n );\n // A workspace the project joins keeps its own package-manager config,\n // which `init` leaves alone; say what it still needs before installing.\n const note = workspaceNote(root, answers, env);\n\n // Keep installed dependencies, Blume's generated runtime (`.blume/`), and\n // build output (`dist/`) out of version control. Idempotent: creates\n // `.gitignore` when absent and skips entries already present\n // (trailing-slash agnostic).\n const ignored = await ensureGitignore(root, [\n \"node_modules/\",\n \".blume/\",\n \"dist/\",\n ]);\n if (ignored.length > 0) {\n sink.success(`Added ${ignored.join(\", \")} to .gitignore`);\n }\n\n // A newly written package.json is the only one `init` knows lists blume;\n // an existing one is left alone, and so are its dependencies. In a pnpm\n // workspace that doesn't list the folder, an install would exit 0 without\n // installing it, so that one waits until the note's change is made.\n const shouldInstall =\n createdPackage && args.install && !outsidePnpmWorkspace(root, answers);\n if (note) {\n (interactive ? clack.log : logger).warn(note);\n }\n if (shouldInstall) {\n await installScaffold(root, answers, interactive);\n }\n const needsInstall = createdPackage && !shouldInstall;\n\n if (args.eject) {\n await ejectScaffold(root, answers, needsInstall);\n return;\n }\n\n await printNextSteps(root, answers, {\n createdPackage,\n interactive,\n needsInstall,\n note,\n });\n },\n});\n",
5
+ "import * as clack from \"@clack/prompts\";\nimport { defineCommand } from \"citty\";\nimport { resolve } from \"pathe\";\n\nimport { ensureGitignore } from \"../../core/gitignore.ts\";\nimport { eject } from \"../../registry/eject.ts\";\nimport { commandMeta } from \"../command-meta.ts\";\nimport { updatePackageScripts } from \"../eject-scripts.ts\";\nimport { installDependencies } from \"../init/install.ts\";\nimport { collectAnswers } from \"../init/questions.ts\";\nimport {\n applyPlan,\n buildPlan,\n cdCommand,\n commandsFor,\n detectPackageManager,\n nextSteps,\n outsidePnpmWorkspace,\n PACKAGE_MANAGERS,\n readExistingPackage,\n TEMPLATES,\n validateContentDir,\n workspaceNote,\n} from \"../init/scaffold.ts\";\nimport type { InitAnswers } from \"../init/scaffold.ts\";\nimport { logger } from \"../log.ts\";\n\n/** The `cd` line that opens every next-steps hint, when one is needed. */\nconst cdStep = (answers: InitAnswers): string[] =>\n answers.directory === \".\" ? [] : [cdCommand(answers.directory)];\n\n/**\n * Install the scaffolded project's dependencies. Interactive runs hide the\n * package manager's output behind a spinner; `--yes`/CI runs stream it. On\n * failure the scaffold is left intact and the exact retry command is printed\n * before exiting non-zero, so a CI wrapper can tell the two outcomes apart.\n */\nconst installScaffold = async (\n root: string,\n answers: InitAnswers,\n interactive: boolean\n): Promise<void> => {\n const command = commandsFor(answers.packageManager).install;\n const spinner = interactive ? clack.spinner() : undefined;\n if (spinner) {\n spinner.start(`Installing dependencies (${command})`);\n } else {\n logger.info(`Installing dependencies (${command})…`);\n }\n const outcome = await installDependencies(root, answers.packageManager, {\n quiet: interactive,\n });\n if (outcome.failure === undefined) {\n if (spinner) {\n spinner.stop(\"Installed dependencies\");\n } else {\n logger.success(\"Installed dependencies\");\n }\n return;\n }\n const retry = [...cdStep(answers), command];\n const hint = `Project created successfully, but dependency installation failed.\\n\\nRetry with:\\n\\n ${retry.join(\"\\n \")}\\n`;\n if (spinner) {\n spinner.stop(\"Dependency installation failed\");\n clack.log.error(outcome.failure);\n clack.note(hint.trimEnd());\n clack.outro(\"Scaffolded without dependencies.\");\n } else {\n logger.error(outcome.failure);\n logger.box(hint.trimEnd());\n }\n process.exit(1);\n};\n\n/**\n * Eject the freshly scaffolded project, or print the install-then-eject path.\n * Eject jiti-loads the scaffolded blume.config.ts, whose `import { defineConfig }\n * from \"blume\"` only resolves once dependencies are installed (or blume is\n * hoisted from an ancestor node_modules, as in a monorepo) — so the fallback\n * below is the common path when the install step was skipped.\n */\nconst ejectScaffold = async (\n root: string,\n answers: InitAnswers,\n needsInstall: boolean\n): Promise<void> => {\n const commands = commandsFor(answers.packageManager);\n const cd = cdStep(answers);\n const install = needsInstall ? [commands.install] : [];\n try {\n const { dependencies } = await eject(root);\n // The scaffolded scripts point at the Blume CLI; the ejected app runs\n // Astro directly (mirroring the standalone `blume eject` command).\n const added = await updatePackageScripts(root, dependencies);\n logger.success(\"Ejected to a standalone Astro project.\");\n // The packages eject added aren't installed yet, even when the scaffold's\n // own install already ran, so install comes first either way.\n const ejectInstall = added.length > 0 ? [commands.install] : install;\n const steps = [...cd, ...ejectInstall, commands.dev];\n logger.box(`Next steps:\\n\\n ${steps.join(\"\\n \")}`);\n } catch (error) {\n // SAFETY: eject and the script rewrite throw Error instances; only the\n // message is surfaced in the fallback hint.\n const { message } = error as Error;\n // Only a skipped install explains the failure; after an install that ran,\n // the error itself is the reason.\n logger.warn(\n needsInstall\n ? `Scaffolded, but eject needs the project's dependencies installed to load blume.config.ts: ${message}`\n : `Scaffolded, but eject failed: ${message}`\n );\n const steps = [...cd, ...install, `${commands.exec} blume eject --yes`];\n logger.box(`Next steps:\\n\\n ${steps.join(\"\\n \")}`);\n }\n};\n\n/**\n * Print the closing next steps. An existing package.json was left alone, so\n * the steps add what it lacks; a workspace `note` already printed ahead of an\n * install that ran, so it closes the steps only when the install is still the\n * user's to run.\n */\nconst printNextSteps = async (\n root: string,\n answers: InitAnswers,\n outcome: {\n createdPackage: boolean;\n interactive: boolean;\n needsInstall: boolean;\n note: string | undefined;\n }\n): Promise<void> => {\n const existing = outcome.createdPackage\n ? undefined\n : await readExistingPackage(root);\n const steps = nextSteps(\n answers,\n outcome.needsInstall,\n existing,\n outcome.needsInstall ? outcome.note : undefined\n );\n if (outcome.interactive) {\n clack.note(steps.trimEnd());\n clack.outro(\"You're all set.\");\n } else {\n // consola's box pads its content itself; a trailing newline would add\n // blank rows at the bottom.\n logger.box(steps.trimEnd());\n }\n};\n\n/**\n * Validate the enum-valued flags up front, exiting with the accepted values\n * on a typo so a bad flag never reaches the prompts.\n */\nconst resolveFlags = (args: {\n \"package-manager\"?: string;\n template?: string;\n}) => {\n const template = TEMPLATES.find((candidate) => candidate === args.template);\n if (args.template !== undefined && template === undefined) {\n logger.error(\n `Unknown template \"${args.template}\" (use ${TEMPLATES.join(\" | \")}).`\n );\n process.exit(1);\n }\n const pm = PACKAGE_MANAGERS.find(\n (candidate) => candidate === args[\"package-manager\"]\n );\n if (args[\"package-manager\"] !== undefined && pm === undefined) {\n logger.error(\n `Unknown package manager \"${args[\"package-manager\"]}\" (use ${PACKAGE_MANAGERS.join(\" | \")}).`\n );\n process.exit(1);\n }\n return { pm, template };\n};\n\nexport const initCommand = defineCommand({\n args: {\n \"content-dir\": {\n description: \"Content directory.\",\n type: \"string\",\n },\n dir: {\n description: \"Directory to scaffold into (default: current directory).\",\n required: false,\n type: \"positional\",\n },\n eject: {\n description: \"Eject to a standalone Astro project after scaffolding.\",\n type: \"boolean\",\n },\n install: {\n default: true,\n description: \"Install dependencies after scaffolding.\",\n negativeDescription: \"Skip installing dependencies after scaffolding.\",\n type: \"boolean\",\n },\n \"package-manager\": {\n description:\n \"Package manager to install with and print in the next steps (npm|pnpm|yarn|bun).\",\n type: \"string\",\n },\n template: {\n description: \"Starter template: docs | api | sdk | changelog.\",\n type: \"string\",\n },\n yes: {\n description: \"Skip prompts and scaffold with defaults.\",\n type: \"boolean\",\n },\n },\n meta: commandMeta.init,\n async run({ args }) {\n const cwd = process.cwd();\n const { pm, template } = resolveFlags(args);\n\n const interactive =\n !args.yes &&\n process.stdin.isTTY === true &&\n clack.isTTY(process.stdout) &&\n !clack.isCI();\n\n let answers: InitAnswers;\n if (interactive) {\n clack.intro(\"blume init\");\n const collected = await collectAnswers(\n clack,\n {\n contentDir: args[\"content-dir\"],\n directory: args.dir,\n packageManager: pm,\n template,\n },\n { cwd, userAgent: process.env.npm_config_user_agent }\n );\n if (collected === null) {\n clack.cancel(\"Canceled — nothing was written.\");\n process.exit(0);\n }\n answers = collected;\n } else {\n answers = {\n contentDir: args[\"content-dir\"] ?? \"docs\",\n directory: args.dir ?? \".\",\n packageManager:\n pm ?? detectPackageManager(process.env.npm_config_user_agent),\n sources: [\"filesystem\"],\n template: template ?? \"docs\",\n title: \"My Docs\",\n };\n }\n\n const root = resolve(cwd, answers.directory);\n // Interactive runs validate this inline, but an explicit --content-dir\n // flag skips that prompt, so guard here in both modes.\n if (validateContentDir(root, answers.contentDir) !== undefined) {\n logger.error(\n `Invalid --content-dir \"${answers.contentDir}\" (must be a path inside the project).`\n );\n process.exit(1);\n }\n\n const sink = interactive ? clack.log : logger;\n const env = { userAgent: process.env.npm_config_user_agent };\n const { createdPackage } = await applyPlan(\n buildPlan(root, answers, env),\n sink\n );\n // A workspace the project joins keeps its own package-manager config,\n // which `init` leaves alone; say what it still needs before installing.\n const note = workspaceNote(root, answers, env);\n\n // Keep installed dependencies, Blume's generated runtime (`.blume/`),\n // build output (`dist/`), and local secrets (`.env.local`, where every\n // missing-secret warning says to put them) out of version control.\n // Idempotent: creates `.gitignore` when absent and skips entries already\n // present (trailing-slash agnostic).\n const ignored = await ensureGitignore(root, [\n \"node_modules/\",\n \".blume/\",\n \"dist/\",\n \".env.local\",\n ]);\n if (ignored.length > 0) {\n sink.success(`Added ${ignored.join(\", \")} to .gitignore`);\n }\n\n // A newly written package.json is the only one `init` knows lists blume;\n // an existing one is left alone, and so are its dependencies. In a pnpm\n // workspace that doesn't list the folder, an install would exit 0 without\n // installing it, so that one waits until the note's change is made.\n const shouldInstall =\n createdPackage && args.install && !outsidePnpmWorkspace(root, answers);\n if (note) {\n (interactive ? clack.log : logger).warn(note);\n }\n if (shouldInstall) {\n await installScaffold(root, answers, interactive);\n }\n const needsInstall = createdPackage && !shouldInstall;\n\n if (args.eject) {\n await ejectScaffold(root, answers, needsInstall);\n return;\n }\n\n await printNextSteps(root, answers, {\n createdPackage,\n interactive,\n needsInstall,\n note,\n });\n },\n});\n",
6
6
  "import { basename, resolve } from \"pathe\";\n\nimport {\n detectPackageManager,\n titleize,\n validateContentDir,\n} from \"./scaffold.ts\";\nimport type {\n InitAnswers,\n PackageManager,\n SourceKind,\n Template,\n} from \"./scaffold.ts\";\n\n/** One prompt option: value plus display label and optional hint. */\ninterface PromptOption<Value> {\n hint?: string;\n label: string;\n value: Value;\n}\n\n/**\n * The prompt surface `collectAnswers` needs — structurally satisfied by the\n * `@clack/prompts` module itself, and by plain fakes in tests. Every prompt\n * resolves to a cancel symbol when the user aborts.\n */\nexport interface Prompter {\n multiselect: (opts: {\n initialValues?: SourceKind[];\n message: string;\n options: PromptOption<SourceKind>[];\n required?: boolean;\n }) => Promise<SourceKind[] | symbol>;\n select: (opts: {\n message: string;\n options: PromptOption<Template>[];\n }) => Promise<Template | symbol>;\n text: (opts: {\n defaultValue?: string;\n initialValue?: string;\n message: string;\n placeholder?: string;\n validate?: (value: string | undefined) => string | undefined;\n }) => Promise<string | symbol>;\n}\n\n/** Flag values the user passed explicitly; each one skips its question. */\nexport interface InitFlags {\n contentDir?: string;\n directory?: string;\n packageManager?: PackageManager;\n template?: Template;\n}\n\nconst cancelled = (value: string | string[] | symbol): value is symbol =>\n typeof value === \"symbol\";\n\n/**\n * Run the interactive init flow, returning the collected answers or `null`\n * when the user cancels. All questions run before anything is written, so a\n * cancel never leaves a partial scaffold behind.\n */\nexport const collectAnswers = async (\n prompter: Prompter,\n flags: InitFlags,\n defaults: { cwd: string; userAgent?: string }\n): Promise<InitAnswers | null> => {\n const directory =\n flags.directory ??\n (await prompter.text({\n defaultValue: \".\",\n message: \"Where should we create your project?\",\n placeholder: \"./my-docs\",\n }));\n if (cancelled(directory)) {\n return null;\n }\n\n const root = resolve(defaults.cwd, directory);\n const title = await prompter.text({\n initialValue: titleize(basename(root)),\n message: \"What's your docs site called?\",\n validate: (value) =>\n value?.trim() ? undefined : \"Give your docs site a name.\",\n });\n if (cancelled(title)) {\n return null;\n }\n\n const template =\n flags.template ??\n (await prompter.select({\n message: \"Which template?\",\n options: [\n { hint: \"Markdown docs site\", label: \"docs\", value: \"docs\" },\n { hint: \"OpenAPI reference at /api\", label: \"api\", value: \"api\" },\n { hint: \"SDK docs with an install page\", label: \"sdk\", value: \"sdk\" },\n {\n hint: \"Docs plus a changelog tab\",\n label: \"changelog\",\n value: \"changelog\",\n },\n ],\n }));\n if (cancelled(template)) {\n return null;\n }\n\n const picked = await prompter.multiselect({\n initialValues: [\"filesystem\"],\n message: \"Where does your content live?\",\n options: [\n { hint: \"Local .mdx files\", label: \"filesystem\", value: \"filesystem\" },\n { hint: \"An Obsidian vault\", label: \"obsidian\", value: \"obsidian\" },\n {\n hint: \"Changelog from GitHub Releases\",\n label: \"github-releases\",\n value: \"github-releases\",\n },\n { hint: \"A Notion database\", label: \"notion\", value: \"notion\" },\n { hint: \"A Sanity dataset\", label: \"sanity\", value: \"sanity\" },\n {\n hint: \"A Contentful content type\",\n label: \"contentful\",\n value: \"contentful\",\n },\n { hint: \"A Payload collection\", label: \"payload\", value: \"payload\" },\n { hint: \"A Strapi content type\", label: \"strapi\", value: \"strapi\" },\n {\n hint: \"MDX fetched from a GitHub repo\",\n label: \"mdx-remote\",\n value: \"mdx-remote\",\n },\n ],\n required: false,\n });\n if (cancelled(picked)) {\n return null;\n }\n // No selection desugars to the implicit local source, same as the schema.\n const sources: SourceKind[] = picked.length === 0 ? [\"filesystem\"] : picked;\n\n let contentDir = flags.contentDir ?? \"docs\";\n if (flags.contentDir === undefined && sources.includes(\"filesystem\")) {\n const answer = await prompter.text({\n defaultValue: \"docs\",\n message: \"Content directory?\",\n placeholder: \"docs\",\n validate: (value) => validateContentDir(root, value || \"docs\"),\n });\n if (cancelled(answer)) {\n return null;\n }\n contentDir = answer;\n }\n\n return {\n contentDir,\n directory,\n packageManager:\n flags.packageManager ?? detectPackageManager(defaults.userAgent),\n sources,\n template,\n title,\n };\n};\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "E14485B14C8DBCED64756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "937A77D93EDC0DE164756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  loadConfig
4
- } from "./chunk-xkz5xbtv.js";
4
+ } from "./chunk-ehweg4fr.js";
5
5
  import"./chunk-zccbjcj0.js";
6
6
  import {
7
7
  commandMeta,
@@ -11,11 +11,11 @@ import {
11
11
  reportDiagnostics
12
12
  } from "./index.js";
13
13
  import"./chunk-jq5n4avg.js";
14
- import"./chunk-43zcf4gz.js";
14
+ import"./chunk-ncj7w596.js";
15
15
  import {
16
16
  CutError,
17
17
  cutVersion
18
- } from "./chunk-e7vvk5ya.js";
18
+ } from "./chunk-sds923fa.js";
19
19
 
20
20
  // src/cli/commands/version.ts
21
21
  import { defineCommand } from "citty";
@@ -88,4 +88,4 @@ export {
88
88
  };
89
89
 
90
90
  //# debugId=86F69482E9E3E55264756E2164756E21
91
- //# sourceMappingURL=chunk-5wj2qwn2.js.map
91
+ //# sourceMappingURL=chunk-ft9vfys6.js.map
@@ -8,14 +8,15 @@ import {
8
8
  fontLocaleCodes,
9
9
  buildFontEntries,
10
10
  isPatternPath,
11
- compileRedirects,
11
+ compileEveryRedirect,
12
12
  hasVariables,
13
13
  SVG_ASSET_HEADERS,
14
14
  applyBaseToAstroRedirects,
15
+ withMirrorRedirects,
15
16
  distDir,
16
17
  adapterRoot,
17
18
  deployPlatform
18
- } from "./chunk-xkz5xbtv.js";
19
+ } from "./chunk-ehweg4fr.js";
19
20
  import {
20
21
  trimChar,
21
22
  normalizeBasePath
@@ -34,7 +35,7 @@ var deployOutputDir = (config, context) => {
34
35
  };
35
36
  var deployStaticDir = (config, context) => {
36
37
  const { deployment } = config;
37
- return deployment.options.output === "server" ? deployPlatform(deployment).serverStaticDir(context) : distDir(context);
38
+ return deployment.options.output === "server" ? deployPlatform(deployment).serverStaticDir(context, normalizeBasePath(deployment.options.base)) : distDir(context);
38
39
  };
39
40
  var surfaceAdapterOutput = async (config, context) => {
40
41
  const { deployment } = config;
@@ -219,6 +220,10 @@ import { existsSync as existsSync2, readFileSync } from "node:fs";
219
220
  import { pathToFileURL } from "node:url";
220
221
  import { dirname as dirname2, isAbsolute as isAbsolute2, join as join3, relative as relative2 } from "pathe";
221
222
 
223
+ // src/ai/ask-limits.ts
224
+ var ASK_MAX_MESSAGES = 40;
225
+ var ASK_MAX_MESSAGES_CHARS = 24000;
226
+
222
227
  // src/consent/clients.ts
223
228
  var CONSENT_CLIENT_MODULES = new Map([
224
229
  ["native", "blume/components/layout/consent/native.ts"]
@@ -273,13 +278,13 @@ var renderAstroAdapter = (deployment, context, ejected) => {
273
278
  const { astro } = platform;
274
279
  const args = {
275
280
  ...astro.options(context),
276
- ...deployPassthrough(deployment.options)
281
+ ...deployPassthrough(deployment.options, astro.configOptions)
277
282
  };
278
283
  const argsLiteral = Object.keys(args).length > 0 ? JSON.stringify(args) : "";
279
284
  const construct = `adapter(${argsLiteral})`;
280
285
  const expression = platform.hiddenRuntime.showProjectRoot && !ejected ? `withAdapterRoot(${construct}, ${JSON.stringify(adapterRoot(context))})` : construct;
281
286
  return {
282
- configEntries: Object.entries(astro.config).map(([key, value]) => `
287
+ configEntries: Object.entries(astro.config(deployment.options)).map(([key, value]) => `
283
288
  ${key}: ${JSON.stringify(value)},`).join(""),
284
289
  importLine: `import adapter from "${astro.package}";
285
290
  `,
@@ -338,7 +343,7 @@ var RENDER_EXTERNAL_DEPS = [
338
343
  ];
339
344
  var renderUserAliases = (aliases) => Object.entries(aliases ?? {}).toSorted(([a], [b]) => b.length - a.length).map(([find, replacement]) => `
340
345
  ${JSON.stringify(find)}: ${JSON.stringify(replacement)},`).join("");
341
- var REACT_EXCLUDE = String.raw`exclude: [/\/node_modules\/\.vite\//, /\/\.cache\/vite\//]`;
346
+ var REACT_EXCLUDE = String.raw`exclude: [/\/\.cache\/vite\//]`;
342
347
  var runtimeCacheOptions = (context, generatedModulesDir) => {
343
348
  if (generatedModulesDir !== undefined) {
344
349
  return { astro: "", vite: "" };
@@ -350,7 +355,7 @@ var runtimeCacheOptions = (context, generatedModulesDir) => {
350
355
  cacheDir: ${JSON.stringify(`${context.outDir}/.cache/vite`)},`
351
356
  };
352
357
  };
353
- var reactIntegration = (compilerPath) => compilerPath ? `react({ babel: { plugins: [[${JSON.stringify(compilerPath)}, { target: "19" }]] }, ${REACT_EXCLUDE} })` : `react({ ${REACT_EXCLUDE} })`;
358
+ var reactIntegration = (compiler) => compiler ? `react({ compiler: true, ${REACT_EXCLUDE} })` : `react({ ${REACT_EXCLUDE} })`;
354
359
  var renderIntegrationBridge = (bridge) => {
355
360
  if (!bridge) {
356
361
  return {
@@ -396,7 +401,7 @@ var resolveOptimizeDeps = (options) => {
396
401
  ...features.mermaid ? ["blume > mermaid"] : [],
397
402
  ...features.epub ? ["blume > epub-gen-memory/bundle"] : [],
398
403
  ...searchDep ? [`blume > ${searchDep}`] : [],
399
- ...options.needsReact && options.reactCompilerPath ? ["react/compiler-runtime"] : []
404
+ ...options.needsReact && options.reactCompiler ? ["react/compiler-runtime"] : []
400
405
  ];
401
406
  return { optimizeDepsEntries, optimizeDepsInclude };
402
407
  };
@@ -465,7 +470,7 @@ var astroConfigTemplate = (options) => {
465
470
  context,
466
471
  features,
467
472
  needsReact,
468
- reactCompilerPath: options.reactCompilerPath,
473
+ reactCompiler: options.reactCompiler,
469
474
  searchKind: config.search.provider.kind
470
475
  });
471
476
  const {
@@ -486,7 +491,8 @@ var astroConfigTemplate = (options) => {
486
491
  prefixDefaultLocale: !config.i18n.hideDefaultLocalePrefix
487
492
  }
488
493
  })},` : "";
489
- const basedRedirects = applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.options.base ?? "", new Set(contentRoutes));
494
+ const redirectPages = new Set(contentRoutes);
495
+ const basedRedirects = withMirrorRedirects(applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.options.base ?? "", redirectPages), redirectPages, { from: "", to: normalizeBasePath(deployment.options.base) });
490
496
  const exactRedirects = basedRedirects.filter((redirect) => !isPatternPath(redirect.from));
491
497
  const redirectsOption = exactRedirects.length > 0 ? `
492
498
  redirects: ${JSON.stringify(Object.fromEntries(exactRedirects.map((redirect) => [
@@ -547,7 +553,7 @@ var astroConfigTemplate = (options) => {
547
553
  `mdx({ processor: blumeMdxProcessor(${processorOptions}) })`
548
554
  ];
549
555
  if (needsReact) {
550
- integrations.push(reactIntegration(options.reactCompilerPath));
556
+ integrations.push(reactIntegration(options.reactCompiler));
551
557
  }
552
558
  if (needsVue) {
553
559
  integrations.push("vue()");
@@ -560,7 +566,7 @@ var astroConfigTemplate = (options) => {
560
566
  contentRoutes,
561
567
  ejected,
562
568
  pages,
563
- redirects: compileRedirects(basedRedirects)
569
+ redirects: compileEveryRedirect(basedRedirects)
564
570
  }))})`);
565
571
  const {
566
572
  configSourceMarker,
@@ -625,8 +631,8 @@ ${userConfigSetup}export default defineConfig({
625
631
  // Everything hydration can reach must be part of the dev dep optimizer's
626
632
  // FIRST run. The Vite root is the generated runtime, so user pages,
627
633
  // islands, and aliased components live outside it and are only crawled
628
- // when first requested — and \`react/compiler-runtime\` is Babel-injected,
629
- // so no source scan can ever see it. A dependency discovered after
634
+ // when first requested — and \`react/compiler-runtime\` is injected by the
635
+ // React Compiler, so no source scan can ever see it. A dependency discovered after
630
636
  // hydration begins triggers a mid-session re-optimization whose new
631
637
  // generation imports React through new \`?v=\` URLs; the browser then
632
638
  // evaluates a second React copy and every island tears down with
@@ -880,7 +886,7 @@ ${limit.check} const text = await readCappedText(request, ${ASK_BODY_LIMIT_BYTE
880
886
  const valid =
881
887
  Array.isArray(raw) &&
882
888
  raw.length > 0 &&
883
- raw.length <= 40 &&
889
+ raw.length <= ${ASK_MAX_MESSAGES} &&
884
890
  raw.every(
885
891
  (m: unknown) =>
886
892
  typeof m === "object" &&
@@ -888,10 +894,10 @@ ${limit.check} const text = await readCappedText(request, ${ASK_BODY_LIMIT_BYTE
888
894
  ("role" in m && (m.role === "user" || m.role === "assistant")) &&
889
895
  ("content" in m && typeof m.content === "string")
890
896
  ) &&
891
- JSON.stringify(raw).length <= 24_000;
897
+ JSON.stringify(raw).length <= ${ASK_MAX_MESSAGES_CHARS};
892
898
  if (!valid) {
893
899
  return new Response(
894
- "Invalid request: send 1-40 user/assistant messages with string content.",
900
+ "Invalid request: send 1-${ASK_MAX_MESSAGES} user/assistant messages with string content.",
895
901
  { status: 400 }
896
902
  );
897
903
  }
@@ -1034,10 +1040,11 @@ var searchClientTemplate = (config) => {
1034
1040
  return hostedSearchClient(provider);
1035
1041
  }
1036
1042
  case "server": {
1037
- return `${SEARCH_CLIENT_HEADER}${searchClientImport("endpoint")}${SEARCH_BASE_IMPORT}
1043
+ return `${SEARCH_CLIENT_HEADER}${searchClientImport("endpoint")}${SEARCH_BASE_IMPORT}import type { SearchClientOptions } from "blume/components/layout/search/types.ts";
1038
1044
  const api = joinBase(import.meta.env.BASE_URL, "api/search");
1039
1045
 
1040
- export const createSearch = () => create({ api });
1046
+ export const createSearch = (options: SearchClientOptions = {}) =>
1047
+ create({ ...options, api });
1041
1048
  `;
1042
1049
  }
1043
1050
  case "pagefind": {
@@ -1054,7 +1061,8 @@ export const createSearch = () => create({ url });
1054
1061
  }
1055
1062
  }
1056
1063
  };
1057
- var mixedbreadSearchEndpointTemplate = (options, rateLimit) => {
1064
+ var mixedbreadSearchEndpointTemplate = (options, pages, rateLimit) => {
1065
+ const { search_options: tuning, storeId, ...searchOptions } = options;
1058
1066
  const limit = rateLimitTemplate(rateLimit, "search");
1059
1067
  const imports = [
1060
1068
  'import type { APIRoute } from "astro";',
@@ -1070,9 +1078,26 @@ ${imports.join(`
1070
1078
  export const prerender = false;
1071
1079
 
1072
1080
  const client = new Mixedbread({ apiKey: getSecret("MIXEDBREAD_API_KEY") ?? "" });
1073
- const OPTIONS = ${JSON.stringify(options)};
1074
- // Every option besides the store reaches the search call verbatim.
1075
- const { storeId: STORE_ID, ...SEARCH_OPTIONS } = OPTIONS;
1081
+ const STORE_ID = ${JSON.stringify(storeId)};
1082
+ // Every other option reaches the search call verbatim.
1083
+ const SEARCH_OPTIONS = ${JSON.stringify(searchOptions)};
1084
+ const SEARCH_TUNING = ${JSON.stringify(tuning ?? {})};
1085
+ // Each page's source file, relative to the project root, and the page it renders.
1086
+ const PAGES = new Map<string, { title: string; url: string }>(${JSON.stringify(pages)});
1087
+
1088
+ // The page a synced file renders. \`mxbai store sync\` records the path
1089
+ // relative to where it ran (the project root, or a monorepo root above it), so
1090
+ // the longest trailing run of that path that names a page's file wins.
1091
+ const pageFor = (path: string) => {
1092
+ const segments = path.replaceAll("\\\\", "/").split("/");
1093
+ for (let start = 0; start < segments.length; start += 1) {
1094
+ const page = PAGES.get(segments.slice(start).join("/"));
1095
+ if (page) {
1096
+ return page;
1097
+ }
1098
+ }
1099
+ return undefined;
1100
+ };
1076
1101
  ${limit.setup}
1077
1102
  export const POST: APIRoute = async (context) => {
1078
1103
  const { request } = context;
@@ -1098,23 +1123,32 @@ ${limit.check} // A search body is one short query: read it under a 16 KB cap,
1098
1123
  });
1099
1124
  }
1100
1125
  // \`top_k\` defaults to 8 unless an option sets it; the query and store
1101
- // always come from the request and \`storeId\`.
1126
+ // always come from the request and \`storeId\`. File metadata is always
1127
+ // returned: it holds the path \`mxbai store sync\` recorded for the file.
1102
1128
  const response = await client.stores.search({
1103
1129
  top_k: 8,
1104
1130
  ...SEARCH_OPTIONS,
1105
1131
  query,
1132
+ search_options: { ...SEARCH_TUNING, return_metadata: true },
1106
1133
  store_identifiers: [STORE_ID],
1107
1134
  });
1108
- const hits = (response.data ?? []).map((chunk) => {
1135
+ const seen = new Set<string>();
1136
+ const hits = (response.data ?? []).flatMap((chunk) => {
1137
+ const { file_path: path } = (chunk.metadata ?? {}) as { file_path?: unknown };
1138
+ const page = typeof path === "string" ? pageFor(path) : undefined;
1139
+ // A file no page renders has nowhere to link, and a page's later chunks
1140
+ // would repeat it: one hit per page, at its best chunk.
1141
+ if (!page || seen.has(page.url)) {
1142
+ return [];
1143
+ }
1144
+ seen.add(page.url);
1109
1145
  const meta = chunk.generated_metadata ?? {};
1110
1146
  // Only a text chunk carries \`text\`; image, audio, and video chunks fall
1111
1147
  // back to the excerpt the store generated for them.
1112
1148
  const text = "text" in chunk ? chunk.text : undefined;
1113
- return {
1114
- excerpt: text ?? meta.excerpt ?? "",
1115
- title: meta.title ?? chunk.filename ?? "",
1116
- url: meta.url ?? "",
1117
- };
1149
+ return [
1150
+ { excerpt: text ?? meta.excerpt ?? "", title: page.title, url: page.url },
1151
+ ];
1118
1152
  });
1119
1153
  return new Response(JSON.stringify(hits), {
1120
1154
  headers: { "Content-Type": "application/json" },
@@ -1629,6 +1663,7 @@ import type { CollectionKey } from "astro:content";
1629
1663
  import RootLayout from "blume/components/layout/RootLayout.astro";
1630
1664
  import { withBase, withMountedBase } from "blume/components/islands/base-path.ts";
1631
1665
  import { mountBasePath, stripBasePath } from "blume/core/base-path.ts";
1666
+ import { routeSetFor, servesRoute } from "blume/core/locale-links.ts";
1632
1667
  import { resolveSlot } from "blume/components/layout/overrides.ts";
1633
1668
  ${componentImports}
1634
1669
  import data from "blume:data";
@@ -1832,18 +1867,24 @@ const logicalRoute = i18n
1832
1867
  ? stripLocale(stripBasePath(data.config.basePath, route), locale)
1833
1868
  : route;
1834
1869
  // A page from a one-language source (GitHub Releases) gets no switcher: every
1835
- // other locale would only repeat the same text.
1870
+ // other locale would only repeat the same text. A locale with no real
1871
+ // translation links the page's fallback copy, which exists only while
1872
+ // fallbacks are on; where nothing is served at that URL (\`fallbackLocale:
1873
+ // null\`), the locale is left out rather than linked to a 404.
1836
1874
  const localeSwitch = i18n && !monolingual
1837
- ? i18n.locales.map((l) => {
1875
+ ? i18n.locales.flatMap((l) => {
1838
1876
  const alt = (alternates ?? []).find((x) => x.locale === l.code);
1839
- return {
1840
- code: l.code,
1841
- current: l.code === locale,
1842
- dir: l.dir,
1843
- href: alt ? alt.path : mountLocalized(logicalRoute, l.code),
1844
- label: l.label,
1845
- untranslated: !alt,
1846
- };
1877
+ const href = alt ? alt.path : mountLocalized(logicalRoute, l.code);
1878
+ return alt || servesRoute(routeSetFor(data.routes), href)
1879
+ ? [{
1880
+ code: l.code,
1881
+ current: l.code === locale,
1882
+ dir: l.dir,
1883
+ href,
1884
+ label: l.label,
1885
+ untranslated: !alt,
1886
+ }]
1887
+ : [];
1847
1888
  })
1848
1889
  : [];
1849
1890
 
@@ -2143,13 +2184,15 @@ const canonical = base ? base + basedRoute : null;
2143
2184
  const ogPath = data.config.og.enabled ? withMountedBase("/og/changelog.png") : null;
2144
2185
  const ogImage = ogPath && base ? base + ogPath : ogPath;
2145
2186
 
2146
- // The page chrome (h1, title, description) comes from the translatable
2147
- // \`changelog\` group; optional chaining tolerates a not-yet-regenerated data
2148
- // snapshot from before these keys existed.
2187
+ // The page chrome (h1, title, description, empty state) comes from the
2188
+ // translatable \`changelog\` group, which carries the \`changelog\` config's title and
2189
+ // description when it sets them; optional chaining tolerates a
2190
+ // not-yet-regenerated data snapshot from before these keys existed.
2149
2191
  const changelogTitle = data.ui.changelog?.title ?? "Changelog";
2150
2192
  const changelogDescription =
2151
2193
  data.ui.changelog?.description ??
2152
2194
  "Product updates, new features, and fixes from every release.";
2195
+ const changelogEmpty = data.ui.changelog?.empty ?? "No changelog entries yet.";
2153
2196
  // The layout suffixes "- {site title}" itself, so the page title is just the
2154
2197
  // changelog's own name — prefixing the site title too would double it
2155
2198
  // ("Acme Changelog - Acme").
@@ -2202,7 +2245,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
2202
2245
  <p class="text-lg text-muted-foreground">{changelogDescription}</p>
2203
2246
  {
2204
2247
  items.length === 0 ? (
2205
- <p>No changelog entries yet.</p>
2248
+ <p>{changelogEmpty}</p>
2206
2249
  ) : (
2207
2250
  <div class="not-prose mt-10 divide-y divide-border border-border border-y">
2208
2251
  {groups.map((group) => (
@@ -2755,5 +2798,5 @@ var runtimeTsconfigTemplate = () => `${JSON.stringify({
2755
2798
 
2756
2799
  export { deployOutputDir, deployStaticDir, surfaceAdapterOutput, planComponentSlots, publishRuntimeModules, runtimeDependencies, EJECTED_CONFIG_HEADER, astroConfigTemplate, stagedContentDir, contentConfigTemplate, askEndpointTemplate, askComponentTemplate, searchEndpointTemplate, featuresTemplate, consentClientTemplate, searchClientTemplate, mixedbreadSearchEndpointTemplate, rawMarkdownEndpointTemplate, contentAssetsEndpointTemplate, mcpPageFile, mcpEndpointTemplate, playgroundProxyTemplate, staticJsonEndpointTemplate, rssEndpointTemplate, navFragmentTemplate, ogEndpointTemplate, scalarReferenceTemplate, catchAllPageTemplate, changelogIndexTemplate, notFoundPageTemplate, notFoundMarkdownTemplate, notFoundJsonTemplate, apiPagesIndexTemplate, apiPageTemplate, apiNavigationTemplate, apiSearchTemplate, apiNotFoundTemplate, exampleSlug, exampleWrapperTemplate, examplesRouteBase, exampleMapTemplate, examplesPageTemplate, runtimePackageTemplate, runtimeTsconfigTemplate };
2757
2800
 
2758
- //# debugId=F21B5F971981289464756E2164756E21
2759
- //# sourceMappingURL=chunk-4h8z9vv5.js.map
2801
+ //# debugId=5E4553A34E0C7B9D64756E2164756E21
2802
+ //# sourceMappingURL=chunk-gb420vvz.js.map