blume 1.7.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (677) hide show
  1. package/AGENTS.md +19 -0
  2. package/CHANGELOG.md +227 -0
  3. package/README.md +34 -21
  4. package/dist/cli/chunk-11j0384y.js +148 -0
  5. package/dist/cli/chunk-11j0384y.js.map +10 -0
  6. package/dist/cli/{chunk-xhtpx3ff.js → chunk-1w8dp3qb.js} +17 -16
  7. package/dist/cli/{chunk-xhtpx3ff.js.map → chunk-1w8dp3qb.js.map} +3 -3
  8. package/dist/cli/chunk-2q1dwty4.js +75 -0
  9. package/dist/cli/chunk-2q1dwty4.js.map +11 -0
  10. package/dist/cli/chunk-41za066z.js +122 -0
  11. package/dist/cli/chunk-41za066z.js.map +11 -0
  12. package/dist/cli/chunk-5a2z0198.js +133 -0
  13. package/dist/cli/chunk-5a2z0198.js.map +10 -0
  14. package/dist/cli/{chunk-9he6crym.js → chunk-6k8vp3ta.js} +25 -13
  15. package/dist/cli/{chunk-9he6crym.js.map → chunk-6k8vp3ta.js.map} +4 -4
  16. package/dist/cli/{chunk-mt76t7dj.js → chunk-79njf86q.js} +133 -54
  17. package/dist/cli/chunk-79njf86q.js.map +11 -0
  18. package/dist/cli/{chunk-3w7b2vcx.js → chunk-7ez8ny0t.js} +2 -2
  19. package/dist/cli/{chunk-688e0dde.js → chunk-88cpgt6h.js} +1 -1
  20. package/dist/cli/chunk-a9kptbw5.js +361 -0
  21. package/dist/cli/chunk-a9kptbw5.js.map +14 -0
  22. package/dist/cli/chunk-abh8yjkn.js +31 -0
  23. package/dist/cli/chunk-abh8yjkn.js.map +10 -0
  24. package/dist/cli/chunk-b5aj94ah.js +91 -0
  25. package/dist/cli/chunk-b5aj94ah.js.map +10 -0
  26. package/dist/cli/{chunk-hs3gbh8p.js → chunk-bctazmbk.js} +9 -5
  27. package/dist/cli/chunk-bctazmbk.js.map +10 -0
  28. package/dist/cli/chunk-beat36xx.js +279 -0
  29. package/dist/cli/chunk-beat36xx.js.map +10 -0
  30. package/dist/cli/chunk-bnbmcwfb.js +145 -0
  31. package/dist/cli/chunk-bnbmcwfb.js.map +11 -0
  32. package/dist/cli/{chunk-9bkjd11x.js → chunk-bw22s759.js} +15 -5
  33. package/dist/cli/{chunk-9bkjd11x.js.map → chunk-bw22s759.js.map} +4 -4
  34. package/dist/cli/chunk-by2290sx.js +39 -0
  35. package/dist/cli/chunk-by2290sx.js.map +10 -0
  36. package/dist/cli/chunk-d1tadaw7.js +79 -0
  37. package/dist/cli/chunk-d1tadaw7.js.map +10 -0
  38. package/dist/cli/{chunk-t3tj0dgr.js → chunk-d80hr03s.js} +24 -19
  39. package/dist/cli/chunk-d80hr03s.js.map +15 -0
  40. package/dist/cli/chunk-ernrthtr.js +97 -0
  41. package/dist/cli/chunk-ernrthtr.js.map +10 -0
  42. package/dist/cli/chunk-f2972sbt.js +374 -0
  43. package/dist/cli/chunk-f2972sbt.js.map +10 -0
  44. package/dist/cli/{chunk-exeeb35e.js → chunk-f7t03s3g.js} +2 -2
  45. package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
  46. package/dist/cli/chunk-fa25z98p.js.map +11 -0
  47. package/dist/cli/{chunk-12dxjqk7.js → chunk-fh5hj5jt.js} +44 -21
  48. package/dist/cli/chunk-fh5hj5jt.js.map +10 -0
  49. package/dist/cli/{chunk-8cd8tj54.js → chunk-j8mw0za6.js} +86 -57
  50. package/dist/cli/chunk-j8mw0za6.js.map +35 -0
  51. package/dist/cli/chunk-jts8mvcz.js +106 -0
  52. package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
  53. package/dist/cli/{chunk-ejjx8znq.js → chunk-mnqj32sj.js} +505 -536
  54. package/dist/cli/chunk-mnqj32sj.js.map +12 -0
  55. package/dist/cli/{chunk-196vjxp9.js → chunk-mwt1k8n7.js} +100 -372
  56. package/dist/cli/chunk-mwt1k8n7.js.map +10 -0
  57. package/dist/cli/chunk-nk3ts2xk.js +51 -0
  58. package/dist/cli/chunk-nk3ts2xk.js.map +10 -0
  59. package/dist/cli/{chunk-n9sra6sy.js → chunk-pat2zzwc.js} +10 -14
  60. package/dist/cli/{chunk-n9sra6sy.js.map → chunk-pat2zzwc.js.map} +2 -2
  61. package/dist/cli/chunk-pnnvybbk.js +176 -0
  62. package/dist/cli/chunk-pnnvybbk.js.map +11 -0
  63. package/dist/cli/{chunk-cvky9gb2.js → chunk-sqn5t4q0.js} +81 -87
  64. package/dist/cli/chunk-sqn5t4q0.js.map +10 -0
  65. package/dist/cli/{chunk-eevwt1sc.js → chunk-tzne8qfq.js} +15 -15
  66. package/dist/cli/{chunk-eevwt1sc.js.map → chunk-tzne8qfq.js.map} +1 -1
  67. package/dist/cli/chunk-xaz13gwg.js +12449 -0
  68. package/dist/cli/chunk-xaz13gwg.js.map +182 -0
  69. package/dist/cli/chunk-y3e45rc8.js +102 -0
  70. package/dist/cli/chunk-y3e45rc8.js.map +10 -0
  71. package/dist/cli/chunk-z01ze5c1.js +261 -0
  72. package/dist/cli/chunk-z01ze5c1.js.map +10 -0
  73. package/dist/cli/{chunk-5n7t497w.js → chunk-z1f5arsg.js} +247 -755
  74. package/dist/cli/chunk-z1f5arsg.js.map +36 -0
  75. package/dist/cli/{chunk-hdm2dkd2.js → chunk-zg2gtj10.js} +1086 -2596
  76. package/dist/cli/chunk-zg2gtj10.js.map +35 -0
  77. package/dist/cli/{chunk-ppfvdcd4.js → chunk-zxccj738.js} +1 -1
  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.d.ts +368 -0
  85. package/dist/types/ai/changelog-markdown.d.ts +2 -0
  86. package/dist/types/ai/component-markdown.d.ts +2 -2
  87. package/dist/types/ai/index.d.ts +24 -0
  88. package/dist/types/ai/link-headers.d.ts +24 -0
  89. package/dist/types/ai/llms.d.ts +25 -0
  90. package/dist/types/ai/markdown.d.ts +45 -0
  91. package/dist/types/ai/mcp/discovery.d.ts +68 -0
  92. package/dist/types/ai/mcp/tools.d.ts +16 -0
  93. package/dist/types/ai/openapi-components.d.ts +43 -0
  94. package/dist/types/ai/relative-links.d.ts +26 -0
  95. package/dist/types/ai/serializers.d.ts +15 -0
  96. package/dist/types/ai/skills.d.ts +42 -0
  97. package/dist/types/ai/tar.d.ts +25 -0
  98. package/dist/types/ai/visibility.d.ts +17 -0
  99. package/dist/types/ai/web-bot-auth.d.ts +16 -0
  100. package/dist/types/analytics/adobe.d.ts +35 -0
  101. package/dist/types/analytics/amplitude.d.ts +50 -0
  102. package/dist/types/analytics/clarity.d.ts +31 -0
  103. package/dist/types/analytics/clearbit.d.ts +29 -0
  104. package/dist/types/analytics/cloudflare.d.ts +41 -0
  105. package/dist/types/analytics/fathom.d.ts +41 -0
  106. package/dist/types/analytics/google-analytics.d.ts +44 -0
  107. package/dist/types/analytics/google-tag-manager.d.ts +40 -0
  108. package/dist/types/analytics/head.d.ts +30 -0
  109. package/dist/types/analytics/heap.d.ts +40 -0
  110. package/dist/types/analytics/hightouch.d.ts +44 -0
  111. package/dist/types/analytics/hotjar.d.ts +33 -0
  112. package/dist/types/analytics/index.d.ts +61 -0
  113. package/dist/types/analytics/inline.d.ts +17 -0
  114. package/dist/types/analytics/logrocket.d.ts +44 -0
  115. package/dist/types/analytics/mixpanel.d.ts +67 -0
  116. package/dist/types/analytics/pirsch.d.ts +42 -0
  117. package/dist/types/analytics/plausible.d.ts +56 -0
  118. package/dist/types/analytics/posthog.d.ts +45 -0
  119. package/dist/types/analytics/schema.d.ts +320 -0
  120. package/dist/types/analytics/script.d.ts +46 -0
  121. package/dist/types/analytics/segment.d.ts +50 -0
  122. package/dist/types/analytics/vercel.d.ts +48 -0
  123. package/dist/types/astro/integration.d.ts +76 -0
  124. package/dist/types/astro/markdown-negotiation.d.ts +23 -0
  125. package/dist/types/astro/module-types.d.ts +14 -0
  126. package/dist/types/astro/pages.d.ts +44 -0
  127. package/dist/types/cli/env.d.ts +12 -0
  128. package/dist/types/cli/init/scaffold.d.ts +154 -0
  129. package/dist/types/components/layout/nav-utils.d.ts +11 -0
  130. package/dist/types/core/adapter.d.ts +47 -0
  131. package/dist/types/core/api-name.d.ts +7 -0
  132. package/dist/types/core/changelog-index.d.ts +13 -0
  133. package/dist/types/core/config-input.d.ts +209 -505
  134. package/dist/types/core/config.d.ts +60 -34
  135. package/dist/types/core/content-assets.d.ts +76 -0
  136. package/dist/types/core/custom-pages.d.ts +33 -0
  137. package/dist/types/core/data.d.ts +28 -11
  138. package/dist/types/core/define-components.d.ts +12 -9
  139. package/dist/types/core/deployment-env.d.ts +6 -11
  140. package/dist/types/core/frontmatter.d.ts +10 -0
  141. package/dist/types/core/graph.d.ts +18 -0
  142. package/dist/types/core/heading-markers.d.ts +54 -0
  143. package/dist/types/core/i18n-ui.d.ts +6 -2
  144. package/dist/types/core/i18n.d.ts +87 -0
  145. package/dist/types/core/includes.d.ts +138 -0
  146. package/dist/types/core/last-modified.d.ts +47 -0
  147. package/dist/types/core/links.d.ts +95 -0
  148. package/dist/types/core/locale-links.d.ts +60 -0
  149. package/dist/types/core/manifest.d.ts +17 -0
  150. package/dist/types/core/meta.d.ts +38 -0
  151. package/dist/types/core/nav-diagnostics.d.ts +26 -0
  152. package/dist/types/core/navigation.d.ts +6 -0
  153. package/dist/types/core/node-require.d.ts +19 -0
  154. package/dist/types/core/package-json.d.ts +13 -0
  155. package/dist/types/core/probe.d.ts +42 -0
  156. package/dist/types/core/project-graph.d.ts +51 -0
  157. package/dist/types/core/project.d.ts +2 -0
  158. package/dist/types/core/safe-href.d.ts +2 -0
  159. package/dist/types/core/safe-links.d.ts +26 -0
  160. package/dist/types/core/schema.d.ts +2291 -441
  161. package/dist/types/core/site-url.d.ts +16 -0
  162. package/dist/types/core/sources/assets.d.ts +36 -0
  163. package/dist/types/core/sources/cache.d.ts +37 -0
  164. package/dist/types/core/sources/collection.d.ts +28 -0
  165. package/dist/types/core/sources/contentful-rich-text.d.ts +31 -0
  166. package/dist/types/core/sources/contentful.d.ts +40 -0
  167. package/dist/types/core/sources/filesystem.d.ts +24 -0
  168. package/dist/types/core/sources/github-releases.d.ts +31 -0
  169. package/dist/types/core/sources/json.d.ts +30 -0
  170. package/dist/types/core/sources/lexical.d.ts +19 -0
  171. package/dist/types/core/sources/lower.d.ts +75 -0
  172. package/dist/types/core/sources/mdx-remote.d.ts +28 -0
  173. package/dist/types/core/sources/normalize.d.ts +147 -0
  174. package/dist/types/core/sources/notion.d.ts +131 -0
  175. package/dist/types/core/sources/obsidian.d.ts +46 -0
  176. package/dist/types/core/sources/payload.d.ts +39 -0
  177. package/dist/types/core/sources/portable-text.d.ts +42 -0
  178. package/dist/types/core/sources/read.d.ts +23 -0
  179. package/dist/types/core/sources/remote.d.ts +74 -0
  180. package/dist/types/core/sources/resolve.d.ts +19 -0
  181. package/dist/types/core/sources/sanity.d.ts +43 -0
  182. package/dist/types/core/sources/strapi-blocks.d.ts +12 -0
  183. package/dist/types/core/sources/strapi.d.ts +33 -0
  184. package/dist/types/core/sources/types.d.ts +7 -0
  185. package/dist/types/core/sources/watch.d.ts +45 -0
  186. package/dist/types/core/text-width.d.ts +11 -0
  187. package/dist/types/core/types.d.ts +20 -1
  188. package/dist/types/core/unrecognized-keys.d.ts +7 -0
  189. package/dist/types/core/versions.d.ts +72 -0
  190. package/dist/types/core/yaml.d.ts +9 -0
  191. package/dist/types/deploy/adapter-output.d.ts +45 -0
  192. package/dist/types/deploy/adapters/cloudflare.d.ts +40 -0
  193. package/dist/types/deploy/adapters/index.d.ts +29 -0
  194. package/dist/types/deploy/adapters/netlify.d.ts +37 -0
  195. package/dist/types/deploy/adapters/node.d.ts +37 -0
  196. package/dist/types/deploy/adapters/registry.d.ts +133 -0
  197. package/dist/types/deploy/adapters/types.d.ts +71 -0
  198. package/dist/types/deploy/adapters/vercel.d.ts +38 -0
  199. package/dist/types/deploy/artifacts.d.ts +65 -0
  200. package/dist/types/deploy/cloudflare-negotiation.d.ts +196 -0
  201. package/dist/types/deploy/function-bundle.d.ts +80 -0
  202. package/dist/types/deploy/headers.d.ts +50 -0
  203. package/dist/types/deploy/node-headers.d.ts +42 -0
  204. package/dist/types/deploy/platforms/cloudflare.d.ts +40 -0
  205. package/dist/types/deploy/platforms/index.d.ts +18 -0
  206. package/dist/types/deploy/platforms/netlify.d.ts +13 -0
  207. package/dist/types/deploy/platforms/node.d.ts +11 -0
  208. package/dist/types/deploy/platforms/paths.d.ts +27 -0
  209. package/dist/types/deploy/platforms/static.d.ts +10 -0
  210. package/dist/types/deploy/platforms/types.d.ts +104 -0
  211. package/dist/types/deploy/platforms/vercel.d.ts +32 -0
  212. package/dist/types/deploy/redirects.d.ts +53 -0
  213. package/dist/types/deploy/robots.d.ts +8 -0
  214. package/dist/types/deploy/rss.d.ts +31 -0
  215. package/dist/types/deploy/sitemap.d.ts +21 -0
  216. package/dist/types/deploy/vercel-negotiation.d.ts +109 -0
  217. package/dist/types/markdown/code-title.d.ts +32 -0
  218. package/dist/types/markdown/fence-meta.d.ts +23 -0
  219. package/dist/types/markdown/themes.d.ts +3 -3
  220. package/dist/types/openapi/asyncapi.d.ts +129 -0
  221. package/dist/types/openapi/graphql-build.d.ts +8 -0
  222. package/dist/types/openapi/graphql.d.ts +122 -0
  223. package/dist/types/openapi/model.d.ts +158 -0
  224. package/dist/types/openapi/parse.d.ts +57 -0
  225. package/dist/types/openapi/references.d.ts +37 -25
  226. package/dist/types/openapi/render-mdx.d.ts +33 -0
  227. package/dist/types/openapi/sentence.d.ts +7 -0
  228. package/dist/types/openapi/signature.d.ts +10 -0
  229. package/dist/types/openapi/source.d.ts +22 -0
  230. package/dist/types/openapi/spec-dependency-error.d.ts +10 -0
  231. package/dist/types/reference/asyncapi.d.ts +166 -0
  232. package/dist/types/reference/graphql.d.ts +181 -0
  233. package/dist/types/reference/index.d.ts +32 -0
  234. package/dist/types/reference/openapi.d.ts +165 -0
  235. package/dist/types/reference/options.d.ts +157 -0
  236. package/dist/types/reference/scalar.d.ts +136 -0
  237. package/dist/types/reference/schema.d.ts +630 -0
  238. package/dist/types/search/adapters/algolia.d.ts +32 -0
  239. package/dist/types/search/adapters/flexsearch.d.ts +12 -0
  240. package/dist/types/search/adapters/index.d.ts +31 -0
  241. package/dist/types/search/adapters/mixedbread.d.ts +22 -0
  242. package/dist/types/search/adapters/orama-cloud.d.ts +33 -0
  243. package/dist/types/search/adapters/orama.d.ts +13 -0
  244. package/dist/types/search/adapters/pagefind.d.ts +12 -0
  245. package/dist/types/search/adapters/registry.d.ts +228 -0
  246. package/dist/types/search/adapters/types.d.ts +34 -0
  247. package/dist/types/search/adapters/typesense.d.ts +42 -0
  248. package/dist/types/search/build.d.ts +23 -0
  249. package/dist/types/search/documents.d.ts +90 -0
  250. package/dist/types/search/facets.d.ts +3 -0
  251. package/dist/types/search/sync/algolia.d.ts +14 -0
  252. package/dist/types/search/sync/index.d.ts +14 -0
  253. package/dist/types/search/sync/orama-cloud.d.ts +10 -0
  254. package/dist/types/search/sync/typesense.d.ts +14 -0
  255. package/dist/types/sources/contentful.d.ts +68 -0
  256. package/dist/types/sources/custom.d.ts +20 -0
  257. package/dist/types/sources/filesystem.d.ts +42 -0
  258. package/dist/types/sources/github-releases.d.ts +46 -0
  259. package/dist/types/sources/index.d.ts +48 -0
  260. package/dist/types/sources/mdx-remote.d.ts +63 -0
  261. package/dist/types/sources/notion.d.ts +65 -0
  262. package/dist/types/sources/obsidian.d.ts +34 -0
  263. package/dist/types/sources/payload.d.ts +68 -0
  264. package/dist/types/sources/registry.d.ts +1414 -0
  265. package/dist/types/sources/sanity.d.ts +69 -0
  266. package/dist/types/sources/shared.d.ts +46 -0
  267. package/dist/types/sources/strapi.d.ts +66 -0
  268. package/dist/types/theme/icon-kind.d.ts +11 -0
  269. package/dist/types/theme/icons.d.ts +20 -0
  270. package/docs/01-quickstart.mdx +18 -18
  271. package/docs/02-deployment.mdx +50 -26
  272. package/docs/03-upgrading.mdx +351 -0
  273. package/docs/04-migrating.mdx +58 -0
  274. package/docs/08-faq.mdx +3 -3
  275. package/docs/advanced/blog.mdx +13 -6
  276. package/docs/advanced/changelog.mdx +23 -35
  277. package/docs/advanced/custom-pages.mdx +20 -8
  278. package/docs/advanced/meta.ts +1 -8
  279. package/docs/advanced/skills.mdx +8 -0
  280. package/docs/cli/audit.mdx +646 -0
  281. package/docs/cli/doctor.mdx +29 -0
  282. package/docs/{reference/eval.mdx → cli/evals.mdx} +9 -8
  283. package/docs/cli/index.mdx +105 -0
  284. package/docs/cli/meta.ts +7 -0
  285. package/docs/{reference → cli}/translate.mdx +1 -1
  286. package/docs/cli/validate.mdx +41 -0
  287. package/docs/cli/version.mdx +40 -0
  288. package/docs/configuration/analytics.mdx +350 -59
  289. package/docs/configuration/ask-ai.mdx +176 -61
  290. package/docs/configuration/customization.mdx +15 -9
  291. package/docs/configuration/index.mdx +52 -31
  292. package/docs/configuration/search.mdx +75 -54
  293. package/docs/configuration/theming.mdx +24 -15
  294. package/docs/content/components.mdx +21 -5
  295. package/docs/{reference → content}/frontmatter.mdx +37 -1
  296. package/docs/content/i18n.mdx +8 -6
  297. package/docs/content/includes.mdx +2 -4
  298. package/docs/content/index.mdx +1 -1
  299. package/docs/content/islands.mdx +10 -5
  300. package/docs/content/meta.mdx +1 -1
  301. package/docs/content/meta.ts +1 -0
  302. package/docs/content/navigation.mdx +12 -7
  303. package/docs/content/sources.mdx +145 -50
  304. package/docs/content/syntax.mdx +26 -12
  305. package/docs/content/versioning.mdx +3 -3
  306. package/docs/discoverability/agent-discovery.mdx +91 -10
  307. package/docs/discoverability/index.mdx +5 -5
  308. package/docs/discoverability/json-api.mdx +4 -4
  309. package/docs/discoverability/llms-txt.mdx +6 -6
  310. package/docs/discoverability/markdown.mdx +4 -4
  311. package/docs/discoverability/mcp.mdx +11 -11
  312. package/docs/discoverability/sitemap-and-robots.mdx +3 -3
  313. package/docs/index.mdx +2 -2
  314. package/docs/references/asyncapi.mdx +59 -0
  315. package/docs/{advanced → references}/graphql.mdx +45 -32
  316. package/docs/{reference → references}/meta.ts +2 -2
  317. package/docs/references/openapi.mdx +171 -0
  318. package/docs/references/scalar.mdx +64 -0
  319. package/package.json +42 -8
  320. package/skills/blume/SKILL.md +21 -8
  321. package/skills/blume-migrate/SKILL.md +22 -21
  322. package/skills/blume-migrate/assets/oxfmt@0.67.0.patch +49 -0
  323. package/skills/blume-migrate/references/docusaurus.md +5 -4
  324. package/skills/blume-migrate/references/fumadocs.md +4 -4
  325. package/skills/blume-migrate/references/mintlify.md +23 -8
  326. package/skills/blume-migrate/references/monorepo.md +6 -6
  327. package/skills/blume-migrate/references/starlight.md +4 -4
  328. package/src/ai/agent-readability.ts +26 -22
  329. package/src/ai/ai-catalog.ts +259 -0
  330. package/src/ai/api/handlers.ts +46 -11
  331. package/src/ai/api-catalog.ts +8 -8
  332. package/src/ai/ask-data.ts +1 -1
  333. package/src/ai/ask.ts +624 -100
  334. package/src/ai/changelog-markdown.ts +91 -0
  335. package/src/ai/component-markdown.ts +328 -12
  336. package/src/ai/index.ts +45 -0
  337. package/src/ai/link-headers.ts +19 -6
  338. package/src/ai/llms.ts +26 -15
  339. package/src/ai/markdown.ts +35 -5
  340. package/src/ai/mcp/data.ts +9 -5
  341. package/src/ai/mcp/discovery.ts +1 -1
  342. package/src/ai/openapi-components.ts +4 -1
  343. package/src/ai/relative-links.ts +170 -0
  344. package/src/ai/serializers.ts +2 -2
  345. package/src/ai/skills.ts +1 -1
  346. package/src/ai/web-bot-auth.ts +2 -2
  347. package/src/analytics/adobe.ts +46 -0
  348. package/src/analytics/amplitude.ts +79 -0
  349. package/src/analytics/clarity.ts +46 -0
  350. package/src/analytics/clearbit.ts +47 -0
  351. package/src/analytics/cloudflare.ts +67 -0
  352. package/src/analytics/fathom.ts +64 -0
  353. package/src/analytics/google-analytics.ts +84 -0
  354. package/src/analytics/google-tag-manager.ts +61 -0
  355. package/src/analytics/head.ts +130 -0
  356. package/src/analytics/heap.ts +65 -0
  357. package/src/analytics/hightouch.ts +77 -0
  358. package/src/analytics/hotjar.ts +47 -0
  359. package/src/analytics/index.ts +71 -0
  360. package/src/analytics/inline.ts +21 -0
  361. package/src/analytics/logrocket.ts +71 -0
  362. package/src/analytics/mixpanel.ts +92 -0
  363. package/src/analytics/pirsch.ts +66 -0
  364. package/src/analytics/plausible.ts +83 -0
  365. package/src/analytics/posthog.ts +78 -0
  366. package/src/analytics/schema.ts +60 -0
  367. package/src/analytics/script.ts +60 -0
  368. package/src/analytics/segment.ts +85 -0
  369. package/src/analytics/vercel.ts +50 -0
  370. package/src/astro/adapter-root.ts +7 -9
  371. package/src/astro/component-slots.ts +131 -91
  372. package/src/astro/generate.ts +114 -345
  373. package/src/astro/integration.ts +2 -6
  374. package/src/astro/pages.ts +13 -101
  375. package/src/astro/render-deps.ts +379 -0
  376. package/src/astro/runtime-deps.ts +201 -0
  377. package/src/astro/templates.ts +554 -541
  378. package/src/audit/agent.ts +24 -0
  379. package/src/audit/catalog.ts +2 -2
  380. package/src/audit/checks/assets.ts +2 -2
  381. package/src/audit/checks/dns-aid.ts +1 -1
  382. package/src/audit/checks/duplicates.ts +3 -1
  383. package/src/audit/checks/i18n.ts +1 -1
  384. package/src/audit/checks/indexability.ts +7 -7
  385. package/src/audit/checks/links.ts +2 -2
  386. package/src/audit/checks/llms.ts +6 -6
  387. package/src/audit/checks/network.ts +3 -3
  388. package/src/audit/checks/og-image.ts +2 -2
  389. package/src/audit/checks/robots.ts +1 -1
  390. package/src/audit/checks/sitemap.ts +2 -2
  391. package/src/audit/checks/social.ts +1 -1
  392. package/src/audit/run.ts +4 -3
  393. package/src/audit/terms.ts +31 -0
  394. package/src/audit/url.ts +13 -13
  395. package/src/cli/command-meta.ts +10 -0
  396. package/src/cli/commands/audit.ts +39 -20
  397. package/src/cli/commands/build.ts +71 -314
  398. package/src/cli/commands/check.ts +1 -0
  399. package/src/cli/commands/dev.ts +40 -1
  400. package/src/cli/commands/doctor.ts +90 -14
  401. package/src/cli/commands/eject.ts +44 -7
  402. package/src/cli/commands/eval.ts +2 -2
  403. package/src/cli/commands/init.ts +161 -41
  404. package/src/cli/commands/migrate.ts +121 -0
  405. package/src/cli/commands/preview.ts +7 -1
  406. package/src/cli/commands/translate.ts +2 -2
  407. package/src/cli/commands/upgrade.ts +141 -0
  408. package/src/cli/commands/version.ts +57 -44
  409. package/src/cli/eject-scripts.ts +121 -6
  410. package/src/cli/index.ts +11 -1
  411. package/src/cli/init/install.ts +70 -0
  412. package/src/cli/init/questions.ts +7 -0
  413. package/src/cli/init/scaffold.ts +459 -75
  414. package/src/cli/lazy-command.ts +37 -1
  415. package/src/cli/prepare.ts +40 -6
  416. package/src/cli/required-secrets.ts +38 -11
  417. package/src/cli/unknown-flags.ts +266 -0
  418. package/src/cli/yarn-pnp.ts +52 -0
  419. package/src/components/content/AccordionItem.astro +7 -1
  420. package/src/components/content/Card.astro +4 -3
  421. package/src/components/content/ColorItem.astro +22 -4
  422. package/src/components/content/GithubInfo.astro +2 -2
  423. package/src/components/content/Prompt.astro +25 -25
  424. package/src/components/content/Tabs.astro +3 -1
  425. package/src/components/content/Tile.astro +2 -3
  426. package/src/components/content/Tooltip.astro +57 -9
  427. package/src/components/content/content-strings.ts +34 -0
  428. package/src/components/content/diff.ts +1 -1
  429. package/src/components/content/mermaid-element.ts +13 -2
  430. package/src/components/content/prompt-markdown.ts +292 -0
  431. package/src/components/content/tooltip-id.ts +41 -0
  432. package/src/components/islands/hooks.ts +75 -3
  433. package/src/components/layout/Analytics.astro +21 -79
  434. package/src/components/layout/Banner.astro +3 -1
  435. package/src/components/layout/DiscoveryLinks.astro +69 -0
  436. package/src/components/layout/Header.astro +83 -20
  437. package/src/components/layout/LanguageSwitcher.astro +4 -1
  438. package/src/components/layout/Logo.astro +23 -2
  439. package/src/components/layout/NavSelector.astro +13 -2
  440. package/src/components/layout/NavTree.astro +12 -3
  441. package/src/components/layout/NavTreeScript.astro +17 -3
  442. package/src/components/layout/PageActions.astro +3 -3
  443. package/src/components/layout/PageFeedback.astro +11 -1
  444. package/src/components/layout/PageLayout.astro +52 -5
  445. package/src/components/layout/ReferenceLayout.astro +21 -12
  446. package/src/components/layout/RootLayout.astro +69 -43
  447. package/src/components/layout/Search.astro +30 -6
  448. package/src/components/layout/WebMcp.astro +1 -1
  449. package/src/components/layout/analytics-client.ts +101 -15
  450. package/src/components/layout/drawer-inert.ts +113 -15
  451. package/src/components/layout/dropdown-clamp.ts +105 -0
  452. package/src/components/layout/head-scripts.ts +15 -6
  453. package/src/components/layout/nav-utils.ts +17 -0
  454. package/src/components/layout/search/algolia.ts +8 -8
  455. package/src/components/layout/search/orama-cloud.ts +9 -7
  456. package/src/components/layout/search/typesense.ts +11 -17
  457. package/src/components/openapi/MessageComposer.astro +2 -2
  458. package/src/components/openapi/Playground.astro +2 -2
  459. package/src/components/openapi/playground-client.ts +79 -10
  460. package/src/core/changelog-index.ts +24 -0
  461. package/src/core/component-overrides.ts +399 -154
  462. package/src/core/config-input.ts +212 -543
  463. package/src/core/config.ts +130 -41
  464. package/src/core/custom-pages.ts +105 -0
  465. package/src/core/data.ts +32 -11
  466. package/src/core/define-components.ts +12 -9
  467. package/src/core/deployment-env.ts +18 -74
  468. package/src/core/diagnostics.ts +14 -7
  469. package/src/core/graph.ts +69 -25
  470. package/src/core/i18n-ui.ts +6 -2
  471. package/src/core/i18n.ts +17 -0
  472. package/src/core/includes.ts +156 -38
  473. package/src/core/last-modified.ts +6 -11
  474. package/src/core/links.ts +166 -2
  475. package/src/core/manifest.ts +10 -3
  476. package/src/core/navigation.ts +137 -19
  477. package/src/core/new-tab.ts +35 -0
  478. package/src/core/node-require.ts +21 -0
  479. package/src/core/project-graph.ts +42 -26
  480. package/src/core/project.ts +9 -4
  481. package/src/core/request-body.ts +61 -0
  482. package/src/core/safe-href.ts +28 -0
  483. package/src/core/safe-links.ts +68 -0
  484. package/src/core/schema.ts +531 -721
  485. package/src/core/server-features.ts +8 -9
  486. package/src/core/sources/assets.ts +47 -11
  487. package/src/core/sources/collection.ts +67 -0
  488. package/src/core/sources/contentful-rich-text.ts +285 -0
  489. package/src/core/sources/contentful.ts +173 -0
  490. package/src/core/sources/github-releases.ts +51 -1
  491. package/src/core/sources/json.ts +71 -0
  492. package/src/core/sources/lexical.ts +195 -0
  493. package/src/core/sources/lower.ts +226 -0
  494. package/src/core/sources/normalize.ts +52 -2
  495. package/src/core/sources/notion.ts +39 -28
  496. package/src/core/sources/payload.ts +135 -0
  497. package/src/core/sources/portable-text.ts +11 -16
  498. package/src/core/sources/remote.ts +226 -0
  499. package/src/core/sources/resolve.ts +104 -166
  500. package/src/core/sources/sanity.ts +16 -49
  501. package/src/core/sources/strapi-blocks.ts +124 -0
  502. package/src/core/sources/strapi.ts +191 -0
  503. package/src/core/sources/types.ts +12 -1
  504. package/src/core/types.ts +20 -1
  505. package/src/core/ui-packs/ar.ts +6 -2
  506. package/src/core/ui-packs/bg.ts +6 -2
  507. package/src/core/ui-packs/bn.ts +6 -2
  508. package/src/core/ui-packs/ca.ts +3 -1
  509. package/src/core/ui-packs/cs.ts +6 -2
  510. package/src/core/ui-packs/da.ts +6 -2
  511. package/src/core/ui-packs/de.ts +6 -2
  512. package/src/core/ui-packs/el.ts +3 -1
  513. package/src/core/ui-packs/es.ts +3 -1
  514. package/src/core/ui-packs/fa.ts +6 -2
  515. package/src/core/ui-packs/fi.ts +6 -2
  516. package/src/core/ui-packs/fr.ts +3 -1
  517. package/src/core/ui-packs/he.ts +6 -2
  518. package/src/core/ui-packs/hi.ts +6 -2
  519. package/src/core/ui-packs/hr.ts +6 -2
  520. package/src/core/ui-packs/hu.ts +6 -2
  521. package/src/core/ui-packs/id.ts +6 -2
  522. package/src/core/ui-packs/it.ts +3 -1
  523. package/src/core/ui-packs/ja.ts +3 -1
  524. package/src/core/ui-packs/ko.ts +3 -1
  525. package/src/core/ui-packs/nl.ts +6 -2
  526. package/src/core/ui-packs/no.ts +6 -2
  527. package/src/core/ui-packs/pl.ts +6 -2
  528. package/src/core/ui-packs/pt-br.ts +3 -1
  529. package/src/core/ui-packs/pt.ts +3 -1
  530. package/src/core/ui-packs/ro.ts +6 -2
  531. package/src/core/ui-packs/ru.ts +6 -2
  532. package/src/core/ui-packs/sk.ts +6 -2
  533. package/src/core/ui-packs/sr.ts +6 -2
  534. package/src/core/ui-packs/sv.ts +6 -2
  535. package/src/core/ui-packs/th.ts +3 -1
  536. package/src/core/ui-packs/tr.ts +6 -2
  537. package/src/core/ui-packs/uk.ts +6 -2
  538. package/src/core/ui-packs/vi.ts +3 -1
  539. package/src/core/ui-packs/zh-tw.ts +3 -1
  540. package/src/core/ui-packs/zh.ts +3 -1
  541. package/src/core/unrecognized-keys.ts +10 -0
  542. package/src/core/version-cut.ts +116 -8
  543. package/src/deploy/adapter-output.ts +57 -97
  544. package/src/deploy/adapters/cloudflare.ts +39 -0
  545. package/src/deploy/adapters/index.ts +41 -0
  546. package/src/deploy/adapters/netlify.ts +34 -0
  547. package/src/deploy/adapters/node.ts +34 -0
  548. package/src/deploy/adapters/registry.ts +127 -0
  549. package/src/deploy/adapters/types.ts +92 -0
  550. package/src/deploy/adapters/vercel.ts +35 -0
  551. package/src/deploy/artifacts.ts +67 -28
  552. package/src/deploy/cloudflare-negotiation.ts +179 -100
  553. package/src/deploy/function-bundle.ts +18 -3
  554. package/src/deploy/headers.ts +129 -22
  555. package/src/deploy/node-headers.ts +198 -0
  556. package/src/deploy/platforms/cloudflare.ts +312 -0
  557. package/src/deploy/platforms/index.ts +67 -0
  558. package/src/deploy/platforms/netlify.ts +52 -0
  559. package/src/deploy/platforms/node.ts +40 -0
  560. package/src/deploy/platforms/paths.ts +42 -0
  561. package/src/deploy/platforms/static.ts +29 -0
  562. package/src/deploy/platforms/types.ts +112 -0
  563. package/src/deploy/platforms/vercel.ts +193 -0
  564. package/src/deploy/redirects.ts +30 -18
  565. package/src/deploy/robots.ts +3 -3
  566. package/src/deploy/rss.ts +2 -2
  567. package/src/deploy/sitemap.ts +2 -2
  568. package/src/deploy/vercel-negotiation.ts +27 -4
  569. package/src/eval/agents.ts +32 -1
  570. package/src/eval/findings.ts +19 -11
  571. package/src/eval/report.ts +10 -2
  572. package/src/markdown/external-links.ts +65 -0
  573. package/src/markdown/include.ts +45 -27
  574. package/src/markdown/index.ts +34 -9
  575. package/src/markdown/inline-code.ts +12 -6
  576. package/src/markdown/relative-links.ts +324 -0
  577. package/src/markdown/themes.ts +3 -3
  578. package/src/migrate/migrate.ts +149 -0
  579. package/src/openapi/parse.ts +64 -16
  580. package/src/openapi/proxy.ts +62 -10
  581. package/src/openapi/references.ts +147 -147
  582. package/src/openapi/render-mdx.ts +32 -10
  583. package/src/openapi/scalar.ts +15 -13
  584. package/src/openapi/sentence.ts +14 -0
  585. package/src/openapi/source.ts +37 -21
  586. package/src/openapi/spec-dependency-error.ts +15 -0
  587. package/src/reference/asyncapi.ts +83 -0
  588. package/src/reference/graphql.ts +89 -0
  589. package/src/reference/index.ts +40 -0
  590. package/src/reference/openapi.ts +83 -0
  591. package/src/reference/options.ts +201 -0
  592. package/src/reference/scalar.ts +136 -0
  593. package/src/reference/schema.ts +88 -0
  594. package/src/registry/eject.ts +97 -42
  595. package/src/search/adapters/algolia.ts +46 -0
  596. package/src/search/adapters/flexsearch.ts +29 -0
  597. package/src/search/adapters/index.ts +39 -0
  598. package/src/search/adapters/mixedbread.ts +39 -0
  599. package/src/search/adapters/orama-cloud.ts +51 -0
  600. package/src/search/adapters/orama.ts +24 -0
  601. package/src/search/adapters/pagefind.ts +27 -0
  602. package/src/search/adapters/registry.ts +131 -0
  603. package/src/search/adapters/types.ts +46 -0
  604. package/src/search/adapters/typesense.ts +57 -0
  605. package/src/search/build.ts +33 -7
  606. package/src/search/documents.ts +6 -0
  607. package/src/search/sync/algolia.ts +12 -11
  608. package/src/search/sync/index.ts +35 -20
  609. package/src/search/sync/orama-cloud.ts +12 -9
  610. package/src/search/sync/typesense.ts +15 -13
  611. package/src/sources/contentful.ts +63 -0
  612. package/src/sources/custom.ts +38 -0
  613. package/src/sources/filesystem.ts +51 -0
  614. package/src/sources/github-releases.ts +52 -0
  615. package/src/sources/index.ts +60 -0
  616. package/src/sources/mdx-remote.ts +76 -0
  617. package/src/sources/notion.ts +63 -0
  618. package/src/sources/obsidian.ts +38 -0
  619. package/src/sources/payload.ts +60 -0
  620. package/src/sources/registry.ts +182 -0
  621. package/src/sources/sanity.ts +66 -0
  622. package/src/sources/shared.ts +52 -0
  623. package/src/sources/strapi.ts +58 -0
  624. package/src/theme/entry.ts +47 -2
  625. package/src/translate/report.ts +40 -7
  626. package/src/upgrade/upgrade.ts +499 -0
  627. package/dist/cli/chunk-12dxjqk7.js.map +0 -10
  628. package/dist/cli/chunk-196vjxp9.js.map +0 -13
  629. package/dist/cli/chunk-2mzebbbz.js +0 -69
  630. package/dist/cli/chunk-2z47ypj8.js.map +0 -11
  631. package/dist/cli/chunk-30e87n55.js +0 -108
  632. package/dist/cli/chunk-30e87n55.js.map +0 -10
  633. package/dist/cli/chunk-450a7rcr.js +0 -185
  634. package/dist/cli/chunk-450a7rcr.js.map +0 -11
  635. package/dist/cli/chunk-5n7t497w.js.map +0 -40
  636. package/dist/cli/chunk-61j18dwk.js +0 -5342
  637. package/dist/cli/chunk-61j18dwk.js.map +0 -58
  638. package/dist/cli/chunk-88by27n5.js +0 -17
  639. package/dist/cli/chunk-88by27n5.js.map +0 -10
  640. package/dist/cli/chunk-8cd8tj54.js.map +0 -34
  641. package/dist/cli/chunk-aztttvb3.js +0 -381
  642. package/dist/cli/chunk-aztttvb3.js.map +0 -12
  643. package/dist/cli/chunk-cvky9gb2.js.map +0 -11
  644. package/dist/cli/chunk-ejjx8znq.js.map +0 -15
  645. package/dist/cli/chunk-fmceyezb.js +0 -1007
  646. package/dist/cli/chunk-fmceyezb.js.map +0 -13
  647. package/dist/cli/chunk-hdm2dkd2.js.map +0 -48
  648. package/dist/cli/chunk-hs3gbh8p.js.map +0 -10
  649. package/dist/cli/chunk-jbj4qhfw.js +0 -30
  650. package/dist/cli/chunk-jbj4qhfw.js.map +0 -10
  651. package/dist/cli/chunk-mqb2ka8m.js +0 -68
  652. package/dist/cli/chunk-mqb2ka8m.js.map +0 -10
  653. package/dist/cli/chunk-mt76t7dj.js.map +0 -11
  654. package/dist/cli/chunk-q4rae3bg.js +0 -60
  655. package/dist/cli/chunk-q4rae3bg.js.map +0 -10
  656. package/dist/cli/chunk-ra1v2nc2.js +0 -35
  657. package/dist/cli/chunk-ra1v2nc2.js.map +0 -10
  658. package/dist/cli/chunk-t3tj0dgr.js.map +0 -15
  659. package/dist/cli/chunk-tqa1s0k8.js +0 -69
  660. package/dist/cli/chunk-tqa1s0k8.js.map +0 -11
  661. package/dist/cli/chunk-vh9w1sgp.js +0 -73
  662. package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
  663. package/dist/cli/chunk-vkrsvbr5.js +0 -107
  664. package/dist/cli/chunk-vkrsvbr5.js.map +0 -11
  665. package/dist/cli/chunk-vrfp10qk.js +0 -81
  666. package/dist/cli/chunk-vrfp10qk.js.map +0 -10
  667. package/dist/cli/chunk-wjt80jps.js +0 -1049
  668. package/dist/cli/chunk-wjt80jps.js.map +0 -24
  669. package/docs/advanced/api-reference.mdx +0 -240
  670. package/docs/reference/cli.mdx +0 -197
  671. package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
  672. package/src/components/content/changelog-element.ts +0 -69
  673. package/src/search/providers.ts +0 -91
  674. /package/dist/cli/{chunk-3w7b2vcx.js.map → chunk-7ez8ny0t.js.map} +0 -0
  675. /package/dist/cli/{chunk-688e0dde.js.map → chunk-88cpgt6h.js.map} +0 -0
  676. /package/dist/cli/{chunk-exeeb35e.js.map → chunk-f7t03s3g.js.map} +0 -0
  677. /package/dist/cli/{chunk-ppfvdcd4.js.map → chunk-zxccj738.js.map} +0 -0
@@ -0,0 +1,91 @@
1
+ import { normalizeBasePath, withBasePath } from "../core/base-path.ts";
2
+ import { EN_UI, resolveUIStrings } from "../core/i18n-ui.ts";
3
+ import type { BlumeProject } from "../core/project-graph.ts";
4
+ import { absoluteUrl } from "../core/site-url.ts";
5
+ import type { PageRecord } from "../core/types.ts";
6
+
7
+ /**
8
+ * The generated `/changelog` index as Markdown, for its `/changelog.md`
9
+ * mirror and MCP `get_page`: the timeline an agent would otherwise have to
10
+ * scrape out of the rendered page. Lists what the index page lists — every
11
+ * visible changelog entry of the current docs in the default locale, newest
12
+ * first, grouped by year — one line each, with its date and category and a
13
+ * link to the entry's own page.
14
+ */
15
+
16
+ interface IndexRow {
17
+ date: Date | null;
18
+ page: PageRecord;
19
+ }
20
+
21
+ const parseDate = (value: string | undefined): Date | null => {
22
+ if (value === undefined) {
23
+ return null;
24
+ }
25
+ const date = new Date(value);
26
+ return Number.isNaN(date.getTime()) ? null : date;
27
+ };
28
+
29
+ /** A row's link: absolute under a configured site, like llms.txt. */
30
+ const entryUrl = (project: BlumeProject, route: string): string => {
31
+ const { base, site } = project.config.deployment.options;
32
+ const path = withBasePath(normalizeBasePath(base), route);
33
+ return encodeURI(site ? absoluteUrl(site, path) : path);
34
+ };
35
+
36
+ const rowLine = (project: BlumeProject, { date, page }: IndexRow): string => {
37
+ const details = [
38
+ date ? date.toISOString().slice(0, 10) : "",
39
+ page.meta.changelog?.category ?? "",
40
+ ].filter(Boolean);
41
+ const title = page.title.replaceAll(/[[\]]/gu, String.raw`\$&`);
42
+ const tail = details.length > 0 ? ` — ${details.join(", ")}` : "";
43
+ return `- [${title}](${entryUrl(project, page.route)})${tail}`;
44
+ };
45
+
46
+ export const buildChangelogIndexMarkdown = (project: BlumeProject): string => {
47
+ const { i18n } = project.config;
48
+ const ui = i18n
49
+ ? resolveUIStrings(i18n.defaultLocale, {
50
+ defaultLocale: i18n.defaultLocale,
51
+ overrides: i18n.ui,
52
+ })
53
+ : EN_UI;
54
+ const rows: IndexRow[] = project.graph.pages
55
+ .filter(
56
+ (page) =>
57
+ page.contentType === "changelog" &&
58
+ !page.meta.draft &&
59
+ !page.meta.sidebar.hidden &&
60
+ !page.fallback &&
61
+ page.version === "" &&
62
+ (!i18n || page.locale === i18n.defaultLocale)
63
+ )
64
+ .map((page) => ({
65
+ date: parseDate(page.meta.date ?? page.meta.changelog?.date),
66
+ page,
67
+ }))
68
+ .toSorted((a, b) => (b.date?.getTime() ?? 0) - (a.date?.getTime() ?? 0));
69
+
70
+ const blocks = [`# ${ui.changelog.title}`, ui.changelog.description];
71
+ let year: number | null | undefined;
72
+ let lines: string[] = [];
73
+ const flush = (): void => {
74
+ if (lines.length > 0) {
75
+ blocks.push(lines.join("\n"));
76
+ lines = [];
77
+ }
78
+ };
79
+ for (const row of rows) {
80
+ const rowYear = row.date ? row.date.getUTCFullYear() : null;
81
+ if (rowYear !== year) {
82
+ flush();
83
+ year = rowYear;
84
+ // Undated entries sort last, under a heading of their own.
85
+ blocks.push(rowYear === null ? "## Undated" : `## ${rowYear}`);
86
+ }
87
+ lines.push(rowLine(project, row));
88
+ }
89
+ flush();
90
+ return `${blocks.join("\n\n")}\n`;
91
+ };
@@ -70,6 +70,15 @@ export const isString = <Value>(value: Value): value is Value & string =>
70
70
  const isNumber = <Value>(value: Value): value is Value & number =>
71
71
  typeof value === "number";
72
72
 
73
+ /** A nested map of evaluated values — an object literal prop, not a date or a list. */
74
+ const isValueMap = (
75
+ value: EvaluatedValue
76
+ ): value is { [key: string]: EvaluatedValue } =>
77
+ typeof value === "object" &&
78
+ value !== null &&
79
+ !Array.isArray(value) &&
80
+ !(value instanceof Date);
81
+
73
82
  /** Evaluated props plus whether any attribute resisted static evaluation. */
74
83
  interface EvaluatedProps {
75
84
  lossy: boolean;
@@ -216,17 +225,22 @@ const applySplices = (text: string, splices: Splice[]): string => {
216
225
  /**
217
226
  * Strip the common indentation JSX children carry in source (`<Step>` bodies
218
227
  * are typically indented two spaces under their tag). The first line starts
219
- * mid-line at the slice boundary, so the common prefix is measured on the
220
- * following lines only.
228
+ * mid-line at the slice boundary, already past its own indent, so that indent
229
+ * is passed in as `firstIndent` when it is known — the whitespace before the
230
+ * slice — and counts toward the common prefix. Without it a nested list
231
+ * (`- a` then ` - b`) would lose its nesting: the deeper following lines
232
+ * alone would set the prefix. When the slice starts after other text on its
233
+ * line (`<Step>Body…`), only the following lines are measured.
221
234
  */
222
- const dedent = (text: string): string => {
235
+ const dedent = (text: string, firstIndent?: number): string => {
223
236
  const lines = text.split("\n");
224
237
  const rest = lines.slice(1).filter((line) => line.trim() !== "");
225
238
  if (rest.length === 0) {
226
239
  return text;
227
240
  }
228
241
  const indent = Math.min(
229
- ...rest.map((line) => line.length - line.trimStart().length)
242
+ ...rest.map((line) => line.length - line.trimStart().length),
243
+ ...(firstIndent === undefined ? [] : [firstIndent])
230
244
  );
231
245
  if (indent === 0) {
232
246
  return text;
@@ -239,6 +253,16 @@ const dedent = (text: string): string => {
239
253
  ].join("\n");
240
254
  };
241
255
 
256
+ /**
257
+ * The indent of the line `offset` sits on, when everything before `offset` on
258
+ * that line is whitespace; `undefined` when the offset follows other text.
259
+ */
260
+ const indentAt = (source: string, offset: number): number | undefined => {
261
+ const lineStart = source.lastIndexOf("\n", offset - 1) + 1;
262
+ const prefix = source.slice(lineStart, offset);
263
+ return /^[\t ]*$/u.test(prefix) ? prefix.length : undefined;
264
+ };
265
+
242
266
  const isJsxElement = (node: MdastNode): boolean =>
243
267
  node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement";
244
268
 
@@ -442,11 +466,15 @@ const card: ComponentMarkdown = ({ children, lossy, props }) => {
442
466
  * JSX as a block of its own instead of vanishing beside a rendered sibling.
443
467
  * Passing the body slice through instead would leave each card's source
444
468
  * indentation in the output and run one card's title straight on from the
445
- * previous card's body as the same paragraph.
469
+ * previous card's body as the same paragraph. The other containers that are
470
+ * only layout — `Accordion`, `Columns`, `CodeGroup`, the `Color` palette —
471
+ * serialize the same way; a child that renders to nothing (an unlabeled
472
+ * `Icon`) leaves no gap.
446
473
  */
447
474
  const cardGroup: ComponentMarkdown = ({ childBlocks }) =>
448
475
  childBlocks()
449
476
  .map((block) => block.markdown)
477
+ .filter(Boolean)
450
478
  .join("\n\n");
451
479
 
452
480
  const youtube: ComponentMarkdown = ({ props }) => {
@@ -512,21 +540,308 @@ export const exampleComponentSerializers = (examples: ExampleLookup) =>
512
540
  },
513
541
  }) satisfies Record<string, ComponentMarkdown>;
514
542
 
543
+ /** A bold label over a body — the shape {@link tabs} and {@link card} use. */
544
+ const labeled = (label: string, ...parts: string[]): string =>
545
+ [label === "" ? "" : `**${label}**`, ...parts]
546
+ .map((part) => part.trim())
547
+ .filter(Boolean)
548
+ .join("\n\n");
549
+
550
+ /**
551
+ * A disclosure — `AccordionItem`, and `Expandable` with its "Show more"
552
+ * default — is its title over its body, open: an agent reads what a reader
553
+ * would have to click for. A title that wouldn't evaluate declines.
554
+ */
555
+ const disclosure = (
556
+ { children, lossy, props }: ComponentMarkdownContext,
557
+ fallbackTitle: string
558
+ ): string | null =>
559
+ lossy
560
+ ? null
561
+ : labeled(
562
+ textProp(props.title) || fallbackTitle,
563
+ textProp(props.description),
564
+ children
565
+ );
566
+
567
+ const accordionItem: ComponentMarkdown = (context) => disclosure(context, "");
568
+
569
+ const expandable: ComponentMarkdown = (context) =>
570
+ disclosure(context, "Show more");
571
+
572
+ /** `Frame` is its slot, with the hint above and the caption below as text. */
573
+ const frame: ComponentMarkdown = ({ children, props }) =>
574
+ [textProp(props.hint), children, textProp(props.caption)]
575
+ .filter(Boolean)
576
+ .join("\n\n");
577
+
578
+ /** A layout wrapper whose body is the whole of its meaning. */
579
+ const body: ComponentMarkdown = ({ children }) => children;
580
+
581
+ /** `Panel` is a titled aside: its title over its body. */
582
+ const panel: ComponentMarkdown = ({ children, props }) =>
583
+ labeled(textProp(props.title), children);
584
+
585
+ /**
586
+ * `Tile` is a card with a preview, so it takes {@link card}'s shape: the
587
+ * title as the link, then the description and the slot.
588
+ */
589
+ const tile: ComponentMarkdown = ({ children, lossy, props }) => {
590
+ if (lossy) {
591
+ return null;
592
+ }
593
+ const title = textProp(props.title);
594
+ const href = isString(props.href) ? props.href.trim() : "";
595
+ const label = title || href;
596
+ const head =
597
+ href === ""
598
+ ? labeled(label)
599
+ : `**[${linkText(label)}](${linkDestination(href)})**`;
600
+ const text = [head, textProp(props.description), children]
601
+ .filter(Boolean)
602
+ .join("\n\n");
603
+ return text === "" ? null : text;
604
+ };
605
+
606
+ /**
607
+ * `Update` is one changelog entry: its label (or title) as the head, linked
608
+ * when it has its own page, then the description, tags, and notes.
609
+ */
610
+ const update: ComponentMarkdown = ({ children, lossy, props }) => {
611
+ if (lossy) {
612
+ return null;
613
+ }
614
+ const label = textProp(props.label) || textProp(props.title) || "Update";
615
+ const href = isString(props.href) ? props.href.trim() : "";
616
+ const head =
617
+ href === ""
618
+ ? `**${label}**`
619
+ : `**[${linkText(label)}](${linkDestination(href)})**`;
620
+ const tags = (Array.isArray(props.tags) ? props.tags : [props.tags])
621
+ .map(textProp)
622
+ .filter(Boolean);
623
+ return [
624
+ head,
625
+ textProp(props.description),
626
+ tags.length > 0 ? `Tags: ${tags.join(", ")}` : "",
627
+ children,
628
+ ]
629
+ .filter(Boolean)
630
+ .join("\n\n");
631
+ };
632
+
633
+ /**
634
+ * `Prompt` is a prompt to copy: its description as the label, and the prompt
635
+ * itself quoted, the way a {@link callout} quotes its body.
636
+ */
637
+ const prompt: ComponentMarkdown = ({ children, props }) => {
638
+ const quoted = children
639
+ .split("\n")
640
+ .map((line) => (line.trim() === "" ? ">" : `> ${line}`))
641
+ .join("\n");
642
+ return labeled(
643
+ textProp(props.description) || "Prompt",
644
+ children ? quoted : ""
645
+ );
646
+ };
647
+
648
+ /**
649
+ * `GithubInfo` is a card for one repository, so it becomes a link to it. The
650
+ * site-wide repo the component falls back to isn't in reach here, so a card
651
+ * without `owner` and `repo` declines.
652
+ */
653
+ const githubInfo: ComponentMarkdown = ({ lossy, props }) => {
654
+ const owner = textProp(props.owner);
655
+ const repo = textProp(props.repo);
656
+ if (lossy || owner === "" || repo === "") {
657
+ return null;
658
+ }
659
+ const host = (textProp(props.host) || "https://github.com").replace(
660
+ /\/+$/u,
661
+ ""
662
+ );
663
+ return `[${linkText(`${owner}/${repo}`)}](${linkDestination(`${host}/${owner}/${repo}`)})`;
664
+ };
665
+
666
+ /** `CodeBlock` is a fenced block, its title kept in the fence's meta. */
667
+ const codeBlock: ComponentMarkdown = ({ lossy, props }) => {
668
+ if (lossy || !isString(props.code)) {
669
+ return null;
670
+ }
671
+ const lang = textProp(props.lang) || "txt";
672
+ const title = textProp(props.title);
673
+ return fencedBlock(
674
+ title === "" ? lang : `${lang} title=${JSON.stringify(title)}`,
675
+ props.code
676
+ );
677
+ };
678
+
679
+ /**
680
+ * `Diff` from an inline patch is that patch, fenced as `diff`; from `old` and
681
+ * `new` strings, both sides fenced in turn. A diff read from files (`src`,
682
+ * `before`/`after`) needs the file system, so it declines.
683
+ */
684
+ const diff: ComponentMarkdown = ({ lossy, props }) => {
685
+ if (lossy) {
686
+ return null;
687
+ }
688
+ if (isString(props.patch)) {
689
+ return fencedBlock("diff", props.patch);
690
+ }
691
+ if (isString(props.old) && isString(props.new)) {
692
+ const lang = textProp(props.lang);
693
+ return [
694
+ labeled("Before", fencedBlock(lang, props.old)),
695
+ labeled("After", fencedBlock(lang, props.new)),
696
+ ].join("\n\n");
697
+ }
698
+ return null;
699
+ };
700
+
701
+ /** `Math` is its TeX source, as a display block or inline span. */
702
+ const math: ComponentMarkdown = ({ lossy, props }) => {
703
+ if (lossy || !isString(props.code)) {
704
+ return null;
705
+ }
706
+ return props.display === true ? `$$\n${props.code}\n$$` : `$${props.code}$`;
707
+ };
708
+
709
+ /** An `Icon` is decoration; one with an accessible label keeps the label. */
710
+ const icon: ComponentMarkdown = ({ props }) => textProp(props.label);
711
+
712
+ /** A `Badge` is its text. */
713
+ const badge: ComponentMarkdown = ({ children }) => children;
714
+
715
+ /**
716
+ * A `Tooltip` is its trigger text followed by the tip, which is otherwise
717
+ * only on hover: `term (tip)`, with the headline leading the tip.
718
+ */
719
+ const tooltip: ComponentMarkdown = ({ children, lossy, props }) => {
720
+ const tip = [textProp(props.headline), textProp(props.tip)]
721
+ .filter(Boolean)
722
+ .join(": ");
723
+ if (lossy || tip === "") {
724
+ return null;
725
+ }
726
+ return children ? `${children} (${tip})` : tip;
727
+ };
728
+
729
+ /** Indent a list block's lines under its parent item. */
730
+ const nested = (block: string): string =>
731
+ block
732
+ .split("\n")
733
+ .map((line) => (line === "" ? line : ` ${line}`))
734
+ .join("\n");
735
+
736
+ /**
737
+ * `Tree` is the nested list it draws: each folder an item with a trailing
738
+ * slash and its entries indented under it, each file an item.
739
+ */
740
+ const treeList: ComponentMarkdown = ({ childBlocks }) =>
741
+ childBlocks()
742
+ .map((block) => block.markdown)
743
+ .join("\n");
744
+
745
+ const treeFolder: ComponentMarkdown = ({ childBlocks, lossy, props }) => {
746
+ const name = textProp(props.name);
747
+ if (lossy || name === "") {
748
+ return null;
749
+ }
750
+ const entries = childBlocks()
751
+ .map((block) => nested(block.markdown))
752
+ .join("\n");
753
+ return entries === "" ? `- ${name}/` : `- ${name}/\n${entries}`;
754
+ };
755
+
756
+ const treeFile: ComponentMarkdown = ({ lossy, props }) => {
757
+ const name = textProp(props.name);
758
+ return lossy || name === "" ? null : `- ${name}`;
759
+ };
760
+
761
+ /**
762
+ * A `Color.Item` is its name and value — both values when the light and dark
763
+ * themes differ — and a `Color.Row` its title over its items.
764
+ */
765
+ const colorItem: ComponentMarkdown = ({ lossy, props }) => {
766
+ const name = textProp(props.name);
767
+ const { value } = props;
768
+ if (lossy || name === "") {
769
+ return null;
770
+ }
771
+ if (isString(value)) {
772
+ return `- **${name}**: ${inlineCode(value)}`;
773
+ }
774
+ if (!isValueMap(value)) {
775
+ return null;
776
+ }
777
+ const light = textProp(value.light);
778
+ const dark = textProp(value.dark);
779
+ if (light === "" && dark === "") {
780
+ return null;
781
+ }
782
+ const shown =
783
+ light && dark && light !== dark
784
+ ? `${inlineCode(light)} (light), ${inlineCode(dark)} (dark)`
785
+ : inlineCode(light || dark);
786
+ return `- **${name}**: ${shown}`;
787
+ };
788
+
789
+ const colorRow: ComponentMarkdown = ({ childBlocks, props }) =>
790
+ labeled(
791
+ textProp(props.title),
792
+ childBlocks()
793
+ .map((block) => block.markdown)
794
+ .join("\n")
795
+ );
796
+
515
797
  /**
516
798
  * The built-in serializer registry, keyed by JSX name. `Step` and `Tab` are
517
799
  * intentionally absent: they only carry meaning inside their containers,
518
800
  * which extract them via `childComponents`; a stray one stays verbatim.
801
+ * `AutoTypeTable` is absent too: its table comes from type-checking a source
802
+ * file, which a serializer can't do synchronously, so it stays as JSX.
519
803
  */
520
804
  const SERIALIZERS = {
805
+ Accordion: cardGroup,
806
+ AccordionItem: accordionItem,
807
+ Badge: badge,
521
808
  Callout: callout,
522
809
  Card: card,
523
810
  CardGroup: cardGroup,
811
+ CodeBlock: codeBlock,
812
+ CodeGroup: cardGroup,
813
+ Color: cardGroup,
814
+ "Color.Item": colorItem,
815
+ "Color.Row": colorRow,
816
+ Column: body,
817
+ Columns: cardGroup,
818
+ Diff: diff,
819
+ Expandable: expandable,
820
+ FileTree: body,
821
+ Frame: frame,
822
+ GithubInfo: githubInfo,
823
+ Icon: icon,
824
+ Math: math,
825
+ Panel: panel,
826
+ Prompt: prompt,
524
827
  Steps: steps,
525
828
  Tabs: tabs,
829
+ Tile: tile,
830
+ Tooltip: tooltip,
831
+ Tree: treeList,
832
+ "Tree.File": treeFile,
833
+ "Tree.Folder": treeFolder,
526
834
  TypeTable: typeTable,
835
+ Update: update,
527
836
  YouTube: youtube,
528
837
  } satisfies Record<string, ComponentMarkdown>;
529
838
 
839
+ /**
840
+ * The built-ins that sit inside a line of prose, and so are downleveled as
841
+ * text elements too: each renders to a single line.
842
+ */
843
+ const INLINE_COMPONENTS = new Set(["Badge", "Icon", "Math", "Tooltip"]);
844
+
530
845
  const escapeRegExp = (value: string): string =>
531
846
  value.replaceAll(/[$()*+.?[\\\]^{|}]/gu, String.raw`\$&`);
532
847
 
@@ -550,7 +865,7 @@ export interface DownlevelWalk {
550
865
  }
551
866
  type Walk = DownlevelWalk;
552
867
 
553
- /** The serializer registry for a site: built-ins under a user's `ai.markdownComponents`. */
868
+ /** The serializer registry for a site: built-ins under a user's `agents.markdownComponents`. */
554
869
  export const componentRegistry = (
555
870
  components?: Record<string, ComponentMarkdown>
556
871
  ): Record<string, ComponentMarkdown> =>
@@ -581,7 +896,7 @@ const renderSlice = (
581
896
  start: splice.start - start,
582
897
  }))
583
898
  );
584
- return dedent(spliced).trim();
899
+ return dedent(spliced, indentAt(walk.source, start)).trim();
585
900
  };
586
901
 
587
902
  /** The element's body as Markdown: the slice covering all of its children. */
@@ -662,10 +977,11 @@ export const downlevelComponentNode = (
662
977
  node: MdastNode,
663
978
  walk: DownlevelWalk
664
979
  ): string | null => {
665
- const serializer =
666
- node.type === "mdxJsxFlowElement" && node.name
667
- ? walk.registry[node.name]
668
- : undefined;
980
+ const block =
981
+ node.type === "mdxJsxFlowElement" ||
982
+ (node.type === "mdxJsxTextElement" &&
983
+ INLINE_COMPONENTS.has(node.name ?? ""));
984
+ const serializer = block && node.name ? walk.registry[node.name] : undefined;
669
985
  return serializer && hasOffsets(node)
670
986
  ? serializeElement(serializer, walk, node)
671
987
  : null;
@@ -695,7 +1011,7 @@ const collectSplices = (
695
1011
  * with no supported components — and sources Satteri can't parse as MDX, e.g.
696
1012
  * plain `.md` with literal `<`/`{` — are returned byte-identical.
697
1013
  *
698
- * `components` adds user serializers from `ai.markdownComponents`, layered
1014
+ * `components` adds user serializers from `agents.markdownComponents`, layered
699
1015
  * over the built-ins: a same-name entry replaces the built-in serializer, and
700
1016
  * one that always returns `null` effectively opts that component out.
701
1017
  *
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Ask AI provider adapters for `blume.config.ts`:
3
+ *
4
+ * ```ts
5
+ * import { defineConfig } from "blume";
6
+ * import { openrouter } from "blume/ai";
7
+ *
8
+ * export default defineConfig({
9
+ * ai: {
10
+ * ask: {
11
+ * enabled: true,
12
+ * provider: openrouter({ model: "anthropic/claude-sonnet-4-5" }),
13
+ * },
14
+ * },
15
+ * });
16
+ * ```
17
+ *
18
+ * Each factory returns a plain descriptor (see `core/adapter.ts`) that the
19
+ * schema validates and the generated `/api/ask` route inlines as literals;
20
+ * nothing here runs at request time.
21
+ */
22
+ export {
23
+ gateway,
24
+ inkeep,
25
+ llmgateway,
26
+ openaiCompatible,
27
+ openrouter,
28
+ } from "./ask.ts";
29
+ export type {
30
+ AskAdapter,
31
+ AskAdapterOptions,
32
+ AskGatewayAdapter,
33
+ AskGatewayOptions,
34
+ AskInkeepAdapter,
35
+ AskInkeepOptions,
36
+ AskLlmGatewayAdapter,
37
+ AskLlmGatewayOptions,
38
+ AskOpenAICompatibleAdapter,
39
+ AskOpenAICompatibleOptions,
40
+ AskOpenRouterAdapter,
41
+ AskOpenRouterOptions,
42
+ AskProviderOptions,
43
+ AskReasoning,
44
+ } from "./ask.ts";
45
+ export type { AdapterDescriptor } from "../core/adapter.ts";
@@ -1,5 +1,10 @@
1
1
  import { normalizeBasePath } from "../core/base-path.ts";
2
2
  import type { ResolvedConfig } from "../core/schema.ts";
3
+ import {
4
+ AI_CATALOG_PATH,
5
+ AI_CATALOG_TYPE,
6
+ hasAiCatalog,
7
+ } from "./ai-catalog.ts";
3
8
  import { API_CATALOG_PATH, hasApiCatalog } from "./api-catalog.ts";
4
9
  import { OPENAPI_PATH } from "./api/paths.ts";
5
10
 
@@ -19,8 +24,9 @@ import { OPENAPI_PATH } from "./api/paths.ts";
19
24
  * could. An agent that enters on a deep page (a search result, a shared link)
20
25
  * never sees this header at all — that path is covered in the HTML instead:
21
26
  * every page's `<head>` carries the same `describedby` links plus its own
22
- * Markdown mirror as an `alternate` (see `RootLayout.astro`), which also
23
- * reaches hosts where Blume can't set response headers. Targets are
27
+ * Markdown mirror as an `alternate` (the `DiscoveryLinks.astro` partial every
28
+ * layout renders), which also reaches hosts where Blume can't set response
29
+ * headers. Targets are
24
30
  * root-relative under `deployment.base` — RFC 8288 resolves them against the
25
31
  * request URL. Returns null when nothing is advertisable.
26
32
  */
@@ -28,7 +34,7 @@ export const buildHomeLinkHeader = (
28
34
  config: ResolvedConfig,
29
35
  routePaths: readonly string[]
30
36
  ): string | null => {
31
- const deployBase = normalizeBasePath(config.deployment.base);
37
+ const deployBase = normalizeBasePath(config.deployment.options.base);
32
38
  const links: string[] = [];
33
39
  // RFC 9727 §3: the api-catalog relation is how a homepage advertises the
34
40
  // well-known catalog.
@@ -37,19 +43,26 @@ export const buildHomeLinkHeader = (
37
43
  `<${deployBase}${API_CATALOG_PATH}>; rel="api-catalog"; type="application/linkset+json"`
38
44
  );
39
45
  }
46
+ // The ai-catalog spec's own relation for its well-known document, the
47
+ // header form of the `<link rel="ai-catalog">` every page carries.
48
+ if (hasAiCatalog(config)) {
49
+ links.push(
50
+ `<${deployBase}${AI_CATALOG_PATH}>; rel="ai-catalog"; type="${AI_CATALOG_TYPE}"`
51
+ );
52
+ }
40
53
  // RFC 8631: `service-desc` is the relation for a machine-readable
41
54
  // description of the service — the JSON docs API's OpenAPI document.
42
- if (config.ai.api) {
55
+ if (config.agents.api) {
43
56
  links.push(
44
57
  `<${deployBase}${OPENAPI_PATH}>; rel="service-desc"; type="application/json"`
45
58
  );
46
59
  }
47
- if (config.seo.agentReadability) {
60
+ if (config.agents.agentReadability) {
48
61
  links.push(
49
62
  `<${deployBase}/agent-readability.json>; rel="describedby"; type="application/json"`
50
63
  );
51
64
  }
52
- if (config.ai.llmsTxt.enabled) {
65
+ if (config.agents.llmsTxt.enabled) {
53
66
  links.push(
54
67
  `<${deployBase}/llms.txt>; rel="describedby"; type="text/plain"`
55
68
  );