blume 2.1.3 → 2.2.0

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 (377) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +126 -0
  3. package/README.md +4 -4
  4. package/dist/cli/{chunk-74wfhv79.js → chunk-05f21r8h.js} +1 -1
  5. package/dist/cli/{chunk-9qzgg6mj.js → chunk-1cm0h819.js} +3 -3
  6. package/dist/cli/{chunk-nbyvgnnm.js → chunk-1rkxzg3n.js} +104 -47
  7. package/dist/cli/chunk-1rkxzg3n.js.map +36 -0
  8. package/dist/cli/{chunk-desvm72z.js → chunk-2nr29y95.js} +22 -26
  9. package/dist/cli/chunk-2nr29y95.js.map +13 -0
  10. package/dist/cli/{chunk-32khwcb6.js → chunk-49r370mb.js} +42 -69
  11. package/dist/cli/{chunk-32khwcb6.js.map → chunk-49r370mb.js.map} +9 -10
  12. package/dist/cli/{chunk-ms9z66nz.js → chunk-4rftmttv.js} +2 -2
  13. package/dist/cli/{chunk-s0bdnc7v.js → chunk-79bzzkx4.js} +5 -4
  14. package/dist/cli/chunk-79bzzkx4.js.map +10 -0
  15. package/dist/cli/{chunk-hvcxng5f.js → chunk-7tekknev.js} +6 -6
  16. package/dist/cli/{chunk-dv2z0rzf.js → chunk-8b489v1b.js} +38 -13
  17. package/dist/cli/{chunk-dv2z0rzf.js.map → chunk-8b489v1b.js.map} +5 -4
  18. package/dist/cli/{chunk-0pmb4tr4.js → chunk-8f8xw4x2.js} +1195 -222
  19. package/dist/cli/chunk-8f8xw4x2.js.map +44 -0
  20. package/dist/cli/chunk-96snx8yy.js +329 -0
  21. package/dist/cli/chunk-96snx8yy.js.map +13 -0
  22. package/dist/cli/{chunk-ckrcm08h.js → chunk-a3ydrqny.js} +48 -62
  23. package/dist/cli/{chunk-ckrcm08h.js.map → chunk-a3ydrqny.js.map} +4 -5
  24. package/dist/cli/{chunk-bxwhtvw8.js → chunk-ahc5gc9h.js} +5 -5
  25. package/dist/cli/{chunk-dpy8qdjf.js → chunk-as09pafp.js} +73 -182
  26. package/dist/cli/chunk-as09pafp.js.map +18 -0
  27. package/dist/cli/{chunk-tfycddbt.js → chunk-bjk964fp.js} +2 -2
  28. package/dist/cli/{chunk-gfc5fqvf.js → chunk-br0n8n3e.js} +18 -18
  29. package/dist/cli/{chunk-gfc5fqvf.js.map → chunk-br0n8n3e.js.map} +1 -1
  30. package/dist/cli/{chunk-297ajdcv.js → chunk-c69tw29j.js} +6 -6
  31. package/dist/cli/{chunk-297ajdcv.js.map → chunk-c69tw29j.js.map} +3 -3
  32. package/dist/cli/chunk-cn3dy3hz.js +146 -0
  33. package/dist/cli/chunk-cn3dy3hz.js.map +11 -0
  34. package/dist/cli/{chunk-124fvmzq.js → chunk-dm4mg9bj.js} +11064 -8742
  35. package/dist/cli/{chunk-124fvmzq.js.map → chunk-dm4mg9bj.js.map} +78 -64
  36. package/dist/cli/{chunk-dqhg54mr.js → chunk-dmx6cezx.js} +1 -1
  37. package/dist/cli/{chunk-60hz265r.js → chunk-dpcahcrb.js} +24 -11
  38. package/dist/cli/chunk-dpcahcrb.js.map +10 -0
  39. package/dist/cli/{chunk-a57yh0h9.js → chunk-dyk3r7jw.js} +7 -7
  40. package/dist/cli/{chunk-a57yh0h9.js.map → chunk-dyk3r7jw.js.map} +1 -1
  41. package/dist/cli/{chunk-twy7psdz.js → chunk-enk76qd5.js} +14 -10
  42. package/dist/cli/chunk-enk76qd5.js.map +10 -0
  43. package/dist/cli/{chunk-k3gr1nm9.js → chunk-fqy4n3q2.js} +13 -16
  44. package/dist/cli/{chunk-k3gr1nm9.js.map → chunk-fqy4n3q2.js.map} +3 -3
  45. package/dist/cli/{chunk-sc93apfs.js → chunk-frk2wdq1.js} +17 -17
  46. package/dist/cli/{chunk-sc93apfs.js.map → chunk-frk2wdq1.js.map} +2 -2
  47. package/dist/cli/{chunk-kdpzw38a.js → chunk-gprwej7h.js} +95 -7
  48. package/dist/cli/chunk-gprwej7h.js.map +11 -0
  49. package/dist/cli/chunk-kkrteb15.js +157 -0
  50. package/dist/cli/chunk-kkrteb15.js.map +10 -0
  51. package/dist/cli/{chunk-ave1wcbr.js → chunk-m9bp2hc1.js} +1 -1
  52. package/dist/cli/{chunk-58bt3hag.js → chunk-mrvh4c88.js} +4 -4
  53. package/dist/cli/{chunk-5cmts6dv.js → chunk-p8zg3a2h.js} +7 -7
  54. package/dist/cli/{chunk-5cmts6dv.js.map → chunk-p8zg3a2h.js.map} +1 -1
  55. package/dist/cli/{chunk-0w6hs479.js → chunk-rkqae7kh.js} +30 -18
  56. package/dist/cli/chunk-rkqae7kh.js.map +10 -0
  57. package/dist/cli/{chunk-bqxaqn5p.js → chunk-t5xx74rd.js} +8 -8
  58. package/dist/cli/{chunk-bqxaqn5p.js.map → chunk-t5xx74rd.js.map} +1 -1
  59. package/dist/cli/{chunk-1f882900.js → chunk-th0pgaj5.js} +2 -2
  60. package/dist/cli/{chunk-dhwtqnnd.js → chunk-vnbvhgmd.js} +2 -2
  61. package/dist/cli/{chunk-gxtg6ed2.js → chunk-vzy9rh6y.js} +21 -21
  62. package/dist/cli/{chunk-gxtg6ed2.js.map → chunk-vzy9rh6y.js.map} +3 -3
  63. package/dist/cli/{chunk-j1x92mx9.js → chunk-w6e455pz.js} +1 -1
  64. package/dist/cli/chunk-wehv26ry.js +155 -0
  65. package/dist/cli/chunk-wehv26ry.js.map +11 -0
  66. package/dist/cli/{chunk-y4msrwm9.js → chunk-xgq4eytj.js} +15 -15
  67. package/dist/cli/{chunk-36bxs9c7.js → chunk-xt0qvz1t.js} +27 -23
  68. package/dist/cli/chunk-xt0qvz1t.js.map +10 -0
  69. package/dist/cli/index.js +78 -42
  70. package/dist/cli/index.js.map +7 -6
  71. package/dist/types/ai/changelog-components.d.ts +18 -0
  72. package/dist/types/ai/changelog-markdown.d.ts +12 -0
  73. package/dist/types/ai/openapi-components.d.ts +7 -7
  74. package/dist/types/ai/operation-details.d.ts +39 -0
  75. package/dist/types/ai/relative-links.d.ts +3 -1
  76. package/dist/types/ai/serializers.d.ts +6 -4
  77. package/dist/types/analytics/head.d.ts +4 -2
  78. package/dist/types/analytics/script.d.ts +8 -2
  79. package/dist/types/components/content/youtube.d.ts +20 -0
  80. package/dist/types/components/layout/nav-utils.d.ts +8 -0
  81. package/dist/types/components/openapi/example-panels.d.ts +33 -0
  82. package/dist/types/components/openapi/helpers.d.ts +53 -11
  83. package/dist/types/components/openapi/snippets.d.ts +7 -1
  84. package/dist/types/core/alert-diagnostics.d.ts +10 -0
  85. package/dist/types/core/builtin-tags.d.ts +16 -0
  86. package/dist/types/core/changelog-list.d.ts +48 -0
  87. package/dist/types/core/closest-match.d.ts +6 -0
  88. package/dist/types/core/code-fence-diagnostics.d.ts +18 -0
  89. package/dist/types/core/code-fences.d.ts +8 -1
  90. package/dist/types/core/config-input.d.ts +1 -1
  91. package/dist/types/core/content-assets.d.ts +16 -18
  92. package/dist/types/core/diagnostics.d.ts +14 -0
  93. package/dist/types/core/directive-diagnostics.d.ts +22 -8
  94. package/dist/types/core/former-routes.d.ts +14 -0
  95. package/dist/types/core/github.d.ts +5 -4
  96. package/dist/types/core/heading-markers.d.ts +65 -2
  97. package/dist/types/core/hidden-pages.d.ts +3 -0
  98. package/dist/types/core/includes.d.ts +23 -0
  99. package/dist/types/core/last-modified.d.ts +18 -6
  100. package/dist/types/core/links.d.ts +42 -2
  101. package/dist/types/core/load-module.d.ts +19 -4
  102. package/dist/types/core/manifest.d.ts +14 -1
  103. package/dist/types/core/markdown-mirrors.d.ts +22 -0
  104. package/dist/types/core/mdx-elements.d.ts +32 -0
  105. package/dist/types/core/mdx-syntax.d.ts +100 -0
  106. package/dist/types/core/meta-diagnostics.d.ts +7 -0
  107. package/dist/types/core/meta.d.ts +32 -5
  108. package/dist/types/core/nav-diagnostics.d.ts +9 -2
  109. package/dist/types/core/navigation.d.ts +13 -0
  110. package/dist/types/core/ordering-prefix.d.ts +6 -0
  111. package/dist/types/core/pinned-ids.d.ts +23 -0
  112. package/dist/types/core/project-graph.d.ts +9 -1
  113. package/dist/types/core/redirect-patterns.d.ts +18 -0
  114. package/dist/types/core/relative-files.d.ts +31 -0
  115. package/dist/types/core/schema.d.ts +267 -7
  116. package/dist/types/core/sources/normalize.d.ts +101 -9
  117. package/dist/types/core/sources/types.d.ts +16 -0
  118. package/dist/types/core/static-files.d.ts +10 -0
  119. package/dist/types/core/static-host.d.ts +42 -0
  120. package/dist/types/core/svg-images.d.ts +26 -0
  121. package/dist/types/core/syntax-diagnostics.d.ts +14 -0
  122. package/dist/types/core/types.d.ts +42 -1
  123. package/dist/types/deploy/generated-files.d.ts +41 -0
  124. package/dist/types/deploy/redirects.d.ts +21 -7
  125. package/dist/types/markdown/code-title.d.ts +9 -5
  126. package/dist/types/markdown/directives.d.ts +8 -0
  127. package/dist/types/markdown/fence-language.d.ts +51 -0
  128. package/dist/types/markdown/fence-meta.d.ts +5 -0
  129. package/dist/types/markdown/github-alerts.d.ts +35 -0
  130. package/dist/types/openapi/asyncapi.d.ts +6 -5
  131. package/dist/types/openapi/checks.d.ts +10 -5
  132. package/dist/types/openapi/model.d.ts +55 -8
  133. package/dist/types/openapi/parse.d.ts +4 -1
  134. package/dist/types/sources/filesystem.d.ts +14 -4
  135. package/dist/types/sources/mdx-remote.d.ts +6 -3
  136. package/dist/types/sources/registry.d.ts +3 -3
  137. package/dist/types/theme/color.d.ts +33 -0
  138. package/dist/types/theme/palette.d.ts +122 -0
  139. package/docs/01-quickstart.mdx +1 -1
  140. package/docs/02-deployment.mdx +23 -8
  141. package/docs/04-migrating.mdx +16 -4
  142. package/docs/advanced/changelog.mdx +27 -1
  143. package/docs/advanced/skills.mdx +1 -1
  144. package/docs/cli/audit.mdx +1 -1
  145. package/docs/cli/doctor.mdx +2 -2
  146. package/docs/cli/evals.mdx +1 -1
  147. package/docs/cli/index.mdx +4 -2
  148. package/docs/cli/validate.mdx +10 -7
  149. package/docs/configuration/analytics.mdx +2 -0
  150. package/docs/configuration/customization.mdx +3 -1
  151. package/docs/configuration/index.mdx +2 -2
  152. package/docs/configuration/theming.mdx +5 -1
  153. package/docs/content/components.mdx +26 -6
  154. package/docs/content/frontmatter.mdx +1 -1
  155. package/docs/content/includes.mdx +6 -2
  156. package/docs/content/index.mdx +11 -1
  157. package/docs/content/islands.mdx +2 -0
  158. package/docs/content/meta.mdx +9 -3
  159. package/docs/content/navigation.mdx +14 -6
  160. package/docs/content/sources/obsidian.mdx +1 -1
  161. package/docs/content/sources/remote-mdx.mdx +3 -1
  162. package/docs/content/syntax.mdx +76 -8
  163. package/docs/content/variables.mdx +3 -1
  164. package/docs/discoverability/agent-discovery.mdx +1 -1
  165. package/docs/discoverability/json-api.mdx +1 -1
  166. package/docs/discoverability/llms-txt.mdx +1 -1
  167. package/docs/discoverability/markdown.mdx +2 -2
  168. package/docs/discoverability/open-graph.mdx +1 -1
  169. package/docs/discoverability/sitemap-and-robots.mdx +1 -1
  170. package/docs/references/graphql.mdx +2 -0
  171. package/docs/references/openapi.mdx +45 -7
  172. package/package.json +4 -4
  173. package/skills/blume/SKILL.md +2 -2
  174. package/skills/blume-migrate/SKILL.md +49 -27
  175. package/skills/blume-migrate/references/docsify.md +262 -0
  176. package/skills/blume-migrate/references/docus.md +298 -0
  177. package/skills/blume-migrate/references/docusaurus.md +3 -3
  178. package/skills/blume-migrate/references/fern.md +327 -0
  179. package/skills/blume-migrate/references/fumadocs.md +1 -1
  180. package/skills/blume-migrate/references/gitbook.md +267 -0
  181. package/skills/blume-migrate/references/github-wiki.md +259 -0
  182. package/skills/blume-migrate/references/jekyll.md +253 -0
  183. package/skills/blume-migrate/references/mdbook.md +256 -0
  184. package/skills/blume-migrate/references/mintlify.md +5 -5
  185. package/skills/blume-migrate/references/mkdocs.md +236 -0
  186. package/skills/blume-migrate/references/monorepo.md +20 -8
  187. package/skills/blume-migrate/references/nextra.md +2 -2
  188. package/skills/blume-migrate/references/readme.md +257 -0
  189. package/skills/blume-migrate/references/redocly.md +198 -0
  190. package/skills/blume-migrate/references/starlight.md +3 -3
  191. package/skills/blume-migrate/references/vitepress.md +204 -0
  192. package/skills/blume-migrate/references/vuepress.md +271 -0
  193. package/skills/blume-migrate/scripts/docsify-codemod.mjs +2387 -0
  194. package/skills/blume-migrate/scripts/docus-codemod.mjs +2542 -0
  195. package/skills/blume-migrate/scripts/fern-codemod.mjs +2633 -0
  196. package/skills/blume-migrate/scripts/github-wiki-codemod.mjs +2808 -0
  197. package/skills/blume-migrate/scripts/include-excerpts.mjs +649 -0
  198. package/skills/blume-migrate/scripts/jekyll-codemod.mjs +3649 -0
  199. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +17 -13
  200. package/skills/blume-migrate/scripts/mkdocs-codemod.mjs +2526 -0
  201. package/skills/blume-migrate/scripts/operation-routes.mjs +508 -0
  202. package/skills/blume-migrate/scripts/pin-heading-ids.mjs +1049 -0
  203. package/skills/blume-migrate/scripts/readme-codemod.mjs +4139 -0
  204. package/skills/blume-migrate/scripts/vitepress-codemod.mjs +1511 -0
  205. package/src/ai/changelog-components.ts +24 -0
  206. package/src/ai/changelog-markdown.ts +45 -41
  207. package/src/ai/component-markdown.ts +22 -9
  208. package/src/ai/llms.ts +36 -5
  209. package/src/ai/markdown.ts +2 -2
  210. package/src/ai/openapi-components.ts +25 -9
  211. package/src/ai/operation-details.ts +208 -0
  212. package/src/ai/relative-links.ts +48 -8
  213. package/src/ai/serializers.ts +7 -6
  214. package/src/ai/site-skill.ts +6 -2
  215. package/src/analytics/head.ts +11 -5
  216. package/src/analytics/script.ts +13 -3
  217. package/src/astro/generate.ts +32 -6
  218. package/src/astro/index.ts +1 -0
  219. package/src/astro/integration.ts +27 -1
  220. package/src/astro/mdx-source-errors.ts +46 -0
  221. package/src/astro/templates.ts +89 -185
  222. package/src/audit/checks/redirects.ts +5 -1
  223. package/src/audit/redirects.ts +36 -19
  224. package/src/audit/report.ts +22 -9
  225. package/src/audit/run.ts +12 -28
  226. package/src/audit/terms.ts +23 -0
  227. package/src/audit/url.ts +2 -2
  228. package/src/cli/build-failure.ts +256 -7
  229. package/src/cli/command-meta.ts +1 -1
  230. package/src/cli/commands/audit.ts +1 -1
  231. package/src/cli/commands/build.ts +12 -3
  232. package/src/cli/commands/check.ts +13 -2
  233. package/src/cli/commands/dev.ts +1 -1
  234. package/src/cli/commands/doctor.ts +4 -2
  235. package/src/cli/commands/init.ts +3 -3
  236. package/src/cli/commands/preview.ts +17 -1
  237. package/src/cli/commands/validate.ts +22 -10
  238. package/src/cli/prepare.ts +1 -1
  239. package/src/cli/preview-pages.ts +161 -0
  240. package/src/cli/unknown-flags.ts +1 -42
  241. package/src/components/code-copy.ts +51 -0
  242. package/src/components/code-language.ts +75 -0
  243. package/src/components/content/AccordionItem.astro +16 -1
  244. package/src/components/content/Callout.astro +11 -1
  245. package/src/components/content/Changelog.astro +189 -0
  246. package/src/components/content/CodeBlock.astro +8 -11
  247. package/src/components/content/Tabs.astro +16 -2
  248. package/src/components/content/YouTube.astro +6 -4
  249. package/src/components/content/code-block.ts +33 -0
  250. package/src/components/content/content-strings.ts +5 -1
  251. package/src/components/content/inline-markdown.ts +35 -8
  252. package/src/components/content/youtube.ts +49 -7
  253. package/src/components/layout/Analytics.astro +5 -1
  254. package/src/components/layout/NavTree.astro +8 -3
  255. package/src/components/layout/RootLayout.astro +18 -31
  256. package/src/components/layout/nav-utils.ts +14 -0
  257. package/src/components/layout/search/pagefind.ts +2 -1
  258. package/src/components/openapi/Operation.astro +4 -0
  259. package/src/components/openapi/PanelTabs.astro +9 -3
  260. package/src/components/openapi/RequestBody.astro +42 -8
  261. package/src/components/openapi/RequestPanel.astro +34 -53
  262. package/src/components/openapi/example-panels.ts +110 -0
  263. package/src/components/openapi/helpers.ts +195 -20
  264. package/src/components/openapi/operation-model.ts +63 -26
  265. package/src/components/openapi/request.ts +13 -0
  266. package/src/components/openapi/snippets.ts +14 -2
  267. package/src/core/alert-diagnostics.ts +89 -0
  268. package/src/core/builtin-tags.ts +76 -0
  269. package/src/core/changelog-list.ts +87 -0
  270. package/src/core/closest-match.ts +41 -0
  271. package/src/core/code-fence-diagnostics.ts +267 -0
  272. package/src/core/code-fences.ts +43 -7
  273. package/src/core/component-diagnostics.ts +65 -12
  274. package/src/core/config-input.ts +1 -1
  275. package/src/core/config.ts +46 -1
  276. package/src/core/content-assets.ts +64 -144
  277. package/src/core/diagnostics.ts +36 -3
  278. package/src/core/directive-diagnostics.ts +265 -47
  279. package/src/core/former-routes.ts +46 -0
  280. package/src/core/git-ignored.ts +53 -0
  281. package/src/core/github.ts +5 -4
  282. package/src/core/heading-markers.ts +156 -2
  283. package/src/core/hidden-pages.ts +64 -0
  284. package/src/core/includes.ts +181 -41
  285. package/src/core/last-modified.ts +47 -10
  286. package/src/core/links.ts +438 -83
  287. package/src/core/load-module.ts +98 -9
  288. package/src/core/manifest.ts +12 -9
  289. package/src/core/markdown-mirrors.ts +52 -0
  290. package/src/core/mdx-elements.ts +153 -0
  291. package/src/core/mdx-syntax.ts +377 -0
  292. package/src/core/meta-diagnostics.ts +134 -0
  293. package/src/core/meta.ts +154 -55
  294. package/src/core/nav-diagnostics.ts +16 -4
  295. package/src/core/navigation.ts +70 -10
  296. package/src/core/ordering-prefix.ts +22 -2
  297. package/src/core/pinned-ids.ts +141 -0
  298. package/src/core/project-graph.ts +221 -29
  299. package/src/core/redirect-patterns.ts +41 -0
  300. package/src/core/relative-files.ts +145 -0
  301. package/src/core/schema.ts +17 -3
  302. package/src/core/sources/mdx-remote.ts +75 -14
  303. package/src/core/sources/normalize.ts +885 -179
  304. package/src/core/sources/notion.ts +5 -4
  305. package/src/core/sources/obsidian.ts +2 -5
  306. package/src/core/sources/types.ts +17 -0
  307. package/src/core/static-files.ts +40 -0
  308. package/src/core/static-host.ts +125 -0
  309. package/src/core/svg-images.ts +98 -0
  310. package/src/core/syntax-diagnostics.ts +491 -0
  311. package/src/core/types.ts +43 -1
  312. package/src/deploy/artifacts.ts +2 -28
  313. package/src/deploy/generated-files.ts +128 -0
  314. package/src/deploy/platforms/vercel.ts +25 -1
  315. package/src/deploy/redirects.ts +43 -16
  316. package/src/deploy/sitemap.ts +2 -1
  317. package/src/markdown/base-links.ts +87 -6
  318. package/src/markdown/code-title.ts +29 -13
  319. package/src/markdown/content-assets.ts +210 -0
  320. package/src/markdown/directives.ts +69 -5
  321. package/src/markdown/fence-language.ts +106 -0
  322. package/src/markdown/fence-meta.ts +42 -0
  323. package/src/markdown/github-alerts.ts +172 -0
  324. package/src/markdown/heading-anchors.ts +265 -56
  325. package/src/markdown/include.ts +30 -3
  326. package/src/markdown/index.ts +145 -40
  327. package/src/markdown/prompt-text.ts +95 -0
  328. package/src/markdown/relative-links.ts +37 -2
  329. package/src/markdown/route-snapshot.ts +22 -12
  330. package/src/markdown/svg-fallback.ts +51 -0
  331. package/src/markdown/title-heading.ts +134 -0
  332. package/src/migrate/migrate.ts +127 -2
  333. package/src/og/card.ts +14 -4
  334. package/src/openapi/asyncapi.ts +14 -6
  335. package/src/openapi/checks.ts +160 -15
  336. package/src/openapi/model.ts +172 -33
  337. package/src/openapi/parse.ts +13 -4
  338. package/src/openapi/render-mdx.ts +55 -9
  339. package/src/openapi/source.ts +87 -6
  340. package/src/registry/eject.ts +0 -1
  341. package/src/search/documents.ts +10 -2
  342. package/src/sources/filesystem.ts +28 -3
  343. package/src/sources/mdx-remote.ts +7 -15
  344. package/src/theme/color.ts +14 -0
  345. package/src/theme/entry.ts +22 -1
  346. package/src/theme/palette.ts +74 -1
  347. package/dist/cli/chunk-0pmb4tr4.js.map +0 -35
  348. package/dist/cli/chunk-0w6hs479.js.map +0 -10
  349. package/dist/cli/chunk-150jk7km.js +0 -52
  350. package/dist/cli/chunk-150jk7km.js.map +0 -10
  351. package/dist/cli/chunk-36bxs9c7.js.map +0 -10
  352. package/dist/cli/chunk-53jqw8z0.js +0 -89
  353. package/dist/cli/chunk-53jqw8z0.js.map +0 -10
  354. package/dist/cli/chunk-60hz265r.js.map +0 -10
  355. package/dist/cli/chunk-desvm72z.js.map +0 -14
  356. package/dist/cli/chunk-dpy8qdjf.js.map +0 -17
  357. package/dist/cli/chunk-es8h0v3j.js +0 -441
  358. package/dist/cli/chunk-es8h0v3j.js.map +0 -11
  359. package/dist/cli/chunk-kdpzw38a.js.map +0 -11
  360. package/dist/cli/chunk-nbyvgnnm.js.map +0 -36
  361. package/dist/cli/chunk-s0bdnc7v.js.map +0 -10
  362. package/dist/cli/chunk-twy7psdz.js.map +0 -10
  363. package/dist/cli/chunk-ydp3065p.js +0 -64
  364. package/dist/cli/chunk-ydp3065p.js.map +0 -10
  365. /package/dist/cli/{chunk-74wfhv79.js.map → chunk-05f21r8h.js.map} +0 -0
  366. /package/dist/cli/{chunk-9qzgg6mj.js.map → chunk-1cm0h819.js.map} +0 -0
  367. /package/dist/cli/{chunk-ms9z66nz.js.map → chunk-4rftmttv.js.map} +0 -0
  368. /package/dist/cli/{chunk-hvcxng5f.js.map → chunk-7tekknev.js.map} +0 -0
  369. /package/dist/cli/{chunk-bxwhtvw8.js.map → chunk-ahc5gc9h.js.map} +0 -0
  370. /package/dist/cli/{chunk-tfycddbt.js.map → chunk-bjk964fp.js.map} +0 -0
  371. /package/dist/cli/{chunk-dqhg54mr.js.map → chunk-dmx6cezx.js.map} +0 -0
  372. /package/dist/cli/{chunk-ave1wcbr.js.map → chunk-m9bp2hc1.js.map} +0 -0
  373. /package/dist/cli/{chunk-58bt3hag.js.map → chunk-mrvh4c88.js.map} +0 -0
  374. /package/dist/cli/{chunk-1f882900.js.map → chunk-th0pgaj5.js.map} +0 -0
  375. /package/dist/cli/{chunk-dhwtqnnd.js.map → chunk-vnbvhgmd.js.map} +0 -0
  376. /package/dist/cli/{chunk-j1x92mx9.js.map → chunk-w6e455pz.js.map} +0 -0
  377. /package/dist/cli/{chunk-y4msrwm9.js.map → chunk-xgq4eytj.js.map} +0 -0
@@ -2,6 +2,7 @@ import { withServerDefaults } from "../../openapi/model.ts";
2
2
  import {
3
3
  declaredExample,
4
4
  exampleValue,
5
+ mediaExample,
5
6
  objectProperties,
6
7
  parameterDescription,
7
8
  resolveSchema,
@@ -172,7 +173,9 @@ const jsonContentType = (
172
173
  /**
173
174
  * Typed field inputs when the body schema is a flat object of primitives —
174
175
  * anything nested (object/array properties) falls back to the raw JSON editor,
175
- * where structure is easier to edit than in exploded form fields.
176
+ * where structure is easier to edit than in exploded form fields. A
177
+ * `readOnly` property gets no field: the server sets it, so a request
178
+ * doesn't send it, as the request body's schema table leaves it out.
176
179
  */
177
180
  const bodyFields = (
178
181
  schema: SchemaLike | undefined,
@@ -184,13 +187,13 @@ const bodyFields = (
184
187
  return undefined;
185
188
  }
186
189
  const { properties, required } = objectProperties(resolved, schemas);
187
- if (properties.length === 0) {
188
- return undefined;
189
- }
190
190
  const defaults = isExampleObject(example) ? example : undefined;
191
191
  const fields: PlaygroundBodyField[] = [];
192
192
  for (const [name, property] of properties) {
193
193
  const propertySchema = resolveSchema(schemas, property);
194
+ if (property.readOnly === true || propertySchema.readOnly === true) {
195
+ continue;
196
+ }
194
197
  const type = scalarType(property, schemas);
195
198
  if (
196
199
  !(type in PRIMITIVE_TYPES) ||
@@ -203,17 +206,12 @@ const bodyFields = (
203
206
  description: propertySchema.description,
204
207
  enum: propertySchema.enum?.map(String),
205
208
  name,
206
- // A `readOnly` property's `required` binds responses only: a request
207
- // shouldn't send the server-generated field at all.
208
- required:
209
- required.has(name) &&
210
- property.readOnly !== true &&
211
- propertySchema.readOnly !== true,
209
+ required: required.has(name),
212
210
  type,
213
211
  value: inputValue(defaults?.[name]),
214
212
  });
215
213
  }
216
- return fields;
214
+ return fields.length > 0 ? fields : undefined;
217
215
  };
218
216
 
219
217
  /**
@@ -232,9 +230,7 @@ const modelBody = (
232
230
  return undefined;
233
231
  }
234
232
  const [contentType, mediaType] = media;
235
- const exampleData =
236
- declaredExample(mediaType, components) ??
237
- exampleValue(mediaType.schema, schemas);
233
+ const exampleData = mediaExample(mediaType, schemas, "request", components);
238
234
  const encoding = bodyEncoding(contentType);
239
235
  const raw = encoding === "raw";
240
236
  const body: PlaygroundBody = {
@@ -344,6 +340,37 @@ export const playgroundAuth = (
344
340
  return input ? [input] : [];
345
341
  });
346
342
 
343
+ /** A response, `$ref` resolved: the media types its body comes in. */
344
+ interface ResponseLike {
345
+ content?: Record<string, MediaTypeLike>;
346
+ }
347
+
348
+ /**
349
+ * The `Accept` header a request sends: the first JSON media type among the
350
+ * operation's responses, success responses first, without its parameters.
351
+ * A request with none reads as a browser's to frameworks like Laravel, so an
352
+ * unauthenticated call got a 500 from the login redirect it tried instead
353
+ * of the 401 the API documents. `undefined` when no response is JSON.
354
+ */
355
+ export const acceptHeader = (
356
+ responses?: Record<string, ResponseLike>
357
+ ): string | undefined => {
358
+ const entries = Object.entries(responses ?? {});
359
+ const success = ([status]: [string, ResponseLike]): boolean =>
360
+ status.startsWith("2");
361
+ for (const [, response] of [
362
+ ...entries.filter(success),
363
+ ...entries.filter((entry) => !success(entry)),
364
+ ]) {
365
+ for (const type of Object.keys(response.content ?? {})) {
366
+ if (bodyEncoding(type) === "json") {
367
+ return (type.split(";")[0] ?? type).trim();
368
+ }
369
+ }
370
+ }
371
+ return undefined;
372
+ };
373
+
347
374
  /** Derive the playground request model for one operation, at build time. */
348
375
  export const operationModel = (args: {
349
376
  method: string;
@@ -351,21 +378,31 @@ export const operationModel = (args: {
351
378
  /** Pre-merged/resolved (`mergeParameters` output). */
352
379
  parameters: ParameterLike[];
353
380
  requestBody?: { content?: Record<string, MediaTypeLike> };
381
+ /** The operation's responses, `$ref`s resolved: they set its `Accept`. */
382
+ responses?: Record<string, ResponseLike>;
354
383
  /** The operation's effective servers (`effectiveServers` output). */
355
384
  servers: ServerLike[];
356
385
  schemas: Record<string, SchemaLike>;
357
386
  /** The document's `components`, which `$ref`'d examples resolve against. */
358
387
  components?: ComponentsLike;
359
388
  security: OperationSecurity;
360
- }): PlaygroundModel => ({
361
- auth: playgroundAuth(args.security),
362
- authOptional: args.security.optional,
363
- body: modelBody(args.requestBody, args.schemas, args.components),
364
- method: args.method.toUpperCase(),
365
- params: modelParams(args.parameters, args.schemas, args.components),
366
- path: args.path,
367
- // Variables resolve to their defaults: the samples and Send need a real URL.
368
- servers: args.servers.map((server) =>
369
- withServerDefaults(server.url ?? "", server.variables)
370
- ),
371
- });
389
+ }): PlaygroundModel => {
390
+ const model: PlaygroundModel = {
391
+ auth: playgroundAuth(args.security),
392
+ authOptional: args.security.optional,
393
+ body: modelBody(args.requestBody, args.schemas, args.components),
394
+ method: args.method.toUpperCase(),
395
+ params: modelParams(args.parameters, args.schemas, args.components),
396
+ path: args.path,
397
+ // Variables resolve to their defaults: the samples and Send need a real
398
+ // URL.
399
+ servers: args.servers.map((server) =>
400
+ withServerDefaults(server.url ?? "", server.variables)
401
+ ),
402
+ };
403
+ const accept = acceptHeader(args.responses);
404
+ if (accept) {
405
+ model.accept = accept;
406
+ }
407
+ return model;
408
+ };
@@ -108,6 +108,11 @@ export interface PlaygroundModel {
108
108
  /** First security alternative (AND set). */
109
109
  auth: PlaygroundAuthInput[];
110
110
  authOptional: boolean;
111
+ /**
112
+ * The `Accept` header every request sends: the operation's first JSON
113
+ * response media type. Absent when none of its responses is JSON.
114
+ */
115
+ accept?: string;
111
116
  }
112
117
 
113
118
  export interface AuthValue {
@@ -431,6 +436,14 @@ export const buildRequest = (
431
436
  headers[param.name] = value;
432
437
  }
433
438
  }
439
+ // The JSON the operation answers with, unless a header parameter already
440
+ // names the type it wants.
441
+ if (
442
+ model.accept &&
443
+ !Object.keys(headers).some((name) => name.toLowerCase() === "accept")
444
+ ) {
445
+ headers.Accept = model.accept;
446
+ }
434
447
 
435
448
  const { body, bodyValue, formData } = model.body
436
449
  ? bodyFor(model.body, values.body)
@@ -1008,12 +1008,16 @@ const LANGUAGES: SampleLanguage[] = [
1008
1008
  /** Every id `codeSamples` accepts for a generated sample. */
1009
1009
  export const SAMPLE_LANGUAGE_IDS = LANGUAGES.map((language) => language.id);
1010
1010
 
1011
- /** Other spellings of the ids, including every alias Mintlify accepts. */
1011
+ /**
1012
+ * Other spellings of the ids, including every alias Mintlify accepts and
1013
+ * ReadMe's ids for the languages Blume generates (`cplusplus`).
1014
+ */
1012
1015
  const ALIASES = new Map([
1013
1016
  [".net", "dotnet"],
1014
1017
  ["bash", "curl"],
1015
1018
  ["c#", "csharp"],
1016
1019
  ["c++", "cpp"],
1020
+ ["cplusplus", "cpp"],
1017
1021
  ["cs", "csharp"],
1018
1022
  ["dot-net", "dotnet"],
1019
1023
  ["flutter", "dart"],
@@ -1056,9 +1060,17 @@ export const sampleLanguageInfo = (raw: string): SampleLanguageInfo | null => {
1056
1060
  /** `openapi()`'s default `codeSamples`, which hand-written endpoint pages always use. */
1057
1061
  export const DEFAULT_SAMPLE_LANGUAGES = ["curl", "js", "python"];
1058
1062
 
1063
+ /**
1064
+ * The configured ids Blume generates no sample for, as written: the ones
1065
+ * {@link sampleLanguages} drops, which the reference source warns about.
1066
+ */
1067
+ export const unknownSampleLanguages = (ids: string[] | false): string[] =>
1068
+ ids === false ? [] : ids.filter((raw) => sampleLanguageInfo(raw) === null);
1069
+
1059
1070
  /**
1060
1071
  * The sample languages to render, resolved from config ids (unknown ids
1061
- * dropped), in order. `false` and an empty list both render none.
1072
+ * dropped, with a warning from the reference source), in order. `false` and
1073
+ * an empty list both render none.
1062
1074
  */
1063
1075
  export const sampleLanguages = (ids: string[] | false): SampleLanguage[] => {
1064
1076
  if (ids === false) {
@@ -0,0 +1,89 @@
1
+ import type { Nodes } from "mdast";
2
+ import { markdownToMdast } from "satteri";
3
+
4
+ import { MARKDOWN_BODY_FEATURES } from "../markdown/features.ts";
5
+ import { alertMarkerOf } from "../markdown/github-alerts.ts";
6
+ import type { AlertMarker } from "../markdown/github-alerts.ts";
7
+ import { strippedLineOffset } from "./sources/normalize.ts";
8
+ import type { SourceEntry } from "./sources/types.ts";
9
+ import type { Diagnostic } from "./types.ts";
10
+
11
+ // A quote line that may open with an alert marker.
12
+ const ALERT_LINE = /^[\t >]*>[\t ]*\[![a-z]+\]/imu;
13
+
14
+ /** An alert quote in an `.md` body: its marker and the quote's line. */
15
+ interface AlertFinding extends AlertMarker {
16
+ line: number;
17
+ }
18
+
19
+ /**
20
+ * The GitHub alerts in an `.md` body, in source order: quotes that open with
21
+ * `[!NOTE]` and the rest, as `markdown/github-alerts.ts` reads them in `.mdx`
22
+ * (an escaped marker, or one quoted inside another alert, is no alert there
23
+ * either). A page is parsed only when a line looks like one.
24
+ */
25
+ const alertFindings = (text: string): AlertFinding[] => {
26
+ if (!ALERT_LINE.test(text)) {
27
+ return [];
28
+ }
29
+ const tree: Nodes = markdownToMdast(text, {
30
+ features: MARKDOWN_BODY_FEATURES,
31
+ });
32
+ const found: AlertFinding[] = [];
33
+ const walk = (node: Nodes): void => {
34
+ if (node.type === "blockquote") {
35
+ const [paragraph] = node.children;
36
+ const first =
37
+ paragraph?.type === "paragraph" ? paragraph.children[0] : undefined;
38
+ const escaped = text[first?.position?.start.offset ?? 0] === "\\";
39
+ const alert =
40
+ first?.type === "text" && !escaped
41
+ ? alertMarkerOf(first.value)
42
+ : undefined;
43
+ if (alert !== undefined) {
44
+ found.push({ ...alert, line: node.position?.start.line ?? 1 });
45
+ // A quote inside an alert stays a quote, alert or not.
46
+ return;
47
+ }
48
+ }
49
+ if ("children" in node) {
50
+ for (const child of node.children) {
51
+ walk(child);
52
+ }
53
+ }
54
+ };
55
+ walk(tree);
56
+ return found;
57
+ };
58
+
59
+ /**
60
+ * Warn about GitHub alerts (`> [!NOTE]`) in an `.md` entry, which renders
61
+ * them as plain quotes that show the marker as text: alerts become callouts
62
+ * only in `.mdx`, where Blume renders components (see
63
+ * `markdown/github-alerts.ts`). Lines point into the file the author wrote, a
64
+ * partial's own file for an alert an `<include>` brought in.
65
+ */
66
+ export const alertDiagnostics = (
67
+ entry: SourceEntry,
68
+ sourceName: string
69
+ ): Diagnostic[] => {
70
+ if (entry.body.format !== "md") {
71
+ return [];
72
+ }
73
+ const page = entry.sourcePath ?? `${sourceName}:${entry.ref}`;
74
+ const offset =
75
+ entry.bodyLineOffset ?? strippedLineOffset(entry.raw, entry.body.text);
76
+ return alertFindings(entry.expanded?.text ?? entry.body.text).map(
77
+ ({ callout, line, marker }) => {
78
+ const origin = entry.expanded?.origins[line - 1];
79
+ return {
80
+ code: "BLUME_MD_GITHUB_ALERT",
81
+ file: origin?.file ?? page,
82
+ line: origin?.line ?? line + offset,
83
+ message: `\`${marker}\` makes a quote a callout only in .mdx; in this .md page it renders as a quote that shows \`${marker}\` as text.`,
84
+ severity: "warning",
85
+ suggestion: `Rename the page to .mdx to render it as a \`${callout}\` callout, or remove \`${marker}\` to keep a plain quote.`,
86
+ };
87
+ }
88
+ );
89
+ };
@@ -14,6 +14,7 @@ export const BUILTIN_MDX_TAGS = new Set<string>([
14
14
  "Callout",
15
15
  "Card",
16
16
  "CardGroup",
17
+ "Changelog",
17
18
  "CodeBlock",
18
19
  "CodeGroup",
19
20
  "Color",
@@ -48,3 +49,78 @@ export const BUILTIN_MDX_TAGS = new Set<string>([
48
49
  "Visibility",
49
50
  "YouTube",
50
51
  ]);
52
+
53
+ /**
54
+ * The props each built-in that shows its children takes, keyed by MDX tag. A
55
+ * childless use with any other prop renders without the content its author
56
+ * meant it to carry (VitePress writes `<Badge type="tip" text="beta" />`, and
57
+ * Blume's Badge shows only its children), which the unknown-prop diagnostic
58
+ * reports. Each list is the component's own `Props` (or what it reads from
59
+ * `Astro.props`); a test checks them against the `.astro` files.
60
+ */
61
+ export const BUILTIN_CHILD_PROPS: ReadonlyMap<string, readonly string[]> =
62
+ new Map([
63
+ ["Accordion", []],
64
+ ["AccordionItem", ["defaultOpen", "description", "icon", "id", "title"]],
65
+ [
66
+ "Badge",
67
+ [
68
+ "class",
69
+ "className",
70
+ "color",
71
+ "disabled",
72
+ "icon",
73
+ "shape",
74
+ "size",
75
+ "stroke",
76
+ "tooltip",
77
+ "variant",
78
+ ],
79
+ ],
80
+ ["Callout", ["color", "icon", "title", "type"]],
81
+ [
82
+ "Card",
83
+ [
84
+ "arrow",
85
+ "color",
86
+ "cta",
87
+ "horizontal",
88
+ "href",
89
+ "icon",
90
+ "img",
91
+ "title",
92
+ "type",
93
+ ],
94
+ ],
95
+ ["CardGroup", ["cols"]],
96
+ ["CodeBlock", ["code", "icons", "lang", "title"]],
97
+ ["CodeGroup", ["dropdown"]],
98
+ ["Column", []],
99
+ ["Columns", ["cols"]],
100
+ ["Expandable", ["defaultOpen", "title"]],
101
+ ["Frame", ["caption", "hint"]],
102
+ ["Panel", ["title"]],
103
+ ["Prompt", ["actions", "description"]],
104
+ ["RequestExample", ["dropdown"]],
105
+ ["ResponseExample", ["dropdown"]],
106
+ ["Step", ["icon", "title"]],
107
+ ["Steps", ["titleSize"]],
108
+ ["Tab", ["class", "icon", "id", "style", "title"]],
109
+ [
110
+ "Tabs",
111
+ [
112
+ "borderBottom",
113
+ "defaultTabIndex",
114
+ "dropdown",
115
+ "hash",
116
+ "inline",
117
+ "param",
118
+ "sync",
119
+ "syncKey",
120
+ ],
121
+ ],
122
+ ["Tile", ["description", "href", "title"]],
123
+ ["Tooltip", ["cta", "headline", "href", "tip"]],
124
+ ["View", ["class", "icon", "title"]],
125
+ ["Visibility", ["for"]],
126
+ ]);
@@ -0,0 +1,87 @@
1
+ /**
2
+ * The policy the changelog index lists by, shared by the surfaces that build
3
+ * it: the `<Changelog />` component (reading Astro collection entries) and
4
+ * `ai/changelog-markdown.ts` (reading the build-time page graph for the
5
+ * `/changelog.md` mirror and MCP `get_page`).
6
+ *
7
+ * The data sources genuinely differ — a collection entry on the Astro side, a
8
+ * `PageRecord` on the Node side — so what lives here is the *decisions*, not
9
+ * the access: which date a row carries, what order rows come in, and how they
10
+ * fall into year groups. Keeping them in one place is what stops the rendered
11
+ * page and the Markdown an agent reads from drifting apart.
12
+ */
13
+
14
+ /**
15
+ * A changelog entry's date, from `date` or the `changelog.date` it may live
16
+ * under instead. Front matter hands either a `Date` (an unquoted YAML date) or
17
+ * a string, and an unparseable value is treated as no date at all rather than
18
+ * failing the build — a malformed date costs the row its stamp and its year
19
+ * group, not the page.
20
+ */
21
+ export const parseChangelogDate = (
22
+ value: Date | string | null | undefined
23
+ ): Date | null => {
24
+ if (value === null || value === undefined) {
25
+ return null;
26
+ }
27
+ const date = value instanceof Date ? value : new Date(value);
28
+ return Number.isNaN(date.getTime()) ? null : date;
29
+ };
30
+
31
+ /**
32
+ * Newest first. An undated entry sorts as the epoch, so undated rows collect
33
+ * at the end of the list (and, through {@link groupChangelogYears}, into a
34
+ * final group with no year label).
35
+ */
36
+ export const compareChangelogDates = (a: Date | null, b: Date | null): number =>
37
+ (b?.getTime() ?? 0) - (a?.getTime() ?? 0);
38
+
39
+ /** One year's run of rows. `year` is `null` for the undated group. */
40
+ export interface ChangelogYearGroup<T> {
41
+ items: T[];
42
+ year: string | null;
43
+ }
44
+
45
+ /**
46
+ * Consecutive rows sharing a year, in list order, so the index reads as a year
47
+ * rail beside its rows. Runs are consecutive rather than keyed, which matters
48
+ * only for a list that isn't sorted by date: such a list keeps its order and
49
+ * repeats the year heading instead of silently regrouping around it.
50
+ *
51
+ * `yearOf` returns the label the surface wants — a locale-formatted year on the
52
+ * rendered page, a plain number in Markdown — or `null` for an undated row.
53
+ */
54
+ export const groupChangelogYears = <T>(
55
+ items: T[],
56
+ yearOf: (item: T) => string | null
57
+ ): ChangelogYearGroup<T>[] => {
58
+ const groups: ChangelogYearGroup<T>[] = [];
59
+ for (const item of items) {
60
+ const year = yearOf(item);
61
+ const last = groups.at(-1);
62
+ if (last && last.year === year) {
63
+ last.items.push(item);
64
+ } else {
65
+ groups.push({ items: [item], year });
66
+ }
67
+ }
68
+ return groups;
69
+ };
70
+
71
+ /**
72
+ * Make each row's anchor unique. Repeated labels slug to the same id (two
73
+ * entries with neither a title nor a version both fall back to "update"), so
74
+ * the later ones take a `-2`, `-3`, … suffix and the first keeps the plain
75
+ * slug — every row ends up with its own hash anchor.
76
+ */
77
+ export const uniqueAnchorIds = (ids: string[]): string[] => {
78
+ const seen = new Set<string>();
79
+ return ids.map((id) => {
80
+ let unique = id;
81
+ for (let n = 2; seen.has(unique); n += 1) {
82
+ unique = `${id}-${n}`;
83
+ }
84
+ seen.add(unique);
85
+ return unique;
86
+ });
87
+ };
@@ -0,0 +1,41 @@
1
+ /** Edit distance between two short strings (insertions, deletions, swaps of one letter). */
2
+ const distance = (from: string, to: string): number => {
3
+ let previous = Array.from({ length: to.length + 1 }, (_, index) => index);
4
+ for (const [row, fromChar] of [...from].entries()) {
5
+ const current = [row + 1];
6
+ for (const [column, toChar] of [...to].entries()) {
7
+ current.push(
8
+ Math.min(
9
+ (previous[column + 1] ?? 0) + 1,
10
+ (current[column] ?? 0) + 1,
11
+ (previous[column] ?? 0) + (fromChar === toChar ? 0 : 1)
12
+ )
13
+ );
14
+ }
15
+ previous = current;
16
+ }
17
+ return previous[to.length] ?? 0;
18
+ };
19
+
20
+ /**
21
+ * The candidate closest to `name`, when it's close enough to be the likely
22
+ * intent: at most two edits away, and fewer edits than half the candidate's
23
+ * length, so a short typo doesn't "suggest" an unrelated short word.
24
+ */
25
+ export const closestMatch = (
26
+ name: string,
27
+ candidates: readonly string[]
28
+ ): string | undefined => {
29
+ let best: { candidate: string; edits: number } | undefined;
30
+ for (const candidate of candidates) {
31
+ const edits = distance(name, candidate);
32
+ if (
33
+ edits <= 2 &&
34
+ edits * 2 < candidate.length &&
35
+ (best === undefined || edits < best.edits)
36
+ ) {
37
+ best = { candidate, edits };
38
+ }
39
+ }
40
+ return best?.candidate;
41
+ };