blume 2.0.3 → 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 (607) hide show
  1. package/AGENTS.md +1 -0
  2. package/CHANGELOG.md +142 -0
  3. package/README.md +1 -1
  4. package/dist/cli/{chunk-5f86nr5m.js → chunk-073rdvgb.js} +21 -48
  5. package/dist/cli/{chunk-5f86nr5m.js.map → chunk-073rdvgb.js.map} +4 -5
  6. package/dist/cli/{chunk-ga0pf4aj.js → chunk-0n9xkp3d.js} +12 -3
  7. package/dist/cli/{chunk-ga0pf4aj.js.map → chunk-0n9xkp3d.js.map} +3 -3
  8. package/dist/cli/chunk-150jk7km.js +52 -0
  9. package/dist/cli/chunk-150jk7km.js.map +10 -0
  10. package/dist/cli/{chunk-9t7a85s3.js → chunk-313vnn40.js} +30 -19
  11. package/dist/cli/chunk-313vnn40.js.map +10 -0
  12. package/dist/cli/{chunk-tkacnehg.js → chunk-3v3ffbrj.js} +2 -2
  13. package/dist/cli/{chunk-q58y5e6a.js → chunk-3x6x3pph.js} +46 -24
  14. package/dist/cli/chunk-3x6x3pph.js.map +10 -0
  15. package/dist/cli/{chunk-1d7ve1dm.js → chunk-42t4jxdx.js} +37 -5
  16. package/dist/cli/chunk-42t4jxdx.js.map +12 -0
  17. package/dist/cli/{chunk-8ktnccpt.js → chunk-54ztw1nj.js} +21 -2
  18. package/dist/cli/chunk-54ztw1nj.js.map +10 -0
  19. package/dist/cli/{chunk-hm3vjy5s.js → chunk-5vjtgs6e.js} +28 -10
  20. package/dist/cli/{chunk-hm3vjy5s.js.map → chunk-5vjtgs6e.js.map} +4 -4
  21. package/dist/cli/chunk-66w9j7p6.js +322 -0
  22. package/dist/cli/chunk-66w9j7p6.js.map +14 -0
  23. package/dist/cli/{chunk-2hsdwb9n.js → chunk-7ppf1rva.js} +34 -18
  24. package/dist/cli/chunk-7ppf1rva.js.map +10 -0
  25. package/dist/cli/{chunk-r9rcc4w7.js → chunk-8y2kmjv8.js} +7 -7
  26. package/dist/cli/{chunk-r20tn01b.js → chunk-c1y538kd.js} +8 -2
  27. package/dist/cli/{chunk-r20tn01b.js.map → chunk-c1y538kd.js.map} +3 -3
  28. package/dist/cli/{chunk-2eytanqx.js → chunk-c887fj0s.js} +2 -2
  29. package/dist/cli/{chunk-p3v96n38.js → chunk-cfyg47zg.js} +16 -6
  30. package/dist/cli/chunk-cfyg47zg.js.map +10 -0
  31. package/dist/cli/chunk-cm89scdv.js +443 -0
  32. package/dist/cli/chunk-cm89scdv.js.map +11 -0
  33. package/dist/cli/{chunk-akbpwfxc.js → chunk-dzwehpy7.js} +2 -2
  34. package/dist/cli/{chunk-wrr3j9w9.js → chunk-e6atmn4h.js} +299 -72
  35. package/dist/cli/chunk-e6atmn4h.js.map +36 -0
  36. package/dist/cli/{chunk-tzmab476.js → chunk-e8xw9qkh.js} +8 -6
  37. package/dist/cli/{chunk-tzmab476.js.map → chunk-e8xw9qkh.js.map} +3 -3
  38. package/dist/cli/{chunk-6dsbexzp.js → chunk-e9q7a2ak.js} +17 -15
  39. package/dist/cli/{chunk-6dsbexzp.js.map → chunk-e9q7a2ak.js.map} +2 -2
  40. package/dist/cli/{chunk-pv29h0wf.js → chunk-ehweg4fr.js} +5155 -1249
  41. package/dist/cli/chunk-ehweg4fr.js.map +218 -0
  42. package/dist/cli/{chunk-c8chx29p.js → chunk-ep6nd0rn.js} +390 -318
  43. package/dist/cli/chunk-ep6nd0rn.js.map +36 -0
  44. package/dist/cli/{chunk-p73c0m7w.js → chunk-fdrkhpjy.js} +18 -15
  45. package/dist/cli/{chunk-p73c0m7w.js.map → chunk-fdrkhpjy.js.map} +3 -3
  46. package/dist/cli/{chunk-2z928egk.js → chunk-ft9vfys6.js} +5 -5
  47. package/dist/cli/{chunk-5m5nmvyq.js → chunk-gb420vvz.js} +316 -79
  48. package/dist/cli/chunk-gb420vvz.js.map +17 -0
  49. package/dist/cli/{chunk-vg9r4eb9.js → chunk-hebn0tpx.js} +86 -13
  50. package/dist/cli/chunk-hebn0tpx.js.map +14 -0
  51. package/dist/cli/{chunk-35d4wj9f.js → chunk-htrwgabr.js} +41 -23
  52. package/dist/cli/chunk-htrwgabr.js.map +15 -0
  53. package/dist/cli/{chunk-g4hq16wv.js → chunk-hx3xqnk9.js} +16 -14
  54. package/dist/cli/{chunk-g4hq16wv.js.map → chunk-hx3xqnk9.js.map} +2 -2
  55. package/dist/cli/chunk-j134vrp2.js +65 -0
  56. package/dist/cli/chunk-j134vrp2.js.map +10 -0
  57. package/dist/cli/{chunk-a58773jm.js → chunk-kma9f6sf.js} +2 -2
  58. package/dist/cli/chunk-kwrg63tm.js +31 -0
  59. package/dist/cli/chunk-kwrg63tm.js.map +10 -0
  60. package/dist/cli/{chunk-ey84smr6.js → chunk-mrcccgnh.js} +6 -6
  61. package/dist/cli/{chunk-ey84smr6.js.map → chunk-mrcccgnh.js.map} +1 -1
  62. package/dist/cli/{chunk-yfyb25rh.js → chunk-n0v7m8ry.js} +24 -8
  63. package/dist/cli/chunk-n0v7m8ry.js.map +14 -0
  64. package/dist/cli/{chunk-j85vccga.js → chunk-ncj7w596.js} +576 -367
  65. package/dist/cli/chunk-ncj7w596.js.map +35 -0
  66. package/dist/cli/{chunk-5xvm6tfj.js → chunk-nq1d20w2.js} +17 -15
  67. package/dist/cli/{chunk-5xvm6tfj.js.map → chunk-nq1d20w2.js.map} +2 -2
  68. package/dist/cli/{chunk-pehfxfta.js → chunk-nrns10mj.js} +6 -98
  69. package/dist/cli/chunk-nrns10mj.js.map +10 -0
  70. package/dist/cli/{chunk-crgn1q09.js → chunk-sds923fa.js} +4 -4
  71. package/dist/cli/chunk-t2m5j4pr.js +104 -0
  72. package/dist/cli/chunk-t2m5j4pr.js.map +11 -0
  73. package/dist/cli/{chunk-acanzt5p.js → chunk-tdqhyxfz.js} +6 -6
  74. package/dist/cli/chunk-tphac74f.js +126 -0
  75. package/dist/cli/chunk-tphac74f.js.map +11 -0
  76. package/dist/cli/chunk-w1r4vase.js +18 -0
  77. package/dist/cli/chunk-w1r4vase.js.map +10 -0
  78. package/dist/cli/{chunk-3em5wd2y.js → chunk-zccbjcj0.js} +4 -3
  79. package/dist/cli/{chunk-3em5wd2y.js.map → chunk-zccbjcj0.js.map} +2 -2
  80. package/dist/cli/index.js +31 -20
  81. package/dist/cli/index.js.map +5 -5
  82. package/dist/types/ai/agent-surface.d.ts +8 -7
  83. package/dist/types/ai/ai-catalog.d.ts +7 -0
  84. package/dist/types/ai/ask-context.d.ts +26 -0
  85. package/dist/types/ai/ask.d.ts +271 -58
  86. package/dist/types/ai/component-markdown.d.ts +2 -0
  87. package/dist/types/ai/index.d.ts +2 -2
  88. package/dist/types/ai/openapi-components.d.ts +4 -1
  89. package/dist/types/ai/site-skill.d.ts +26 -0
  90. package/dist/types/ai/skills.d.ts +16 -0
  91. package/dist/types/astro/integration.d.ts +9 -0
  92. package/dist/types/astro/markdown-negotiation.d.ts +3 -0
  93. package/dist/types/astro/pages.d.ts +10 -0
  94. package/dist/types/captcha/hcaptcha.d.ts +27 -0
  95. package/dist/types/captcha/index.d.ts +28 -0
  96. package/dist/types/captcha/schema.d.ts +29 -0
  97. package/dist/types/captcha/turnstile.d.ts +28 -0
  98. package/dist/types/cli/init/scaffold.d.ts +1 -1
  99. package/dist/types/components/content/api-field.d.ts +62 -0
  100. package/dist/types/components/content/api-page.d.ts +100 -0
  101. package/dist/types/components/layout/nav-utils.d.ts +26 -0
  102. package/dist/types/components/openapi/code-samples.d.ts +29 -0
  103. package/dist/types/components/openapi/helpers.d.ts +158 -0
  104. package/dist/types/components/openapi/security.d.ts +95 -0
  105. package/dist/types/components/openapi/snippets.d.ts +60 -0
  106. package/dist/types/consent/ethyca.d.ts +48 -0
  107. package/dist/types/consent/index.d.ts +37 -0
  108. package/dist/types/consent/native.d.ts +28 -0
  109. package/dist/types/consent/osano.d.ts +42 -0
  110. package/dist/types/consent/schema.d.ts +110 -0
  111. package/dist/types/core/changelog-index.d.ts +8 -0
  112. package/dist/types/core/config-input.d.ts +217 -23
  113. package/dist/types/core/data.d.ts +53 -4
  114. package/dist/types/core/footer.d.ts +8 -0
  115. package/dist/types/core/i18n-ui.d.ts +88 -0
  116. package/dist/types/core/includes.d.ts +8 -2
  117. package/dist/types/core/links.d.ts +8 -0
  118. package/dist/types/core/localizable.d.ts +7 -0
  119. package/dist/types/core/page-modes.d.ts +29 -0
  120. package/dist/types/core/probe.d.ts +2 -0
  121. package/dist/types/core/project-graph.d.ts +6 -0
  122. package/dist/types/core/redirect-patterns.d.ts +152 -0
  123. package/dist/types/core/related.d.ts +40 -0
  124. package/dist/types/core/schema.d.ts +670 -56
  125. package/dist/types/core/sources/cache.d.ts +3 -0
  126. package/dist/types/core/sources/contentful-rich-text.d.ts +11 -2
  127. package/dist/types/core/sources/contentful.d.ts +17 -1
  128. package/dist/types/core/sources/lexical.d.ts +5 -0
  129. package/dist/types/core/sources/normalize.d.ts +20 -1
  130. package/dist/types/core/sources/read.d.ts +5 -0
  131. package/dist/types/core/sources/remote.d.ts +37 -10
  132. package/dist/types/core/sources/sanity.d.ts +1 -1
  133. package/dist/types/core/types.d.ts +18 -1
  134. package/dist/types/core/variables.d.ts +42 -0
  135. package/dist/types/deploy/adapter-output.d.ts +2 -1
  136. package/dist/types/deploy/adapters/cloudflare.d.ts +7 -5
  137. package/dist/types/deploy/adapters/node.d.ts +58 -23
  138. package/dist/types/deploy/adapters/registry.d.ts +10 -0
  139. package/dist/types/deploy/adapters/types.d.ts +3 -2
  140. package/dist/types/deploy/node-headers.d.ts +13 -2
  141. package/dist/types/deploy/platforms/cloudflare.d.ts +15 -7
  142. package/dist/types/deploy/platforms/netlify.d.ts +7 -0
  143. package/dist/types/deploy/platforms/node.d.ts +3 -1
  144. package/dist/types/deploy/platforms/types.d.ts +18 -7
  145. package/dist/types/deploy/platforms/vercel.d.ts +26 -1
  146. package/dist/types/deploy/redirects.d.ts +55 -11
  147. package/dist/types/deploy/sitemap.d.ts +2 -1
  148. package/dist/types/deploy/vercel-negotiation.d.ts +51 -21
  149. package/dist/types/markdown/code-title.d.ts +17 -0
  150. package/dist/types/markdown/features.d.ts +3 -2
  151. package/dist/types/narration/build.d.ts +70 -0
  152. package/dist/types/narration/provider.d.ts +26 -0
  153. package/dist/types/narration/script.d.ts +154 -0
  154. package/dist/types/openapi/checks.d.ts +27 -0
  155. package/dist/types/openapi/graphql.d.ts +6 -0
  156. package/dist/types/openapi/model.d.ts +27 -10
  157. package/dist/types/openapi/overlay.d.ts +54 -0
  158. package/dist/types/openapi/parse.d.ts +16 -0
  159. package/dist/types/openapi/references.d.ts +30 -4
  160. package/dist/types/ratelimit/cloudflare.d.ts +39 -0
  161. package/dist/types/ratelimit/index.d.ts +27 -0
  162. package/dist/types/ratelimit/memory.d.ts +36 -0
  163. package/dist/types/ratelimit/schema.d.ts +119 -0
  164. package/dist/types/ratelimit/upstash.d.ts +46 -0
  165. package/dist/types/ratelimit/wrangler.d.ts +23 -0
  166. package/dist/types/reference/asyncapi.d.ts +10 -10
  167. package/dist/types/reference/graphql.d.ts +89 -11
  168. package/dist/types/reference/index.d.ts +1 -1
  169. package/dist/types/reference/openapi.d.ts +33 -12
  170. package/dist/types/reference/options.d.ts +82 -6
  171. package/dist/types/reference/scalar.d.ts +13 -0
  172. package/dist/types/reference/schema.d.ts +144 -36
  173. package/dist/types/search/adapters/registry.d.ts +3 -0
  174. package/dist/types/search/adapters/typesense.d.ts +14 -4
  175. package/dist/types/search/build.d.ts +3 -1
  176. package/dist/types/search/documents.d.ts +12 -1
  177. package/dist/types/search/orama-index.d.ts +13 -9
  178. package/dist/types/search/sync/algolia.d.ts +5 -2
  179. package/dist/types/search/sync/index.d.ts +3 -1
  180. package/dist/types/search/sync/typesense.d.ts +11 -7
  181. package/dist/types/seo/metatags.d.ts +20 -0
  182. package/dist/types/sources/contentful.d.ts +16 -0
  183. package/dist/types/sources/github-releases.d.ts +8 -1
  184. package/dist/types/sources/payload.d.ts +2 -0
  185. package/dist/types/sources/registry.d.ts +54 -0
  186. package/dist/types/sources/shared.d.ts +3 -0
  187. package/dist/types/sources/strapi.d.ts +2 -0
  188. package/docs/01-quickstart.mdx +4 -2
  189. package/docs/02-deployment.mdx +71 -17
  190. package/docs/03-upgrading.mdx +4 -4
  191. package/docs/04-migrating.mdx +1 -1
  192. package/docs/advanced/changelog.mdx +13 -2
  193. package/docs/advanced/skills.mdx +15 -1
  194. package/docs/cli/audit.mdx +51 -8
  195. package/docs/cli/doctor.mdx +5 -1
  196. package/docs/cli/evals.mdx +4 -4
  197. package/docs/cli/index.mdx +1 -0
  198. package/docs/cli/translate.mdx +1 -0
  199. package/docs/cli/validate.mdx +4 -3
  200. package/docs/configuration/analytics.mdx +3 -1
  201. package/docs/configuration/assistant.mdx +194 -38
  202. package/docs/configuration/consent.mdx +100 -0
  203. package/docs/configuration/customization.mdx +8 -6
  204. package/docs/configuration/export.mdx +5 -3
  205. package/docs/configuration/index.mdx +64 -5
  206. package/docs/configuration/meta.ts +3 -0
  207. package/docs/configuration/narration.mdx +119 -0
  208. package/docs/configuration/rate-limiting.mdx +90 -0
  209. package/docs/configuration/search.mdx +63 -12
  210. package/docs/configuration/theming.mdx +3 -1
  211. package/docs/content/components.mdx +108 -2
  212. package/docs/content/frontmatter.mdx +80 -2
  213. package/docs/content/i18n.mdx +39 -4
  214. package/docs/content/includes.mdx +16 -0
  215. package/docs/content/meta.mdx +1 -0
  216. package/docs/content/meta.ts +1 -0
  217. package/docs/content/navigation.mdx +32 -10
  218. package/docs/content/sources/contentful.mdx +35 -0
  219. package/docs/content/sources/custom.mdx +43 -0
  220. package/docs/content/sources/github-releases.mdx +39 -0
  221. package/docs/content/sources/index.mdx +91 -0
  222. package/docs/content/sources/meta.ts +16 -0
  223. package/docs/content/sources/notion.mdx +32 -0
  224. package/docs/content/sources/obsidian.mdx +37 -0
  225. package/docs/content/sources/payload.mdx +31 -0
  226. package/docs/content/sources/remote-mdx.mdx +44 -0
  227. package/docs/content/sources/sanity.mdx +29 -0
  228. package/docs/content/sources/strapi.mdx +32 -0
  229. package/docs/content/syntax.mdx +69 -4
  230. package/docs/content/variables.mdx +41 -0
  231. package/docs/discoverability/agent-discovery.mdx +29 -2
  232. package/docs/discoverability/index.mdx +2 -2
  233. package/docs/discoverability/json-api.mdx +2 -0
  234. package/docs/discoverability/llms-txt.mdx +2 -2
  235. package/docs/discoverability/markdown.mdx +3 -1
  236. package/docs/discoverability/mcp.mdx +4 -0
  237. package/docs/discoverability/metadata.mdx +17 -0
  238. package/docs/discoverability/sitemap-and-robots.mdx +1 -1
  239. package/docs/references/api-pages.mdx +74 -0
  240. package/docs/references/asyncapi.mdx +4 -2
  241. package/docs/references/graphql.mdx +14 -2
  242. package/docs/references/meta.ts +1 -1
  243. package/docs/references/openapi.mdx +148 -7
  244. package/docs/references/scalar.mdx +3 -1
  245. package/package.json +43 -8
  246. package/skills/blume/SKILL.md +3 -0
  247. package/skills/blume-migrate/SKILL.md +6 -6
  248. package/skills/blume-migrate/references/docusaurus.md +7 -7
  249. package/skills/blume-migrate/references/fumadocs.md +17 -13
  250. package/skills/blume-migrate/references/mintlify.md +37 -19
  251. package/skills/blume-migrate/references/nextra.md +10 -7
  252. package/skills/blume-migrate/references/starlight.md +11 -8
  253. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +60 -14
  254. package/skills/blume-write-skill/SKILL.md +82 -0
  255. package/src/ai/agent-readability.ts +2 -1
  256. package/src/ai/agent-surface.ts +9 -7
  257. package/src/ai/ai-catalog.ts +6 -3
  258. package/src/ai/ask-context.ts +103 -20
  259. package/src/ai/ask-data.ts +6 -0
  260. package/src/ai/ask-limits.ts +13 -0
  261. package/src/ai/ask-tools.ts +142 -0
  262. package/src/ai/ask.ts +354 -76
  263. package/src/ai/changelog-markdown.ts +11 -6
  264. package/src/ai/component-markdown.ts +76 -1
  265. package/src/ai/cors.ts +14 -3
  266. package/src/ai/index.ts +12 -0
  267. package/src/ai/llms.ts +6 -2
  268. package/src/ai/markdown.ts +2 -1
  269. package/src/ai/mcp/data.ts +6 -0
  270. package/src/ai/mcp/query.ts +14 -6
  271. package/src/ai/openapi-components.ts +36 -6
  272. package/src/ai/relative-links.ts +4 -38
  273. package/src/ai/site-skill.ts +274 -0
  274. package/src/ai/skills.ts +35 -2
  275. package/src/ai/write-skill.ts +97 -0
  276. package/src/astro/generate.ts +210 -66
  277. package/src/astro/index.ts +1 -0
  278. package/src/astro/integration.ts +42 -4
  279. package/src/astro/markdown-negotiation.ts +3 -0
  280. package/src/astro/module-types.ts +9 -1
  281. package/src/astro/pages.ts +23 -0
  282. package/src/astro/templates.ts +406 -108
  283. package/src/astro/variables.ts +31 -0
  284. package/src/audit/catalog.ts +38 -3
  285. package/src/audit/checks/contrast.ts +183 -0
  286. package/src/audit/checks/i18n.ts +2 -3
  287. package/src/audit/checks/indexability.ts +2 -3
  288. package/src/audit/checks/links.ts +19 -13
  289. package/src/audit/checks/network.ts +110 -6
  290. package/src/audit/checks/redirects.ts +6 -4
  291. package/src/audit/checks/robots.ts +58 -2
  292. package/src/audit/checks/sitemap.ts +2 -3
  293. package/src/audit/redirects.ts +46 -15
  294. package/src/audit/run.ts +5 -0
  295. package/src/audit/types.ts +4 -1
  296. package/src/audit/url.ts +14 -5
  297. package/src/blume-modules.d.ts +12 -1
  298. package/src/captcha/client.ts +152 -0
  299. package/src/captcha/hcaptcha.ts +36 -0
  300. package/src/captcha/index.ts +28 -0
  301. package/src/captcha/schema.ts +32 -0
  302. package/src/captcha/turnstile.ts +38 -0
  303. package/src/captcha/verify.ts +71 -0
  304. package/src/cli/args.ts +51 -0
  305. package/src/cli/build-failure.ts +23 -0
  306. package/src/cli/command-meta.ts +5 -0
  307. package/src/cli/commands/audit.ts +10 -1
  308. package/src/cli/commands/dev.ts +18 -2
  309. package/src/cli/commands/doctor.ts +67 -28
  310. package/src/cli/commands/eval.ts +36 -4
  311. package/src/cli/commands/init.ts +6 -4
  312. package/src/cli/commands/skill.ts +96 -0
  313. package/src/cli/commands/validate.ts +10 -1
  314. package/src/cli/index.ts +5 -0
  315. package/src/cli/init/scaffold.ts +3 -3
  316. package/src/cli/prepare.ts +6 -3
  317. package/src/cli/required-secrets.ts +72 -30
  318. package/src/components/BlumePage.astro +2 -0
  319. package/src/components/content/ApiEndpoint.astro +18 -0
  320. package/src/components/content/ApiField.astro +79 -0
  321. package/src/components/content/ApiPlayground.astro +66 -0
  322. package/src/components/content/ApiRail.astro +19 -0
  323. package/src/components/content/Color.astro +1 -0
  324. package/src/components/content/FileTree.astro +1 -0
  325. package/src/components/content/GithubInfo.astro +1 -0
  326. package/src/components/content/Panel.astro +1 -0
  327. package/src/components/content/ParamField.astro +25 -0
  328. package/src/components/content/RequestExample.astro +17 -0
  329. package/src/components/content/ResponseExample.astro +17 -0
  330. package/src/components/content/ResponseField.astro +32 -0
  331. package/src/components/content/Step.astro +1 -0
  332. package/src/components/content/Tile.astro +1 -0
  333. package/src/components/content/Tooltip.astro +1 -0
  334. package/src/components/content/Tree.astro +1 -0
  335. package/src/components/content/TypeTable.astro +4 -1
  336. package/src/components/content/View.astro +21 -0
  337. package/src/components/content/ViewSwitcher.astro +168 -0
  338. package/src/components/content/api-field.ts +103 -0
  339. package/src/components/content/api-page.ts +248 -0
  340. package/src/components/content/mermaid-element.ts +15 -1
  341. package/src/components/content/view-switcher.ts +71 -0
  342. package/src/components/index.ts +2 -0
  343. package/src/components/islands/Assistant.astro +10 -1
  344. package/src/components/islands/assistant.tsx +104 -14
  345. package/src/components/islands/code-question.ts +62 -0
  346. package/src/components/islands/hooks.ts +136 -21
  347. package/src/components/islands/support-link.ts +68 -0
  348. package/src/components/layout/Analytics.astro +11 -2
  349. package/src/components/layout/Banner.astro +14 -10
  350. package/src/components/layout/Breadcrumbs.astro +6 -2
  351. package/src/components/layout/ConsentBanner.astro +62 -0
  352. package/src/components/layout/ConsentHead.astro +38 -0
  353. package/src/components/layout/Directory.astro +94 -0
  354. package/src/components/layout/DrawerSwitchers.astro +51 -0
  355. package/src/components/layout/Empty.astro +2 -2
  356. package/src/components/layout/Header.astro +122 -80
  357. package/src/components/layout/LanguageSwitcher.astro +48 -15
  358. package/src/components/layout/NarrationPlayer.astro +1085 -0
  359. package/src/components/layout/NavSelector.astro +33 -7
  360. package/src/components/layout/PageActions.astro +139 -24
  361. package/src/components/layout/PageFeedback.astro +54 -49
  362. package/src/components/layout/PageLayout.astro +71 -3
  363. package/src/components/layout/ReferenceLayout.astro +17 -6
  364. package/src/components/layout/RelatedPages.astro +42 -0
  365. package/src/components/layout/RootLayout.astro +318 -47
  366. package/src/components/layout/Search.astro +47 -19
  367. package/src/components/layout/SiteFooter.astro +124 -0
  368. package/src/components/layout/SiteMetatags.astro +16 -0
  369. package/src/components/layout/TableOfContents.astro +24 -17
  370. package/src/components/layout/consent/native.ts +79 -0
  371. package/src/components/layout/consent/types.ts +37 -0
  372. package/src/components/layout/footer-links.ts +53 -0
  373. package/src/components/layout/footer-socials.ts +87 -0
  374. package/src/components/layout/head-scripts.ts +6 -1
  375. package/src/components/layout/locale-redirect.ts +107 -0
  376. package/src/components/layout/nav-utils.ts +83 -0
  377. package/src/components/layout/page-feedback.ts +96 -0
  378. package/src/components/layout/search/algolia.ts +10 -1
  379. package/src/components/layout/search/analytics.ts +126 -0
  380. package/src/components/layout/search/endpoint.ts +48 -5
  381. package/src/components/layout/search/flexsearch.ts +17 -5
  382. package/src/components/layout/search/orama-cloud.ts +26 -14
  383. package/src/components/layout/search/pagefind.ts +114 -5
  384. package/src/components/layout/search/types.ts +32 -0
  385. package/src/components/layout/search/typesense.ts +19 -3
  386. package/src/components/openapi/AsyncApiOperation.astro +14 -7
  387. package/src/components/openapi/Authorization.astro +10 -0
  388. package/src/components/openapi/GraphqlOperation.astro +5 -0
  389. package/src/components/openapi/Operation.astro +184 -13
  390. package/src/components/openapi/ParametersTable.astro +8 -4
  391. package/src/components/openapi/Playground.astro +7 -1
  392. package/src/components/openapi/RequestBody.astro +24 -5
  393. package/src/components/openapi/RequestPanel.astro +59 -7
  394. package/src/components/openapi/Responses.astro +7 -4
  395. package/src/components/openapi/SchemaTable.astro +15 -3
  396. package/src/components/openapi/async-snippets.ts +65 -9
  397. package/src/components/openapi/async.ts +123 -29
  398. package/src/components/openapi/code-samples.ts +97 -0
  399. package/src/components/openapi/graphql-helpers.ts +35 -12
  400. package/src/components/openapi/helpers.ts +36 -2
  401. package/src/components/openapi/message-model.ts +54 -11
  402. package/src/components/openapi/message.ts +14 -4
  403. package/src/components/openapi/operation-model.ts +16 -7
  404. package/src/components/openapi/playground-client.ts +24 -5
  405. package/src/components/openapi/playground-schema.ts +1 -1
  406. package/src/components/openapi/schema-tree.ts +44 -14
  407. package/src/components/openapi/security.ts +16 -3
  408. package/src/components/openapi/snippets.ts +873 -10
  409. package/src/components/openapi/validate-json.ts +4 -3
  410. package/src/components/props.ts +6 -0
  411. package/src/consent/client.ts +95 -0
  412. package/src/consent/clients.ts +19 -0
  413. package/src/consent/ethyca.ts +71 -0
  414. package/src/consent/head.ts +24 -0
  415. package/src/consent/index.ts +37 -0
  416. package/src/consent/init.ts +29 -0
  417. package/src/consent/native.ts +36 -0
  418. package/src/consent/osano.ts +59 -0
  419. package/src/consent/schema.ts +30 -0
  420. package/src/core/builtin-tags.ts +5 -0
  421. package/src/core/changelog-index.ts +31 -1
  422. package/src/core/client-address.ts +19 -0
  423. package/src/core/component-diagnostics.ts +53 -0
  424. package/src/core/component-overrides.ts +32 -0
  425. package/src/core/config-input.ts +225 -23
  426. package/src/core/data.ts +46 -4
  427. package/src/core/diagnostics.ts +8 -2
  428. package/src/core/footer.ts +26 -0
  429. package/src/core/graph.ts +39 -36
  430. package/src/core/i18n-ui.ts +84 -2
  431. package/src/core/includes.ts +21 -4
  432. package/src/core/links.ts +63 -19
  433. package/src/core/localizable.ts +26 -0
  434. package/src/core/navigation.ts +43 -12
  435. package/src/core/page-modes.ts +56 -0
  436. package/src/core/probe.ts +26 -6
  437. package/src/core/project-graph.ts +163 -16
  438. package/src/core/redirect-patterns.ts +520 -0
  439. package/src/core/related.ts +131 -0
  440. package/src/core/schema.ts +339 -66
  441. package/src/core/sources/cache.ts +6 -0
  442. package/src/core/sources/contentful-rich-text.ts +29 -6
  443. package/src/core/sources/contentful.ts +135 -25
  444. package/src/core/sources/filesystem.ts +26 -4
  445. package/src/core/sources/github-releases.ts +12 -1
  446. package/src/core/sources/lexical.ts +15 -10
  447. package/src/core/sources/mdx-remote.ts +62 -10
  448. package/src/core/sources/normalize.ts +228 -41
  449. package/src/core/sources/notion.ts +7 -1
  450. package/src/core/sources/obsidian.ts +16 -3
  451. package/src/core/sources/payload.ts +38 -15
  452. package/src/core/sources/read.ts +8 -3
  453. package/src/core/sources/remote.ts +72 -15
  454. package/src/core/sources/resolve.ts +11 -1
  455. package/src/core/sources/sanity.ts +43 -25
  456. package/src/core/sources/strapi.ts +2 -2
  457. package/src/core/types.ts +19 -1
  458. package/src/core/ui-packs/ar.ts +44 -0
  459. package/src/core/ui-packs/bg.ts +46 -0
  460. package/src/core/ui-packs/bn.ts +44 -0
  461. package/src/core/ui-packs/ca.ts +47 -0
  462. package/src/core/ui-packs/cs.ts +45 -0
  463. package/src/core/ui-packs/da.ts +46 -0
  464. package/src/core/ui-packs/de.ts +47 -0
  465. package/src/core/ui-packs/el.ts +46 -0
  466. package/src/core/ui-packs/es.ts +47 -0
  467. package/src/core/ui-packs/fa.ts +46 -0
  468. package/src/core/ui-packs/fi.ts +46 -0
  469. package/src/core/ui-packs/fr.ts +47 -0
  470. package/src/core/ui-packs/he.ts +44 -0
  471. package/src/core/ui-packs/hi.ts +45 -0
  472. package/src/core/ui-packs/hr.ts +46 -0
  473. package/src/core/ui-packs/hu.ts +45 -0
  474. package/src/core/ui-packs/id.ts +46 -0
  475. package/src/core/ui-packs/it.ts +46 -0
  476. package/src/core/ui-packs/ja.ts +46 -0
  477. package/src/core/ui-packs/ko.ts +45 -0
  478. package/src/core/ui-packs/nl.ts +47 -0
  479. package/src/core/ui-packs/no.ts +45 -0
  480. package/src/core/ui-packs/pl.ts +46 -0
  481. package/src/core/ui-packs/pt-br.ts +47 -0
  482. package/src/core/ui-packs/pt.ts +46 -0
  483. package/src/core/ui-packs/ro.ts +46 -0
  484. package/src/core/ui-packs/ru.ts +46 -0
  485. package/src/core/ui-packs/sk.ts +45 -0
  486. package/src/core/ui-packs/sr.ts +46 -0
  487. package/src/core/ui-packs/sv.ts +45 -0
  488. package/src/core/ui-packs/th.ts +44 -0
  489. package/src/core/ui-packs/tr.ts +46 -0
  490. package/src/core/ui-packs/uk.ts +46 -0
  491. package/src/core/ui-packs/vi.ts +46 -0
  492. package/src/core/ui-packs/zh-tw.ts +44 -0
  493. package/src/core/ui-packs/zh.ts +44 -0
  494. package/src/core/variables.ts +103 -0
  495. package/src/deploy/adapter-output.ts +7 -2
  496. package/src/deploy/adapters/cloudflare.ts +7 -5
  497. package/src/deploy/adapters/node.ts +47 -9
  498. package/src/deploy/adapters/types.ts +7 -3
  499. package/src/deploy/artifacts.ts +79 -9
  500. package/src/deploy/cloudflare-negotiation.ts +35 -5
  501. package/src/deploy/headers.ts +2 -1
  502. package/src/deploy/node-headers.ts +63 -9
  503. package/src/deploy/platforms/cloudflare.ts +45 -9
  504. package/src/deploy/platforms/netlify.ts +35 -2
  505. package/src/deploy/platforms/node.ts +12 -2
  506. package/src/deploy/platforms/types.ts +21 -7
  507. package/src/deploy/platforms/vercel.ts +149 -17
  508. package/src/deploy/redirects.ts +151 -24
  509. package/src/deploy/rss.ts +3 -1
  510. package/src/deploy/sitemap.ts +39 -5
  511. package/src/deploy/vercel-negotiation.ts +326 -102
  512. package/src/eval/agents.ts +18 -1
  513. package/src/eval/prompts.ts +6 -3
  514. package/src/eval/report.ts +34 -13
  515. package/src/eval/run.ts +5 -0
  516. package/src/markdown/api-rail.ts +259 -0
  517. package/src/markdown/code-title.ts +35 -9
  518. package/src/markdown/features.ts +3 -2
  519. package/src/markdown/fence-meta.ts +2 -0
  520. package/src/markdown/include.ts +11 -1
  521. package/src/markdown/index.ts +28 -5
  522. package/src/markdown/math.ts +4 -4
  523. package/src/markdown/relative-links.ts +3 -2
  524. package/src/markdown/variables.ts +56 -0
  525. package/src/markdown/views.ts +82 -0
  526. package/src/narration/build.ts +412 -0
  527. package/src/narration/player.ts +249 -0
  528. package/src/narration/provider.ts +29 -0
  529. package/src/narration/script.ts +592 -0
  530. package/src/og/card.ts +7 -6
  531. package/src/openapi/checks.ts +273 -0
  532. package/src/openapi/graphql-build.ts +21 -0
  533. package/src/openapi/graphql.ts +11 -0
  534. package/src/openapi/model.ts +72 -27
  535. package/src/openapi/overlay.ts +256 -0
  536. package/src/openapi/parse.ts +182 -4
  537. package/src/openapi/references.ts +64 -8
  538. package/src/openapi/render-mdx.ts +5 -1
  539. package/src/openapi/scalar.ts +40 -6
  540. package/src/openapi/source.ts +40 -15
  541. package/src/ratelimit/cloudflare.ts +54 -0
  542. package/src/ratelimit/index.ts +30 -0
  543. package/src/ratelimit/memory.ts +45 -0
  544. package/src/ratelimit/runtime.ts +247 -0
  545. package/src/ratelimit/schema.ts +28 -0
  546. package/src/ratelimit/upstash.ts +60 -0
  547. package/src/ratelimit/wrangler.ts +70 -0
  548. package/src/reference/asyncapi.ts +2 -2
  549. package/src/reference/graphql.ts +20 -3
  550. package/src/reference/index.ts +1 -0
  551. package/src/reference/openapi.ts +21 -7
  552. package/src/reference/options.ts +80 -8
  553. package/src/reference/scalar.ts +33 -8
  554. package/src/registry/eject.ts +23 -5
  555. package/src/registry/registry.ts +7 -0
  556. package/src/search/adapters/locale-scope.ts +30 -0
  557. package/src/search/adapters/typesense.ts +14 -4
  558. package/src/search/build.ts +21 -3
  559. package/src/search/documents.ts +26 -2
  560. package/src/search/orama-index.ts +191 -34
  561. package/src/search/pagefind-ranking.ts +39 -0
  562. package/src/search/source-pages.ts +29 -0
  563. package/src/search/sync/algolia.ts +111 -10
  564. package/src/search/sync/index.ts +52 -13
  565. package/src/search/sync/orama-cloud.ts +3 -0
  566. package/src/search/sync/typesense.ts +76 -26
  567. package/src/seo/metatags.ts +67 -0
  568. package/src/sources/contentful.ts +12 -0
  569. package/src/sources/github-releases.ts +7 -1
  570. package/src/sources/shared.ts +3 -0
  571. package/src/theme/chrome-icons.ts +1 -0
  572. package/src/theme/color.ts +500 -0
  573. package/src/theme/entry.ts +85 -6
  574. package/src/theme/palette.ts +121 -45
  575. package/src/translate/prompts.ts +1 -0
  576. package/src/translate/validate.ts +31 -3
  577. package/src/upgrade/upgrade.ts +4 -171
  578. package/dist/cli/chunk-1d7ve1dm.js.map +0 -12
  579. package/dist/cli/chunk-2hsdwb9n.js.map +0 -10
  580. package/dist/cli/chunk-35d4wj9f.js.map +0 -15
  581. package/dist/cli/chunk-364znk6q.js +0 -75
  582. package/dist/cli/chunk-364znk6q.js.map +0 -11
  583. package/dist/cli/chunk-5m5nmvyq.js.map +0 -13
  584. package/dist/cli/chunk-8ktnccpt.js.map +0 -10
  585. package/dist/cli/chunk-9t7a85s3.js.map +0 -10
  586. package/dist/cli/chunk-b07cmahc.js +0 -145
  587. package/dist/cli/chunk-b07cmahc.js.map +0 -11
  588. package/dist/cli/chunk-c8chx29p.js.map +0 -36
  589. package/dist/cli/chunk-e04dxsz1.js +0 -39
  590. package/dist/cli/chunk-e04dxsz1.js.map +0 -10
  591. package/dist/cli/chunk-j85vccga.js.map +0 -36
  592. package/dist/cli/chunk-p3v96n38.js.map +0 -10
  593. package/dist/cli/chunk-pehfxfta.js.map +0 -10
  594. package/dist/cli/chunk-pv29h0wf.js.map +0 -190
  595. package/dist/cli/chunk-q58y5e6a.js.map +0 -10
  596. package/dist/cli/chunk-vg9r4eb9.js.map +0 -14
  597. package/dist/cli/chunk-wrr3j9w9.js.map +0 -35
  598. package/dist/cli/chunk-yfyb25rh.js.map +0 -14
  599. package/docs/content/sources.mdx +0 -334
  600. /package/dist/cli/{chunk-tkacnehg.js.map → chunk-3v3ffbrj.js.map} +0 -0
  601. /package/dist/cli/{chunk-r9rcc4w7.js.map → chunk-8y2kmjv8.js.map} +0 -0
  602. /package/dist/cli/{chunk-2eytanqx.js.map → chunk-c887fj0s.js.map} +0 -0
  603. /package/dist/cli/{chunk-akbpwfxc.js.map → chunk-dzwehpy7.js.map} +0 -0
  604. /package/dist/cli/{chunk-2z928egk.js.map → chunk-ft9vfys6.js.map} +0 -0
  605. /package/dist/cli/{chunk-a58773jm.js.map → chunk-kma9f6sf.js.map} +0 -0
  606. /package/dist/cli/{chunk-crgn1q09.js.map → chunk-sds923fa.js.map} +0 -0
  607. /package/dist/cli/{chunk-acanzt5p.js.map → chunk-tdqhyxfz.js.map} +0 -0
@@ -2,7 +2,7 @@ import type { JsonValue } from "../../core/adapter.ts";
2
2
  import type { BlumeProject } from "../../core/project-graph.ts";
3
3
  import type { ResolvedConfig } from "../../core/schema.ts";
4
4
  import type { ProjectContext } from "../../core/types.ts";
5
- import type { DeployAdapterKind } from "../adapters/registry.ts";
5
+ import type { DeployAdapterKind, ResolvedDeployOptions } from "../adapters/registry.ts";
6
6
  import type { DeployOutput } from "../adapters/types.ts";
7
7
  /**
8
8
  * Everything Blume does differently per deployment target, keyed by the
@@ -13,8 +13,16 @@ import type { DeployOutput } from "../adapters/types.ts";
13
13
  */
14
14
  /** How the generated `astro.config.mjs` constructs the `@astrojs/*` adapter. */
15
15
  export interface AstroAdapterSpec {
16
- /** Top-level `defineConfig` entries the adapter needs beside itself. */
17
- config: Record<string, JsonValue>;
16
+ /**
17
+ * Top-level `defineConfig` entries the adapter needs beside itself, some
18
+ * of them set from the deployment's own options.
19
+ */
20
+ config: (options: ResolvedDeployOptions) => Record<string, JsonValue>;
21
+ /**
22
+ * The deployment options `config` reads, which therefore stay out of the
23
+ * passthrough to the `@astrojs/*` constructor.
24
+ */
25
+ configOptions: string[];
18
26
  /** Blume's own constructor options; the user's passthrough is spread over them. */
19
27
  options: (context: ProjectContext) => Record<string, JsonValue>;
20
28
  /** The package the config imports the adapter from. */
@@ -106,14 +114,17 @@ export interface DeployPlatform {
106
114
  /**
107
115
  * Whether the adapter moves a server build's client output under
108
116
  * `deployment.base` (`dist/client/<base>/`, the directory Astro then hands
109
- * `astro:build:done`) while the platform keeps serving `serverStaticDir`
110
- * as the assets root. The files the platform reads there, like `_headers`,
117
+ * `astro:build:done`) while the platform keeps serving `dist/client` as
118
+ * the assets root. The files the platform reads there, like `_headers`,
111
119
  * belong above the directory Astro reports.
112
120
  */
113
121
  serverClientUnderBase: boolean;
114
122
  /** Where a server build's deploy bundle lands. */
115
123
  serverOutputDir: (context: ProjectContext) => string;
116
- /** The directory a server build serves as static files. */
117
- serverStaticDir: (context: ProjectContext) => string;
124
+ /**
125
+ * The directory a server build serves as static files, given the normalized
126
+ * `deployment.base` for a platform that serves them from `<dir>/<base>/`.
127
+ */
128
+ serverStaticDir: (context: ProjectContext, base: string) => string;
118
129
  }
119
130
  export {};
@@ -1,4 +1,5 @@
1
1
  import type { BlumeProject } from "../../core/project-graph.ts";
2
+ import type { ProjectContext } from "../../core/types.ts";
2
3
  import type { BuildLog, DeployPlatform, RedirectFile } from "./types.ts";
3
4
  /** `vercel.json` with a `redirects` array, for a static deploy of `dist/`. */
4
5
  export declare const VERCEL_JSON_FILE: RedirectFile;
@@ -20,6 +21,28 @@ export declare const checkVercelFunctionBundles: (outputDir: string, root: strin
20
21
  * root it was shown.
21
22
  */
22
23
  export declare const emitVercelNegotiation: (project: BlumeProject, log: BuildLog) => Promise<void>;
24
+ /**
25
+ * Route the pattern redirects (`/beta/:slug*`) in the adapter's Build Output
26
+ * config: Astro's `redirects` carry only the exact ones, since it can't
27
+ * prerender a pattern's pages, so the adapter never sees these.
28
+ */
29
+ export declare const emitVercelPatternRedirects: (project: BlumeProject, log: BuildLog) => Promise<void>;
30
+ /**
31
+ * Move a server build's static files under `deployment.base`.
32
+ * `@astrojs/vercel` copies them to the root of the Build Output tree's
33
+ * `static/`, while the pages request `<base>/_astro/…` and link to
34
+ * `<base>/…`, so nothing the site asks for would be found. Moved to
35
+ * `static/<base>/`, they're served at the base, as the routes that
36
+ * {@link rebaseVercelRoutes} moves there expect.
37
+ */
38
+ export declare const moveStaticUnderBase: (context: ProjectContext, base: string) => Promise<void>;
39
+ /**
40
+ * Move the adapter's routing config under `deployment.base` to match the
41
+ * static files (see `rebaseAdapterRoutes`), its exact redirects rebuilt from
42
+ * the configured ones. Resolves to false when the config can't be read: the
43
+ * adapter's routes would then miss every path under the base.
44
+ */
45
+ export declare const rebaseVercelRoutes: (project: BlumeProject, log: BuildLog) => Promise<boolean>;
23
46
  /**
24
47
  * Vercel. A server build's Build Output tree lands at `.vercel/output` — at
25
48
  * the project root, because the adapter is handed that root up front: its
@@ -28,6 +51,8 @@ export declare const emitVercelNegotiation: (project: BlumeProject, log: BuildLo
28
51
  * Static assets are served from the tree's `static/` half, so the deploy
29
52
  * artifacts are written there; headers (the discovery files', the sandbox on
30
53
  * downloaded SVGs) arrive through the routing config rather than a
31
- * `_headers` file, which Vercel never reads.
54
+ * `_headers` file, which Vercel never reads. The adapter ignores
55
+ * `deployment.base`, so under one the build moves the static files and the
56
+ * routes beneath it.
32
57
  */
33
58
  export declare const vercelPlatform: DeployPlatform;
@@ -2,12 +2,16 @@ import type { RouteSet } from "../core/locale-links.ts";
2
2
  import type { BlumeProject } from "../core/project-graph.ts";
3
3
  import type { ResolvedConfig } from "../core/schema.ts";
4
4
  import type { VercelHeader } from "./headers.ts";
5
+ import type { VercelRoute } from "./vercel-negotiation.ts";
5
6
  /**
6
7
  * Platform redirect files for a static build. Astro already emits redirect HTML
7
8
  * (meta-refresh) pages for static output, but that's a soft client redirect.
8
9
  * These give the host a real HTTP 3xx: Netlify/Cloudflare read `_redirects`,
9
10
  * Vercel reads `vercel.json`, and `blume-redirects.json` is a structured
10
- * manifest for anything else (Apache/nginx rules, an edge worker).
11
+ * manifest for anything else (Apache/nginx rules, an edge worker). A pattern
12
+ * redirect (`/beta/:slug*`) gets no redirect page, since Astro can't
13
+ * prerender one for paths it doesn't know; each host file carries it in that
14
+ * host's syntax (see `core/redirect-patterns.ts`).
11
15
  */
12
16
  type Redirect = ResolvedConfig["redirects"][number];
13
17
  /**
@@ -37,21 +41,40 @@ export declare const applyBaseToAstroRedirects: (redirects: Redirect[], basePath
37
41
  * public file (see {@link baseRedirectTarget}).
38
42
  */
39
43
  export declare const applyBaseToPlatformRedirects: (redirects: Redirect[], basePath: string, deployBase: string, routes: RouteSet) => Redirect[];
44
+ /**
45
+ * Based `redirects`, each exact one that moves a page followed by the same
46
+ * redirect for the page's Markdown copies: from a path no page is served at
47
+ * to one a page is, `/old.md` goes to `/new.md` (and `.mdx` alike), where it
48
+ * would otherwise 404 for an agent still reading the old URL. A pattern gets
49
+ * none; one that carries its capture over (`/beta/:slug*` → `/v2/:slug*`)
50
+ * already moves `/beta/guide.md` along. `pages` are the served page routes
51
+ * (carrying `basePath`, not `deployment.base`), and `bases` the deployment
52
+ * base each end carries: Astro's config leaves it off `from` (see
53
+ * {@link applyBaseToAstroRedirects}).
54
+ */
55
+ export declare const withMirrorRedirects: (redirects: Redirect[], pages: RouteSet, bases: {
56
+ from: string;
57
+ to: string;
58
+ }) => Redirect[];
40
59
  /**
41
60
  * The configured redirects as the host platform matches them, via
42
- * {@link applyBaseToPlatformRedirects}. The one basing every consumer must
43
- * share: the emitted redirect files and the Cloudflare worker-first redirect
44
- * exemptions both compare these paths against real served URLs.
61
+ * {@link applyBaseToPlatformRedirects} plus the Markdown copies of each moved
62
+ * page ({@link withMirrorRedirects}), exact paths ahead of patterns: hosts
63
+ * try rules in order, and an exact redirect wins over a pattern that also
64
+ * covers its path. The one basing every consumer must share: the emitted
65
+ * redirect files and the server wrappers all compare these paths against
66
+ * real served URLs.
45
67
  */
46
68
  export declare const platformRedirects: (project: {
47
69
  config: ResolvedConfig;
48
70
  manifest: Pick<BlumeProject["manifest"], "routes">;
49
71
  }) => Redirect[];
50
72
  /**
51
- * `_redirects` text (Netlify + Cloudflare Pages): `from to status` per line.
52
- * `force` appends Netlify's `!` to each status (`301!`), so the rule wins over
53
- * the redirect page Astro writes at `from`; Cloudflare, which always applies
54
- * its rules first, rejects a line carrying it.
73
+ * `_redirects` text (Netlify + Cloudflare Pages): `from to status` per line,
74
+ * a pattern as `:placeholder`s and a `*` splat the destination reads as
75
+ * `:splat`. `force` appends Netlify's `!` to each status (`301!`), so the rule
76
+ * wins over the redirect page Astro writes at `from`; Cloudflare, which always
77
+ * applies its rules first, rejects a line carrying it.
55
78
  */
56
79
  export declare const buildNetlifyRedirects: (redirects: Redirect[], force?: boolean) => string;
57
80
  /**
@@ -60,10 +83,31 @@ export declare const buildNetlifyRedirects: (redirects: Redirect[], force?: bool
60
83
  * alternative to the boolean `permanent`) so the configured code ships exactly:
61
84
  * `permanent` would silently coerce a 301 to 308 and a 302 to 307, diverging
62
85
  * from the `_redirects` file, which preserves exact codes. A `source` is a
63
- * `path-to-regexp` pattern, so each exact `from` path is escaped: unescaped,
64
- * `/c++-guide` fails the whole config and `/faq(old)` never matches.
86
+ * `path-to-regexp` pattern, so each literal run of a `from` path is escaped:
87
+ * unescaped, `/c++-guide` fails the whole config and `/faq(old)` never
88
+ * matches. A pattern's captures are `path-to-regexp` params.
65
89
  */
66
90
  export declare const buildVercelConfig: (redirects: Redirect[], headers?: readonly VercelHeader[]) => string;
67
- /** Structured manifest for hosts that need manual wiring. */
91
+ /**
92
+ * The pattern redirects as `_redirects` entries, for the `redirects` of a
93
+ * Netlify server build's Frameworks API config (see
94
+ * {@link buildNetlifyRedirects} for the syntax).
95
+ */
96
+ export declare const netlifyPatternRedirects: (redirects: Redirect[]) => {
97
+ from: string;
98
+ status: number;
99
+ to: string;
100
+ }[];
101
+ /**
102
+ * The pattern redirects as Build Output API routes, for a Vercel server
103
+ * build: the adapter routes only the exact redirects Astro's config carries.
104
+ * Each matches the served path, a trailing slash optional, and fills its
105
+ * `Location` from numbered captures, as the adapter's own redirect routes do.
106
+ */
107
+ export declare const vercelPatternRoutes: (redirects: Redirect[]) => VercelRoute[];
108
+ /**
109
+ * Structured manifest for hosts that need manual wiring. A pattern stays as
110
+ * configured (`/beta/:slug*`), for the rule it becomes to be written by hand.
111
+ */
68
112
  export declare const buildRedirectManifest: (redirects: Redirect[]) => string;
69
113
  export {};
@@ -11,7 +11,8 @@ export declare const describeSitemapFiles: (files: readonly SitemapFile[]) => st
11
11
  * can't see: custom `.astro` pages (most importantly a custom landing `/`) and
12
12
  * the generated `/changelog` index. Returns null when the sitemap is disabled
13
13
  * or no `site` is configured (absolute URLs are required for a valid sitemap).
14
- * Drafts, hidden, and `noindex` pages are excluded.
14
+ * Drafts, hidden, and `noindex` pages are excluded, and so is a page whose
15
+ * `seo.canonical` points elsewhere.
15
16
  *
16
17
  * Sites within the per-file URL cap get the single classic `sitemap.xml`;
17
18
  * larger sites get `sitemap.xml` as a sitemap index over numbered
@@ -14,25 +14,31 @@
14
14
  * prerendered Markdown 404 body with the 404 status, instead of the HTML
15
15
  * shell, and one that prefers JSON (or asks for a `.json` URL) gets the
16
16
  * prerendered problem-details 404.
17
+ *
18
+ * Under `deployment.base` every route here matches the served URL, base
19
+ * included, and names the files where Blume moves them (`static/<base>/`, see
20
+ * {@link rebaseAdapterRoutes}); `base` is the normalized base, `""` for none.
17
21
  */
18
- /**
19
- * Regex for the `accept` header condition. Written to hold under both matching
20
- * semantics a router may apply — full-string and substring — by anchoring the
21
- * end and letting `(.*,)?` absorb any earlier list entries: it requires a
22
- * `text/markdown` or `text/x-markdown` entry terminated by `;`, `,`, or the end
23
- * of the header. Kept lookaround-free so it stays valid in RE2, and lowercase
24
- * only — real agents send lowercase media types, and q-values are not compared
25
- * (a client sending `text/markdown` at `q=0` is pathological). Browsers never
26
- * send `text/markdown`, so ordinary page requests are unaffected.
27
- */
28
- export declare const ACCEPT_MARKDOWN_HEADER_VALUE = "(.*,)?\\s*text/(x-)?markdown(\\s*[;,].*)?$";
22
+ /** One header condition on a Build Output route. */
23
+ export interface VercelCondition {
24
+ key?: string;
25
+ type: string;
26
+ value?: string;
27
+ }
28
+ /** The conditions of one route: all of `has`, none of `missing`. */
29
+ export interface AcceptConditions {
30
+ has: VercelCondition[];
31
+ missing?: VercelCondition[];
32
+ }
33
+ /** When a client prefers `text/markdown` (or `text/x-markdown`) over HTML. */
34
+ export declare const ACCEPT_MARKDOWN_CONDITIONS: AcceptConditions[];
29
35
  /**
30
36
  * The JSON counterpart, for the problem-details 404: `application/json` or
31
37
  * `application/problem+json`. Browsers never send either on a navigation
32
38
  * (the catch-all wildcard does not match), so ordinary page requests are
33
39
  * unaffected.
34
40
  */
35
- export declare const ACCEPT_JSON_HEADER_VALUE = "(.*,)?\\s*application/(problem\\+)?json(\\s*[;,].*)?$";
41
+ export declare const ACCEPT_JSON_CONDITIONS: AcceptConditions[];
36
42
  /**
37
43
  * A Build Output API route — the subset these helpers read and write. Parsed
38
44
  * routes keep whatever other fields they carry at runtime; only these are
@@ -42,12 +48,9 @@ export interface VercelRoute {
42
48
  continue?: boolean;
43
49
  dest?: string;
44
50
  handle?: string;
45
- has?: {
46
- key?: string;
47
- type: string;
48
- value?: string;
49
- }[];
51
+ has?: VercelCondition[];
50
52
  headers?: Record<string, string>;
53
+ missing?: VercelCondition[];
51
54
  src?: string;
52
55
  status?: number;
53
56
  }
@@ -82,9 +85,10 @@ export interface NegotiationRoutes {
82
85
  * rewrite also stamps `x-markdown-tokens` — the estimated token count of the
83
86
  * homepage mirror (Cloudflare's Markdown for Agents convention). Only the home
84
87
  * route can carry it: the other rewrites are chunked alternations spanning
85
- * many pages, and a count is per-page.
88
+ * many pages, and a count is per-page. Under a `base`, each path is matched
89
+ * and rewritten where it's served (`/docs` → `/docs/index.md`).
86
90
  */
87
- export declare const buildNegotiationRoutes: (routePaths: readonly string[], homeTokens?: number) => NegotiationRoutes;
91
+ export declare const buildNegotiationRoutes: (routePaths: readonly string[], homeTokens?: number, base?: string) => NegotiationRoutes;
88
92
  /**
89
93
  * Splice the negotiation routes into a Build Output `config.json`, plus — when
90
94
  * given — a homepage `Link` header route for agent discovery (see
@@ -102,9 +106,35 @@ export declare const buildNegotiationRoutes: (routePaths: readonly string[], hom
102
106
  * phase right before the adapter's `/404.html` fallback — and nowhere when
103
107
  * that fallback is absent, since a `dest` with no file behind it would serve
104
108
  * nothing. With `svgAssets`, a main-phase route also sandboxes the SVGs a
105
- * content source downloaded (see {@link svgAssetRoute}). Returns the updated JSON
109
+ * content source downloaded (see {@link svgAssetRoute}). Under a `base`, every
110
+ * route matches and names paths beneath it, and the fallback anchor is the
111
+ * one {@link rebaseAdapterRoutes} moved there. Returns the updated JSON
106
112
  * text (tab-indented, like the adapter's own output), or `null` when there is
107
113
  * nowhere safe to splice: an unparsable config, no `routes` array, or no
108
114
  * `handle: "filesystem"` marker to anchor the splice.
109
115
  */
110
- export declare const injectNegotiationRoutes: (configText: string, routePaths: readonly string[], homeLinkHeader?: string | null, contentTypeOverrides?: Record<string, string>, homeTokens?: number, notFound?: NotFoundVariants, corsPaths?: readonly string[], svgAssets?: boolean) => string | null;
116
+ export declare const injectNegotiationRoutes: (configText: string, routePaths: readonly string[], homeLinkHeader?: string | null, contentTypeOverrides?: Record<string, string>, homeTokens?: number, notFound?: NotFoundVariants, corsPaths?: readonly string[], svgAssets?: boolean, base?: string) => string | null;
117
+ /**
118
+ * Splice routes for the pattern redirects (see `vercelPatternRoutes`) into a
119
+ * Build Output `config.json`, in the main phase just ahead of
120
+ * `handle: "filesystem"`: after the exact redirects the adapter puts first,
121
+ * so an exact path still wins. A second pass replaces its own routes. Returns
122
+ * the updated JSON text, or `null` when there is nowhere safe to splice: an
123
+ * unparsable config, no `routes` array, or no `handle: "filesystem"` marker.
124
+ */
125
+ export declare const injectRedirectRoutes: (configText: string, redirectRoutes: readonly VercelRoute[]) => string | null;
126
+ /**
127
+ * Move the adapter's routes under `deployment.base`, to match the static files
128
+ * Blume moves to `static/<base>/`. `@astrojs/vercel` routes a server build as
129
+ * if it were served from the root: its route patterns (the `_astro/` cache
130
+ * header, every server route) match base-less paths, its 404 fallback names
131
+ * `/404.html`, and it joins the base onto each redirect with no slash on the
132
+ * `from` side and a second time on the `to` side, which Astro hands it
133
+ * already based (`^/docsold$` → `/docs/docs/new`). Each pattern is
134
+ * re-anchored under the base and the fallback names the base's `404.html`;
135
+ * the adapter's redirects make way for `redirectRoutes`, the exact redirects
136
+ * as the host matches them. Returns the updated JSON text, or `null` when
137
+ * there is nowhere safe to splice: an unparsable config, no `routes` array,
138
+ * or no `handle: "filesystem"` marker.
139
+ */
140
+ export declare const rebaseAdapterRoutes: (configText: string, base: string, redirectRoutes: readonly VercelRoute[]) => string | null;
@@ -7,7 +7,20 @@
7
7
  * language label.
8
8
  * - the `lineNumbers` keyword (```ts file.ts lineNumbers) becomes
9
9
  * `data-line-numbers`; the theme renders a counter-driven line-number gutter.
10
+ * - the `wrap` keyword becomes `data-wrap`: this block's long lines wrap
11
+ * instead of scrolling, as `markdown.code.wrap` does for every block.
12
+ * - the `expandable` keyword becomes `data-expandable` on a block of
13
+ * {@link EXPANDABLE_MIN_LINES} lines or more: the theme shows its first
14
+ * {@link EXPANDABLE_VISIBLE_LINES} lines, and the page script adds a toggle
15
+ * that shows the rest in full. A shorter block renders as it is.
10
16
  */
17
+ /** The lines a collapsed `expandable` block shows. */
18
+ export declare const EXPANDABLE_VISIBLE_LINES = 10;
19
+ /**
20
+ * The lines a block needs before `expandable` collapses it: a few more than it
21
+ * shows, so the toggle never hides a line or two behind a click.
22
+ */
23
+ export declare const EXPANDABLE_MIN_LINES = 16;
11
24
  /** The slice of Shiki's transformer `this` context Blume reads. */
12
25
  interface CodeMetaContext {
13
26
  options: {
@@ -15,6 +28,8 @@ interface CodeMetaContext {
15
28
  __raw?: string;
16
29
  };
17
30
  };
31
+ /** The block's code, as highlighted. */
32
+ source?: string;
18
33
  }
19
34
  /** The `<pre>` hast node a Shiki `pre` hook receives. */
20
35
  interface PreNode {
@@ -27,6 +42,8 @@ export interface CodeTitleTransformer {
27
42
  }
28
43
  /** The title a fence's meta string promotes to `data-title`, if any. */
29
44
  export declare const parseCodeTitle: (raw: string | undefined) => string | undefined;
45
+ /** How many lines a block's code runs to, a trailing newline aside. */
46
+ export declare const lineCount: (source?: string) => number;
30
47
  /** Build the transformer. Runs after Shiki's built-in `data-language` hook. */
31
48
  export declare const codeTitleTransformer: () => CodeTitleTransformer;
32
49
  export {};
@@ -8,8 +8,9 @@ export declare const MARKDOWN_FEATURES: {
8
8
  };
9
9
  /**
10
10
  * The `.mdx` feature set: Markdown's plus `:::` directives (→ `<Callout>`) and
11
- * block-only math — `singleDollarTextMath: false` keeps a bare `$` (currency,
12
- * shell, code) as literal text and only parses `$$…$$`.
11
+ * math — `singleDollarTextMath: false` keeps a bare `$` (currency, shell,
12
+ * code) as literal text and only parses `$$…$$`, as a block on its own lines
13
+ * or inline within a sentence.
13
14
  */
14
15
  export declare const MDX_FEATURES: {
15
16
  directive: true;
@@ -0,0 +1,70 @@
1
+ import { HTMLElement } from "node-html-parser";
2
+ import type { Node } from "node-html-parser";
3
+ import type { BlumeProject } from "../core/project-graph.ts";
4
+ import type { ProjectContext } from "../core/types.ts";
5
+ import type { NarrationProvider } from "./provider.ts";
6
+ import type { NarrationCues, NarrationTree } from "./script.ts";
7
+ /**
8
+ * Generated narration: after Astro writes the HTML, read every page that
9
+ * carries the player exactly as the browser will (same walker, same blocks),
10
+ * split it into sentences, and give each sentence a clip from the configured
11
+ * speech model. Clips are cached by what decides their sound (text, language,
12
+ * model, voice, instructions, provider options), so a rebuild only pays for
13
+ * sentences that changed, and one sentence shared by many pages is generated
14
+ * once. Each page gets a manifest listing its clips; the player plays them in
15
+ * order and falls back to browser voices wherever a manifest is missing.
16
+ */
17
+ /** How the build logs: the integration's Astro logger. */
18
+ export interface NarrationLogger {
19
+ info: (message: string) => void;
20
+ warn: (message: string) => void;
21
+ }
22
+ /** Speak `text` in `lang`, returning MP3 bytes. */
23
+ export type Speak = (text: string, lang: string) => Promise<Uint8Array>;
24
+ /** What a narration build did, for the log line and tests. */
25
+ export interface NarrationBuildResult {
26
+ /** Clips that failed to generate; their pages get no manifest. */
27
+ failed: number;
28
+ /** Clips generated by the speech model on this build. */
29
+ generated: number;
30
+ /** Pages that got a manifest. */
31
+ pages: number;
32
+ /** Clips read back from the cache. */
33
+ reused: number;
34
+ }
35
+ /**
36
+ * The clip cache directory: `node_modules/.cache/blume/narration`, next to the
37
+ * OG card cache and restored by the same host build caches (see `ogCacheDir`).
38
+ */
39
+ export declare const narrationCacheDir: (context: Pick<ProjectContext, "outDir" | "root">) => string;
40
+ /** The walker's view of a node-html-parser tree. */
41
+ export declare const htmlTree: NarrationTree<Node>;
42
+ /** The player's settings on a built page, and the article it reads. */
43
+ interface PlayerPage {
44
+ article: HTMLElement;
45
+ audioBase: string;
46
+ cues: NarrationCues;
47
+ lang: string;
48
+ manifest: string;
49
+ }
50
+ /**
51
+ * The generated player on a built page, or `null` when the page has none (or
52
+ * a player without generated audio, which reads with browser voices).
53
+ */
54
+ export declare const readPlayerPage: (html: string) => PlayerPage | null;
55
+ /**
56
+ * A clip's cache key: a digest of everything that decides how it sounds. The
57
+ * Blume version is deliberately left out, unlike the OG card's: an upgrade
58
+ * shouldn't pay to regenerate audio that would sound the same.
59
+ */
60
+ export declare const clipKey: (provider: NarrationProvider, lang: string, text: string) => string;
61
+ /** Speak through the Vercel AI Gateway with the provider's model and voice. */
62
+ export declare const gatewaySpeaker: (provider: NarrationProvider) => Speak;
63
+ /**
64
+ * Generate the narration for a built site in `distDir`: a clip per sentence
65
+ * and a manifest per page. Does nothing unless `narration.provider` is set,
66
+ * and warns instead of generating when the provider's key is missing (the
67
+ * pages then read with browser voices). `speak` replaces the gateway call.
68
+ */
69
+ export declare const buildNarration: (project: BlumeProject, distDir: string, logger: NarrationLogger, speak?: Speak) => Promise<NarrationBuildResult | null>;
70
+ export {};
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ /** The speech model narration uses when `gateway()` names none. */
3
+ export declare const DEFAULT_NARRATION_MODEL = "openai/tts-1-hd";
4
+ /** The voice narration uses when `gateway()` names none. */
5
+ export declare const DEFAULT_NARRATION_VOICE = "alloy";
6
+ /**
7
+ * `narration.provider`: the `gateway()` descriptor from `blume/ai`, read with
8
+ * speech defaults. `reasoning` is an assistant option and is rejected here;
9
+ * `voice` and `instructions` are narration options and are rejected by the
10
+ * assistant.
11
+ */
12
+ export declare const narrationProviderSchema: z.ZodObject<{
13
+ kind: z.ZodLiteral<"gateway">;
14
+ options: z.ZodObject<{
15
+ instructions: z.ZodOptional<z.ZodString>;
16
+ model: z.ZodDefault<z.ZodString>;
17
+ voice: z.ZodDefault<z.ZodString>;
18
+ apiKeyEnv: z.ZodDefault<z.ZodString>;
19
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
20
+ providerOptions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodJSONSchema>>>;
21
+ }, z.core.$strict>;
22
+ requiredSecrets: z.ZodArray<z.ZodString>;
23
+ runtimeDeps: z.ZodArray<z.ZodString>;
24
+ }, z.core.$strict>;
25
+ /** A validated narration provider, defaults filled in. */
26
+ export type NarrationProvider = z.output<typeof narrationProviderSchema>;
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Narration's reading script: what "Listen to this page" says, in order, and
3
+ * where each spoken sentence sits in the page's text.
4
+ *
5
+ * One walker serves both sides. `blume build` runs it over the built HTML
6
+ * (parsed with node-html-parser) to generate a clip per sentence, and the
7
+ * player runs it over the live `<article>` to highlight the sentence being
8
+ * read. Both see the same markup and apply the same rules, so they agree on
9
+ * every block's text; the sentence split is only ever computed once per
10
+ * engine (by the build for generated audio, by the browser for its own
11
+ * voices), so an ICU difference between Node and the browser can't move a
12
+ * highlight.
13
+ *
14
+ * The rules follow what reads well aloud: the title, description, headings,
15
+ * and prose are read in order; callouts, steps, tabs, and collapsible
16
+ * sections are announced with a short spoken cue; code, tables, media,
17
+ * diagrams, math, API field tables, and anything marked
18
+ * `data-blume-narration="skip"` are left out.
19
+ */
20
+ /**
21
+ * The slice of a DOM-like tree the walker reads. The browser DOM and
22
+ * node-html-parser both satisfy it through a small adapter, so the walker
23
+ * never touches either API directly.
24
+ */
25
+ export interface NarrationTree<N> {
26
+ /** An element's attribute, or `null` when it is absent. */
27
+ attr: (node: N, name: string) => string | null;
28
+ children: (node: N) => readonly N[];
29
+ /** An element's lowercase tag name; `null` for text and other nodes. */
30
+ tag: (node: N) => string | null;
31
+ /** A text node's decoded text; `null` for elements and other nodes. */
32
+ text: (node: N) => string | null;
33
+ }
34
+ /**
35
+ * The spoken cues, already localized for the page. `{n}` in `step` is the
36
+ * step's number and `{title}` in `tab` is the tab's label. An empty string
37
+ * silences that cue.
38
+ */
39
+ export interface NarrationCues {
40
+ danger: string;
41
+ info: string;
42
+ note: string;
43
+ section: string;
44
+ step: string;
45
+ success: string;
46
+ tab: string;
47
+ tip: string;
48
+ warning: string;
49
+ }
50
+ /**
51
+ * A run of text read as one unit: a paragraph, heading, list item, or any
52
+ * other block. `nodes` are the text nodes it was read from; `nodeOf[i]` and
53
+ * `offsetOf[i]` locate character `i` of `text` in them, so a sentence's
54
+ * `[start, end)` maps back to a DOM range for highlighting.
55
+ */
56
+ export interface NarrationBlock<N> {
57
+ nodeOf: number[];
58
+ nodes: N[];
59
+ offsetOf: number[];
60
+ text: string;
61
+ }
62
+ /** One step of the reading order: a spoken cue, or a block of page text. */
63
+ export type NarrationItem = {
64
+ block: number;
65
+ kind: "block";
66
+ } | {
67
+ kind: "cue";
68
+ text: string;
69
+ };
70
+ /** What {@link extractNarration} reads from a page. */
71
+ export interface NarrationExtract<N> {
72
+ blocks: NarrationBlock<N>[];
73
+ items: NarrationItem[];
74
+ }
75
+ /**
76
+ * One spoken unit. A sentence carries its block and its `[start, end)` in
77
+ * that block's text; a cue carries `block: null`. `text` is what is spoken.
78
+ */
79
+ export interface NarrationSegment {
80
+ block: number | null;
81
+ end: number;
82
+ start: number;
83
+ text: string;
84
+ }
85
+ /**
86
+ * The per-page manifest `blume build` writes for generated narration. The
87
+ * player aligns `blocks` (the build's block texts) with the live page by
88
+ * text, then plays one clip per segment. A sentence names its block and range;
89
+ * a cue carries its spoken `text` instead.
90
+ */
91
+ export interface NarrationManifest {
92
+ blocks: string[];
93
+ segments: NarrationManifestSegment[];
94
+ version: 1;
95
+ }
96
+ /** One clip of a {@link NarrationManifest}: a sentence or a cue. */
97
+ export type NarrationManifestSegment = {
98
+ audio: string;
99
+ block: number;
100
+ end: number;
101
+ start: number;
102
+ } | {
103
+ audio: string;
104
+ text: string;
105
+ };
106
+ /**
107
+ * A page needs at least this many spoken characters (title and description
108
+ * included) to offer narration: roughly 50 English words. Shorter pages, and
109
+ * pages that are mostly code, tables, or API fields, get no player.
110
+ */
111
+ export declare const NARRATION_MIN_CHARS = 280;
112
+ /**
113
+ * Sentences longer than this are split at a clause, then a word boundary.
114
+ * Browser speech engines drop an utterance that runs past about 15 seconds,
115
+ * and shorter clips also keep the highlight moving.
116
+ */
117
+ export declare const NARRATION_MAX_SEGMENT_CHARS = 220;
118
+ /** The attribute that keeps an element (and everything in it) out of narration. */
119
+ export declare const NARRATION_SKIP_ATTRIBUTE = "data-blume-narration";
120
+ /**
121
+ * Walk `root` and return its reading order: each block of text, with the
122
+ * cues that introduce callouts, steps, tabs, and collapsible sections.
123
+ * Whitespace collapses to single spaces, as it renders.
124
+ */
125
+ export declare const extractNarration: <N>(root: N, tree: NarrationTree<N>, cues: NarrationCues) => NarrationExtract<N>;
126
+ /**
127
+ * Split an extract into spoken segments: a cue as it is, and each block into
128
+ * its sentences for `lang` (long ones broken further, see
129
+ * {@link NARRATION_MAX_SEGMENT_CHARS}).
130
+ */
131
+ export declare const segmentNarration: <N>(extract: NarrationExtract<N>, lang: string, max?: number) => NarrationSegment[];
132
+ /** How many characters the page's blocks will speak, cues excluded. */
133
+ export declare const narrationLength: <N>(extract: NarrationExtract<N>) => number;
134
+ /** Whether a page has enough prose to offer narration. */
135
+ export declare const isNarratable: <N>(extract: NarrationExtract<N>) => boolean;
136
+ /**
137
+ * Characters read per second at 1x: about 170 words a minute for
138
+ * space-separated scripts, and a slower character rate where a character is a
139
+ * word or more. Estimates only; neither engine reports durations up front.
140
+ */
141
+ export declare const narrationCharsPerSecond: (lang: string) => number;
142
+ /** The page's estimated listening time at 1x, in whole minutes (at least 1). */
143
+ export declare const narrationMinutes: (chars: number, lang: string) => number;
144
+ /**
145
+ * Map each manifest block onto the live page's blocks by exact text, in
146
+ * order, skipping page blocks the build didn't see (a script may have added
147
+ * some). A manifest block with no match maps to `-1`: its sentences still
148
+ * play, without a highlight.
149
+ */
150
+ export declare const alignBlocks: (manifestBlocks: readonly string[], pageBlocks: readonly string[]) => number[];
151
+ /** Whether a value (the player's `data-cues` JSON) is a full set of cues. */
152
+ export declare const isNarrationCues: (value: unknown) => value is NarrationCues;
153
+ /** Whether a fetched manifest has the shape the player plays. */
154
+ export declare const isNarrationManifest: (value: unknown) => value is NarrationManifest;
@@ -0,0 +1,27 @@
1
+ import type { ApiDocument } from "./model.ts";
2
+ /**
3
+ * Targeted checks for spec mistakes that would otherwise render silently
4
+ * wrong. This is not a validator — a linter such as Spectral or oasdiff owns
5
+ * that — and a spec that fails one of these still renders. Each check names
6
+ * one mistake whose symptom on the page is quiet: a path placeholder sent
7
+ * as literal text, a Try it input whose value goes nowhere, an Authorization
8
+ * section with no scheme to describe. Each reports a warning with its own
9
+ * code, so a build says what's wrong instead of shipping it.
10
+ */
11
+ /** One mistake a check found, before the source names the spec it's in. */
12
+ export interface SpecIssue {
13
+ code: string;
14
+ message: string;
15
+ suggestion: string;
16
+ }
17
+ /**
18
+ * How a warning names an operation: `GET /pets`, or a webhook by its name
19
+ * (`Webhook "newPet" (POST)`), since a webhook has no path.
20
+ */
21
+ export declare const operationLabel: (name: string, method: string, webhook: boolean) => string;
22
+ /**
23
+ * Check a parsed document for the mistakes above, and for the OpenAPI 3.2
24
+ * features Blume doesn't render yet. `$ref` path items are skipped: the
25
+ * extractor already reports them as missing from the reference.
26
+ */
27
+ export declare const specIssues: (document: ApiDocument) => SpecIssue[];