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,357 @@
1
+ ---
2
+ title: Assistant
3
+ description: An in-page assistant grounded in your docs — suggested questions, custom instructions, retrieval sizing, provider adapters from the Vercel AI Gateway to any OpenAI-compatible endpoint, and the server output it needs.
4
+ ---
5
+
6
+ Add an assistant that answers reader questions in an in-page chat panel, backed by a streaming server endpoint and the [AI SDK](https://ai-sdk.dev). It's opt-in, and static docs stay fully static until you turn it on:
7
+
8
+ ```ts blume.config.ts lineNumbers
9
+ ai: {
10
+ assistant: {
11
+ enabled: true,
12
+ },
13
+ }
14
+ ```
15
+
16
+ With nothing else written, answers stream through the [Vercel AI Gateway](#adapters) from `openai/gpt-5.5`. Pick a different model or provider with an [adapter](#adapters).
17
+
18
+ ## Suggested questions
19
+
20
+ Seed the empty state with a few starter prompts. Each renders as a clickable suggestion — click one to send it — with an optional [Lucide icon](/docs/content/components#icon) beside the label:
21
+
22
+ ```ts blume.config.ts lineNumbers
23
+ ai: {
24
+ assistant: {
25
+ enabled: true,
26
+ suggestions: [
27
+ { label: "What is Blume?", icon: "rocket" },
28
+ { label: "How do I write a docs page?", icon: "file-text" },
29
+ { label: "How do I configure the theme?", icon: "settings" },
30
+ ],
31
+ },
32
+ }
33
+ ```
34
+
35
+ `label` is the question that gets asked; `icon` is optional. Leave `suggestions` unset (or empty) and the panel opens to a plain input.
36
+
37
+ ## Custom instructions
38
+
39
+ Add your own system-prompt text with `instructions` — identity, language, tone, or anything else the assistant should keep in mind:
40
+
41
+ ```ts blume.config.ts lineNumbers
42
+ ai: {
43
+ assistant: {
44
+ enabled: true,
45
+ instructions:
46
+ "You are Bloomy, the Acme docs assistant. Answer in the language the question was asked in, and keep answers under three paragraphs.",
47
+ },
48
+ }
49
+ ```
50
+
51
+ Your text is **appended to** the built-in instructions rather than replacing them: the built-in part carries the [grounding](#grounding) contract — answer only from the retrieved pages, cite them as Markdown links — that the chat panel's citations depend on, so it stays intact whatever you add.
52
+
53
+ ## Grounding
54
+
55
+ The assistant is **grounded in your docs**. For each question it retrieves the most relevant pages — using the same lexical [Orama](/docs/configuration/search) index that powers on-page search — and injects them into the model's system prompt, so answers come from your content instead of the model's own knowledge. The assistant is told to answer only from the retrieved pages, to say when something isn't covered, and to cite the pages it drew from.
56
+
57
+ The page the reader is currently on is added to the context first and used to scope retrieval to that page's language, so answers stay relevant to where they are in the docs. Retrieval runs at request time from a snapshot baked into the build, so it works regardless of your [search](/docs/configuration/search) provider — even with `search: false` — and needs no configuration.
58
+
59
+ Grounding is on for every adapter except **[Inkeep](#inkeep)**, which runs its own retrieval over the content you've indexed in its dashboard.
60
+
61
+ ## Retrieval size
62
+
63
+ How much documentation a question carries is the biggest lever on how long the reader waits for the first word: the model reads every injected character before it emits a token. On a hosted frontier model that's invisible, but on a self-hosted backend it dominates. `retrieval` sizes it:
64
+
65
+ ```ts blume.config.ts lineNumbers
66
+ ai: {
67
+ assistant: {
68
+ enabled: true,
69
+ retrieval: {
70
+ maxResults: 3, // fewer pages retrieved per question
71
+ excerptChars: 1200, // shorter excerpt from each one
72
+ contextBudget: 3000, // smaller total injection
73
+ },
74
+ },
75
+ }
76
+ ```
77
+
78
+ | Option | Default | Description |
79
+ | --------------- | ------- | ----------------------------------------------- |
80
+ | `maxResults` | `6` | Documents retrieved per question. |
81
+ | `excerptChars` | `2000` | Characters kept from each retrieved page. |
82
+ | `contextBudget` | `10000` | Total injected characters, across all excerpts. |
83
+
84
+ The three aren't interchangeable. `contextBudget` caps the whole injection, `excerptChars` decides how deep into a single long page its excerpt reaches — raise it when one page holds the whole answer and the excerpt cuts it off — and `maxResults` caps how many pages retrieval adds. The page the reader is viewing is injected on top of the retrieved ones, so an answer can cite up to one page more than `maxResults`.
85
+
86
+ The defaults suit a hosted model. Lower them when you're serving from your own hardware and time-to-first-token matters more than recall; answers stay grounded either way, and the assistant is told to say when something isn't covered rather than fill the gap.
87
+
88
+ ## External endpoint
89
+
90
+ Already have an API backend for AI? Point the panel at it and keep the docs build static:
91
+
92
+ ```ts blume.config.ts lineNumbers
93
+ ai: {
94
+ assistant: {
95
+ enabled: true,
96
+ endpoint: "https://api.example.com/v1/docs/ask",
97
+ },
98
+ }
99
+ ```
100
+
101
+ Blume sends the same `POST` body as its built-in route:
102
+
103
+ ```json
104
+ {
105
+ "messages": [{ "role": "user", "content": "How do I deploy?" }],
106
+ "page": { "path": "/deployment" }
107
+ }
108
+ ```
109
+
110
+ Return a successful response whose body is a plain UTF-8 text stream. If the endpoint is on another origin, allow the docs origin with CORS: accept `OPTIONS` and `POST`, permit the `content-type` request header, and return the CORS headers on both the preflight and streamed response. With `endpoint` set, Blume generates the chat UI but no server route, grounding snapshot, provider dependency, or provider-secret warning; your backend owns retrieval, authentication, rate limiting, model access, and citations. An adapter set alongside it is ignored.
111
+
112
+ ## Cross-origin callers
113
+
114
+ The generated endpoint answers the in-page assistant on its own origin. To call it from another site as well — a marketing page with an ask box, say — list that site's origin in `cors`:
115
+
116
+ ```ts blume.config.ts lineNumbers
117
+ ai: {
118
+ assistant: {
119
+ enabled: true,
120
+ cors: ["https://www.example.com"],
121
+ },
122
+ }
123
+ ```
124
+
125
+ The route then answers the browser's `OPTIONS` preflight and names a listed origin on every response — the streamed answer and the error statuses alike, so the caller can tell a rejected body from a provider failure. Origins that aren't listed get no header and stay subject to the browser's same-origin rule. Each entry is reduced to its origin, so `https://www.example.com/docs/` and `https://www.example.com` mean the same thing. To let any page call the route, list `"*"` instead of origins.
126
+
127
+ The caller sends the same `POST` body the [external endpoint](#external-endpoint) contract describes and reads back the same text stream. Send it as JSON with a `content-type: application/json` header:
128
+
129
+ ```ts
130
+ const response = await fetch("https://docs.example.com/api/ask", {
131
+ body: JSON.stringify({
132
+ messages: [{ role: "user", content: "How do I deploy?" }],
133
+ }),
134
+ headers: { "content-type": "application/json" },
135
+ method: "POST",
136
+ });
137
+ ```
138
+
139
+ The content type matters: Astro's cross-site request check rejects a cross-origin `POST` that has no content type, or a form-like one such as `text/plain`, with a 403 before the route runs, and that response carries no CORS headers, so the browser reports it as a network error rather than a status. The preflight allows whatever request headers the caller asks for, so a fetch wrapper that adds its own headers needs no extra configuration.
140
+
141
+ `cors` only affects the generated route; with an external `endpoint`, CORS is that backend's job, and setting both is a config error. The endpoint stays unauthenticated either way, so the [rate limiting](#rate-limiting) advice applies to cross-origin traffic too.
142
+
143
+ ## Server output required
144
+
145
+ Blume's built-in assistant backend is a server route (`POST /api/ask`), so it can't run on a static build. Name a host adapter from `blume/deploy` to switch to server output:
146
+
147
+ ```ts blume.config.ts lineNumbers
148
+ import { vercel } from "blume/deploy";
149
+
150
+ export default defineConfig({
151
+ deployment: vercel(),
152
+ });
153
+ ```
154
+
155
+ A static build with the assistant enabled and no external `endpoint` fails fast with a message telling you to set a host adapter. See [Deployment](/docs/deployment) for the adapters.
156
+
157
+ ## Adapters
158
+
159
+ `provider` picks the backend that answers. Its value is an **adapter**: a small function exported from `blume/ai` that takes that backend's own options and returns a plain descriptor Blume writes into the generated route. Each adapter owns its model, the env var its key is read from, how it maps [reasoning](#reasoning), and which provider SDK it needs — so there is no shared set of fields to reconcile across backends:
160
+
161
+ ```ts blume.config.ts lineNumbers
162
+ import { defineConfig } from "blume";
163
+ import { openrouter } from "blume/ai";
164
+
165
+ export default defineConfig({
166
+ ai: {
167
+ assistant: {
168
+ enabled: true,
169
+ provider: openrouter({ model: "anthropic/claude-sonnet-4-5" }),
170
+ },
171
+ },
172
+ });
173
+ ```
174
+
175
+ | Adapter | Answers with | API key env var | SDK to install |
176
+ | --- | --- | --- | --- |
177
+ | [`gateway()`](#vercel-ai-gateway) (default) | a `provider/model` string via the Vercel AI Gateway | `AI_GATEWAY_API_KEY` | none — ships with Blume |
178
+ | [`openrouter()`](#openrouter) | any [OpenRouter](https://openrouter.ai) model | `OPENROUTER_API_KEY` | `@openrouter/ai-sdk-provider` |
179
+ | [`llmgateway()`](#llmgateway) | any [LLMGateway](https://llmgateway.io) model | `LLMGATEWAY_API_KEY` | `@ai-sdk/openai-compatible` |
180
+ | [`inkeep()`](#inkeep) | an [Inkeep](https://inkeep.com) QA model | `INKEEP_API_KEY` | `@ai-sdk/openai-compatible` |
181
+ | [`openaiCompatible()`](#openai-compatible-endpoints) | whatever your endpoint serves | the `apiKeyEnv` you name | `@ai-sdk/openai-compatible` |
182
+
183
+ The SDKs are optional peer dependencies, so add the one your adapter needs to your project (`npm install @openrouter/ai-sdk-provider`, say). If it's missing, `blume build` stops before Vite runs, naming the package and the command that installs it, and [`blume doctor`](/docs/cli/doctor) reports it too.
184
+
185
+ The descriptor an adapter returns is plain data — its kind, its options, the env vars it reads, and the SDK it needs — so the generated route (and the [ejected](/docs/configuration/customization#eject) one) inlines it as literals and imports the provider SDK by name. Nothing reads `blume.config.ts` at request time, and no secret is ever written into a route: adapters take the **name** of the env var holding the key, and the route reads the value through Astro's [`getSecret()`](https://docs.astro.build/en/guides/environment-variables/#retrieving-secrets-programmatically), so each deployment adapter supplies it its own way — environment variables on Node, Vercel, and Netlify, and the Worker's [bindings](https://docs.astro.build/en/guides/integrations-guide/cloudflare/#environment-variables-and-secrets) on Cloudflare.
186
+
187
+ ### Vercel AI Gateway
188
+
189
+ The default. `model` is a `provider/model` string, so you switch models by changing it (`openai/gpt-5.5`, `anthropic/claude-sonnet-4-5`, and so on) with no provider SDK to install. The gateway reads `AI_GATEWAY_API_KEY` from your environment and is wired up automatically when you deploy on Vercel, where it can also authenticate with the deployment's OIDC token:
190
+
191
+ ```ts blume.config.ts lineNumbers
192
+ import { defineConfig } from "blume";
193
+ import { gateway } from "blume/ai";
194
+
195
+ export default defineConfig({
196
+ ai: {
197
+ assistant: {
198
+ enabled: true,
199
+ provider: gateway({ model: "anthropic/claude-sonnet-4-5" }),
200
+ },
201
+ },
202
+ });
203
+ ```
204
+
205
+ Leaving `provider` unset is the same as `gateway({ model: "openai/gpt-5.5" })`.
206
+
207
+ ### OpenRouter
208
+
209
+ Any model on [OpenRouter](https://openrouter.ai), through its dedicated AI SDK provider:
210
+
211
+ ```ts blume.config.ts lineNumbers
212
+ import { defineConfig } from "blume";
213
+ import { openrouter } from "blume/ai";
214
+
215
+ export default defineConfig({
216
+ ai: {
217
+ assistant: {
218
+ enabled: true,
219
+ provider: openrouter({
220
+ model: "anthropic/claude-sonnet-4-5",
221
+ reasoning: "none",
222
+ }),
223
+ },
224
+ },
225
+ });
226
+ ```
227
+
228
+ ### LLMGateway
229
+
230
+ Any model on [LLMGateway](https://llmgateway.io), through its OpenAI-compatible endpoint:
231
+
232
+ ```ts blume.config.ts lineNumbers
233
+ import { defineConfig } from "blume";
234
+ import { llmgateway } from "blume/ai";
235
+
236
+ export default defineConfig({
237
+ ai: {
238
+ assistant: {
239
+ enabled: true,
240
+ provider: llmgateway({ model: "openai/gpt-5.5" }),
241
+ },
242
+ },
243
+ });
244
+ ```
245
+
246
+ `baseUrl` overrides the preset endpoint (`https://api.llmgateway.io/v1`) when you run LLMGateway yourself.
247
+
248
+ ### Inkeep
249
+
250
+ [Inkeep](https://inkeep.com) answers from the content you've indexed in the Inkeep dashboard — it runs its own retrieval — so Blume leaves it **ungrounded**: no snapshot of this site's pages is injected, and the [retrieval size](#retrieval-size) options don't apply. It has no reasoning control either, so the adapter takes no `reasoning`:
251
+
252
+ ```ts blume.config.ts lineNumbers
253
+ import { defineConfig } from "blume";
254
+ import { inkeep } from "blume/ai";
255
+
256
+ export default defineConfig({
257
+ ai: {
258
+ assistant: {
259
+ enabled: true,
260
+ provider: inkeep({ model: "inkeep-qa-expert" }),
261
+ },
262
+ },
263
+ });
264
+ ```
265
+
266
+ `baseUrl` overrides the preset endpoint (`https://api.inkeep.com/v1`).
267
+
268
+ ### OpenAI-compatible endpoints
269
+
270
+ Any endpoint that speaks the OpenAI API works through `openaiCompatible()` — supply its `baseUrl`, the `model` it serves, and the env var holding its key. A generic endpoint has no preset for any of these, so all three are required; `name` is the provider name the AI SDK reports and defaults to `openai-compatible`:
271
+
272
+ ```ts blume.config.ts lineNumbers
273
+ import { defineConfig } from "blume";
274
+ import { openaiCompatible } from "blume/ai";
275
+
276
+ export default defineConfig({
277
+ ai: {
278
+ assistant: {
279
+ enabled: true,
280
+ provider: openaiCompatible({
281
+ baseUrl: "https://my-gateway.example.com/v1",
282
+ apiKeyEnv: "MY_GATEWAY_API_KEY",
283
+ model: "gpt-4o",
284
+ name: "my-gateway",
285
+ }),
286
+ },
287
+ },
288
+ });
289
+ ```
290
+
291
+ ### Options every adapter takes
292
+
293
+ **`apiKeyEnv`** points an adapter at a different env var than its default — `gateway({ apiKeyEnv: "DOCS_GATEWAY_KEY" })` reads that variable instead of `AI_GATEWAY_API_KEY`, and the missing-secret warning at `blume dev`/`build` checks it too. Until the key is set, the deployed route answers `503` with a message naming the variable. The route reads a request body only up to 64 KB and answers anything larger with `413`.
294
+
295
+ **`headers`** sends static request headers with every call — a caller-identifying header for a shared backend, say, so its own observability or rate limiting can tell your docs apart from other traffic:
296
+
297
+ ```ts blume.config.ts lineNumbers
298
+ provider: openaiCompatible({
299
+ baseUrl: "https://llm.internal.example.com/v1",
300
+ apiKeyEnv: "INTERNAL_LLM_API_KEY",
301
+ model: "gpt-4o",
302
+ headers: { "X-Caller-Id": "docs" },
303
+ }),
304
+ ```
305
+
306
+ The values are written into the generated route as-is, so keep secrets in `apiKeyEnv` rather than in `headers`. The API key's `Authorization` header is applied first, so a custom header can't displace it.
307
+
308
+ **`providerOptions`** passes anything else straight through to the AI SDK's [`providerOptions`](https://ai-sdk.dev/docs/foundations/prompts#provider-options), in the SDK's own shape — keyed by provider, then by option — so a new model control never needs a Blume field of its own:
309
+
310
+ ```ts blume.config.ts lineNumbers
311
+ provider: gateway({
312
+ model: "openai/gpt-5.5",
313
+ providerOptions: { openai: { textVerbosity: "low" } },
314
+ }),
315
+ ```
316
+
317
+ Blume maps only the options it names (`model`, `reasoning`, `apiKeyEnv`, `headers`) and forwards `providerOptions` verbatim, so it has to be JSON — it's inlined into the route — and it has to use the key the underlying provider expects (`openai` for an OpenAI model behind the gateway, `openrouter` on OpenRouter). Enabling the assistant also turns on React for the in-page island — see [Customization](/docs/configuration/customization#interactive-islands).
318
+
319
+ ## Reasoning
320
+
321
+ Reasoning models think before they answer, and how much they do so by default varies by model. For grounded docs Q&A the retrieved excerpts carry the answer, so most of that thinking is latency the reader waits through. An adapter's `reasoning` option sets how much the model reasons: `"none"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, or `"xhigh"`:
322
+
323
+ ```ts blume.config.ts lineNumbers
324
+ provider: gateway({ model: "openai/gpt-5.5", reasoning: "none" }),
325
+ ```
326
+
327
+ Each adapter sends the level as its backend's own reasoning control, which is why it lives on the adapter rather than on `assistant`:
328
+
329
+ | Adapter | What the level becomes |
330
+ | --- | --- |
331
+ | `gateway()` | The AI SDK's [`reasoning`](https://ai-sdk.dev/docs/ai-sdk-core/reasoning) call option, which the gateway maps to the model's own setting — OpenAI's `reasoning_effort`, for example. |
332
+ | `openrouter()` | OpenRouter's `reasoning.effort`, set on the model. Its provider ignores the AI SDK's call option, so the level is placed where OpenRouter reads it. |
333
+ | `llmgateway()` | `reasoning_effort` in the request, through the AI SDK's call option. |
334
+ | `openaiCompatible()` | `reasoning_effort` in the request, so the endpoint has to accept that parameter. |
335
+ | `inkeep()` | Not available. Inkeep runs its own QA pipeline with no reasoning control, so the adapter has no `reasoning` option and setting one is a config error. |
336
+
337
+ The model has to support the level you pick: OpenAI rejects a level a model doesn't offer (`"none"` and `"xhigh"` exist only on some), so check the model's documentation before setting one. Leave it unset to keep the model's default. Like [retrieval size](#retrieval-size), it trades thoroughness for time-to-first-token, and answers stay grounded either way.
338
+
339
+ ## Analytics
340
+
341
+ With an [analytics provider](/docs/configuration/analytics) configured, the assistant reports its usage through the same `track()` the page feedback widget uses, so questions land next to your pageviews:
342
+
343
+ | Event | When | Properties |
344
+ | --- | --- | --- |
345
+ | `ask` | A question is sent | `path`, `questionChars` |
346
+ | `ask_answer` | The answer finishes streaming | `path`, `questionChars`, `ms`, `chars` |
347
+ | `ask_error` | The request fails, breaks, or comes back empty | `path`, `questionChars`, `ms`, `status` |
348
+
349
+ `path` is the page the reader asked from (the served pathname, so it matches the feedback widget and your pageviews under a `base`), `questionChars` the question's length, `ms` the time from sending the question to the last chunk, and `chars` the answer's length. `status` is the HTTP status: `0` when no response arrived at all (offline, DNS, CORS), and `200` when the response was fine but its stream broke mid-answer — how a provider or credential error surfaces, since the backend has already sent its headers — or delivered nothing. Clearing the conversation mid-answer reports neither outcome.
350
+
351
+ The question's text never reaches a provider: it is free-form reader input (pasted keys, error logs, names) that would breach most providers' terms and per-value size limits. It travels only on the `blume:track` DOM event, as `question` in `detail.props`, so a listener you write can forward it wherever you decide it belongs. A custom chat UI built on `useAssistant` from `blume/hooks` reports the same events. With no provider configured the built-in provider calls are no-ops, but the `blume:track` event still fires, so a custom integration listening for it receives them.
352
+
353
+ ## Rate limiting
354
+
355
+ The `POST /api/ask` endpoint is **unauthenticated** — it has to be, so the in-page assistant can call it. Blume validates each request — rejecting malformed bodies, capping it to 1–40 messages, and accepting only `user`/`assistant` roles so a caller can't inject their own system prompt and repurpose the route as a general LLM proxy — to bound how much a single call can spend against your model, but it can't stop someone from calling the endpoint repeatedly. If cost abuse is a concern, put the route behind a rate limiter — your host's (e.g. Vercel's) edge rate limiting, a middleware, or your model provider's per-key spend limits.
356
+
357
+ The endpoint is advertised in the [agent readability manifest](/docs/discoverability/agent-discovery#agent-readability) alongside the rest of the site's machine-readable surface.
@@ -24,7 +24,7 @@ Keys are the names you write in MDX (`<Callout>`, `<Pricing>`). Use the `.tsx` f
24
24
 
25
25
  ### Reference form
26
26
 
27
- Every override — in `mdx`, `layout`, or `islands` — accepts three forms:
27
+ Every override — in `mdx` or `layout` — accepts three forms:
28
28
 
29
29
  ```ts components.ts
30
30
  import { defineComponents } from "blume";
@@ -39,6 +39,8 @@ export default defineComponents({
39
39
  });
40
40
  ```
41
41
 
42
+ Blume reads `components.ts` statically — it never runs the file — so these three forms are the only ones it accepts. An inline function or expression, a component declared in the file itself, a spread, a computed key, or a `client` that isn't one of the mode strings below is a `BLUME_COMPONENTS_INVALID` error that names the entry: `blume dev` reports it in the terminal and the browser overlay, and `blume build` fails.
43
+
42
44
  The **descriptor** form adds a hydration mode so an interactive React/Vue/Svelte component ships its JavaScript and comes alive on the client. Without a `client` mode a framework component renders as static HTML — Blume prints a build warning when it spots one, since that's usually a mistake.
43
45
 
44
46
  | `client` | Hydrates |
@@ -49,7 +51,7 @@ The **descriptor** form adds a hydration mode so an interactive React/Vue/Svelte
49
51
  | `"media"` | When a `media` query matches (add `media: "(min-width: 40rem)"`) |
50
52
  | `"only"` | Client only, never server-rendered |
51
53
 
52
- For interactive components you use across many pages, the [`islands` group](/docs/content/islands#registering-islands-in-componentsts) is a shorthand for the descriptor form with `client: "visible"`.
54
+ An `mdx` entry with a `client` mode _is_ an island: it's available in every page and hydrates exactly like a component dropped in the [`islands/` folder](/docs/content/islands). The folder stays the zero-config path — reach for a `components.ts` entry when you want a different name than the file, a `media` query, or to keep islands beside your other overrides.
53
55
 
54
56
  ### Typing an override
55
57
 
@@ -88,8 +90,8 @@ Wired slots:
88
90
  | --- | --- | --- |
89
91
  | `Layout` | The entire page shell (`RootLayout`) | Everything the built-in layout receives, plus the `layout` map |
90
92
  | `Header` | The top navigation bar | `site`, `logo`, `navigation`, `route`, `searchEnabled`, … |
91
- | `Logo` | The brand link (mark + title) in the header | `site`, `logo` |
92
- | `Search` | The header search trigger + modal | `navigation`, `strings`, `locale`, `askEnabled` |
93
+ | `Logo` | The brand link (mark + title) in the header | `site`, `logo`, `locale` |
94
+ | `Search` | The header search trigger + modal | `navigation`, `strings`, `locale`, `assistantEnabled` |
93
95
  | `Sidebar` | The primary navigation tree | `items`, `currentRoute` |
94
96
  | `MobileNav` | The nav inside the mobile drawer (defaults to `Sidebar`) | `items`, `currentRoute` |
95
97
  | `Breadcrumbs` | The breadcrumb trail | `crumbs` |
@@ -126,7 +128,7 @@ See [Islands](/docs/content/islands) for hydration strategies and framework setu
126
128
 
127
129
  Add `.astro` files under your `pages/` folder to mount fully custom routes alongside your docs — a landing page, a pricing page, or a hand-built index. They keep their location, so relative imports and `getStaticPaths` work as usual, and they can read your config, navigation, and routes from the `blume:data` module.
128
130
 
129
- See [Custom Pages](/docs/advanced/custom-pages) for the full guide.
131
+ See [Custom pages](/docs/advanced/custom-pages) for the full guide.
130
132
 
131
133
  ## Registry
132
134
 
@@ -150,17 +152,17 @@ The copy imports the rest of the framework from `blume/*`, so it renders exactly
150
152
  Add any Astro integration from the top-level `integrations` array in `blume.config.ts`. Install the integration in your site first; Blume does not add it to the generated runtime's dependencies or manage its Astro compatibility.
151
153
 
152
154
  ```bash
153
- npm install @astrojs/sitemap
155
+ npm install @astrojs/partytown
154
156
  ```
155
157
 
156
158
  ```ts blume.config.ts lineNumbers
157
- import sitemap from "@astrojs/sitemap";
159
+ import partytown from "@astrojs/partytown";
158
160
  import { defineConfig } from "blume";
159
161
 
160
162
  export default defineConfig({
161
163
  integrations: [
162
- sitemap({
163
- filter: (page) => !page.includes("/drafts/"),
164
+ partytown({
165
+ config: { forward: ["dataLayer.push"] },
164
166
  }),
165
167
  ],
166
168
  });
@@ -177,11 +179,15 @@ The same integrations run in `blume dev` and `blume build`. Editing `blume.confi
177
179
  When you want full control, eject the generated runtime into a standalone Astro project:
178
180
 
179
181
  ```bash
180
- blume eject --yes
182
+ npx blume eject --yes
181
183
  ```
182
184
 
183
185
  Eject is a one-way step: the hidden `.blume/` runtime becomes a normal Astro app you own and can modify directly. The `blume` package stays importable, so you keep its components, theme, and Markdown processors.
184
186
 
187
+ Eject points your `package.json` scripts at `astro dev` and `astro build`, and adds the packages the Astro app imports by name — `astro`, `@tailwindcss/vite`, the search client, integrations, and adapter the config wires in, React when an island, example, or the assistant uses it, `ai` for the assistant route, and `epub-gen-memory` for EPUB export — at the ranges Blume itself uses. Run an install before `dev` or `build`; eject lists what it added. Every path in the ejected app is relative, so it builds from any checkout, CI included.
188
+
189
+ From then on, run the app through its own scripts (`npm run dev`, `npm run build`): `blume dev` and `blume build` stop in an ejected project and point you there. Running `blume eject` again refuses too, since it would overwrite your edits; pass `--force` to regenerate the app anyway.
190
+
185
191
  ### What eject keeps
186
192
 
187
193
  The ejected app's `build` script runs plain `astro build`, and the artifacts `blume build` layers on top — the search index (and a hosted provider's index sync), `llms.txt` and `llms-full.txt`, `sitemap.xml`, `robots.txt`, `agent-readability.json`, the `.well-known` discovery files, Agent Skills, and the platform `_redirects`/`_headers` files — are still produced: the Blume integration in the ejected `astro.config.mjs` writes them from Astro's `astro:build:done` hook, scanning the project (your `blume.config.ts` and content) the way the CLI did. What the ejected build does not do is the CLI's adapter post-processing: the Vercel and Cloudflare `Accept: text/markdown` routing splices, the Vercel function-bundle audit, and the `--analyze`/`--budget-*` gate.
@@ -21,8 +21,9 @@ export default defineConfig({
21
21
  A broader example touching the most common options (see each feature's guide for the rest):
22
22
 
23
23
  ```ts blume.config.ts lineNumbers
24
- import sitemap from "@astrojs/sitemap";
24
+ import partytown from "@astrojs/partytown";
25
25
  import { defineConfig } from "blume";
26
+ import { orama } from "blume/search";
26
27
 
27
28
  export default defineConfig({
28
29
  // Site
@@ -31,7 +32,7 @@ export default defineConfig({
31
32
  logo: "/logo.svg",
32
33
 
33
34
  // Astro integrations — installed and versioned by this site
34
- integrations: [sitemap()],
35
+ integrations: [partytown()],
35
36
 
36
37
  // Content
37
38
  content: {
@@ -45,19 +46,16 @@ export default defineConfig({
45
46
  mode: "system",
46
47
  },
47
48
 
48
- // Search — see the Search guide
49
- search: {
50
- provider: "orama",
51
- },
49
+ // Search — an adapter from "blume/search"; see the Search guide
50
+ search: orama(),
52
51
 
53
52
  // Markdown features
54
53
  markdown: {
55
54
  imageZoom: true,
55
+ externalLinks: false, // open https:// links in a new tab
56
56
  code: {
57
57
  icons: true, // language icon in the code-block header
58
58
  wrap: false, // wrap long lines instead of scrolling
59
- },
60
- codeBlocks: {
61
59
  theme: {
62
60
  light: "github-light", // bundled name or custom Shiki theme object
63
61
  dark: "github-dark",
@@ -65,8 +63,8 @@ export default defineConfig({
65
63
  },
66
64
  },
67
65
 
68
- // AI — llms.txt, MCP, the AI catalog; see the Discoverability section
69
- ai: {
66
+ // Agents — llms.txt, MCP, the AI catalog; see the Discoverability section
67
+ agents: {
70
68
  llmsTxt: true,
71
69
  // AI Catalog / ARD manifest at /.well-known/ai-catalog.json (needs deployment.site)
72
70
  catalog: true,
@@ -86,9 +84,8 @@ export default defineConfig({
86
84
  structuredData: true,
87
85
  },
88
86
 
89
- // Deployment — see the Deployment guide
87
+ // Deployment — a static build here; see the Deployment guide for host adapters
90
88
  deployment: {
91
- output: "static",
92
89
  site: "https://docs.example.com",
93
90
  },
94
91
  });
@@ -123,6 +120,8 @@ logo: {
123
120
 
124
121
  `image` takes the same value as the shorthand — a single path, or `{ light, dark, alt }` for separate light/dark artwork (raster images must live in `public/`).
125
122
 
123
+ `href` is a default-locale path like a tab path: on a [multi-locale site](/docs/content/i18n) the brand link moves into the reader's locale (`/` becomes `/en` under `/en/…`) whenever that locale serves the route, so clicking the logo doesn't leave the language they were reading. A route only the default locale serves — a [custom page](/docs/advanced/custom-pages) or the generated changelog index — keeps its own path instead of pointing at a localized URL that would 404. An absolute URL is used as-is.
124
+
126
125
  `text` controls the wordmark independently of the mark:
127
126
 
128
127
  - **Omit `text`** and the brand uses your site `title` (the default).
@@ -177,10 +176,10 @@ banner: "Docs are in beta — expect changes.",
177
176
 
178
177
  ```ts blume.config.ts lineNumbers
179
178
  banner: {
180
- content: "Blume v1 is here!",
181
- link: { text: "Read more", href: "/blog/v1" },
179
+ content: "Version 2.0 is here!",
180
+ link: { text: "Read the release notes", href: "/changelog" },
182
181
  dismissible: true,
183
- id: "v1",
182
+ id: "v2",
184
183
  },
185
184
  ```
186
185
 
@@ -198,9 +197,10 @@ content: {
198
197
 
199
198
  | Option | Default | Description |
200
199
  | --- | --- | --- |
201
- | `root` | `"docs"` | Folder Blume scans for content. |
202
- | `include` | `["**/*.{md,mdx}"]` | Globs that match content files. |
203
- | `exclude` | `["**/_*", "**/.*"]` | Globs to ignore (underscore- and dot-files). |
200
+ | `root` | `"docs"` | Folder Blume scans for content. Shorthand for a single `filesystem()` source; not allowed beside `sources`. |
201
+ | `include` | `["**/*.{md,mdx}"]` | Globs that match content files. Shorthand, like `root`. |
202
+ | `exclude` | `["**/_*", "**/.*"]` | Globs to ignore (underscore- and dot-files). Shorthand, like `root`. |
203
+ | `sources` | one `filesystem()` | Content source adapters from `blume/sources`, replacing the shorthand. See [Content sources](/docs/content/sources). |
204
204
  | `pages` | `"pages"` | Folder for custom `.astro` pages. |
205
205
  | `defaultType` | `"doc"` | Page `type` used when frontmatter omits it. |
206
206
  | `types` | `{}` | Per-type content definitions — custom frontmatter keys scoped to pages of one `type`. See [Frontmatter](#frontmatter). |
@@ -243,7 +243,7 @@ export default defineConfig({
243
243
  });
244
244
  ```
245
245
 
246
- Any [Standard Schema](https://standardschema.dev) library works — Zod (whichever version your project installs), Valibot, ArkType. Keys outside the extension stay strictly validated, so typo-catching is unchanged. See [Custom keys](/docs/reference/frontmatter#custom-keys) for the validation semantics.
246
+ Any [Standard Schema](https://standardschema.dev) library works — Zod (whichever version your project installs), Valibot, ArkType. Keys outside the extension stay strictly validated, so typo-catching is unchanged. See [Custom keys](/docs/content/frontmatter#custom-keys) for the validation semantics.
247
247
 
248
248
  Keys under `extend` apply site-wide. To require keys only on pages of one content type — an RFC's `status`, a runbook's `service` — declare them per type under `content.types` instead:
249
249
 
@@ -266,7 +266,7 @@ export default defineConfig({
266
266
  });
267
267
  ```
268
268
 
269
- A key can be declared site-wide or per-type, not both. See [Per-type keys](/docs/reference/frontmatter#per-type-keys) for how the scoping resolves.
269
+ A key can be declared site-wide or per-type, not both. See [Per-type keys](/docs/content/frontmatter#per-type-keys) for how the scoping resolves.
270
270
 
271
271
  `facets` names the custom keys whose values become filterable metadata: they ride along on search documents (`blume-search.json` and the MCP index), and the [MCP tools](/docs/discoverability/mcp) accept a `filters` input matching against them, so an agent can retrieve, say, only `enforced` RFCs in the `architecture` domain. Each facet must be a declared custom key — per-type or site-wide — and only string (or stringified number/boolean) values facet.
272
272
 
@@ -314,18 +314,17 @@ An instance reachable only over plain HTTP still renders its counts, but `GITHUB
314
314
 
315
315
  ## Last modified
316
316
 
317
- Show a "Last updated on …" line at the bottom of each page. Off by default; set `lastModified` to `true` to derive each page's date from its git history:
317
+ Show a "Last updated on …" line at the bottom of each page. Off by default; set `lastModified` to `"git"` to derive each page's date from its git history:
318
318
 
319
319
  ```ts blume.config.ts
320
- lastModified: true,
320
+ lastModified: "git",
321
321
  ```
322
322
 
323
323
  | Value | Description |
324
324
  | --- | --- |
325
325
  | `false` | Disabled (default). |
326
- | `true` | Read the date from git history (commit dates). |
327
- | `{ type: "git" }` | Same as `true`, written explicitly. |
328
- | `{ type: "frontmatter" }` | Never run git — use only the `lastModified` frontmatter field. |
326
+ | `"git"` | Read the date from git history (commit dates). |
327
+ | `"frontmatter"` | Never run git — use only the `lastModified` frontmatter field. |
329
328
 
330
329
  The git source reads the most recent commit that touched each file, so it works in any git repository — including monorepos — and needs the repo's history at build time. CI platforms usually check out a shallow clone, which silently drops most dates (the build warns with `BLUME_SHALLOW_GIT_HISTORY` when that happens): on Vercel, set the `VERCEL_DEEP_CLONE=true` environment variable; with `actions/checkout`, set `fetch-depth: 0`. A page's own `lastModified` frontmatter always wins, which is handy for pinning a date or for files that aren't committed yet:
331
330
 
@@ -365,9 +364,9 @@ dateFormat: { year: "numeric", month: "2-digit", day: "2-digit" },
365
364
  | `timeZone` | IANA time zone. Defaults to `UTC`, so a date reads the same regardless of where the site builds. |
366
365
  | `calendar`, `numberingSystem` | Calendar system (e.g. `"japanese"`) and numbering system (e.g. `"arab"`). |
367
366
 
368
- ## SEO and AI
367
+ ## SEO and agents
369
368
 
370
- Metadata, Open Graph images, RSS feeds, JSON-LD, the sitemap, and `robots.txt` live under `seo`; `llms.txt`, raw Markdown, the JSON API, and the MCP server live under `ai`. Both are covered page by page in the [Discoverability](/docs/discoverability) section, which treats search engines and AI agents as two audiences for the same machine-readable layer.
369
+ Metadata, Open Graph images, RSS feeds, JSON-LD, the sitemap, and `robots.txt` live under `seo`; `llms.txt`, raw Markdown, the JSON API, the MCP server, and the discovery manifests live under `agents`. Both are covered page by page in the [Discoverability](/docs/discoverability) section, which treats search engines and AI agents as two audiences for the same machine-readable layer. The reader-facing model features — the assistant and the Open in chat action — live under `ai`.
371
370
 
372
371
  ```ts blume.config.ts lineNumbers
373
372
  seo: {
@@ -409,6 +408,18 @@ export default defineConfig({
409
408
  });
410
409
  ```
411
410
 
411
+ ## Page feedback
412
+
413
+ Each docs page ends with a "Was this page helpful?" rating. It's on by default; set `feedback` to `false` to hide it everywhere:
414
+
415
+ ```ts blume.config.ts
416
+ export default defineConfig({
417
+ feedback: false,
418
+ });
419
+ ```
420
+
421
+ A reader's answer is sent as a `feedback` [custom event](/docs/configuration/analytics#custom-events) — with `helpful` (`"yes"` or `"no"`), `path`, and `title` — through every configured analytics adapter that has an event API, and as a `blume:track` event on `window`. Without an analytics adapter, the answer isn't recorded anywhere. The question and thank-you text are UI strings you can translate with [`i18n.ui`](/docs/content/i18n#translated-ui).
422
+
412
423
  ## Feature options
413
424
 
414
425
  Each of these has its own guide. The config field is the entry point:
@@ -419,13 +430,21 @@ Each of these has its own guide. The config field is the entry point:
419
430
  | `navigation` | Explicit sidebar and header tabs | [Navigation](/docs/content/navigation) |
420
431
  | `search` | Provider (Orama, Pagefind, Algolia, and more) and indexing | [Search](/docs/configuration/search) |
421
432
  | `markdown` | Markdown rendering options — code blocks, heading anchors, image zoom | [Syntax](/docs/content/syntax) |
422
- | `ai` | `llms.txt`, Markdown mirrors, the JSON API, and the hosted MCP server for coding agents | [SEO and AEO](/docs/discoverability) |
423
- | `ai.ask` | The in-page Ask AI assistant | [Ask AI](/docs/configuration/ask-ai) |
424
- | `analytics` | Vercel, PostHog, and custom scripts | [Analytics](/docs/configuration/analytics) |
433
+ | `agents` | `llms.txt`, Markdown mirrors, the JSON API, the hosted MCP server, skills, and discovery manifests for coding agents | [SEO and AEO](/docs/discoverability) |
434
+ | `ai` | The in-page assistant and the Open in chat action | [Assistant](/docs/configuration/assistant) |
435
+ | `reference` | API references: `openapi()`, `asyncapi()`, `graphql()`, and `scalar()` adapters from `blume/reference` | [OpenAPI](/docs/references/openapi), [AsyncAPI](/docs/references/asyncapi), [GraphQL](/docs/references/graphql), [Scalar](/docs/references/scalar) |
436
+ | `analytics` | Adapters from `blume/analytics` — PostHog, Google Analytics, Plausible, Mixpanel, Segment, and more — plus custom scripts | [Analytics](/docs/configuration/analytics) |
425
437
  | `seo` | Metadata, OG images, feeds, structured data, sitemap, robots | [SEO and AEO](/docs/discoverability) |
426
- | `deployment` | Output mode, adapter, and site URL | [Deployment](/docs/deployment) |
438
+ | `deployment` | A host adapter from `blume/deploy`, or `{ site, base }` for a static build | [Deployment](/docs/deployment) |
427
439
  | `redirects` | Permanent and temporary redirects | [Deployment](/docs/deployment#redirects) |
428
440
  | `integrations` | Astro integrations appended after Blume's built-ins | [Customization](/docs/configuration/customization#astro-integrations) |
441
+ | `basePath` | A path every generated route mounts under (e.g. `/docs`), invisible to the sidebar | [Deployment](/docs/deployment#mount-the-docs-under-a-path) |
442
+ | `i18n` | Locales, the default locale, and translated UI strings | [Internationalization](/docs/content/i18n) |
443
+ | `versions` | Frozen snapshots of older docs with a version switcher | [Versioning](/docs/content/versioning) |
444
+ | `export` | Reader-facing PDF and EPUB downloads | [Export](/docs/configuration/export) |
445
+ | `examples` | Where `<Component path>` example previews live, and the CSS injected into their frames | [Component](/docs/content/components#component) |
446
+ | `react` | React island behavior — the React Compiler's auto-memoization | [Islands](/docs/content/islands#frameworks) |
447
+ | `feedback` | The "Was this page helpful?" rating at the foot of each page (default `true`) | [Page feedback](#page-feedback) |
429
448
 
430
449
  ## Precedence
431
450
 
@@ -6,7 +6,7 @@ export default defineMeta({
6
6
  "theming",
7
7
  "customization",
8
8
  "search",
9
- "ask-ai",
9
+ "assistant",
10
10
  "analytics",
11
11
  "export",
12
12
  ],