blume 1.7.3 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (690) hide show
  1. package/AGENTS.md +19 -0
  2. package/CHANGELOG.md +245 -0
  3. package/README.md +34 -21
  4. package/dist/cli/{chunk-vacwm2hv.js → chunk-27g6wdth.js} +2 -2
  5. package/dist/cli/{chunk-ps4m1xh4.js → chunk-2hn4b8z7.js} +513 -550
  6. package/dist/cli/chunk-2hn4b8z7.js.map +12 -0
  7. package/dist/cli/chunk-5shv93fd.js +39 -0
  8. package/dist/cli/chunk-5shv93fd.js.map +10 -0
  9. package/dist/cli/chunk-6crbhc3x.js +361 -0
  10. package/dist/cli/chunk-6crbhc3x.js.map +14 -0
  11. package/dist/cli/{chunk-8cjtbafj.js → chunk-6hsn950k.js} +109 -383
  12. package/dist/cli/chunk-6hsn950k.js.map +10 -0
  13. package/dist/cli/chunk-6vm74dry.js +148 -0
  14. package/dist/cli/chunk-6vm74dry.js.map +10 -0
  15. package/dist/cli/{chunk-yg63d42r.js → chunk-79jhk4py.js} +87 -58
  16. package/dist/cli/chunk-79jhk4py.js.map +35 -0
  17. package/dist/cli/chunk-82bbrxdn.js +51 -0
  18. package/dist/cli/chunk-82bbrxdn.js.map +10 -0
  19. package/dist/cli/chunk-abh8yjkn.js +31 -0
  20. package/dist/cli/chunk-abh8yjkn.js.map +10 -0
  21. package/dist/cli/chunk-ah61y8py.js +75 -0
  22. package/dist/cli/chunk-ah61y8py.js.map +11 -0
  23. package/dist/cli/{chunk-dwgcp5sm.js → chunk-ce574jw2.js} +1 -1
  24. package/dist/cli/chunk-ch6g3ar0.js +102 -0
  25. package/dist/cli/chunk-ch6g3ar0.js.map +10 -0
  26. package/dist/cli/chunk-dh8cwk36.js +279 -0
  27. package/dist/cli/chunk-dh8cwk36.js.map +10 -0
  28. package/dist/cli/{chunk-rqy0s5wh.js → chunk-epjnccmv.js} +17 -16
  29. package/dist/cli/{chunk-rqy0s5wh.js.map → chunk-epjnccmv.js.map} +3 -3
  30. package/dist/cli/chunk-f2z5v128.js +97 -0
  31. package/dist/cli/chunk-f2z5v128.js.map +10 -0
  32. package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
  33. package/dist/cli/chunk-fa25z98p.js.map +11 -0
  34. package/dist/cli/{chunk-1jefwnfs.js → chunk-fs23ddbb.js} +1076 -2592
  35. package/dist/cli/chunk-fs23ddbb.js.map +35 -0
  36. package/dist/cli/{chunk-e7f42gdj.js → chunk-fxypxtvm.js} +2 -2
  37. package/dist/cli/{chunk-bvwwhd84.js → chunk-fz5wtpmh.js} +15 -15
  38. package/dist/cli/{chunk-bvwwhd84.js.map → chunk-fz5wtpmh.js.map} +1 -1
  39. package/dist/cli/chunk-hdpx1tax.js +91 -0
  40. package/dist/cli/chunk-hdpx1tax.js.map +10 -0
  41. package/dist/cli/{chunk-ct47dqpx.js → chunk-jts8mvcz.js} +67 -7
  42. package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
  43. package/dist/cli/{chunk-ahnw3kxw.js → chunk-jwyddg7y.js} +27 -22
  44. package/dist/cli/chunk-jwyddg7y.js.map +15 -0
  45. package/dist/cli/{chunk-cjtn640a.js → chunk-kdp5q7ke.js} +43 -20
  46. package/dist/cli/chunk-kdp5q7ke.js.map +10 -0
  47. package/dist/cli/{chunk-5g0w1e2c.js → chunk-kpf8rrjc.js} +28 -16
  48. package/dist/cli/{chunk-5g0w1e2c.js.map → chunk-kpf8rrjc.js.map} +4 -4
  49. package/dist/cli/chunk-m3vmjgmq.js +133 -0
  50. package/dist/cli/chunk-m3vmjgmq.js.map +10 -0
  51. package/dist/cli/{chunk-b27xqwn9.js → chunk-mb2919y2.js} +9 -5
  52. package/dist/cli/chunk-mb2919y2.js.map +10 -0
  53. package/dist/cli/{chunk-5qk08vmp.js → chunk-q5163e60.js} +133 -54
  54. package/dist/cli/chunk-q5163e60.js.map +11 -0
  55. package/dist/cli/chunk-qkqwkpte.js +12437 -0
  56. package/dist/cli/chunk-qkqwkpte.js.map +182 -0
  57. package/dist/cli/{chunk-4x36ddpw.js → chunk-qs4q5p4e.js} +81 -87
  58. package/dist/cli/chunk-qs4q5p4e.js.map +10 -0
  59. package/dist/cli/{chunk-0xjyb285.js → chunk-qwsrynx5.js} +15 -5
  60. package/dist/cli/{chunk-0xjyb285.js.map → chunk-qwsrynx5.js.map} +4 -4
  61. package/dist/cli/chunk-s1p84fyh.js +261 -0
  62. package/dist/cli/chunk-s1p84fyh.js.map +10 -0
  63. package/dist/cli/chunk-s6jhgk0q.js +176 -0
  64. package/dist/cli/chunk-s6jhgk0q.js.map +11 -0
  65. package/dist/cli/chunk-vtk4a6dg.js +374 -0
  66. package/dist/cli/chunk-vtk4a6dg.js.map +10 -0
  67. package/dist/cli/{chunk-k79xp7av.js → chunk-wgm7m9qk.js} +230 -700
  68. package/dist/cli/chunk-wgm7m9qk.js.map +36 -0
  69. package/dist/cli/chunk-wm7js3j9.js +145 -0
  70. package/dist/cli/chunk-wm7js3j9.js.map +11 -0
  71. package/dist/cli/chunk-yt5n7ppj.js +79 -0
  72. package/dist/cli/chunk-yt5n7ppj.js.map +10 -0
  73. package/dist/cli/{chunk-3r45185y.js → chunk-yw7dm696.js} +9 -11
  74. package/dist/cli/{chunk-3r45185y.js.map → chunk-yw7dm696.js.map} +3 -3
  75. package/dist/cli/{chunk-nn13znc2.js → chunk-zxcczpyx.js} +1 -1
  76. package/dist/cli/chunk-zxh4d9vy.js +122 -0
  77. package/dist/cli/chunk-zxh4d9vy.js.map +11 -0
  78. package/dist/cli/index.js +214 -57
  79. package/dist/cli/index.js.map +8 -7
  80. package/dist/types/ai/agent-readability.d.ts +52 -0
  81. package/dist/types/ai/ai-catalog.d.ts +42 -0
  82. package/dist/types/ai/api/paths.d.ts +17 -0
  83. package/dist/types/ai/api-catalog.d.ts +18 -0
  84. package/dist/types/ai/ask-context.d.ts +7 -7
  85. package/dist/types/ai/ask.d.ts +368 -0
  86. package/dist/types/ai/changelog-markdown.d.ts +2 -0
  87. package/dist/types/ai/component-markdown.d.ts +2 -2
  88. package/dist/types/ai/index.d.ts +24 -0
  89. package/dist/types/ai/link-headers.d.ts +24 -0
  90. package/dist/types/ai/llms.d.ts +25 -0
  91. package/dist/types/ai/markdown.d.ts +45 -0
  92. package/dist/types/ai/mcp/discovery.d.ts +68 -0
  93. package/dist/types/ai/mcp/tools.d.ts +16 -0
  94. package/dist/types/ai/openapi-components.d.ts +43 -0
  95. package/dist/types/ai/relative-links.d.ts +26 -0
  96. package/dist/types/ai/serializers.d.ts +15 -0
  97. package/dist/types/ai/skills.d.ts +42 -0
  98. package/dist/types/ai/tar.d.ts +25 -0
  99. package/dist/types/ai/visibility.d.ts +17 -0
  100. package/dist/types/ai/web-bot-auth.d.ts +16 -0
  101. package/dist/types/analytics/adobe.d.ts +35 -0
  102. package/dist/types/analytics/amplitude.d.ts +50 -0
  103. package/dist/types/analytics/clarity.d.ts +31 -0
  104. package/dist/types/analytics/clearbit.d.ts +29 -0
  105. package/dist/types/analytics/cloudflare.d.ts +41 -0
  106. package/dist/types/analytics/fathom.d.ts +41 -0
  107. package/dist/types/analytics/google-analytics.d.ts +44 -0
  108. package/dist/types/analytics/google-tag-manager.d.ts +40 -0
  109. package/dist/types/analytics/head.d.ts +30 -0
  110. package/dist/types/analytics/heap.d.ts +40 -0
  111. package/dist/types/analytics/hightouch.d.ts +44 -0
  112. package/dist/types/analytics/hotjar.d.ts +33 -0
  113. package/dist/types/analytics/index.d.ts +61 -0
  114. package/dist/types/analytics/inline.d.ts +17 -0
  115. package/dist/types/analytics/logrocket.d.ts +44 -0
  116. package/dist/types/analytics/mixpanel.d.ts +67 -0
  117. package/dist/types/analytics/pirsch.d.ts +42 -0
  118. package/dist/types/analytics/plausible.d.ts +56 -0
  119. package/dist/types/analytics/posthog.d.ts +45 -0
  120. package/dist/types/analytics/schema.d.ts +320 -0
  121. package/dist/types/analytics/script.d.ts +46 -0
  122. package/dist/types/analytics/segment.d.ts +50 -0
  123. package/dist/types/analytics/vercel.d.ts +48 -0
  124. package/dist/types/astro/integration.d.ts +76 -0
  125. package/dist/types/astro/markdown-negotiation.d.ts +23 -0
  126. package/dist/types/astro/module-types.d.ts +14 -0
  127. package/dist/types/astro/pages.d.ts +44 -0
  128. package/dist/types/cli/env.d.ts +12 -0
  129. package/dist/types/cli/init/scaffold.d.ts +154 -0
  130. package/dist/types/components/layout/nav-utils.d.ts +11 -0
  131. package/dist/types/core/adapter.d.ts +47 -0
  132. package/dist/types/core/api-name.d.ts +7 -0
  133. package/dist/types/core/changelog-index.d.ts +13 -0
  134. package/dist/types/core/config-input.d.ts +197 -526
  135. package/dist/types/core/config.d.ts +61 -35
  136. package/dist/types/core/content-assets.d.ts +76 -0
  137. package/dist/types/core/custom-pages.d.ts +33 -0
  138. package/dist/types/core/data.d.ts +30 -15
  139. package/dist/types/core/define-components.d.ts +12 -9
  140. package/dist/types/core/deployment-env.d.ts +6 -11
  141. package/dist/types/core/frontmatter.d.ts +10 -0
  142. package/dist/types/core/graph.d.ts +18 -0
  143. package/dist/types/core/heading-markers.d.ts +54 -0
  144. package/dist/types/core/i18n-ui.d.ts +12 -10
  145. package/dist/types/core/i18n.d.ts +87 -0
  146. package/dist/types/core/includes.d.ts +138 -0
  147. package/dist/types/core/last-modified.d.ts +47 -0
  148. package/dist/types/core/links.d.ts +95 -0
  149. package/dist/types/core/locale-links.d.ts +60 -0
  150. package/dist/types/core/manifest.d.ts +17 -0
  151. package/dist/types/core/meta.d.ts +38 -0
  152. package/dist/types/core/nav-diagnostics.d.ts +26 -0
  153. package/dist/types/core/navigation.d.ts +6 -0
  154. package/dist/types/core/node-require.d.ts +19 -0
  155. package/dist/types/core/package-json.d.ts +13 -0
  156. package/dist/types/core/probe.d.ts +42 -0
  157. package/dist/types/core/project-graph.d.ts +51 -0
  158. package/dist/types/core/project.d.ts +2 -0
  159. package/dist/types/core/safe-href.d.ts +2 -0
  160. package/dist/types/core/safe-links.d.ts +26 -0
  161. package/dist/types/core/schema.d.ts +2284 -454
  162. package/dist/types/core/site-url.d.ts +16 -0
  163. package/dist/types/core/sources/assets.d.ts +36 -0
  164. package/dist/types/core/sources/cache.d.ts +37 -0
  165. package/dist/types/core/sources/collection.d.ts +28 -0
  166. package/dist/types/core/sources/contentful-rich-text.d.ts +31 -0
  167. package/dist/types/core/sources/contentful.d.ts +40 -0
  168. package/dist/types/core/sources/filesystem.d.ts +24 -0
  169. package/dist/types/core/sources/github-releases.d.ts +31 -0
  170. package/dist/types/core/sources/json.d.ts +30 -0
  171. package/dist/types/core/sources/lexical.d.ts +19 -0
  172. package/dist/types/core/sources/lower.d.ts +75 -0
  173. package/dist/types/core/sources/mdx-remote.d.ts +28 -0
  174. package/dist/types/core/sources/normalize.d.ts +147 -0
  175. package/dist/types/core/sources/notion.d.ts +131 -0
  176. package/dist/types/core/sources/obsidian.d.ts +46 -0
  177. package/dist/types/core/sources/payload.d.ts +39 -0
  178. package/dist/types/core/sources/portable-text.d.ts +42 -0
  179. package/dist/types/core/sources/read.d.ts +23 -0
  180. package/dist/types/core/sources/remote.d.ts +74 -0
  181. package/dist/types/core/sources/resolve.d.ts +19 -0
  182. package/dist/types/core/sources/sanity.d.ts +43 -0
  183. package/dist/types/core/sources/strapi-blocks.d.ts +12 -0
  184. package/dist/types/core/sources/strapi.d.ts +33 -0
  185. package/dist/types/core/sources/types.d.ts +7 -0
  186. package/dist/types/core/sources/watch.d.ts +45 -0
  187. package/dist/types/core/text-width.d.ts +11 -0
  188. package/dist/types/core/types.d.ts +15 -1
  189. package/dist/types/core/unrecognized-keys.d.ts +7 -0
  190. package/dist/types/core/versions.d.ts +72 -0
  191. package/dist/types/core/yaml.d.ts +9 -0
  192. package/dist/types/deploy/adapter-output.d.ts +45 -0
  193. package/dist/types/deploy/adapters/cloudflare.d.ts +40 -0
  194. package/dist/types/deploy/adapters/index.d.ts +29 -0
  195. package/dist/types/deploy/adapters/netlify.d.ts +37 -0
  196. package/dist/types/deploy/adapters/node.d.ts +37 -0
  197. package/dist/types/deploy/adapters/registry.d.ts +133 -0
  198. package/dist/types/deploy/adapters/types.d.ts +71 -0
  199. package/dist/types/deploy/adapters/vercel.d.ts +38 -0
  200. package/dist/types/deploy/artifacts.d.ts +65 -0
  201. package/dist/types/deploy/cloudflare-negotiation.d.ts +196 -0
  202. package/dist/types/deploy/function-bundle.d.ts +80 -0
  203. package/dist/types/deploy/headers.d.ts +50 -0
  204. package/dist/types/deploy/node-headers.d.ts +42 -0
  205. package/dist/types/deploy/platforms/cloudflare.d.ts +40 -0
  206. package/dist/types/deploy/platforms/index.d.ts +18 -0
  207. package/dist/types/deploy/platforms/netlify.d.ts +13 -0
  208. package/dist/types/deploy/platforms/node.d.ts +11 -0
  209. package/dist/types/deploy/platforms/paths.d.ts +27 -0
  210. package/dist/types/deploy/platforms/static.d.ts +10 -0
  211. package/dist/types/deploy/platforms/types.d.ts +104 -0
  212. package/dist/types/deploy/platforms/vercel.d.ts +32 -0
  213. package/dist/types/deploy/redirects.d.ts +53 -0
  214. package/dist/types/deploy/robots.d.ts +8 -0
  215. package/dist/types/deploy/rss.d.ts +31 -0
  216. package/dist/types/deploy/sitemap.d.ts +21 -0
  217. package/dist/types/deploy/vercel-negotiation.d.ts +109 -0
  218. package/dist/types/markdown/code-title.d.ts +32 -0
  219. package/dist/types/markdown/fence-meta.d.ts +23 -0
  220. package/dist/types/markdown/themes.d.ts +3 -3
  221. package/dist/types/openapi/asyncapi.d.ts +129 -0
  222. package/dist/types/openapi/graphql-build.d.ts +8 -0
  223. package/dist/types/openapi/graphql.d.ts +122 -0
  224. package/dist/types/openapi/model.d.ts +158 -0
  225. package/dist/types/openapi/parse.d.ts +57 -0
  226. package/dist/types/openapi/references.d.ts +37 -25
  227. package/dist/types/openapi/render-mdx.d.ts +33 -0
  228. package/dist/types/openapi/sentence.d.ts +7 -0
  229. package/dist/types/openapi/signature.d.ts +10 -0
  230. package/dist/types/openapi/source.d.ts +22 -0
  231. package/dist/types/openapi/spec-dependency-error.d.ts +10 -0
  232. package/dist/types/reference/asyncapi.d.ts +166 -0
  233. package/dist/types/reference/graphql.d.ts +181 -0
  234. package/dist/types/reference/index.d.ts +32 -0
  235. package/dist/types/reference/openapi.d.ts +165 -0
  236. package/dist/types/reference/options.d.ts +157 -0
  237. package/dist/types/reference/scalar.d.ts +136 -0
  238. package/dist/types/reference/schema.d.ts +630 -0
  239. package/dist/types/search/adapters/algolia.d.ts +32 -0
  240. package/dist/types/search/adapters/flexsearch.d.ts +12 -0
  241. package/dist/types/search/adapters/index.d.ts +31 -0
  242. package/dist/types/search/adapters/mixedbread.d.ts +22 -0
  243. package/dist/types/search/adapters/orama-cloud.d.ts +33 -0
  244. package/dist/types/search/adapters/orama.d.ts +13 -0
  245. package/dist/types/search/adapters/pagefind.d.ts +12 -0
  246. package/dist/types/search/adapters/registry.d.ts +228 -0
  247. package/dist/types/search/adapters/types.d.ts +34 -0
  248. package/dist/types/search/adapters/typesense.d.ts +42 -0
  249. package/dist/types/search/build.d.ts +23 -0
  250. package/dist/types/search/documents.d.ts +90 -0
  251. package/dist/types/search/facets.d.ts +3 -0
  252. package/dist/types/search/orama-index.d.ts +1 -1
  253. package/dist/types/search/sync/algolia.d.ts +14 -0
  254. package/dist/types/search/sync/index.d.ts +14 -0
  255. package/dist/types/search/sync/orama-cloud.d.ts +10 -0
  256. package/dist/types/search/sync/typesense.d.ts +14 -0
  257. package/dist/types/sources/contentful.d.ts +68 -0
  258. package/dist/types/sources/custom.d.ts +20 -0
  259. package/dist/types/sources/filesystem.d.ts +42 -0
  260. package/dist/types/sources/github-releases.d.ts +46 -0
  261. package/dist/types/sources/index.d.ts +48 -0
  262. package/dist/types/sources/mdx-remote.d.ts +63 -0
  263. package/dist/types/sources/notion.d.ts +65 -0
  264. package/dist/types/sources/obsidian.d.ts +34 -0
  265. package/dist/types/sources/payload.d.ts +68 -0
  266. package/dist/types/sources/registry.d.ts +1414 -0
  267. package/dist/types/sources/sanity.d.ts +69 -0
  268. package/dist/types/sources/shared.d.ts +46 -0
  269. package/dist/types/sources/strapi.d.ts +66 -0
  270. package/dist/types/theme/icon-kind.d.ts +11 -0
  271. package/dist/types/theme/icons.d.ts +20 -0
  272. package/docs/01-quickstart.mdx +18 -18
  273. package/docs/02-deployment.mdx +52 -28
  274. package/docs/03-upgrading.mdx +364 -0
  275. package/docs/04-migrating.mdx +58 -0
  276. package/docs/08-faq.mdx +5 -5
  277. package/docs/advanced/blog.mdx +13 -6
  278. package/docs/advanced/changelog.mdx +23 -35
  279. package/docs/advanced/custom-pages.mdx +22 -10
  280. package/docs/advanced/meta.ts +1 -8
  281. package/docs/advanced/skills.mdx +8 -0
  282. package/docs/cli/audit.mdx +646 -0
  283. package/docs/cli/doctor.mdx +29 -0
  284. package/docs/{reference/eval.mdx → cli/evals.mdx} +12 -11
  285. package/docs/cli/index.mdx +105 -0
  286. package/docs/cli/meta.ts +7 -0
  287. package/docs/{reference → cli}/translate.mdx +9 -9
  288. package/docs/cli/validate.mdx +41 -0
  289. package/docs/cli/version.mdx +40 -0
  290. package/docs/configuration/analytics.mdx +350 -59
  291. package/docs/configuration/assistant.mdx +357 -0
  292. package/docs/configuration/customization.mdx +16 -10
  293. package/docs/configuration/index.mdx +50 -31
  294. package/docs/configuration/meta.ts +1 -1
  295. package/docs/configuration/search.mdx +76 -55
  296. package/docs/configuration/theming.mdx +24 -15
  297. package/docs/content/components.mdx +21 -5
  298. package/docs/{reference → content}/frontmatter.mdx +35 -1
  299. package/docs/content/i18n.mdx +9 -7
  300. package/docs/content/includes.mdx +2 -4
  301. package/docs/content/index.mdx +1 -1
  302. package/docs/content/islands.mdx +11 -6
  303. package/docs/content/meta.mdx +1 -1
  304. package/docs/content/meta.ts +1 -0
  305. package/docs/content/navigation.mdx +9 -7
  306. package/docs/content/sources.mdx +145 -50
  307. package/docs/content/syntax.mdx +16 -12
  308. package/docs/content/versioning.mdx +3 -3
  309. package/docs/discoverability/agent-discovery.mdx +12 -12
  310. package/docs/discoverability/index.mdx +4 -4
  311. package/docs/discoverability/json-api.mdx +4 -4
  312. package/docs/discoverability/llms-txt.mdx +6 -6
  313. package/docs/discoverability/markdown.mdx +4 -4
  314. package/docs/discoverability/mcp.mdx +11 -11
  315. package/docs/discoverability/sitemap-and-robots.mdx +3 -3
  316. package/docs/index.mdx +4 -4
  317. package/docs/references/asyncapi.mdx +59 -0
  318. package/docs/{advanced → references}/graphql.mdx +45 -32
  319. package/docs/{reference → references}/meta.ts +2 -2
  320. package/docs/references/openapi.mdx +171 -0
  321. package/docs/references/scalar.mdx +64 -0
  322. package/package.json +42 -8
  323. package/skills/blume/SKILL.md +23 -10
  324. package/skills/blume-migrate/SKILL.md +22 -21
  325. package/skills/blume-migrate/assets/oxfmt@0.67.0.patch +49 -0
  326. package/skills/blume-migrate/references/docusaurus.md +5 -4
  327. package/skills/blume-migrate/references/fumadocs.md +4 -4
  328. package/skills/blume-migrate/references/mintlify.md +23 -8
  329. package/skills/blume-migrate/references/monorepo.md +6 -6
  330. package/skills/blume-migrate/references/starlight.md +4 -4
  331. package/src/ai/agent-readability.ts +25 -26
  332. package/src/ai/ai-catalog.ts +50 -32
  333. package/src/ai/api/handlers.ts +46 -11
  334. package/src/ai/api/paths.ts +1 -1
  335. package/src/ai/api-catalog.ts +8 -8
  336. package/src/ai/ask-context.ts +7 -7
  337. package/src/ai/ask-data.ts +3 -3
  338. package/src/ai/ask.ts +637 -100
  339. package/src/ai/changelog-markdown.ts +91 -0
  340. package/src/ai/component-markdown.ts +328 -12
  341. package/src/ai/cors.ts +3 -3
  342. package/src/ai/index.ts +45 -0
  343. package/src/ai/link-headers.ts +7 -6
  344. package/src/ai/llms.ts +20 -15
  345. package/src/ai/markdown.ts +35 -5
  346. package/src/ai/mcp/data.ts +9 -5
  347. package/src/ai/openapi-components.ts +5 -2
  348. package/src/ai/relative-links.ts +170 -0
  349. package/src/ai/serializers.ts +3 -3
  350. package/src/ai/skills.ts +1 -1
  351. package/src/ai/visibility.ts +1 -1
  352. package/src/ai/web-bot-auth.ts +2 -2
  353. package/src/analytics/adobe.ts +46 -0
  354. package/src/analytics/amplitude.ts +79 -0
  355. package/src/analytics/clarity.ts +46 -0
  356. package/src/analytics/clearbit.ts +47 -0
  357. package/src/analytics/cloudflare.ts +67 -0
  358. package/src/analytics/fathom.ts +64 -0
  359. package/src/analytics/google-analytics.ts +84 -0
  360. package/src/analytics/google-tag-manager.ts +61 -0
  361. package/src/analytics/head.ts +130 -0
  362. package/src/analytics/heap.ts +65 -0
  363. package/src/analytics/hightouch.ts +77 -0
  364. package/src/analytics/hotjar.ts +47 -0
  365. package/src/analytics/index.ts +71 -0
  366. package/src/analytics/inline.ts +21 -0
  367. package/src/analytics/logrocket.ts +71 -0
  368. package/src/analytics/mixpanel.ts +92 -0
  369. package/src/analytics/pirsch.ts +66 -0
  370. package/src/analytics/plausible.ts +83 -0
  371. package/src/analytics/posthog.ts +78 -0
  372. package/src/analytics/schema.ts +60 -0
  373. package/src/analytics/script.ts +60 -0
  374. package/src/analytics/segment.ts +85 -0
  375. package/src/analytics/vercel.ts +50 -0
  376. package/src/astro/adapter-root.ts +7 -9
  377. package/src/astro/component-slots.ts +131 -91
  378. package/src/astro/generate.ts +129 -361
  379. package/src/astro/integration.ts +2 -6
  380. package/src/astro/module-types.ts +1 -1
  381. package/src/astro/pages.ts +13 -101
  382. package/src/astro/render-deps.ts +379 -0
  383. package/src/astro/runtime-deps.ts +201 -0
  384. package/src/astro/templates.ts +575 -562
  385. package/src/audit/agent.ts +24 -0
  386. package/src/audit/catalog.ts +2 -2
  387. package/src/audit/checks/assets.ts +2 -2
  388. package/src/audit/checks/dns-aid.ts +1 -1
  389. package/src/audit/checks/duplicates.ts +3 -1
  390. package/src/audit/checks/i18n.ts +1 -1
  391. package/src/audit/checks/indexability.ts +7 -7
  392. package/src/audit/checks/links.ts +2 -2
  393. package/src/audit/checks/llms.ts +6 -6
  394. package/src/audit/checks/network.ts +3 -3
  395. package/src/audit/checks/og-image.ts +2 -2
  396. package/src/audit/checks/robots.ts +1 -1
  397. package/src/audit/checks/sitemap.ts +2 -2
  398. package/src/audit/checks/social.ts +1 -1
  399. package/src/audit/run.ts +4 -3
  400. package/src/audit/terms.ts +31 -0
  401. package/src/audit/url.ts +13 -13
  402. package/src/blume-modules.d.ts +2 -2
  403. package/src/cli/command-meta.ts +10 -0
  404. package/src/cli/commands/audit.ts +40 -21
  405. package/src/cli/commands/build.ts +71 -316
  406. package/src/cli/commands/check.ts +1 -0
  407. package/src/cli/commands/dev.ts +40 -1
  408. package/src/cli/commands/doctor.ts +92 -14
  409. package/src/cli/commands/eject.ts +44 -7
  410. package/src/cli/commands/eval.ts +5 -5
  411. package/src/cli/commands/init.ts +161 -41
  412. package/src/cli/commands/migrate.ts +121 -0
  413. package/src/cli/commands/preview.ts +7 -1
  414. package/src/cli/commands/translate.ts +5 -5
  415. package/src/cli/commands/upgrade.ts +141 -0
  416. package/src/cli/commands/version.ts +57 -44
  417. package/src/cli/eject-scripts.ts +121 -6
  418. package/src/cli/index.ts +11 -1
  419. package/src/cli/init/install.ts +70 -0
  420. package/src/cli/init/questions.ts +7 -0
  421. package/src/cli/init/scaffold.ts +459 -75
  422. package/src/cli/lazy-command.ts +37 -1
  423. package/src/cli/prepare.ts +40 -6
  424. package/src/cli/required-secrets.ts +39 -12
  425. package/src/cli/unknown-flags.ts +266 -0
  426. package/src/cli/yarn-pnp.ts +52 -0
  427. package/src/components/content/AccordionItem.astro +7 -1
  428. package/src/components/content/Card.astro +4 -3
  429. package/src/components/content/ColorItem.astro +22 -4
  430. package/src/components/content/GithubInfo.astro +2 -2
  431. package/src/components/content/Prompt.astro +25 -25
  432. package/src/components/content/Tabs.astro +3 -1
  433. package/src/components/content/Tile.astro +2 -3
  434. package/src/components/content/Tooltip.astro +57 -9
  435. package/src/components/content/content-strings.ts +34 -0
  436. package/src/components/content/diff.ts +1 -1
  437. package/src/components/content/mermaid-element.ts +13 -2
  438. package/src/components/content/prompt-markdown.ts +292 -0
  439. package/src/components/content/tooltip-id.ts +41 -0
  440. package/src/components/copy-feedback.ts +1 -1
  441. package/src/components/islands/{AskAI.astro → Assistant.astro} +10 -10
  442. package/src/components/islands/{ask-ai.tsx → assistant.tsx} +23 -23
  443. package/src/components/islands/hooks.ts +36 -11
  444. package/src/components/layout/Analytics.astro +21 -79
  445. package/src/components/layout/Banner.astro +3 -1
  446. package/src/components/layout/DiscoveryLinks.astro +69 -0
  447. package/src/components/layout/Header.astro +93 -30
  448. package/src/components/layout/LanguageSwitcher.astro +4 -1
  449. package/src/components/layout/Logo.astro +23 -2
  450. package/src/components/layout/NavSelector.astro +13 -2
  451. package/src/components/layout/NavTree.astro +12 -3
  452. package/src/components/layout/NavTreeScript.astro +17 -3
  453. package/src/components/layout/PageActions.astro +3 -3
  454. package/src/components/layout/PageFeedback.astro +11 -1
  455. package/src/components/layout/PageLayout.astro +58 -11
  456. package/src/components/layout/Pagination.astro +7 -7
  457. package/src/components/layout/ReferenceLayout.astro +22 -13
  458. package/src/components/layout/RootLayout.astro +75 -72
  459. package/src/components/layout/Search.astro +43 -19
  460. package/src/components/layout/WebMcp.astro +1 -1
  461. package/src/components/layout/analytics-client.ts +73 -16
  462. package/src/components/layout/drawer-inert.ts +113 -15
  463. package/src/components/layout/dropdown-clamp.ts +105 -0
  464. package/src/components/layout/head-scripts.ts +15 -6
  465. package/src/components/layout/nav-utils.ts +17 -0
  466. package/src/components/layout/search/algolia.ts +8 -8
  467. package/src/components/layout/search/orama-cloud.ts +9 -7
  468. package/src/components/layout/search/typesense.ts +11 -17
  469. package/src/components/openapi/MessageComposer.astro +2 -2
  470. package/src/components/openapi/Playground.astro +2 -2
  471. package/src/components/openapi/description.ts +2 -2
  472. package/src/components/openapi/playground-client.ts +79 -10
  473. package/src/core/changelog-index.ts +24 -0
  474. package/src/core/code-fences.ts +1 -1
  475. package/src/core/component-overrides.ts +399 -154
  476. package/src/core/config-input.ts +201 -566
  477. package/src/core/config.ts +131 -42
  478. package/src/core/custom-pages.ts +105 -0
  479. package/src/core/data.ts +34 -15
  480. package/src/core/define-components.ts +12 -9
  481. package/src/core/deployment-env.ts +18 -74
  482. package/src/core/diagnostics.ts +14 -7
  483. package/src/core/graph.ts +69 -25
  484. package/src/core/i18n-ui.ts +41 -11
  485. package/src/core/i18n.ts +17 -0
  486. package/src/core/includes.ts +156 -38
  487. package/src/core/last-modified.ts +6 -11
  488. package/src/core/links.ts +166 -2
  489. package/src/core/manifest.ts +10 -3
  490. package/src/core/navigation.ts +115 -16
  491. package/src/core/new-tab.ts +35 -0
  492. package/src/core/node-require.ts +21 -0
  493. package/src/core/project-graph.ts +42 -26
  494. package/src/core/project.ts +9 -4
  495. package/src/core/request-body.ts +61 -0
  496. package/src/core/safe-href.ts +28 -0
  497. package/src/core/safe-links.ts +68 -0
  498. package/src/core/schema.ts +528 -745
  499. package/src/core/server-features.ts +10 -11
  500. package/src/core/sources/assets.ts +47 -11
  501. package/src/core/sources/collection.ts +67 -0
  502. package/src/core/sources/contentful-rich-text.ts +285 -0
  503. package/src/core/sources/contentful.ts +173 -0
  504. package/src/core/sources/github-releases.ts +51 -1
  505. package/src/core/sources/json.ts +71 -0
  506. package/src/core/sources/lexical.ts +195 -0
  507. package/src/core/sources/lower.ts +226 -0
  508. package/src/core/sources/normalize.ts +52 -2
  509. package/src/core/sources/notion.ts +39 -28
  510. package/src/core/sources/payload.ts +135 -0
  511. package/src/core/sources/portable-text.ts +11 -16
  512. package/src/core/sources/remote.ts +226 -0
  513. package/src/core/sources/resolve.ts +104 -166
  514. package/src/core/sources/sanity.ts +16 -49
  515. package/src/core/sources/strapi-blocks.ts +124 -0
  516. package/src/core/sources/strapi.ts +191 -0
  517. package/src/core/sources/types.ts +12 -1
  518. package/src/core/types.ts +15 -1
  519. package/src/core/ui-packs/ar.ts +10 -7
  520. package/src/core/ui-packs/bg.ts +10 -7
  521. package/src/core/ui-packs/bn.ts +10 -7
  522. package/src/core/ui-packs/ca.ts +7 -6
  523. package/src/core/ui-packs/cs.ts +10 -7
  524. package/src/core/ui-packs/da.ts +10 -7
  525. package/src/core/ui-packs/de.ts +10 -7
  526. package/src/core/ui-packs/el.ts +7 -6
  527. package/src/core/ui-packs/es.ts +7 -6
  528. package/src/core/ui-packs/fa.ts +10 -7
  529. package/src/core/ui-packs/fi.ts +10 -7
  530. package/src/core/ui-packs/fr.ts +7 -6
  531. package/src/core/ui-packs/he.ts +10 -7
  532. package/src/core/ui-packs/hi.ts +10 -7
  533. package/src/core/ui-packs/hr.ts +10 -7
  534. package/src/core/ui-packs/hu.ts +10 -7
  535. package/src/core/ui-packs/id.ts +10 -7
  536. package/src/core/ui-packs/it.ts +7 -6
  537. package/src/core/ui-packs/ja.ts +7 -6
  538. package/src/core/ui-packs/ko.ts +7 -6
  539. package/src/core/ui-packs/nl.ts +10 -7
  540. package/src/core/ui-packs/no.ts +10 -7
  541. package/src/core/ui-packs/pl.ts +10 -7
  542. package/src/core/ui-packs/pt-br.ts +7 -6
  543. package/src/core/ui-packs/pt.ts +7 -6
  544. package/src/core/ui-packs/ro.ts +10 -7
  545. package/src/core/ui-packs/ru.ts +10 -7
  546. package/src/core/ui-packs/sk.ts +10 -7
  547. package/src/core/ui-packs/sr.ts +10 -7
  548. package/src/core/ui-packs/sv.ts +10 -7
  549. package/src/core/ui-packs/th.ts +7 -6
  550. package/src/core/ui-packs/tr.ts +10 -7
  551. package/src/core/ui-packs/uk.ts +10 -7
  552. package/src/core/ui-packs/vi.ts +7 -6
  553. package/src/core/ui-packs/zh-tw.ts +7 -6
  554. package/src/core/ui-packs/zh.ts +7 -6
  555. package/src/core/unrecognized-keys.ts +10 -0
  556. package/src/core/version-cut.ts +116 -8
  557. package/src/deploy/adapter-output.ts +57 -97
  558. package/src/deploy/adapters/cloudflare.ts +39 -0
  559. package/src/deploy/adapters/index.ts +41 -0
  560. package/src/deploy/adapters/netlify.ts +34 -0
  561. package/src/deploy/adapters/node.ts +34 -0
  562. package/src/deploy/adapters/registry.ts +127 -0
  563. package/src/deploy/adapters/types.ts +92 -0
  564. package/src/deploy/adapters/vercel.ts +35 -0
  565. package/src/deploy/artifacts.ts +55 -27
  566. package/src/deploy/cloudflare-negotiation.ts +179 -100
  567. package/src/deploy/function-bundle.ts +18 -3
  568. package/src/deploy/headers.ts +124 -23
  569. package/src/deploy/node-headers.ts +198 -0
  570. package/src/deploy/platforms/cloudflare.ts +312 -0
  571. package/src/deploy/platforms/index.ts +67 -0
  572. package/src/deploy/platforms/netlify.ts +52 -0
  573. package/src/deploy/platforms/node.ts +40 -0
  574. package/src/deploy/platforms/paths.ts +42 -0
  575. package/src/deploy/platforms/static.ts +29 -0
  576. package/src/deploy/platforms/types.ts +112 -0
  577. package/src/deploy/platforms/vercel.ts +193 -0
  578. package/src/deploy/redirects.ts +30 -18
  579. package/src/deploy/robots.ts +3 -3
  580. package/src/deploy/rss.ts +2 -2
  581. package/src/deploy/sitemap.ts +2 -2
  582. package/src/deploy/vercel-negotiation.ts +2 -2
  583. package/src/eval/agents.ts +32 -1
  584. package/src/eval/findings.ts +19 -11
  585. package/src/eval/report.ts +10 -2
  586. package/src/markdown/external-links.ts +65 -0
  587. package/src/markdown/include.ts +45 -27
  588. package/src/markdown/index.ts +34 -9
  589. package/src/markdown/inline-code.ts +12 -6
  590. package/src/markdown/relative-links.ts +324 -0
  591. package/src/markdown/themes.ts +3 -3
  592. package/src/migrate/migrate.ts +149 -0
  593. package/src/openapi/parse.ts +64 -16
  594. package/src/openapi/proxy.ts +62 -10
  595. package/src/openapi/references.ts +147 -147
  596. package/src/openapi/render-mdx.ts +32 -10
  597. package/src/openapi/scalar.ts +15 -13
  598. package/src/openapi/sentence.ts +14 -0
  599. package/src/openapi/source.ts +37 -21
  600. package/src/openapi/spec-dependency-error.ts +15 -0
  601. package/src/reference/asyncapi.ts +83 -0
  602. package/src/reference/graphql.ts +89 -0
  603. package/src/reference/index.ts +40 -0
  604. package/src/reference/openapi.ts +83 -0
  605. package/src/reference/options.ts +201 -0
  606. package/src/reference/scalar.ts +136 -0
  607. package/src/reference/schema.ts +88 -0
  608. package/src/registry/eject.ts +109 -53
  609. package/src/search/adapters/algolia.ts +46 -0
  610. package/src/search/adapters/flexsearch.ts +29 -0
  611. package/src/search/adapters/index.ts +39 -0
  612. package/src/search/adapters/mixedbread.ts +39 -0
  613. package/src/search/adapters/orama-cloud.ts +51 -0
  614. package/src/search/adapters/orama.ts +24 -0
  615. package/src/search/adapters/pagefind.ts +27 -0
  616. package/src/search/adapters/registry.ts +131 -0
  617. package/src/search/adapters/types.ts +46 -0
  618. package/src/search/adapters/typesense.ts +57 -0
  619. package/src/search/build.ts +8 -4
  620. package/src/search/documents.ts +8 -2
  621. package/src/search/orama-index.ts +1 -1
  622. package/src/search/sync/algolia.ts +12 -11
  623. package/src/search/sync/index.ts +35 -20
  624. package/src/search/sync/orama-cloud.ts +12 -9
  625. package/src/search/sync/typesense.ts +15 -13
  626. package/src/sources/contentful.ts +63 -0
  627. package/src/sources/custom.ts +38 -0
  628. package/src/sources/filesystem.ts +51 -0
  629. package/src/sources/github-releases.ts +52 -0
  630. package/src/sources/index.ts +60 -0
  631. package/src/sources/mdx-remote.ts +76 -0
  632. package/src/sources/notion.ts +63 -0
  633. package/src/sources/obsidian.ts +38 -0
  634. package/src/sources/payload.ts +60 -0
  635. package/src/sources/registry.ts +182 -0
  636. package/src/sources/sanity.ts +66 -0
  637. package/src/sources/shared.ts +52 -0
  638. package/src/sources/strapi.ts +58 -0
  639. package/src/theme/entry.ts +24 -2
  640. package/src/translate/report.ts +40 -7
  641. package/src/upgrade/upgrade.ts +499 -0
  642. package/dist/cli/chunk-0qymqwzz.js +0 -164
  643. package/dist/cli/chunk-0qymqwzz.js.map +0 -15
  644. package/dist/cli/chunk-1jefwnfs.js.map +0 -48
  645. package/dist/cli/chunk-2mzebbbz.js +0 -69
  646. package/dist/cli/chunk-2z47ypj8.js.map +0 -11
  647. package/dist/cli/chunk-4x36ddpw.js.map +0 -11
  648. package/dist/cli/chunk-5093q3n7.js +0 -68
  649. package/dist/cli/chunk-5093q3n7.js.map +0 -10
  650. package/dist/cli/chunk-5qk08vmp.js.map +0 -11
  651. package/dist/cli/chunk-7s8hm3b6.js +0 -5347
  652. package/dist/cli/chunk-7s8hm3b6.js.map +0 -58
  653. package/dist/cli/chunk-8cjtbafj.js.map +0 -13
  654. package/dist/cli/chunk-97r59kpr.js +0 -381
  655. package/dist/cli/chunk-97r59kpr.js.map +0 -12
  656. package/dist/cli/chunk-ahnw3kxw.js.map +0 -15
  657. package/dist/cli/chunk-b27xqwn9.js.map +0 -10
  658. package/dist/cli/chunk-bf6bt1xt.js +0 -185
  659. package/dist/cli/chunk-bf6bt1xt.js.map +0 -11
  660. package/dist/cli/chunk-cjtn640a.js.map +0 -10
  661. package/dist/cli/chunk-ct47dqpx.js.map +0 -11
  662. package/dist/cli/chunk-esphfr8p.js +0 -107
  663. package/dist/cli/chunk-esphfr8p.js.map +0 -11
  664. package/dist/cli/chunk-ex56aa81.js +0 -1016
  665. package/dist/cli/chunk-ex56aa81.js.map +0 -13
  666. package/dist/cli/chunk-garjf5z9.js +0 -30
  667. package/dist/cli/chunk-garjf5z9.js.map +0 -10
  668. package/dist/cli/chunk-js7saxwm.js +0 -1045
  669. package/dist/cli/chunk-js7saxwm.js.map +0 -22
  670. package/dist/cli/chunk-k79xp7av.js.map +0 -39
  671. package/dist/cli/chunk-ps4m1xh4.js.map +0 -15
  672. package/dist/cli/chunk-q4rae3bg.js +0 -60
  673. package/dist/cli/chunk-q4rae3bg.js.map +0 -10
  674. package/dist/cli/chunk-rz9jmfhz.js +0 -108
  675. package/dist/cli/chunk-rz9jmfhz.js.map +0 -10
  676. package/dist/cli/chunk-vh9w1sgp.js +0 -73
  677. package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
  678. package/dist/cli/chunk-vrfp10qk.js +0 -81
  679. package/dist/cli/chunk-vrfp10qk.js.map +0 -10
  680. package/dist/cli/chunk-yg63d42r.js.map +0 -34
  681. package/docs/advanced/api-reference.mdx +0 -240
  682. package/docs/configuration/ask-ai.mdx +0 -256
  683. package/docs/reference/cli.mdx +0 -197
  684. package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
  685. package/src/components/content/changelog-element.ts +0 -69
  686. package/src/search/providers.ts +0 -91
  687. /package/dist/cli/{chunk-vacwm2hv.js.map → chunk-27g6wdth.js.map} +0 -0
  688. /package/dist/cli/{chunk-dwgcp5sm.js.map → chunk-ce574jw2.js.map} +0 -0
  689. /package/dist/cli/{chunk-e7f42gdj.js.map → chunk-fxypxtvm.js.map} +0 -0
  690. /package/dist/cli/{chunk-nn13znc2.js.map → chunk-zxcczpyx.js.map} +0 -0
@@ -0,0 +1,312 @@
1
+ import { existsSync } from "node:fs";
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+
4
+ import { basename, dirname, join, relative, resolve } from "pathe";
5
+
6
+ import { pageJsonPath } from "../../ai/api/paths.ts";
7
+ import { buildHomeLinkHeader } from "../../ai/link-headers.ts";
8
+ import {
9
+ agentMarkdown,
10
+ buildRawMarkdown,
11
+ markdownRoutePaths,
12
+ markdownTokenCount,
13
+ } from "../../ai/markdown.ts";
14
+ import type { BlumeProject } from "../../core/project-graph.ts";
15
+ import type { ProjectContext } from "../../core/types.ts";
16
+ import { CLOUDFLARE_ADAPTER_PACKAGE } from "../adapters/cloudflare.ts";
17
+ import {
18
+ injectWorkerNegotiation,
19
+ NEGOTIATION_WORKER_FILE,
20
+ } from "../cloudflare-negotiation.ts";
21
+ import { platformRedirects } from "../redirects.ts";
22
+ import { REDIRECTS_FILE } from "./netlify.ts";
23
+ import { clientDir, distDir, toSiteUrl } from "./paths.ts";
24
+ import type { BuildLog, DeployPlatform } from "./types.ts";
25
+
26
+ const WRANGLER_CONFIG_FILES = [
27
+ "wrangler.jsonc",
28
+ "wrangler.json",
29
+ "wrangler.toml",
30
+ ];
31
+
32
+ /**
33
+ * The adapter's constructor options. Every Blume HTML route prerenders (the
34
+ * only server routes are API endpoints), so images are optimized at build
35
+ * time with sharp: the adapter's default (`cloudflare-binding`) would instead
36
+ * declare a runtime `IMAGES` binding in the generated wrangler config that
37
+ * nothing uses. A wrangler config at the project root is pointed at
38
+ * explicitly, because the adapter would otherwise look beside the Astro
39
+ * root — the hidden runtime — and the dev workerd runtime would miss
40
+ * `nodejs_compat`.
41
+ */
42
+ const adapterOptions = (context: ProjectContext) => {
43
+ const options = { imageService: "compile", prerenderEnvironment: "node" };
44
+ const wranglerPath = WRANGLER_CONFIG_FILES.map((file) =>
45
+ join(context.root, file)
46
+ ).find((file) => existsSync(file));
47
+ if (!wranglerPath) {
48
+ return options;
49
+ }
50
+ let configPath = relative(context.outDir, wranglerPath);
51
+ // The wrangler config always lives at the project root, above the `.blume`
52
+ // runtime, so `relative` yields a `../…` path; normalize the theoretical
53
+ // sibling case to an explicit `./` so it reads as relative.
54
+ if (!configPath.startsWith(".") && !configPath.startsWith("/")) {
55
+ configPath = `./${configPath}`;
56
+ }
57
+ return { ...options, configPath };
58
+ };
59
+
60
+ const warnNegotiationSkipped = (log: BuildLog): void =>
61
+ log.warn(
62
+ "Could not wire Accept: text/markdown negotiation into dist/server/wrangler.json — raw Markdown stays available at the .md URLs."
63
+ );
64
+
65
+ /**
66
+ * Wire `Accept: text/markdown` negotiation into a server build. The ASSETS
67
+ * binding serves the prerendered content pages before the Worker runs — and
68
+ * even a request that reaches the Worker is answered by the adapter's handler
69
+ * from that binding, ahead of the only place middleware runs — so the
70
+ * negotiation lives in a generated wrapper Worker, routed to by
71
+ * `assets.run_worker_first` (see `deploy/cloudflare-negotiation.ts`). Both
72
+ * pieces are spliced into the adapter's emitted `dist/server` bundle.
73
+ */
74
+ export const emitCloudflareNegotiation = async (
75
+ project: BlumeProject,
76
+ log: BuildLog
77
+ ): Promise<void> => {
78
+ const { config, context } = project;
79
+ const serverDir = join(distDir(context), "server");
80
+ const wranglerPath = join(serverDir, "wrangler.json");
81
+ if (!existsSync(wranglerPath)) {
82
+ warnNegotiationSkipped(log);
83
+ return;
84
+ }
85
+ const routePaths = markdownRoutePaths(project);
86
+ // The homepage mirror is served from the static layer, so its
87
+ // `x-markdown-tokens` estimate rides the wrapper Worker, mirroring the
88
+ // Vercel routing config.
89
+ const rawMarkdown = await buildRawMarkdown(project);
90
+ const home = rawMarkdown["/"];
91
+ // The 404 twins the wrapper may substitute for the HTML shell; only wired
92
+ // when the build actually emitted them (a project that owns `/404` gets
93
+ // neither), like the Vercel routing config.
94
+ const staticDir = clientDir(context);
95
+ const injected = injectWorkerNegotiation(
96
+ await readFile(wranglerPath, "utf-8"),
97
+ {
98
+ base: config.deployment.options.base,
99
+ // The manifest routes guard the wrapper's redirect table; `routePaths`
100
+ // also carries the synthesized homepage mirror, which must not block a
101
+ // configured root redirect.
102
+ contentRoutePaths: project.manifest.routes.map((route) => route.path),
103
+ homeLinkHeader: buildHomeLinkHeader(config, routePaths),
104
+ homeTokens: home ? markdownTokenCount(agentMarkdown(home)) : undefined,
105
+ notFound: {
106
+ json: existsSync(join(staticDir, "404.json")),
107
+ markdown: existsSync(join(staticDir, "404.md")),
108
+ },
109
+ // Exactly the per-page JSON documents the API emits (see `pageParams`):
110
+ // the non-hidden routes with agent Markdown, when the API is on.
111
+ pageJsonPaths: config.agents.api
112
+ ? project.manifest.routes
113
+ .filter(
114
+ (route) => !route.hidden && rawMarkdown[route.path] !== undefined
115
+ )
116
+ .map((route) => pageJsonPath(route.path))
117
+ : [],
118
+ // The wrapper Worker matches full served URLs, so the redirects are
119
+ // based the same way the platform files are — it answers any the
120
+ // worker-first rules claim, where `_redirects` is never consulted and
121
+ // Astro would default their status.
122
+ redirects: platformRedirects(config),
123
+ routePaths,
124
+ }
125
+ );
126
+ if (injected === null) {
127
+ warnNegotiationSkipped(log);
128
+ return;
129
+ }
130
+ await writeFile(
131
+ join(serverDir, NEGOTIATION_WORKER_FILE),
132
+ injected.worker,
133
+ "utf-8"
134
+ );
135
+ await writeFile(wranglerPath, injected.wrangler, "utf-8");
136
+ log.success(
137
+ "Wired Accept: text/markdown negotiation into the Cloudflare Worker"
138
+ );
139
+ };
140
+
141
+ /**
142
+ * Where Cloudflare's deploy tooling looks for the redirect to the built
143
+ * config, relative to the directory `wrangler deploy` runs in (or any parent).
144
+ */
145
+ const DEPLOY_CONFIG = join(".wrangler", "deploy", "config.json");
146
+
147
+ /** The redirect file the Cloudflare Vite plugin writes. */
148
+ interface DeployConfig {
149
+ auxiliaryWorkers?: { configPath: string }[];
150
+ configPath: string;
151
+ prerenderWorkerConfigPath?: string;
152
+ }
153
+
154
+ /**
155
+ * Point `wrangler deploy` run from the project root at the built Worker.
156
+ * The adapter's Vite plugin writes its redirect beside the Astro root — the
157
+ * hidden `.blume` runtime, where nobody runs wrangler — and wrangler only
158
+ * looks in the working directory and its parents, so from the project root it
159
+ * finds no config and fails with "Could not detect a directory containing
160
+ * static files". This writes the same redirect at the project root, its paths
161
+ * rebased there. A user wrangler config at the project root stays compatible:
162
+ * wrangler accepts a redirect in the same directory's `.wrangler/deploy/`.
163
+ */
164
+ export const emitCloudflareDeployConfig = async (
165
+ context: ProjectContext
166
+ ): Promise<void> => {
167
+ const builtConfig = join(distDir(context), "server", "wrangler.json");
168
+ if (!existsSync(builtConfig)) {
169
+ return;
170
+ }
171
+ const source = join(context.outDir, DEPLOY_CONFIG);
172
+ const target = join(context.root, DEPLOY_CONFIG);
173
+ const rebase = (path: string): string =>
174
+ relative(dirname(target), resolve(dirname(source), path));
175
+ const deployConfig: DeployConfig = existsSync(source)
176
+ ? JSON.parse(await readFile(source, "utf-8"))
177
+ : { configPath: relative(dirname(source), builtConfig) };
178
+ const rebased: DeployConfig = {
179
+ auxiliaryWorkers: (deployConfig.auxiliaryWorkers ?? []).map((worker) => ({
180
+ configPath: rebase(worker.configPath),
181
+ })),
182
+ configPath: rebase(deployConfig.configPath),
183
+ };
184
+ if (deployConfig.prerenderWorkerConfigPath) {
185
+ rebased.prerenderWorkerConfigPath = rebase(
186
+ deployConfig.prerenderWorkerConfigPath
187
+ );
188
+ }
189
+ await mkdir(dirname(target), { recursive: true });
190
+ await writeFile(target, `${JSON.stringify(rebased)}\n`, "utf-8");
191
+ };
192
+
193
+ /**
194
+ * The name the Worker gets when the build names it: the generated runtime's
195
+ * package name, which every Blume site shares. Left as is, two sites deployed
196
+ * to one account would overwrite each other's Worker.
197
+ */
198
+ const RUNTIME_WORKER_NAME = "blume-runtime";
199
+
200
+ /**
201
+ * A Worker name from free text: lowercase letters, digits, and dashes, no
202
+ * leading or trailing dash, at most 63 characters (a Worker name is also a
203
+ * `workers.dev` hostname label).
204
+ */
205
+ const toWorkerName = (text: string): string =>
206
+ text
207
+ .toLowerCase()
208
+ .replaceAll(/[^\da-z]+/gu, "-")
209
+ .slice(0, 63)
210
+ .replaceAll(/^-+|-+$/gu, "");
211
+
212
+ /**
213
+ * The Worker name for a project that doesn't name its own: the project's
214
+ * `package.json` name (a scope folded in, `@acme/docs` → `acme-docs`), else the
215
+ * site's hostname, else the project folder's name.
216
+ */
217
+ const projectWorkerName = async (
218
+ project: BlumeProject
219
+ ): Promise<string | undefined> => {
220
+ const { config, context } = project;
221
+ const packageFile = join(context.root, "package.json");
222
+ const manifest: { name?: string } = existsSync(packageFile)
223
+ ? JSON.parse(await readFile(packageFile, "utf-8"))
224
+ : {};
225
+ const { site } = config.deployment.options;
226
+ return [
227
+ String(manifest.name ?? ""),
228
+ site ? new URL(site).hostname : "",
229
+ basename(context.root),
230
+ ]
231
+ .map(toWorkerName)
232
+ .find((name) => name.length > 0);
233
+ };
234
+
235
+ /**
236
+ * Name the built Worker after the project when it still carries the shared
237
+ * runtime name. A name set in the project's own wrangler config reaches the
238
+ * built config instead, and is left alone.
239
+ */
240
+ export const nameCloudflareWorker = async (
241
+ project: BlumeProject,
242
+ log: BuildLog
243
+ ): Promise<void> => {
244
+ const wranglerPath = join(
245
+ distDir(project.context),
246
+ "server",
247
+ "wrangler.json"
248
+ );
249
+ if (!existsSync(wranglerPath)) {
250
+ return;
251
+ }
252
+ // Only the two name fields are read; every other key rides through as parsed.
253
+ const wrangler: { name?: string; topLevelName?: string } = JSON.parse(
254
+ await readFile(wranglerPath, "utf-8")
255
+ );
256
+ const name = await projectWorkerName(project);
257
+ if (wrangler.name !== RUNTIME_WORKER_NAME || name === undefined) {
258
+ return;
259
+ }
260
+ wrangler.name = name;
261
+ if (wrangler.topLevelName === RUNTIME_WORKER_NAME) {
262
+ wrangler.topLevelName = name;
263
+ }
264
+ await writeFile(wranglerPath, JSON.stringify(wrangler), "utf-8");
265
+ log.info(
266
+ `Named the Cloudflare Worker "${name}"; set "name" in a wrangler.jsonc at the project root to choose another.`
267
+ );
268
+ };
269
+
270
+ /**
271
+ * Cloudflare Workers and Pages. A server build emits the Worker into
272
+ * `dist/server` and serves `dist/client` through the ASSETS binding, which
273
+ * honors `_headers` from that directory exactly as Pages does — so the file
274
+ * applies to both output modes here. Without a configured driver the adapter
275
+ * force-enables KV-backed sessions and declares a `SESSION` binding that
276
+ * `wrangler deploy` then demands a namespace for, even though Blume never
277
+ * reads `Astro.session`; `session: false` opts the project out.
278
+ */
279
+ export const cloudflarePlatform: DeployPlatform = {
280
+ astro: {
281
+ config: { session: false },
282
+ options: adapterOptions,
283
+ package: CLOUDFLARE_ADAPTER_PACKAGE,
284
+ },
285
+ env: {
286
+ detect: (env) => Boolean(env.CF_PAGES),
287
+ site: (env) => toSiteUrl(env.CF_PAGES_URL),
288
+ },
289
+ finalizeBuild: async ({ isolated, log, project }) => {
290
+ // The Worker's name, the wrapper Worker, and the deploy redirect are
291
+ // deploy artifacts; an isolated verify skips them.
292
+ if (!isolated) {
293
+ await nameCloudflareWorker(project, log);
294
+ await emitCloudflareNegotiation(project, log);
295
+ await emitCloudflareDeployConfig(project.context);
296
+ }
297
+ return true;
298
+ },
299
+ hiddenRuntime: {
300
+ // The redirected deploy config `wrangler deploy` reads from the project
301
+ // root lands in `.wrangler/`, a build artifact like Vercel's `.vercel/`.
302
+ ignoreDir: ".wrangler/",
303
+ showProjectRoot: false,
304
+ surfacePath: null,
305
+ },
306
+ kind: "cloudflare",
307
+ negotiatesMarkdown: true,
308
+ readsHeaderFiles: { server: true, static: true },
309
+ redirectFiles: [REDIRECTS_FILE],
310
+ serverOutputDir: distDir,
311
+ serverStaticDir: clientDir,
312
+ };
@@ -0,0 +1,67 @@
1
+ import type {
2
+ DeployAdapterKind,
3
+ ResolvedDeployment,
4
+ } from "../adapters/registry.ts";
5
+ import { cloudflarePlatform } from "./cloudflare.ts";
6
+ import { netlifyPlatform } from "./netlify.ts";
7
+ import { nodePlatform } from "./node.ts";
8
+ import { staticPlatform } from "./static.ts";
9
+ import type { DeployPlatform } from "./types.ts";
10
+ import { vercelPlatform } from "./vercel.ts";
11
+
12
+ /**
13
+ * Every platform, in the order their env detection is tried when a build's
14
+ * own adapter says nothing about where it runs (a static build on Vercel
15
+ * still gets its site URL from `VERCEL_URL`).
16
+ */
17
+ export const DEPLOY_PLATFORMS: readonly DeployPlatform[] = [
18
+ vercelPlatform,
19
+ netlifyPlatform,
20
+ cloudflarePlatform,
21
+ nodePlatform,
22
+ staticPlatform,
23
+ ];
24
+
25
+ const byKind = new Map<DeployAdapterKind, DeployPlatform>(
26
+ DEPLOY_PLATFORMS.map((platform) => [platform.kind, platform])
27
+ );
28
+
29
+ /** The behaviors behind a resolved deployment descriptor. */
30
+ export const deployPlatform = (
31
+ deployment: Pick<ResolvedDeployment, "kind">
32
+ ): DeployPlatform => {
33
+ const platform = byKind.get(deployment.kind);
34
+ if (!platform) {
35
+ throw new Error(`Unknown deployment adapter "${deployment.kind}".`);
36
+ }
37
+ return platform;
38
+ };
39
+
40
+ /**
41
+ * The site URL the platform env implies, or null. The configured adapter's
42
+ * own platform is asked first, then the rest in registration order, so a
43
+ * static build (which names no host) still picks up the URL of whichever
44
+ * platform it is building on.
45
+ */
46
+ export const inferDeploymentSite = (
47
+ deployment: Pick<ResolvedDeployment, "kind">,
48
+ env: NodeJS.ProcessEnv
49
+ ): string | null => {
50
+ const own = deployPlatform(deployment);
51
+ const candidates = [own, ...DEPLOY_PLATFORMS.filter((p) => p !== own)];
52
+ const detected = candidates.find(
53
+ (platform) => platform.env?.detect(env) ?? false
54
+ );
55
+ // `find` only returns a platform whose `env` matched, so it is present.
56
+ return detected?.env?.site(env) ?? null;
57
+ };
58
+
59
+ export type {
60
+ AstroAdapterSpec,
61
+ BuildLog,
62
+ DeployPlatform,
63
+ FinalizeBuildOptions,
64
+ HiddenRuntime,
65
+ PlatformEnv,
66
+ RedirectFile,
67
+ } from "./types.ts";
@@ -0,0 +1,52 @@
1
+ import { NETLIFY_ADAPTER_PACKAGE } from "../adapters/netlify.ts";
2
+ import { buildNetlifyRedirects } from "../redirects.ts";
3
+ import { distDir, toSiteUrl } from "./paths.ts";
4
+ import type { DeployPlatform, RedirectFile } from "./types.ts";
5
+
6
+ /** `_redirects`, the format Netlify and Cloudflare Pages/Workers read. */
7
+ export const REDIRECTS_FILE: RedirectFile = {
8
+ build: buildNetlifyRedirects,
9
+ name: "_redirects",
10
+ };
11
+
12
+ /**
13
+ * Netlify. A server build runs on Netlify Functions from the Frameworks API
14
+ * tree the adapter writes to `.netlify/v1`, relative to the Astro root —
15
+ * which for Blume is the hidden `.blume` runtime, so the tree is moved up to
16
+ * the project root after the build (the `.netlify/build` sibling is only the
17
+ * intermediate SSR bundle, already traced into `v1/functions`, and moving
18
+ * `v1` alone keeps the `.netlify/state.json` from `netlify link` intact).
19
+ * Static assets are served from `dist/` either way.
20
+ */
21
+ export const netlifyPlatform: DeployPlatform = {
22
+ astro: {
23
+ config: {},
24
+ options: () => ({}),
25
+ package: NETLIFY_ADAPTER_PACKAGE,
26
+ },
27
+ env: {
28
+ detect: (env) => Boolean(env.NETLIFY),
29
+ // Fall through per *resolved* value, not per variable — a platform can
30
+ // set a var to the empty string, which `??` on the raw values treats as
31
+ // present, dead-ending the chain and silently losing the site URL.
32
+ site: (env) =>
33
+ toSiteUrl(env.URL) ??
34
+ toSiteUrl(env.DEPLOY_PRIME_URL) ??
35
+ toSiteUrl(env.DEPLOY_URL),
36
+ },
37
+ finalizeBuild: null,
38
+ hiddenRuntime: {
39
+ ignoreDir: ".netlify/",
40
+ showProjectRoot: false,
41
+ surfacePath: ".netlify/v1",
42
+ },
43
+ kind: "netlify",
44
+ negotiatesMarkdown: false,
45
+ // Netlify reads `_headers` from the publish directory of a static deploy.
46
+ // A server build's static assets ride the Frameworks API tree instead,
47
+ // where the file has never been applied.
48
+ readsHeaderFiles: { server: false, static: true },
49
+ redirectFiles: [REDIRECTS_FILE],
50
+ serverOutputDir: distDir,
51
+ serverStaticDir: distDir,
52
+ };
@@ -0,0 +1,40 @@
1
+ import { NODE_ADAPTER_PACKAGE } from "../adapters/node.ts";
2
+ import { wrapNodeEntry } from "../node-headers.ts";
3
+ import { clientDir, distDir } from "./paths.ts";
4
+ import type { DeployPlatform } from "./types.ts";
5
+
6
+ /**
7
+ * A self-hosted Node server. The standalone server in `dist/server` serves
8
+ * `dist/client` through its own static handler, which has no `_headers` or
9
+ * `_redirects` support — redirects are answered at request time from the
10
+ * Astro config, and a header file written there would be inert. The headers
11
+ * the discovery files need come from a wrapper around the server entry
12
+ * instead (`deploy/node-headers.ts`). No platform env to detect: the site URL
13
+ * has to be configured.
14
+ */
15
+ export const nodePlatform: DeployPlatform = {
16
+ astro: {
17
+ config: {},
18
+ options: () => ({ mode: "standalone" }),
19
+ package: NODE_ADAPTER_PACKAGE,
20
+ },
21
+ env: null,
22
+ finalizeBuild: async ({ isolated, log, project }) => {
23
+ // The wrapped entry is a deploy artifact; an isolated verify skips it.
24
+ if (!isolated) {
25
+ await wrapNodeEntry(project, log);
26
+ }
27
+ return true;
28
+ },
29
+ hiddenRuntime: {
30
+ ignoreDir: null,
31
+ showProjectRoot: false,
32
+ surfacePath: null,
33
+ },
34
+ kind: "node",
35
+ negotiatesMarkdown: false,
36
+ readsHeaderFiles: { server: false, static: false },
37
+ redirectFiles: [],
38
+ serverOutputDir: distDir,
39
+ serverStaticDir: clientDir,
40
+ };
@@ -0,0 +1,42 @@
1
+ import { dirname, join } from "pathe";
2
+
3
+ import type { ProjectContext } from "../../core/types.ts";
4
+
5
+ /** Astro's build output dir: the runtime's own `distDir`, else `<root>/dist`. */
6
+ export const distDir = (context: ProjectContext): string =>
7
+ context.distDir ?? join(context.root, "dist");
8
+
9
+ /**
10
+ * The `client/` half of a server build that keeps Astro's `dist/client` +
11
+ * `dist/server` split and serves only the client half: the Node standalone
12
+ * server's static handler reads only `build.client`, and `@astrojs/cloudflare`
13
+ * declares `preserveBuildClientDir: true` and points the ASSETS binding in the
14
+ * `dist/server/wrangler.json` it generates at `../client`.
15
+ */
16
+ export const clientDir = (context: ProjectContext): string =>
17
+ join(distDir(context), "client");
18
+
19
+ /**
20
+ * The root a deploy adapter is shown, in place of the `.blume` runtime Astro
21
+ * actually roots at. Adapters assume `outDir` is `<root>/dist` and resolve
22
+ * their own output (and Vercel's dependency trace) against `root`, so the
23
+ * root implied by Blume's `outDir` is the one that keeps that assumption
24
+ * true. See `withAdapterRoot`.
25
+ *
26
+ * For a normal build that is the project root (`<project>/dist` ->
27
+ * `<project>`). For a relocated runtime (`blume build --isolated`) it is the
28
+ * runtime dir itself (`<runtime>/dist` -> `<runtime>`), keeping a verify
29
+ * build's adapter output self-contained instead of overwriting the real
30
+ * `.vercel/output`.
31
+ */
32
+ export const adapterRoot = (context: ProjectContext): string =>
33
+ dirname(distDir(context));
34
+
35
+ /** Prefix a bare host with `https://`; pass values that are already absolute. */
36
+ export const toSiteUrl = (value: string | undefined): string | null => {
37
+ const trimmed = value?.trim();
38
+ if (!trimmed) {
39
+ return null;
40
+ }
41
+ return /^https?:\/\//u.test(trimmed) ? trimmed : `https://${trimmed}`;
42
+ };
@@ -0,0 +1,29 @@
1
+ import { REDIRECTS_FILE } from "./netlify.ts";
2
+ import { distDir } from "./paths.ts";
3
+ import type { DeployPlatform } from "./types.ts";
4
+ import { VERCEL_JSON_FILE } from "./vercel.ts";
5
+
6
+ /**
7
+ * A static build for an unnamed host — the default. Nothing is known about
8
+ * where `dist/` ends up, so the build writes every platform's redirect file
9
+ * (`_redirects` for Netlify and Cloudflare, `vercel.json` for Vercel, plus the
10
+ * manifest for everything else) and the `_headers` file; a host that reads
11
+ * none of them ignores them harmlessly. The site URL is still inferred from
12
+ * whichever platform env the build runs in.
13
+ */
14
+ export const staticPlatform: DeployPlatform = {
15
+ astro: null,
16
+ env: null,
17
+ finalizeBuild: null,
18
+ hiddenRuntime: {
19
+ ignoreDir: null,
20
+ showProjectRoot: false,
21
+ surfacePath: null,
22
+ },
23
+ kind: "static",
24
+ negotiatesMarkdown: false,
25
+ readsHeaderFiles: { server: false, static: true },
26
+ redirectFiles: [REDIRECTS_FILE, VERCEL_JSON_FILE],
27
+ serverOutputDir: distDir,
28
+ serverStaticDir: distDir,
29
+ };
@@ -0,0 +1,112 @@
1
+ import type { JsonValue } from "../../core/adapter.ts";
2
+ import type { BlumeProject } from "../../core/project-graph.ts";
3
+ import type { ResolvedConfig } from "../../core/schema.ts";
4
+ import type { ProjectContext } from "../../core/types.ts";
5
+ import type { DeployAdapterKind } from "../adapters/registry.ts";
6
+ import type { DeployOutput } from "../adapters/types.ts";
7
+
8
+ /**
9
+ * Everything Blume does differently per deployment target, keyed by the
10
+ * descriptor's `kind`. The descriptor a `blume/deploy` factory returns is
11
+ * plain data (it is inlined into the generated project), so the behavior
12
+ * lives here, one module per adapter, and every consumer reads it through
13
+ * `deployPlatform()` instead of switching on an adapter name.
14
+ */
15
+
16
+ /** How the generated `astro.config.mjs` constructs the `@astrojs/*` adapter. */
17
+ export interface AstroAdapterSpec {
18
+ /** Top-level `defineConfig` entries the adapter needs beside itself. */
19
+ config: Record<string, JsonValue>;
20
+ /** Blume's own constructor options; the user's passthrough is spread over them. */
21
+ options: (context: ProjectContext) => Record<string, JsonValue>;
22
+ /** The package the config imports the adapter from. */
23
+ package: string;
24
+ }
25
+
26
+ /** Platform env detection, for inferring `site` and the audit's wording. */
27
+ export interface PlatformEnv {
28
+ /** True when the env says the build is running on this platform. */
29
+ detect: (env: NodeJS.ProcessEnv) => boolean;
30
+ /** The canonical site URL from the platform's env vars, or null. */
31
+ site: (env: NodeJS.ProcessEnv) => string | null;
32
+ }
33
+
34
+ type Redirect = ResolvedConfig["redirects"][number];
35
+
36
+ /** A redirect file a static build writes for the host to read. */
37
+ export interface RedirectFile {
38
+ build: (redirects: Redirect[]) => string;
39
+ name: string;
40
+ }
41
+
42
+ /** The log surface a post-build step reports through (the CLI's logger). */
43
+ export interface BuildLog {
44
+ error: (message: string) => void;
45
+ info: (message: string) => void;
46
+ success: (message: string) => void;
47
+ warn: (message: string) => void;
48
+ }
49
+
50
+ export interface FinalizeBuildOptions {
51
+ /** A `blume build --isolated` verify: check the output, publish nothing. */
52
+ isolated: boolean;
53
+ log: BuildLog;
54
+ project: BlumeProject;
55
+ }
56
+
57
+ /**
58
+ * What exists only because the Astro project lives in the hidden `.blume/`
59
+ * runtime instead of the project root. RFC #114 (integration-first) puts the
60
+ * Astro project at the root, after which this whole group goes: the platform
61
+ * then reads its bundle where the adapter wrote it, and the adapter sees the
62
+ * real root without being told.
63
+ */
64
+ export interface HiddenRuntime {
65
+ /**
66
+ * The top-level directory the adapter's deploy bundle lands in, for
67
+ * `.gitignore`. The platform's own state lives beside the bundle
68
+ * (`.vercel/project.json`, `.netlify/state.json`), so the directory is
69
+ * ignored whole. Null when the bundle lands in `dist/`, already ignored.
70
+ */
71
+ ignoreDir: string | null;
72
+ /**
73
+ * Hand the adapter the project root (`withAdapterRoot`) instead of the
74
+ * runtime: for an adapter that resolves its output tree, or a dependency
75
+ * trace, against `root`, which for Blume is the hidden runtime.
76
+ */
77
+ showProjectRoot: boolean;
78
+ /**
79
+ * A bundle written relative to the Astro root, to move from
80
+ * `<root>/.blume/<path>` up to `<root>/<path>` after the build, where the
81
+ * platform looks for it. Null when nothing needs moving.
82
+ */
83
+ surfacePath: string | null;
84
+ }
85
+
86
+ export interface DeployPlatform {
87
+ /** The `@astrojs/*` adapter a server build uses; null for the static kind. */
88
+ astro: AstroAdapterSpec | null;
89
+ /** Env detection, or null for a target with no platform env (Node, static). */
90
+ env: PlatformEnv | null;
91
+ /**
92
+ * The post-build step for a server build — Vercel's function-bundle audit
93
+ * and negotiation routes, Cloudflare's wrapper Worker. Resolves to false
94
+ * when the build must not ship.
95
+ */
96
+ finalizeBuild: ((options: FinalizeBuildOptions) => Promise<boolean>) | null;
97
+ hiddenRuntime: HiddenRuntime;
98
+ kind: DeployAdapterKind;
99
+ /** Whether a server build honors `Accept: text/markdown` at the content URLs. */
100
+ negotiatesMarkdown: boolean;
101
+ /**
102
+ * Whether the platform applies a `_headers` file to the static assets it
103
+ * serves, per output mode.
104
+ */
105
+ readsHeaderFiles: Record<DeployOutput, boolean>;
106
+ /** The redirect files a static build writes, beside the manifest. */
107
+ redirectFiles: RedirectFile[];
108
+ /** Where a server build's deploy bundle lands. */
109
+ serverOutputDir: (context: ProjectContext) => string;
110
+ /** The directory a server build serves as static files. */
111
+ serverStaticDir: (context: ProjectContext) => string;
112
+ }