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
@@ -6,6 +6,7 @@ import { join } from "pathe";
6
6
 
7
7
  import { loadConfig } from "../../core/config.ts";
8
8
  import { resolveProjectContext } from "../../core/project.ts";
9
+ import { deployOutputDir } from "../../deploy/adapter-output.ts";
9
10
  import { parsePort } from "../args.ts";
10
11
  import { commandMeta } from "../command-meta.ts";
11
12
  import { normalizeHost } from "../host-args.ts";
@@ -22,7 +23,12 @@ export const previewCommand = defineCommand({
22
23
  const { config } = await loadConfig(root);
23
24
  const context = resolveProjectContext(root, config);
24
25
 
25
- if (!existsSync(join(context.outDir, "astro.config.mjs"))) {
26
+ // `blume dev` writes `.blume/astro.config.mjs` too, so the runtime alone
27
+ // doesn't mean there's anything to serve: the build output must exist.
28
+ if (
29
+ !existsSync(join(context.outDir, "astro.config.mjs")) ||
30
+ !existsSync(deployOutputDir(config, context))
31
+ ) {
26
32
  logger.error("No build found. Run `blume build` first.");
27
33
  process.exit(1);
28
34
  }
@@ -28,7 +28,7 @@ import { runTranslate } from "../../translate/run.ts";
28
28
  import { computeWorkList } from "../../translate/work-list.ts";
29
29
  import { commandMeta } from "../command-meta.ts";
30
30
  import { reportInternalError } from "../internal-error.ts";
31
- import { flushStdout, logger } from "../log.ts";
31
+ import { flushStdout, logger, reportDiagnostics } from "../log.ts";
32
32
 
33
33
  /** Wall-clock ceiling per file, in seconds. */
34
34
  const DEFAULT_TIMEOUT_S = DEFAULT_TRANSLATE_TIMEOUT_MS / 1000;
@@ -63,18 +63,18 @@ const parseFlags = (args: TranslateFlags): ParsedTranslateFlags => {
63
63
  (kind) => args[kind]
64
64
  );
65
65
  if (agents.length > 1) {
66
- logger.error("Pass exactly one of --claude or --codex.");
66
+ logger.error("Pass exactly one of --codex or --claude.");
67
67
  process.exit(1);
68
68
  }
69
69
  if (args.check && agents.length > 0) {
70
70
  logger.error(
71
- "--check is read-only and never runs an agent; drop --claude/--codex."
71
+ "--check is read-only and never runs an agent; drop --codex/--claude."
72
72
  );
73
73
  process.exit(1);
74
74
  }
75
75
  if (!args.check && agents.length === 0) {
76
76
  logger.error(
77
- "Pass --claude or --codex to choose the agent CLI that translates."
77
+ "Pass --codex or --claude to choose the agent CLI that translates."
78
78
  );
79
79
  process.exit(1);
80
80
  }
@@ -293,7 +293,7 @@ export const translateCommand = defineCommand({
293
293
  }
294
294
  } catch (error) {
295
295
  if (error instanceof BlumeError) {
296
- logger.error(error.diagnostic.message);
296
+ reportDiagnostics([error.diagnostic], root);
297
297
  process.exit(1);
298
298
  }
299
299
  // SAFETY: an ENOENT from spawning the agent CLI is an ErrnoException;
@@ -0,0 +1,141 @@
1
+ import { defineCommand } from "citty";
2
+ import { join } from "pathe";
3
+
4
+ import { AGENTS, launchInstalledAgent } from "../../audit/agent.ts";
5
+ import type { AgentKind } from "../../audit/agent.ts";
6
+ import { formatDiagnostic } from "../../core/diagnostics.ts";
7
+ import { packageRoot } from "../../core/package-root.ts";
8
+ import { getBlumeVersion } from "../../core/version.ts";
9
+ import {
10
+ UPGRADE_GUIDE_FILE,
11
+ UPGRADE_GUIDE_URL,
12
+ bumpBlumeDependency,
13
+ collectUpgradeFindings,
14
+ isOutsideBlumeProject,
15
+ upgradePrompt,
16
+ } from "../../upgrade/upgrade.ts";
17
+ import { commandMeta } from "../command-meta.ts";
18
+ import { installDependencies } from "../init/install.ts";
19
+ import { commandsFor, detectProjectPackageManager } from "../init/scaffold.ts";
20
+ import { reportInternalError } from "../internal-error.ts";
21
+ import { logger } from "../log.ts";
22
+
23
+ /**
24
+ * `blume upgrade` — move a project to this version of Blume. Run it through the
25
+ * package runner (`npx blume@latest upgrade`), since a project on the previous
26
+ * major doesn't have the command yet: it bumps `blume` in `package.json`,
27
+ * installs, then checks the config, `components.ts`, and each page's front
28
+ * matter against this version and lists what's left, or hands the list to
29
+ * Claude Code or Codex the way
30
+ * `blume audit --claude` does. Status lines go straight to stderr, like the
31
+ * audit's: consola drops info-level lines in test and CI environments.
32
+ */
33
+ export const upgradeCommand = defineCommand({
34
+ args: {
35
+ claude: {
36
+ description: "Hand the remaining changes to Claude Code.",
37
+ type: "boolean",
38
+ },
39
+ codex: {
40
+ description: "Hand the remaining changes to Codex.",
41
+ type: "boolean",
42
+ },
43
+ install: {
44
+ default: true,
45
+ description: "Install dependencies after bumping blume.",
46
+ negativeDescription: "Bump package.json without installing.",
47
+ type: "boolean",
48
+ },
49
+ },
50
+ meta: commandMeta.upgrade,
51
+ async run({ args }) {
52
+ const root = process.cwd();
53
+ // SAFETY: AGENTS is a closed record keyed by AgentKind, so its keys are
54
+ // exactly the agent kinds.
55
+ const agents = (Object.keys(AGENTS) as AgentKind[]).filter(
56
+ (kind) => args[kind]
57
+ );
58
+ if (agents.length > 1) {
59
+ logger.error("Pass at most one of --codex or --claude.");
60
+ process.exit(1);
61
+ }
62
+ const [agent] = agents;
63
+ const version = getBlumeVersion();
64
+
65
+ try {
66
+ const bump = await bumpBlumeDependency(root, version);
67
+ // With neither a config nor a `blume` dependency there is nothing to
68
+ // check: the defaults would always pass and report the folder ready.
69
+ if (isOutsideBlumeProject(root, bump)) {
70
+ logger.error(
71
+ "No blume.config.ts or `blume` dependency here. Run `blume upgrade` from the folder with blume.config.ts — in a monorepo, the package that depends on blume."
72
+ );
73
+ process.exit(1);
74
+ }
75
+ const pm = await detectProjectPackageManager(root);
76
+ // A local install puts no `blume` on PATH, so every command this
77
+ // prints (or hands the agent) runs through the project's runner.
78
+ const runner = commandsFor(pm).exec;
79
+ if (bump.status === "bumped") {
80
+ process.stderr.write(
81
+ ` Bumped blume ${bump.from} → ${bump.to} in package.json.\n`
82
+ );
83
+ if (args.install) {
84
+ const outcome = await installDependencies(root, pm, {
85
+ quiet: false,
86
+ });
87
+ if (outcome.failure) {
88
+ logger.warn(
89
+ `Installing failed; run \`${outcome.command}\` yourself.\n${outcome.failure}`
90
+ );
91
+ }
92
+ }
93
+ } else if (bump.status === "missing") {
94
+ logger.warn(
95
+ `No \`blume\` dependency in ./package.json; add blume@^${version} to the package that uses it.`
96
+ );
97
+ }
98
+
99
+ const findings = await collectUpgradeFindings(root);
100
+ if (findings.length === 0) {
101
+ process.stderr.write(
102
+ ` Ready for Blume ${version}: the config, components.ts, and pages check out. Run \`${runner} blume build\` to confirm.\n`
103
+ );
104
+ return;
105
+ }
106
+ process.stderr.write(
107
+ `\n${findings.map((finding) => formatDiagnostic(finding, root)).join("\n\n")}\n\n`
108
+ );
109
+
110
+ if (!agent) {
111
+ process.stderr.write(
112
+ ` Each change is covered in the upgrade guide: ${UPGRADE_GUIDE_URL}\n Rerun with --codex or --claude to hand them to a coding agent.\n`
113
+ );
114
+ process.exit(1);
115
+ }
116
+
117
+ const cli = AGENTS[agent];
118
+ process.stderr.write(` Handing the upgrade to ${cli.name}…\n\n`);
119
+ const prompt = upgradePrompt({
120
+ findings,
121
+ guidePath: join(packageRoot(), UPGRADE_GUIDE_FILE),
122
+ root,
123
+ runner,
124
+ version,
125
+ });
126
+ const code = await launchInstalledAgent(cli.bin, prompt);
127
+ if (code === null) {
128
+ logger.error(
129
+ `${cli.name} (\`${cli.bin}\`) was not found on PATH. Install it with \`${cli.install}\`.`
130
+ );
131
+ process.exit(1);
132
+ }
133
+ if (code !== 0) {
134
+ process.exit(code);
135
+ }
136
+ } catch (error) {
137
+ reportInternalError(error);
138
+ process.exit(1);
139
+ }
140
+ },
141
+ });
@@ -3,9 +3,58 @@ import { defineCommand } from "citty";
3
3
  import { loadConfig } from "../../core/config.ts";
4
4
  import { BlumeError } from "../../core/diagnostics.ts";
5
5
  import { CutError, cutVersion } from "../../core/version-cut.ts";
6
+ import type { CutResult } from "../../core/version-cut.ts";
6
7
  import { commandMeta } from "../command-meta.ts";
7
8
  import { reportInternalError } from "../internal-error.ts";
8
- import { logger } from "../log.ts";
9
+ import { logger, reportDiagnostics } from "../log.ts";
10
+
11
+ /** `blume version` with no id: list the configured versions. */
12
+ const listVersions = async (root: string): Promise<void> => {
13
+ const { config } = await loadConfig(root);
14
+ if (!config.versions) {
15
+ logger.info(
16
+ "Versioning is not configured. Cut the first version with `blume version <id>` (e.g. `blume version v1.0`)."
17
+ );
18
+ return;
19
+ }
20
+ const { current, archived } = config.versions;
21
+ process.stdout.write(
22
+ ` ${current.label} (current)${current.badge ? ` — ${current.badge}` : ""}\n`
23
+ );
24
+ for (const version of archived) {
25
+ process.stdout.write(` ${version.label ?? version.id} — ${version.id}/\n`);
26
+ }
27
+ };
28
+
29
+ /** Report what a cut did, including how its id reached the config (or didn't). */
30
+ const reportCut = (id: string, result: CutResult): void => {
31
+ logger.success(`Snapshot ${result.dir} (${result.copied} file(s) copied)`);
32
+ const totalRewrites = result.rewritten.reduce(
33
+ (sum, entry) => sum + entry.count,
34
+ 0
35
+ );
36
+ if (totalRewrites > 0) {
37
+ logger.info(
38
+ `Rewrote root-absolute links in ${result.rewritten.length} page(s) (${totalRewrites} line(s)).`
39
+ );
40
+ }
41
+ if (result.versionsAdded) {
42
+ logger.success(
43
+ `Turned on versioning in blume.config.ts with "${id}" archived; the live docs are labeled "Latest" in the switcher until you rename versions.current.label.`
44
+ );
45
+ } else if (result.configUpdated) {
46
+ logger.success(`Added "${id}" to versions.archived in blume.config.ts`);
47
+ } else if (result.configSnippet) {
48
+ // A warning, not info: until it's pasted, the snapshot builds as ordinary
49
+ // content — every page twice — and consola drops info lines under CI.
50
+ logger.warn(
51
+ `blume.config.ts couldn't be updated automatically, so "${id}" isn't registered yet and its pages build as ordinary content until it is. ${result.configSnippet}`
52
+ );
53
+ }
54
+ logger.info(
55
+ "Archived versions are frozen — future edits belong in the live tree. Restart `blume dev` to pick up the snapshot."
56
+ );
57
+ };
9
58
 
10
59
  export const versionCommand = defineCommand({
11
60
  args: {
@@ -22,58 +71,22 @@ export const versionCommand = defineCommand({
22
71
  meta: commandMeta.version,
23
72
  async run({ args }) {
24
73
  const root = process.cwd();
25
-
26
- if (!args.id) {
27
- const { config } = await loadConfig(root);
28
- if (!config.versions) {
29
- logger.info(
30
- "Versioning is not configured. Cut the first version with `blume version <id>` (e.g. `blume version v1.0`)."
31
- );
32
- return;
33
- }
34
- const { current, archived } = config.versions;
35
- process.stdout.write(
36
- ` ${current.label} (current)${current.badge ? ` — ${current.badge}` : ""}\n`
37
- );
38
- for (const version of archived) {
39
- process.stdout.write(
40
- ` ${version.label ?? version.id} — ${version.id}/\n`
41
- );
42
- }
43
- return;
44
- }
45
-
46
74
  try {
47
- const result = await cutVersion(root, args.id, { force: args.force });
48
- logger.success(
49
- `Snapshot ${result.dir} (${result.copied} file(s) copied)`
50
- );
51
- const totalRewrites = result.rewritten.reduce(
52
- (sum, entry) => sum + entry.count,
53
- 0
54
- );
55
- if (totalRewrites > 0) {
56
- logger.info(
57
- `Rewrote root-absolute links in ${result.rewritten.length} page(s) (${totalRewrites} line(s)).`
58
- );
59
- }
60
- if (result.configUpdated) {
61
- logger.success(
62
- `Added "${args.id}" to versions.archived in blume.config.ts`
75
+ if (args.id) {
76
+ reportCut(
77
+ args.id,
78
+ await cutVersion(root, args.id, { force: args.force })
63
79
  );
64
- } else if (result.configSnippet) {
65
- logger.info(result.configSnippet);
80
+ } else {
81
+ await listVersions(root);
66
82
  }
67
- logger.info(
68
- "Archived versions are frozen — future edits belong in the live tree. Restart `blume dev` to pick up the snapshot."
69
- );
70
83
  } catch (error) {
71
84
  if (error instanceof CutError) {
72
85
  logger.error(error.message);
73
86
  process.exit(1);
74
87
  }
75
88
  if (error instanceof BlumeError) {
76
- logger.error(error.diagnostic.message);
89
+ reportDiagnostics([error.diagnostic], root);
77
90
  process.exit(1);
78
91
  }
79
92
  reportInternalError(error);
@@ -1,7 +1,13 @@
1
+ import { existsSync, readFileSync } from "node:fs";
1
2
  import { readFile, writeFile } from "node:fs/promises";
2
3
 
3
4
  import { join } from "pathe";
4
5
 
6
+ import { EJECTED_CONFIG_HEADER } from "../astro/templates.ts";
7
+ import { packageRoot } from "../core/package-root.ts";
8
+ import { commandsFor, detectProjectPackageManager } from "./init/scaffold.ts";
9
+ import { logger } from "./log.ts";
10
+
5
11
  /** A JSON value, as `JSON.parse` of a manifest can return. */
6
12
  type JsonValue =
7
13
  | string
@@ -14,22 +20,72 @@ type JsonValue =
14
20
  /** The slice of package.json the rewrite touches; the rest rides along. */
15
21
  interface PackageManifest {
16
22
  [key: string]: JsonValue | undefined;
23
+ dependencies?: Record<string, string>;
24
+ devDependencies?: Record<string, string>;
25
+ optionalDependencies?: Record<string, string>;
26
+ peerDependencies?: Record<string, string>;
17
27
  scripts?: Record<string, string>;
18
28
  }
19
29
 
30
+ /** Package name → the semver range to depend on it at. */
31
+ export interface DependencyRanges {
32
+ [name: string]: string;
33
+ }
34
+
20
35
  /**
21
- * Rewrite the project's package.json scripts to run Astro directly. After an
22
- * eject the Blume CLI no longer manages the runtime, so scaffolded scripts like
23
- * `"dev": "blume dev"` would rebuild the removed `.blume` tree instead of
24
- * serving the ejected app. A missing or unreadable package.json is left alone.
36
+ * The version range Blume itself uses for each package it depends on or
37
+ * accepts as a peer, plus `blume` at the installed version — what an ejected
38
+ * app should pin so it keeps building against the same majors.
25
39
  */
26
- export const updatePackageScripts = async (root: string): Promise<void> => {
40
+ export const blumeDependencyRanges = (): DependencyRanges => {
41
+ // SAFETY: blume's own package.json, which declares its version and both
42
+ // dependency maps; nothing else is read.
43
+ const manifest = JSON.parse(
44
+ readFileSync(join(packageRoot(), "package.json"), "utf-8")
45
+ ) as {
46
+ dependencies: Record<string, string>;
47
+ peerDependencies: Record<string, string>;
48
+ version: string;
49
+ };
50
+ return {
51
+ ...manifest.peerDependencies,
52
+ ...manifest.dependencies,
53
+ blume: `^${manifest.version}`,
54
+ };
55
+ };
56
+
57
+ /** Whether the manifest already lists `name` in any dependency field. */
58
+ const declares = (pkg: PackageManifest, name: string): boolean =>
59
+ [
60
+ pkg.dependencies,
61
+ pkg.devDependencies,
62
+ pkg.optionalDependencies,
63
+ pkg.peerDependencies,
64
+ ].some((field) => field !== undefined && Object.hasOwn(field, name));
65
+
66
+ /**
67
+ * Point the project's package.json at the ejected app. Its scripts run Astro
68
+ * directly: after an eject the Blume CLI no longer manages the runtime, so
69
+ * scaffolded scripts like `"dev": "blume dev"` would rebuild the removed
70
+ * `.blume` tree instead of serving the ejected app. And every package the
71
+ * ejected app imports by bare name (`dependencies`, from `eject()`) that the
72
+ * project doesn't list yet becomes a dependency at the range Blume itself
73
+ * uses (`ranges`).
74
+ *
75
+ * Returns the names it added, so the caller can ask for an install. A missing
76
+ * or unreadable package.json is left alone.
77
+ */
78
+ export const updatePackageScripts = async (
79
+ root: string,
80
+ dependencies: string[] = [],
81
+ ranges: DependencyRanges = blumeDependencyRanges()
82
+ ): Promise<string[]> => {
27
83
  const pkgPath = join(root, "package.json");
28
84
  let pkg: PackageManifest;
29
85
  try {
30
86
  pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
31
87
  } catch {
32
- return;
88
+ return [];
33
89
  }
34
90
  const scripts = pkg.scripts ?? {};
35
91
  pkg.scripts = {
@@ -38,5 +94,64 @@ export const updatePackageScripts = async (root: string): Promise<void> => {
38
94
  dev: "astro dev",
39
95
  preview: "astro preview",
40
96
  };
97
+ const added = dependencies.filter((name) => !declares(pkg, name));
98
+ if (added.length > 0) {
99
+ // Sorted, the way package managers write the field.
100
+ pkg.dependencies = Object.fromEntries(
101
+ Object.entries({
102
+ ...pkg.dependencies,
103
+ ...Object.fromEntries(added.map((name) => [name, ranges[name] ?? "*"])),
104
+ }).toSorted(([a], [b]) => (a < b ? -1 : 1))
105
+ );
106
+ }
41
107
  await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`, "utf-8");
108
+ return added;
109
+ };
110
+
111
+ /**
112
+ * The first line Blume 1's `blume eject` wrote into the ejected
113
+ * `astro.config.mjs` — the hidden runtime's own header, carried over. Blume 2's
114
+ * hidden runtime keeps it under `.blume/`, never at the project root, so a root
115
+ * config that opens with it is an app Blume 1 ejected.
116
+ */
117
+ const BLUME_1_EJECTED_CONFIG_HEADER =
118
+ "// Generated by Blume. Do not edit; this file is recreated on each run.";
119
+
120
+ /**
121
+ * Whether `root` holds an app `blume eject` already wrote: a root
122
+ * `astro.config.mjs` whose first line is eject's header, or the header Blume 1
123
+ * ejected with. The header is the only signal: a Blume project may keep its own
124
+ * `astro.config.mjs` and a codegen `src/generated/` folder beside its content,
125
+ * and neither makes it an ejected app.
126
+ */
127
+ export const isEjectedProject = (root: string): boolean => {
128
+ const config = join(root, "astro.config.mjs");
129
+ if (!existsSync(config)) {
130
+ return false;
131
+ }
132
+ const source = readFileSync(config, "utf-8");
133
+ return (
134
+ source.startsWith(EJECTED_CONFIG_HEADER) ||
135
+ source.startsWith(BLUME_1_EJECTED_CONFIG_HEADER)
136
+ );
137
+ };
138
+
139
+ /**
140
+ * Stop `blume dev`/`blume build` in an ejected app. Either would regenerate
141
+ * `.blume/` from `blume.config.ts` and run that hidden copy, ignoring every
142
+ * edit made to the app since eject, so point at the app's own script under
143
+ * the project's package manager instead.
144
+ */
145
+ export const refuseIfEjected = async (
146
+ root: string,
147
+ script: "build" | "dev"
148
+ ): Promise<void> => {
149
+ if (!isEjectedProject(root)) {
150
+ return;
151
+ }
152
+ const commands = commandsFor(await detectProjectPackageManager(root));
153
+ logger.error(
154
+ `This project was ejected to a standalone Astro app, so \`blume ${script}\` would run a regenerated copy of the site instead of it. Run \`${commands[script]}\` instead.`
155
+ );
156
+ process.exit(1);
42
157
  };
package/src/cli/index.ts CHANGED
@@ -16,7 +16,7 @@ import "./log.ts";
16
16
 
17
17
  const main = defineCommand({
18
18
  meta: {
19
- description: "Markdown-first documentation powered by Astro and Vite.",
19
+ description: "The open-source docs framework for humans and agents.",
20
20
  name: "blume",
21
21
  version: getBlumeVersion(),
22
22
  },
@@ -71,6 +71,11 @@ const main = defineCommand({
71
71
  () => import("./commands/mcp-stdio.ts"),
72
72
  "mcpStdioCommand"
73
73
  ),
74
+ migrate: lazyCommand(
75
+ commandMeta.migrate,
76
+ () => import("./commands/migrate.ts"),
77
+ "migrateCommand"
78
+ ),
74
79
  preview: lazyCommand(
75
80
  commandMeta.preview,
76
81
  () => import("./commands/preview.ts"),
@@ -86,6 +91,11 @@ const main = defineCommand({
86
91
  () => import("./commands/translate.ts"),
87
92
  "translateCommand"
88
93
  ),
94
+ upgrade: lazyCommand(
95
+ commandMeta.upgrade,
96
+ () => import("./commands/upgrade.ts"),
97
+ "upgradeCommand"
98
+ ),
89
99
  validate: lazyCommand(
90
100
  commandMeta.validate,
91
101
  () => import("./commands/validate.ts"),
@@ -0,0 +1,70 @@
1
+ import { spawn } from "node:child_process";
2
+ import { once } from "node:events";
3
+
4
+ import { commandsFor } from "./scaffold.ts";
5
+ import type { PackageManager } from "./scaffold.ts";
6
+
7
+ /** How `installDependencies` ended, plus the command to print on failure. */
8
+ export interface InstallOutcome {
9
+ /** The install command that ran (`bun install`, `npm install`, …). */
10
+ command: string;
11
+ /**
12
+ * Why the install failed: the package manager's exit code with whatever it
13
+ * printed, or the spawn error when the binary isn't on PATH. Absent on
14
+ * success.
15
+ */
16
+ failure?: string;
17
+ }
18
+
19
+ export interface InstallOptions {
20
+ /**
21
+ * Capture the package manager's output instead of streaming it to the
22
+ * terminal. Interactive runs capture it behind a spinner and show it only
23
+ * on failure; non-interactive runs stream it as-is.
24
+ */
25
+ quiet: boolean;
26
+ }
27
+
28
+ /**
29
+ * Run the package manager's install in a freshly scaffolded project so
30
+ * `blume dev` works as soon as `init` returns. Never throws: a missing binary
31
+ * or a non-zero exit resolves with a `failure`, so the caller can keep the
32
+ * scaffolded files and print the exact command to retry by hand.
33
+ */
34
+ export const installDependencies = async (
35
+ root: string,
36
+ pm: PackageManager,
37
+ { quiet }: InstallOptions
38
+ ): Promise<InstallOutcome> => {
39
+ const command = commandsFor(pm).install;
40
+ const child = spawn(pm, ["install"], {
41
+ cwd: root,
42
+ env: process.env,
43
+ // npm, pnpm and yarn are `.cmd` shims on Windows, which Node only runs
44
+ // through a shell; bun is a real executable everywhere.
45
+ shell: process.platform === "win32",
46
+ stdio: quiet ? ["ignore", "pipe", "pipe"] : "inherit",
47
+ });
48
+ const chunks: Buffer[] = [];
49
+ child.stdout?.on("data", (chunk: Buffer) => chunks.push(chunk));
50
+ child.stderr?.on("data", (chunk: Buffer) => chunks.push(chunk));
51
+ try {
52
+ // `once` rejects when the child emits `error` (e.g. ENOENT) before `close`.
53
+ // SAFETY: `close` is emitted with `(code, signal)`, so the first element
54
+ // is the exit code, or null when a signal ended the process.
55
+ const [code] = (await once(child, "close")) as [number | null];
56
+ if (code === 0) {
57
+ return { command };
58
+ }
59
+ const output = Buffer.concat(chunks).toString("utf-8").trim();
60
+ return {
61
+ command,
62
+ failure: [`${command} exited with code ${code}`, output]
63
+ .filter(Boolean)
64
+ .join("\n"),
65
+ };
66
+ } catch (error) {
67
+ // SAFETY: a spawn failure is an ErrnoException; only its message is shown.
68
+ return { command, failure: (error as Error).message };
69
+ }
70
+ };
@@ -119,6 +119,13 @@ export const collectAnswers = async (
119
119
  },
120
120
  { hint: "A Notion database", label: "notion", value: "notion" },
121
121
  { hint: "A Sanity dataset", label: "sanity", value: "sanity" },
122
+ {
123
+ hint: "A Contentful content type",
124
+ label: "contentful",
125
+ value: "contentful",
126
+ },
127
+ { hint: "A Payload collection", label: "payload", value: "payload" },
128
+ { hint: "A Strapi content type", label: "strapi", value: "strapi" },
122
129
  {
123
130
  hint: "MDX fetched from a GitHub repo",
124
131
  label: "mdx-remote",