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,12 +1,26 @@
1
1
  import type { SourceEntry } from "./sources/types.ts";
2
2
  import type { Diagnostic } from "./types.ts";
3
3
  /**
4
- * Warn about each `:::name` container in an `.mdx` entry that isn't a callout.
5
- * The page keeps its content — the body renders between the literal `:::`
6
- * lines (see `markdown/directives.ts`) — but a typo like `:::warnig`, or a
7
- * `:::details` carried over from another docs tool, should read as the
8
- * mistake it is rather than as a finished page. Lines point into the file
9
- * the author wrote, a partial's own file for a container an `<include>`
10
- * brought in.
4
+ * Warn about the `:::` directives in an entry that don't render as their
5
+ * author meant. In `.mdx`:
6
+ *
7
+ * - `BLUME_UNKNOWN_DIRECTIVE`: a `:::name` container that isn't a callout.
8
+ * The page keeps its content — the body renders between the literal `:::`
9
+ * lines (see `markdown/directives.ts`) — but a typo like `:::warnig`, or a
10
+ * `:::details` carried over from another docs tool, should read as the
11
+ * mistake it is rather than as a finished page.
12
+ * - `BLUME_DIRECTIVE_OPENING_TEXT`: a callout opener with text after its
13
+ * name, which the page drops (`:::tip Some title`).
14
+ * - `BLUME_DIRECTIVE_CLOSING_TEXT`: a closing fence with text after it, which
15
+ * the page drops (`::: card` inside a `:::warning`).
16
+ * - `BLUME_DIRECTIVE_SPACED_NAME`: a spaced callout opener (`::: tip`), which
17
+ * the page shows as text.
18
+ *
19
+ * In `.md`, which renders no directives:
20
+ *
21
+ * - `BLUME_MD_DIRECTIVE`: a `:::name` opener, which the page shows as text.
22
+ *
23
+ * Lines point into the file the author wrote, a partial's own file for a
24
+ * directive an `<include>` brought in.
11
25
  */
12
- export declare const unknownDirectiveDiagnostics: (entry: SourceEntry, sourceName: string) => Diagnostic[];
26
+ export declare const directiveDiagnostics: (entry: SourceEntry, sourceName: string) => Diagnostic[];
@@ -0,0 +1,14 @@
1
+ import type { ResolvedConfig } from "./schema.ts";
2
+ import type { PageRecord } from "./types.ts";
3
+ type Redirect = ResolvedConfig["redirects"][number];
4
+ /**
5
+ * Redirects from the routes an earlier Blume published pages at
6
+ * (`PageRecord.formerRoute`) to where they publish now, so a date-named
7
+ * page's old URL keeps working. None is added where the old URL is still
8
+ * served (another page, or a custom page, lives there now), where an authored
9
+ * redirect already starts, or where two pages once resolved to it: that was a
10
+ * duplicate route, which failed the build, so the URL never served either.
11
+ * Both ends are written base-less, like authored redirects.
12
+ */
13
+ export declare const formerRouteRedirects: (pages: readonly PageRecord[], served: ReadonlySet<string>, config: Pick<ResolvedConfig, "basePath" | "redirects">) => Redirect[];
14
+ export {};
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * Repository URL derivation for `config.github`.
3
3
  *
4
- * Every repo-derived link — the header mark, per-page edit links, the agent
5
- * manifest's `repository` — is built from `host`, which defaults to github.com
6
- * but accepts a GitHub Enterprise origin so self-hosted and data-resident
7
- * installations get working links instead of ones pointing at the public site.
4
+ * Every repo-derived link — the footer's repository link, per-page edit links,
5
+ * the agent manifest's `repository` — is built from `host`, which defaults to
6
+ * github.com but accepts a GitHub Enterprise origin so self-hosted and
7
+ * data-resident installations get working links instead of ones pointing at the
8
+ * public site.
8
9
  *
9
10
  * The REST base is derived from the host unless `api` is set explicitly, since
10
11
  * the two Enterprise flavors expose it differently: Enterprise Cloud with data
@@ -13,7 +13,9 @@
13
13
  * Both heading pipelines share this parser — the render-time hast plugin
14
14
  * (`markdown/heading-anchors.ts`) and the scan-time source scanner
15
15
  * (`core/sources/normalize.ts`) — so the rendered `id`, the TOC entry, and the
16
- * anchor index `blume validate` checks against always agree.
16
+ * anchor index `blume validate` checks against always agree. Both also escape
17
+ * a pinned id's punctuation before they parse (`core/pinned-ids.ts`), so
18
+ * smart punctuation never rewrites the id an author pinned.
17
19
  */
18
20
  import type GithubSlugger from "github-slugger";
19
21
  /**
@@ -22,6 +24,64 @@ import type GithubSlugger from "github-slugger";
22
24
  * `remarkPluginFrontmatter` to filter the TOC.
23
25
  */
24
26
  export declare const TOC_HIDDEN_KEY = "__blumeTocHidden";
27
+ /**
28
+ * Frontmatter key carrying TOC text out of a render, keyed by slug, for the
29
+ * headings whose TOC entry must read differently from the heading's text
30
+ * content: a heading holding a `<Badge>` lists without the badge's text. The
31
+ * page template reads it back the way it reads {@link TOC_HIDDEN_KEY}.
32
+ */
33
+ export declare const TOC_TEXT_KEY = "__blumeTocText";
34
+ /**
35
+ * A heading's auto-generated anchor id, registered with the document slugger.
36
+ * The text is trimmed first: a heading that opens or ends with something that
37
+ * has no text (an inline component, an image, raw HTML) would otherwise slug
38
+ * that edge whitespace into a leading or trailing dash. A slug can still end
39
+ * in dashes when the slugger drops a symbol after a space (`Features ✨`);
40
+ * those go too, so no id ends in a dash.
41
+ */
42
+ export declare const headingSlug: (slugger: GithubSlugger, text: string) => string;
43
+ /**
44
+ * A heading's text with its badges taken out. `pieces` is the heading's text
45
+ * in order, with `null` where a badge stood; a badge between two words
46
+ * leaves one space, not the two around it (`Install <Badge>beta</Badge> now`
47
+ * reads `Install now`).
48
+ */
49
+ export declare const joinHeadingText: (pieces: readonly (string | null)[]) => string;
50
+ /**
51
+ * How a raw HTML node in a heading reads for its anchor: a `<Badge>` tag that
52
+ * opens or closes a run of badge text (a self-closing one is a badge with no
53
+ * text), the opening tag of an `<a>` (`target` its `id`, else its `name`),
54
+ * the `</a>` that closes one, or none of these.
55
+ */
56
+ export type RawHeadingTag = {
57
+ kind: "anchor-close";
58
+ } | {
59
+ kind: "anchor-open";
60
+ selfClosing: boolean;
61
+ target?: string;
62
+ } | {
63
+ kind: "badge";
64
+ selfClosing: boolean;
65
+ closing: boolean;
66
+ } | {
67
+ kind: "other";
68
+ };
69
+ /** Classify a raw HTML node in a heading — see {@link RawHeadingTag}. */
70
+ export declare const rawHeadingTag: (value: string) => RawHeadingTag;
71
+ /**
72
+ * A JSX attribute: a name with a string value or an `{expression}` one, or a
73
+ * `{...spread}` (no name).
74
+ */
75
+ export interface JsxAttribute {
76
+ name?: string;
77
+ type: string;
78
+ value?: string | {
79
+ type: string;
80
+ value?: string;
81
+ } | null;
82
+ }
83
+ /** A JSX `<a>`'s own fragment target: its string `id`, else its `name`. */
84
+ export declare const jsxAnchorTarget: (attributes: readonly JsxAttribute[]) => string | undefined;
25
85
  /**
26
86
  * Register a pinned `[#id]` with the document slugger, the way
27
87
  * `GithubSlugger#slug` registers the slugs it returns — so a later heading
@@ -32,7 +92,10 @@ export declare const TOC_HIDDEN_KEY = "__blumeTocHidden";
32
92
  */
33
93
  export declare const occupySlug: (slugger: GithubSlugger, id: string) => void;
34
94
  export interface HeadingMarkers {
35
- /** Author-pinned anchor id from `[#id]` or `{#id}`, used verbatim (never re-slugged). */
95
+ /**
96
+ * Author-pinned anchor id from `[#id]` or `{#id}`, used verbatim (never
97
+ * re-slugged, and never smart-punctuated: see `core/pinned-ids.ts`).
98
+ */
36
99
  id?: string;
37
100
  /** The heading text with every trailing marker stripped. */
38
101
  text: string;
@@ -0,0 +1,3 @@
1
+ import type { ContentGraph, PageRecord } from "./types.ts";
2
+ /** Whether a page is hidden from the navigation (see the module comment). */
3
+ export declare const isHiddenPage: (page: PageRecord, graph: ContentGraph) => boolean;
@@ -1,3 +1,4 @@
1
+ import type { LinkDefinition } from "./sources/normalize.ts";
1
2
  import type { Diagnostic } from "./types.ts";
2
3
  /**
3
4
  * Cheap pre-filter so include-free content (the overwhelmingly common case)
@@ -116,6 +117,28 @@ export declare const expandIncludes: (body: string, options: {
116
117
  /** Raw-file line of `body`'s first line, minus one (default `0`). */
117
118
  lineOffset?: number;
118
119
  }) => Promise<IncludeExpansion>;
120
+ /**
121
+ * `text` with each of `definitions` it doesn't define itself appended, so a
122
+ * reference in it resolves through a definition written elsewhere in the
123
+ * page (CommonMark definitions are document-wide). Definitions render
124
+ * nothing; they're left off a text that ends in an open code fence, where
125
+ * they'd show as code.
126
+ */
127
+ export declare const withDefinitions: (text: string, definitions: readonly LinkDefinition[]) => string;
128
+ /**
129
+ * A page's source with the link-reference definitions its included partials
130
+ * write appended, for the render to parse. Each partial is spliced after the
131
+ * page is parsed (see `markdown/include.ts`), so a reference in the page
132
+ * (`[PEP 508]`) to a definition in a partial would otherwise stay text,
133
+ * though an include reads as if written inline. The definitions come from
134
+ * the expansion every surface shares, so a partial's definition of a file
135
+ * beside it is already rebased onto the page. The page's own definition of
136
+ * a label wins.
137
+ */
138
+ export declare const withIncludedDefinitions: (body: string, options: {
139
+ sourcePath: string;
140
+ contentRoot?: string;
141
+ }) => Promise<string>;
119
142
  /**
120
143
  * Resolve one include statement to its fully-expanded markdown text — the
121
144
  * render plugin's entry point (it finds the statements as AST nodes and only
@@ -4,13 +4,23 @@ export interface ResolvedLastModified {
4
4
  enabled: boolean;
5
5
  source: "git" | "frontmatter";
6
6
  }
7
+ export declare const gitEnv: () => NodeJS.ProcessEnv;
7
8
  /** Normalize the `lastModified` config (`false | "git" | "frontmatter"`) into `{ enabled, source }`. */
8
9
  export declare const resolveLastModifiedConfig: (value: false | "git" | "frontmatter") => ResolvedLastModified;
9
10
  /**
10
- * Parse `git log --format=%x00%cI --name-only` output into a map of
11
- * repo-root-relative path → most recent committer ISO date. Each commit emits a
12
- * NUL-prefixed date line followed by the paths it touched; since git logs
13
- * newest-first, the first date seen for a path wins. Blank lines are ignored.
11
+ * Parse `git log --format=%x00%cI --name-status -M100%` output into a map of
12
+ * repo-root-relative path → the committer ISO date of the newest commit that
13
+ * changed the file. Each commit emits a NUL-prefixed date line followed by a
14
+ * status line per path it touched (`M\tpath`, `R100\told\tnew`); since git
15
+ * logs newest-first, the first date seen for a path wins. Blank lines are
16
+ * ignored.
17
+ *
18
+ * A rename (`-M100%` reports only exact ones, where the content is unchanged)
19
+ * follows the file the way `git log --follow` does for one path: it dates
20
+ * nothing itself, and the older commits that name the old path date the file
21
+ * under its current name, so renaming `page.md` to `page.mdx` keeps the page's
22
+ * date. A file whose visible history starts at a rename (a shallow clone cut
23
+ * off the commits before it) takes the rename's date.
14
24
  */
15
25
  export declare const parseGitLog: (output: string) => Map<string, string>;
16
26
  /**
@@ -33,8 +43,10 @@ export declare const gitRepositoryRoot: (root: string) => string | null;
33
43
  /**
34
44
  * Resolve each source file's last-modified date from git history, keyed by
35
45
  * absolute source path. Runs a single `git log` over the given content roots
36
- * (each local source's own root, which may diverge from `content.root`)
37
- * and maps repo-root-relative paths back to the given absolute paths
46
+ * (each local source's own root, which may diverge from `content.root`),
47
+ * following renames within them (see `parseGitLog`; a file moved in from
48
+ * outside every root dates from the move), and maps repo-root-relative paths
49
+ * back to the given absolute paths
38
50
  * (monorepo-safe via `rev-parse --show-toplevel`). Returns an empty map if git
39
51
  * is unavailable or the project isn't a repo — the feature then simply shows
40
52
  * no dates.
@@ -22,7 +22,9 @@ export interface RelativeLinkBase {
22
22
  * `/install`. A `.md`/`.mdx` target is a file link: `resolveFile` maps its
23
23
  * decoded path, relative to the linking file, to the route that file
24
24
  * publishes at, so a target with its own `slug` or an ordering prefix still
25
- * lands on its page instead of on its raw Markdown source. Without
25
+ * lands on its page instead of on its raw Markdown source. A file renamed
26
+ * from `.md` to `.mdx`, or back, is found under its other extension first,
27
+ * so a link written before the rename keeps that slug or prefix. Without
26
28
  * `resolveFile`, or for a file it doesn't know, the target resolves
27
29
  * route-relative with the extension dropped.
28
30
  *
@@ -31,6 +33,23 @@ export interface RelativeLinkBase {
31
33
  * name (`./node.js` for `node.js.mdx`, `./v1.2`) is still a page link.
32
34
  */
33
35
  export declare const resolveRelativeHref: (href: string, from: RelativeLinkBase, resolveFile?: (path: string) => string | undefined, hasRoute?: (route: string) => boolean) => string | undefined;
36
+ /**
37
+ * Where a root-relative link to a content file (`/guide/new.md`, the way
38
+ * VitePress, Docsify, and TypeDoc write one) lands: the route of the source
39
+ * file it names under the content root, with the authored `?query#hash`
40
+ * kept, or `undefined` when it names no source file (or isn't a root-relative
41
+ * `.md`/`.mdx` link at all). It's read as written from the content root, or,
42
+ * when it starts with `deployment.base`, as including the base (see
43
+ * `withBasePath`). `routeOfFile` maps an absolute source path to the route
44
+ * that file publishes at. A link that names no source file is left alone:
45
+ * `/guide/new.md` is also the URL of a page's Markdown copy, which a link may
46
+ * mean on purpose.
47
+ */
48
+ export declare const resolveRootFileHref: (href: string, options: {
49
+ contentRoot: string;
50
+ deployBase: string;
51
+ routeOfFile: (file: string) => string | undefined;
52
+ }) => string | undefined;
34
53
  /**
35
54
  * Whether a content file is its folder's index, from its name as written on
36
55
  * disk: `index.md(x)` after an ordering prefix, optionally carrying one of
@@ -92,14 +111,35 @@ export declare const validateLinks: (graph: ContentGraph, options: {
92
111
  * full-route-set resolution in `nav-diagnostics.ts`/`generateRuntime`.
93
112
  */
94
113
  extraRoutes?: string[];
114
+ /**
115
+ * The files the build generates beside `public/` (`/llms.txt`,
116
+ * `/sitemap.xml`; see `deploy/generated-files.ts`), base-less: links to
117
+ * them resolve like links to `public/` files.
118
+ */
119
+ generatedFiles?: string[];
95
120
  /** Locale routing when i18n is on; links then resolve into the page's locale. */
96
121
  i18n?: LocaleRouting | null;
122
+ /** The project's `public/` folder, or `null` when it has none (and so
123
+ * ships no public files). */
97
124
  publicDir: string | null;
98
125
  checkExternal?: boolean;
99
126
  /** External URLs not to request (`--ignore`). Internal links are always checked. */
100
127
  ignore?: (url: string) => boolean;
101
- /** Configured redirects; their `from` paths count as valid link targets. */
128
+ /**
129
+ * Configured redirects: their `from` paths count as valid link targets,
130
+ * and an internal `to` must land somewhere the site serves.
131
+ */
102
132
  redirects?: {
103
133
  from: string;
134
+ to: string;
104
135
  }[];
136
+ /** The config file the redirects are written in, for their positions. */
137
+ configFile?: string;
138
+ /**
139
+ * The `docs` collection's content root, which a root-relative link to a
140
+ * content file (`/guide/new.md`) is read from.
141
+ */
142
+ contentRoot?: string;
143
+ /** `deployment.base` (`""` or `/seg`), which such a link may start with. */
144
+ deployBase?: string;
105
145
  }) => Promise<Diagnostic[]>;
@@ -1,8 +1,18 @@
1
+ /**
2
+ * jiti aliases that resolve `blume` and every subpath it exports to the
3
+ * running Blume package, read from its own `exports` map. Without them a user
4
+ * module resolves `blume` by walking up from its own folder, so a `meta.ts`
5
+ * under a content root outside the project (`content.root: "../docs"`, a
6
+ * sibling workspace package) or a file `blume.config.ts` imports from beside
7
+ * the project can't find the `blume` installed in the project. A wildcard
8
+ * export (`./core/*`) becomes a prefix alias (`blume/core/`), which jiti
9
+ * extends with the rest of the specifier.
10
+ */
11
+ export declare const blumeModuleAliases: () => Record<string, string>;
1
12
  /**
2
13
  * Create a loader for user-authored ESM/TS modules (`blume.config.ts`,
3
- * `meta.ts`). One jiti instance is reused across every file the returned loader
4
- * is called with. `moduleCache: false` ensures edits are picked up on each load,
5
- * which is what makes dev-server regeneration reflect config/meta changes.
14
+ * `meta.ts`), in which `blume` resolves to the running package wherever the
15
+ * module lives (see {@link blumeModuleAliases}).
6
16
  */
7
17
  export declare const createModuleLoader: () => ((file: string) => Promise<unknown>);
8
18
  /**
@@ -12,6 +22,11 @@ export declare const createModuleLoader: () => ((file: string) => Promise<unknow
12
22
  * exports `null`/`undefined`, resolves to `undefined` so the caller can say
13
23
  * so, instead of validating `{}` (a bare `defineConfig({…})` call) or
14
24
  * `{ config }` (a named export). jiti's default interop is off because it
15
- * throws on `export default null`.
25
+ * throws on `export default null`. Turning it off changes how jiti compiles
26
+ * every module the config reaches, Blume's own source included, but jiti keys
27
+ * its disk cache by file and source alone, so this loader keeps a cache of its
28
+ * own: sharing one, it would run code compiled for {@link createModuleLoader}
29
+ * (and that loader, code compiled for this one), whichever loaded the file
30
+ * first.
16
31
  */
17
32
  export declare const createDefaultExportLoader: typeof createModuleLoader;
@@ -8,7 +8,20 @@ export declare const MANIFEST_VERSION = 1;
8
8
  * site search provider is enabled, so features like the MCP server can index
9
9
  * docs even when on-page search is off.
10
10
  */
11
- export declare const contentIndexable: (page: PageRecord, config: ResolvedConfig) => boolean;
11
+ export declare const contentIndexable: (page: PageRecord, config: ResolvedConfig, graph: ContentGraph) => boolean;
12
+ /**
13
+ * Fallback materialization: render the fallback locale's content at the
14
+ * localized URL for any translation a non-default locale is missing, so static
15
+ * output is fully prerendered (render-fallback, no client redirect). Fallback
16
+ * routes are not indexed and carry no `hreflang` of their own.
17
+ */
18
+ /**
19
+ * The description a page's `<head>` emits — `seo.description` over the front
20
+ * matter `description` — mirrored onto its route so the OG card's subtitle
21
+ * matches the page's `og:description`, and the summary page indexes like
22
+ * `llms.txt` give it.
23
+ */
24
+ export declare const metaDescription: (page: PageRecord) => string | undefined;
12
25
  /** Build the runtime manifest that bridges core and the generated Astro app. */
13
26
  export declare const buildManifest: (options: {
14
27
  context: ProjectContext;
@@ -0,0 +1,22 @@
1
+ import type { RouteSet } from "./locale-links.ts";
2
+ /**
3
+ * Where Blume serves each page's raw Markdown: a copy beside the page, named
4
+ * for its route (`/guide.md`, `/guide.mdx`; see `rawMarkdownEndpointTemplate`).
5
+ */
6
+ /** The extensions every page's Markdown copies are served at. */
7
+ export declare const MIRROR_EXTENSIONS: readonly [".md", ".mdx"];
8
+ /** The name a page's Markdown copies are served under, from its route. */
9
+ export declare const mirrorName: (route: string) => string;
10
+ /**
11
+ * The page whose Markdown copies are served under `name`, if any are: the
12
+ * root's under `/index`, and a page's under its own route. `/index` is no
13
+ * page's route, yet it names the root's copies, so a path that isn't a page
14
+ * can still name a served copy.
15
+ */
16
+ export declare const mirrorOwner: (pages: RouteSet, name: string) => string | undefined;
17
+ /**
18
+ * The page a served Markdown copy at `path` belongs to (`/guide.md` the page
19
+ * `/guide`'s, `/index.mdx` the root's), or `undefined` when `path` is no
20
+ * served copy.
21
+ */
22
+ export declare const mirroredPage: (pages: RouteSet, path: string) => string | undefined;
@@ -0,0 +1,47 @@
1
+ import type { LocalizableLabel } from "./schema.ts";
2
+ /**
3
+ * Clients the "Connect to MCP" page action knows how to install the server
4
+ * into, in display order. Shared by the config schema (`agents.mcp.clients`
5
+ * entries validate against this list) and the PageActions menu (which renders
6
+ * the full list when the config is `true`). Lives outside `schema.ts` so the
7
+ * component can import the list without pulling the whole config schema into
8
+ * the layout module graph.
9
+ */
10
+ export declare const mcpClients: readonly ["claude-code", "codex", "cursor", "vscode"];
11
+ export type McpClient = (typeof mcpClients)[number];
12
+ /** A client Blume doesn't ship: a menu row that copies its `command`. */
13
+ export interface McpCustomClient {
14
+ /**
15
+ * Command the row copies, with `{name}` (the server name as an id, like
16
+ * `acme-docs`) and `{url}` (the server's absolute URL) filled in.
17
+ */
18
+ command: string;
19
+ /** Icon beside the label: a Lucide name, inline SVG, or image. Defaults to `terminal`. */
20
+ icon?: string;
21
+ /** Row label, optionally per locale (`{ en: "…", de: "…" }`). */
22
+ label: LocalizableLabel;
23
+ }
24
+ export type McpClientEntry = McpClient | McpCustomClient;
25
+ /** A menu entry as a page renders it: a custom label resolved to its locale. */
26
+ export type McpMenuEntry = McpClient | (Omit<McpCustomClient, "label"> & {
27
+ label: string;
28
+ });
29
+ /** Whether a `clients` entry names a built-in client rather than a custom one. */
30
+ export declare const isBuiltInMcpClient: (client: McpClientEntry | McpMenuEntry) => client is McpClient;
31
+ /** Resolve the custom clients' labels for one page's locale. */
32
+ export declare const mcpMenuEntries: (clients: readonly McpClientEntry[], locale?: string, defaultLocale?: string) => McpMenuEntry[];
33
+ /**
34
+ * The menu's rows after "Copy server URL", each with whether a rule goes
35
+ * above it: wherever the list switches between commands to copy and install
36
+ * links ("Copy server URL" copies too), so the default menu keeps its one
37
+ * rule before Cursor.
38
+ */
39
+ export declare const mcpMenuRows: (entries: readonly McpMenuEntry[]) => {
40
+ client: McpMenuEntry;
41
+ rule: boolean;
42
+ }[];
43
+ /** Fill a custom client's command for the server it installs. */
44
+ export declare const mcpClientCommand: (command: string, server: {
45
+ name: string;
46
+ url: string;
47
+ }) => string;
@@ -0,0 +1,32 @@
1
+ import type { Nodes } from "mdast";
2
+ import type { ElementUse } from "./types.ts";
3
+ /**
4
+ * JSX elements in an `.mdx` body whose props don't render as written:
5
+ *
6
+ * - `handler`: an HTML element with a JavaScript event handler
7
+ * (`<button onClick={() => …}>`). The page is static HTML, so the function
8
+ * is written into the attribute as text and never runs. A string handler
9
+ * (`onclick="…"`) is inline script the browser does run, and is left alone.
10
+ * - `prop`: a built-in that shows its children (see `BUILTIN_CHILD_PROPS`),
11
+ * used without any, with props it doesn't take. Those are ignored, so the
12
+ * element renders without the content they carry.
13
+ */
14
+ type JsxElement = Extract<Nodes, {
15
+ type: "mdxJsxFlowElement" | "mdxJsxTextElement";
16
+ }>;
17
+ type AttributeValue = Extract<JsxElement["attributes"][number], {
18
+ type: "mdxJsxAttribute";
19
+ }>["value"];
20
+ type ExpressionValue = Extract<AttributeValue, {
21
+ type: string;
22
+ }>;
23
+ /** Whether an attribute's value is a `{…}` expression, not a string or nothing. */
24
+ export declare const isExpression: (value: AttributeValue) => value is ExpressionValue;
25
+ /**
26
+ * Every element in an `.mdx` body whose props don't render as written (see
27
+ * the module comment), in source order, its line shifted by `lineOffset`. The
28
+ * body is parsed only when a cheap test finds a suspect, and a body MDX can't
29
+ * parse fails to render with its own error, so it yields none.
30
+ */
31
+ export declare const extractElementUses: (body: string, lineOffset?: number) => ElementUse[];
32
+ export {};
@@ -0,0 +1,100 @@
1
+ import type { SourceEntry } from "./sources/types.ts";
2
+ import type { Diagnostic } from "./types.ts";
3
+ import type { ContentVariables } from "./variables.ts";
4
+ /**
5
+ * MDX that doesn't parse, found before Astro compiles it. The parse is
6
+ * Sätteri's, with the feature set the renderer uses, so a body that fails it
7
+ * here fails `astro build` too: Astro compiles every `.mdx` file in the
8
+ * collection, drafts and pages the scan dropped included. Parsing only (no
9
+ * plugins, no render) keeps it cheap enough to run on every page.
10
+ *
11
+ * - `BLUME_MDX_SYNTAX` (error): the page's own text doesn't parse, so the
12
+ * build fails at it.
13
+ * - `BLUME_MDX_SYNTAX` (warning): the page parses, but not once its
14
+ * `<include>`s are spliced in. Reported in the partial. The render splices a
15
+ * partial more leniently than this parse reads it, so the page may still
16
+ * build, with the partial's markup rendered wrong (an HTML comment shown as
17
+ * text, an unclosed `<img>` taking in what follows it).
18
+ *
19
+ * The same reading locates a build failure Astro reports with no line: an
20
+ * `.mdx` page that throws while it renders (a `{…}` expression reading a name
21
+ * nothing defines), or a partial that breaks the including page's compile.
22
+ */
23
+ /** Where MDX stopped reading a text, and why. */
24
+ export interface MdxSyntaxError {
25
+ column: number;
26
+ line: number;
27
+ /** Sätteri's message, without its leading position and trailing rule id. */
28
+ reason: string;
29
+ }
30
+ /**
31
+ * The first MDX syntax error in `text`, a page body with its front matter
32
+ * off, or null when it parses.
33
+ *
34
+ * Only the verdict is needed, so the parse stays native: Sätteri's tree is
35
+ * dropped unread rather than built as JavaScript objects, which costs as much
36
+ * again as the parse itself on every page. A parse error carries its own
37
+ * position, so node positions aren't tracked either.
38
+ */
39
+ export declare const mdxSyntaxError: (text: string) => MdxSyntaxError | null;
40
+ /** A position in the file the author wrote. */
41
+ interface Site {
42
+ column?: number;
43
+ file: string;
44
+ line: number;
45
+ }
46
+ /** Maps a line and column of the parsed text to the file it came from. */
47
+ type SiteOf = (line: number, column?: number) => Site;
48
+ /**
49
+ * The `BLUME_MDX_SYNTAX` diagnostic for `error`, read from a text whose lines
50
+ * `siteOf` places.
51
+ */
52
+ export declare const mdxSyntaxDiagnostic: (error: MdxSyntaxError, siteOf: SiteOf, options: {
53
+ includedIn?: string;
54
+ severity: Diagnostic["severity"];
55
+ }) => Diagnostic;
56
+ /** What the scan learned from parsing an `.mdx` entry. */
57
+ export interface MdxSyntaxCheck {
58
+ diagnostics: Diagnostic[];
59
+ /** Whether the page's own text fails to parse, so its build would fail. */
60
+ unparsable: boolean;
61
+ }
62
+ /**
63
+ * Parse an `.mdx` entry's body, and its include-expanded text when it has
64
+ * one (see the module comment). The body is read as the build reads it: with
65
+ * the site's variables substituted, which the scan has already done when
66
+ * there was no expansion to do it in.
67
+ */
68
+ export declare const mdxSyntaxCheck: (entry: SourceEntry, sourceName: string, variables?: ContentVariables) => MdxSyntaxCheck;
69
+ /** A page as the build failure locator reads it. */
70
+ export interface FailedPage {
71
+ /** The owning source's content root, which bounds its includes. */
72
+ contentRoot?: string;
73
+ /** How a message names the page: its path from the project root. */
74
+ name: string;
75
+ sourcePath: string;
76
+ variables?: ContentVariables;
77
+ }
78
+ /** What a build failure in an `.mdx` page said about itself. */
79
+ export type MdxFailure = {
80
+ kind: "syntax";
81
+ } | {
82
+ kind: "undefined-name";
83
+ name: string;
84
+ };
85
+ /** Where a build failure happened in the files the author wrote. */
86
+ export interface MdxFailureSite extends Site {
87
+ /** For a syntax failure, the parse's own diagnostic. */
88
+ diagnostic?: Diagnostic;
89
+ /** For an undefined name, the expression that reads it, braces included. */
90
+ expression?: string;
91
+ }
92
+ /**
93
+ * Locate a build failure Astro reported against an `.mdx` page with no line:
94
+ * the expression that reads an undefined name, or the syntax error that
95
+ * stopped the compile (which, when the page's own text parsed, sits in a
96
+ * partial it includes). Null when the page can't be read or the cause can't
97
+ * be found in it.
98
+ */
99
+ export declare const locateMdxFailure: (page: FailedPage, failure: MdxFailure) => Promise<MdxFailureSite | null>;
100
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { DiscoveredFolderMeta } from "./meta.ts";
2
+ import type { Diagnostic, PageRecord } from "./types.ts";
3
+ /** Folder-meta diagnostics against every page the sources produced. */
4
+ export declare const folderMetaDiagnostics: (discovered: DiscoveredFolderMeta, pages: readonly PageRecord[], options?: {
5
+ localeDirs?: readonly string[];
6
+ versionDirs?: readonly string[];
7
+ }) => Promise<Diagnostic[]>;
@@ -19,6 +19,26 @@ export interface FolderMetaSource {
19
19
  * translates through this too, so it covers exactly the ones the scan reads.
20
20
  */
21
21
  export declare const findFolderMetaFiles: (source: FolderMetaSource, patterns?: readonly string[]) => Promise<string[]>;
22
+ /** Folder meta by key: per-locale `meta.*` files, and shared `meta.$.*` ones. */
23
+ export interface FolderMetaMaps {
24
+ meta: Map<string, FolderMeta>;
25
+ shared: Map<string, FolderMeta>;
26
+ }
27
+ /** A folder-meta file Blume found but doesn't read, and the key it would have. */
28
+ export interface UnreadFolderMeta {
29
+ /** Its folder, relative to the source root. */
30
+ dir: string;
31
+ file: string;
32
+ key: string;
33
+ }
34
+ /** What {@link discoverFolderMeta} found across the sources. */
35
+ export interface DiscoveredFolderMeta extends FolderMetaMaps {
36
+ diagnostics: Diagnostic[];
37
+ /** The file each meta in `meta` and `shared` was read from. */
38
+ files: Map<FolderMeta, string>;
39
+ /** Meta files under a source root that no source's `include` globs reach. */
40
+ unread: UnreadFolderMeta[];
41
+ }
22
42
  /**
23
43
  * Discover `meta.{ts,js,mjs}` files across the given filesystem sources. Keys are
24
44
  * the source's route prefix joined with the directory relative to that source's
@@ -43,8 +63,15 @@ export declare const findFolderMetaFiles: (source: FolderMetaSource, patterns?:
43
63
  export declare const discoverFolderMeta: (sources: string | FolderMetaSource[], options?: {
44
64
  localeDirs?: readonly string[];
45
65
  versionDirs?: readonly string[];
46
- }) => Promise<{
47
- meta: Map<string, FolderMeta>;
48
- shared: Map<string, FolderMeta>;
49
- diagnostics: Diagnostic[];
50
- }>;
66
+ }) => Promise<DiscoveredFolderMeta>;
67
+ /**
68
+ * Lay the folder meta content sources derive (the OpenAPI source's tag
69
+ * titles and order) beneath the user's `meta.ts` and `meta.$.ts` files, field
70
+ * by field: a user file's own keys win, and the generated ones fill the rest,
71
+ * so a `meta.ts` that only renames a tag group keeps its generated `order`.
72
+ * Generated meta is locale-agnostic, keyed like `meta.$.*`, so it also sits
73
+ * beneath a locale's own `meta.ts` (`fr/reference/pets` over
74
+ * `reference/pets`). It doesn't reach into an archived version's snapshot,
75
+ * whose groups read only meta keyed under the version.
76
+ */
77
+ export declare const withGeneratedFolderMeta: (user: FolderMetaMaps, generated: Map<string, FolderMeta>, localeDirs?: readonly string[]) => FolderMetaMaps;