blume 1.7.3 → 2.0.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 (690) hide show
  1. package/AGENTS.md +19 -0
  2. package/CHANGELOG.md +245 -0
  3. package/README.md +34 -21
  4. package/dist/cli/{chunk-vacwm2hv.js → chunk-27g6wdth.js} +2 -2
  5. package/dist/cli/{chunk-ps4m1xh4.js → chunk-2hn4b8z7.js} +513 -550
  6. package/dist/cli/chunk-2hn4b8z7.js.map +12 -0
  7. package/dist/cli/chunk-5shv93fd.js +39 -0
  8. package/dist/cli/chunk-5shv93fd.js.map +10 -0
  9. package/dist/cli/chunk-6crbhc3x.js +361 -0
  10. package/dist/cli/chunk-6crbhc3x.js.map +14 -0
  11. package/dist/cli/{chunk-8cjtbafj.js → chunk-6hsn950k.js} +109 -383
  12. package/dist/cli/chunk-6hsn950k.js.map +10 -0
  13. package/dist/cli/chunk-6vm74dry.js +148 -0
  14. package/dist/cli/chunk-6vm74dry.js.map +10 -0
  15. package/dist/cli/{chunk-yg63d42r.js → chunk-79jhk4py.js} +87 -58
  16. package/dist/cli/chunk-79jhk4py.js.map +35 -0
  17. package/dist/cli/chunk-82bbrxdn.js +51 -0
  18. package/dist/cli/chunk-82bbrxdn.js.map +10 -0
  19. package/dist/cli/chunk-abh8yjkn.js +31 -0
  20. package/dist/cli/chunk-abh8yjkn.js.map +10 -0
  21. package/dist/cli/chunk-ah61y8py.js +75 -0
  22. package/dist/cli/chunk-ah61y8py.js.map +11 -0
  23. package/dist/cli/{chunk-dwgcp5sm.js → chunk-ce574jw2.js} +1 -1
  24. package/dist/cli/chunk-ch6g3ar0.js +102 -0
  25. package/dist/cli/chunk-ch6g3ar0.js.map +10 -0
  26. package/dist/cli/chunk-dh8cwk36.js +279 -0
  27. package/dist/cli/chunk-dh8cwk36.js.map +10 -0
  28. package/dist/cli/{chunk-rqy0s5wh.js → chunk-epjnccmv.js} +17 -16
  29. package/dist/cli/{chunk-rqy0s5wh.js.map → chunk-epjnccmv.js.map} +3 -3
  30. package/dist/cli/chunk-f2z5v128.js +97 -0
  31. package/dist/cli/chunk-f2z5v128.js.map +10 -0
  32. package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
  33. package/dist/cli/chunk-fa25z98p.js.map +11 -0
  34. package/dist/cli/{chunk-1jefwnfs.js → chunk-fs23ddbb.js} +1076 -2592
  35. package/dist/cli/chunk-fs23ddbb.js.map +35 -0
  36. package/dist/cli/{chunk-e7f42gdj.js → chunk-fxypxtvm.js} +2 -2
  37. package/dist/cli/{chunk-bvwwhd84.js → chunk-fz5wtpmh.js} +15 -15
  38. package/dist/cli/{chunk-bvwwhd84.js.map → chunk-fz5wtpmh.js.map} +1 -1
  39. package/dist/cli/chunk-hdpx1tax.js +91 -0
  40. package/dist/cli/chunk-hdpx1tax.js.map +10 -0
  41. package/dist/cli/{chunk-ct47dqpx.js → chunk-jts8mvcz.js} +67 -7
  42. package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
  43. package/dist/cli/{chunk-ahnw3kxw.js → chunk-jwyddg7y.js} +27 -22
  44. package/dist/cli/chunk-jwyddg7y.js.map +15 -0
  45. package/dist/cli/{chunk-cjtn640a.js → chunk-kdp5q7ke.js} +43 -20
  46. package/dist/cli/chunk-kdp5q7ke.js.map +10 -0
  47. package/dist/cli/{chunk-5g0w1e2c.js → chunk-kpf8rrjc.js} +28 -16
  48. package/dist/cli/{chunk-5g0w1e2c.js.map → chunk-kpf8rrjc.js.map} +4 -4
  49. package/dist/cli/chunk-m3vmjgmq.js +133 -0
  50. package/dist/cli/chunk-m3vmjgmq.js.map +10 -0
  51. package/dist/cli/{chunk-b27xqwn9.js → chunk-mb2919y2.js} +9 -5
  52. package/dist/cli/chunk-mb2919y2.js.map +10 -0
  53. package/dist/cli/{chunk-5qk08vmp.js → chunk-q5163e60.js} +133 -54
  54. package/dist/cli/chunk-q5163e60.js.map +11 -0
  55. package/dist/cli/chunk-qkqwkpte.js +12437 -0
  56. package/dist/cli/chunk-qkqwkpte.js.map +182 -0
  57. package/dist/cli/{chunk-4x36ddpw.js → chunk-qs4q5p4e.js} +81 -87
  58. package/dist/cli/chunk-qs4q5p4e.js.map +10 -0
  59. package/dist/cli/{chunk-0xjyb285.js → chunk-qwsrynx5.js} +15 -5
  60. package/dist/cli/{chunk-0xjyb285.js.map → chunk-qwsrynx5.js.map} +4 -4
  61. package/dist/cli/chunk-s1p84fyh.js +261 -0
  62. package/dist/cli/chunk-s1p84fyh.js.map +10 -0
  63. package/dist/cli/chunk-s6jhgk0q.js +176 -0
  64. package/dist/cli/chunk-s6jhgk0q.js.map +11 -0
  65. package/dist/cli/chunk-vtk4a6dg.js +374 -0
  66. package/dist/cli/chunk-vtk4a6dg.js.map +10 -0
  67. package/dist/cli/{chunk-k79xp7av.js → chunk-wgm7m9qk.js} +230 -700
  68. package/dist/cli/chunk-wgm7m9qk.js.map +36 -0
  69. package/dist/cli/chunk-wm7js3j9.js +145 -0
  70. package/dist/cli/chunk-wm7js3j9.js.map +11 -0
  71. package/dist/cli/chunk-yt5n7ppj.js +79 -0
  72. package/dist/cli/chunk-yt5n7ppj.js.map +10 -0
  73. package/dist/cli/{chunk-3r45185y.js → chunk-yw7dm696.js} +9 -11
  74. package/dist/cli/{chunk-3r45185y.js.map → chunk-yw7dm696.js.map} +3 -3
  75. package/dist/cli/{chunk-nn13znc2.js → chunk-zxcczpyx.js} +1 -1
  76. package/dist/cli/chunk-zxh4d9vy.js +122 -0
  77. package/dist/cli/chunk-zxh4d9vy.js.map +11 -0
  78. package/dist/cli/index.js +214 -57
  79. package/dist/cli/index.js.map +8 -7
  80. package/dist/types/ai/agent-readability.d.ts +52 -0
  81. package/dist/types/ai/ai-catalog.d.ts +42 -0
  82. package/dist/types/ai/api/paths.d.ts +17 -0
  83. package/dist/types/ai/api-catalog.d.ts +18 -0
  84. package/dist/types/ai/ask-context.d.ts +7 -7
  85. package/dist/types/ai/ask.d.ts +368 -0
  86. package/dist/types/ai/changelog-markdown.d.ts +2 -0
  87. package/dist/types/ai/component-markdown.d.ts +2 -2
  88. package/dist/types/ai/index.d.ts +24 -0
  89. package/dist/types/ai/link-headers.d.ts +24 -0
  90. package/dist/types/ai/llms.d.ts +25 -0
  91. package/dist/types/ai/markdown.d.ts +45 -0
  92. package/dist/types/ai/mcp/discovery.d.ts +68 -0
  93. package/dist/types/ai/mcp/tools.d.ts +16 -0
  94. package/dist/types/ai/openapi-components.d.ts +43 -0
  95. package/dist/types/ai/relative-links.d.ts +26 -0
  96. package/dist/types/ai/serializers.d.ts +15 -0
  97. package/dist/types/ai/skills.d.ts +42 -0
  98. package/dist/types/ai/tar.d.ts +25 -0
  99. package/dist/types/ai/visibility.d.ts +17 -0
  100. package/dist/types/ai/web-bot-auth.d.ts +16 -0
  101. package/dist/types/analytics/adobe.d.ts +35 -0
  102. package/dist/types/analytics/amplitude.d.ts +50 -0
  103. package/dist/types/analytics/clarity.d.ts +31 -0
  104. package/dist/types/analytics/clearbit.d.ts +29 -0
  105. package/dist/types/analytics/cloudflare.d.ts +41 -0
  106. package/dist/types/analytics/fathom.d.ts +41 -0
  107. package/dist/types/analytics/google-analytics.d.ts +44 -0
  108. package/dist/types/analytics/google-tag-manager.d.ts +40 -0
  109. package/dist/types/analytics/head.d.ts +30 -0
  110. package/dist/types/analytics/heap.d.ts +40 -0
  111. package/dist/types/analytics/hightouch.d.ts +44 -0
  112. package/dist/types/analytics/hotjar.d.ts +33 -0
  113. package/dist/types/analytics/index.d.ts +61 -0
  114. package/dist/types/analytics/inline.d.ts +17 -0
  115. package/dist/types/analytics/logrocket.d.ts +44 -0
  116. package/dist/types/analytics/mixpanel.d.ts +67 -0
  117. package/dist/types/analytics/pirsch.d.ts +42 -0
  118. package/dist/types/analytics/plausible.d.ts +56 -0
  119. package/dist/types/analytics/posthog.d.ts +45 -0
  120. package/dist/types/analytics/schema.d.ts +320 -0
  121. package/dist/types/analytics/script.d.ts +46 -0
  122. package/dist/types/analytics/segment.d.ts +50 -0
  123. package/dist/types/analytics/vercel.d.ts +48 -0
  124. package/dist/types/astro/integration.d.ts +76 -0
  125. package/dist/types/astro/markdown-negotiation.d.ts +23 -0
  126. package/dist/types/astro/module-types.d.ts +14 -0
  127. package/dist/types/astro/pages.d.ts +44 -0
  128. package/dist/types/cli/env.d.ts +12 -0
  129. package/dist/types/cli/init/scaffold.d.ts +154 -0
  130. package/dist/types/components/layout/nav-utils.d.ts +11 -0
  131. package/dist/types/core/adapter.d.ts +47 -0
  132. package/dist/types/core/api-name.d.ts +7 -0
  133. package/dist/types/core/changelog-index.d.ts +13 -0
  134. package/dist/types/core/config-input.d.ts +197 -526
  135. package/dist/types/core/config.d.ts +61 -35
  136. package/dist/types/core/content-assets.d.ts +76 -0
  137. package/dist/types/core/custom-pages.d.ts +33 -0
  138. package/dist/types/core/data.d.ts +30 -15
  139. package/dist/types/core/define-components.d.ts +12 -9
  140. package/dist/types/core/deployment-env.d.ts +6 -11
  141. package/dist/types/core/frontmatter.d.ts +10 -0
  142. package/dist/types/core/graph.d.ts +18 -0
  143. package/dist/types/core/heading-markers.d.ts +54 -0
  144. package/dist/types/core/i18n-ui.d.ts +12 -10
  145. package/dist/types/core/i18n.d.ts +87 -0
  146. package/dist/types/core/includes.d.ts +138 -0
  147. package/dist/types/core/last-modified.d.ts +47 -0
  148. package/dist/types/core/links.d.ts +95 -0
  149. package/dist/types/core/locale-links.d.ts +60 -0
  150. package/dist/types/core/manifest.d.ts +17 -0
  151. package/dist/types/core/meta.d.ts +38 -0
  152. package/dist/types/core/nav-diagnostics.d.ts +26 -0
  153. package/dist/types/core/navigation.d.ts +6 -0
  154. package/dist/types/core/node-require.d.ts +19 -0
  155. package/dist/types/core/package-json.d.ts +13 -0
  156. package/dist/types/core/probe.d.ts +42 -0
  157. package/dist/types/core/project-graph.d.ts +51 -0
  158. package/dist/types/core/project.d.ts +2 -0
  159. package/dist/types/core/safe-href.d.ts +2 -0
  160. package/dist/types/core/safe-links.d.ts +26 -0
  161. package/dist/types/core/schema.d.ts +2284 -454
  162. package/dist/types/core/site-url.d.ts +16 -0
  163. package/dist/types/core/sources/assets.d.ts +36 -0
  164. package/dist/types/core/sources/cache.d.ts +37 -0
  165. package/dist/types/core/sources/collection.d.ts +28 -0
  166. package/dist/types/core/sources/contentful-rich-text.d.ts +31 -0
  167. package/dist/types/core/sources/contentful.d.ts +40 -0
  168. package/dist/types/core/sources/filesystem.d.ts +24 -0
  169. package/dist/types/core/sources/github-releases.d.ts +31 -0
  170. package/dist/types/core/sources/json.d.ts +30 -0
  171. package/dist/types/core/sources/lexical.d.ts +19 -0
  172. package/dist/types/core/sources/lower.d.ts +75 -0
  173. package/dist/types/core/sources/mdx-remote.d.ts +28 -0
  174. package/dist/types/core/sources/normalize.d.ts +147 -0
  175. package/dist/types/core/sources/notion.d.ts +131 -0
  176. package/dist/types/core/sources/obsidian.d.ts +46 -0
  177. package/dist/types/core/sources/payload.d.ts +39 -0
  178. package/dist/types/core/sources/portable-text.d.ts +42 -0
  179. package/dist/types/core/sources/read.d.ts +23 -0
  180. package/dist/types/core/sources/remote.d.ts +74 -0
  181. package/dist/types/core/sources/resolve.d.ts +19 -0
  182. package/dist/types/core/sources/sanity.d.ts +43 -0
  183. package/dist/types/core/sources/strapi-blocks.d.ts +12 -0
  184. package/dist/types/core/sources/strapi.d.ts +33 -0
  185. package/dist/types/core/sources/types.d.ts +7 -0
  186. package/dist/types/core/sources/watch.d.ts +45 -0
  187. package/dist/types/core/text-width.d.ts +11 -0
  188. package/dist/types/core/types.d.ts +15 -1
  189. package/dist/types/core/unrecognized-keys.d.ts +7 -0
  190. package/dist/types/core/versions.d.ts +72 -0
  191. package/dist/types/core/yaml.d.ts +9 -0
  192. package/dist/types/deploy/adapter-output.d.ts +45 -0
  193. package/dist/types/deploy/adapters/cloudflare.d.ts +40 -0
  194. package/dist/types/deploy/adapters/index.d.ts +29 -0
  195. package/dist/types/deploy/adapters/netlify.d.ts +37 -0
  196. package/dist/types/deploy/adapters/node.d.ts +37 -0
  197. package/dist/types/deploy/adapters/registry.d.ts +133 -0
  198. package/dist/types/deploy/adapters/types.d.ts +71 -0
  199. package/dist/types/deploy/adapters/vercel.d.ts +38 -0
  200. package/dist/types/deploy/artifacts.d.ts +65 -0
  201. package/dist/types/deploy/cloudflare-negotiation.d.ts +196 -0
  202. package/dist/types/deploy/function-bundle.d.ts +80 -0
  203. package/dist/types/deploy/headers.d.ts +50 -0
  204. package/dist/types/deploy/node-headers.d.ts +42 -0
  205. package/dist/types/deploy/platforms/cloudflare.d.ts +40 -0
  206. package/dist/types/deploy/platforms/index.d.ts +18 -0
  207. package/dist/types/deploy/platforms/netlify.d.ts +13 -0
  208. package/dist/types/deploy/platforms/node.d.ts +11 -0
  209. package/dist/types/deploy/platforms/paths.d.ts +27 -0
  210. package/dist/types/deploy/platforms/static.d.ts +10 -0
  211. package/dist/types/deploy/platforms/types.d.ts +104 -0
  212. package/dist/types/deploy/platforms/vercel.d.ts +32 -0
  213. package/dist/types/deploy/redirects.d.ts +53 -0
  214. package/dist/types/deploy/robots.d.ts +8 -0
  215. package/dist/types/deploy/rss.d.ts +31 -0
  216. package/dist/types/deploy/sitemap.d.ts +21 -0
  217. package/dist/types/deploy/vercel-negotiation.d.ts +109 -0
  218. package/dist/types/markdown/code-title.d.ts +32 -0
  219. package/dist/types/markdown/fence-meta.d.ts +23 -0
  220. package/dist/types/markdown/themes.d.ts +3 -3
  221. package/dist/types/openapi/asyncapi.d.ts +129 -0
  222. package/dist/types/openapi/graphql-build.d.ts +8 -0
  223. package/dist/types/openapi/graphql.d.ts +122 -0
  224. package/dist/types/openapi/model.d.ts +158 -0
  225. package/dist/types/openapi/parse.d.ts +57 -0
  226. package/dist/types/openapi/references.d.ts +37 -25
  227. package/dist/types/openapi/render-mdx.d.ts +33 -0
  228. package/dist/types/openapi/sentence.d.ts +7 -0
  229. package/dist/types/openapi/signature.d.ts +10 -0
  230. package/dist/types/openapi/source.d.ts +22 -0
  231. package/dist/types/openapi/spec-dependency-error.d.ts +10 -0
  232. package/dist/types/reference/asyncapi.d.ts +166 -0
  233. package/dist/types/reference/graphql.d.ts +181 -0
  234. package/dist/types/reference/index.d.ts +32 -0
  235. package/dist/types/reference/openapi.d.ts +165 -0
  236. package/dist/types/reference/options.d.ts +157 -0
  237. package/dist/types/reference/scalar.d.ts +136 -0
  238. package/dist/types/reference/schema.d.ts +630 -0
  239. package/dist/types/search/adapters/algolia.d.ts +32 -0
  240. package/dist/types/search/adapters/flexsearch.d.ts +12 -0
  241. package/dist/types/search/adapters/index.d.ts +31 -0
  242. package/dist/types/search/adapters/mixedbread.d.ts +22 -0
  243. package/dist/types/search/adapters/orama-cloud.d.ts +33 -0
  244. package/dist/types/search/adapters/orama.d.ts +13 -0
  245. package/dist/types/search/adapters/pagefind.d.ts +12 -0
  246. package/dist/types/search/adapters/registry.d.ts +228 -0
  247. package/dist/types/search/adapters/types.d.ts +34 -0
  248. package/dist/types/search/adapters/typesense.d.ts +42 -0
  249. package/dist/types/search/build.d.ts +23 -0
  250. package/dist/types/search/documents.d.ts +90 -0
  251. package/dist/types/search/facets.d.ts +3 -0
  252. package/dist/types/search/orama-index.d.ts +1 -1
  253. package/dist/types/search/sync/algolia.d.ts +14 -0
  254. package/dist/types/search/sync/index.d.ts +14 -0
  255. package/dist/types/search/sync/orama-cloud.d.ts +10 -0
  256. package/dist/types/search/sync/typesense.d.ts +14 -0
  257. package/dist/types/sources/contentful.d.ts +68 -0
  258. package/dist/types/sources/custom.d.ts +20 -0
  259. package/dist/types/sources/filesystem.d.ts +42 -0
  260. package/dist/types/sources/github-releases.d.ts +46 -0
  261. package/dist/types/sources/index.d.ts +48 -0
  262. package/dist/types/sources/mdx-remote.d.ts +63 -0
  263. package/dist/types/sources/notion.d.ts +65 -0
  264. package/dist/types/sources/obsidian.d.ts +34 -0
  265. package/dist/types/sources/payload.d.ts +68 -0
  266. package/dist/types/sources/registry.d.ts +1414 -0
  267. package/dist/types/sources/sanity.d.ts +69 -0
  268. package/dist/types/sources/shared.d.ts +46 -0
  269. package/dist/types/sources/strapi.d.ts +66 -0
  270. package/dist/types/theme/icon-kind.d.ts +11 -0
  271. package/dist/types/theme/icons.d.ts +20 -0
  272. package/docs/01-quickstart.mdx +18 -18
  273. package/docs/02-deployment.mdx +52 -28
  274. package/docs/03-upgrading.mdx +364 -0
  275. package/docs/04-migrating.mdx +58 -0
  276. package/docs/08-faq.mdx +5 -5
  277. package/docs/advanced/blog.mdx +13 -6
  278. package/docs/advanced/changelog.mdx +23 -35
  279. package/docs/advanced/custom-pages.mdx +22 -10
  280. package/docs/advanced/meta.ts +1 -8
  281. package/docs/advanced/skills.mdx +8 -0
  282. package/docs/cli/audit.mdx +646 -0
  283. package/docs/cli/doctor.mdx +29 -0
  284. package/docs/{reference/eval.mdx → cli/evals.mdx} +12 -11
  285. package/docs/cli/index.mdx +105 -0
  286. package/docs/cli/meta.ts +7 -0
  287. package/docs/{reference → cli}/translate.mdx +9 -9
  288. package/docs/cli/validate.mdx +41 -0
  289. package/docs/cli/version.mdx +40 -0
  290. package/docs/configuration/analytics.mdx +350 -59
  291. package/docs/configuration/assistant.mdx +357 -0
  292. package/docs/configuration/customization.mdx +16 -10
  293. package/docs/configuration/index.mdx +50 -31
  294. package/docs/configuration/meta.ts +1 -1
  295. package/docs/configuration/search.mdx +76 -55
  296. package/docs/configuration/theming.mdx +24 -15
  297. package/docs/content/components.mdx +21 -5
  298. package/docs/{reference → content}/frontmatter.mdx +35 -1
  299. package/docs/content/i18n.mdx +9 -7
  300. package/docs/content/includes.mdx +2 -4
  301. package/docs/content/index.mdx +1 -1
  302. package/docs/content/islands.mdx +11 -6
  303. package/docs/content/meta.mdx +1 -1
  304. package/docs/content/meta.ts +1 -0
  305. package/docs/content/navigation.mdx +9 -7
  306. package/docs/content/sources.mdx +145 -50
  307. package/docs/content/syntax.mdx +16 -12
  308. package/docs/content/versioning.mdx +3 -3
  309. package/docs/discoverability/agent-discovery.mdx +12 -12
  310. package/docs/discoverability/index.mdx +4 -4
  311. package/docs/discoverability/json-api.mdx +4 -4
  312. package/docs/discoverability/llms-txt.mdx +6 -6
  313. package/docs/discoverability/markdown.mdx +4 -4
  314. package/docs/discoverability/mcp.mdx +11 -11
  315. package/docs/discoverability/sitemap-and-robots.mdx +3 -3
  316. package/docs/index.mdx +4 -4
  317. package/docs/references/asyncapi.mdx +59 -0
  318. package/docs/{advanced → references}/graphql.mdx +45 -32
  319. package/docs/{reference → references}/meta.ts +2 -2
  320. package/docs/references/openapi.mdx +171 -0
  321. package/docs/references/scalar.mdx +64 -0
  322. package/package.json +42 -8
  323. package/skills/blume/SKILL.md +23 -10
  324. package/skills/blume-migrate/SKILL.md +22 -21
  325. package/skills/blume-migrate/assets/oxfmt@0.67.0.patch +49 -0
  326. package/skills/blume-migrate/references/docusaurus.md +5 -4
  327. package/skills/blume-migrate/references/fumadocs.md +4 -4
  328. package/skills/blume-migrate/references/mintlify.md +23 -8
  329. package/skills/blume-migrate/references/monorepo.md +6 -6
  330. package/skills/blume-migrate/references/starlight.md +4 -4
  331. package/src/ai/agent-readability.ts +25 -26
  332. package/src/ai/ai-catalog.ts +50 -32
  333. package/src/ai/api/handlers.ts +46 -11
  334. package/src/ai/api/paths.ts +1 -1
  335. package/src/ai/api-catalog.ts +8 -8
  336. package/src/ai/ask-context.ts +7 -7
  337. package/src/ai/ask-data.ts +3 -3
  338. package/src/ai/ask.ts +637 -100
  339. package/src/ai/changelog-markdown.ts +91 -0
  340. package/src/ai/component-markdown.ts +328 -12
  341. package/src/ai/cors.ts +3 -3
  342. package/src/ai/index.ts +45 -0
  343. package/src/ai/link-headers.ts +7 -6
  344. package/src/ai/llms.ts +20 -15
  345. package/src/ai/markdown.ts +35 -5
  346. package/src/ai/mcp/data.ts +9 -5
  347. package/src/ai/openapi-components.ts +5 -2
  348. package/src/ai/relative-links.ts +170 -0
  349. package/src/ai/serializers.ts +3 -3
  350. package/src/ai/skills.ts +1 -1
  351. package/src/ai/visibility.ts +1 -1
  352. package/src/ai/web-bot-auth.ts +2 -2
  353. package/src/analytics/adobe.ts +46 -0
  354. package/src/analytics/amplitude.ts +79 -0
  355. package/src/analytics/clarity.ts +46 -0
  356. package/src/analytics/clearbit.ts +47 -0
  357. package/src/analytics/cloudflare.ts +67 -0
  358. package/src/analytics/fathom.ts +64 -0
  359. package/src/analytics/google-analytics.ts +84 -0
  360. package/src/analytics/google-tag-manager.ts +61 -0
  361. package/src/analytics/head.ts +130 -0
  362. package/src/analytics/heap.ts +65 -0
  363. package/src/analytics/hightouch.ts +77 -0
  364. package/src/analytics/hotjar.ts +47 -0
  365. package/src/analytics/index.ts +71 -0
  366. package/src/analytics/inline.ts +21 -0
  367. package/src/analytics/logrocket.ts +71 -0
  368. package/src/analytics/mixpanel.ts +92 -0
  369. package/src/analytics/pirsch.ts +66 -0
  370. package/src/analytics/plausible.ts +83 -0
  371. package/src/analytics/posthog.ts +78 -0
  372. package/src/analytics/schema.ts +60 -0
  373. package/src/analytics/script.ts +60 -0
  374. package/src/analytics/segment.ts +85 -0
  375. package/src/analytics/vercel.ts +50 -0
  376. package/src/astro/adapter-root.ts +7 -9
  377. package/src/astro/component-slots.ts +131 -91
  378. package/src/astro/generate.ts +129 -361
  379. package/src/astro/integration.ts +2 -6
  380. package/src/astro/module-types.ts +1 -1
  381. package/src/astro/pages.ts +13 -101
  382. package/src/astro/render-deps.ts +379 -0
  383. package/src/astro/runtime-deps.ts +201 -0
  384. package/src/astro/templates.ts +575 -562
  385. package/src/audit/agent.ts +24 -0
  386. package/src/audit/catalog.ts +2 -2
  387. package/src/audit/checks/assets.ts +2 -2
  388. package/src/audit/checks/dns-aid.ts +1 -1
  389. package/src/audit/checks/duplicates.ts +3 -1
  390. package/src/audit/checks/i18n.ts +1 -1
  391. package/src/audit/checks/indexability.ts +7 -7
  392. package/src/audit/checks/links.ts +2 -2
  393. package/src/audit/checks/llms.ts +6 -6
  394. package/src/audit/checks/network.ts +3 -3
  395. package/src/audit/checks/og-image.ts +2 -2
  396. package/src/audit/checks/robots.ts +1 -1
  397. package/src/audit/checks/sitemap.ts +2 -2
  398. package/src/audit/checks/social.ts +1 -1
  399. package/src/audit/run.ts +4 -3
  400. package/src/audit/terms.ts +31 -0
  401. package/src/audit/url.ts +13 -13
  402. package/src/blume-modules.d.ts +2 -2
  403. package/src/cli/command-meta.ts +10 -0
  404. package/src/cli/commands/audit.ts +40 -21
  405. package/src/cli/commands/build.ts +71 -316
  406. package/src/cli/commands/check.ts +1 -0
  407. package/src/cli/commands/dev.ts +40 -1
  408. package/src/cli/commands/doctor.ts +92 -14
  409. package/src/cli/commands/eject.ts +44 -7
  410. package/src/cli/commands/eval.ts +5 -5
  411. package/src/cli/commands/init.ts +161 -41
  412. package/src/cli/commands/migrate.ts +121 -0
  413. package/src/cli/commands/preview.ts +7 -1
  414. package/src/cli/commands/translate.ts +5 -5
  415. package/src/cli/commands/upgrade.ts +141 -0
  416. package/src/cli/commands/version.ts +57 -44
  417. package/src/cli/eject-scripts.ts +121 -6
  418. package/src/cli/index.ts +11 -1
  419. package/src/cli/init/install.ts +70 -0
  420. package/src/cli/init/questions.ts +7 -0
  421. package/src/cli/init/scaffold.ts +459 -75
  422. package/src/cli/lazy-command.ts +37 -1
  423. package/src/cli/prepare.ts +40 -6
  424. package/src/cli/required-secrets.ts +39 -12
  425. package/src/cli/unknown-flags.ts +266 -0
  426. package/src/cli/yarn-pnp.ts +52 -0
  427. package/src/components/content/AccordionItem.astro +7 -1
  428. package/src/components/content/Card.astro +4 -3
  429. package/src/components/content/ColorItem.astro +22 -4
  430. package/src/components/content/GithubInfo.astro +2 -2
  431. package/src/components/content/Prompt.astro +25 -25
  432. package/src/components/content/Tabs.astro +3 -1
  433. package/src/components/content/Tile.astro +2 -3
  434. package/src/components/content/Tooltip.astro +57 -9
  435. package/src/components/content/content-strings.ts +34 -0
  436. package/src/components/content/diff.ts +1 -1
  437. package/src/components/content/mermaid-element.ts +13 -2
  438. package/src/components/content/prompt-markdown.ts +292 -0
  439. package/src/components/content/tooltip-id.ts +41 -0
  440. package/src/components/copy-feedback.ts +1 -1
  441. package/src/components/islands/{AskAI.astro → Assistant.astro} +10 -10
  442. package/src/components/islands/{ask-ai.tsx → assistant.tsx} +23 -23
  443. package/src/components/islands/hooks.ts +36 -11
  444. package/src/components/layout/Analytics.astro +21 -79
  445. package/src/components/layout/Banner.astro +3 -1
  446. package/src/components/layout/DiscoveryLinks.astro +69 -0
  447. package/src/components/layout/Header.astro +93 -30
  448. package/src/components/layout/LanguageSwitcher.astro +4 -1
  449. package/src/components/layout/Logo.astro +23 -2
  450. package/src/components/layout/NavSelector.astro +13 -2
  451. package/src/components/layout/NavTree.astro +12 -3
  452. package/src/components/layout/NavTreeScript.astro +17 -3
  453. package/src/components/layout/PageActions.astro +3 -3
  454. package/src/components/layout/PageFeedback.astro +11 -1
  455. package/src/components/layout/PageLayout.astro +58 -11
  456. package/src/components/layout/Pagination.astro +7 -7
  457. package/src/components/layout/ReferenceLayout.astro +22 -13
  458. package/src/components/layout/RootLayout.astro +75 -72
  459. package/src/components/layout/Search.astro +43 -19
  460. package/src/components/layout/WebMcp.astro +1 -1
  461. package/src/components/layout/analytics-client.ts +73 -16
  462. package/src/components/layout/drawer-inert.ts +113 -15
  463. package/src/components/layout/dropdown-clamp.ts +105 -0
  464. package/src/components/layout/head-scripts.ts +15 -6
  465. package/src/components/layout/nav-utils.ts +17 -0
  466. package/src/components/layout/search/algolia.ts +8 -8
  467. package/src/components/layout/search/orama-cloud.ts +9 -7
  468. package/src/components/layout/search/typesense.ts +11 -17
  469. package/src/components/openapi/MessageComposer.astro +2 -2
  470. package/src/components/openapi/Playground.astro +2 -2
  471. package/src/components/openapi/description.ts +2 -2
  472. package/src/components/openapi/playground-client.ts +79 -10
  473. package/src/core/changelog-index.ts +24 -0
  474. package/src/core/code-fences.ts +1 -1
  475. package/src/core/component-overrides.ts +399 -154
  476. package/src/core/config-input.ts +201 -566
  477. package/src/core/config.ts +131 -42
  478. package/src/core/custom-pages.ts +105 -0
  479. package/src/core/data.ts +34 -15
  480. package/src/core/define-components.ts +12 -9
  481. package/src/core/deployment-env.ts +18 -74
  482. package/src/core/diagnostics.ts +14 -7
  483. package/src/core/graph.ts +69 -25
  484. package/src/core/i18n-ui.ts +41 -11
  485. package/src/core/i18n.ts +17 -0
  486. package/src/core/includes.ts +156 -38
  487. package/src/core/last-modified.ts +6 -11
  488. package/src/core/links.ts +166 -2
  489. package/src/core/manifest.ts +10 -3
  490. package/src/core/navigation.ts +115 -16
  491. package/src/core/new-tab.ts +35 -0
  492. package/src/core/node-require.ts +21 -0
  493. package/src/core/project-graph.ts +42 -26
  494. package/src/core/project.ts +9 -4
  495. package/src/core/request-body.ts +61 -0
  496. package/src/core/safe-href.ts +28 -0
  497. package/src/core/safe-links.ts +68 -0
  498. package/src/core/schema.ts +528 -745
  499. package/src/core/server-features.ts +10 -11
  500. package/src/core/sources/assets.ts +47 -11
  501. package/src/core/sources/collection.ts +67 -0
  502. package/src/core/sources/contentful-rich-text.ts +285 -0
  503. package/src/core/sources/contentful.ts +173 -0
  504. package/src/core/sources/github-releases.ts +51 -1
  505. package/src/core/sources/json.ts +71 -0
  506. package/src/core/sources/lexical.ts +195 -0
  507. package/src/core/sources/lower.ts +226 -0
  508. package/src/core/sources/normalize.ts +52 -2
  509. package/src/core/sources/notion.ts +39 -28
  510. package/src/core/sources/payload.ts +135 -0
  511. package/src/core/sources/portable-text.ts +11 -16
  512. package/src/core/sources/remote.ts +226 -0
  513. package/src/core/sources/resolve.ts +104 -166
  514. package/src/core/sources/sanity.ts +16 -49
  515. package/src/core/sources/strapi-blocks.ts +124 -0
  516. package/src/core/sources/strapi.ts +191 -0
  517. package/src/core/sources/types.ts +12 -1
  518. package/src/core/types.ts +15 -1
  519. package/src/core/ui-packs/ar.ts +10 -7
  520. package/src/core/ui-packs/bg.ts +10 -7
  521. package/src/core/ui-packs/bn.ts +10 -7
  522. package/src/core/ui-packs/ca.ts +7 -6
  523. package/src/core/ui-packs/cs.ts +10 -7
  524. package/src/core/ui-packs/da.ts +10 -7
  525. package/src/core/ui-packs/de.ts +10 -7
  526. package/src/core/ui-packs/el.ts +7 -6
  527. package/src/core/ui-packs/es.ts +7 -6
  528. package/src/core/ui-packs/fa.ts +10 -7
  529. package/src/core/ui-packs/fi.ts +10 -7
  530. package/src/core/ui-packs/fr.ts +7 -6
  531. package/src/core/ui-packs/he.ts +10 -7
  532. package/src/core/ui-packs/hi.ts +10 -7
  533. package/src/core/ui-packs/hr.ts +10 -7
  534. package/src/core/ui-packs/hu.ts +10 -7
  535. package/src/core/ui-packs/id.ts +10 -7
  536. package/src/core/ui-packs/it.ts +7 -6
  537. package/src/core/ui-packs/ja.ts +7 -6
  538. package/src/core/ui-packs/ko.ts +7 -6
  539. package/src/core/ui-packs/nl.ts +10 -7
  540. package/src/core/ui-packs/no.ts +10 -7
  541. package/src/core/ui-packs/pl.ts +10 -7
  542. package/src/core/ui-packs/pt-br.ts +7 -6
  543. package/src/core/ui-packs/pt.ts +7 -6
  544. package/src/core/ui-packs/ro.ts +10 -7
  545. package/src/core/ui-packs/ru.ts +10 -7
  546. package/src/core/ui-packs/sk.ts +10 -7
  547. package/src/core/ui-packs/sr.ts +10 -7
  548. package/src/core/ui-packs/sv.ts +10 -7
  549. package/src/core/ui-packs/th.ts +7 -6
  550. package/src/core/ui-packs/tr.ts +10 -7
  551. package/src/core/ui-packs/uk.ts +10 -7
  552. package/src/core/ui-packs/vi.ts +7 -6
  553. package/src/core/ui-packs/zh-tw.ts +7 -6
  554. package/src/core/ui-packs/zh.ts +7 -6
  555. package/src/core/unrecognized-keys.ts +10 -0
  556. package/src/core/version-cut.ts +116 -8
  557. package/src/deploy/adapter-output.ts +57 -97
  558. package/src/deploy/adapters/cloudflare.ts +39 -0
  559. package/src/deploy/adapters/index.ts +41 -0
  560. package/src/deploy/adapters/netlify.ts +34 -0
  561. package/src/deploy/adapters/node.ts +34 -0
  562. package/src/deploy/adapters/registry.ts +127 -0
  563. package/src/deploy/adapters/types.ts +92 -0
  564. package/src/deploy/adapters/vercel.ts +35 -0
  565. package/src/deploy/artifacts.ts +55 -27
  566. package/src/deploy/cloudflare-negotiation.ts +179 -100
  567. package/src/deploy/function-bundle.ts +18 -3
  568. package/src/deploy/headers.ts +124 -23
  569. package/src/deploy/node-headers.ts +198 -0
  570. package/src/deploy/platforms/cloudflare.ts +312 -0
  571. package/src/deploy/platforms/index.ts +67 -0
  572. package/src/deploy/platforms/netlify.ts +52 -0
  573. package/src/deploy/platforms/node.ts +40 -0
  574. package/src/deploy/platforms/paths.ts +42 -0
  575. package/src/deploy/platforms/static.ts +29 -0
  576. package/src/deploy/platforms/types.ts +112 -0
  577. package/src/deploy/platforms/vercel.ts +193 -0
  578. package/src/deploy/redirects.ts +30 -18
  579. package/src/deploy/robots.ts +3 -3
  580. package/src/deploy/rss.ts +2 -2
  581. package/src/deploy/sitemap.ts +2 -2
  582. package/src/deploy/vercel-negotiation.ts +2 -2
  583. package/src/eval/agents.ts +32 -1
  584. package/src/eval/findings.ts +19 -11
  585. package/src/eval/report.ts +10 -2
  586. package/src/markdown/external-links.ts +65 -0
  587. package/src/markdown/include.ts +45 -27
  588. package/src/markdown/index.ts +34 -9
  589. package/src/markdown/inline-code.ts +12 -6
  590. package/src/markdown/relative-links.ts +324 -0
  591. package/src/markdown/themes.ts +3 -3
  592. package/src/migrate/migrate.ts +149 -0
  593. package/src/openapi/parse.ts +64 -16
  594. package/src/openapi/proxy.ts +62 -10
  595. package/src/openapi/references.ts +147 -147
  596. package/src/openapi/render-mdx.ts +32 -10
  597. package/src/openapi/scalar.ts +15 -13
  598. package/src/openapi/sentence.ts +14 -0
  599. package/src/openapi/source.ts +37 -21
  600. package/src/openapi/spec-dependency-error.ts +15 -0
  601. package/src/reference/asyncapi.ts +83 -0
  602. package/src/reference/graphql.ts +89 -0
  603. package/src/reference/index.ts +40 -0
  604. package/src/reference/openapi.ts +83 -0
  605. package/src/reference/options.ts +201 -0
  606. package/src/reference/scalar.ts +136 -0
  607. package/src/reference/schema.ts +88 -0
  608. package/src/registry/eject.ts +109 -53
  609. package/src/search/adapters/algolia.ts +46 -0
  610. package/src/search/adapters/flexsearch.ts +29 -0
  611. package/src/search/adapters/index.ts +39 -0
  612. package/src/search/adapters/mixedbread.ts +39 -0
  613. package/src/search/adapters/orama-cloud.ts +51 -0
  614. package/src/search/adapters/orama.ts +24 -0
  615. package/src/search/adapters/pagefind.ts +27 -0
  616. package/src/search/adapters/registry.ts +131 -0
  617. package/src/search/adapters/types.ts +46 -0
  618. package/src/search/adapters/typesense.ts +57 -0
  619. package/src/search/build.ts +8 -4
  620. package/src/search/documents.ts +8 -2
  621. package/src/search/orama-index.ts +1 -1
  622. package/src/search/sync/algolia.ts +12 -11
  623. package/src/search/sync/index.ts +35 -20
  624. package/src/search/sync/orama-cloud.ts +12 -9
  625. package/src/search/sync/typesense.ts +15 -13
  626. package/src/sources/contentful.ts +63 -0
  627. package/src/sources/custom.ts +38 -0
  628. package/src/sources/filesystem.ts +51 -0
  629. package/src/sources/github-releases.ts +52 -0
  630. package/src/sources/index.ts +60 -0
  631. package/src/sources/mdx-remote.ts +76 -0
  632. package/src/sources/notion.ts +63 -0
  633. package/src/sources/obsidian.ts +38 -0
  634. package/src/sources/payload.ts +60 -0
  635. package/src/sources/registry.ts +182 -0
  636. package/src/sources/sanity.ts +66 -0
  637. package/src/sources/shared.ts +52 -0
  638. package/src/sources/strapi.ts +58 -0
  639. package/src/theme/entry.ts +24 -2
  640. package/src/translate/report.ts +40 -7
  641. package/src/upgrade/upgrade.ts +499 -0
  642. package/dist/cli/chunk-0qymqwzz.js +0 -164
  643. package/dist/cli/chunk-0qymqwzz.js.map +0 -15
  644. package/dist/cli/chunk-1jefwnfs.js.map +0 -48
  645. package/dist/cli/chunk-2mzebbbz.js +0 -69
  646. package/dist/cli/chunk-2z47ypj8.js.map +0 -11
  647. package/dist/cli/chunk-4x36ddpw.js.map +0 -11
  648. package/dist/cli/chunk-5093q3n7.js +0 -68
  649. package/dist/cli/chunk-5093q3n7.js.map +0 -10
  650. package/dist/cli/chunk-5qk08vmp.js.map +0 -11
  651. package/dist/cli/chunk-7s8hm3b6.js +0 -5347
  652. package/dist/cli/chunk-7s8hm3b6.js.map +0 -58
  653. package/dist/cli/chunk-8cjtbafj.js.map +0 -13
  654. package/dist/cli/chunk-97r59kpr.js +0 -381
  655. package/dist/cli/chunk-97r59kpr.js.map +0 -12
  656. package/dist/cli/chunk-ahnw3kxw.js.map +0 -15
  657. package/dist/cli/chunk-b27xqwn9.js.map +0 -10
  658. package/dist/cli/chunk-bf6bt1xt.js +0 -185
  659. package/dist/cli/chunk-bf6bt1xt.js.map +0 -11
  660. package/dist/cli/chunk-cjtn640a.js.map +0 -10
  661. package/dist/cli/chunk-ct47dqpx.js.map +0 -11
  662. package/dist/cli/chunk-esphfr8p.js +0 -107
  663. package/dist/cli/chunk-esphfr8p.js.map +0 -11
  664. package/dist/cli/chunk-ex56aa81.js +0 -1016
  665. package/dist/cli/chunk-ex56aa81.js.map +0 -13
  666. package/dist/cli/chunk-garjf5z9.js +0 -30
  667. package/dist/cli/chunk-garjf5z9.js.map +0 -10
  668. package/dist/cli/chunk-js7saxwm.js +0 -1045
  669. package/dist/cli/chunk-js7saxwm.js.map +0 -22
  670. package/dist/cli/chunk-k79xp7av.js.map +0 -39
  671. package/dist/cli/chunk-ps4m1xh4.js.map +0 -15
  672. package/dist/cli/chunk-q4rae3bg.js +0 -60
  673. package/dist/cli/chunk-q4rae3bg.js.map +0 -10
  674. package/dist/cli/chunk-rz9jmfhz.js +0 -108
  675. package/dist/cli/chunk-rz9jmfhz.js.map +0 -10
  676. package/dist/cli/chunk-vh9w1sgp.js +0 -73
  677. package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
  678. package/dist/cli/chunk-vrfp10qk.js +0 -81
  679. package/dist/cli/chunk-vrfp10qk.js.map +0 -10
  680. package/dist/cli/chunk-yg63d42r.js.map +0 -34
  681. package/docs/advanced/api-reference.mdx +0 -240
  682. package/docs/configuration/ask-ai.mdx +0 -256
  683. package/docs/reference/cli.mdx +0 -197
  684. package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
  685. package/src/components/content/changelog-element.ts +0 -69
  686. package/src/search/providers.ts +0 -91
  687. /package/dist/cli/{chunk-vacwm2hv.js.map → chunk-27g6wdth.js.map} +0 -0
  688. /package/dist/cli/{chunk-dwgcp5sm.js.map → chunk-ce574jw2.js.map} +0 -0
  689. /package/dist/cli/{chunk-e7f42gdj.js.map → chunk-fxypxtvm.js.map} +0 -0
  690. /package/dist/cli/{chunk-nn13znc2.js.map → chunk-zxcczpyx.js.map} +0 -0
@@ -0,0 +1,171 @@
1
+ ---
2
+ title: OpenAPI
3
+ description: Drop in an OpenAPI spec and get a native API reference — one real page per operation, in your sidebar and search.
4
+ ---
5
+
6
+ Point Blume at an OpenAPI spec and it generates a native API reference: one **real page per operation**, grouped by tag in a tab-scoped sidebar, with schema tables, request/response examples, generated code samples, and an interactive [Try it](#try-it-playground) panel. Because each operation is a genuine Blume page, it gets its own URL, shows up in **site search** and `llms.txt`, and gets an Open Graph image — the same as any hand-written doc.
7
+
8
+ Every reference is an **adapter** imported from `blume/reference` and listed under `reference`: `openapi()` for an OpenAPI document, [`asyncapi()`](/docs/references/asyncapi) for an AsyncAPI document, and [`graphql()`](/docs/references/graphql) for a GraphQL schema. Each adapter owns its spec sources, its mount route, and its display options, so the list can hold as many of each kind as you need. The config below points Blume at the public Petstore spec as an example.
9
+
10
+ ```ts blume.config.ts lineNumbers
11
+ import { defineConfig } from "blume";
12
+ import { openapi } from "blume/reference";
13
+
14
+ export default defineConfig({
15
+ reference: [
16
+ openapi({ spec: "https://petstore3.swagger.io/api/v3/openapi.json" }),
17
+ ],
18
+ });
19
+ ```
20
+
21
+ That mounts the reference at `/reference` (an overview page) with each operation at `/reference/<tag>/<operation>`. The `spec` is either an `http(s)` URL or a path to a local file in your project. Blume parses it with [Scalar's OpenAPI parser](https://github.com/scalar/scalar) — Swagger 2.0 and OpenAPI 3.0 specs are upgraded to 3.1 automatically. An adapter is a plain description of the reference — not a parsed spec — so Blume can validate it up front and inline it into the generated site; leaving `reference` out (or empty) renders no reference at all. Documenting an event-driven or GraphQL API instead? See [AsyncAPI](/docs/references/asyncapi) and [GraphQL](/docs/references/graphql).
22
+
23
+ The reference doesn't add a header tab on its own. To surface it, point a [navigation tab](/docs/content/navigation#tabs) at its route — this also scopes the operations sidebar for the native renderer:
24
+
25
+ ```ts blume.config.ts
26
+ navigation: {
27
+ tabs: [{ label: "API", path: "/reference" }],
28
+ }
29
+ ```
30
+
31
+ :::note
32
+ Operations are indexed for search by their **summary and tag**. The rendered schema tables and code samples aren't full-text indexed; search matches an operation's title and section, then links to its own page.
33
+ :::
34
+
35
+ ## A local spec
36
+
37
+ A relative path is resolved from your project root and read at build time. Both JSON and YAML work:
38
+
39
+ ```ts blume.config.ts lineNumbers
40
+ reference: [openapi({ spec: "./openapi.yaml" })],
41
+ ```
42
+
43
+ ## Route
44
+
45
+ `route` controls where the reference mounts — the overview page and the prefix for every operation route (and the route you point a navigation tab at):
46
+
47
+ ```ts blume.config.ts lineNumbers
48
+ reference: [
49
+ openapi({
50
+ route: "/api", // overview at /api, operations at /api/<tag>/<operation>
51
+ spec: "./openapi.yaml",
52
+ }),
53
+ ],
54
+ ```
55
+
56
+ ## Code samples and schemas
57
+
58
+ `codeSamples` picks which languages render per operation (built in: `curl`, `js`, `python`); `expandSchemas` starts nested schema rows expanded rather than collapsed:
59
+
60
+ ```ts blume.config.ts lineNumbers
61
+ reference: [
62
+ openapi({
63
+ spec: "./openapi.yaml",
64
+ codeSamples: ["curl", "js"],
65
+ expandSchemas: true,
66
+ }),
67
+ ],
68
+ ```
69
+
70
+ ## Try it playground
71
+
72
+ Operation pages rendered natively ship an interactive **Try it** panel by default. Blume generates the form from the operation itself: an input per path, query, and header parameter, a body editor built from the request-body schema, everything prefilled from the spec's examples. A server picker lists the spec's `servers`, with a free-text field for any other base URL, and auth inputs match the operation's [resolved security](#authorization) — bearer token, API key, and basic credentials, with OAuth2 as a token paste field (bring an access token; Blume doesn't run the flow).
73
+
74
+ The panel and the code samples stay in lockstep: values typed into the form update the generated samples live, so a copied curl command always matches exactly what **Send** would do. And it stays out of the way — the panel is server-rendered collapsed, and its JavaScript loads only when a reader first opens it. Readers who never touch it download none of it.
75
+
76
+ `playground: false` is the entire off switch:
77
+
78
+ ```ts blume.config.ts lineNumbers
79
+ reference: [openapi({ spec: "./openapi.yaml", playground: false })],
80
+ ```
81
+
82
+ ### Credentials
83
+
84
+ Credentials typed into the auth inputs stay in memory and vanish on reload. Checking **Remember on this device** persists them in `localStorage`, scoped to the docs origin — they're never sent anywhere except the API being called. Code samples keep showing placeholders (`YOUR_TOKEN` and friends) whatever's typed, unless the reader toggles **Include my values in samples**.
85
+
86
+ ### CORS and the proxy
87
+
88
+ As with a [Scalar embed](/docs/references/scalar), requests go **directly from the browser** to the target API, so the API must allow cross-origin requests from the docs site (`Access-Control-Allow-Origin`). For APIs that can't, set `playground.proxy`: a URL routes requests through a proxy you host, and `true` enables the built-in `/_api-proxy` route — which needs [server output](/docs/deployment#server-rendering): a host adapter such as `deployment: vercel()` from `blume/deploy`:
89
+
90
+ ```ts blume.config.ts lineNumbers
91
+ reference: [
92
+ openapi({
93
+ spec: "./openapi.yaml",
94
+ playground: {
95
+ proxy: true, // or a URL of your own
96
+ },
97
+ }),
98
+ ],
99
+ ```
100
+
101
+ The built-in proxy only forwards requests to the origins your specs declare in `servers` — including across redirects — so a public docs deployment can't be aimed at other hosts on its network. A **Custom base URL** typed into the panel isn't a documented server: with the proxy enabled, requests to it are refused with a 403. It reads a request body only up to 4 MB (anything larger gets a `413`), and every response it relays carries `Content-Security-Policy: sandbox`, `X-Content-Type-Options: nosniff`, and `Cross-Origin-Resource-Policy: same-origin` — plus `Content-Disposition: attachment` for HTML or SVG — so an API error page that echoes its input can't run script on the docs origin.
102
+
103
+ ## Multiple specs
104
+
105
+ Use `sources` to publish more than one spec from one adapter. Each source gets its own overview route and operation pages, and shares the adapter's display options. Give each a `label` (used for the sidebar and to derive its route), or set an explicit `route`:
106
+
107
+ ```ts blume.config.ts lineNumbers
108
+ reference: [
109
+ openapi({
110
+ sources: [
111
+ { label: "Public API", spec: "./public.json" }, // → /reference/public-api
112
+ { label: "Admin API", route: "/admin", spec: "./admin.json" },
113
+ ],
114
+ }),
115
+ ],
116
+ ```
117
+
118
+ `spec` is shorthand for a single-entry `sources`, so you only reach for `sources` when you have more than one. When two specs need different display options — a different code-sample set, say — list two `openapi()` adapters instead, each with its own `route`. An embedded [Scalar](/docs/references/scalar) reference beside native pages is its own `scalar()` adapter in the list. Sources are resolved in list order, and when two resolve to the same route the first one wins (the build warns about the one it dropped).
119
+
120
+ ### Per-source indexing
121
+
122
+ Generated pages participate in search, `llms.txt`, and crawler indexing by default. A secondary or overlapping spec can opt out of any surface without hiding its pages or removing it from navigation:
123
+
124
+ ```ts blume.config.ts lineNumbers
125
+ reference: [
126
+ openapi({
127
+ sources: [
128
+ { label: "Public API", route: "/api", spec: "./public.json" },
129
+ {
130
+ label: "Platform API",
131
+ route: "/platform",
132
+ spec: "./platform.json",
133
+ includeInSearch: false,
134
+ includeInLlms: false,
135
+ noindex: true,
136
+ },
137
+ ],
138
+ }),
139
+ ],
140
+ ```
141
+
142
+ - `includeInSearch: false` keeps the source's overview and operations out of site search.
143
+ - `includeInLlms: false` keeps them out of both `llms.txt` files.
144
+ - `noindex: true` adds crawler noindex metadata and removes the pages from the sitemap.
145
+
146
+ Each operation page's meta description is the operation's own `description` (or `summary`), followed by a generated sentence naming the endpoint — "Reference for the `GET /pets` endpoint in the Petstore API." — so a spec of terse one-line summaries still ships a distinct, snippet-length description per page. That sentence is English. On a site whose spec prose is written in another language, set `seoDescriptionSuffix: false` on the source to drop it and describe each page with the authored prose alone; an operation with neither a `description` nor a `summary` falls back to its title (`GET /pets`), so no page ships an empty description:
147
+
148
+ ```ts blume.config.ts lineNumbers
149
+ reference: [
150
+ openapi({
151
+ sources: [{ spec: "./openapi.de.json", seoDescriptionSuffix: false }],
152
+ }),
153
+ ],
154
+ ```
155
+
156
+ A [`scalar()`](/docs/references/scalar) embed takes only `noindex` of these — it already sits outside Blume's search and `llms.txt`, so the two `include*` settings have nothing to act on there.
157
+
158
+ ## Authorization
159
+
160
+ Operations that declare [security requirements](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) render an **Authorization** section above their parameters, and the generated code samples send a placeholder credential (`Authorization: Bearer YOUR_TOKEN`, an API-key header, or a query key — whatever the scheme calls for). There's nothing to configure: Blume reads `security` from the spec, so the reference always matches what the API actually enforces.
161
+
162
+ The OpenAPI semantics carry over as written:
163
+
164
+ - An operation's own `security` overrides the document's root default; `security: []` marks it **public** and renders no Authorization section.
165
+ - Multiple requirement entries are alternatives — rendered as "or" groups; every scheme inside one entry is required together. The first alternative feeds the code samples.
166
+ - An empty `{}` entry means auth is **optional** for that operation, and the section says so.
167
+ - OAuth2 scopes are listed per scheme; scheme `description`s from `components.securitySchemes` render inline.
168
+
169
+ ## Embedding Scalar instead
170
+
171
+ `openapi()` always renders Blume's own pages. To embed [Scalar](https://scalar.com)'s self-contained API reference UI on a single route instead — its own sidebar, search, theme, and request client — list a `scalar()` adapter from `blume/reference` in place of (or beside) this one. The [Scalar](/docs/references/scalar) page covers what the embed does and doesn't do, and how to pass Scalar's own options through.
@@ -0,0 +1,64 @@
1
+ ---
2
+ title: Scalar
3
+ description: Embed Scalar's self-contained API reference UI on a single route, with any Scalar option passed straight through.
4
+ ---
5
+
6
+ Blume's own renderer is what [`openapi()`](/docs/references/openapi), [`asyncapi()`](/docs/references/asyncapi), and [`graphql()`](/docs/references/graphql) give you: one real page per operation, in your sidebar, search, and `llms.txt`, with a [Try it playground](/docs/references/openapi#try-it-playground). If you'd rather embed [Scalar](https://scalar.com)'s self-contained API reference UI — its own sidebar, search, theme, and request client on a single route — list a `scalar()` adapter from `blume/reference` instead. It takes an OpenAPI or AsyncAPI document and Scalar detects which:
7
+
8
+ ```ts blume.config.ts lineNumbers
9
+ import { defineConfig } from "blume";
10
+ import { scalar } from "blume/reference";
11
+
12
+ export default defineConfig({
13
+ reference: [
14
+ scalar({
15
+ spec: "./openapi.yaml",
16
+ theme: "purple", // a Scalar theme name
17
+ }),
18
+ ],
19
+ });
20
+ ```
21
+
22
+ That mounts the embed at `/reference`. `spec` is either an `http(s)` URL, which the page loads from the browser, or a path to a local file, which is read at build time and inlined so the page stays self-contained. `route` moves it, and `sources` publishes several documents, each on its own route — the same [`label`/`route` rules](/docs/references/openapi#multiple-specs) the native adapters follow:
23
+
24
+ ```ts blume.config.ts lineNumbers
25
+ reference: [
26
+ scalar({
27
+ route: "/api",
28
+ sources: [
29
+ { label: "Public API", spec: "./public.json" }, // → /api/public-api
30
+ { label: "Legacy API", route: "/legacy", spec: "./legacy.json", noindex: true },
31
+ ],
32
+ }),
33
+ ],
34
+ ```
35
+
36
+ A Scalar embed and native pages can sit side by side in the list — an `openapi()` adapter for the current API and a `scalar()` adapter for a legacy one, say — as long as their routes differ. Like every reference, the embed doesn't add a header tab on its own; point a [navigation tab](/docs/content/navigation#tabs) at its route to surface it.
37
+
38
+ ## What the embed doesn't do
39
+
40
+ A Scalar-rendered reference is a self-contained page on its own route. It doesn't weave into Blume's sidebar, search, or `llms.txt`, so of the native adapters' per-source controls only `noindex` applies here (it adds crawler noindex metadata and keeps the page out of the sitemap); there is no `codeSamples`, `expandSchemas`, or `playground` to set. Scalar brings its own request client, which calls your **target API directly from the browser** (Blume's [`playground.proxy`](/docs/references/openapi#cors-and-the-proxy) route isn't available here), so the API must allow cross-origin requests from the docs site (`Access-Control-Allow-Origin`).
41
+
42
+ The embed does follow Blume's light/dark toggle: it's pinned to the page's theme when it mounts and switches with it, so Scalar's own theme switch is hidden (pass `forceDarkModeState` or `darkMode` to hand color mode back to Scalar). Without a `theme`, Blume layers its accent and radius onto Scalar's default theme; a named `theme` replaces that. The adapter declares `@scalar/astro` as its runtime dependency, so the generated project only lists it when a `scalar()` adapter is configured.
43
+
44
+ ## Passing Scalar options
45
+
46
+ `theme` is the one option most people reach for, but Scalar supports many more. Every key you pass to `scalar()` beyond `spec`, `sources`, `route`, and `theme` is forwarded verbatim as [Scalar configuration](https://github.com/scalar/scalar/blob/main/documentation/configuration.md) to the embedded reference — Blume doesn't gate the keys, so anything Scalar accepts flows through (JSON values only, since the configuration is inlined into the generated page):
47
+
48
+ ```ts blume.config.ts lineNumbers
49
+ reference: [
50
+ scalar({
51
+ spec: "./openapi.yaml",
52
+ localization: { locale: "es" }, // translate Scalar's own UI
53
+ agent: { disabled: true }, // disable the Scalar Agent
54
+ hideTestRequestButton: true,
55
+ orderSchemaPropertiesBy: "preserve",
56
+ }),
57
+ ],
58
+ ```
59
+
60
+ Blume's own [`i18n`](/docs/content/i18n) translates the docs chrome, but Scalar has a separate localization system — set `localization.locale` to translate the embedded reference too. Forwarded options win over Blume's derived config, so anything set here (including `customCss` or the spec `content`/`url`) overrides Blume's defaults. The one key that can't be forwarded is Scalar's own multi-document `sources`: that name is Blume's, and each Blume source becomes its own page.
61
+
62
+ ## AsyncAPI documents
63
+
64
+ Point `spec` at an AsyncAPI document and the embed renders channels, operations, messages, and a Models section. Scalar has no AsyncAPI playground of its own, so choosing the embed over [`asyncapi()`](/docs/references/asyncapi) trades Blume's [event composer](/docs/references/asyncapi#try-it-for-events) away. A GraphQL schema has no Scalar embed at all — the [`graphql()`](/docs/references/graphql) reference is always rendered natively.
package/package.json CHANGED
@@ -1,12 +1,17 @@
1
1
  {
2
2
  "name": "blume",
3
- "version": "1.7.3",
4
- "description": "Documentation that's fast, AI-ready, and zero-config.",
3
+ "version": "2.0.1",
4
+ "description": "The open-source docs framework for humans and agents.",
5
5
  "keywords": [
6
+ "agents",
7
+ "ai",
6
8
  "astro",
7
9
  "docs",
8
10
  "documentation",
11
+ "documentation-generator",
12
+ "llms",
9
13
  "markdown",
14
+ "mcp",
10
15
  "mdx",
11
16
  "vite"
12
17
  ],
@@ -30,6 +35,7 @@
30
35
  "bin",
31
36
  "docs",
32
37
  "skills",
38
+ "AGENTS.md",
33
39
  "CHANGELOG.md"
34
40
  ],
35
41
  "type": "module",
@@ -39,11 +45,31 @@
39
45
  "types": "./dist/types/index.d.ts",
40
46
  "default": "./src/index.ts"
41
47
  },
48
+ "./ai": {
49
+ "types": "./dist/types/ai/index.d.ts",
50
+ "default": "./src/ai/index.ts"
51
+ },
42
52
  "./ai/*": "./src/ai/*",
53
+ "./analytics": {
54
+ "types": "./dist/types/analytics/index.d.ts",
55
+ "default": "./src/analytics/index.ts"
56
+ },
57
+ "./deploy": {
58
+ "types": "./dist/types/deploy/adapters/index.d.ts",
59
+ "default": "./src/deploy/adapters/index.ts"
60
+ },
61
+ "./reference": {
62
+ "types": "./dist/types/reference/index.d.ts",
63
+ "default": "./src/reference/index.ts"
64
+ },
43
65
  "./schema": {
44
66
  "types": "./dist/types/core/schema.d.ts",
45
67
  "default": "./src/core/schema.ts"
46
68
  },
69
+ "./search": {
70
+ "types": "./dist/types/search/adapters/index.d.ts",
71
+ "default": "./src/search/adapters/index.ts"
72
+ },
47
73
  "./runtime": "./src/runtime/index.ts",
48
74
  "./hooks": "./src/components/islands/hooks.ts",
49
75
  "./astro": "./src/astro/index.ts",
@@ -53,6 +79,10 @@
53
79
  "./components/*": "./src/components/*",
54
80
  "./core/*": "./src/core/*",
55
81
  "./openapi/*": "./src/openapi/*",
82
+ "./sources": {
83
+ "types": "./dist/types/sources/index.d.ts",
84
+ "default": "./src/sources/index.ts"
85
+ },
56
86
  "./sources/*": "./src/core/sources/*",
57
87
  "./theme/*": "./src/theme/*",
58
88
  "./package.json": "./package.json"
@@ -73,7 +103,6 @@
73
103
  "@astrojs/node": "^11.1.5",
74
104
  "@astrojs/react": "^6.0.5",
75
105
  "@astrojs/vercel": "^11.0.10",
76
- "@asyncapi/converter": "^2.0.2",
77
106
  "@clack/prompts": "^1.8.0",
78
107
  "@iconify-json/lucide": "^1.2.131",
79
108
  "@iconify/types": "^2.0.0",
@@ -81,7 +110,7 @@
81
110
  "@modelcontextprotocol/sdk": "^1.30.0",
82
111
  "@orama/orama": "^3.1.18",
83
112
  "@pierre/diffs": "^1.4.2",
84
- "@scalar/astro": "^0.4.18",
113
+ "@scalar/astro": "^0.4.21",
85
114
  "@scalar/openapi-parser": "^0.29.1",
86
115
  "@scalar/openapi-types": "^0.9.5",
87
116
  "@shikijs/transformers": "^4.4.3",
@@ -89,6 +118,7 @@
89
118
  "@tailwindcss/typography": "^0.5.20",
90
119
  "@tailwindcss/vite": "^4.3.3",
91
120
  "@types/mdast": "^4.0.4",
121
+ "@types/node": "^22.20.2",
92
122
  "@vercel/analytics": "^2.0.1",
93
123
  "ai": "^7.0.99",
94
124
  "astro": "^7.3.2",
@@ -144,12 +174,13 @@
144
174
  "twoslash": "^0.3.9",
145
175
  "typescript": "^6.0.3",
146
176
  "ufo": "^1.6.4",
147
- "undici": "^8.10.2",
148
- "write-file-atomic": "^8.0.0",
177
+ "undici": "^7.29.1",
178
+ "write-file-atomic": "^7.0.1",
149
179
  "zod": "^4.6.2"
150
180
  },
151
181
  "devDependencies": {
152
182
  "@ai-sdk/openai-compatible": "^3.0.48",
183
+ "@asyncapi/converter": "^2.0.2",
153
184
  "@mixedbread/sdk": "^0.77.0",
154
185
  "@notionhq/client": "^5.26.0",
155
186
  "@openrouter/ai-sdk-provider": "^3.0.0",
@@ -157,7 +188,6 @@
157
188
  "@sanity/client": "^8.6.1",
158
189
  "@types/cross-spawn": "^6.0.6",
159
190
  "@types/html-escaper": "^3.0.4",
160
- "@types/node": "^22.20.2",
161
191
  "@types/picomatch": "^4.0.3",
162
192
  "@types/react": "^19.3.0",
163
193
  "@types/react-dom": "^19.3.0",
@@ -176,7 +206,8 @@
176
206
  "@astrojs/netlify": "^8.0.0",
177
207
  "@astrojs/svelte": "^9.0.0",
178
208
  "@astrojs/vue": "^7.0.0",
179
- "@mixedbread/sdk": "^0.77.0",
209
+ "@asyncapi/converter": "^2.0.2",
210
+ "@mixedbread/sdk": ">=0.77.0 <1",
180
211
  "@notionhq/client": "^5.0.0",
181
212
  "@openrouter/ai-sdk-provider": "^3.0.0",
182
213
  "@oramacloud/client": "^2.1.0",
@@ -201,6 +232,9 @@
201
232
  "@astrojs/vue": {
202
233
  "optional": true
203
234
  },
235
+ "@asyncapi/converter": {
236
+ "optional": true
237
+ },
204
238
  "@mixedbread/sdk": {
205
239
  "optional": true
206
240
  },
@@ -12,22 +12,21 @@ The core idea: **the framework _is_ the template.** There's no starter to clone
12
12
  ## What makes it different
13
13
 
14
14
  - **Fast by default** — Static HTML on Astro/Vite. The core theme ships no client framework JS so pages score well on Core Web Vitals out of the box. You opt into server features only when you need them.
15
- - **AI-ready out of the box** — Emits `llms.txt`/`llms-full.txt`, serves any page's raw Markdown by appending `.md` to its URL, publishes a JSON docs API (`/api/docs/…`) described by an OpenAPI document at `/openapi.json`, offers **Copy as Markdown** and **Open in chat** on every page, and can host an optional **Ask AI** assistant or an **MCP server** so coding agents read your docs directly.
15
+ - **AI-ready out of the box** — Emits `llms.txt`/`llms-full.txt`, serves any page's raw Markdown by appending `.md` to its URL, publishes a JSON docs API (`/api/docs/…`) described by an OpenAPI document at `/openapi.json`, offers **Copy as Markdown** and **Open in chat** on every page, and can host an optional in-page **assistant** or an **MCP server** so coding agents read your docs directly.
16
16
  - **Zero configuration — even the template** — A folder of docs is a complete project. Navigation is inferred from files, search works in dev and production with no hosted service, and theming is a handful of tokens.
17
17
  - **Type-safe to the core** — `blume.config.ts` and every `meta.ts` are real TypeScript, validated by a schema and authored with `defineConfig` and `defineMeta`. Your editor autocompletes options and catches mistakes before a build.
18
18
 
19
19
  ## Quickstart
20
20
 
21
- Blume needs **Node.js 22.12 or newer**. From an empty or existing project:
21
+ Blume needs **Node.js 22.12 or newer**. From an empty folder:
22
22
 
23
23
  ```bash
24
- npm i blume # install the package
25
- blume init # scaffold: docs/index.mdx + blume.config.ts
26
- blume dev # dev server with hot reload
27
- blume build # static HTML to dist/, with a local search index
24
+ npx blume init # scaffold docs/index.mdx, blume.config.ts, and package.json scripts, then install
25
+ npm run dev # dev server with hot reload
26
+ npm run build # static HTML to dist/, with a local search index
28
27
  ```
29
28
 
30
- Blume works with any package manager and never requires you to set up Astro or Tailwind yourself.
29
+ In a project that already has a `package.json`, `blume init` leaves it alone: add `"dev": "blume dev"` and `"build": "blume build"` to its scripts, or run `npx blume dev`. Blume works with any package manager and never requires you to set up Astro or Tailwind yourself.
31
30
 
32
31
  ### Writing a page
33
32
 
@@ -48,11 +47,25 @@ Blume ships callouts, cards, tabs, steps, and more.
48
47
 
49
48
  Navigation, search, and page metadata are inferred from your files as you add them.
50
49
 
50
+ ## Upgrading from Blume 1
51
+
52
+ Blume 2 changes configuration, not content: search, deployment, content sources, API references, analytics, and the assistant's model backend become adapters imported from `blume/*` subpaths (`search: algolia({ … })` from `blume/search`), Ask AI is renamed the assistant (`ai.ask` becomes `ai.assistant`), the machine-readable settings move from `ai` to `agents`, and `components.ts` entries must be static. From the folder with `blume.config.ts`, run:
53
+
54
+ ```bash
55
+ npx blume@latest upgrade
56
+ ```
57
+
58
+ It bumps `blume` in `package.json`, installs, and lists every config change still needed with its file, line, and replacement (plus `package.json` scripts that pass removed `blume build` flags, and pages whose frontmatter sets a removed field), exiting non-zero until none are left — rerun it after each round of fixes. (`--codex` or `--claude` hands that list to an agent CLI from a terminal.) When you are the agent doing the upgrade, work from that list and the upgrade guide, `docs/03-upgrading.mdx` in the installed package, which has before-and-after examples for every change. Keep the site's behavior the same, and verify with `blume doctor` and `blume build`.
59
+
60
+ ## Migrating from another framework
61
+
62
+ To move a Mintlify, Fumadocs, Docusaurus, Starlight, or Nextra site to Blume, the user runs `npx blume migrate [source] --codex` (or `--claude`) from that project, which opens an agent on the `blume-migrate` skill. When you are that agent, or the user asks you to migrate directly, follow `skills/blume-migrate/SKILL.md` in the installed package instead of this file.
63
+
51
64
  ## What's included
52
65
 
53
66
  - **Components** — callouts, cards, steps, tabs, accordions, badges, file trees, and parameter tables, usable in MDX with no imports.
54
- - **Local search** — Orama in dev and production; Pagefind is one flag away for large sites. No hosted index.
55
- - **AI** — `llms.txt`, raw Markdown URLs, a JSON docs API with an OpenAPI description, Copy as Markdown, Open in chat, an Ask AI assistant, and an MCP server endpoint served by the docs site itself.
67
+ - **Local search** — Orama in dev and production, with no hosted index; Pagefind, Algolia, and other backends are one adapter away (`search: pagefind()` from `blume/search`).
68
+ - **AI** — `llms.txt`, raw Markdown URLs, a JSON docs API with an OpenAPI description, Copy as Markdown, Open in chat, an in-page assistant, and an MCP server endpoint served by the docs site itself.
56
69
  - **Navigation** — inferred from files, refined with `meta.ts` or config.
57
70
  - **SEO** — metadata, Open Graph images, RSS feeds, and JSON-LD.
58
71
  - **Customization** — component overrides, React islands, custom pages, theme tokens, and a source-component registry via `blume add`.
@@ -72,4 +85,4 @@ This is a high-level overview. For complete, authoritative docs — configuratio
72
85
  node -e "console.log(require.resolve('blume/package.json'))"
73
86
  ```
74
87
 
75
- The docs sit in `docs/` next to that `package.json`. Start with `docs/index.mdx` (Introduction) and `docs/01-quickstart.mdx`, then browse the `configuration/`, `content/`, `reference/`, and `advanced/` sections for specifics.
88
+ The docs sit in `docs/` next to that `package.json`. Start with `docs/index.mdx` (Introduction) and `docs/01-quickstart.mdx`, then list the `docs/` directory: each section is a folder — configuration, content authoring, API references, discoverability (SEO and the agent-facing surface), the CLI, and advanced topics — so open the one that covers the task.
@@ -31,10 +31,10 @@ Throughout this skill (including the `references/` files), **`<skill>` means the
31
31
  2. **Inventory the repo** before changing anything: the config file(s), the content tree, the nav definition, snippets/partials/includes, static assets, OpenAPI/AsyncAPI specs and GraphQL schemas, redirects, i18n locales, custom components, and icon usage. Note what's declared vs. defaulted.
32
32
  3. **Write `blume.config.ts`** with `defineConfig` from `blume`. Map only declared fields (see the reference's mapping table); rely on defaults everywhere else. A minimal result is `defineConfig({ title: "…" })`.
33
33
  4. **Restructure content.** Choose `content.root` (default `docs`) — **detect where `.md`/`.mdx` actually live, don't assume a `docs/` folder.** Many repos keep content directly under an app dir (`apps/docs/api/`, `.../getting-started/`) with no `docs/` subfolder; when so, set `content.root` to that dir and scope `content.include` to the real content folders rather than leaving a bare `content.root: "."` that scans everything (see `references/monorepo.md` §1). Order with numeric prefixes (`01-intro.mdx`), group without a URL segment via `(group)/` folders, and add a `meta.ts` (`defineMeta`) only where filesystem order isn't enough. **A source that already declares per-folder navigation in a sidecar file — Fumadocs `meta.json`, Nextra `_meta.*` — _is_ that case: convert each one to a `meta.ts`, carrying over its title/icon/order/collapse, rather than dropping it and hoping filenames reproduce the intent. Filesystem inference is the fallback for folders that declare no per-folder nav, never a reason to discard one that does.** Reach for an explicit `navigation.sidebar` only when the source nav genuinely can't be expressed by files. **Reshaping into folder-per-tab moves URLs** — track every old→new path as you go; you'll turn them into `redirects` in step 5.
34
- 5. **Rewrite pages.** Map frontmatter to Blume's strict schema; convert callout JSX to `:::` directives — **directives (and math/mermaid/package-install fences) are MDX-only, so rename any `.md` page that needs them to `.mdx`**; rename components; inline snippets/partials (Blume has no import-based includes); fix asset paths; **rewrite internal links** to their new routes (including OpenAPI/GraphQL operation links — see the API-reference sections, their slugs differ from most sources); **add a `redirects` entry for every route you moved** in step 4; **convert every icon name to Lucide** (Blume is Lucide-only — no FontAwesome/Tabler). Remove any duplicated H1 in the body (`title` renders the H1; bodies start at `##`). **If the source has a hand-maintained changelog and the repo is open source on GitHub, offer to swap it for the `github-releases` source** (see "Changelogs" below) rather than porting the entries. For **Mintlify**, run the bundled codemod first — `node <skill>/scripts/mintlify-codemod.mjs --write <content-dir>` deterministically remaps icons and drops/renames unsupported frontmatter keys, and reports the rest (unknown icons, OpenAPI-stub flags) for you to finish by hand (see `references/mintlify.md`).
35
- 6. **Adopt `package.json`.** Repoint `dev`/`build`/`start` → `blume dev`/`blume build`/`blume preview`, remove the old framework's deps, add `blume`. A config-only source (e.g. a bare Mintlify `docs.json`) has no manifest — scaffold one. **In a pnpm workspace:** if `pnpm-workspace.yaml`/`.npmrc` sets `minimumReleaseAge`, add **only** `blume` to `minimumReleaseAgeExclude` (don't disable the guard) so the just-published version installs. **Always regenerate the lockfile in the same change:** after editing deps run a plain `pnpm install` (from the workspace root) and commit `pnpm-lock.yaml` alongside `package.json` — CI/Vercel use `--frozen-lockfile`, so a stale lockfile fails the build before it starts. **If the repo uses (or the user wants) [Ultracite](https://www.ultracite.ai) for formatting:** its oxfmt formatter mangles the `:::` directives you just wrote unless you ship the bundled `assets/oxfmt@0.55.0.patch` and register it under `patchedDependencies` — see `references/monorepo.md` §6. See `references/monorepo.md` §2–3.
34
+ 5. **Rewrite pages.** Map frontmatter to Blume's strict schema; convert callout JSX to `:::` directives — **directives (and math/mermaid/package-install fences) are MDX-only, so rename any `.md` page that needs them to `.mdx`**; rename components; turn snippets/partials into `<include>` statements or inline them (Blume has no import-based includes: `import Snippet from "…"` plus `<Snippet />` has to become one or the other); fix asset paths; **rewrite internal links** to their new routes (including OpenAPI/GraphQL operation links — see the API-reference sections, their slugs differ from most sources); **add a `redirects` entry for every route you moved** in step 4; **convert every icon name to Lucide** (Blume is Lucide-only — no FontAwesome/Tabler). Remove any duplicated H1 in the body (`title` renders the H1; bodies start at `##`). **If the source has a hand-maintained changelog and the repo is open source on GitHub, offer to swap it for the `github-releases` source** (see "Changelogs" below) rather than porting the entries. For **Mintlify**, run the bundled codemod first — `node <skill>/scripts/mintlify-codemod.mjs --write <content-dir>` deterministically remaps icons and drops/renames unsupported frontmatter keys, and reports the rest (unknown icons, OpenAPI-stub flags) for you to finish by hand (see `references/mintlify.md`).
35
+ 6. **Adopt `package.json`.** Repoint `dev`/`build`/`start` → `blume dev`/`blume build`/`blume preview`, remove the old framework's deps, add `blume`. A config-only source (e.g. a bare Mintlify `docs.json`) has no manifest — scaffold one. **In a pnpm workspace:** if `pnpm-workspace.yaml`/`.npmrc` sets `minimumReleaseAge`, add **only** `blume` to `minimumReleaseAgeExclude` (don't disable the guard) so the just-published version installs. **Always regenerate the lockfile in the same change:** after editing deps run a plain `pnpm install` (from the workspace root) and commit `pnpm-lock.yaml` alongside `package.json` — CI/Vercel use `--frozen-lockfile`, so a stale lockfile fails the build before it starts. **If the repo uses (or the user wants) [Ultracite](https://www.ultracite.ai) for formatting:** its oxfmt formatter mangles the `:::` directives you just wrote unless you ship the bundled `assets/oxfmt@0.67.0.patch` and register it under `patchedDependencies` — see `references/monorepo.md` §6. See `references/monorepo.md` §2–3.
36
36
  7. **Wire up the host repo & deploy (non-trivial repos).** For a monorepo on Vercel, emit the root-aware install/build recipe and `apps/docs/vercel.json`, and tell the user the two settings you can't commit (Vercel Root Directory, Node 22). If the workspace pins Vite and `blume build` crashes inside Astro/Vite, apply the pnpm-patch workaround. All copy-pasteable in `references/monorepo.md` §4–5.
37
- 8. **Verify.** Run `blume build --strict` (frontmatter schema, duplicate routes, config — **without `--strict` a build exits 0 despite content errors**, silently dropping invalid pages) and `blume validate --strict` (internal links, heading anchors, assets — the link checker lives in `validate`, not `build`), fix diagnostics, then `blume dev` for a visual pass. End with a written summary of what was migrated, dropped, and approximated — **and every repo-specific edit you made** (pnpm-workspace, vercel.json, config globs) with the reason, plus any manual step left to the user (the Astro patch, Vercel dashboard settings).
37
+ 8. **Verify.** Run `blume build` (frontmatter schema, duplicate routes, config — it fails on any error diagnostic by default; **never pass `--no-strict`**, which builds anyway and silently drops invalid pages) and `blume validate --strict` (internal links, heading anchors, assets — the link checker lives in `validate`, not `build`), fix diagnostics, then `blume dev` for a visual pass. End with a written summary of what was migrated, dropped, and approximated — **and every repo-specific edit you made** (pnpm-workspace, vercel.json, config globs) with the reason, plus any manual step left to the user (the Astro patch, Vercel dashboard settings).
38
38
 
39
39
  ## The Blume mental model
40
40
 
@@ -64,12 +64,13 @@ The single biggest shift for most sources — especially Mintlify — is that **
64
64
 
65
65
  `defineConfig({...})` — every field optional, all with defaults:
66
66
 
67
- - **Site:** `title`, `description`, `logo` (string SVG, or `{ image: string | { light, dark, alt }, text, href }`), `banner` (`{ content, link, dismissible, id }` — no color/type). A logo renders beside `title` in the header, so a **wordmark logo doubles the brand** ("Acme Acme") — set `text: ""` to render the mark alone. **Prefer the string form over `{ light, dark }`:** if you have the logo SVG locally and it's monochrome (solid black or white), rewrite its `fill`/`stroke` to `currentColor` and use `logo: "/logo.svg"` — it then inherits the theme's text color and adapts to light/dark automatically, so you don't need separate light/dark files.
67
+ - **Site:** `title`, `description`, `logo` (string SVG, or `{ image: string | { light, dark, alt }, text, href }`), `banner` (a string, or `{ content, link: { href, text }, dismissible, id }` — no color/type). A logo renders beside `title` in the header, so a **wordmark logo doubles the brand** ("Acme Acme") — set `text: ""` to render the mark alone. **Prefer the string form over `{ light, dark }`:** if you have the logo SVG locally and it's monochrome (solid black or white), rewrite its `fill`/`stroke` to `currentColor` and use `logo: "/logo.svg"` — it then inherits the theme's text color and adapts to light/dark automatically, so you don't need separate light/dark files.
68
68
  - **`theme`:** `accent` (a color string for both modes, or `{ light, dark }` per mode), `action` (color), `mode` (`light`/`dark`/`system`), `radius`, `fonts` (`{ body, display, mono }` — each a curated Google-font slug, a `{ name, provider?, weights? }` object for any Google/Fontsource/Bunny/Fontshare family, or `{ name, variants: [{ src, weight?, style? }] }` for local font files), `background` and `backgroundImage` (each a string, or `{ light, dark }` per mode). The old `accentDark`/`backgroundDark`/`backgroundImageDark` fields were **merged into these per-mode objects** — a bare string still applies to both modes, so only reach for `{ light, dark }` when the two modes differ. There is **no** `theme.strict` and **no** `theme.css` config field — custom CSS goes in a project-root **`theme.css` file** (auto-picked-up), and a source's "strict appearance" flags drop.
69
- - **`content`:** `root` (default `"docs"`, relative to the project dir where `blume` runs), `include`/`exclude` (arrays of globs **relative to `content.root`**; defaults `["**/*.{md,mdx}"]` / `["**/_*", "**/.*"]`), `sources` (staged sources: `filesystem`, `obsidian`, `github-releases`, `notion`, `sanity`, `mdx-remote`, `custom` — OpenAPI/GraphQL are **not** among these; they're the top-level `openapi`/`graphql` fields), `pages` (custom `.astro` dir), `defaultType`. When docs sit directly under the project dir (no `docs/` subfolder), set `root` there and **scope `include` to the real content folders** instead of scanning everything — `references/monorepo.md` §1.
69
+ - **`content`:** `root` (default `"docs"`, relative to the project dir where `blume` runs), `include`/`exclude` (arrays of globs **relative to `content.root`**; defaults `["**/*.{md,mdx}"]` / `["**/_*", "**/.*"]`), `sources` (an array of **adapters imported from `blume/sources`**: `filesystem({ root, include, exclude })`, `obsidian({ vault })`, `githubReleases({ owner, repo })`, `notion({ database })`, `sanity({ projectId, dataset, query })`, `contentful({ space, contentType })`, `payload({ url, collection })`, `strapi({ url, contentType })`, `mdxRemote({ github })`, `custom(source)`; every factory with an options object also takes `prefix` and `pollInterval`, while `custom(source)` takes a `ContentSource` instance that sets its own `prefix`. The 1.x `{ type: "…" }` objects were removed — rename `type` to the factory call and pass the other fields as its options — except `{ type: "custom", source }`, which becomes `custom(source)` with the instance as the only argument. `root`/`include`/`exclude` are shorthand for a single `filesystem()` and are **rejected beside `sources`** — move them into the `filesystem()` entry. OpenAPI/AsyncAPI/GraphQL are **not** among these; they're adapters in the top-level `reference` list), `pages` (custom `.astro` dir), `defaultType`. When docs sit directly under the project dir (no `docs/` subfolder), set `root` there and **scope `include` to the real content folders** instead of scanning everything — `references/monorepo.md` §1.
70
70
  - **`basePath`** (top-level): a site-wide mount point (e.g. `"/docs"`) prepended to **every** route while staying invisible to the sidebar (no wrapper group). This is the right target for a source that served all docs under a prefix (Docusaurus `routeBasePath`, a Fumadocs `baseUrl` of `/docs`) — distinct from a per-source `prefix` (which adds a nav group) and from `deployment.base` (host subdirectory).
71
71
  - **`navigation`:** `tabs`, `selectors`, `actions` and `cta` (header links and the one filled button), `featured` (links pinned above the sidebar on every route), `sidebar` (`{ display, items }` — `display` is the global render mode above; `items` is an explicit tree), `repo` (`true`/`false`, or an absolute GitHub URL for the header mark when the docs repo is private and `github` must stay unset). **Avoid an explicit `navigation.sidebar` unless you have to** — lean on the filesystem-derived sidebar. It only works when the file tree roughly matches the intended sidebar layout, so reshape folders to match first; reach for `sidebar.items` only for a shape files genuinely can't express (see "Config-declared nesting" above).
72
- - **`search`** (Orama default, Pagefind opt-in), **`ai`** (llms.txt, Ask AI, the MCP server), **`openapi`**, **`graphql`**, **`redirects`**, **`seo`**, **`markdown`**, **`analytics`**, **`deployment`**, **`i18n`**, **`toc`**, **`lastModified`**, **`github`** (`{ owner, repo, branch?, dir?, host?, api? }` — set `host` whenever the source's edit URL is on a GitHub Enterprise origin rather than `github.com`).
72
+ - **`search`** — an adapter imported from `blume/search`: `orama()` (default, so omit `search` entirely for it), `flexsearch()`, `pagefind()`, `algolia({ appId, apiKey, indexName })`, `oramaCloud({ endpoint, apiKey, indexId? })`, `typesense({ host, collection, apiKey })`, `mixedbread({ storeId })`, or `false` to disable. Pass the adapter directly (`search: algolia({…})`) or as `search: { provider, popular, indexing }` when you also set curated links or indexing options. **Blume 1.x's `search.provider` string and its `search.algolia`/`oramaCloud`/`typesense`/`mixedbread` credential blocks are gone** — when a source config (or an older `blume.config.ts`) has `provider: "algolia", algolia: { appId, indexName, searchApiKey }`, rewrite it as `search: algolia({ appId, indexName, apiKey: searchApiKey })` (the search-only key is now `apiKey` in every adapter that takes one; admin keys stay in env vars). **`ai`** (the assistant, Open in chat — `ai.assistant.provider` takes an **adapter descriptor** imported from `blume/ai`: `gateway({ model })` (the default, `openai/gpt-5.5`), `openrouter({ model, reasoning })`, `llmgateway({ model })`, `inkeep({ model })`, or `openaiCompatible({ baseUrl, name, model, apiKeyEnv })`. Each adapter owns `model`, `apiKeyEnv`, `headers`, `reasoning`, and a verbatim `providerOptions` passthrough (`headers` values are written into the generated route source as-is, so they are for non-secret static headers only — a bearer token or any other credential belongs in the env var `apiKeyEnv` names, never in `headers`); there are **no** flat `provider`/`model`/`apiKeyEnv`/`baseUrl`/`headers`/`reasoning` fields on `ai.assistant` — a source that configured an AI assistant that way (Blume < 2.0 included) maps onto one adapter call. `enabled`, `instructions`, `retrieval`, `suggestions`, `cors`, and `endpoint` sit on `ai.assistant` itself; there is **no** `ai.ask` — Blume 2.0.0 and earlier used that name, so an older `blume.config.ts` moves the whole block to `ai.assistant`), **`agents`** (llms.txt, the JSON API, the MCP server, published skills, discovery manifests, robots content signals), **`reference`** (a list of adapters imported from `blume/reference` — `openapi({ spec | sources, route, … })`, `asyncapi({ … })`, `graphql({ spec, endpoint, … })` — never the 1.x `openapi`/`asyncapi`/`graphql` blocks), **`redirects`**, **`seo`**, **`markdown`**, **`analytics`** (a list of adapters imported from `blume/analytics` — one factory per provider (`posthog({ key, host })`, `googleAnalytics({ id })`, `plausible({ domain, host })`, `mixpanel({ token, region })`, `segment({ key })`, …; the docs page lists them all), `vercel()`, and `script({ src | content, strategy, attributes })` for anything without one — never an object keyed by provider), **`deployment`**, **`i18n`**, **`toc`**, **`lastModified`**, **`github`** (`{ owner, repo, branch?, dir?, host?, api? }` — set `host` whenever the source's edit URL is on a GitHub Enterprise origin rather than `github.com`).
73
+ - **`deployment`** is a host adapter from `blume/deploy` — `vercel()`, `netlify()`, `cloudflare()`, or `node()` — or a plain `{ site, base }` for a static build on any host (the default is a static build). Naming a host adapter switches the build to **server output** on that host (pass `output: "static"` to stay static there); `site`, `base`, and `output` are the named options, and anything else is forwarded verbatim to the underlying `@astrojs/*` adapter. There is **no** `deployment.adapter` string and **no** `deployment.output` field: a source that needs server rendering (the assistant, the MCP server, Mixedbread search, the API playground proxy) gets `import { vercel } from "blume/deploy"` and `deployment: vercel()`; a static source gets nothing — unless it served its docs under a subpath, which becomes `deployment: { base: "/docs" }` (leave `site` unset; see below). Note that `cloudflare` and `vercel` are also exported from `blume/analytics` — alias one (`import { cloudflare as cloudflareDeploy } from "blume/deploy"`) when a config uses both.
73
74
  - **Don't set `deployment.site`.** Blume auto-fills it: the dev server's `localhost` URL in dev, and the deployment URL (`VERCEL_PROJECT_PRODUCTION_URL`/`VERCEL_URL`) on Vercel. Hardcoding it in `blume.config.ts` overrides that auto-detection and pins the wrong absolute URL (canonical links, sitemap, OG, llms.txt) everywhere but the one host you typed — so leave it unset even when a source config had a `url`/`site` field. (Sitemap still generates in production because the deploy URL is present there.)
74
75
  - **Favicon is a filename convention, not config.** Drop `icon.{svg,png,ico}` or `favicon.{svg,png,ico}` (and `apple-icon.png`) in the project root or `public/` — Blume auto-detects it. There is **no** `favicon` config field. A source favicon given as `{ light, dark }` maps to a filename pair: copy the light file to a conventional name (e.g. `public/icon.png`) and the dark file to its `-dark` sibling — same directory and extension, `-dark` before the extension (`public/icon-dark.png`). If the two files have different formats, convert one so the extensions match; only an exact sibling of the resolved icon is picked up.
75
76
 
@@ -86,7 +87,6 @@ Blume resolves **bare kebab-case [Lucide](https://lucide.dev) names** everywhere
86
87
  title: Install # renders as the page H1 — remove any duplicate H1 in the body
87
88
  description: Install Blume and scaffold your first project.
88
89
  type: doc # doc (default) | blog | changelog | api
89
- icon: download # a Lucide name
90
90
  sidebar:
91
91
  label: Install # overrides title in the sidebar
92
92
  order: 2
@@ -120,43 +120,44 @@ Also valid: `date`/`authors` (blog/changelog feeds), `changelog` (changelog meta
120
120
 
121
121
  ### OpenAPI
122
122
 
123
- `openapi: { enabled: true, sources: [{ spec, label?, route? }] }` generates **one real page per operation** — with routing, sidebar, search, and OG images for free. **The reference does not get a header tab automatically** — add a `navigation.tabs` entry pointing at the reference's `route` (reference routes are valid tab targets) or the API reference is unreachable from the header. **Never hand-migrate generated API-reference pages** (per-endpoint stub pages in the source): delete them and point `openapi.sources` at the spec. (`renderer: "scalar"` keeps the Scalar embed instead; AsyncAPI uses the same embed.)
123
+ `reference: [openapi({ sources: [{ spec, label?, route? }] })]` — the `openapi()` adapter imported from `blume/reference` (`spec` is the single-source shorthand) — generates **one real page per operation** — with routing, sidebar, search, and OG images for free. **The reference does not get a header tab automatically** — add a `navigation.tabs` entry pointing at the adapter's `route` (reference routes are valid tab targets) or the API reference is unreachable from the header. **Never hand-migrate generated API-reference pages** (per-endpoint stub pages in the source): delete them and point `openapi()` at the spec. To keep a source's **Scalar embed** instead, list `scalar({ spec, theme?, …scalarOptions })` (also from `blume/reference`) in `reference` in place of `openapi()`: it renders an OpenAPI or AsyncAPI document as one embedded page per source, forwards every key it doesn't name verbatim to Scalar, and doesn't take the native display options (`codeSamples`, `expandSchemas`, `playground`). There is **no** `renderer` option on `openapi()`/`asyncapi()` — it fails validation. **Blume 1.x's top-level `openapi`/`asyncapi`/`graphql` blocks are gone** — when a source config (or an older `blume.config.ts`) has `openapi: { enabled: true, ... }`, rewrite it as an entry in `reference` and drop `enabled`; a 1.x block with `renderer: "scalar"` becomes its own `scalar({ … })` entry instead, keeping the block's `route`, `sources`, and `noindex`, with its `theme` and the keys of its `scalar: { … }` object passed straight to `scalar()` (`scalar({ spec, theme: "purple", localization })`).
124
124
 
125
125
  - **Vendor the spec by default.** A remote `spec:` URL makes every build depend on fetching it at build time — a single point of failure in CI, offline, or behind a proxy, and a failed fetch skips the whole reference. Prefer committing the spec into the repo (`openapi/<name>.json`) and pointing `spec` at the local path; if you keep the URL, say so and consider a `prebuild` step that refreshes the local copy with a fallback.
126
126
  - **Operation routes have their own slug scheme** — `<route>/<slugified-tag>/<slugified-operationId>` (e.g. tag `Models`, id `listModels` → `/api-reference/models/listmodels`). This rarely matches the source's endpoint links (Mintlify/others kebab-case differently), so **rewrite every inbound link to an operation**. `blume validate` resolves operation pages like any other route, so it catches the ones you miss.
127
- - **Keep hand-written conceptual pages.** Sources often pair a written "Introduction/Authentication" page with the endpoint group in the same tab. A normal content page placed under the openapi `route` merges into the reference tab's sidebar — so keep those (auth, errors, rate limits) and delete only the per-endpoint stubs.
127
+ - **Keep hand-written conceptual pages.** Sources often pair a written "Introduction/Authentication" page with the endpoint group in the same tab. A normal content page placed under the `openapi()` adapter's `route` merges into the reference tab's sidebar — so keep those (auth, errors, rate limits) and delete only the per-endpoint stubs.
128
128
 
129
129
  ### GraphQL
130
130
 
131
- `graphql: { enabled: true, spec, endpoint? }` is the GraphQL counterpart: Blume lowers a schema — SDL text or an introspection JSON result, local path or URL — into **one real page per root field** (grouped as Queries/Mutations/Subscriptions) plus **one page per named type** (Objects, Input Objects, Enums, Interfaces, Unions, custom Scalars). Every OpenAPI rule above carries over: never hand-migrate a source's generated GraphQL reference pages (delete them and point `spec` at the schema), vendor a remote schema locally, keep hand-written conceptual pages under the `route` (default `/graphql`), add the `navigation.tabs` entry, and rewrite inbound links — routes are `<route>/<slugified-group>/<slugified-name>` (e.g. `/graphql/queries/pets`, `/graphql/objects/pet`), which `blume validate` resolves like any other page. Differences from the OpenAPI block:
131
+ `reference: [graphql({ spec, endpoint? })]` is the GraphQL counterpart: Blume lowers a schema — SDL text or an introspection JSON result, local path or URL — into **one real page per root field** (grouped as Queries/Mutations/Subscriptions) plus **one page per named type** (Objects, Input Objects, Enums, Interfaces, Unions, custom Scalars). Every OpenAPI rule above carries over: never hand-migrate a source's generated GraphQL reference pages (delete them and point `spec` at the schema), vendor a remote schema locally, keep hand-written conceptual pages under the `route` (default `/graphql`), add the `navigation.tabs` entry, and rewrite inbound links — routes are `<route>/<slugified-group>/<slugified-name>` (e.g. `/graphql/queries/pets`, `/graphql/objects/pet`), which `blume validate` resolves like any other page. Differences from the `openapi()` adapter:
132
132
 
133
- - **Set `endpoint` to the live GraphQL URL.** A schema, unlike an OpenAPI document, names no server — `endpoint` is what the Try It playground and code samples target (without it they render a placeholder URL, and a `playground.proxy: true` block warns at build time because the proxy has no origin to allow). Multiple schemas use `sources: [{ spec, endpoint?, label?, route? }]`; a per-source `endpoint` overrides the block-level one.
134
- - **No `renderer`/`scalar`/`theme` opt-outs** — the reference is always Blume-rendered (the Scalar embed reads OpenAPI documents only). A source's GraphQL playground/explorer embed (GraphiQL, Apollo Explorer) has no direct equivalent beyond the built-in Try It panel; report anything it did that the panel doesn't.
133
+ - **Set `endpoint` to the live GraphQL URL.** A schema, unlike an OpenAPI document, names no server — `endpoint` is what the Try It playground and code samples target (without it they render a placeholder URL, and `playground: { proxy: true }` warns at build time because the proxy has no origin to allow). Multiple schemas use `sources: [{ spec, endpoint?, label?, route? }]`; a per-source `endpoint` overrides the adapter-level one.
134
+ - **No Scalar embed** — there is no `scalar()` counterpart for a GraphQL schema (and `graphql()` takes no `expandSchemas`); the reference is always Blume-rendered (the Scalar embed reads OpenAPI and AsyncAPI documents only). A source's GraphQL playground/explorer embed (GraphiQL, Apollo Explorer) has no direct equivalent beyond the built-in Try It panel; report anything it did that the panel doesn't.
135
135
  - **Only SDL and introspection JSON are accepted.** A source that builds its schema programmatically (a `GraphQLSchema` instance in code) must be printed to SDL (`printSchema` from `graphql`) and committed; report that conversion.
136
136
 
137
137
  ### Changelogs
138
138
 
139
- If the source ships a **hand-maintained changelog** (a `changelog.mdx`, a folder of dated entries, Mintlify `<Update>` blocks) **and the project is open source on GitHub**, offer to replace it with the **`github-releases`** content source — release notes become the changelog automatically, with no files to maintain. It's an offer, not an automatic rewrite: some teams keep a curated changelog that doesn't map 1:1 to GitHub releases, so confirm the release notes are the source of truth before deleting their pages.
139
+ If the source ships a **hand-maintained changelog** (a `changelog.mdx`, a folder of dated entries, Mintlify `<Update>` blocks) **and the project is open source on GitHub**, offer to replace it with the **`githubReleases()`** content source — release notes become the changelog automatically, with no files to maintain. It's an offer, not an automatic rewrite: some teams keep a curated changelog that doesn't map 1:1 to GitHub releases, so confirm the release notes are the source of truth before deleting their pages.
140
140
 
141
- Add it under `content.sources` alongside the filesystem source:
141
+ Add it under `content.sources` alongside the filesystem source (both imported from `blume/sources`; with `sources` present, the content root moves into `filesystem()`):
142
142
 
143
143
  ```ts
144
+ import { filesystem, githubReleases } from "blume/sources";
145
+
144
146
  content: {
145
147
  sources: [
146
- { include: ["docs/**/*.mdx"], root: ".", type: "filesystem" },
147
- {
148
+ filesystem({ include: ["docs/**/*.mdx"], root: "." }),
149
+ githubReleases({
148
150
  owner: "haydenbleasel",
149
151
  repo: "ultracite",
150
152
  prefix: "changelog",
151
- type: "github-releases",
152
- },
153
+ }),
153
154
  ],
154
155
  },
155
156
  ```
156
157
 
157
158
  - Each release materializes as a `type: changelog` page under `/<prefix>/` (`prefix: "changelog"` → `/changelog/…`); omit `prefix` to mount at the root.
158
159
  - Optional fields: `limit` (cap materialized releases, newest-first, default 100), `prereleases` (include prereleases), `drafts` (include drafts — needs a token with repo write access), `pollInterval` (dev polling seconds; omit to freeze for the session).
159
- - A **private** repo reads a token from `GITHUB_TOKEN`; it is never inlined in config. A public repo needs no token.
160
+ - A **private** repo reads a token from `GITHUB_TOKEN`; it is never inlined in config. The adapter declares it, so `blume dev`/`build` warn when it is unset; a public repo still works without it.
160
161
  - **Delete the old changelog pages** once the source is wired (and add `redirects` from their old routes to the new `/<prefix>/…` slugs). Pin a header/sidebar link with `navigation.featured` if the source had one.
161
162
 
162
163
  ### Redirects are static
@@ -165,7 +166,7 @@ A `redirects: [{ from, to, status? }]` array **in `blume.config.ts`** maps old U
165
166
 
166
167
  ## Verification & reporting
167
168
 
168
- 1. Run **`blume build --strict`** — it validates the frontmatter schema, duplicate routes, and config, and `--strict` makes diagnostics fail the build (without it, `blume build` **exits 0 despite content errors** and silently drops invalid pages). Then run **`blume validate --strict`** — links, heading anchors, and assets live here, not in `build` (add `--external` to also check outbound HTTP links). OpenAPI operation pages are real routes to `validate`, so dead links to them are caught too. Iterate until both are clean.
169
+ 1. Run **`blume build`** — it validates the frontmatter schema, duplicate routes, and config, and fails on any error diagnostic by default (**don't pass `--no-strict`**: that builds anyway and silently drops invalid pages). Then run **`blume validate --strict`** — links, heading anchors, and assets live here, not in `build` (add `--external` to also check outbound HTTP links). OpenAPI operation pages are real routes to `validate`, so dead links to them are caught too. Iterate until both are clean.
169
170
  2. Run `blume dev` and review the site visually — nav structure, tabs, theme, rendered components.
170
171
  3. **Write a migration summary** covering: what was migrated (config, N pages, nav, API references), what was **dropped** (navbar CTAs, footers, custom theming, dynamic redirects, unmappable icons, unsupported components), and suggested follow-ups (`blume eject` for full control, `blume add` to vendor a component for customization).
171
172
 
@@ -178,4 +179,4 @@ The mapping details live in `references/`: one file per source framework (`mintl
178
179
  - `content/meta.mdx` — `meta.ts` and display modes.
179
180
  - `content/syntax.mdx` — directives, code features, math.
180
181
  - `content/components.mdx` — the component library and APIs.
181
- - `reference/frontmatter.mdx` — the strict page schema.
182
+ - `content/frontmatter.mdx` — the strict page schema.