blume 2.0.1 → 2.0.3

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 (492) hide show
  1. package/CHANGELOG.md +147 -0
  2. package/dist/cli/{chunk-qwsrynx5.js → chunk-1d7ve1dm.js} +38 -19
  3. package/dist/cli/{chunk-qwsrynx5.js.map → chunk-1d7ve1dm.js.map} +4 -4
  4. package/dist/cli/{chunk-s6jhgk0q.js → chunk-2eytanqx.js} +2 -2
  5. package/dist/cli/{chunk-kdp5q7ke.js → chunk-2hsdwb9n.js} +18 -19
  6. package/dist/cli/{chunk-kdp5q7ke.js.map → chunk-2hsdwb9n.js.map} +2 -2
  7. package/dist/cli/{chunk-hdpx1tax.js → chunk-2z928egk.js} +5 -5
  8. package/dist/cli/{chunk-jwyddg7y.js → chunk-35d4wj9f.js} +30 -24
  9. package/dist/cli/chunk-35d4wj9f.js.map +15 -0
  10. package/dist/cli/{chunk-ah61y8py.js → chunk-364znk6q.js} +2 -2
  11. package/dist/cli/{chunk-jts8mvcz.js → chunk-3em5wd2y.js} +25 -6
  12. package/dist/cli/{chunk-jts8mvcz.js.map → chunk-3em5wd2y.js.map} +3 -3
  13. package/dist/cli/{chunk-s1p84fyh.js → chunk-5f86nr5m.js} +63 -22
  14. package/dist/cli/chunk-5f86nr5m.js.map +11 -0
  15. package/dist/cli/{chunk-2hn4b8z7.js → chunk-5m5nmvyq.js} +170 -76
  16. package/dist/cli/chunk-5m5nmvyq.js.map +13 -0
  17. package/dist/cli/{chunk-epjnccmv.js → chunk-5xvm6tfj.js} +18 -15
  18. package/dist/cli/chunk-5xvm6tfj.js.map +10 -0
  19. package/dist/cli/{chunk-fz5wtpmh.js → chunk-6dsbexzp.js} +18 -15
  20. package/dist/cli/chunk-6dsbexzp.js.map +10 -0
  21. package/dist/cli/{chunk-vtk4a6dg.js → chunk-8ktnccpt.js} +1 -1
  22. package/dist/cli/{chunk-6hsn950k.js → chunk-9t7a85s3.js} +178 -48
  23. package/dist/cli/chunk-9t7a85s3.js.map +10 -0
  24. package/dist/cli/{chunk-fxypxtvm.js → chunk-a58773jm.js} +2 -2
  25. package/dist/cli/{chunk-mb2919y2.js → chunk-acanzt5p.js} +17 -6
  26. package/dist/cli/chunk-acanzt5p.js.map +10 -0
  27. package/dist/cli/{chunk-27g6wdth.js → chunk-akbpwfxc.js} +90 -26
  28. package/dist/cli/chunk-akbpwfxc.js.map +10 -0
  29. package/dist/cli/{chunk-wm7js3j9.js → chunk-b07cmahc.js} +2 -2
  30. package/dist/cli/{chunk-wgm7m9qk.js → chunk-c8chx29p.js} +179 -51
  31. package/dist/cli/chunk-c8chx29p.js.map +36 -0
  32. package/dist/cli/{chunk-qs4q5p4e.js → chunk-crgn1q09.js} +32 -14
  33. package/dist/cli/chunk-crgn1q09.js.map +10 -0
  34. package/dist/cli/chunk-e04dxsz1.js +39 -0
  35. package/dist/cli/chunk-e04dxsz1.js.map +10 -0
  36. package/dist/cli/{chunk-yt5n7ppj.js → chunk-ey84smr6.js} +17 -7
  37. package/dist/cli/chunk-ey84smr6.js.map +10 -0
  38. package/dist/cli/{chunk-f2z5v128.js → chunk-g4hq16wv.js} +14 -15
  39. package/dist/cli/{chunk-f2z5v128.js.map → chunk-g4hq16wv.js.map} +2 -2
  40. package/dist/cli/{chunk-fa25z98p.js → chunk-ga0pf4aj.js} +9 -8
  41. package/dist/cli/chunk-ga0pf4aj.js.map +11 -0
  42. package/dist/cli/{chunk-kpf8rrjc.js → chunk-hm3vjy5s.js} +109 -58
  43. package/dist/cli/chunk-hm3vjy5s.js.map +19 -0
  44. package/dist/cli/{chunk-fs23ddbb.js → chunk-j85vccga.js} +625 -750
  45. package/dist/cli/chunk-j85vccga.js.map +36 -0
  46. package/dist/cli/{chunk-ch6g3ar0.js → chunk-p3v96n38.js} +6 -6
  47. package/dist/cli/{chunk-ch6g3ar0.js.map → chunk-p3v96n38.js.map} +3 -3
  48. package/dist/cli/{chunk-q5163e60.js → chunk-p73c0m7w.js} +21 -19
  49. package/dist/cli/chunk-p73c0m7w.js.map +11 -0
  50. package/dist/cli/{chunk-dh8cwk36.js → chunk-pehfxfta.js} +24 -9
  51. package/dist/cli/chunk-pehfxfta.js.map +10 -0
  52. package/dist/cli/{chunk-qkqwkpte.js → chunk-pv29h0wf.js} +3688 -1313
  53. package/dist/cli/chunk-pv29h0wf.js.map +190 -0
  54. package/dist/cli/{chunk-6vm74dry.js → chunk-q58y5e6a.js} +10 -10
  55. package/dist/cli/{chunk-6vm74dry.js.map → chunk-q58y5e6a.js.map} +3 -3
  56. package/dist/cli/{chunk-zxcczpyx.js → chunk-r20tn01b.js} +1 -1
  57. package/dist/cli/{chunk-m3vmjgmq.js → chunk-r9rcc4w7.js} +16 -8
  58. package/dist/cli/chunk-r9rcc4w7.js.map +10 -0
  59. package/dist/cli/{chunk-5shv93fd.js → chunk-tkacnehg.js} +2 -2
  60. package/dist/cli/{chunk-zxh4d9vy.js → chunk-tzmab476.js} +4 -4
  61. package/dist/cli/{chunk-yw7dm696.js → chunk-vg9r4eb9.js} +24 -11
  62. package/dist/cli/chunk-vg9r4eb9.js.map +14 -0
  63. package/dist/cli/{chunk-79jhk4py.js → chunk-wrr3j9w9.js} +260 -132
  64. package/dist/cli/chunk-wrr3j9w9.js.map +35 -0
  65. package/dist/cli/{chunk-6crbhc3x.js → chunk-yfyb25rh.js} +54 -27
  66. package/dist/cli/chunk-yfyb25rh.js.map +14 -0
  67. package/dist/cli/index.js +162 -35
  68. package/dist/cli/index.js.map +4 -4
  69. package/dist/types/ai/agent-surface.d.ts +32 -0
  70. package/dist/types/ai/api-catalog.d.ts +7 -1
  71. package/dist/types/ai/ask-context.d.ts +7 -0
  72. package/dist/types/ai/component-markdown.d.ts +4 -4
  73. package/dist/types/ai/link-headers.d.ts +8 -1
  74. package/dist/types/ai/openapi-components.d.ts +5 -2
  75. package/dist/types/ai/relative-links.d.ts +11 -4
  76. package/dist/types/ai/skills.d.ts +4 -1
  77. package/dist/types/ai/static-expression.d.ts +28 -0
  78. package/dist/types/ai/tar.d.ts +1 -3
  79. package/dist/types/analytics/databuddy.d.ts +43 -0
  80. package/dist/types/analytics/index.d.ts +4 -0
  81. package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
  82. package/dist/types/analytics/schema.d.ts +28 -0
  83. package/dist/types/astro/integration.d.ts +3 -2
  84. package/dist/types/cli/env.d.ts +5 -0
  85. package/dist/types/cli/init/scaffold.d.ts +19 -3
  86. package/dist/types/cli/init/starter-spec.d.ts +11 -0
  87. package/dist/types/core/base-path.d.ts +24 -1
  88. package/dist/types/core/config-input.d.ts +13 -11
  89. package/dist/types/core/config.d.ts +2 -2
  90. package/dist/types/core/directive-diagnostics.d.ts +12 -0
  91. package/dist/types/core/graph.d.ts +2 -0
  92. package/dist/types/core/heading-markers.d.ts +5 -7
  93. package/dist/types/core/i18n-ui.d.ts +31 -0
  94. package/dist/types/core/i18n.d.ts +9 -1
  95. package/dist/types/core/last-modified.d.ts +10 -0
  96. package/dist/types/core/links.d.ts +3 -1
  97. package/dist/types/core/load-module.d.ts +10 -0
  98. package/dist/types/core/locale-links.d.ts +12 -2
  99. package/dist/types/core/meta.d.ts +13 -1
  100. package/dist/types/core/nav-diagnostics.d.ts +10 -0
  101. package/dist/types/core/navigation.d.ts +38 -0
  102. package/dist/types/core/ordering-prefix.d.ts +4 -0
  103. package/dist/types/core/safe-links.d.ts +3 -1
  104. package/dist/types/core/schema.d.ts +59 -13
  105. package/dist/types/core/sources/github-releases.d.ts +5 -0
  106. package/dist/types/core/sources/lower.d.ts +38 -13
  107. package/dist/types/core/sources/normalize.d.ts +23 -2
  108. package/dist/types/core/sources/remote.d.ts +11 -1
  109. package/dist/types/core/sources/resolve.d.ts +12 -0
  110. package/dist/types/core/sources/types.d.ts +31 -0
  111. package/dist/types/core/sources/watch.d.ts +12 -5
  112. package/dist/types/core/standard-schema.d.ts +5 -0
  113. package/dist/types/core/types.d.ts +9 -0
  114. package/dist/types/deploy/adapters/node.d.ts +5 -2
  115. package/dist/types/deploy/adapters/types.d.ts +7 -0
  116. package/dist/types/deploy/artifacts.d.ts +6 -4
  117. package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
  118. package/dist/types/deploy/headers.d.ts +36 -7
  119. package/dist/types/deploy/node-headers.d.ts +43 -8
  120. package/dist/types/deploy/platforms/netlify.d.ts +27 -2
  121. package/dist/types/deploy/platforms/node.d.ts +6 -5
  122. package/dist/types/deploy/platforms/types.d.ts +15 -0
  123. package/dist/types/deploy/platforms/vercel.d.ts +3 -2
  124. package/dist/types/deploy/redirects.d.ts +31 -15
  125. package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
  126. package/dist/types/markdown/directives.d.ts +62 -0
  127. package/dist/types/markdown/features.d.ts +21 -0
  128. package/dist/types/markdown/mdast.d.ts +63 -0
  129. package/dist/types/openapi/asyncapi.d.ts +4 -2
  130. package/dist/types/openapi/model.d.ts +20 -6
  131. package/dist/types/search/sync/algolia.d.ts +3 -1
  132. package/docs/01-quickstart.mdx +3 -2
  133. package/docs/02-deployment.mdx +20 -9
  134. package/docs/08-faq.mdx +10 -3
  135. package/docs/advanced/changelog.mdx +1 -1
  136. package/docs/advanced/custom-pages.mdx +7 -5
  137. package/docs/cli/audit.mdx +19 -3
  138. package/docs/cli/doctor.mdx +2 -2
  139. package/docs/cli/evals.mdx +4 -4
  140. package/docs/cli/index.mdx +4 -1
  141. package/docs/cli/translate.mdx +4 -4
  142. package/docs/cli/version.mdx +1 -1
  143. package/docs/configuration/analytics.mdx +42 -2
  144. package/docs/configuration/assistant.mdx +1 -1
  145. package/docs/configuration/customization.mdx +6 -3
  146. package/docs/configuration/index.mdx +5 -3
  147. package/docs/configuration/search.mdx +2 -2
  148. package/docs/content/components.mdx +2 -2
  149. package/docs/content/frontmatter.mdx +5 -1
  150. package/docs/content/i18n.mdx +3 -1
  151. package/docs/content/index.mdx +8 -4
  152. package/docs/content/islands.mdx +1 -1
  153. package/docs/content/meta.mdx +7 -3
  154. package/docs/content/navigation.mdx +29 -4
  155. package/docs/content/sources.mdx +18 -16
  156. package/docs/content/syntax.mdx +14 -0
  157. package/docs/content/versioning.mdx +2 -1
  158. package/docs/discoverability/agent-discovery.mdx +22 -8
  159. package/docs/discoverability/index.mdx +4 -3
  160. package/docs/discoverability/llms-txt.mdx +2 -5
  161. package/docs/discoverability/markdown.mdx +6 -4
  162. package/docs/discoverability/mcp.mdx +4 -0
  163. package/docs/discoverability/metadata.mdx +3 -2
  164. package/docs/discoverability/open-graph.mdx +8 -4
  165. package/docs/discoverability/rss.mdx +4 -2
  166. package/docs/references/asyncapi.mdx +2 -2
  167. package/docs/references/graphql.mdx +2 -2
  168. package/docs/references/openapi.mdx +6 -4
  169. package/package.json +1 -1
  170. package/skills/blume-migrate/SKILL.md +6 -6
  171. package/skills/blume-migrate/references/docusaurus.md +6 -6
  172. package/skills/blume-migrate/references/fumadocs.md +1 -1
  173. package/skills/blume-migrate/references/mintlify.md +3 -3
  174. package/skills/blume-migrate/references/monorepo.md +1 -1
  175. package/skills/blume-migrate/references/nextra.md +2 -2
  176. package/skills/blume-migrate/references/starlight.md +5 -5
  177. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +9 -4
  178. package/skills/blume-update-docs/references/audit-checklist.md +1 -1
  179. package/src/ai/agent-readability.ts +2 -2
  180. package/src/ai/agent-surface.ts +56 -0
  181. package/src/ai/ai-catalog.ts +6 -2
  182. package/src/ai/api/handlers.ts +2 -2
  183. package/src/ai/api/spec.ts +17 -4
  184. package/src/ai/api-catalog.ts +13 -3
  185. package/src/ai/ask-context.ts +14 -2
  186. package/src/ai/ask-data.ts +26 -12
  187. package/src/ai/changelog-markdown.ts +2 -2
  188. package/src/ai/component-markdown.ts +43 -37
  189. package/src/ai/link-headers.ts +22 -8
  190. package/src/ai/llms.ts +22 -10
  191. package/src/ai/markdown.ts +23 -11
  192. package/src/ai/mcp/discovery.ts +2 -2
  193. package/src/ai/mcp/query.ts +2 -2
  194. package/src/ai/mcp/server.ts +80 -9
  195. package/src/ai/openapi-components.ts +22 -6
  196. package/src/ai/relative-links.ts +99 -15
  197. package/src/ai/serializers.ts +2 -1
  198. package/src/ai/skills.ts +14 -1
  199. package/src/ai/static-expression.ts +416 -0
  200. package/src/ai/tar.ts +139 -12
  201. package/src/ai/visibility.ts +45 -14
  202. package/src/analytics/databuddy.ts +67 -0
  203. package/src/analytics/head.ts +8 -0
  204. package/src/analytics/index.ts +7 -0
  205. package/src/analytics/one-dollar-stats.ts +86 -0
  206. package/src/analytics/posthog.ts +21 -3
  207. package/src/analytics/schema.ts +4 -0
  208. package/src/astro/generate.ts +72 -28
  209. package/src/astro/include-hmr.ts +31 -12
  210. package/src/astro/include-refresh.ts +19 -8
  211. package/src/astro/integration.ts +108 -14
  212. package/src/astro/runtime-modules.ts +28 -13
  213. package/src/astro/templates.ts +139 -57
  214. package/src/audit/catalog.ts +2 -2
  215. package/src/audit/checks/assets.ts +25 -5
  216. package/src/audit/checks/content.ts +20 -2
  217. package/src/audit/checks/i18n.ts +46 -8
  218. package/src/audit/checks/indexability.ts +39 -19
  219. package/src/audit/checks/links.ts +22 -1
  220. package/src/audit/checks/llms.ts +6 -3
  221. package/src/audit/checks/network.ts +3 -1
  222. package/src/audit/checks/og-image.ts +10 -0
  223. package/src/audit/checks/robots.ts +6 -1
  224. package/src/audit/checks/sitemap.ts +56 -31
  225. package/src/audit/checks/social.ts +21 -2
  226. package/src/audit/crawl.ts +88 -15
  227. package/src/audit/graph.ts +3 -1
  228. package/src/audit/report.ts +54 -17
  229. package/src/audit/run.ts +13 -9
  230. package/src/audit/snapshot.ts +5 -0
  231. package/src/audit/types.ts +18 -0
  232. package/src/audit/url.ts +37 -6
  233. package/src/cli/args.ts +32 -0
  234. package/src/cli/build-failure.ts +50 -0
  235. package/src/cli/commands/audit.ts +11 -1
  236. package/src/cli/commands/build.ts +19 -5
  237. package/src/cli/commands/check.ts +2 -0
  238. package/src/cli/commands/doctor.ts +3 -1
  239. package/src/cli/commands/eval.ts +20 -18
  240. package/src/cli/commands/init.ts +15 -5
  241. package/src/cli/commands/preview.ts +15 -0
  242. package/src/cli/commands/sync.ts +2 -0
  243. package/src/cli/commands/translate.ts +18 -18
  244. package/src/cli/commands/upgrade.ts +11 -0
  245. package/src/cli/commands/validate.ts +3 -1
  246. package/src/cli/dev-lock.ts +157 -37
  247. package/src/cli/eject-scripts.ts +32 -7
  248. package/src/cli/env.ts +12 -1
  249. package/src/cli/init/scaffold.ts +117 -11
  250. package/src/cli/init/starter-spec.ts +235 -0
  251. package/src/cli/report-format.ts +11 -6
  252. package/src/components/colors.ts +19 -0
  253. package/src/components/content/AccordionItem.astro +26 -22
  254. package/src/components/content/Badge.astro +7 -12
  255. package/src/components/content/Card.astro +2 -2
  256. package/src/components/content/Component.astro +11 -5
  257. package/src/components/content/Expandable.astro +5 -1
  258. package/src/components/content/Frame.astro +2 -7
  259. package/src/components/content/GithubInfo.astro +12 -2
  260. package/src/components/content/Prompt.astro +2 -7
  261. package/src/components/content/Tab.astro +0 -1
  262. package/src/components/content/Tabs.astro +58 -5
  263. package/src/components/content/Tile.astro +1 -1
  264. package/src/components/content/Tooltip.astro +69 -7
  265. package/src/components/content/Tree.astro +7 -2
  266. package/src/components/content/TypeTable.astro +10 -5
  267. package/src/components/content/Update.astro +8 -2
  268. package/src/components/content/auto-type-table.ts +4 -1
  269. package/src/components/content/badge-color.ts +20 -0
  270. package/src/components/content/base-href.ts +14 -22
  271. package/src/components/content/inline-markdown.ts +27 -7
  272. package/src/components/copy-feedback.ts +35 -8
  273. package/src/components/islands/assistant.tsx +37 -6
  274. package/src/components/islands/base-path.ts +47 -10
  275. package/src/components/islands/hooks.ts +42 -21
  276. package/src/components/islands/webmcp.ts +16 -10
  277. package/src/components/layout/Banner.astro +23 -4
  278. package/src/components/layout/Breadcrumbs.astro +5 -2
  279. package/src/components/layout/DiscoveryLinks.astro +9 -5
  280. package/src/components/layout/Header.astro +23 -10
  281. package/src/components/layout/LanguageSwitcher.astro +2 -2
  282. package/src/components/layout/Logo.astro +5 -0
  283. package/src/components/layout/NavSelector.astro +8 -3
  284. package/src/components/layout/NavTabMenu.astro +133 -0
  285. package/src/components/layout/NavTree.astro +31 -12
  286. package/src/components/layout/NavTreeCache.astro +5 -2
  287. package/src/components/layout/NavTreeScript.astro +45 -5
  288. package/src/components/layout/PageActions.astro +4 -3
  289. package/src/components/layout/PageLayout.astro +28 -13
  290. package/src/components/layout/Pagination.astro +3 -3
  291. package/src/components/layout/ReferenceLayout.astro +4 -1
  292. package/src/components/layout/RootLayout.astro +25 -12
  293. package/src/components/layout/Search.astro +38 -14
  294. package/src/components/layout/VersionBanner.astro +2 -2
  295. package/src/components/layout/analytics-client.ts +14 -0
  296. package/src/components/layout/toc-active.ts +41 -0
  297. package/src/components/layout/toc-element.ts +8 -14
  298. package/src/components/openapi/ApiTagOperations.astro +2 -2
  299. package/src/components/openapi/AsyncApiOperation.astro +7 -4
  300. package/src/components/openapi/GraphqlChip.astro +2 -2
  301. package/src/components/openapi/GraphqlType.astro +11 -3
  302. package/src/components/openapi/MessageComposer.astro +1 -1
  303. package/src/components/openapi/Operation.astro +23 -5
  304. package/src/components/openapi/PanelTabs.astro +4 -1
  305. package/src/components/openapi/Playground.astro +8 -2
  306. package/src/components/openapi/RequestPanel.astro +13 -6
  307. package/src/components/openapi/SchemaProperty.astro +11 -33
  308. package/src/components/openapi/SchemaTable.astro +34 -52
  309. package/src/components/openapi/async.ts +38 -6
  310. package/src/components/openapi/helpers.ts +100 -12
  311. package/src/components/openapi/message-composer.ts +14 -1
  312. package/src/components/openapi/message-model.ts +12 -2
  313. package/src/components/openapi/message.ts +21 -3
  314. package/src/components/openapi/operation-model.ts +119 -17
  315. package/src/components/openapi/panel.ts +31 -5
  316. package/src/components/openapi/param-style.ts +181 -0
  317. package/src/components/openapi/playground-client.ts +110 -23
  318. package/src/components/openapi/playground-schema.ts +25 -6
  319. package/src/components/openapi/request.ts +192 -26
  320. package/src/components/openapi/schema-tree.ts +209 -0
  321. package/src/components/openapi/snippets.ts +113 -19
  322. package/src/components/openapi/validate-json.ts +1 -1
  323. package/src/components/openapi/ws-client.ts +18 -2
  324. package/src/core/base-path.ts +69 -8
  325. package/src/core/config-input.ts +13 -11
  326. package/src/core/config.ts +18 -4
  327. package/src/core/diagnostics.ts +219 -30
  328. package/src/core/directive-diagnostics.ts +99 -0
  329. package/src/core/frontmatter.ts +21 -18
  330. package/src/core/graph.ts +120 -11
  331. package/src/core/heading-markers.ts +5 -18
  332. package/src/core/i18n-ui.ts +39 -2
  333. package/src/core/i18n.ts +44 -5
  334. package/src/core/last-modified.ts +25 -3
  335. package/src/core/links.ts +7 -4
  336. package/src/core/load-module.ts +20 -0
  337. package/src/core/locale-links.ts +22 -18
  338. package/src/core/manifest.ts +3 -2
  339. package/src/core/meta.ts +89 -12
  340. package/src/core/nav-diagnostics.ts +56 -1
  341. package/src/core/navigation.ts +272 -83
  342. package/src/core/ordering-prefix.ts +27 -0
  343. package/src/core/project-graph.ts +50 -6
  344. package/src/core/safe-href.ts +53 -1
  345. package/src/core/safe-links.ts +11 -2
  346. package/src/core/schema.ts +94 -18
  347. package/src/core/sources/assets.ts +83 -41
  348. package/src/core/sources/contentful-rich-text.ts +28 -20
  349. package/src/core/sources/contentful.ts +25 -12
  350. package/src/core/sources/filesystem.ts +25 -3
  351. package/src/core/sources/github-releases.ts +131 -11
  352. package/src/core/sources/lexical.ts +30 -20
  353. package/src/core/sources/lower.ts +276 -56
  354. package/src/core/sources/mdx-remote.ts +52 -16
  355. package/src/core/sources/normalize.ts +456 -119
  356. package/src/core/sources/notion.ts +77 -34
  357. package/src/core/sources/obsidian.ts +40 -9
  358. package/src/core/sources/payload.ts +1 -0
  359. package/src/core/sources/portable-text.ts +85 -49
  360. package/src/core/sources/remote.ts +18 -2
  361. package/src/core/sources/resolve.ts +52 -33
  362. package/src/core/sources/sanity.ts +1 -0
  363. package/src/core/sources/strapi-blocks.ts +28 -19
  364. package/src/core/sources/strapi.ts +1 -0
  365. package/src/core/sources/types.ts +31 -0
  366. package/src/core/sources/watch.ts +20 -7
  367. package/src/core/standard-schema.ts +10 -6
  368. package/src/core/types.ts +9 -0
  369. package/src/core/ui-packs/ar.ts +13 -0
  370. package/src/core/ui-packs/bg.ts +13 -0
  371. package/src/core/ui-packs/bn.ts +13 -0
  372. package/src/core/ui-packs/ca.ts +13 -0
  373. package/src/core/ui-packs/cs.ts +13 -0
  374. package/src/core/ui-packs/da.ts +13 -0
  375. package/src/core/ui-packs/de.ts +13 -0
  376. package/src/core/ui-packs/el.ts +13 -0
  377. package/src/core/ui-packs/es.ts +13 -0
  378. package/src/core/ui-packs/fa.ts +13 -0
  379. package/src/core/ui-packs/fi.ts +13 -0
  380. package/src/core/ui-packs/fr.ts +13 -0
  381. package/src/core/ui-packs/he.ts +13 -0
  382. package/src/core/ui-packs/hi.ts +13 -0
  383. package/src/core/ui-packs/hr.ts +13 -0
  384. package/src/core/ui-packs/hu.ts +13 -0
  385. package/src/core/ui-packs/id.ts +13 -0
  386. package/src/core/ui-packs/it.ts +13 -0
  387. package/src/core/ui-packs/ja.ts +13 -0
  388. package/src/core/ui-packs/ko.ts +13 -0
  389. package/src/core/ui-packs/nl.ts +13 -0
  390. package/src/core/ui-packs/no.ts +13 -0
  391. package/src/core/ui-packs/pl.ts +13 -0
  392. package/src/core/ui-packs/pt-br.ts +13 -0
  393. package/src/core/ui-packs/pt.ts +13 -0
  394. package/src/core/ui-packs/ro.ts +13 -0
  395. package/src/core/ui-packs/ru.ts +13 -0
  396. package/src/core/ui-packs/sk.ts +13 -0
  397. package/src/core/ui-packs/sr.ts +13 -0
  398. package/src/core/ui-packs/sv.ts +13 -0
  399. package/src/core/ui-packs/th.ts +13 -0
  400. package/src/core/ui-packs/tr.ts +13 -0
  401. package/src/core/ui-packs/uk.ts +13 -0
  402. package/src/core/ui-packs/vi.ts +13 -0
  403. package/src/core/ui-packs/zh-tw.ts +13 -0
  404. package/src/core/ui-packs/zh.ts +13 -0
  405. package/src/core/version-cut.ts +69 -17
  406. package/src/core/versions.ts +4 -1
  407. package/src/deploy/adapters/node.ts +5 -2
  408. package/src/deploy/adapters/registry.ts +2 -1
  409. package/src/deploy/adapters/types.ts +13 -1
  410. package/src/deploy/artifacts.ts +52 -11
  411. package/src/deploy/cloudflare-negotiation.ts +27 -16
  412. package/src/deploy/headers.ts +75 -55
  413. package/src/deploy/node-headers.ts +148 -27
  414. package/src/deploy/platforms/cloudflare.ts +13 -3
  415. package/src/deploy/platforms/netlify.ts +83 -5
  416. package/src/deploy/platforms/node.ts +8 -5
  417. package/src/deploy/platforms/static.ts +2 -0
  418. package/src/deploy/platforms/types.ts +15 -0
  419. package/src/deploy/platforms/vercel.ts +10 -3
  420. package/src/deploy/redirects.ts +68 -21
  421. package/src/deploy/robots.ts +2 -2
  422. package/src/deploy/rss.ts +4 -3
  423. package/src/deploy/sitemap.ts +7 -5
  424. package/src/deploy/vercel-negotiation.ts +35 -3
  425. package/src/eval/agents.ts +10 -2
  426. package/src/eval/run.ts +25 -0
  427. package/src/markdown/base-links.ts +74 -29
  428. package/src/markdown/directives.ts +242 -36
  429. package/src/markdown/features.ts +17 -0
  430. package/src/markdown/index.ts +13 -9
  431. package/src/markdown/mdast.ts +5 -2
  432. package/src/markdown/relative-links.ts +15 -27
  433. package/src/markdown/route-snapshot.ts +37 -0
  434. package/src/og/card.ts +149 -9
  435. package/src/og/derive.ts +156 -5
  436. package/src/og/index.ts +1 -0
  437. package/src/openapi/asyncapi.ts +4 -2
  438. package/src/openapi/graphql-build.ts +28 -2
  439. package/src/openapi/model.ts +99 -27
  440. package/src/openapi/proxy.ts +63 -10
  441. package/src/openapi/render-mdx.ts +51 -3
  442. package/src/registry/eject.ts +297 -43
  443. package/src/search/adapters/version-scope.ts +30 -0
  444. package/src/search/documents.ts +89 -27
  445. package/src/search/popular.ts +2 -1
  446. package/src/search/sync/algolia.ts +36 -2
  447. package/src/seo/jsonld.ts +7 -3
  448. package/src/sources/registry.ts +5 -0
  449. package/src/theme/entry.ts +11 -4
  450. package/src/translate/agents.ts +6 -1
  451. package/src/translate/ledger.ts +26 -3
  452. package/src/translate/meta.ts +76 -24
  453. package/src/translate/run.ts +14 -8
  454. package/src/translate/validate.ts +14 -2
  455. package/src/translate/work-list.ts +91 -19
  456. package/src/upgrade/upgrade.ts +36 -4
  457. package/dist/cli/chunk-27g6wdth.js.map +0 -10
  458. package/dist/cli/chunk-2hn4b8z7.js.map +0 -12
  459. package/dist/cli/chunk-6crbhc3x.js.map +0 -14
  460. package/dist/cli/chunk-6hsn950k.js.map +0 -10
  461. package/dist/cli/chunk-79jhk4py.js.map +0 -35
  462. package/dist/cli/chunk-82bbrxdn.js +0 -51
  463. package/dist/cli/chunk-82bbrxdn.js.map +0 -10
  464. package/dist/cli/chunk-abh8yjkn.js +0 -31
  465. package/dist/cli/chunk-abh8yjkn.js.map +0 -10
  466. package/dist/cli/chunk-ce574jw2.js +0 -23
  467. package/dist/cli/chunk-ce574jw2.js.map +0 -10
  468. package/dist/cli/chunk-dh8cwk36.js.map +0 -10
  469. package/dist/cli/chunk-epjnccmv.js.map +0 -10
  470. package/dist/cli/chunk-fa25z98p.js.map +0 -11
  471. package/dist/cli/chunk-fs23ddbb.js.map +0 -35
  472. package/dist/cli/chunk-fz5wtpmh.js.map +0 -10
  473. package/dist/cli/chunk-jwyddg7y.js.map +0 -15
  474. package/dist/cli/chunk-kpf8rrjc.js.map +0 -19
  475. package/dist/cli/chunk-m3vmjgmq.js.map +0 -10
  476. package/dist/cli/chunk-mb2919y2.js.map +0 -10
  477. package/dist/cli/chunk-q5163e60.js.map +0 -11
  478. package/dist/cli/chunk-qkqwkpte.js.map +0 -182
  479. package/dist/cli/chunk-qs4q5p4e.js.map +0 -10
  480. package/dist/cli/chunk-s1p84fyh.js.map +0 -10
  481. package/dist/cli/chunk-wgm7m9qk.js.map +0 -36
  482. package/dist/cli/chunk-yt5n7ppj.js.map +0 -10
  483. package/dist/cli/chunk-yw7dm696.js.map +0 -14
  484. /package/dist/cli/{chunk-s6jhgk0q.js.map → chunk-2eytanqx.js.map} +0 -0
  485. /package/dist/cli/{chunk-hdpx1tax.js.map → chunk-2z928egk.js.map} +0 -0
  486. /package/dist/cli/{chunk-ah61y8py.js.map → chunk-364znk6q.js.map} +0 -0
  487. /package/dist/cli/{chunk-vtk4a6dg.js.map → chunk-8ktnccpt.js.map} +0 -0
  488. /package/dist/cli/{chunk-fxypxtvm.js.map → chunk-a58773jm.js.map} +0 -0
  489. /package/dist/cli/{chunk-wm7js3j9.js.map → chunk-b07cmahc.js.map} +0 -0
  490. /package/dist/cli/{chunk-zxcczpyx.js.map → chunk-r20tn01b.js.map} +0 -0
  491. /package/dist/cli/{chunk-5shv93fd.js.map → chunk-tkacnehg.js.map} +0 -0
  492. /package/dist/cli/{chunk-zxh4d9vy.js.map → chunk-tzmab476.js.map} +0 -0
@@ -3,10 +3,13 @@ import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
3
 
4
4
  import { join, relative } from "pathe";
5
5
 
6
+ import { OPENAPI_PATH } from "../ai/api/paths.ts";
7
+ import { buildApiSpec } from "../ai/api/spec.ts";
6
8
  import { buildAskData } from "../ai/ask-data.ts";
7
9
  import { resolveAskBackend } from "../ai/ask.ts";
8
10
  import { buildRawMarkdown } from "../ai/markdown.ts";
9
11
  import { buildMcpData } from "../ai/mcp/data.ts";
12
+ import type { McpData } from "../ai/mcp/data.ts";
10
13
  import { buildMcpDiscovery, buildMcpServerCard } from "../ai/mcp/discovery.ts";
11
14
  import { planComponentSlots } from "../astro/component-slots.ts";
12
15
  import {
@@ -23,15 +26,25 @@ import {
23
26
  detectNeedsReact,
24
27
  detectUsesMath,
25
28
  languageIconCssFor,
29
+ PLAYGROUND_PROXY_ENTRY,
30
+ playgroundProxyPattern,
31
+ proxyAllowlistWarnings,
32
+ specOrigins,
26
33
  } from "../astro/generate.ts";
27
34
  import { discoverIslands } from "../astro/islands.ts";
28
35
  import { customOgRoutes, discoverPages, routeIsTaken } from "../astro/pages.ts";
29
36
  import {
37
+ apiNavigationTemplate,
38
+ apiNotFoundTemplate,
39
+ apiPagesIndexTemplate,
40
+ apiPageTemplate,
41
+ apiSearchTemplate,
30
42
  askComponentTemplate,
31
43
  askEndpointTemplate,
32
44
  astroConfigTemplate,
33
45
  catchAllPageTemplate,
34
46
  changelogIndexTemplate,
47
+ contentAssetsEndpointTemplate,
35
48
  contentConfigTemplate,
36
49
  exampleMapTemplate,
37
50
  exampleSlug,
@@ -41,8 +54,11 @@ import {
41
54
  mcpEndpointTemplate,
42
55
  mcpPageFile,
43
56
  mixedbreadSearchEndpointTemplate,
57
+ notFoundJsonTemplate,
58
+ notFoundMarkdownTemplate,
44
59
  notFoundPageTemplate,
45
60
  ogEndpointTemplate,
61
+ playgroundProxyTemplate,
46
62
  rawMarkdownEndpointTemplate,
47
63
  rssEndpointTemplate,
48
64
  runtimeDependencies,
@@ -51,6 +67,7 @@ import {
51
67
  searchEndpointTemplate,
52
68
  staticJsonEndpointTemplate,
53
69
  } from "../astro/templates.ts";
70
+ import { collectContentAssets } from "../core/content-assets.ts";
54
71
  import { buildIncludeGraph } from "../core/includes.ts";
55
72
  import { packageRoot } from "../core/package-root.ts";
56
73
  import { scanProject } from "../core/project-graph.ts";
@@ -61,8 +78,12 @@ import {
61
78
  } from "../core/sources/collection.ts";
62
79
  import type { ProjectContext } from "../core/types.ts";
63
80
  import { buildRssFeeds, renderRssFeed } from "../deploy/rss.ts";
81
+ import { resolveOgFonts } from "../og/derive.ts";
64
82
  import type { OpenApiData } from "../openapi/model.ts";
65
- import { hasScalarReferences } from "../openapi/references.ts";
83
+ import {
84
+ hasScalarReferences,
85
+ needsPlaygroundProxy,
86
+ } from "../openapi/references.ts";
66
87
  import { buildReferenceFiles } from "../openapi/scalar.ts";
67
88
  import { isOpenApiSource } from "../openapi/source.ts";
68
89
  import { buildSearchDocuments } from "../search/documents.ts";
@@ -70,6 +91,7 @@ import {
70
91
  examplesEntryTemplate,
71
92
  tailwindEntryTemplate,
72
93
  } from "../theme/entry.ts";
94
+ import { fontLocaleCodes } from "../theme/fonts.ts";
73
95
  import { buildThemeCss } from "../theme/palette.ts";
74
96
  import { rebaseSourceDirectives } from "../theme/sources.ts";
75
97
  import { twoslashCss } from "../theme/twoslash.ts";
@@ -191,21 +213,70 @@ const mcpDiscoveryPages = (
191
213
  : [];
192
214
 
193
215
  /**
194
- * The MCP data snapshot, server endpoint, and `.well-known` discovery
195
- * documents, mirroring `writeMcpFiles` in generate.ts. Empty when the server
196
- * is disabled or its route is already owned by a page.
216
+ * The playground's built-in CORS proxy route (`playground: { proxy: true }`),
217
+ * mirroring `planPlaygroundProxy` in generate.ts: injected like the MCP
218
+ * discovery routes, because Astro treats a `_`-prefixed page file as private,
219
+ * and mounted under `basePath` at the URL the playground sends to. Empty when
220
+ * no reference routes its playground through it.
197
221
  */
198
- const mcpFiles = async (
222
+ const playgroundProxyPages = (
223
+ config: BlumeProject["config"]
224
+ ): { entrypoint: string; pattern: string }[] =>
225
+ needsPlaygroundProxy(config)
226
+ ? [
227
+ {
228
+ entrypoint: toPosix(join("src", PLAYGROUND_PROXY_ENTRY)),
229
+ pattern: playgroundProxyPattern(config),
230
+ },
231
+ ]
232
+ : [];
233
+
234
+ /**
235
+ * The proxy endpoint behind {@link playgroundProxyPages}, with the origin
236
+ * allowlist baked in from the same parsed specs the reference pages render.
237
+ */
238
+ const playgroundProxyFiles = (
239
+ config: BlumeProject["config"],
240
+ openApiData: OpenApiData,
241
+ srcDir: string
242
+ ): { content: string; path: string }[] =>
243
+ needsPlaygroundProxy(config)
244
+ ? [
245
+ {
246
+ content: playgroundProxyTemplate(specOrigins(openApiData)),
247
+ path: join(srcDir, PLAYGROUND_PROXY_ENTRY),
248
+ },
249
+ ]
250
+ : [];
251
+
252
+ /**
253
+ * The agent data snapshot (`blume:mcp-data`) behind the MCP server and the
254
+ * JSON docs API, mirroring `publishAgentData` in generate.ts: built when
255
+ * either is on, null when neither needs it.
256
+ */
257
+ const ejectAgentData = async (
258
+ project: BlumeProject,
259
+ userPages: { pattern: string }[]
260
+ ): Promise<McpData | null> =>
261
+ hostsMcp(project, userPages) || project.config.agents.api
262
+ ? await buildMcpData(project)
263
+ : null;
264
+
265
+ /**
266
+ * The MCP server endpoint and `.well-known` discovery documents, mirroring
267
+ * `writeMcpFiles` in generate.ts. Empty when the server is disabled or its
268
+ * route is already owned by a page.
269
+ */
270
+ const mcpFiles = (
199
271
  project: BlumeProject,
200
272
  userPages: { pattern: string }[],
201
273
  srcDir: string,
202
- genDir: string
203
- ): Promise<{ content: string; path: string }[]> => {
204
- if (!hostsMcp(project, userPages)) {
274
+ data: McpData | null
275
+ ): { content: string; path: string }[] => {
276
+ if (!(data && hostsMcp(project, userPages))) {
205
277
  return [];
206
278
  }
207
279
  const { route } = project.config.agents.mcp;
208
- const data = await buildMcpData(project);
209
280
  const discoveryInput = {
210
281
  base: data.base,
211
282
  name: data.name,
@@ -214,10 +285,6 @@ const mcpFiles = async (
214
285
  version: data.version,
215
286
  };
216
287
  return [
217
- {
218
- content: `${JSON.stringify(data)}\n`,
219
- path: join(genDir, "mcp-data.json"),
220
- },
221
288
  {
222
289
  content: mcpEndpointTemplate(),
223
290
  path: join(srcDir, "pages", mcpPageFile(route)),
@@ -233,6 +300,87 @@ const mcpFiles = async (
233
300
  ];
234
301
  };
235
302
 
303
+ /**
304
+ * The JSON docs API, mirroring `planApi` and `writeApiFiles` in generate.ts:
305
+ * the prerendered page index, per-page documents, and navigation; on server
306
+ * output the search endpoint and, unless a user page or a content page already
307
+ * lives under `/api/`, the JSON 404 catch-all; and `/openapi.json`, unless a
308
+ * `public/openapi.json` or a page owns that route. The ejected `llms.txt`,
309
+ * homepage `Link` header, and 404 page advertise these routes, so the ejected
310
+ * app serves them. Empty when `agents.api` is off.
311
+ */
312
+ const apiFiles = (
313
+ project: BlumeProject,
314
+ userPages: { pattern: string }[],
315
+ root: string,
316
+ srcDir: string,
317
+ data: McpData | null
318
+ ): { content: string; path: string }[] => {
319
+ const { config } = project;
320
+ if (!(data && config.agents.api)) {
321
+ return [];
322
+ }
323
+ const server = config.deployment.options.output === "server";
324
+ const apiDir = join(srcDir, "pages", "api");
325
+ const files = [
326
+ {
327
+ content: apiPagesIndexTemplate(),
328
+ path: join(apiDir, "docs", "pages.json.ts"),
329
+ },
330
+ {
331
+ content: apiPageTemplate(),
332
+ path: join(apiDir, "docs", "pages", "[...route].json.ts"),
333
+ },
334
+ {
335
+ content: apiNavigationTemplate(),
336
+ path: join(apiDir, "docs", "navigation.json.ts"),
337
+ },
338
+ ];
339
+ if (server) {
340
+ files.push({
341
+ content: apiSearchTemplate(),
342
+ path: join(apiDir, "docs", "search.ts"),
343
+ });
344
+ }
345
+ const apiOwned =
346
+ userPages.some((page) => page.pattern.startsWith("/api/[")) ||
347
+ project.graph.pages.some(
348
+ (page) => page.route === "/api" || page.route.startsWith("/api/")
349
+ );
350
+ if (server && !apiOwned) {
351
+ files.push({
352
+ content: apiNotFoundTemplate({ base: data.base, site: data.site }),
353
+ path: join(apiDir, "[...path].ts"),
354
+ });
355
+ }
356
+ if (
357
+ !(
358
+ routeIsTaken(userPages, project.graph.pages, OPENAPI_PATH) ||
359
+ existsSync(join(root, "public", "openapi.json"))
360
+ )
361
+ ) {
362
+ files.push({
363
+ content: staticJsonEndpointTemplate(
364
+ buildApiSpec({
365
+ agentReadability: config.agents.agentReadability,
366
+ base: data.base,
367
+ description: config.description,
368
+ llmsTxt: config.agents.llmsTxt.enabled,
369
+ mcpRoute: hostsMcp(project, userPages)
370
+ ? config.agents.mcp.route
371
+ : null,
372
+ name: config.title,
373
+ search: server,
374
+ site: data.site,
375
+ version: data.version,
376
+ })
377
+ ),
378
+ path: join(srcDir, "pages", "openapi.json.ts"),
379
+ });
380
+ }
381
+ return files;
382
+ };
383
+
236
384
  /**
237
385
  * The `/changelog` index page, mirroring `shouldGenerateChangelog` in
238
386
  * generate.ts: emitted when `type: changelog` entries or a release-backed
@@ -265,6 +413,59 @@ const changelogFiles = (
265
413
  ];
266
414
  };
267
415
 
416
+ /**
417
+ * The colocated-image map and the `/blume-assets/[...asset]` endpoint that
418
+ * serves it, mirroring generate.ts: the ejected raw Markdown points
419
+ * `![x](./diagram.png)` at `/blume-assets/content/…`, and the config aliases
420
+ * `blume:content-assets` to the map. Each original's path is written relative
421
+ * to the project root (the directory `astro dev`/`astro build` run from), so
422
+ * the ejected app builds from any checkout. Remote-source images need no
423
+ * endpoint: eject copies them into the project's own `public/blume-assets`.
424
+ */
425
+ const contentAssetFiles = async (
426
+ project: BlumeProject,
427
+ root: string,
428
+ srcDir: string,
429
+ genDir: string
430
+ ): Promise<{ content: string; path: string }[]> => {
431
+ const assets = await collectContentAssets(project);
432
+ const portable = Object.fromEntries(
433
+ Object.entries(assets).map(([param, abs]) => [
434
+ param,
435
+ toPosix(relative(root, abs)),
436
+ ])
437
+ );
438
+ return [
439
+ {
440
+ content: `${JSON.stringify(portable)}\n`,
441
+ path: join(genDir, "content-assets.json"),
442
+ },
443
+ {
444
+ content: contentAssetsEndpointTemplate(null),
445
+ path: join(srcDir, "pages", "blume-assets", "[...asset].ts"),
446
+ },
447
+ ];
448
+ };
449
+
450
+ /**
451
+ * The partial → including-pages map with every path relative to the project
452
+ * root, like every other path in the ejected app, so it holds in any checkout.
453
+ * Its readers (`includeHmrPlugin`, `withIncludeRefresh`) resolve each path
454
+ * against the app's root, which after eject is the project itself.
455
+ */
456
+ const portableIncludeGraph = (
457
+ project: BlumeProject,
458
+ root: string
459
+ ): Record<string, string[]> =>
460
+ Object.fromEntries(
461
+ Object.entries(buildIncludeGraph(project.graph.pages)).map(
462
+ ([partial, includers]) => [
463
+ toPosix(relative(root, partial)),
464
+ includers.map((page) => toPosix(relative(root, page))),
465
+ ]
466
+ )
467
+ );
468
+
268
469
  /** Contents of the configured `examples.css`, or `""` when unset/absent. */
269
470
  /**
270
471
  * Read a user stylesheet that eject inlines into a generated entry under
@@ -309,16 +510,18 @@ const examplesPreviewFiles = (
309
510
 
310
511
  /**
311
512
  * The packages the ejected app imports by bare name: Astro, Tailwind's Vite
312
- * plugin, `blume` itself, the integrations the config wires in, whatever the
313
- * configured adapters declare, and React when islands, examples, or the assistant
314
- * render with it (Blume ships React, so projects rarely list it). They have
315
- * to be the project's own dependencies after eject — under a strict linker
316
- * such as pnpm nothing else makes them resolvable, and `astro build` fails.
317
- * The hidden runtime reaches the same packages through its `node_modules`
318
- * junction into Blume's own, so only eject declares the ones its generated
319
- * files import directly: the AI SDK the assistant route streams through (unless
320
- * `ai.assistant.endpoint` points elsewhere, when no route is written) and the EPUB
321
- * generator's browser bundle `features.ts` loads.
513
+ * plugin, Tailwind and its typography plugin (which the generated `app.css`
514
+ * and `examples.css` import by name), `blume` itself, the integrations the
515
+ * config wires in, whatever the configured adapters declare, and React when
516
+ * islands, examples, or the assistant render with it (Blume ships React, so
517
+ * projects rarely list it). They have to be the project's own dependencies
518
+ * after eject — under a strict linker such as pnpm nothing else makes them
519
+ * resolvable, and `astro build` fails. The hidden runtime reaches the same
520
+ * packages through its `node_modules` junction into Blume's own, so only
521
+ * eject declares the ones its generated files import directly: the AI SDK the
522
+ * assistant route streams through (unless `ai.assistant.endpoint` points
523
+ * elsewhere, when no route is written) and the EPUB generator's browser bundle
524
+ * `features.ts` loads (only named there when `export.epub` is on).
322
525
  */
323
526
  const ejectDependencies = (
324
527
  options: Parameters<typeof runtimeDependencies>[0]
@@ -328,6 +531,8 @@ const ejectDependencies = (
328
531
  ...new Set([
329
532
  "astro",
330
533
  "@tailwindcss/vite",
534
+ "tailwindcss",
535
+ "@tailwindcss/typography",
331
536
  "blume",
332
537
  ...runtimeDependencies(options),
333
538
  ...(options.needsReact ? ["react", "react-dom"] : []),
@@ -439,7 +644,9 @@ export const eject = async (
439
644
  pattern: page.pattern,
440
645
  })),
441
646
  ...mcpDiscoveryPages(project, pages),
647
+ ...playgroundProxyPages(config),
442
648
  ];
649
+ const openApiData = ejectOpenApiData(project);
443
650
 
444
651
  // Non-filesystem sources eject their materialized MDX into `<root>/blume-staged`
445
652
  // (a dedicated dir so it never clashes with a content root literally named
@@ -555,7 +762,7 @@ export const eject = async (
555
762
  path: join(genDir, "Ask.astro"),
556
763
  },
557
764
  {
558
- content: `${JSON.stringify(ejectOpenApiData(project))}\n`,
765
+ content: `${JSON.stringify(openApiData)}\n`,
559
766
  path: join(genDir, "openapi.json"),
560
767
  },
561
768
  {
@@ -568,7 +775,7 @@ export const eject = async (
568
775
  // hot update's read would silently no-op and partial edits would serve
569
776
  // stale pages. A snapshot like the rest of `src/generated`: the ejected
570
777
  // app owns (and may regenerate or prune) it.
571
- content: `${JSON.stringify(buildIncludeGraph(project.graph.pages))}\n`,
778
+ content: `${JSON.stringify(portableIncludeGraph(project, root))}\n`,
572
779
  path: join(genDir, "includes.json"),
573
780
  },
574
781
  {
@@ -581,40 +788,85 @@ export const eject = async (
581
788
  },
582
789
  ];
583
790
 
791
+ files.push(...(await contentAssetFiles(project, root, srcDir, genDir)));
792
+
584
793
  if (assistantEnabled) {
585
794
  files.push(...(await askFiles(project, srcDir, genDir)));
586
795
  }
587
796
 
797
+ // The `/changelog` index, mirrored from the generated runtime (`[]` when
798
+ // the project has no changelog). The OG endpoint below adds its card.
799
+ const changelog = changelogFiles(project, pages, srcDir, {
800
+ exportEpub,
801
+ exportPdf,
802
+ needsReact,
803
+ staged: hasStaged,
804
+ });
805
+
588
806
  if (config.seo.og.enabled) {
807
+ // The default script fallbacks ride along (Google family names, nothing
808
+ // machine-specific), so a non-Latin card still renders after eject. An
809
+ // explicit seo.og.fonts replaces them, and isn't carried over.
810
+ const { fallbacks, families } = resolveOgFonts(
811
+ {
812
+ locales: fontLocaleCodes(config.i18n),
813
+ ogFonts: config.seo.og.fonts,
814
+ themeFonts: config.theme.fonts,
815
+ themeFontsConfigured: false,
816
+ },
817
+ root
818
+ );
589
819
  files.push({
590
820
  content: ogEndpointTemplate(
591
821
  customOgRoutes(pages, config.title, config.seo.og.titles),
592
- { pageDescriptions: config.seo.og.description !== false }
822
+ {
823
+ fallbacks,
824
+ families,
825
+ pageDescriptions: config.seo.og.description !== false,
826
+ },
827
+ changelog.length > 0
593
828
  ),
594
829
  path: join(srcDir, "pages", "og", "[...slug].png.ts"),
595
830
  });
596
831
  }
597
832
 
598
- // The hosted MCP server and the `/changelog` index, mirrored from the
599
- // generated runtime (each helper returns `[]` when its feature is off).
833
+ // The hosted MCP server, the JSON docs API, and the playground's built-in
834
+ // proxy, mirrored from the generated runtime (`[]` when each is off). The
835
+ // server and the API share one agent data snapshot.
836
+ const agentData = await ejectAgentData(project, pages);
837
+ if (agentData) {
838
+ files.push({
839
+ content: `${JSON.stringify(agentData)}\n`,
840
+ path: join(genDir, "mcp-data.json"),
841
+ });
842
+ }
600
843
  files.push(
601
- ...(await mcpFiles(project, pages, srcDir, genDir)),
602
- ...changelogFiles(project, pages, srcDir, {
603
- exportEpub,
604
- exportPdf,
605
- needsReact,
606
- staged: hasStaged,
607
- })
844
+ ...mcpFiles(project, pages, srcDir, agentData),
845
+ ...apiFiles(project, pages, root, srcDir, agentData),
846
+ ...changelog,
847
+ ...playgroundProxyFiles(config, openApiData, srcDir)
608
848
  );
609
849
 
610
- // Default 404 page, unless the project already owns `/404` (a custom
611
- // `pages/404.astro` or a `404.md` content page). The ejected project owns the
612
- // file afterwards and can edit or remove it.
850
+ // Default 404 page and its Markdown (`/404.md`) and JSON (`/404.json`)
851
+ // twins, mirroring `writeNotFoundPage` in generate.ts: all three are skipped
852
+ // when the project already owns `/404` (a custom `pages/404.astro` or a
853
+ // `404.md` content page). The ejected project owns the files afterwards and
854
+ // can edit or remove them.
613
855
  if (!routeIsTaken(pages, project.graph.pages, "/404")) {
614
- files.push({
615
- content: notFoundPageTemplate(),
616
- path: join(srcDir, "pages", "404.astro"),
617
- });
856
+ files.push(
857
+ {
858
+ content: notFoundPageTemplate(),
859
+ path: join(srcDir, "pages", "404.astro"),
860
+ },
861
+ {
862
+ content: notFoundMarkdownTemplate(),
863
+ path: join(srcDir, "pages", "404.md.ts"),
864
+ },
865
+ {
866
+ content: notFoundJsonTemplate(),
867
+ path: join(srcDir, "pages", "404.json.ts"),
868
+ }
869
+ );
618
870
  }
619
871
 
620
872
  // The client-feature loaders behind the `blume:features` alias, and the
@@ -673,7 +925,9 @@ export const eject = async (
673
925
  // the ejected app keeps its reference routes — including the warnings (a
674
926
  // missing spec file, a route collision), which the caller surfaces exactly
675
927
  // like the generated-runtime path does.
676
- const warnings: string[] = [];
928
+ // A proxied spec with no origin to allow gets the generated runtime's
929
+ // diagnostic too.
930
+ const warnings: string[] = proxyAllowlistWarnings(config, openApiData);
677
931
  if (hasScalarReferences(config)) {
678
932
  const references = await buildReferenceFiles({
679
933
  config,
@@ -0,0 +1,30 @@
1
+ import type { SearchAdapterKind } from "./registry.ts";
2
+
3
+ /**
4
+ * Whether each adapter's client can filter results to one docs version. The
5
+ * source-built indexes (Orama, FlexSearch) store every document's `version`,
6
+ * and the Algolia and Typesense syncs upload it as a facet their clients
7
+ * filter on. Pagefind indexes the built HTML with no version metadata, the
8
+ * Orama Cloud sync uploads no `version`, and the Mixedbread endpoint takes no
9
+ * filter, so those always search every version. Keyed by every kind so a new
10
+ * adapter has to decide.
11
+ */
12
+ const SCOPES_VERSIONS = {
13
+ algolia: true,
14
+ flexsearch: true,
15
+ mixedbread: false,
16
+ none: false,
17
+ orama: true,
18
+ "orama-cloud": false,
19
+ pagefind: false,
20
+ typesense: true,
21
+ } satisfies Record<SearchAdapterKind, boolean>;
22
+
23
+ /**
24
+ * Whether the configured search adapter scopes results to the viewed docs
25
+ * version. The search dialog offers its "All versions" toggle only when it
26
+ * does: on the others the toggle would change nothing, and every query
27
+ * already spans all versions.
28
+ */
29
+ export const scopesVersions = (kind: SearchAdapterKind): boolean =>
30
+ SCOPES_VERSIONS[kind];