blume 2.1.3 → 2.2.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/AGENTS.md +1 -1
  2. package/CHANGELOG.md +134 -0
  3. package/README.md +4 -4
  4. package/dist/cli/{chunk-y4msrwm9.js → chunk-080mfch6.js} +15 -15
  5. package/dist/cli/{chunk-gfc5fqvf.js → chunk-1ch3ct3r.js} +18 -18
  6. package/dist/cli/{chunk-gfc5fqvf.js.map → chunk-1ch3ct3r.js.map} +1 -1
  7. package/dist/cli/{chunk-32khwcb6.js → chunk-2ssh60qh.js} +42 -69
  8. package/dist/cli/{chunk-32khwcb6.js.map → chunk-2ssh60qh.js.map} +9 -10
  9. package/dist/cli/{chunk-9qzgg6mj.js → chunk-34wap3ed.js} +3 -3
  10. package/dist/cli/{chunk-k3gr1nm9.js → chunk-40vk8kgf.js} +13 -16
  11. package/dist/cli/{chunk-k3gr1nm9.js.map → chunk-40vk8kgf.js.map} +3 -3
  12. package/dist/cli/chunk-487b95qy.js +329 -0
  13. package/dist/cli/chunk-487b95qy.js.map +13 -0
  14. package/dist/cli/chunk-4zxh25hc.js +157 -0
  15. package/dist/cli/chunk-4zxh25hc.js.map +10 -0
  16. package/dist/cli/chunk-69rjf786.js +146 -0
  17. package/dist/cli/chunk-69rjf786.js.map +11 -0
  18. package/dist/cli/{chunk-dqhg54mr.js → chunk-9h8mh2tk.js} +3 -3
  19. package/dist/cli/{chunk-dqhg54mr.js.map → chunk-9h8mh2tk.js.map} +2 -2
  20. package/dist/cli/{chunk-bqxaqn5p.js → chunk-9jqmq5hv.js} +8 -8
  21. package/dist/cli/{chunk-bqxaqn5p.js.map → chunk-9jqmq5hv.js.map} +1 -1
  22. package/dist/cli/{chunk-dv2z0rzf.js → chunk-aafhwx74.js} +38 -13
  23. package/dist/cli/{chunk-dv2z0rzf.js.map → chunk-aafhwx74.js.map} +5 -4
  24. package/dist/cli/{chunk-desvm72z.js → chunk-b680sv30.js} +22 -26
  25. package/dist/cli/chunk-b680sv30.js.map +13 -0
  26. package/dist/cli/{chunk-0w6hs479.js → chunk-beb0z983.js} +30 -18
  27. package/dist/cli/chunk-beb0z983.js.map +10 -0
  28. package/dist/cli/{chunk-1f882900.js → chunk-c5bjxq8v.js} +2 -2
  29. package/dist/cli/chunk-e1n41w9m.js +155 -0
  30. package/dist/cli/chunk-e1n41w9m.js.map +11 -0
  31. package/dist/cli/{chunk-sc93apfs.js → chunk-etckvbrh.js} +17 -17
  32. package/dist/cli/{chunk-sc93apfs.js.map → chunk-etckvbrh.js.map} +2 -2
  33. package/dist/cli/{chunk-bxwhtvw8.js → chunk-f260jdrn.js} +5 -5
  34. package/dist/cli/{chunk-74wfhv79.js → chunk-fnxgtjeq.js} +1 -1
  35. package/dist/cli/{chunk-ms9z66nz.js → chunk-gwy55cx3.js} +2 -2
  36. package/dist/cli/{chunk-ms9z66nz.js.map → chunk-gwy55cx3.js.map} +2 -2
  37. package/dist/cli/{chunk-dhwtqnnd.js → chunk-gxhcf2hs.js} +2 -2
  38. package/dist/cli/{chunk-tfycddbt.js → chunk-h0qwdbem.js} +2 -2
  39. package/dist/cli/{chunk-nbyvgnnm.js → chunk-hktq4j5r.js} +109 -49
  40. package/dist/cli/chunk-hktq4j5r.js.map +36 -0
  41. package/dist/cli/{chunk-twy7psdz.js → chunk-hn3g2b89.js} +14 -10
  42. package/dist/cli/chunk-hn3g2b89.js.map +10 -0
  43. package/dist/cli/{chunk-j1x92mx9.js → chunk-j4nfgn2j.js} +1 -1
  44. package/dist/cli/{chunk-dpy8qdjf.js → chunk-k45sq16q.js} +74 -183
  45. package/dist/cli/chunk-k45sq16q.js.map +18 -0
  46. package/dist/cli/{chunk-5cmts6dv.js → chunk-kmswjxj9.js} +7 -7
  47. package/dist/cli/{chunk-5cmts6dv.js.map → chunk-kmswjxj9.js.map} +1 -1
  48. package/dist/cli/{chunk-36bxs9c7.js → chunk-nqna8dzp.js} +27 -23
  49. package/dist/cli/chunk-nqna8dzp.js.map +10 -0
  50. package/dist/cli/{chunk-a57yh0h9.js → chunk-p834rkcn.js} +7 -7
  51. package/dist/cli/{chunk-a57yh0h9.js.map → chunk-p834rkcn.js.map} +1 -1
  52. package/dist/cli/{chunk-60hz265r.js → chunk-ppa6mg4d.js} +24 -11
  53. package/dist/cli/chunk-ppa6mg4d.js.map +10 -0
  54. package/dist/cli/{chunk-s0bdnc7v.js → chunk-q1wwrxzw.js} +5 -4
  55. package/dist/cli/chunk-q1wwrxzw.js.map +10 -0
  56. package/dist/cli/{chunk-ave1wcbr.js → chunk-qcyxkj44.js} +1 -1
  57. package/dist/cli/{chunk-124fvmzq.js → chunk-r5nm9w0c.js} +11183 -8806
  58. package/dist/cli/{chunk-124fvmzq.js.map → chunk-r5nm9w0c.js.map} +82 -66
  59. package/dist/cli/{chunk-ckrcm08h.js → chunk-rtvgmg2j.js} +48 -62
  60. package/dist/cli/{chunk-ckrcm08h.js.map → chunk-rtvgmg2j.js.map} +4 -5
  61. package/dist/cli/{chunk-297ajdcv.js → chunk-t2h8pwy1.js} +6 -6
  62. package/dist/cli/{chunk-297ajdcv.js.map → chunk-t2h8pwy1.js.map} +3 -3
  63. package/dist/cli/{chunk-gxtg6ed2.js → chunk-x60e15st.js} +21 -21
  64. package/dist/cli/{chunk-gxtg6ed2.js.map → chunk-x60e15st.js.map} +3 -3
  65. package/dist/cli/{chunk-58bt3hag.js → chunk-x7bh6d9j.js} +4 -4
  66. package/dist/cli/{chunk-hvcxng5f.js → chunk-ydqzkhjn.js} +6 -6
  67. package/dist/cli/{chunk-kdpzw38a.js → chunk-yg8ckc3g.js} +95 -7
  68. package/dist/cli/chunk-yg8ckc3g.js.map +11 -0
  69. package/dist/cli/{chunk-0pmb4tr4.js → chunk-zxd5jrgx.js} +1205 -222
  70. package/dist/cli/chunk-zxd5jrgx.js.map +44 -0
  71. package/dist/cli/index.js +78 -42
  72. package/dist/cli/index.js.map +7 -6
  73. package/dist/types/ai/changelog-components.d.ts +18 -0
  74. package/dist/types/ai/changelog-markdown.d.ts +12 -0
  75. package/dist/types/ai/openapi-components.d.ts +7 -7
  76. package/dist/types/ai/operation-details.d.ts +39 -0
  77. package/dist/types/ai/relative-links.d.ts +3 -1
  78. package/dist/types/ai/serializers.d.ts +6 -4
  79. package/dist/types/analytics/head.d.ts +4 -2
  80. package/dist/types/analytics/script.d.ts +8 -2
  81. package/dist/types/components/content/youtube.d.ts +20 -0
  82. package/dist/types/components/layout/nav-utils.d.ts +8 -0
  83. package/dist/types/components/openapi/example-panels.d.ts +33 -0
  84. package/dist/types/components/openapi/helpers.d.ts +53 -11
  85. package/dist/types/components/openapi/snippets.d.ts +7 -1
  86. package/dist/types/core/alert-diagnostics.d.ts +10 -0
  87. package/dist/types/core/builtin-tags.d.ts +16 -0
  88. package/dist/types/core/changelog-list.d.ts +48 -0
  89. package/dist/types/core/closest-match.d.ts +6 -0
  90. package/dist/types/core/code-fence-diagnostics.d.ts +18 -0
  91. package/dist/types/core/code-fences.d.ts +8 -1
  92. package/dist/types/core/config-input.d.ts +38 -6
  93. package/dist/types/core/content-assets.d.ts +16 -18
  94. package/dist/types/core/data.d.ts +6 -2
  95. package/dist/types/core/diagnostics.d.ts +14 -0
  96. package/dist/types/core/directive-diagnostics.d.ts +22 -8
  97. package/dist/types/core/former-routes.d.ts +14 -0
  98. package/dist/types/core/github.d.ts +5 -4
  99. package/dist/types/core/heading-markers.d.ts +65 -2
  100. package/dist/types/core/hidden-pages.d.ts +3 -0
  101. package/dist/types/core/includes.d.ts +23 -0
  102. package/dist/types/core/last-modified.d.ts +18 -6
  103. package/dist/types/core/links.d.ts +42 -2
  104. package/dist/types/core/load-module.d.ts +19 -4
  105. package/dist/types/core/manifest.d.ts +14 -1
  106. package/dist/types/core/markdown-mirrors.d.ts +22 -0
  107. package/dist/types/core/mcp-clients.d.ts +47 -0
  108. package/dist/types/core/mdx-elements.d.ts +32 -0
  109. package/dist/types/core/mdx-syntax.d.ts +100 -0
  110. package/dist/types/core/meta-diagnostics.d.ts +7 -0
  111. package/dist/types/core/meta.d.ts +32 -5
  112. package/dist/types/core/nav-diagnostics.d.ts +16 -2
  113. package/dist/types/core/navigation.d.ts +13 -0
  114. package/dist/types/core/ordering-prefix.d.ts +6 -0
  115. package/dist/types/core/pinned-ids.d.ts +23 -0
  116. package/dist/types/core/project-graph.d.ts +9 -1
  117. package/dist/types/core/redirect-patterns.d.ts +18 -0
  118. package/dist/types/core/relative-files.d.ts +31 -0
  119. package/dist/types/core/schema.d.ts +322 -11
  120. package/dist/types/core/sources/normalize.d.ts +101 -9
  121. package/dist/types/core/sources/types.d.ts +16 -0
  122. package/dist/types/core/static-files.d.ts +10 -0
  123. package/dist/types/core/static-host.d.ts +42 -0
  124. package/dist/types/core/svg-images.d.ts +26 -0
  125. package/dist/types/core/syntax-diagnostics.d.ts +14 -0
  126. package/dist/types/core/types.d.ts +42 -1
  127. package/dist/types/deploy/generated-files.d.ts +41 -0
  128. package/dist/types/deploy/redirects.d.ts +21 -7
  129. package/dist/types/markdown/code-title.d.ts +9 -5
  130. package/dist/types/markdown/directives.d.ts +8 -0
  131. package/dist/types/markdown/fence-language.d.ts +51 -0
  132. package/dist/types/markdown/fence-meta.d.ts +5 -0
  133. package/dist/types/markdown/github-alerts.d.ts +35 -0
  134. package/dist/types/openapi/asyncapi.d.ts +6 -5
  135. package/dist/types/openapi/checks.d.ts +10 -5
  136. package/dist/types/openapi/model.d.ts +55 -8
  137. package/dist/types/openapi/parse.d.ts +4 -1
  138. package/dist/types/ratelimit/index.d.ts +2 -0
  139. package/dist/types/ratelimit/memory.d.ts +1 -1
  140. package/dist/types/ratelimit/schema.d.ts +40 -0
  141. package/dist/types/ratelimit/unkey.d.ts +48 -0
  142. package/dist/types/sources/filesystem.d.ts +14 -4
  143. package/dist/types/sources/mdx-remote.d.ts +6 -3
  144. package/dist/types/sources/registry.d.ts +3 -3
  145. package/dist/types/theme/color.d.ts +33 -0
  146. package/dist/types/theme/palette.d.ts +122 -0
  147. package/docs/01-quickstart.mdx +1 -1
  148. package/docs/02-deployment.mdx +24 -8
  149. package/docs/04-migrating.mdx +16 -4
  150. package/docs/advanced/changelog.mdx +27 -1
  151. package/docs/advanced/skills.mdx +1 -1
  152. package/docs/cli/audit.mdx +1 -1
  153. package/docs/cli/doctor.mdx +2 -2
  154. package/docs/cli/evals.mdx +1 -1
  155. package/docs/cli/index.mdx +4 -2
  156. package/docs/cli/validate.mdx +10 -7
  157. package/docs/configuration/analytics.mdx +2 -0
  158. package/docs/configuration/customization.mdx +3 -1
  159. package/docs/configuration/index.mdx +7 -6
  160. package/docs/configuration/rate-limiting.mdx +20 -1
  161. package/docs/configuration/theming.mdx +5 -1
  162. package/docs/content/components.mdx +26 -6
  163. package/docs/content/frontmatter.mdx +1 -1
  164. package/docs/content/i18n.mdx +1 -1
  165. package/docs/content/includes.mdx +6 -2
  166. package/docs/content/index.mdx +11 -1
  167. package/docs/content/islands.mdx +2 -0
  168. package/docs/content/meta.mdx +9 -3
  169. package/docs/content/navigation.mdx +14 -6
  170. package/docs/content/sources/obsidian.mdx +1 -1
  171. package/docs/content/sources/remote-mdx.mdx +3 -1
  172. package/docs/content/syntax.mdx +76 -8
  173. package/docs/content/variables.mdx +3 -1
  174. package/docs/discoverability/agent-discovery.mdx +1 -1
  175. package/docs/discoverability/json-api.mdx +1 -1
  176. package/docs/discoverability/llms-txt.mdx +1 -1
  177. package/docs/discoverability/markdown.mdx +2 -2
  178. package/docs/discoverability/mcp.mdx +40 -8
  179. package/docs/discoverability/open-graph.mdx +1 -1
  180. package/docs/discoverability/sitemap-and-robots.mdx +1 -1
  181. package/docs/references/graphql.mdx +2 -0
  182. package/docs/references/openapi.mdx +45 -7
  183. package/package.json +4 -4
  184. package/skills/blume/SKILL.md +2 -2
  185. package/skills/blume-migrate/SKILL.md +51 -29
  186. package/skills/blume-migrate/references/docsify.md +262 -0
  187. package/skills/blume-migrate/references/docus.md +298 -0
  188. package/skills/blume-migrate/references/docusaurus.md +5 -5
  189. package/skills/blume-migrate/references/fern.md +327 -0
  190. package/skills/blume-migrate/references/fumadocs.md +1 -1
  191. package/skills/blume-migrate/references/gitbook.md +267 -0
  192. package/skills/blume-migrate/references/github-wiki.md +259 -0
  193. package/skills/blume-migrate/references/jekyll.md +253 -0
  194. package/skills/blume-migrate/references/mdbook.md +256 -0
  195. package/skills/blume-migrate/references/mintlify.md +5 -5
  196. package/skills/blume-migrate/references/mkdocs.md +236 -0
  197. package/skills/blume-migrate/references/monorepo.md +20 -8
  198. package/skills/blume-migrate/references/nextra.md +5 -5
  199. package/skills/blume-migrate/references/readme.md +257 -0
  200. package/skills/blume-migrate/references/redocly.md +198 -0
  201. package/skills/blume-migrate/references/starlight.md +3 -3
  202. package/skills/blume-migrate/references/vitepress.md +204 -0
  203. package/skills/blume-migrate/references/vuepress.md +271 -0
  204. package/skills/blume-migrate/scripts/docsify-codemod.mjs +2387 -0
  205. package/skills/blume-migrate/scripts/docus-codemod.mjs +2542 -0
  206. package/skills/blume-migrate/scripts/fern-codemod.mjs +2633 -0
  207. package/skills/blume-migrate/scripts/github-wiki-codemod.mjs +2808 -0
  208. package/skills/blume-migrate/scripts/include-excerpts.mjs +649 -0
  209. package/skills/blume-migrate/scripts/jekyll-codemod.mjs +3649 -0
  210. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +17 -13
  211. package/skills/blume-migrate/scripts/mkdocs-codemod.mjs +2526 -0
  212. package/skills/blume-migrate/scripts/operation-routes.mjs +508 -0
  213. package/skills/blume-migrate/scripts/pin-heading-ids.mjs +1049 -0
  214. package/skills/blume-migrate/scripts/readme-codemod.mjs +4139 -0
  215. package/skills/blume-migrate/scripts/vitepress-codemod.mjs +1511 -0
  216. package/src/ai/changelog-components.ts +24 -0
  217. package/src/ai/changelog-markdown.ts +45 -41
  218. package/src/ai/component-markdown.ts +22 -9
  219. package/src/ai/llms.ts +36 -5
  220. package/src/ai/markdown.ts +2 -2
  221. package/src/ai/openapi-components.ts +25 -9
  222. package/src/ai/operation-details.ts +208 -0
  223. package/src/ai/relative-links.ts +48 -8
  224. package/src/ai/serializers.ts +7 -6
  225. package/src/ai/site-skill.ts +6 -2
  226. package/src/analytics/head.ts +11 -5
  227. package/src/analytics/script.ts +13 -3
  228. package/src/astro/generate.ts +47 -11
  229. package/src/astro/index.ts +1 -0
  230. package/src/astro/integration.ts +27 -1
  231. package/src/astro/mdx-source-errors.ts +46 -0
  232. package/src/astro/templates.ts +93 -189
  233. package/src/audit/checks/redirects.ts +5 -1
  234. package/src/audit/redirects.ts +36 -19
  235. package/src/audit/report.ts +22 -9
  236. package/src/audit/run.ts +12 -28
  237. package/src/audit/terms.ts +23 -0
  238. package/src/audit/url.ts +2 -2
  239. package/src/cli/build-failure.ts +256 -7
  240. package/src/cli/command-meta.ts +1 -1
  241. package/src/cli/commands/audit.ts +1 -1
  242. package/src/cli/commands/build.ts +12 -3
  243. package/src/cli/commands/check.ts +13 -2
  244. package/src/cli/commands/dev.ts +1 -1
  245. package/src/cli/commands/doctor.ts +4 -2
  246. package/src/cli/commands/init.ts +3 -3
  247. package/src/cli/commands/preview.ts +17 -1
  248. package/src/cli/commands/validate.ts +22 -10
  249. package/src/cli/prepare.ts +1 -1
  250. package/src/cli/preview-pages.ts +161 -0
  251. package/src/cli/required-secrets.ts +0 -1
  252. package/src/cli/unknown-flags.ts +1 -42
  253. package/src/components/code-copy.ts +51 -0
  254. package/src/components/code-language.ts +75 -0
  255. package/src/components/content/AccordionItem.astro +16 -1
  256. package/src/components/content/Callout.astro +11 -1
  257. package/src/components/content/Changelog.astro +189 -0
  258. package/src/components/content/CodeBlock.astro +8 -11
  259. package/src/components/content/Tabs.astro +16 -2
  260. package/src/components/content/YouTube.astro +6 -4
  261. package/src/components/content/code-block.ts +33 -0
  262. package/src/components/content/content-strings.ts +5 -1
  263. package/src/components/content/inline-markdown.ts +35 -8
  264. package/src/components/content/youtube.ts +49 -7
  265. package/src/components/layout/Analytics.astro +5 -1
  266. package/src/components/layout/NavTree.astro +8 -3
  267. package/src/components/layout/PageActions.astro +81 -23
  268. package/src/components/layout/RootLayout.astro +35 -32
  269. package/src/components/layout/SiteFooter.astro +31 -8
  270. package/src/components/layout/nav-utils.ts +14 -0
  271. package/src/components/layout/search/pagefind.ts +2 -1
  272. package/src/components/openapi/Operation.astro +4 -0
  273. package/src/components/openapi/PanelTabs.astro +9 -3
  274. package/src/components/openapi/RequestBody.astro +42 -8
  275. package/src/components/openapi/RequestPanel.astro +34 -53
  276. package/src/components/openapi/example-panels.ts +110 -0
  277. package/src/components/openapi/helpers.ts +195 -20
  278. package/src/components/openapi/operation-model.ts +63 -26
  279. package/src/components/openapi/request.ts +13 -0
  280. package/src/components/openapi/snippets.ts +14 -2
  281. package/src/core/alert-diagnostics.ts +89 -0
  282. package/src/core/builtin-tags.ts +76 -0
  283. package/src/core/changelog-list.ts +87 -0
  284. package/src/core/closest-match.ts +41 -0
  285. package/src/core/code-fence-diagnostics.ts +267 -0
  286. package/src/core/code-fences.ts +43 -7
  287. package/src/core/component-diagnostics.ts +65 -12
  288. package/src/core/config-input.ts +39 -5
  289. package/src/core/config.ts +46 -1
  290. package/src/core/content-assets.ts +64 -144
  291. package/src/core/data.ts +10 -3
  292. package/src/core/diagnostics.ts +36 -3
  293. package/src/core/directive-diagnostics.ts +265 -47
  294. package/src/core/former-routes.ts +46 -0
  295. package/src/core/git-ignored.ts +53 -0
  296. package/src/core/github.ts +5 -4
  297. package/src/core/heading-markers.ts +156 -2
  298. package/src/core/hidden-pages.ts +64 -0
  299. package/src/core/includes.ts +181 -41
  300. package/src/core/last-modified.ts +47 -10
  301. package/src/core/links.ts +438 -83
  302. package/src/core/load-module.ts +98 -9
  303. package/src/core/manifest.ts +12 -9
  304. package/src/core/markdown-mirrors.ts +52 -0
  305. package/src/core/mcp-clients.ts +87 -0
  306. package/src/core/mdx-elements.ts +153 -0
  307. package/src/core/mdx-syntax.ts +377 -0
  308. package/src/core/meta-diagnostics.ts +134 -0
  309. package/src/core/meta.ts +154 -55
  310. package/src/core/nav-diagnostics.ts +41 -4
  311. package/src/core/navigation.ts +70 -10
  312. package/src/core/ordering-prefix.ts +22 -2
  313. package/src/core/pinned-ids.ts +141 -0
  314. package/src/core/project-graph.ts +221 -29
  315. package/src/core/redirect-patterns.ts +41 -0
  316. package/src/core/relative-files.ts +145 -0
  317. package/src/core/schema.ts +110 -6
  318. package/src/core/sources/mdx-remote.ts +75 -14
  319. package/src/core/sources/normalize.ts +885 -179
  320. package/src/core/sources/notion.ts +5 -4
  321. package/src/core/sources/obsidian.ts +2 -5
  322. package/src/core/sources/types.ts +17 -0
  323. package/src/core/static-files.ts +40 -0
  324. package/src/core/static-host.ts +125 -0
  325. package/src/core/svg-images.ts +98 -0
  326. package/src/core/syntax-diagnostics.ts +491 -0
  327. package/src/core/types.ts +43 -1
  328. package/src/deploy/artifacts.ts +2 -28
  329. package/src/deploy/generated-files.ts +128 -0
  330. package/src/deploy/platforms/vercel.ts +25 -1
  331. package/src/deploy/redirects.ts +43 -16
  332. package/src/deploy/sitemap.ts +2 -1
  333. package/src/markdown/base-links.ts +87 -6
  334. package/src/markdown/code-title.ts +29 -13
  335. package/src/markdown/content-assets.ts +210 -0
  336. package/src/markdown/directives.ts +69 -5
  337. package/src/markdown/fence-language.ts +106 -0
  338. package/src/markdown/fence-meta.ts +42 -0
  339. package/src/markdown/github-alerts.ts +172 -0
  340. package/src/markdown/heading-anchors.ts +265 -56
  341. package/src/markdown/include.ts +30 -3
  342. package/src/markdown/index.ts +145 -40
  343. package/src/markdown/prompt-text.ts +95 -0
  344. package/src/markdown/relative-links.ts +37 -2
  345. package/src/markdown/route-snapshot.ts +22 -12
  346. package/src/markdown/svg-fallback.ts +51 -0
  347. package/src/markdown/title-heading.ts +134 -0
  348. package/src/migrate/migrate.ts +127 -2
  349. package/src/og/card.ts +14 -4
  350. package/src/openapi/asyncapi.ts +14 -6
  351. package/src/openapi/checks.ts +160 -15
  352. package/src/openapi/model.ts +172 -33
  353. package/src/openapi/parse.ts +13 -4
  354. package/src/openapi/render-mdx.ts +55 -9
  355. package/src/openapi/source.ts +87 -6
  356. package/src/ratelimit/index.ts +2 -0
  357. package/src/ratelimit/memory.ts +1 -1
  358. package/src/ratelimit/runtime.ts +81 -0
  359. package/src/ratelimit/schema.ts +2 -0
  360. package/src/ratelimit/unkey.ts +61 -0
  361. package/src/registry/eject.ts +0 -1
  362. package/src/registry/registry.ts +1 -1
  363. package/src/search/documents.ts +10 -2
  364. package/src/sources/filesystem.ts +28 -3
  365. package/src/sources/mdx-remote.ts +7 -15
  366. package/src/theme/color.ts +14 -0
  367. package/src/theme/entry.ts +22 -1
  368. package/src/theme/palette.ts +74 -1
  369. package/dist/cli/chunk-0pmb4tr4.js.map +0 -35
  370. package/dist/cli/chunk-0w6hs479.js.map +0 -10
  371. package/dist/cli/chunk-150jk7km.js +0 -52
  372. package/dist/cli/chunk-150jk7km.js.map +0 -10
  373. package/dist/cli/chunk-36bxs9c7.js.map +0 -10
  374. package/dist/cli/chunk-53jqw8z0.js +0 -89
  375. package/dist/cli/chunk-53jqw8z0.js.map +0 -10
  376. package/dist/cli/chunk-60hz265r.js.map +0 -10
  377. package/dist/cli/chunk-desvm72z.js.map +0 -14
  378. package/dist/cli/chunk-dpy8qdjf.js.map +0 -17
  379. package/dist/cli/chunk-es8h0v3j.js +0 -441
  380. package/dist/cli/chunk-es8h0v3j.js.map +0 -11
  381. package/dist/cli/chunk-kdpzw38a.js.map +0 -11
  382. package/dist/cli/chunk-nbyvgnnm.js.map +0 -36
  383. package/dist/cli/chunk-s0bdnc7v.js.map +0 -10
  384. package/dist/cli/chunk-twy7psdz.js.map +0 -10
  385. package/dist/cli/chunk-ydp3065p.js +0 -64
  386. package/dist/cli/chunk-ydp3065p.js.map +0 -10
  387. /package/dist/cli/{chunk-y4msrwm9.js.map → chunk-080mfch6.js.map} +0 -0
  388. /package/dist/cli/{chunk-9qzgg6mj.js.map → chunk-34wap3ed.js.map} +0 -0
  389. /package/dist/cli/{chunk-1f882900.js.map → chunk-c5bjxq8v.js.map} +0 -0
  390. /package/dist/cli/{chunk-bxwhtvw8.js.map → chunk-f260jdrn.js.map} +0 -0
  391. /package/dist/cli/{chunk-74wfhv79.js.map → chunk-fnxgtjeq.js.map} +0 -0
  392. /package/dist/cli/{chunk-dhwtqnnd.js.map → chunk-gxhcf2hs.js.map} +0 -0
  393. /package/dist/cli/{chunk-tfycddbt.js.map → chunk-h0qwdbem.js.map} +0 -0
  394. /package/dist/cli/{chunk-j1x92mx9.js.map → chunk-j4nfgn2j.js.map} +0 -0
  395. /package/dist/cli/{chunk-ave1wcbr.js.map → chunk-qcyxkj44.js.map} +0 -0
  396. /package/dist/cli/{chunk-58bt3hag.js.map → chunk-x7bh6d9j.js.map} +0 -0
  397. /package/dist/cli/{chunk-hvcxng5f.js.map → chunk-ydqzkhjn.js.map} +0 -0
@@ -1,5 +1,3 @@
1
- import { existsSync } from "node:fs";
2
-
3
1
  import { defineCommand } from "citty";
4
2
  import { join } from "pathe";
5
3
 
@@ -8,11 +6,15 @@ import {
8
6
  discoverPages,
9
7
  hasGeneratedChangelog,
10
8
  } from "../../astro/pages.ts";
9
+ import { normalizeBasePath } from "../../core/base-path.ts";
11
10
  import { BlumeError } from "../../core/diagnostics.ts";
12
11
  import { validateLinks } from "../../core/links.ts";
13
12
  import { buildManifest } from "../../core/manifest.ts";
14
13
  import { scanProject } from "../../core/project-graph.ts";
14
+ import { resolveDocsCollection } from "../../core/sources/collection.ts";
15
15
  import type { Diagnostic } from "../../core/types.ts";
16
+ import { generatedFilePaths } from "../../deploy/generated-files.ts";
17
+ import { referenceRoutes } from "../../openapi/references.ts";
16
18
  import { parseIgnoreFlag } from "../args.ts";
17
19
  import { commandMeta } from "../command-meta.ts";
18
20
  import { reportInternalError } from "../internal-error.ts";
@@ -56,13 +58,17 @@ export const validateCommand = defineCommand({
56
58
  // link-validation blind spot, so silently passing would be misleading.
57
59
  diagnostics.push(...project.diagnostics);
58
60
 
59
- // Custom `.astro` pages and the generated changelog index are servable
60
- // routes the content graph can't see — without them, a docs link to e.g.
61
- // a custom landing page fails as BLUME_BROKEN_LINK.
61
+ // Custom `.astro` pages, reference routes (a `scalar()` page), and the
62
+ // generated changelog index are servable routes the content graph can't
63
+ // see — without them, a docs link to e.g. a custom landing page fails as
64
+ // BLUME_BROKEN_LINK.
62
65
  const userPages = project.context.pagesRoot
63
66
  ? await discoverPages(project.context.pagesRoot)
64
67
  : [];
65
- const extraRoutes = customStaticRoutes(userPages);
68
+ const extraRoutes = [
69
+ ...customStaticRoutes(userPages),
70
+ ...referenceRoutes(project.config),
71
+ ];
66
72
  if (hasGeneratedChangelog(project, userPages)) {
67
73
  extraRoutes.push("/changelog");
68
74
  }
@@ -84,15 +90,21 @@ export const validateCommand = defineCommand({
84
90
  );
85
91
  }
86
92
 
87
- const publicDir = join(root, "public");
93
+ // Links to `public/` files and to the files the build generates
94
+ // (`/llms.txt`, `/sitemap.xml`) resolve too. With no `public/` folder,
95
+ // the site ships no public files, so links to one are reported.
88
96
  diagnostics.push(
89
97
  ...(await validateLinks(project.graph, {
90
98
  basePath: project.config.basePath,
91
99
  checkExternal: Boolean(args.external),
100
+ configFile: project.context.configFile ?? undefined,
101
+ contentRoot: resolveDocsCollection(project.config, root).base,
102
+ deployBase: normalizeBasePath(project.config.deployment.options.base),
92
103
  extraRoutes,
104
+ generatedFiles: generatedFilePaths(project),
93
105
  i18n: project.config.i18n,
94
106
  ignore,
95
- publicDir: existsSync(publicDir) ? publicDir : null,
107
+ publicDir: join(root, "public"),
96
108
  redirects: project.config.redirects,
97
109
  }))
98
110
  );
@@ -105,8 +117,8 @@ export const validateCommand = defineCommand({
105
117
  }
106
118
  }
107
119
 
108
- // `--strict` escalates warnings to failures; info-level notes (e.g.
109
- // BLUME_ASSETS_UNCHECKED when there is no public/ dir) stay advisory.
120
+ // `--strict` escalates warnings to failures; info-level notes stay
121
+ // advisory.
110
122
  const strictFailure =
111
123
  Boolean(args.strict) &&
112
124
  diagnostics.some((diagnostic) => diagnostic.severity !== "info");
@@ -112,7 +112,7 @@ export const prepareProject = async (
112
112
  const hadErrors = reportDiagnostics(project.diagnostics, options.root);
113
113
  const dropped =
114
114
  project.droppedPages > 0
115
- ? `${project.droppedPages} page(s) failed frontmatter validation and were dropped from the site. `
115
+ ? `${project.droppedPages} page(s) failed validation and were dropped from the site. `
116
116
  : "";
117
117
  const optIn = options.strictOptIn ?? options.mode === "dev";
118
118
  if (hadErrors && options.strict) {
@@ -0,0 +1,161 @@
1
+ import { readFileSync, statSync } from "node:fs";
2
+ import { Server } from "node:http";
3
+ import type { IncomingMessage } from "node:http";
4
+
5
+ import type { PreviewServer } from "astro";
6
+ import { join } from "pathe";
7
+
8
+ import { stripBasePath } from "../core/base-path.ts";
9
+ import {
10
+ compileEveryRedirect,
11
+ matchCompiledRedirect,
12
+ requestPath,
13
+ } from "../core/redirect-patterns.ts";
14
+ import type { CompiledRedirect } from "../core/redirect-patterns.ts";
15
+ import type { ResolvedConfig } from "../core/schema.ts";
16
+ import {
17
+ answerRequestsFirst,
18
+ trailingSlashAnswer,
19
+ } from "../core/static-host.ts";
20
+ import type { HostAnswer } from "../core/static-host.ts";
21
+ import type { BlumeManifest } from "../core/types.ts";
22
+ import { platformRedirects } from "../deploy/redirects.ts";
23
+
24
+ /**
25
+ * Astro previews a static build on Vite's preview server, which serves the
26
+ * files in `dist/` and nothing a host would add: the redirect rules the build
27
+ * writes for it (`_redirects`, `vercel.json`), which carry every pattern
28
+ * redirect, and the host's handling of a trailing slash (see
29
+ * `core/static-host.ts`). Its HTML fallback also answers a slashless `/guide`
30
+ * with `guide.html` whenever that path exists. It checks with
31
+ * `fs.existsSync`, which a directory passes too. A redirect from
32
+ * `/guide.html` (a migrated site's URL) has its redirect page written to
33
+ * `dist/guide.html/index.html`, a directory, so the fallback rewrites
34
+ * `/guide` to it, Astro's own preview rewrite appends `/index.html`, and the
35
+ * page at `/guide` becomes a redirect page that refreshes to itself forever.
36
+ * Hosts look up files, so they serve the page at `guide/index.html`.
37
+ */
38
+
39
+ /** Whether `path` is a directory (true) or a file (false); null when absent. */
40
+ const isDirectory = (path: string): boolean | null => {
41
+ try {
42
+ return statSync(path).isDirectory();
43
+ } catch {
44
+ return null;
45
+ }
46
+ };
47
+
48
+ /**
49
+ * The URL to serve a preview request from in place of the one Vite's HTML
50
+ * fallback would pick, or null to leave the request alone: the page's own
51
+ * `index.html` when `dist/<route>.html` is a directory, the redirect page of
52
+ * a redirect from `<route>.html`. `base` is the normalized
53
+ * `deployment.base`, which the URL carries and `dist/` doesn't.
54
+ */
55
+ export const previewPageUrl = (
56
+ distDir: string,
57
+ base: string,
58
+ url: string
59
+ ): string | null => {
60
+ const queryAt = url.search(/[?#]/u);
61
+ const pathname = queryAt === -1 ? url : url.slice(0, queryAt);
62
+ if (pathname.endsWith("/")) {
63
+ return null;
64
+ }
65
+ let route: string;
66
+ try {
67
+ route = decodeURIComponent(stripBasePath(base, pathname));
68
+ } catch {
69
+ return null;
70
+ }
71
+ const page = join(distDir, route);
72
+ if (!page.startsWith(`${distDir}/`)) {
73
+ return null;
74
+ }
75
+ return isDirectory(`${page}.html`) === true &&
76
+ isDirectory(join(page, "index.html")) === false
77
+ ? `${pathname}/index.html${queryAt === -1 ? "" : url.slice(queryAt)}`
78
+ : null;
79
+ };
80
+
81
+ /**
82
+ * The configured redirects as a static build's host files carry them, for
83
+ * the preview to answer as the host would. They're based against the pages
84
+ * of the last generated project (`blume.manifest.json` in the runtime dir),
85
+ * which tell a page from a public file and say which moved pages' Markdown
86
+ * copies move with them.
87
+ */
88
+ export const previewRedirects = (
89
+ config: ResolvedConfig,
90
+ runtimeDir: string
91
+ ): CompiledRedirect[] => {
92
+ if (config.redirects.length === 0) {
93
+ return [];
94
+ }
95
+ let manifest: Pick<BlumeManifest, "routes">;
96
+ try {
97
+ manifest = JSON.parse(
98
+ readFileSync(join(runtimeDir, "blume.manifest.json"), "utf-8")
99
+ );
100
+ } catch {
101
+ manifest = { routes: [] };
102
+ }
103
+ return compileEveryRedirect(platformRedirects({ config, manifest }));
104
+ };
105
+
106
+ /** What a static build's preview answers like a host would. */
107
+ export interface PreviewRouting {
108
+ /** The normalized `deployment.base` (`""` at the root). */
109
+ base: string;
110
+ distDir: string;
111
+ /**
112
+ * Whether a path names a folder of HTML in the project's `public/`, served
113
+ * at its slashed URL (see `publicFolder`).
114
+ */
115
+ isPublicFolder: (path: string) => boolean;
116
+ /** Every configured redirect, as the build's host files carry them. */
117
+ redirects: readonly CompiledRedirect[];
118
+ }
119
+
120
+ /**
121
+ * How the preview answers a request ahead of Vite: a configured redirect
122
+ * first, as the host's rules do, then the trailing slash, then the page
123
+ * Vite's fallback would miss ({@link previewPageUrl}).
124
+ */
125
+ export const previewAnswer = (
126
+ routing: PreviewRouting,
127
+ request: Pick<IncomingMessage, "method" | "url">
128
+ ): HostAnswer | null => {
129
+ const url = request.url ?? "/";
130
+ const redirect = matchCompiledRedirect(routing.redirects, requestPath(url));
131
+ if (redirect) {
132
+ return { kind: "redirect", location: redirect[0], status: redirect[1] };
133
+ }
134
+ const slash = trailingSlashAnswer(
135
+ request,
136
+ routing.base,
137
+ routing.isPublicFolder
138
+ );
139
+ if (slash) {
140
+ return slash;
141
+ }
142
+ const page = previewPageUrl(routing.distDir, routing.base, url);
143
+ return page === null ? null : { kind: "rewrite", url: page };
144
+ };
145
+
146
+ /**
147
+ * Answer each request with {@link previewAnswer} before Vite's middleware
148
+ * sees it. Astro's static preview hands back Vite's HTTP server beside the
149
+ * documented fields; without one, the server is left as it is.
150
+ */
151
+ export const servePreview = (
152
+ preview: PreviewServer,
153
+ routing: PreviewRouting
154
+ ): void => {
155
+ if (!("server" in preview && preview.server instanceof Server)) {
156
+ return;
157
+ }
158
+ answerRequestsFirst(preview.server, (request) =>
159
+ previewAnswer(routing, request)
160
+ );
161
+ };
@@ -45,7 +45,6 @@ const adapterSecretOwners = (config: ResolvedConfig): SecretOwner[] => {
45
45
  secrets: consent.requiredSecrets,
46
46
  });
47
47
  }
48
- // Upstash's endpoint and token.
49
48
  if (rateLimit) {
50
49
  owners.push({
51
50
  feature: `Rate limiting (${rateLimit.kind})`,
@@ -1,5 +1,6 @@
1
1
  import type { ArgsDef } from "citty";
2
2
 
3
+ import { closestMatch } from "../core/closest-match.ts";
3
4
  import type { Diagnostic } from "../core/types.ts";
4
5
 
5
6
  /** A flag the command doesn't declare, with the declared one it most resembles. */
@@ -74,48 +75,6 @@ const knownFlags = (argsDef: ArgsDef): Map<string, KnownFlag> => {
74
75
  return flags;
75
76
  };
76
77
 
77
- /** Edit distance between two short strings (insertions, deletions, swaps of one letter). */
78
- const distance = (from: string, to: string): number => {
79
- let previous = Array.from({ length: to.length + 1 }, (_, index) => index);
80
- for (const [row, fromChar] of [...from].entries()) {
81
- const current = [row + 1];
82
- for (const [column, toChar] of [...to].entries()) {
83
- current.push(
84
- Math.min(
85
- (previous[column + 1] ?? 0) + 1,
86
- (current[column] ?? 0) + 1,
87
- (previous[column] ?? 0) + (fromChar === toChar ? 0 : 1)
88
- )
89
- );
90
- }
91
- previous = current;
92
- }
93
- return previous[to.length] ?? 0;
94
- };
95
-
96
- /**
97
- * The candidate closest to `name`, when it's close enough to be the likely
98
- * intent: at most two edits away, and fewer edits than half the candidate's
99
- * length, so a short typo doesn't "suggest" an unrelated short word.
100
- */
101
- export const closestMatch = (
102
- name: string,
103
- candidates: readonly string[]
104
- ): string | undefined => {
105
- let best: { candidate: string; edits: number } | undefined;
106
- for (const candidate of candidates) {
107
- const edits = distance(name, candidate);
108
- if (
109
- edits <= 2 &&
110
- edits * 2 < candidate.length &&
111
- (best === undefined || edits < best.edits)
112
- ) {
113
- best = { candidate, edits };
114
- }
115
- }
116
- return best?.candidate;
117
- };
118
-
119
78
  /** A `--name`, `--no-name`, `--name=value`, or `-n` token, taken apart. */
120
79
  interface FlagToken {
121
80
  /** Whether it carries its value inline (`--port=4000`). */
@@ -0,0 +1,51 @@
1
+ /**
2
+ * What a code block's copy button puts on the clipboard. Most blocks copy as
3
+ * shown. A terminal session (` ```console `, ` ```shellsession `) shows
4
+ * prompts and output around its commands, and pasting that into a terminal
5
+ * runs the `$` and the output as commands, so it copies only the commands,
6
+ * prompts stripped, one per line.
7
+ */
8
+
9
+ /** Shiki's terminal-session language and its alias. */
10
+ const SESSION_LANGUAGES: ReadonlySet<string> = new Set([
11
+ "console",
12
+ "shellsession",
13
+ ]);
14
+
15
+ /**
16
+ * A command line: an optional prefix (`(venv)`, `user@host:~`,
17
+ * `[user@host dir]`), a prompt character, a space, then the command. The
18
+ * prefixes are the ones Shiki's session grammar reads, with a virtualenv's
19
+ * `(venv)` allowed on its own as Pygments' does. Shiki's `>` and Greek
20
+ * prompts are left out: a `>` line in a transcript is usually output (npm
21
+ * prints its scripts that way) or a continuation, handled below.
22
+ */
23
+ const PROMPT =
24
+ /^(?:\(\S+\)\s*)?(?:(?:sh\S*?|\w\S+[:@]\S+(?:\s+\S+)?|\[\S+?[:@][^\n]+?\].*?)\s*)?[#$%❯➜]\s+(?<command>.*)$/u;
25
+
26
+ /** The `> ` a shell prints before each continuation of a `\`-ended line. */
27
+ const CONTINUATION_PROMPT = /^> /u;
28
+
29
+ /**
30
+ * The commands of a terminal session, prompts stripped and output dropped. A
31
+ * line after one ending in `\` continues its command. A session with no
32
+ * prompt at all copies as written: it's commands alone.
33
+ */
34
+ const sessionCommands = (text: string): string => {
35
+ const commands: string[] = [];
36
+ let continuing = false;
37
+ for (const line of text.split("\n")) {
38
+ const command: string | undefined = continuing
39
+ ? line.replace(CONTINUATION_PROMPT, "")
40
+ : PROMPT.exec(line)?.groups?.command;
41
+ if (command) {
42
+ commands.push(command);
43
+ }
44
+ continuing = command?.trimEnd().endsWith("\\") ?? false;
45
+ }
46
+ return commands.length > 0 ? commands.join("\n") : text;
47
+ };
48
+
49
+ /** The text to copy from a block of `language` that reads `text`. */
50
+ export const copyableCode = (text: string, language = ""): string =>
51
+ SESSION_LANGUAGES.has(language.toLowerCase()) ? sessionCommands(text) : text;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * A fence language's display name: the label a code block's header shows in
3
+ * place of its language id, and the tab label of an untitled block in a
4
+ * `<CodeGroup>`. Shared by the docs layout's script and the tabs element's,
5
+ * so a block reads the same in both places.
6
+ */
7
+
8
+ /** Language id (lowercase, aliases included) → display name. */
9
+ const LANGUAGE_LABELS: ReadonlyMap<string, string> = new Map([
10
+ ["astro", "Astro"],
11
+ ["bash", "Bash"],
12
+ ["c", "C"],
13
+ ["c#", "C#"],
14
+ ["c++", "C++"],
15
+ ["console", "Console"],
16
+ ["cpp", "C++"],
17
+ ["cs", "C#"],
18
+ ["csharp", "C#"],
19
+ ["css", "CSS"],
20
+ ["dart", "Dart"],
21
+ ["diff", "Diff"],
22
+ ["docker", "Dockerfile"],
23
+ ["dockerfile", "Dockerfile"],
24
+ ["elixir", "Elixir"],
25
+ ["go", "Go"],
26
+ ["gql", "GraphQL"],
27
+ ["graphql", "GraphQL"],
28
+ ["html", "HTML"],
29
+ ["http", "HTTP"],
30
+ ["java", "Java"],
31
+ ["javascript", "JavaScript"],
32
+ ["js", "JavaScript"],
33
+ ["json", "JSON"],
34
+ ["jsonc", "JSONC"],
35
+ ["jsx", "JSX"],
36
+ ["kotlin", "Kotlin"],
37
+ ["kt", "Kotlin"],
38
+ ["lua", "Lua"],
39
+ ["markdown", "Markdown"],
40
+ ["md", "Markdown"],
41
+ ["mdx", "MDX"],
42
+ ["php", "PHP"],
43
+ ["plaintext", "Text"],
44
+ ["powershell", "PowerShell"],
45
+ ["ps1", "PowerShell"],
46
+ ["py", "Python"],
47
+ ["python", "Python"],
48
+ ["rb", "Ruby"],
49
+ ["rs", "Rust"],
50
+ ["ruby", "Ruby"],
51
+ ["rust", "Rust"],
52
+ ["scala", "Scala"],
53
+ ["scss", "SCSS"],
54
+ ["sh", "Shell"],
55
+ ["shell", "Shell"],
56
+ ["shellsession", "Shell Session"],
57
+ ["sql", "SQL"],
58
+ ["svelte", "Svelte"],
59
+ ["swift", "Swift"],
60
+ ["text", "Text"],
61
+ ["toml", "TOML"],
62
+ ["ts", "TypeScript"],
63
+ ["tsx", "TSX"],
64
+ ["txt", "Text"],
65
+ ["typescript", "TypeScript"],
66
+ ["vue", "Vue"],
67
+ ["xml", "XML"],
68
+ ["yaml", "YAML"],
69
+ ["yml", "YAML"],
70
+ ["zsh", "Zsh"],
71
+ ]);
72
+
73
+ /** The display name of a fence language, or the id as written for one without a name here. */
74
+ export const languageLabel = (language: string): string =>
75
+ LANGUAGE_LABELS.get(language.toLowerCase()) ?? language;
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  import Icon from "../Icon.astro";
3
3
  import { componentSlug } from "../slug.ts";
4
+ import { renderInlineTitle } from "./inline-markdown.ts";
4
5
 
5
6
  interface Props {
6
7
  title: string;
@@ -11,7 +12,12 @@ interface Props {
11
12
  }
12
13
 
13
14
  const { defaultOpen = false, description, icon, id, title } = Astro.props;
15
+ // The id still slugs the title as written, so existing deep links keep
16
+ // working once its Markdown renders.
14
17
  const accordionId = id ?? componentSlug(title);
18
+ // The title's inline Markdown (`The \`x\` option`), or undefined for a title
19
+ // shown as written.
20
+ const titleHtml = await renderInlineTitle(title);
15
21
  ---
16
22
 
17
23
  <details
@@ -34,7 +40,16 @@ const accordionId = id ?? componentSlug(title);
34
40
  )
35
41
  }
36
42
  <span>
37
- <span class="block">{title}</span>
43
+ {
44
+ titleHtml === undefined ? (
45
+ <span class="block">{title}</span>
46
+ ) : (
47
+ <span
48
+ class="block [&_a]:underline [&_a]:decoration-current/50 [&_code]:font-mono"
49
+ set:html={titleHtml}
50
+ />
51
+ )
52
+ }
38
53
  {
39
54
  description && (
40
55
  <span class="block font-normal text-muted-foreground text-sm">
@@ -6,6 +6,7 @@ import {
6
6
  admonitionType,
7
7
  } from "../colors.ts";
8
8
  import Icon from "../Icon.astro";
9
+ import { renderInlineTitle } from "./inline-markdown.ts";
9
10
 
10
11
  interface Props {
11
12
  type?: AdmonitionType | "check";
@@ -17,6 +18,9 @@ interface Props {
17
18
  const { color, icon, type = "info", title } = Astro.props;
18
19
  // `check` is an alias of `success`; fold it once so the tables need one row.
19
20
  const kind = admonitionType(type);
21
+ // The title's inline Markdown (a `:::note[Use **this**]` label passes its
22
+ // formatting through as Markdown), or undefined for a title shown as written.
23
+ const titleHtml = title ? await renderInlineTitle(title) : undefined;
20
24
 
21
25
  const variantClass: Record<AdmonitionType, string> = {
22
26
  danger: "border-red-500/25 bg-red-500/10",
@@ -50,7 +54,13 @@ const variantClass: Record<AdmonitionType, string> = {
50
54
  the unlayered prose rule): every child a small top margin, none on the
51
55
  first, and no trailing bottom margin. */}
52
56
  <div class="flex-1 [&>*]:mt-2! [&>*]:mb-0! [&>:first-child]:mt-0!">
53
- {title && <p class="font-semibold text-foreground">{title}</p>}
57
+ {
58
+ titleHtml === undefined ? (
59
+ title && <p class="font-semibold text-foreground">{title}</p>
60
+ ) : (
61
+ <p class="font-semibold text-foreground" set:html={titleHtml} />
62
+ )
63
+ }
54
64
  <slot />
55
65
  </div>
56
66
  </aside>