blume 1.7.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (677) hide show
  1. package/AGENTS.md +19 -0
  2. package/CHANGELOG.md +227 -0
  3. package/README.md +34 -21
  4. package/dist/cli/chunk-11j0384y.js +148 -0
  5. package/dist/cli/chunk-11j0384y.js.map +10 -0
  6. package/dist/cli/{chunk-xhtpx3ff.js → chunk-1w8dp3qb.js} +17 -16
  7. package/dist/cli/{chunk-xhtpx3ff.js.map → chunk-1w8dp3qb.js.map} +3 -3
  8. package/dist/cli/chunk-2q1dwty4.js +75 -0
  9. package/dist/cli/chunk-2q1dwty4.js.map +11 -0
  10. package/dist/cli/chunk-41za066z.js +122 -0
  11. package/dist/cli/chunk-41za066z.js.map +11 -0
  12. package/dist/cli/chunk-5a2z0198.js +133 -0
  13. package/dist/cli/chunk-5a2z0198.js.map +10 -0
  14. package/dist/cli/{chunk-9he6crym.js → chunk-6k8vp3ta.js} +25 -13
  15. package/dist/cli/{chunk-9he6crym.js.map → chunk-6k8vp3ta.js.map} +4 -4
  16. package/dist/cli/{chunk-mt76t7dj.js → chunk-79njf86q.js} +133 -54
  17. package/dist/cli/chunk-79njf86q.js.map +11 -0
  18. package/dist/cli/{chunk-3w7b2vcx.js → chunk-7ez8ny0t.js} +2 -2
  19. package/dist/cli/{chunk-688e0dde.js → chunk-88cpgt6h.js} +1 -1
  20. package/dist/cli/chunk-a9kptbw5.js +361 -0
  21. package/dist/cli/chunk-a9kptbw5.js.map +14 -0
  22. package/dist/cli/chunk-abh8yjkn.js +31 -0
  23. package/dist/cli/chunk-abh8yjkn.js.map +10 -0
  24. package/dist/cli/chunk-b5aj94ah.js +91 -0
  25. package/dist/cli/chunk-b5aj94ah.js.map +10 -0
  26. package/dist/cli/{chunk-hs3gbh8p.js → chunk-bctazmbk.js} +9 -5
  27. package/dist/cli/chunk-bctazmbk.js.map +10 -0
  28. package/dist/cli/chunk-beat36xx.js +279 -0
  29. package/dist/cli/chunk-beat36xx.js.map +10 -0
  30. package/dist/cli/chunk-bnbmcwfb.js +145 -0
  31. package/dist/cli/chunk-bnbmcwfb.js.map +11 -0
  32. package/dist/cli/{chunk-9bkjd11x.js → chunk-bw22s759.js} +15 -5
  33. package/dist/cli/{chunk-9bkjd11x.js.map → chunk-bw22s759.js.map} +4 -4
  34. package/dist/cli/chunk-by2290sx.js +39 -0
  35. package/dist/cli/chunk-by2290sx.js.map +10 -0
  36. package/dist/cli/chunk-d1tadaw7.js +79 -0
  37. package/dist/cli/chunk-d1tadaw7.js.map +10 -0
  38. package/dist/cli/{chunk-t3tj0dgr.js → chunk-d80hr03s.js} +24 -19
  39. package/dist/cli/chunk-d80hr03s.js.map +15 -0
  40. package/dist/cli/chunk-ernrthtr.js +97 -0
  41. package/dist/cli/chunk-ernrthtr.js.map +10 -0
  42. package/dist/cli/chunk-f2972sbt.js +374 -0
  43. package/dist/cli/chunk-f2972sbt.js.map +10 -0
  44. package/dist/cli/{chunk-exeeb35e.js → chunk-f7t03s3g.js} +2 -2
  45. package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
  46. package/dist/cli/chunk-fa25z98p.js.map +11 -0
  47. package/dist/cli/{chunk-12dxjqk7.js → chunk-fh5hj5jt.js} +44 -21
  48. package/dist/cli/chunk-fh5hj5jt.js.map +10 -0
  49. package/dist/cli/{chunk-8cd8tj54.js → chunk-j8mw0za6.js} +86 -57
  50. package/dist/cli/chunk-j8mw0za6.js.map +35 -0
  51. package/dist/cli/chunk-jts8mvcz.js +106 -0
  52. package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
  53. package/dist/cli/{chunk-ejjx8znq.js → chunk-mnqj32sj.js} +505 -536
  54. package/dist/cli/chunk-mnqj32sj.js.map +12 -0
  55. package/dist/cli/{chunk-196vjxp9.js → chunk-mwt1k8n7.js} +100 -372
  56. package/dist/cli/chunk-mwt1k8n7.js.map +10 -0
  57. package/dist/cli/chunk-nk3ts2xk.js +51 -0
  58. package/dist/cli/chunk-nk3ts2xk.js.map +10 -0
  59. package/dist/cli/{chunk-n9sra6sy.js → chunk-pat2zzwc.js} +10 -14
  60. package/dist/cli/{chunk-n9sra6sy.js.map → chunk-pat2zzwc.js.map} +2 -2
  61. package/dist/cli/chunk-pnnvybbk.js +176 -0
  62. package/dist/cli/chunk-pnnvybbk.js.map +11 -0
  63. package/dist/cli/{chunk-cvky9gb2.js → chunk-sqn5t4q0.js} +81 -87
  64. package/dist/cli/chunk-sqn5t4q0.js.map +10 -0
  65. package/dist/cli/{chunk-eevwt1sc.js → chunk-tzne8qfq.js} +15 -15
  66. package/dist/cli/{chunk-eevwt1sc.js.map → chunk-tzne8qfq.js.map} +1 -1
  67. package/dist/cli/chunk-xaz13gwg.js +12449 -0
  68. package/dist/cli/chunk-xaz13gwg.js.map +182 -0
  69. package/dist/cli/chunk-y3e45rc8.js +102 -0
  70. package/dist/cli/chunk-y3e45rc8.js.map +10 -0
  71. package/dist/cli/chunk-z01ze5c1.js +261 -0
  72. package/dist/cli/chunk-z01ze5c1.js.map +10 -0
  73. package/dist/cli/{chunk-5n7t497w.js → chunk-z1f5arsg.js} +247 -755
  74. package/dist/cli/chunk-z1f5arsg.js.map +36 -0
  75. package/dist/cli/{chunk-hdm2dkd2.js → chunk-zg2gtj10.js} +1086 -2596
  76. package/dist/cli/chunk-zg2gtj10.js.map +35 -0
  77. package/dist/cli/{chunk-ppfvdcd4.js → chunk-zxccj738.js} +1 -1
  78. package/dist/cli/index.js +214 -57
  79. package/dist/cli/index.js.map +8 -7
  80. package/dist/types/ai/agent-readability.d.ts +52 -0
  81. package/dist/types/ai/ai-catalog.d.ts +42 -0
  82. package/dist/types/ai/api/paths.d.ts +17 -0
  83. package/dist/types/ai/api-catalog.d.ts +18 -0
  84. package/dist/types/ai/ask.d.ts +368 -0
  85. package/dist/types/ai/changelog-markdown.d.ts +2 -0
  86. package/dist/types/ai/component-markdown.d.ts +2 -2
  87. package/dist/types/ai/index.d.ts +24 -0
  88. package/dist/types/ai/link-headers.d.ts +24 -0
  89. package/dist/types/ai/llms.d.ts +25 -0
  90. package/dist/types/ai/markdown.d.ts +45 -0
  91. package/dist/types/ai/mcp/discovery.d.ts +68 -0
  92. package/dist/types/ai/mcp/tools.d.ts +16 -0
  93. package/dist/types/ai/openapi-components.d.ts +43 -0
  94. package/dist/types/ai/relative-links.d.ts +26 -0
  95. package/dist/types/ai/serializers.d.ts +15 -0
  96. package/dist/types/ai/skills.d.ts +42 -0
  97. package/dist/types/ai/tar.d.ts +25 -0
  98. package/dist/types/ai/visibility.d.ts +17 -0
  99. package/dist/types/ai/web-bot-auth.d.ts +16 -0
  100. package/dist/types/analytics/adobe.d.ts +35 -0
  101. package/dist/types/analytics/amplitude.d.ts +50 -0
  102. package/dist/types/analytics/clarity.d.ts +31 -0
  103. package/dist/types/analytics/clearbit.d.ts +29 -0
  104. package/dist/types/analytics/cloudflare.d.ts +41 -0
  105. package/dist/types/analytics/fathom.d.ts +41 -0
  106. package/dist/types/analytics/google-analytics.d.ts +44 -0
  107. package/dist/types/analytics/google-tag-manager.d.ts +40 -0
  108. package/dist/types/analytics/head.d.ts +30 -0
  109. package/dist/types/analytics/heap.d.ts +40 -0
  110. package/dist/types/analytics/hightouch.d.ts +44 -0
  111. package/dist/types/analytics/hotjar.d.ts +33 -0
  112. package/dist/types/analytics/index.d.ts +61 -0
  113. package/dist/types/analytics/inline.d.ts +17 -0
  114. package/dist/types/analytics/logrocket.d.ts +44 -0
  115. package/dist/types/analytics/mixpanel.d.ts +67 -0
  116. package/dist/types/analytics/pirsch.d.ts +42 -0
  117. package/dist/types/analytics/plausible.d.ts +56 -0
  118. package/dist/types/analytics/posthog.d.ts +45 -0
  119. package/dist/types/analytics/schema.d.ts +320 -0
  120. package/dist/types/analytics/script.d.ts +46 -0
  121. package/dist/types/analytics/segment.d.ts +50 -0
  122. package/dist/types/analytics/vercel.d.ts +48 -0
  123. package/dist/types/astro/integration.d.ts +76 -0
  124. package/dist/types/astro/markdown-negotiation.d.ts +23 -0
  125. package/dist/types/astro/module-types.d.ts +14 -0
  126. package/dist/types/astro/pages.d.ts +44 -0
  127. package/dist/types/cli/env.d.ts +12 -0
  128. package/dist/types/cli/init/scaffold.d.ts +154 -0
  129. package/dist/types/components/layout/nav-utils.d.ts +11 -0
  130. package/dist/types/core/adapter.d.ts +47 -0
  131. package/dist/types/core/api-name.d.ts +7 -0
  132. package/dist/types/core/changelog-index.d.ts +13 -0
  133. package/dist/types/core/config-input.d.ts +209 -505
  134. package/dist/types/core/config.d.ts +60 -34
  135. package/dist/types/core/content-assets.d.ts +76 -0
  136. package/dist/types/core/custom-pages.d.ts +33 -0
  137. package/dist/types/core/data.d.ts +28 -11
  138. package/dist/types/core/define-components.d.ts +12 -9
  139. package/dist/types/core/deployment-env.d.ts +6 -11
  140. package/dist/types/core/frontmatter.d.ts +10 -0
  141. package/dist/types/core/graph.d.ts +18 -0
  142. package/dist/types/core/heading-markers.d.ts +54 -0
  143. package/dist/types/core/i18n-ui.d.ts +6 -2
  144. package/dist/types/core/i18n.d.ts +87 -0
  145. package/dist/types/core/includes.d.ts +138 -0
  146. package/dist/types/core/last-modified.d.ts +47 -0
  147. package/dist/types/core/links.d.ts +95 -0
  148. package/dist/types/core/locale-links.d.ts +60 -0
  149. package/dist/types/core/manifest.d.ts +17 -0
  150. package/dist/types/core/meta.d.ts +38 -0
  151. package/dist/types/core/nav-diagnostics.d.ts +26 -0
  152. package/dist/types/core/navigation.d.ts +6 -0
  153. package/dist/types/core/node-require.d.ts +19 -0
  154. package/dist/types/core/package-json.d.ts +13 -0
  155. package/dist/types/core/probe.d.ts +42 -0
  156. package/dist/types/core/project-graph.d.ts +51 -0
  157. package/dist/types/core/project.d.ts +2 -0
  158. package/dist/types/core/safe-href.d.ts +2 -0
  159. package/dist/types/core/safe-links.d.ts +26 -0
  160. package/dist/types/core/schema.d.ts +2291 -441
  161. package/dist/types/core/site-url.d.ts +16 -0
  162. package/dist/types/core/sources/assets.d.ts +36 -0
  163. package/dist/types/core/sources/cache.d.ts +37 -0
  164. package/dist/types/core/sources/collection.d.ts +28 -0
  165. package/dist/types/core/sources/contentful-rich-text.d.ts +31 -0
  166. package/dist/types/core/sources/contentful.d.ts +40 -0
  167. package/dist/types/core/sources/filesystem.d.ts +24 -0
  168. package/dist/types/core/sources/github-releases.d.ts +31 -0
  169. package/dist/types/core/sources/json.d.ts +30 -0
  170. package/dist/types/core/sources/lexical.d.ts +19 -0
  171. package/dist/types/core/sources/lower.d.ts +75 -0
  172. package/dist/types/core/sources/mdx-remote.d.ts +28 -0
  173. package/dist/types/core/sources/normalize.d.ts +147 -0
  174. package/dist/types/core/sources/notion.d.ts +131 -0
  175. package/dist/types/core/sources/obsidian.d.ts +46 -0
  176. package/dist/types/core/sources/payload.d.ts +39 -0
  177. package/dist/types/core/sources/portable-text.d.ts +42 -0
  178. package/dist/types/core/sources/read.d.ts +23 -0
  179. package/dist/types/core/sources/remote.d.ts +74 -0
  180. package/dist/types/core/sources/resolve.d.ts +19 -0
  181. package/dist/types/core/sources/sanity.d.ts +43 -0
  182. package/dist/types/core/sources/strapi-blocks.d.ts +12 -0
  183. package/dist/types/core/sources/strapi.d.ts +33 -0
  184. package/dist/types/core/sources/types.d.ts +7 -0
  185. package/dist/types/core/sources/watch.d.ts +45 -0
  186. package/dist/types/core/text-width.d.ts +11 -0
  187. package/dist/types/core/types.d.ts +20 -1
  188. package/dist/types/core/unrecognized-keys.d.ts +7 -0
  189. package/dist/types/core/versions.d.ts +72 -0
  190. package/dist/types/core/yaml.d.ts +9 -0
  191. package/dist/types/deploy/adapter-output.d.ts +45 -0
  192. package/dist/types/deploy/adapters/cloudflare.d.ts +40 -0
  193. package/dist/types/deploy/adapters/index.d.ts +29 -0
  194. package/dist/types/deploy/adapters/netlify.d.ts +37 -0
  195. package/dist/types/deploy/adapters/node.d.ts +37 -0
  196. package/dist/types/deploy/adapters/registry.d.ts +133 -0
  197. package/dist/types/deploy/adapters/types.d.ts +71 -0
  198. package/dist/types/deploy/adapters/vercel.d.ts +38 -0
  199. package/dist/types/deploy/artifacts.d.ts +65 -0
  200. package/dist/types/deploy/cloudflare-negotiation.d.ts +196 -0
  201. package/dist/types/deploy/function-bundle.d.ts +80 -0
  202. package/dist/types/deploy/headers.d.ts +50 -0
  203. package/dist/types/deploy/node-headers.d.ts +42 -0
  204. package/dist/types/deploy/platforms/cloudflare.d.ts +40 -0
  205. package/dist/types/deploy/platforms/index.d.ts +18 -0
  206. package/dist/types/deploy/platforms/netlify.d.ts +13 -0
  207. package/dist/types/deploy/platforms/node.d.ts +11 -0
  208. package/dist/types/deploy/platforms/paths.d.ts +27 -0
  209. package/dist/types/deploy/platforms/static.d.ts +10 -0
  210. package/dist/types/deploy/platforms/types.d.ts +104 -0
  211. package/dist/types/deploy/platforms/vercel.d.ts +32 -0
  212. package/dist/types/deploy/redirects.d.ts +53 -0
  213. package/dist/types/deploy/robots.d.ts +8 -0
  214. package/dist/types/deploy/rss.d.ts +31 -0
  215. package/dist/types/deploy/sitemap.d.ts +21 -0
  216. package/dist/types/deploy/vercel-negotiation.d.ts +109 -0
  217. package/dist/types/markdown/code-title.d.ts +32 -0
  218. package/dist/types/markdown/fence-meta.d.ts +23 -0
  219. package/dist/types/markdown/themes.d.ts +3 -3
  220. package/dist/types/openapi/asyncapi.d.ts +129 -0
  221. package/dist/types/openapi/graphql-build.d.ts +8 -0
  222. package/dist/types/openapi/graphql.d.ts +122 -0
  223. package/dist/types/openapi/model.d.ts +158 -0
  224. package/dist/types/openapi/parse.d.ts +57 -0
  225. package/dist/types/openapi/references.d.ts +37 -25
  226. package/dist/types/openapi/render-mdx.d.ts +33 -0
  227. package/dist/types/openapi/sentence.d.ts +7 -0
  228. package/dist/types/openapi/signature.d.ts +10 -0
  229. package/dist/types/openapi/source.d.ts +22 -0
  230. package/dist/types/openapi/spec-dependency-error.d.ts +10 -0
  231. package/dist/types/reference/asyncapi.d.ts +166 -0
  232. package/dist/types/reference/graphql.d.ts +181 -0
  233. package/dist/types/reference/index.d.ts +32 -0
  234. package/dist/types/reference/openapi.d.ts +165 -0
  235. package/dist/types/reference/options.d.ts +157 -0
  236. package/dist/types/reference/scalar.d.ts +136 -0
  237. package/dist/types/reference/schema.d.ts +630 -0
  238. package/dist/types/search/adapters/algolia.d.ts +32 -0
  239. package/dist/types/search/adapters/flexsearch.d.ts +12 -0
  240. package/dist/types/search/adapters/index.d.ts +31 -0
  241. package/dist/types/search/adapters/mixedbread.d.ts +22 -0
  242. package/dist/types/search/adapters/orama-cloud.d.ts +33 -0
  243. package/dist/types/search/adapters/orama.d.ts +13 -0
  244. package/dist/types/search/adapters/pagefind.d.ts +12 -0
  245. package/dist/types/search/adapters/registry.d.ts +228 -0
  246. package/dist/types/search/adapters/types.d.ts +34 -0
  247. package/dist/types/search/adapters/typesense.d.ts +42 -0
  248. package/dist/types/search/build.d.ts +23 -0
  249. package/dist/types/search/documents.d.ts +90 -0
  250. package/dist/types/search/facets.d.ts +3 -0
  251. package/dist/types/search/sync/algolia.d.ts +14 -0
  252. package/dist/types/search/sync/index.d.ts +14 -0
  253. package/dist/types/search/sync/orama-cloud.d.ts +10 -0
  254. package/dist/types/search/sync/typesense.d.ts +14 -0
  255. package/dist/types/sources/contentful.d.ts +68 -0
  256. package/dist/types/sources/custom.d.ts +20 -0
  257. package/dist/types/sources/filesystem.d.ts +42 -0
  258. package/dist/types/sources/github-releases.d.ts +46 -0
  259. package/dist/types/sources/index.d.ts +48 -0
  260. package/dist/types/sources/mdx-remote.d.ts +63 -0
  261. package/dist/types/sources/notion.d.ts +65 -0
  262. package/dist/types/sources/obsidian.d.ts +34 -0
  263. package/dist/types/sources/payload.d.ts +68 -0
  264. package/dist/types/sources/registry.d.ts +1414 -0
  265. package/dist/types/sources/sanity.d.ts +69 -0
  266. package/dist/types/sources/shared.d.ts +46 -0
  267. package/dist/types/sources/strapi.d.ts +66 -0
  268. package/dist/types/theme/icon-kind.d.ts +11 -0
  269. package/dist/types/theme/icons.d.ts +20 -0
  270. package/docs/01-quickstart.mdx +18 -18
  271. package/docs/02-deployment.mdx +50 -26
  272. package/docs/03-upgrading.mdx +351 -0
  273. package/docs/04-migrating.mdx +58 -0
  274. package/docs/08-faq.mdx +3 -3
  275. package/docs/advanced/blog.mdx +13 -6
  276. package/docs/advanced/changelog.mdx +23 -35
  277. package/docs/advanced/custom-pages.mdx +20 -8
  278. package/docs/advanced/meta.ts +1 -8
  279. package/docs/advanced/skills.mdx +8 -0
  280. package/docs/cli/audit.mdx +646 -0
  281. package/docs/cli/doctor.mdx +29 -0
  282. package/docs/{reference/eval.mdx → cli/evals.mdx} +9 -8
  283. package/docs/cli/index.mdx +105 -0
  284. package/docs/cli/meta.ts +7 -0
  285. package/docs/{reference → cli}/translate.mdx +1 -1
  286. package/docs/cli/validate.mdx +41 -0
  287. package/docs/cli/version.mdx +40 -0
  288. package/docs/configuration/analytics.mdx +350 -59
  289. package/docs/configuration/ask-ai.mdx +176 -61
  290. package/docs/configuration/customization.mdx +15 -9
  291. package/docs/configuration/index.mdx +52 -31
  292. package/docs/configuration/search.mdx +75 -54
  293. package/docs/configuration/theming.mdx +24 -15
  294. package/docs/content/components.mdx +21 -5
  295. package/docs/{reference → content}/frontmatter.mdx +37 -1
  296. package/docs/content/i18n.mdx +8 -6
  297. package/docs/content/includes.mdx +2 -4
  298. package/docs/content/index.mdx +1 -1
  299. package/docs/content/islands.mdx +10 -5
  300. package/docs/content/meta.mdx +1 -1
  301. package/docs/content/meta.ts +1 -0
  302. package/docs/content/navigation.mdx +12 -7
  303. package/docs/content/sources.mdx +145 -50
  304. package/docs/content/syntax.mdx +26 -12
  305. package/docs/content/versioning.mdx +3 -3
  306. package/docs/discoverability/agent-discovery.mdx +91 -10
  307. package/docs/discoverability/index.mdx +5 -5
  308. package/docs/discoverability/json-api.mdx +4 -4
  309. package/docs/discoverability/llms-txt.mdx +6 -6
  310. package/docs/discoverability/markdown.mdx +4 -4
  311. package/docs/discoverability/mcp.mdx +11 -11
  312. package/docs/discoverability/sitemap-and-robots.mdx +3 -3
  313. package/docs/index.mdx +2 -2
  314. package/docs/references/asyncapi.mdx +59 -0
  315. package/docs/{advanced → references}/graphql.mdx +45 -32
  316. package/docs/{reference → references}/meta.ts +2 -2
  317. package/docs/references/openapi.mdx +171 -0
  318. package/docs/references/scalar.mdx +64 -0
  319. package/package.json +42 -8
  320. package/skills/blume/SKILL.md +21 -8
  321. package/skills/blume-migrate/SKILL.md +22 -21
  322. package/skills/blume-migrate/assets/oxfmt@0.67.0.patch +49 -0
  323. package/skills/blume-migrate/references/docusaurus.md +5 -4
  324. package/skills/blume-migrate/references/fumadocs.md +4 -4
  325. package/skills/blume-migrate/references/mintlify.md +23 -8
  326. package/skills/blume-migrate/references/monorepo.md +6 -6
  327. package/skills/blume-migrate/references/starlight.md +4 -4
  328. package/src/ai/agent-readability.ts +26 -22
  329. package/src/ai/ai-catalog.ts +259 -0
  330. package/src/ai/api/handlers.ts +46 -11
  331. package/src/ai/api-catalog.ts +8 -8
  332. package/src/ai/ask-data.ts +1 -1
  333. package/src/ai/ask.ts +624 -100
  334. package/src/ai/changelog-markdown.ts +91 -0
  335. package/src/ai/component-markdown.ts +328 -12
  336. package/src/ai/index.ts +45 -0
  337. package/src/ai/link-headers.ts +19 -6
  338. package/src/ai/llms.ts +26 -15
  339. package/src/ai/markdown.ts +35 -5
  340. package/src/ai/mcp/data.ts +9 -5
  341. package/src/ai/mcp/discovery.ts +1 -1
  342. package/src/ai/openapi-components.ts +4 -1
  343. package/src/ai/relative-links.ts +170 -0
  344. package/src/ai/serializers.ts +2 -2
  345. package/src/ai/skills.ts +1 -1
  346. package/src/ai/web-bot-auth.ts +2 -2
  347. package/src/analytics/adobe.ts +46 -0
  348. package/src/analytics/amplitude.ts +79 -0
  349. package/src/analytics/clarity.ts +46 -0
  350. package/src/analytics/clearbit.ts +47 -0
  351. package/src/analytics/cloudflare.ts +67 -0
  352. package/src/analytics/fathom.ts +64 -0
  353. package/src/analytics/google-analytics.ts +84 -0
  354. package/src/analytics/google-tag-manager.ts +61 -0
  355. package/src/analytics/head.ts +130 -0
  356. package/src/analytics/heap.ts +65 -0
  357. package/src/analytics/hightouch.ts +77 -0
  358. package/src/analytics/hotjar.ts +47 -0
  359. package/src/analytics/index.ts +71 -0
  360. package/src/analytics/inline.ts +21 -0
  361. package/src/analytics/logrocket.ts +71 -0
  362. package/src/analytics/mixpanel.ts +92 -0
  363. package/src/analytics/pirsch.ts +66 -0
  364. package/src/analytics/plausible.ts +83 -0
  365. package/src/analytics/posthog.ts +78 -0
  366. package/src/analytics/schema.ts +60 -0
  367. package/src/analytics/script.ts +60 -0
  368. package/src/analytics/segment.ts +85 -0
  369. package/src/analytics/vercel.ts +50 -0
  370. package/src/astro/adapter-root.ts +7 -9
  371. package/src/astro/component-slots.ts +131 -91
  372. package/src/astro/generate.ts +114 -345
  373. package/src/astro/integration.ts +2 -6
  374. package/src/astro/pages.ts +13 -101
  375. package/src/astro/render-deps.ts +379 -0
  376. package/src/astro/runtime-deps.ts +201 -0
  377. package/src/astro/templates.ts +554 -541
  378. package/src/audit/agent.ts +24 -0
  379. package/src/audit/catalog.ts +2 -2
  380. package/src/audit/checks/assets.ts +2 -2
  381. package/src/audit/checks/dns-aid.ts +1 -1
  382. package/src/audit/checks/duplicates.ts +3 -1
  383. package/src/audit/checks/i18n.ts +1 -1
  384. package/src/audit/checks/indexability.ts +7 -7
  385. package/src/audit/checks/links.ts +2 -2
  386. package/src/audit/checks/llms.ts +6 -6
  387. package/src/audit/checks/network.ts +3 -3
  388. package/src/audit/checks/og-image.ts +2 -2
  389. package/src/audit/checks/robots.ts +1 -1
  390. package/src/audit/checks/sitemap.ts +2 -2
  391. package/src/audit/checks/social.ts +1 -1
  392. package/src/audit/run.ts +4 -3
  393. package/src/audit/terms.ts +31 -0
  394. package/src/audit/url.ts +13 -13
  395. package/src/cli/command-meta.ts +10 -0
  396. package/src/cli/commands/audit.ts +39 -20
  397. package/src/cli/commands/build.ts +71 -314
  398. package/src/cli/commands/check.ts +1 -0
  399. package/src/cli/commands/dev.ts +40 -1
  400. package/src/cli/commands/doctor.ts +90 -14
  401. package/src/cli/commands/eject.ts +44 -7
  402. package/src/cli/commands/eval.ts +2 -2
  403. package/src/cli/commands/init.ts +161 -41
  404. package/src/cli/commands/migrate.ts +121 -0
  405. package/src/cli/commands/preview.ts +7 -1
  406. package/src/cli/commands/translate.ts +2 -2
  407. package/src/cli/commands/upgrade.ts +141 -0
  408. package/src/cli/commands/version.ts +57 -44
  409. package/src/cli/eject-scripts.ts +121 -6
  410. package/src/cli/index.ts +11 -1
  411. package/src/cli/init/install.ts +70 -0
  412. package/src/cli/init/questions.ts +7 -0
  413. package/src/cli/init/scaffold.ts +459 -75
  414. package/src/cli/lazy-command.ts +37 -1
  415. package/src/cli/prepare.ts +40 -6
  416. package/src/cli/required-secrets.ts +38 -11
  417. package/src/cli/unknown-flags.ts +266 -0
  418. package/src/cli/yarn-pnp.ts +52 -0
  419. package/src/components/content/AccordionItem.astro +7 -1
  420. package/src/components/content/Card.astro +4 -3
  421. package/src/components/content/ColorItem.astro +22 -4
  422. package/src/components/content/GithubInfo.astro +2 -2
  423. package/src/components/content/Prompt.astro +25 -25
  424. package/src/components/content/Tabs.astro +3 -1
  425. package/src/components/content/Tile.astro +2 -3
  426. package/src/components/content/Tooltip.astro +57 -9
  427. package/src/components/content/content-strings.ts +34 -0
  428. package/src/components/content/diff.ts +1 -1
  429. package/src/components/content/mermaid-element.ts +13 -2
  430. package/src/components/content/prompt-markdown.ts +292 -0
  431. package/src/components/content/tooltip-id.ts +41 -0
  432. package/src/components/islands/hooks.ts +75 -3
  433. package/src/components/layout/Analytics.astro +21 -79
  434. package/src/components/layout/Banner.astro +3 -1
  435. package/src/components/layout/DiscoveryLinks.astro +69 -0
  436. package/src/components/layout/Header.astro +83 -20
  437. package/src/components/layout/LanguageSwitcher.astro +4 -1
  438. package/src/components/layout/Logo.astro +23 -2
  439. package/src/components/layout/NavSelector.astro +13 -2
  440. package/src/components/layout/NavTree.astro +12 -3
  441. package/src/components/layout/NavTreeScript.astro +17 -3
  442. package/src/components/layout/PageActions.astro +3 -3
  443. package/src/components/layout/PageFeedback.astro +11 -1
  444. package/src/components/layout/PageLayout.astro +52 -5
  445. package/src/components/layout/ReferenceLayout.astro +21 -12
  446. package/src/components/layout/RootLayout.astro +69 -43
  447. package/src/components/layout/Search.astro +30 -6
  448. package/src/components/layout/WebMcp.astro +1 -1
  449. package/src/components/layout/analytics-client.ts +101 -15
  450. package/src/components/layout/drawer-inert.ts +113 -15
  451. package/src/components/layout/dropdown-clamp.ts +105 -0
  452. package/src/components/layout/head-scripts.ts +15 -6
  453. package/src/components/layout/nav-utils.ts +17 -0
  454. package/src/components/layout/search/algolia.ts +8 -8
  455. package/src/components/layout/search/orama-cloud.ts +9 -7
  456. package/src/components/layout/search/typesense.ts +11 -17
  457. package/src/components/openapi/MessageComposer.astro +2 -2
  458. package/src/components/openapi/Playground.astro +2 -2
  459. package/src/components/openapi/playground-client.ts +79 -10
  460. package/src/core/changelog-index.ts +24 -0
  461. package/src/core/component-overrides.ts +399 -154
  462. package/src/core/config-input.ts +212 -543
  463. package/src/core/config.ts +130 -41
  464. package/src/core/custom-pages.ts +105 -0
  465. package/src/core/data.ts +32 -11
  466. package/src/core/define-components.ts +12 -9
  467. package/src/core/deployment-env.ts +18 -74
  468. package/src/core/diagnostics.ts +14 -7
  469. package/src/core/graph.ts +69 -25
  470. package/src/core/i18n-ui.ts +6 -2
  471. package/src/core/i18n.ts +17 -0
  472. package/src/core/includes.ts +156 -38
  473. package/src/core/last-modified.ts +6 -11
  474. package/src/core/links.ts +166 -2
  475. package/src/core/manifest.ts +10 -3
  476. package/src/core/navigation.ts +137 -19
  477. package/src/core/new-tab.ts +35 -0
  478. package/src/core/node-require.ts +21 -0
  479. package/src/core/project-graph.ts +42 -26
  480. package/src/core/project.ts +9 -4
  481. package/src/core/request-body.ts +61 -0
  482. package/src/core/safe-href.ts +28 -0
  483. package/src/core/safe-links.ts +68 -0
  484. package/src/core/schema.ts +531 -721
  485. package/src/core/server-features.ts +8 -9
  486. package/src/core/sources/assets.ts +47 -11
  487. package/src/core/sources/collection.ts +67 -0
  488. package/src/core/sources/contentful-rich-text.ts +285 -0
  489. package/src/core/sources/contentful.ts +173 -0
  490. package/src/core/sources/github-releases.ts +51 -1
  491. package/src/core/sources/json.ts +71 -0
  492. package/src/core/sources/lexical.ts +195 -0
  493. package/src/core/sources/lower.ts +226 -0
  494. package/src/core/sources/normalize.ts +52 -2
  495. package/src/core/sources/notion.ts +39 -28
  496. package/src/core/sources/payload.ts +135 -0
  497. package/src/core/sources/portable-text.ts +11 -16
  498. package/src/core/sources/remote.ts +226 -0
  499. package/src/core/sources/resolve.ts +104 -166
  500. package/src/core/sources/sanity.ts +16 -49
  501. package/src/core/sources/strapi-blocks.ts +124 -0
  502. package/src/core/sources/strapi.ts +191 -0
  503. package/src/core/sources/types.ts +12 -1
  504. package/src/core/types.ts +20 -1
  505. package/src/core/ui-packs/ar.ts +6 -2
  506. package/src/core/ui-packs/bg.ts +6 -2
  507. package/src/core/ui-packs/bn.ts +6 -2
  508. package/src/core/ui-packs/ca.ts +3 -1
  509. package/src/core/ui-packs/cs.ts +6 -2
  510. package/src/core/ui-packs/da.ts +6 -2
  511. package/src/core/ui-packs/de.ts +6 -2
  512. package/src/core/ui-packs/el.ts +3 -1
  513. package/src/core/ui-packs/es.ts +3 -1
  514. package/src/core/ui-packs/fa.ts +6 -2
  515. package/src/core/ui-packs/fi.ts +6 -2
  516. package/src/core/ui-packs/fr.ts +3 -1
  517. package/src/core/ui-packs/he.ts +6 -2
  518. package/src/core/ui-packs/hi.ts +6 -2
  519. package/src/core/ui-packs/hr.ts +6 -2
  520. package/src/core/ui-packs/hu.ts +6 -2
  521. package/src/core/ui-packs/id.ts +6 -2
  522. package/src/core/ui-packs/it.ts +3 -1
  523. package/src/core/ui-packs/ja.ts +3 -1
  524. package/src/core/ui-packs/ko.ts +3 -1
  525. package/src/core/ui-packs/nl.ts +6 -2
  526. package/src/core/ui-packs/no.ts +6 -2
  527. package/src/core/ui-packs/pl.ts +6 -2
  528. package/src/core/ui-packs/pt-br.ts +3 -1
  529. package/src/core/ui-packs/pt.ts +3 -1
  530. package/src/core/ui-packs/ro.ts +6 -2
  531. package/src/core/ui-packs/ru.ts +6 -2
  532. package/src/core/ui-packs/sk.ts +6 -2
  533. package/src/core/ui-packs/sr.ts +6 -2
  534. package/src/core/ui-packs/sv.ts +6 -2
  535. package/src/core/ui-packs/th.ts +3 -1
  536. package/src/core/ui-packs/tr.ts +6 -2
  537. package/src/core/ui-packs/uk.ts +6 -2
  538. package/src/core/ui-packs/vi.ts +3 -1
  539. package/src/core/ui-packs/zh-tw.ts +3 -1
  540. package/src/core/ui-packs/zh.ts +3 -1
  541. package/src/core/unrecognized-keys.ts +10 -0
  542. package/src/core/version-cut.ts +116 -8
  543. package/src/deploy/adapter-output.ts +57 -97
  544. package/src/deploy/adapters/cloudflare.ts +39 -0
  545. package/src/deploy/adapters/index.ts +41 -0
  546. package/src/deploy/adapters/netlify.ts +34 -0
  547. package/src/deploy/adapters/node.ts +34 -0
  548. package/src/deploy/adapters/registry.ts +127 -0
  549. package/src/deploy/adapters/types.ts +92 -0
  550. package/src/deploy/adapters/vercel.ts +35 -0
  551. package/src/deploy/artifacts.ts +67 -28
  552. package/src/deploy/cloudflare-negotiation.ts +179 -100
  553. package/src/deploy/function-bundle.ts +18 -3
  554. package/src/deploy/headers.ts +129 -22
  555. package/src/deploy/node-headers.ts +198 -0
  556. package/src/deploy/platforms/cloudflare.ts +312 -0
  557. package/src/deploy/platforms/index.ts +67 -0
  558. package/src/deploy/platforms/netlify.ts +52 -0
  559. package/src/deploy/platforms/node.ts +40 -0
  560. package/src/deploy/platforms/paths.ts +42 -0
  561. package/src/deploy/platforms/static.ts +29 -0
  562. package/src/deploy/platforms/types.ts +112 -0
  563. package/src/deploy/platforms/vercel.ts +193 -0
  564. package/src/deploy/redirects.ts +30 -18
  565. package/src/deploy/robots.ts +3 -3
  566. package/src/deploy/rss.ts +2 -2
  567. package/src/deploy/sitemap.ts +2 -2
  568. package/src/deploy/vercel-negotiation.ts +27 -4
  569. package/src/eval/agents.ts +32 -1
  570. package/src/eval/findings.ts +19 -11
  571. package/src/eval/report.ts +10 -2
  572. package/src/markdown/external-links.ts +65 -0
  573. package/src/markdown/include.ts +45 -27
  574. package/src/markdown/index.ts +34 -9
  575. package/src/markdown/inline-code.ts +12 -6
  576. package/src/markdown/relative-links.ts +324 -0
  577. package/src/markdown/themes.ts +3 -3
  578. package/src/migrate/migrate.ts +149 -0
  579. package/src/openapi/parse.ts +64 -16
  580. package/src/openapi/proxy.ts +62 -10
  581. package/src/openapi/references.ts +147 -147
  582. package/src/openapi/render-mdx.ts +32 -10
  583. package/src/openapi/scalar.ts +15 -13
  584. package/src/openapi/sentence.ts +14 -0
  585. package/src/openapi/source.ts +37 -21
  586. package/src/openapi/spec-dependency-error.ts +15 -0
  587. package/src/reference/asyncapi.ts +83 -0
  588. package/src/reference/graphql.ts +89 -0
  589. package/src/reference/index.ts +40 -0
  590. package/src/reference/openapi.ts +83 -0
  591. package/src/reference/options.ts +201 -0
  592. package/src/reference/scalar.ts +136 -0
  593. package/src/reference/schema.ts +88 -0
  594. package/src/registry/eject.ts +97 -42
  595. package/src/search/adapters/algolia.ts +46 -0
  596. package/src/search/adapters/flexsearch.ts +29 -0
  597. package/src/search/adapters/index.ts +39 -0
  598. package/src/search/adapters/mixedbread.ts +39 -0
  599. package/src/search/adapters/orama-cloud.ts +51 -0
  600. package/src/search/adapters/orama.ts +24 -0
  601. package/src/search/adapters/pagefind.ts +27 -0
  602. package/src/search/adapters/registry.ts +131 -0
  603. package/src/search/adapters/types.ts +46 -0
  604. package/src/search/adapters/typesense.ts +57 -0
  605. package/src/search/build.ts +33 -7
  606. package/src/search/documents.ts +6 -0
  607. package/src/search/sync/algolia.ts +12 -11
  608. package/src/search/sync/index.ts +35 -20
  609. package/src/search/sync/orama-cloud.ts +12 -9
  610. package/src/search/sync/typesense.ts +15 -13
  611. package/src/sources/contentful.ts +63 -0
  612. package/src/sources/custom.ts +38 -0
  613. package/src/sources/filesystem.ts +51 -0
  614. package/src/sources/github-releases.ts +52 -0
  615. package/src/sources/index.ts +60 -0
  616. package/src/sources/mdx-remote.ts +76 -0
  617. package/src/sources/notion.ts +63 -0
  618. package/src/sources/obsidian.ts +38 -0
  619. package/src/sources/payload.ts +60 -0
  620. package/src/sources/registry.ts +182 -0
  621. package/src/sources/sanity.ts +66 -0
  622. package/src/sources/shared.ts +52 -0
  623. package/src/sources/strapi.ts +58 -0
  624. package/src/theme/entry.ts +47 -2
  625. package/src/translate/report.ts +40 -7
  626. package/src/upgrade/upgrade.ts +499 -0
  627. package/dist/cli/chunk-12dxjqk7.js.map +0 -10
  628. package/dist/cli/chunk-196vjxp9.js.map +0 -13
  629. package/dist/cli/chunk-2mzebbbz.js +0 -69
  630. package/dist/cli/chunk-2z47ypj8.js.map +0 -11
  631. package/dist/cli/chunk-30e87n55.js +0 -108
  632. package/dist/cli/chunk-30e87n55.js.map +0 -10
  633. package/dist/cli/chunk-450a7rcr.js +0 -185
  634. package/dist/cli/chunk-450a7rcr.js.map +0 -11
  635. package/dist/cli/chunk-5n7t497w.js.map +0 -40
  636. package/dist/cli/chunk-61j18dwk.js +0 -5342
  637. package/dist/cli/chunk-61j18dwk.js.map +0 -58
  638. package/dist/cli/chunk-88by27n5.js +0 -17
  639. package/dist/cli/chunk-88by27n5.js.map +0 -10
  640. package/dist/cli/chunk-8cd8tj54.js.map +0 -34
  641. package/dist/cli/chunk-aztttvb3.js +0 -381
  642. package/dist/cli/chunk-aztttvb3.js.map +0 -12
  643. package/dist/cli/chunk-cvky9gb2.js.map +0 -11
  644. package/dist/cli/chunk-ejjx8znq.js.map +0 -15
  645. package/dist/cli/chunk-fmceyezb.js +0 -1007
  646. package/dist/cli/chunk-fmceyezb.js.map +0 -13
  647. package/dist/cli/chunk-hdm2dkd2.js.map +0 -48
  648. package/dist/cli/chunk-hs3gbh8p.js.map +0 -10
  649. package/dist/cli/chunk-jbj4qhfw.js +0 -30
  650. package/dist/cli/chunk-jbj4qhfw.js.map +0 -10
  651. package/dist/cli/chunk-mqb2ka8m.js +0 -68
  652. package/dist/cli/chunk-mqb2ka8m.js.map +0 -10
  653. package/dist/cli/chunk-mt76t7dj.js.map +0 -11
  654. package/dist/cli/chunk-q4rae3bg.js +0 -60
  655. package/dist/cli/chunk-q4rae3bg.js.map +0 -10
  656. package/dist/cli/chunk-ra1v2nc2.js +0 -35
  657. package/dist/cli/chunk-ra1v2nc2.js.map +0 -10
  658. package/dist/cli/chunk-t3tj0dgr.js.map +0 -15
  659. package/dist/cli/chunk-tqa1s0k8.js +0 -69
  660. package/dist/cli/chunk-tqa1s0k8.js.map +0 -11
  661. package/dist/cli/chunk-vh9w1sgp.js +0 -73
  662. package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
  663. package/dist/cli/chunk-vkrsvbr5.js +0 -107
  664. package/dist/cli/chunk-vkrsvbr5.js.map +0 -11
  665. package/dist/cli/chunk-vrfp10qk.js +0 -81
  666. package/dist/cli/chunk-vrfp10qk.js.map +0 -10
  667. package/dist/cli/chunk-wjt80jps.js +0 -1049
  668. package/dist/cli/chunk-wjt80jps.js.map +0 -24
  669. package/docs/advanced/api-reference.mdx +0 -240
  670. package/docs/reference/cli.mdx +0 -197
  671. package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
  672. package/src/components/content/changelog-element.ts +0 -69
  673. package/src/search/providers.ts +0 -91
  674. /package/dist/cli/{chunk-3w7b2vcx.js.map → chunk-7ez8ny0t.js.map} +0 -0
  675. /package/dist/cli/{chunk-688e0dde.js.map → chunk-88cpgt6h.js.map} +0 -0
  676. /package/dist/cli/{chunk-exeeb35e.js.map → chunk-f7t03s3g.js.map} +0 -0
  677. /package/dist/cli/{chunk-ppfvdcd4.js.map → chunk-zxccj738.js.map} +0 -0
@@ -20,4 +20,4 @@ var parsePort = (value) => {
20
20
  export { parsePort };
21
21
 
22
22
  //# debugId=EAEB4015F7DCE38D64756E2164756E21
23
- //# sourceMappingURL=chunk-ppfvdcd4.js.map
23
+ //# sourceMappingURL=chunk-zxccj738.js.map
package/dist/cli/index.js CHANGED
@@ -79,6 +79,10 @@ var commandMeta = {
79
79
  description: "Serve an MCP data snapshot over stdio (internal, used by `blume eval`).",
80
80
  name: "mcp-stdio"
81
81
  },
82
+ migrate: {
83
+ description: "Migrate a docs site from Mintlify, Fumadocs, Docusaurus, Starlight, or Nextra with a coding agent.",
84
+ name: "migrate"
85
+ },
82
86
  preview: {
83
87
  description: "Preview the last production build.",
84
88
  name: "preview"
@@ -91,6 +95,10 @@ var commandMeta = {
91
95
  description: "Translate docs into the configured locales with a local agent CLI.",
92
96
  name: "translate"
93
97
  },
98
+ upgrade: {
99
+ description: "Upgrade to this version of Blume: bump the dependency and list the config changes left.",
100
+ name: "upgrade"
101
+ },
94
102
  validate: {
95
103
  description: "Validate internal, anchor, asset, and external links.",
96
104
  name: "validate"
@@ -160,37 +168,6 @@ var reportInternalError = (error) => {
160
168
  `);
161
169
  };
162
170
 
163
- // src/cli/lazy-command.ts
164
- var lazyCommand = (meta, load, key) => {
165
- const command = async () => {
166
- const module = await load();
167
- return module[key];
168
- };
169
- return {
170
- args: async () => {
171
- const { args } = await command();
172
- return args;
173
- },
174
- cleanup: async (context) => {
175
- const loaded = await command();
176
- await loaded.cleanup?.(context);
177
- },
178
- meta,
179
- run: async (context) => {
180
- const loaded = await command();
181
- await loaded.run?.(context);
182
- },
183
- setup: async (context) => {
184
- const loaded = await command();
185
- await loaded.setup?.(context);
186
- }
187
- };
188
- };
189
-
190
- // src/cli/log.ts
191
- import { consola } from "consola";
192
- import { relative as relative2 } from "pathe";
193
-
194
171
  // src/core/diagnostics.ts
195
172
  import { colors as colors2 } from "consola/utils";
196
173
  import { relative } from "pathe";
@@ -205,25 +182,28 @@ class BlumeError extends Error {
205
182
  }
206
183
  var DOCS_BASE = "https://useblume.dev";
207
184
  var DOCS_DEPLOYMENT = "/docs/deployment";
208
- var DOCS_REFERENCE_CLI = "/docs/reference/cli";
185
+ var DOCS_CLI_VALIDATE = "/docs/cli/validate";
209
186
  var DOCS_CONTENT_SOURCES = "/docs/content/sources";
210
187
  var DOCS_CONTENT_NAVIGATION = "/docs/content/navigation";
211
188
  var DOCS_CONTENT_INCLUDES = "/docs/content/includes";
212
189
  var DOCS_PATHS = new Map(Object.entries({
213
190
  BLUME_ADAPTER_REQUIRED: DOCS_DEPLOYMENT,
214
- BLUME_ASSETS_UNCHECKED: DOCS_REFERENCE_CLI,
191
+ BLUME_ASSETS_UNCHECKED: DOCS_CLI_VALIDATE,
215
192
  BLUME_ASSET_FETCH_FAILED: DOCS_CONTENT_SOURCES,
216
- BLUME_BROKEN_ANCHOR: DOCS_REFERENCE_CLI,
217
- BLUME_BROKEN_ASSET: DOCS_REFERENCE_CLI,
218
- BLUME_BROKEN_LINK: DOCS_REFERENCE_CLI,
193
+ BLUME_BROKEN_ANCHOR: DOCS_CLI_VALIDATE,
194
+ BLUME_BROKEN_ASSET: DOCS_CLI_VALIDATE,
195
+ BLUME_BROKEN_LINK: DOCS_CLI_VALIDATE,
196
+ BLUME_COMPONENTS_INVALID: "/docs/configuration/customization",
219
197
  BLUME_CONFIG_INVALID: "/docs/configuration",
220
198
  BLUME_CONFIG_LOAD_FAILED: "/docs/configuration",
221
199
  BLUME_CONTENT_ROOT_MISSING: DOCS_CONTENT_SOURCES,
222
- BLUME_DEAD_LINK: DOCS_REFERENCE_CLI,
200
+ BLUME_DEAD_LINK: DOCS_CLI_VALIDATE,
201
+ BLUME_DEPENDENCY_MISSING: "/docs/cli/doctor",
223
202
  BLUME_DUPLICATE_ROUTE: DOCS_CONTENT_NAVIGATION,
224
203
  BLUME_DUPLICATE_SIDEBAR_ORDER: DOCS_CONTENT_NAVIGATION,
225
- BLUME_FRONTMATTER_INVALID: "/docs/reference/frontmatter",
204
+ BLUME_FRONTMATTER_INVALID: "/docs/content/frontmatter",
226
205
  BLUME_INCLUDE_CYCLE: DOCS_CONTENT_INCLUDES,
206
+ BLUME_INCLUDE_MALFORMED: DOCS_CONTENT_INCLUDES,
227
207
  BLUME_INCLUDE_NOT_FOUND: DOCS_CONTENT_INCLUDES,
228
208
  BLUME_INCLUDE_OUTSIDE_ROOT: DOCS_CONTENT_INCLUDES,
229
209
  BLUME_MDX_CURLY_ANCHOR: "/docs/content/syntax",
@@ -242,10 +222,14 @@ var DOCS_PATHS = new Map(Object.entries({
242
222
  BLUME_SOURCE_OFFLINE: DOCS_CONTENT_SOURCES,
243
223
  BLUME_SOURCE_SDK_MISSING: DOCS_CONTENT_SOURCES,
244
224
  BLUME_SOURCE_UNAVAILABLE: DOCS_CONTENT_SOURCES,
225
+ BLUME_TRANSLATE_MISSING: "/docs/cli/translate",
226
+ BLUME_TRANSLATE_STALE: "/docs/cli/translate",
245
227
  BLUME_UNKNOWN_COMPONENT: "/docs/configuration/customization",
246
228
  BLUME_UNKNOWN_ICON: DOCS_CONTENT_NAVIGATION,
229
+ BLUME_UNKNOWN_OPTION: "/docs/cli",
247
230
  BLUME_WIKILINK_AMBIGUOUS: DOCS_CONTENT_SOURCES,
248
- BLUME_WIKILINK_UNRESOLVED: DOCS_CONTENT_SOURCES
231
+ BLUME_WIKILINK_UNRESOLVED: DOCS_CONTENT_SOURCES,
232
+ BLUME_YARN_PNP: "/docs/quickstart"
249
233
  }));
250
234
  var resolveDocsUrl = (code) => {
251
235
  const path = DOCS_PATHS.get(code);
@@ -358,6 +342,8 @@ var countBySeverity = (diagnostics) => {
358
342
  };
359
343
 
360
344
  // src/cli/log.ts
345
+ import { consola } from "consola";
346
+ import { relative as relative2 } from "pathe";
361
347
  var logger = consola.withTag("blume");
362
348
  var flushStdout = () => new Promise((resolve) => {
363
349
  process.stdout.write("", () => resolve());
@@ -392,29 +378,198 @@ ${summary}
392
378
  return hasErrors(diagnostics);
393
379
  };
394
380
 
381
+ // src/cli/unknown-flags.ts
382
+ var kebabCase = (name) => name.replaceAll(/(?<upper>[A-Z])/gu, (letter) => `-${letter.toLowerCase()}`);
383
+ var camelCase = (name) => name.replaceAll(/-(?<letter>[a-z])/gu, (match) => match.slice(1).toUpperCase());
384
+ var aliasesOf = (alias) => {
385
+ if (alias === undefined) {
386
+ return [];
387
+ }
388
+ return Array.isArray(alias) ? alias : [alias];
389
+ };
390
+ var knownFlags = (argsDef) => {
391
+ const flags = new Map;
392
+ for (const [name, def] of Object.entries(argsDef)) {
393
+ if (def.type === "positional") {
394
+ continue;
395
+ }
396
+ const kebab = kebabCase(name);
397
+ const boolean = def.type === "boolean";
398
+ const onByDefault = boolean && "default" in def && def.default === true;
399
+ const flag = {
400
+ boolean,
401
+ display: onByDefault ? `--no-${kebab}` : `--${kebab}`,
402
+ name: kebab,
403
+ takesValue: def.type === "string" || def.type === "enum"
404
+ };
405
+ for (const spelling of [
406
+ name,
407
+ kebabCase(name),
408
+ camelCase(name),
409
+ ...aliasesOf("alias" in def ? def.alias : undefined)
410
+ ]) {
411
+ flags.set(spelling, flag);
412
+ }
413
+ }
414
+ return flags;
415
+ };
416
+ var distance = (from, to) => {
417
+ let previous = Array.from({ length: to.length + 1 }, (_, index) => index);
418
+ for (const [row, fromChar] of [...from].entries()) {
419
+ const current = [row + 1];
420
+ for (const [column, toChar] of [...to].entries()) {
421
+ current.push(Math.min((previous[column + 1] ?? 0) + 1, (current[column] ?? 0) + 1, (previous[column] ?? 0) + (fromChar === toChar ? 0 : 1)));
422
+ }
423
+ previous = current;
424
+ }
425
+ return previous[to.length] ?? 0;
426
+ };
427
+ var closestMatch = (name, candidates) => {
428
+ let best;
429
+ for (const candidate of candidates) {
430
+ const edits = distance(name, candidate);
431
+ if (edits <= 2 && edits * 2 < candidate.length && (best === undefined || edits < best.edits)) {
432
+ best = { candidate, edits };
433
+ }
434
+ }
435
+ return best?.candidate;
436
+ };
437
+ var parseToken = (arg) => {
438
+ const long = arg.startsWith("--");
439
+ const [name = ""] = arg.slice(long ? 2 : 1).split("=");
440
+ return {
441
+ hasValue: arg.includes("="),
442
+ long,
443
+ name,
444
+ negated: long && name.startsWith("no-") ? name.slice(3) : undefined
445
+ };
446
+ };
447
+ var declaredWidth = (token, flags) => {
448
+ const known = flags.get(token.name) ?? (token.negated === undefined ? undefined : flags.get(token.negated));
449
+ if (known) {
450
+ return known.takesValue && !token.hasValue && token.negated === undefined ? 1 : 0;
451
+ }
452
+ const grouped = !token.long && token.name.length > 1 && [...token.name].every((letter) => flags.get(letter)?.takesValue === false);
453
+ return grouped ? 0 : undefined;
454
+ };
455
+ var describeUnknown = (token, flags) => {
456
+ const unknown = {
457
+ flag: `${token.long ? "--" : "-"}${token.name}`
458
+ };
459
+ const names = [...new Set([...flags.values()].map((flag) => flag.name))];
460
+ const match = closestMatch(token.negated ?? token.name, names);
461
+ if (match) {
462
+ const negate = token.negated !== undefined && flags.get(match)?.boolean;
463
+ unknown.suggestion = negate ? `--no-${match}` : `--${match}`;
464
+ }
465
+ return unknown;
466
+ };
467
+ var unknownFlags = (rawArgs, argsDef, accepted = []) => {
468
+ const flags = knownFlags(argsDef);
469
+ const unknown = [];
470
+ for (let index = 0;index < rawArgs.length; index += 1) {
471
+ const arg = rawArgs[index] ?? "";
472
+ if (arg === "--") {
473
+ break;
474
+ }
475
+ if (!arg.startsWith("-") || arg === "-") {
476
+ continue;
477
+ }
478
+ const token = parseToken(arg);
479
+ const width = declaredWidth(token, flags);
480
+ if (width !== undefined) {
481
+ index += width;
482
+ } else if (!accepted.includes(token.negated ?? token.name)) {
483
+ unknown.push(describeUnknown(token, flags));
484
+ }
485
+ }
486
+ return unknown;
487
+ };
488
+ var COMMAND_HANDLED_FLAGS = new Map([
489
+ ["build", ["adapter", "output", "base"]]
490
+ ]);
491
+ var unknownFlagsDiagnostic = (command, unknown, argsDef) => {
492
+ const listed = unknown.map(({ flag, suggestion }) => suggestion ? `${flag} (did you mean ${suggestion}?)` : flag).join(", ");
493
+ const declared = [
494
+ ...new Set([...knownFlags(argsDef).values()].map((flag) => flag.display))
495
+ ].toSorted();
496
+ const takes = declared.length > 0 ? `It takes ${declared.join(", ")}.` : "It takes no options.";
497
+ return {
498
+ code: "BLUME_UNKNOWN_OPTION",
499
+ message: `blume ${command} doesn't know ${unknown.length === 1 ? "the option" : "the options"} ${listed}.`,
500
+ severity: "error",
501
+ suggestion: `${takes} Run \`blume ${command} --help\` for what each does.`
502
+ };
503
+ };
504
+
505
+ // src/cli/lazy-command.ts
506
+ var lazyCommand = (meta, load, key) => {
507
+ const command = async () => {
508
+ const module = await load();
509
+ return module[key];
510
+ };
511
+ const name = meta.name ?? key;
512
+ return {
513
+ args: async () => {
514
+ const { args } = await command();
515
+ return args;
516
+ },
517
+ cleanup: async (context) => {
518
+ const loaded = await command();
519
+ await loaded.cleanup?.(context);
520
+ },
521
+ meta,
522
+ run: async (context) => {
523
+ const loaded = await command();
524
+ try {
525
+ await loaded.run?.(context);
526
+ } catch (error) {
527
+ if (error instanceof BlumeError) {
528
+ reportDiagnostics([error.diagnostic], process.cwd());
529
+ } else {
530
+ reportInternalError(error);
531
+ }
532
+ process.exit(1);
533
+ }
534
+ },
535
+ setup: async (context) => {
536
+ const loaded = await command();
537
+ const argsDef = loaded.args ?? {};
538
+ const unknown = unknownFlags(context.rawArgs, argsDef, COMMAND_HANDLED_FLAGS.get(name));
539
+ if (unknown.length > 0) {
540
+ reportDiagnostics([unknownFlagsDiagnostic(name, unknown, argsDef)]);
541
+ process.exit(1);
542
+ }
543
+ await loaded.setup?.(context);
544
+ }
545
+ };
546
+ };
547
+
395
548
  // src/cli/index.ts
396
549
  var main = defineCommand({
397
550
  meta: {
398
- description: "Markdown-first documentation powered by Astro and Vite.",
551
+ description: "The open-source docs framework for humans and agents.",
399
552
  name: "blume",
400
553
  version: getBlumeVersion()
401
554
  },
402
555
  subCommands: {
403
- add: lazyCommand(commandMeta.add, () => import("./chunk-3w7b2vcx.js"), "addCommand"),
404
- audit: lazyCommand(commandMeta.audit, () => import("./chunk-8cd8tj54.js"), "auditCommand"),
405
- build: lazyCommand(commandMeta.build, () => import("./chunk-fmceyezb.js"), "buildCommand"),
406
- check: lazyCommand(commandMeta.check, () => import("./chunk-xhtpx3ff.js"), "checkCommand"),
407
- dev: lazyCommand(commandMeta.dev, () => import("./chunk-12dxjqk7.js"), "devCommand"),
408
- doctor: lazyCommand(commandMeta.doctor, () => import("./chunk-30e87n55.js"), "doctorCommand"),
409
- eject: lazyCommand(commandMeta.eject, () => import("./chunk-mqb2ka8m.js"), "ejectCommand"),
410
- eval: lazyCommand(commandMeta.eval, () => import("./chunk-t3tj0dgr.js"), "evalCommand"),
411
- init: lazyCommand(commandMeta.init, () => import("./chunk-mt76t7dj.js"), "initCommand"),
412
- "mcp-stdio": lazyCommand(commandMeta["mcp-stdio"], () => import("./chunk-n9sra6sy.js"), "mcpStdioCommand"),
413
- preview: lazyCommand(commandMeta.preview, () => import("./chunk-hs3gbh8p.js"), "previewCommand"),
414
- sync: lazyCommand(commandMeta.sync, () => import("./chunk-eevwt1sc.js"), "syncCommand"),
415
- translate: lazyCommand(commandMeta.translate, () => import("./chunk-9he6crym.js"), "translateCommand"),
416
- validate: lazyCommand(commandMeta.validate, () => import("./chunk-aztttvb3.js"), "validateCommand"),
417
- version: lazyCommand(commandMeta.version, () => import("./chunk-cvky9gb2.js"), "versionCommand")
556
+ add: lazyCommand(commandMeta.add, () => import("./chunk-7ez8ny0t.js"), "addCommand"),
557
+ audit: lazyCommand(commandMeta.audit, () => import("./chunk-j8mw0za6.js"), "auditCommand"),
558
+ build: lazyCommand(commandMeta.build, () => import("./chunk-z01ze5c1.js"), "buildCommand"),
559
+ check: lazyCommand(commandMeta.check, () => import("./chunk-1w8dp3qb.js"), "checkCommand"),
560
+ dev: lazyCommand(commandMeta.dev, () => import("./chunk-fh5hj5jt.js"), "devCommand"),
561
+ doctor: lazyCommand(commandMeta.doctor, () => import("./chunk-11j0384y.js"), "doctorCommand"),
562
+ eject: lazyCommand(commandMeta.eject, () => import("./chunk-ernrthtr.js"), "ejectCommand"),
563
+ eval: lazyCommand(commandMeta.eval, () => import("./chunk-d80hr03s.js"), "evalCommand"),
564
+ init: lazyCommand(commandMeta.init, () => import("./chunk-79njf86q.js"), "initCommand"),
565
+ "mcp-stdio": lazyCommand(commandMeta["mcp-stdio"], () => import("./chunk-pat2zzwc.js"), "mcpStdioCommand"),
566
+ migrate: lazyCommand(commandMeta.migrate, () => import("./chunk-pnnvybbk.js"), "migrateCommand"),
567
+ preview: lazyCommand(commandMeta.preview, () => import("./chunk-bctazmbk.js"), "previewCommand"),
568
+ sync: lazyCommand(commandMeta.sync, () => import("./chunk-tzne8qfq.js"), "syncCommand"),
569
+ translate: lazyCommand(commandMeta.translate, () => import("./chunk-6k8vp3ta.js"), "translateCommand"),
570
+ upgrade: lazyCommand(commandMeta.upgrade, () => import("./chunk-5a2z0198.js"), "upgradeCommand"),
571
+ validate: lazyCommand(commandMeta.validate, () => import("./chunk-y3e45rc8.js"), "validateCommand"),
572
+ version: lazyCommand(commandMeta.version, () => import("./chunk-b5aj94ah.js"), "versionCommand")
418
573
  }
419
574
  });
420
575
  loadEnvFiles(process.cwd());
@@ -439,13 +594,15 @@ export {
439
594
  locateFrontmatterKey,
440
595
  diagnosticsFromIssues,
441
596
  diagnosticsFromZod,
597
+ formatDiagnostic,
442
598
  hasErrors,
443
599
  countBySeverity,
444
600
  logger,
445
601
  flushStdout,
446
602
  reportDiagnosticsJson,
447
- reportDiagnostics
603
+ reportDiagnostics,
604
+ closestMatch
448
605
  };
449
606
 
450
- //# debugId=3D851F7CCD64619664756E2164756E21
607
+ //# debugId=3B8E364FC63CDED364756E2164756E21
451
608
  //# sourceMappingURL=index.js.map
@@ -1,19 +1,20 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/cli/index.ts", "../src/core/version.ts", "../src/core/package-root.ts", "../src/cli/command-meta.ts", "../src/cli/env.ts", "../src/cli/host-args.ts", "../src/cli/internal-error.ts", "../src/cli/lazy-command.ts", "../src/cli/log.ts", "../src/core/diagnostics.ts"],
3
+ "sources": ["../src/cli/index.ts", "../src/core/version.ts", "../src/core/package-root.ts", "../src/cli/command-meta.ts", "../src/cli/env.ts", "../src/cli/host-args.ts", "../src/cli/internal-error.ts", "../src/core/diagnostics.ts", "../src/cli/log.ts", "../src/cli/unknown-flags.ts", "../src/cli/lazy-command.ts"],
4
4
  "sourcesContent": [
5
- "import { defineCommand, runMain } from \"citty\";\n\nimport { getBlumeVersion } from \"../core/version.ts\";\nimport { commandMeta } from \"./command-meta.ts\";\nimport { loadEnvFiles } from \"./env.ts\";\nimport { normalizeHostArgs } from \"./host-args.ts\";\nimport { reportInternalError } from \"./internal-error.ts\";\nimport { lazyCommand } from \"./lazy-command.ts\";\n// consola reads CONSOLA_LEVEL / NODE_ENV / TEST / CI / DEBUG when its module\n// evaluates. Import the logger here, ahead of `loadEnvFiles`, so those values\n// come from the real environment — never from a project `.env`, which would\n// otherwise silence or restyle every command's output. The commands are loaded\n// lazily below, so without this line consola would first evaluate after `.env`\n// had been applied.\nimport \"./log.ts\";\n\nconst main = defineCommand({\n meta: {\n description: \"Markdown-first documentation powered by Astro and Vite.\",\n name: \"blume\",\n version: getBlumeVersion(),\n },\n subCommands: {\n add: lazyCommand(\n commandMeta.add,\n () => import(\"./commands/add.ts\"),\n \"addCommand\"\n ),\n audit: lazyCommand(\n commandMeta.audit,\n () => import(\"./commands/audit.ts\"),\n \"auditCommand\"\n ),\n build: lazyCommand(\n commandMeta.build,\n () => import(\"./commands/build.ts\"),\n \"buildCommand\"\n ),\n check: lazyCommand(\n commandMeta.check,\n () => import(\"./commands/check.ts\"),\n \"checkCommand\"\n ),\n dev: lazyCommand(\n commandMeta.dev,\n () => import(\"./commands/dev.ts\"),\n \"devCommand\"\n ),\n doctor: lazyCommand(\n commandMeta.doctor,\n () => import(\"./commands/doctor.ts\"),\n \"doctorCommand\"\n ),\n eject: lazyCommand(\n commandMeta.eject,\n () => import(\"./commands/eject.ts\"),\n \"ejectCommand\"\n ),\n eval: lazyCommand(\n commandMeta.eval,\n () => import(\"./commands/eval.ts\"),\n \"evalCommand\"\n ),\n init: lazyCommand(\n commandMeta.init,\n () => import(\"./commands/init.ts\"),\n \"initCommand\"\n ),\n \"mcp-stdio\": lazyCommand(\n commandMeta[\"mcp-stdio\"],\n () => import(\"./commands/mcp-stdio.ts\"),\n \"mcpStdioCommand\"\n ),\n preview: lazyCommand(\n commandMeta.preview,\n () => import(\"./commands/preview.ts\"),\n \"previewCommand\"\n ),\n sync: lazyCommand(\n commandMeta.sync,\n () => import(\"./commands/sync.ts\"),\n \"syncCommand\"\n ),\n translate: lazyCommand(\n commandMeta.translate,\n () => import(\"./commands/translate.ts\"),\n \"translateCommand\"\n ),\n validate: lazyCommand(\n commandMeta.validate,\n () => import(\"./commands/validate.ts\"),\n \"validateCommand\"\n ),\n version: lazyCommand(\n commandMeta.version,\n () => import(\"./commands/version.ts\"),\n \"versionCommand\"\n ),\n },\n});\n\nloadEnvFiles(process.cwd());\n\nprocess.on(\"uncaughtException\", (error) => {\n reportInternalError(error);\n process.exit(1);\n});\nprocess.on(\"unhandledRejection\", (error) => {\n reportInternalError(error);\n process.exit(1);\n});\n\nrunMain(main, { rawArgs: normalizeHostArgs(process.argv.slice(2)) });\n",
5
+ "import { defineCommand, runMain } from \"citty\";\n\nimport { getBlumeVersion } from \"../core/version.ts\";\nimport { commandMeta } from \"./command-meta.ts\";\nimport { loadEnvFiles } from \"./env.ts\";\nimport { normalizeHostArgs } from \"./host-args.ts\";\nimport { reportInternalError } from \"./internal-error.ts\";\nimport { lazyCommand } from \"./lazy-command.ts\";\n// consola reads CONSOLA_LEVEL / NODE_ENV / TEST / CI / DEBUG when its module\n// evaluates. Import the logger here, ahead of `loadEnvFiles`, so those values\n// come from the real environment — never from a project `.env`, which would\n// otherwise silence or restyle every command's output. The commands are loaded\n// lazily below, so without this line consola would first evaluate after `.env`\n// had been applied.\nimport \"./log.ts\";\n\nconst main = defineCommand({\n meta: {\n description: \"The open-source docs framework for humans and agents.\",\n name: \"blume\",\n version: getBlumeVersion(),\n },\n subCommands: {\n add: lazyCommand(\n commandMeta.add,\n () => import(\"./commands/add.ts\"),\n \"addCommand\"\n ),\n audit: lazyCommand(\n commandMeta.audit,\n () => import(\"./commands/audit.ts\"),\n \"auditCommand\"\n ),\n build: lazyCommand(\n commandMeta.build,\n () => import(\"./commands/build.ts\"),\n \"buildCommand\"\n ),\n check: lazyCommand(\n commandMeta.check,\n () => import(\"./commands/check.ts\"),\n \"checkCommand\"\n ),\n dev: lazyCommand(\n commandMeta.dev,\n () => import(\"./commands/dev.ts\"),\n \"devCommand\"\n ),\n doctor: lazyCommand(\n commandMeta.doctor,\n () => import(\"./commands/doctor.ts\"),\n \"doctorCommand\"\n ),\n eject: lazyCommand(\n commandMeta.eject,\n () => import(\"./commands/eject.ts\"),\n \"ejectCommand\"\n ),\n eval: lazyCommand(\n commandMeta.eval,\n () => import(\"./commands/eval.ts\"),\n \"evalCommand\"\n ),\n init: lazyCommand(\n commandMeta.init,\n () => import(\"./commands/init.ts\"),\n \"initCommand\"\n ),\n \"mcp-stdio\": lazyCommand(\n commandMeta[\"mcp-stdio\"],\n () => import(\"./commands/mcp-stdio.ts\"),\n \"mcpStdioCommand\"\n ),\n migrate: lazyCommand(\n commandMeta.migrate,\n () => import(\"./commands/migrate.ts\"),\n \"migrateCommand\"\n ),\n preview: lazyCommand(\n commandMeta.preview,\n () => import(\"./commands/preview.ts\"),\n \"previewCommand\"\n ),\n sync: lazyCommand(\n commandMeta.sync,\n () => import(\"./commands/sync.ts\"),\n \"syncCommand\"\n ),\n translate: lazyCommand(\n commandMeta.translate,\n () => import(\"./commands/translate.ts\"),\n \"translateCommand\"\n ),\n upgrade: lazyCommand(\n commandMeta.upgrade,\n () => import(\"./commands/upgrade.ts\"),\n \"upgradeCommand\"\n ),\n validate: lazyCommand(\n commandMeta.validate,\n () => import(\"./commands/validate.ts\"),\n \"validateCommand\"\n ),\n version: lazyCommand(\n commandMeta.version,\n () => import(\"./commands/version.ts\"),\n \"versionCommand\"\n ),\n },\n});\n\nloadEnvFiles(process.cwd());\n\nprocess.on(\"uncaughtException\", (error) => {\n reportInternalError(error);\n process.exit(1);\n});\nprocess.on(\"unhandledRejection\", (error) => {\n reportInternalError(error);\n process.exit(1);\n});\n\nrunMain(main, { rawArgs: normalizeHostArgs(process.argv.slice(2)) });\n",
6
6
  "import { readFileSync } from \"node:fs\";\n\nimport { join } from \"pathe\";\n\nimport { packageRoot } from \"./package-root.ts\";\n\nlet cached: string | undefined;\n\n/**\n * The installed Blume package version, read lazily from its `package.json`.\n *\n * Computed on demand (not at module load) so importing the `blume` barrel has no\n * filesystem side effect, and anchored at the package root so it resolves the\n * same whether running from source or the bundled CLI.\n */\nexport const getBlumeVersion = (): string => {\n if (cached === undefined) {\n const pkgPath = join(packageRoot(), \"package.json\");\n // SAFETY: this reads blume's own package.json, which always declares a\n // `version` (publishing requires it).\n cached = (JSON.parse(readFileSync(pkgPath, \"utf-8\")) as { version: string })\n .version;\n }\n return cached;\n};\n",
7
7
  "import { existsSync } from \"node:fs\";\n\nimport { dirname, join } from \"pathe\";\n\n/**\n * Walk up from `start` until a directory containing a `package.json` is found.\n *\n * Exported for testing; call sites should use {@link packageRoot}.\n */\nexport const findPackageRoot = (start: string): string => {\n let dir = start;\n while (!existsSync(join(dir, \"package.json\"))) {\n const parent = dirname(dir);\n if (parent === dir) {\n throw new Error(\"blume: unable to locate the package root\");\n }\n dir = parent;\n }\n return dir;\n};\n\nlet cached: string | undefined;\n\n/**\n * Absolute path to the installed Blume package root (the directory holding its\n * `package.json`), found by walking up from this module.\n *\n * Anchoring here — rather than at a fixed offset from `import.meta` — keeps the\n * package's own `src/`, assets, and `node_modules` locatable whether the code\n * runs from source under Bun (`src/...`) or from the published, bundled CLI\n * (`dist/cli/*.js`). The two layouts sit at different depths, so a relative\n * `../..` resolves to different places; locating `package.json` does not.\n */\nexport const packageRoot = (): string => {\n cached ??= findPackageRoot(import.meta.dirname);\n return cached;\n};\n",
8
- "import type { CommandMeta } from \"citty\";\n\n/**\n * Every command's `meta`, held apart from the command modules themselves.\n *\n * The CLI entry loads each command lazily (see `lazy-command.ts`), but citty\n * still reads every subcommand's `meta` to render `blume --help` and to match\n * an unknown name against aliases. Keeping that table here lets those paths\n * run without importing a single command module — `dev` alone drags in Astro,\n * `mcp-stdio` the MCP SDK. The command modules read their `meta` from this\n * table too, so the entry and the command can't drift.\n */\nexport const commandMeta = {\n add: {\n description: \"Install a source component or template from the registry.\",\n name: \"add\",\n },\n audit: {\n description: \"Audit the built site for SEO and site-health issues.\",\n name: \"audit\",\n },\n build: {\n description: \"Build the docs site for production.\",\n name: \"build\",\n },\n check: {\n description: \"Type-check the docs site with astro check.\",\n name: \"check\",\n },\n dev: {\n description: \"Start the Blume development server.\",\n name: \"dev\",\n },\n doctor: {\n description: \"Diagnose common configuration and content problems.\",\n name: \"doctor\",\n },\n eject: {\n description: \"Promote the generated runtime into an owned Astro project.\",\n name: \"eject\",\n },\n eval: {\n description:\n \"Test the docs: an agent answers your questions using only the documentation.\",\n name: \"eval\",\n },\n init: {\n description: \"Scaffold a minimal Blume project.\",\n name: \"init\",\n },\n \"mcp-stdio\": {\n description:\n \"Serve an MCP data snapshot over stdio (internal, used by `blume eval`).\",\n name: \"mcp-stdio\",\n },\n preview: {\n description: \"Preview the last production build.\",\n name: \"preview\",\n },\n sync: {\n description: \"Re-fetch remote content sources and regenerate the runtime.\",\n name: \"sync\",\n },\n translate: {\n description:\n \"Translate docs into the configured locales with a local agent CLI.\",\n name: \"translate\",\n },\n validate: {\n description: \"Validate internal, anchor, asset, and external links.\",\n name: \"validate\",\n },\n version: {\n description: \"Freeze the current docs as an archived version.\",\n name: \"version\",\n },\n} satisfies Record<string, CommandMeta>;\n",
8
+ "import type { CommandMeta } from \"citty\";\n\n/**\n * Every command's `meta`, held apart from the command modules themselves.\n *\n * The CLI entry loads each command lazily (see `lazy-command.ts`), but citty\n * still reads every subcommand's `meta` to render `blume --help` and to match\n * an unknown name against aliases. Keeping that table here lets those paths\n * run without importing a single command module — `dev` alone drags in Astro,\n * `mcp-stdio` the MCP SDK. The command modules read their `meta` from this\n * table too, so the entry and the command can't drift.\n */\nexport const commandMeta = {\n add: {\n description: \"Install a source component or template from the registry.\",\n name: \"add\",\n },\n audit: {\n description: \"Audit the built site for SEO and site-health issues.\",\n name: \"audit\",\n },\n build: {\n description: \"Build the docs site for production.\",\n name: \"build\",\n },\n check: {\n description: \"Type-check the docs site with astro check.\",\n name: \"check\",\n },\n dev: {\n description: \"Start the Blume development server.\",\n name: \"dev\",\n },\n doctor: {\n description: \"Diagnose common configuration and content problems.\",\n name: \"doctor\",\n },\n eject: {\n description: \"Promote the generated runtime into an owned Astro project.\",\n name: \"eject\",\n },\n eval: {\n description:\n \"Test the docs: an agent answers your questions using only the documentation.\",\n name: \"eval\",\n },\n init: {\n description: \"Scaffold a minimal Blume project.\",\n name: \"init\",\n },\n \"mcp-stdio\": {\n description:\n \"Serve an MCP data snapshot over stdio (internal, used by `blume eval`).\",\n name: \"mcp-stdio\",\n },\n migrate: {\n description:\n \"Migrate a docs site from Mintlify, Fumadocs, Docusaurus, Starlight, or Nextra with a coding agent.\",\n name: \"migrate\",\n },\n preview: {\n description: \"Preview the last production build.\",\n name: \"preview\",\n },\n sync: {\n description: \"Re-fetch remote content sources and regenerate the runtime.\",\n name: \"sync\",\n },\n translate: {\n description:\n \"Translate docs into the configured locales with a local agent CLI.\",\n name: \"translate\",\n },\n upgrade: {\n description:\n \"Upgrade to this version of Blume: bump the dependency and list the config changes left.\",\n name: \"upgrade\",\n },\n validate: {\n description: \"Validate internal, anchor, asset, and external links.\",\n name: \"validate\",\n },\n version: {\n description: \"Freeze the current docs as an archived version.\",\n name: \"version\",\n },\n} satisfies Record<string, CommandMeta>;\n",
9
9
  "import { existsSync } from \"node:fs\";\n\nimport { config } from \"dotenv\";\nimport { dirname, join, resolve } from \"pathe\";\n\n// Blume's remote sources (GitHub Releases, mdx-remote, Sanity, Notion…) read\n// their tokens from `process.env` during the content scan — which runs before\n// Astro/Vite boots, so Vite's own `.env` loading is too late. This loader fills\n// that gap: it cascades `.env`/`.env.local` from the working dir up to the repo\n// root, so a monorepo can keep one `.env` at the root and every app picks it up.\n\n/**\n * Load `.env`/`.env.local`, cascading from `startDir` up to the repository root\n * (the first ancestor containing a `.git`) or the filesystem root. The ordered\n * path list is handed to dotenv, whose `config` is first-wins, never clobbers\n * existing `process.env` values, and treats unreadable files as best-effort —\n * so shell/CI overrides are never lost, `.env.local` layers over `.env`, and a\n * bad file never aborts a build. dotenv is also the parser Vite runs over\n * these files at build time, so a value means the same thing to the pre-boot\n * content scan and the built site — including multi-line double-quoted values\n * (PEM keys), which a line-based parser silently truncates.\n */\nexport const loadEnvFiles = (startDir: string): void => {\n const paths: string[] = [];\n let dir = resolve(startDir);\n let done = false;\n while (!done) {\n paths.push(join(dir, \".env.local\"), join(dir, \".env\"));\n const parent = dirname(dir);\n // Stop at the repo root (nearest `.git`) or the filesystem root.\n done = existsSync(join(dir, \".git\")) || parent === dir;\n dir = parent;\n }\n config({ path: paths, quiet: true });\n};\n",
10
10
  "/**\n * Rewrite a bare `--host` in the raw argv to `--host=` before citty parses it.\n *\n * `host` is a string arg (citty has no mixed string/boolean type), and citty\n * 0.2 parses with `node:util.parseArgs`, where a string option consumes the\n * next token as its value even when that token is another flag: `blume dev\n * --host --open` would bind the literal hostname \"--open\" and drop `--open`.\n * The `--host=` spelling parses as `\"\"` without touching its neighbor, which\n * `normalizeHost` then maps to Astro's \"bind all interfaces\".\n */\nexport const normalizeHostArgs = (rawArgs: readonly string[]): string[] =>\n rawArgs.map((arg, index) => {\n if (arg !== \"--host\") {\n return arg;\n }\n const next = rawArgs[index + 1];\n return next === undefined || next.startsWith(\"-\") ? \"--host=\" : arg;\n });\n\n/**\n * Resolve a `--host` flag value into what Astro/Vite's `server.host` expects.\n * citty has no mixed string/boolean arg type, so `host` is declared as a\n * string and a bare `--host` parses as `\"\"` (`normalizeHostArgs` rewrites it\n * to `--host=` first) — Node would bind all interfaces for `\"\"`, but Vite's\n * `resolveHostname` treats it as a literal hostname and prints malformed URLs\n * like `http://:4321/`. Match Astro's own `--host` semantics instead: bare\n * flag → `true` (bind all interfaces), `--host 10.0.0.1` → that address,\n * absent → `false` (localhost only).\n *\n * Lives beside `normalizeHostArgs` rather than in `commands/dev.ts` so\n * `preview` can share it without importing the whole dev command graph.\n */\nexport const normalizeHost = (host?: string): boolean | string =>\n host === \"\" ? true : (host ?? false);\n",
11
11
  "import { colors } from \"consola/utils\";\n\nimport { getBlumeVersion } from \"../core/version.ts\";\n\nconst ISSUES_URL = \"https://github.com/haydenbleasel/blume/issues\";\n\n// Absolute paths into the hidden generated runtime — POSIX (`…/.blume/…`) or\n// Windows drive-letter (`C:\\…\\.blume\\…`) — including any trailing `:line:col`,\n// stopping at whitespace or a closing paren.\nconst BLUME_FRAME =\n /(?<abs>(?:\\/[^\\s()]*\\/|[A-Za-z]:\\\\[^\\s()]*\\\\)\\.blume[/\\\\][^\\s()]*)/gu;\n\n// The separator immediately before `.blume/` (or `.blume\\`) in a matched path.\nconst BLUME_MARKER = /[/\\\\]\\.blume[/\\\\]/u;\n\n/**\n * Rewrite `.blume/` frames in a stack so the generated runtime reads clearly:\n * the machine-absolute prefix is dropped to a project-relative `.blume/…` path\n * and tagged `(generated)`, keeping the reader oriented instead of staring at a\n * long path into a hidden directory. Frames in the user's own source (custom\n * pages keep their real location; wrappers import user files by their real path)\n * are untouched, so the actionable frame stays intact.\n */\nexport const remapBlumeStack = (stack: string): string =>\n stack.replaceAll(BLUME_FRAME, (match) => {\n const marker = match.search(BLUME_MARKER);\n return `${match.slice(marker + 1)} (generated)`;\n });\n\n/**\n * Print an unexpected (non-{@link BlumeError}) failure in a stable, reportable\n * shape instead of a bare stack trace: a fixed `BLUME_INTERNAL` code, the\n * message, a trimmed stack, and an environment dump for bug reports. Callers\n * exit after this — it doesn't exit itself, so it's testable.\n */\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- last-resort handler for whatever a catch clause caught; anything narrower would force casts at every call site\nexport const reportInternalError = (error: unknown): void => {\n const err = error instanceof Error ? error : new Error(String(error));\n const lines = [\n `${colors.red(colors.bold(\"BLUME_INTERNAL\"))} An unexpected error occurred.`,\n ` ${err.message}`,\n ];\n\n // A few frames are enough to locate the fault without burying the report;\n // `.blume/` frames are relativized so the hidden runtime reads clearly.\n const stack = remapBlumeStack(err.stack ?? \"\")\n .split(\"\\n\")\n .slice(1, 5)\n .map((line) => line.trim())\n .filter(Boolean);\n if (stack.length > 0) {\n lines.push(\"\", colors.dim(stack.join(\"\\n\")));\n }\n\n lines.push(\n \"\",\n \"This is likely a bug in Blume. Please report it with the details below:\",\n colors.dim(\n [\n ` Blume: ${getBlumeVersion()}`,\n ` Node: ${process.version}`,\n ` Platform: ${process.platform} ${process.arch}`,\n ].join(\"\\n\")\n ),\n ` ${ISSUES_URL}`\n );\n\n process.stderr.write(`${lines.join(\"\\n\")}\\n`);\n};\n",
12
- "import type { ArgsDef, CommandDef, CommandMeta } from \"citty\";\n\n/**\n * Wrap a command so its module is imported only when citty needs its `args`\n * or runs it. `meta` stays static (from `command-meta.ts`), so rendering root\n * usage, matching an unknown name, and `blume <cmd> --help` for *another*\n * command never touch this one's dependency graph.\n *\n * `load` imports the command's module and `key` names its export, so the call\n * site stays a plain `() => import(\"./commands/x.ts\")`.\n *\n * Only `args`, `setup`, `run`, and `cleanup` are forwarded: no Blume command\n * declares `default`, `plugins`, or nested `subCommands`.\n */\nexport const lazyCommand = <Args extends ArgsDef, Key extends string>(\n meta: CommandMeta,\n load: () => Promise<Record<Key, CommandDef<Args>>>,\n key: Key\n): CommandDef<Args> => {\n const command = async () => {\n const module = await load();\n return module[key];\n };\n return {\n args: async () => {\n const { args } = await command();\n // SAFETY: every Blume command passes `args` to `defineCommand` as a plain\n // object literal (the \"command registry\" test checks it); citty's\n // `Resolvable` widening is the only reason the type also admits a thunk\n // or a promise here.\n return args as Args;\n },\n cleanup: async (context) => {\n const loaded = await command();\n await loaded.cleanup?.(context);\n },\n meta,\n run: async (context) => {\n const loaded = await command();\n await loaded.run?.(context);\n },\n setup: async (context) => {\n const loaded = await command();\n await loaded.setup?.(context);\n },\n };\n};\n",
12
+ "import { colors } from \"consola/utils\";\nimport { relative } from \"pathe\";\nimport type { ZodError } from \"zod\";\n\nimport type { Diagnostic } from \"./types.ts\";\n\n/** A recoverable error carrying a structured diagnostic. */\nexport class BlumeError extends Error {\n readonly diagnostic: Diagnostic;\n\n constructor(diagnostic: Diagnostic) {\n super(diagnostic.message);\n this.name = \"BlumeError\";\n this.diagnostic = diagnostic;\n }\n}\n\nexport const createDiagnostic = (diagnostic: Diagnostic): Diagnostic =>\n diagnostic;\n\n/** Docs site base; diagnostic help links resolve against it. */\nconst DOCS_BASE = \"https://useblume.dev\";\n\nconst DOCS_DEPLOYMENT = \"/docs/deployment\";\nconst DOCS_CLI_VALIDATE = \"/docs/cli/validate\";\nconst DOCS_CONTENT_SOURCES = \"/docs/content/sources\";\nconst DOCS_CONTENT_NAVIGATION = \"/docs/content/navigation\";\nconst DOCS_CONTENT_INCLUDES = \"/docs/content/includes\";\n\n/** Diagnostic code → the docs page that explains it. */\nconst DOCS_PATHS = new Map(\n Object.entries({\n BLUME_ADAPTER_REQUIRED: DOCS_DEPLOYMENT,\n BLUME_ASSETS_UNCHECKED: DOCS_CLI_VALIDATE,\n BLUME_ASSET_FETCH_FAILED: DOCS_CONTENT_SOURCES,\n BLUME_BROKEN_ANCHOR: DOCS_CLI_VALIDATE,\n BLUME_BROKEN_ASSET: DOCS_CLI_VALIDATE,\n BLUME_BROKEN_LINK: DOCS_CLI_VALIDATE,\n BLUME_COMPONENTS_INVALID: \"/docs/configuration/customization\",\n BLUME_CONFIG_INVALID: \"/docs/configuration\",\n BLUME_CONFIG_LOAD_FAILED: \"/docs/configuration\",\n BLUME_CONTENT_ROOT_MISSING: DOCS_CONTENT_SOURCES,\n BLUME_DEAD_LINK: DOCS_CLI_VALIDATE,\n BLUME_DEPENDENCY_MISSING: \"/docs/cli/doctor\",\n BLUME_DUPLICATE_ROUTE: DOCS_CONTENT_NAVIGATION,\n BLUME_DUPLICATE_SIDEBAR_ORDER: DOCS_CONTENT_NAVIGATION,\n BLUME_FRONTMATTER_INVALID: \"/docs/content/frontmatter\",\n BLUME_INCLUDE_CYCLE: DOCS_CONTENT_INCLUDES,\n BLUME_INCLUDE_MALFORMED: DOCS_CONTENT_INCLUDES,\n BLUME_INCLUDE_NOT_FOUND: DOCS_CONTENT_INCLUDES,\n BLUME_INCLUDE_OUTSIDE_ROOT: DOCS_CONTENT_INCLUDES,\n BLUME_MDX_CURLY_ANCHOR: \"/docs/content/syntax\",\n\n BLUME_META_INVALID: \"/docs/content/meta\",\n BLUME_META_LOAD_FAILED: \"/docs/content/meta\",\n BLUME_MISSING_SECRET: DOCS_DEPLOYMENT,\n BLUME_NAV_DUPLICATE_LABEL: DOCS_CONTENT_NAVIGATION,\n BLUME_NAV_HIDDEN_IN_SIDEBAR: DOCS_CONTENT_NAVIGATION,\n BLUME_NAV_INDEX_TITLE_MISMATCH: DOCS_CONTENT_NAVIGATION,\n BLUME_NAV_MISSING_PAGE: DOCS_CONTENT_NAVIGATION,\n BLUME_NODE_VERSION: \"/docs/quickstart\",\n BLUME_SERVER_FEATURE_REQUIRED: DOCS_DEPLOYMENT,\n BLUME_SIDEBAR_DISPLAY_IGNORED: DOCS_CONTENT_NAVIGATION,\n BLUME_SOURCE_FETCH_FAILED: DOCS_CONTENT_SOURCES,\n BLUME_SOURCE_MISCONFIGURED: DOCS_CONTENT_SOURCES,\n BLUME_SOURCE_OFFLINE: DOCS_CONTENT_SOURCES,\n BLUME_SOURCE_SDK_MISSING: DOCS_CONTENT_SOURCES,\n BLUME_SOURCE_UNAVAILABLE: DOCS_CONTENT_SOURCES,\n BLUME_TRANSLATE_MISSING: \"/docs/cli/translate\",\n BLUME_TRANSLATE_STALE: \"/docs/cli/translate\",\n BLUME_UNKNOWN_COMPONENT: \"/docs/configuration/customization\",\n BLUME_UNKNOWN_ICON: DOCS_CONTENT_NAVIGATION,\n BLUME_UNKNOWN_OPTION: \"/docs/cli\",\n BLUME_WIKILINK_AMBIGUOUS: DOCS_CONTENT_SOURCES,\n BLUME_WIKILINK_UNRESOLVED: DOCS_CONTENT_SOURCES,\n BLUME_YARN_PNP: \"/docs/quickstart\",\n })\n);\n\n/** The docs URL that explains a diagnostic code, if one is mapped. */\nexport const resolveDocsUrl = (code: string): string | undefined => {\n const path = DOCS_PATHS.get(code);\n return path ? `${DOCS_BASE}${path}` : undefined;\n};\n\n/** Fill in `docsUrl` from the code map where a diagnostic doesn't set its own. */\nexport const enrichDiagnostic = (diagnostic: Diagnostic): Diagnostic =>\n diagnostic.docsUrl\n ? diagnostic\n : { ...diagnostic, docsUrl: resolveDocsUrl(diagnostic.code) };\n\nconst REGEXP_SPECIAL = /[$()*+.?[\\\\\\]^{|}]/gu;\nconst escapeRegExp = (value: string): string =>\n value.replaceAll(REGEXP_SPECIAL, String.raw`\\$&`);\n\n/** A key segment scans the source text; an array index has no key to find. */\nconst isKeySegment = (segment: string | number): segment is string =>\n typeof segment === \"string\";\n\n/**\n * Best-effort source position for a Zod issue path (e.g. `[\"seo\", \"title\"]`) in\n * the raw config / frontmatter text. Narrows key-by-key — finding each string\n * segment as a `key:`/`key =` at or after the previous match — so a nested key\n * lands under its parent. Array indices are skipped. Returns 1-based line/column,\n * or undefined when nothing matches.\n */\nconst stepSegment = (\n source: string,\n segment: string | number,\n cursor: number\n) => {\n // A non-string path segment (array index) is skipped without moving on.\n if (!isKeySegment(segment)) {\n return { index: -1, next: cursor, stop: false };\n }\n // The negative lookbehind keeps a segment like `title` from matching the\n // tail of an unrelated key such as `subtitle:`.\n const matcher = new RegExp(\n `(?<![\\\\w$])${escapeRegExp(segment)}\\\\s*[:=]`,\n \"gu\"\n );\n matcher.lastIndex = cursor;\n const match = matcher.exec(source);\n if (!match) {\n return { index: -1, next: cursor, stop: true };\n }\n return { index: match.index, next: matcher.lastIndex, stop: false };\n};\n\nconst locatePath = (\n source: string,\n path: readonly (string | number)[]\n): { column: number; line: number } | undefined => {\n let cursor = 0;\n let found = -1;\n for (const segment of path) {\n const step = stepSegment(source, segment, cursor);\n if (step.stop) {\n break;\n }\n cursor = step.next;\n if (step.index >= 0) {\n found = step.index;\n }\n }\n if (found < 0) {\n return;\n }\n const before = source.slice(0, found);\n const lastNewline = before.lastIndexOf(\"\\n\");\n return { column: found - lastNewline, line: before.split(\"\\n\").length };\n};\n\n/** The YAML front matter block of a `.md`/`.mdx` source, if it has one. */\nconst FRONTMATTER = /^---\\r?\\n(?<body>[\\s\\S]*?)\\r?\\n---/u;\n\n/**\n * Locate a front matter key in a content file, e.g. `[\"seo\", \"description\"]` in\n * `docs/api.mdx`. Scoped to the front matter block so a `title:` written in the\n * page body can't be mistaken for the front matter key of the same name; returns\n * undefined when the file has no front matter or the key isn't set (a missing\n * key has no line to point at — callers anchor to the file instead).\n */\nexport const locateFrontmatterKey = (\n source: string,\n path: readonly (string | number)[]\n): { column: number; line: number } | undefined => {\n const block = FRONTMATTER.exec(source);\n if (!block) {\n return;\n }\n // `locatePath` reports lines 1-based within the text it was given, and the\n // front matter body starts one line below the opening `---`.\n const position = locatePath(block.groups?.body ?? \"\", path);\n return position && { column: position.column, line: position.line + 1 };\n};\n\n/**\n * Convert generic validation issues (message + path, the shape shared by Zod\n * and Standard Schema issues) into Blume diagnostics, anchored to a file.\n */\nexport const diagnosticsFromIssues = (\n issues: readonly {\n message: string;\n path: readonly (string | number)[];\n }[],\n options: { code: string; file?: string; source?: string }\n): Diagnostic[] =>\n issues.map((issue) => {\n const schemaPath = issue.path.join(\".\");\n const position = options.source\n ? locatePath(options.source, issue.path)\n : undefined;\n return {\n code: options.code,\n column: position?.column,\n file: options.file,\n line: position?.line,\n message: schemaPath ? `${schemaPath}: ${issue.message}` : issue.message,\n schemaPath: schemaPath || undefined,\n severity: \"error\",\n } satisfies Diagnostic;\n });\n\n/** Convert a ZodError into Blume diagnostics, anchored to a file. */\nexport const diagnosticsFromZod = (\n error: ZodError,\n options: { code: string; file?: string; source?: string }\n): Diagnostic[] =>\n diagnosticsFromIssues(\n error.issues.map((issue) => ({\n message: issue.message,\n // Zod 4 paths are PropertyKey[]; a symbol segment has no place in a\n // dotted schema path or a source-position scan.\n path: issue.path.filter(\n (segment): segment is string | number => typeof segment !== \"symbol\"\n ),\n })),\n options\n );\n\nconst severityColor = (severity: Diagnostic[\"severity\"]) => {\n if (severity === \"error\") {\n return colors.red;\n }\n if (severity === \"warning\") {\n return colors.yellow;\n }\n return colors.blue;\n};\n\n/** Format a single diagnostic for terminal output. */\nexport const formatDiagnostic = (\n diagnostic: Diagnostic,\n root?: string\n): string => {\n const color = severityColor(diagnostic.severity);\n const lines: string[] = [\n `${color(colors.bold(diagnostic.code))} ${diagnostic.message}`,\n ];\n\n // An audit finding is about a built URL, and names the source file that fixes\n // it as a second line (\"at /docs/api\" / \"in docs/api.mdx:3:2\"). Everything\n // else is about a file alone, and keeps the original single `at file` line.\n if (diagnostic.url) {\n lines.push(` ${colors.dim(`at ${diagnostic.url}`)}`);\n }\n if (diagnostic.file) {\n const location = root ? relative(root, diagnostic.file) : diagnostic.file;\n const column =\n diagnostic.column === undefined ? \"\" : `:${diagnostic.column}`;\n const position =\n diagnostic.line === undefined ? \"\" : `:${diagnostic.line}${column}`;\n const label = diagnostic.url ? \"in\" : \"at\";\n lines.push(` ${colors.dim(`${label} ${location}${position}`)}`);\n }\n\n if (diagnostic.suggestion) {\n lines.push(` ${colors.cyan(`fix: ${diagnostic.suggestion}`)}`);\n }\n\n if (diagnostic.docsUrl) {\n lines.push(` ${colors.dim(`docs: ${diagnostic.docsUrl}`)}`);\n }\n\n return lines.join(\"\\n\");\n};\n\nexport const hasErrors = (diagnostics: Diagnostic[]): boolean =>\n diagnostics.some((d) => d.severity === \"error\");\n\nexport const countBySeverity = (diagnostics: Diagnostic[]) => {\n const counts = { error: 0, info: 0, warning: 0 } satisfies Record<\n Diagnostic[\"severity\"],\n number\n >;\n for (const diagnostic of diagnostics) {\n counts[diagnostic.severity] += 1;\n }\n return counts;\n};\n",
13
13
  "import { consola } from \"consola\";\nimport { relative } from \"pathe\";\n\nimport {\n countBySeverity,\n enrichDiagnostic,\n formatDiagnostic,\n hasErrors,\n} from \"../core/diagnostics.ts\";\nimport type { Diagnostic } from \"../core/types.ts\";\n\nexport const logger = consola.withTag(\"blume\");\n\n/**\n * Resolve once stdout has drained. `process.exit` doesn't flush a piped stdout,\n * so await this before exiting non-zero after writing machine-readable output\n * (e.g. `--json`), otherwise the payload can be truncated in CI.\n */\nexport const flushStdout = (): Promise<void> =>\n // oxlint-disable-next-line promise/avoid-new -- adapt stdout's write callback\n new Promise((resolve) => {\n process.stdout.write(\"\", () => resolve());\n });\n\n/**\n * Print diagnostics as a JSON document on stdout for CI and editors: each is\n * enriched with its `docsUrl` and its `file` made root-relative. Returns whether\n * any were errors, matching {@link reportDiagnostics}.\n */\nexport const reportDiagnosticsJson = (\n diagnostics: Diagnostic[],\n root?: string\n): boolean => {\n const enriched = diagnostics.map((diagnostic) => {\n const withDocs = enrichDiagnostic(diagnostic);\n return withDocs.file && root\n ? { ...withDocs, file: relative(root, withDocs.file) }\n : withDocs;\n });\n process.stdout.write(\n `${JSON.stringify(\n { diagnostics: enriched, summary: countBySeverity(diagnostics) },\n null,\n 2\n )}\\n`\n );\n return hasErrors(diagnostics);\n};\n\n/** Print a batch of diagnostics and return whether any were errors. */\nexport const reportDiagnostics = (\n diagnostics: Diagnostic[],\n root?: string\n): boolean => {\n if (diagnostics.length === 0) {\n return false;\n }\n\n for (const diagnostic of diagnostics) {\n process.stderr.write(\n `${formatDiagnostic(enrichDiagnostic(diagnostic), root)}\\n`\n );\n }\n\n const counts = countBySeverity(diagnostics);\n const summary = [\n counts.error ? `${counts.error} error(s)` : null,\n counts.warning ? `${counts.warning} warning(s)` : null,\n ]\n .filter(Boolean)\n .join(\", \");\n if (summary) {\n process.stderr.write(`\\n${summary}\\n`);\n }\n\n return hasErrors(diagnostics);\n};\n",
14
- "import { colors } from \"consola/utils\";\nimport { relative } from \"pathe\";\nimport type { ZodError } from \"zod\";\n\nimport type { Diagnostic } from \"./types.ts\";\n\n/** A recoverable error carrying a structured diagnostic. */\nexport class BlumeError extends Error {\n readonly diagnostic: Diagnostic;\n\n constructor(diagnostic: Diagnostic) {\n super(diagnostic.message);\n this.name = \"BlumeError\";\n this.diagnostic = diagnostic;\n }\n}\n\nexport const createDiagnostic = (diagnostic: Diagnostic): Diagnostic =>\n diagnostic;\n\n/** Docs site base; diagnostic help links resolve against it. */\nconst DOCS_BASE = \"https://useblume.dev\";\n\nconst DOCS_DEPLOYMENT = \"/docs/deployment\";\nconst DOCS_REFERENCE_CLI = \"/docs/reference/cli\";\nconst DOCS_CONTENT_SOURCES = \"/docs/content/sources\";\nconst DOCS_CONTENT_NAVIGATION = \"/docs/content/navigation\";\nconst DOCS_CONTENT_INCLUDES = \"/docs/content/includes\";\n\n/** Diagnostic code → the docs page that explains it. */\nconst DOCS_PATHS = new Map(\n Object.entries({\n BLUME_ADAPTER_REQUIRED: DOCS_DEPLOYMENT,\n BLUME_ASSETS_UNCHECKED: DOCS_REFERENCE_CLI,\n BLUME_ASSET_FETCH_FAILED: DOCS_CONTENT_SOURCES,\n BLUME_BROKEN_ANCHOR: DOCS_REFERENCE_CLI,\n BLUME_BROKEN_ASSET: DOCS_REFERENCE_CLI,\n BLUME_BROKEN_LINK: DOCS_REFERENCE_CLI,\n BLUME_CONFIG_INVALID: \"/docs/configuration\",\n BLUME_CONFIG_LOAD_FAILED: \"/docs/configuration\",\n BLUME_CONTENT_ROOT_MISSING: DOCS_CONTENT_SOURCES,\n BLUME_DEAD_LINK: DOCS_REFERENCE_CLI,\n BLUME_DUPLICATE_ROUTE: DOCS_CONTENT_NAVIGATION,\n BLUME_DUPLICATE_SIDEBAR_ORDER: DOCS_CONTENT_NAVIGATION,\n BLUME_FRONTMATTER_INVALID: \"/docs/reference/frontmatter\",\n BLUME_INCLUDE_CYCLE: DOCS_CONTENT_INCLUDES,\n BLUME_INCLUDE_NOT_FOUND: DOCS_CONTENT_INCLUDES,\n BLUME_INCLUDE_OUTSIDE_ROOT: DOCS_CONTENT_INCLUDES,\n BLUME_MDX_CURLY_ANCHOR: \"/docs/content/syntax\",\n\n BLUME_META_INVALID: \"/docs/content/meta\",\n BLUME_META_LOAD_FAILED: \"/docs/content/meta\",\n BLUME_MISSING_SECRET: DOCS_DEPLOYMENT,\n BLUME_NAV_DUPLICATE_LABEL: DOCS_CONTENT_NAVIGATION,\n BLUME_NAV_HIDDEN_IN_SIDEBAR: DOCS_CONTENT_NAVIGATION,\n BLUME_NAV_INDEX_TITLE_MISMATCH: DOCS_CONTENT_NAVIGATION,\n BLUME_NAV_MISSING_PAGE: DOCS_CONTENT_NAVIGATION,\n BLUME_NODE_VERSION: \"/docs/quickstart\",\n BLUME_SERVER_FEATURE_REQUIRED: DOCS_DEPLOYMENT,\n BLUME_SIDEBAR_DISPLAY_IGNORED: DOCS_CONTENT_NAVIGATION,\n BLUME_SOURCE_FETCH_FAILED: DOCS_CONTENT_SOURCES,\n BLUME_SOURCE_MISCONFIGURED: DOCS_CONTENT_SOURCES,\n BLUME_SOURCE_OFFLINE: DOCS_CONTENT_SOURCES,\n BLUME_SOURCE_SDK_MISSING: DOCS_CONTENT_SOURCES,\n BLUME_SOURCE_UNAVAILABLE: DOCS_CONTENT_SOURCES,\n BLUME_UNKNOWN_COMPONENT: \"/docs/configuration/customization\",\n BLUME_UNKNOWN_ICON: DOCS_CONTENT_NAVIGATION,\n BLUME_WIKILINK_AMBIGUOUS: DOCS_CONTENT_SOURCES,\n BLUME_WIKILINK_UNRESOLVED: DOCS_CONTENT_SOURCES,\n })\n);\n\n/** The docs URL that explains a diagnostic code, if one is mapped. */\nexport const resolveDocsUrl = (code: string): string | undefined => {\n const path = DOCS_PATHS.get(code);\n return path ? `${DOCS_BASE}${path}` : undefined;\n};\n\n/** Fill in `docsUrl` from the code map where a diagnostic doesn't set its own. */\nexport const enrichDiagnostic = (diagnostic: Diagnostic): Diagnostic =>\n diagnostic.docsUrl\n ? diagnostic\n : { ...diagnostic, docsUrl: resolveDocsUrl(diagnostic.code) };\n\nconst REGEXP_SPECIAL = /[$()*+.?[\\\\\\]^{|}]/gu;\nconst escapeRegExp = (value: string): string =>\n value.replaceAll(REGEXP_SPECIAL, String.raw`\\$&`);\n\n/** A key segment scans the source text; an array index has no key to find. */\nconst isKeySegment = (segment: string | number): segment is string =>\n typeof segment === \"string\";\n\n/**\n * Best-effort source position for a Zod issue path (e.g. `[\"seo\", \"title\"]`) in\n * the raw config / frontmatter text. Narrows key-by-key — finding each string\n * segment as a `key:`/`key =` at or after the previous match — so a nested key\n * lands under its parent. Array indices are skipped. Returns 1-based line/column,\n * or undefined when nothing matches.\n */\nconst stepSegment = (\n source: string,\n segment: string | number,\n cursor: number\n) => {\n // A non-string path segment (array index) is skipped without moving on.\n if (!isKeySegment(segment)) {\n return { index: -1, next: cursor, stop: false };\n }\n // The negative lookbehind keeps a segment like `title` from matching the\n // tail of an unrelated key such as `subtitle:`.\n const matcher = new RegExp(\n `(?<![\\\\w$])${escapeRegExp(segment)}\\\\s*[:=]`,\n \"gu\"\n );\n matcher.lastIndex = cursor;\n const match = matcher.exec(source);\n if (!match) {\n return { index: -1, next: cursor, stop: true };\n }\n return { index: match.index, next: matcher.lastIndex, stop: false };\n};\n\nconst locatePath = (\n source: string,\n path: readonly (string | number)[]\n): { column: number; line: number } | undefined => {\n let cursor = 0;\n let found = -1;\n for (const segment of path) {\n const step = stepSegment(source, segment, cursor);\n if (step.stop) {\n break;\n }\n cursor = step.next;\n if (step.index >= 0) {\n found = step.index;\n }\n }\n if (found < 0) {\n return;\n }\n const before = source.slice(0, found);\n const lastNewline = before.lastIndexOf(\"\\n\");\n return { column: found - lastNewline, line: before.split(\"\\n\").length };\n};\n\n/** The YAML front matter block of a `.md`/`.mdx` source, if it has one. */\nconst FRONTMATTER = /^---\\r?\\n(?<body>[\\s\\S]*?)\\r?\\n---/u;\n\n/**\n * Locate a front matter key in a content file, e.g. `[\"seo\", \"description\"]` in\n * `docs/api.mdx`. Scoped to the front matter block so a `title:` written in the\n * page body can't be mistaken for the front matter key of the same name; returns\n * undefined when the file has no front matter or the key isn't set (a missing\n * key has no line to point at — callers anchor to the file instead).\n */\nexport const locateFrontmatterKey = (\n source: string,\n path: readonly (string | number)[]\n): { column: number; line: number } | undefined => {\n const block = FRONTMATTER.exec(source);\n if (!block) {\n return;\n }\n // `locatePath` reports lines 1-based within the text it was given, and the\n // front matter body starts one line below the opening `---`.\n const position = locatePath(block.groups?.body ?? \"\", path);\n return position && { column: position.column, line: position.line + 1 };\n};\n\n/**\n * Convert generic validation issues (message + path, the shape shared by Zod\n * and Standard Schema issues) into Blume diagnostics, anchored to a file.\n */\nexport const diagnosticsFromIssues = (\n issues: readonly {\n message: string;\n path: readonly (string | number)[];\n }[],\n options: { code: string; file?: string; source?: string }\n): Diagnostic[] =>\n issues.map((issue) => {\n const schemaPath = issue.path.join(\".\");\n const position = options.source\n ? locatePath(options.source, issue.path)\n : undefined;\n return {\n code: options.code,\n column: position?.column,\n file: options.file,\n line: position?.line,\n message: schemaPath ? `${schemaPath}: ${issue.message}` : issue.message,\n schemaPath: schemaPath || undefined,\n severity: \"error\",\n } satisfies Diagnostic;\n });\n\n/** Convert a ZodError into Blume diagnostics, anchored to a file. */\nexport const diagnosticsFromZod = (\n error: ZodError,\n options: { code: string; file?: string; source?: string }\n): Diagnostic[] =>\n diagnosticsFromIssues(\n error.issues.map((issue) => ({\n message: issue.message,\n // Zod 4 paths are PropertyKey[]; a symbol segment has no place in a\n // dotted schema path or a source-position scan.\n path: issue.path.filter(\n (segment): segment is string | number => typeof segment !== \"symbol\"\n ),\n })),\n options\n );\n\nconst severityColor = (severity: Diagnostic[\"severity\"]) => {\n if (severity === \"error\") {\n return colors.red;\n }\n if (severity === \"warning\") {\n return colors.yellow;\n }\n return colors.blue;\n};\n\n/** Format a single diagnostic for terminal output. */\nexport const formatDiagnostic = (\n diagnostic: Diagnostic,\n root?: string\n): string => {\n const color = severityColor(diagnostic.severity);\n const lines: string[] = [\n `${color(colors.bold(diagnostic.code))} ${diagnostic.message}`,\n ];\n\n // An audit finding is about a built URL, and names the source file that fixes\n // it as a second line (\"at /docs/api\" / \"in docs/api.mdx:3:2\"). Everything\n // else is about a file alone, and keeps the original single `at file` line.\n if (diagnostic.url) {\n lines.push(` ${colors.dim(`at ${diagnostic.url}`)}`);\n }\n if (diagnostic.file) {\n const location = root ? relative(root, diagnostic.file) : diagnostic.file;\n const column =\n diagnostic.column === undefined ? \"\" : `:${diagnostic.column}`;\n const position =\n diagnostic.line === undefined ? \"\" : `:${diagnostic.line}${column}`;\n const label = diagnostic.url ? \"in\" : \"at\";\n lines.push(` ${colors.dim(`${label} ${location}${position}`)}`);\n }\n\n if (diagnostic.suggestion) {\n lines.push(` ${colors.cyan(`fix: ${diagnostic.suggestion}`)}`);\n }\n\n if (diagnostic.docsUrl) {\n lines.push(` ${colors.dim(`docs: ${diagnostic.docsUrl}`)}`);\n }\n\n return lines.join(\"\\n\");\n};\n\nexport const hasErrors = (diagnostics: Diagnostic[]): boolean =>\n diagnostics.some((d) => d.severity === \"error\");\n\nexport const countBySeverity = (diagnostics: Diagnostic[]) => {\n const counts = { error: 0, info: 0, warning: 0 } satisfies Record<\n Diagnostic[\"severity\"],\n number\n >;\n for (const diagnostic of diagnostics) {\n counts[diagnostic.severity] += 1;\n }\n return counts;\n};\n"
14
+ "import type { ArgsDef } from \"citty\";\n\nimport type { Diagnostic } from \"../core/types.ts\";\n\n/** A flag the command doesn't declare, with the declared one it most resembles. */\nexport interface UnknownFlag {\n /** The flag as typed, without any `=value`. */\n flag: string;\n /** The closest declared flag (`--isolated` for `--isolatd`), if one is close. */\n suggestion?: string;\n}\n\n/** What a declared option spelling means for the token that follows it. */\ninterface KnownFlag {\n /** Whether it's a boolean switch, which `--no-<name>` turns off. */\n boolean: boolean;\n /**\n * How the flags a command takes list it: `--kebab-name`, or `--no-<name>`\n * for a boolean that's on by default, since that's the form anyone types.\n */\n display: string;\n /** The canonical kebab-case name, which typos are matched against. */\n name: string;\n /** Whether it reads the next token as its value (`--port 4000`). */\n takesValue: boolean;\n}\n\n/** `budgetJs` → `budget-js`; a name already in kebab case is unchanged. */\nconst kebabCase = (name: string): string =>\n name.replaceAll(/(?<upper>[A-Z])/gu, (letter) => `-${letter.toLowerCase()}`);\n\n/** `budget-js` → `budgetJs`; a name already in camel case is unchanged. */\nconst camelCase = (name: string): string =>\n name.replaceAll(/-(?<letter>[a-z])/gu, (match) =>\n match.slice(1).toUpperCase()\n );\n\nconst aliasesOf = (alias: string | string[] | undefined): string[] => {\n if (alias === undefined) {\n return [];\n }\n return Array.isArray(alias) ? alias : [alias];\n};\n\n/**\n * Every spelling citty accepts for each declared option — the name, its camel\n * and kebab forms, and its aliases — mapped to what that option is. Positional\n * arguments aren't flags and don't appear.\n */\nconst knownFlags = (argsDef: ArgsDef): Map<string, KnownFlag> => {\n const flags = new Map<string, KnownFlag>();\n for (const [name, def] of Object.entries(argsDef)) {\n if (def.type === \"positional\") {\n continue;\n }\n const kebab = kebabCase(name);\n const boolean = def.type === \"boolean\";\n const onByDefault = boolean && \"default\" in def && def.default === true;\n const flag = {\n boolean,\n display: onByDefault ? `--no-${kebab}` : `--${kebab}`,\n name: kebab,\n takesValue: def.type === \"string\" || def.type === \"enum\",\n };\n for (const spelling of [\n name,\n kebabCase(name),\n camelCase(name),\n ...aliasesOf(\"alias\" in def ? def.alias : undefined),\n ]) {\n flags.set(spelling, flag);\n }\n }\n return flags;\n};\n\n/** Edit distance between two short strings (insertions, deletions, swaps of one letter). */\nconst distance = (from: string, to: string): number => {\n let previous = Array.from({ length: to.length + 1 }, (_, index) => index);\n for (const [row, fromChar] of [...from].entries()) {\n const current = [row + 1];\n for (const [column, toChar] of [...to].entries()) {\n current.push(\n Math.min(\n (previous[column + 1] ?? 0) + 1,\n (current[column] ?? 0) + 1,\n (previous[column] ?? 0) + (fromChar === toChar ? 0 : 1)\n )\n );\n }\n previous = current;\n }\n return previous[to.length] ?? 0;\n};\n\n/**\n * The candidate closest to `name`, when it's close enough to be the likely\n * intent: at most two edits away, and fewer edits than half the candidate's\n * length, so a short typo doesn't \"suggest\" an unrelated short word.\n */\nexport const closestMatch = (\n name: string,\n candidates: readonly string[]\n): string | undefined => {\n let best: { candidate: string; edits: number } | undefined;\n for (const candidate of candidates) {\n const edits = distance(name, candidate);\n if (\n edits <= 2 &&\n edits * 2 < candidate.length &&\n (best === undefined || edits < best.edits)\n ) {\n best = { candidate, edits };\n }\n }\n return best?.candidate;\n};\n\n/** A `--name`, `--no-name`, `--name=value`, or `-n` token, taken apart. */\ninterface FlagToken {\n /** Whether it carries its value inline (`--port=4000`). */\n hasValue: boolean;\n /** `--name` rather than `-n`. */\n long: boolean;\n /** The name as typed, without dashes or `=value`. */\n name: string;\n /** The negated flag's name, for a `--no-name` token. */\n negated: string | undefined;\n}\n\nconst parseToken = (arg: string): FlagToken => {\n const long = arg.startsWith(\"--\");\n const [name = \"\"] = arg.slice(long ? 2 : 1).split(\"=\");\n return {\n hasValue: arg.includes(\"=\"),\n long,\n name,\n negated: long && name.startsWith(\"no-\") ? name.slice(3) : undefined,\n };\n};\n\n/**\n * How many tokens after this one a declared flag consumes — one for a string\n * flag's separate value (`--port 4000`, read whatever it looks like, as\n * citty's parser does), none otherwise — or undefined when the token names no\n * declared flag. A negation never reads a value; grouped single-letter\n * booleans (`-ab`) are declared when every letter is.\n */\nconst declaredWidth = (\n token: FlagToken,\n flags: Map<string, KnownFlag>\n): number | undefined => {\n const known =\n flags.get(token.name) ??\n (token.negated === undefined ? undefined : flags.get(token.negated));\n if (known) {\n return known.takesValue && !token.hasValue && token.negated === undefined\n ? 1\n : 0;\n }\n const grouped =\n !token.long &&\n token.name.length > 1 &&\n [...token.name].every((letter) => flags.get(letter)?.takesValue === false);\n return grouped ? 0 : undefined;\n};\n\n/**\n * An undeclared token as reported, with the declared flag it most resembles.\n * A mistyped negation keeps its `no-` in the suggestion (`--no-instal` →\n * `--no-install`), so the fix doesn't flip what was asked for; negating a flag\n * that takes a value means nothing, so those suggest the flag itself.\n */\nconst describeUnknown = (\n token: FlagToken,\n flags: Map<string, KnownFlag>\n): UnknownFlag => {\n const unknown: UnknownFlag = {\n flag: `${token.long ? \"--\" : \"-\"}${token.name}`,\n };\n const names = [...new Set([...flags.values()].map((flag) => flag.name))];\n const match = closestMatch(token.negated ?? token.name, names);\n if (match) {\n const negate = token.negated !== undefined && flags.get(match)?.boolean;\n unknown.suggestion = negate ? `--no-${match}` : `--${match}`;\n }\n return unknown;\n};\n\n/**\n * The flags in `rawArgs` that the command's `args` don't declare. citty itself\n * accepts any flag and drops the ones it doesn't know, so a typo like\n * `--isolatd` would silently run a different command than the one intended.\n *\n * Mirrors what citty accepts: every spelling from {@link knownFlags}, a\n * `--no-<flag>` negation of any of them, `--flag=value`, a declared string\n * flag's separate value token, grouped single-letter boolean aliases, and\n * everything after a bare `--`. `accepted` names extra flags the command\n * handles itself (the removed `blume build --adapter`, which gets its own\n * migration message).\n */\nexport const unknownFlags = (\n rawArgs: readonly string[],\n argsDef: ArgsDef,\n accepted: readonly string[] = []\n): UnknownFlag[] => {\n const flags = knownFlags(argsDef);\n const unknown: UnknownFlag[] = [];\n for (let index = 0; index < rawArgs.length; index += 1) {\n const arg = rawArgs[index] ?? \"\";\n if (arg === \"--\") {\n break;\n }\n if (!arg.startsWith(\"-\") || arg === \"-\") {\n continue;\n }\n const token = parseToken(arg);\n const width = declaredWidth(token, flags);\n if (width !== undefined) {\n index += width;\n } else if (!accepted.includes(token.negated ?? token.name)) {\n unknown.push(describeUnknown(token, flags));\n }\n }\n return unknown;\n};\n\n/**\n * Flags a command reads from its raw arguments itself instead of declaring\n * them, keyed by command name. `blume build` answers the Blume 1 `--adapter`,\n * `--output`, and `--base` with the `deployment` setting that replaced each,\n * which says more than \"unknown option\" would.\n */\nexport const COMMAND_HANDLED_FLAGS = new Map([\n [\"build\", [\"adapter\", \"output\", \"base\"]],\n]);\n\n/**\n * The error for a command run with flags it doesn't declare: each unknown\n * flag (with its likely intended spelling), then every flag the command does\n * take, so the fix is on screen without a trip to `--help`.\n */\nexport const unknownFlagsDiagnostic = (\n command: string,\n unknown: readonly UnknownFlag[],\n argsDef: ArgsDef\n): Diagnostic => {\n const listed = unknown\n .map(({ flag, suggestion }) =>\n suggestion ? `${flag} (did you mean ${suggestion}?)` : flag\n )\n .join(\", \");\n const declared = [\n ...new Set([...knownFlags(argsDef).values()].map((flag) => flag.display)),\n ].toSorted();\n const takes =\n declared.length > 0\n ? `It takes ${declared.join(\", \")}.`\n : \"It takes no options.\";\n return {\n code: \"BLUME_UNKNOWN_OPTION\",\n message: `blume ${command} doesn't know ${unknown.length === 1 ? \"the option\" : \"the options\"} ${listed}.`,\n severity: \"error\",\n suggestion: `${takes} Run \\`blume ${command} --help\\` for what each does.`,\n };\n};\n",
15
+ "import type { ArgsDef, CommandDef, CommandMeta } from \"citty\";\n\nimport { BlumeError } from \"../core/diagnostics.ts\";\nimport { reportInternalError } from \"./internal-error.ts\";\nimport { reportDiagnostics } from \"./log.ts\";\nimport {\n COMMAND_HANDLED_FLAGS,\n unknownFlags,\n unknownFlagsDiagnostic,\n} from \"./unknown-flags.ts\";\n\n/**\n * Wrap a command so its module is imported only when citty needs its `args`\n * or runs it. `meta` stays static (from `command-meta.ts`), so rendering root\n * usage, matching an unknown name, and `blume <cmd> --help` for *another*\n * command never touch this one's dependency graph.\n *\n * `load` imports the command's module and `key` names its export, so the call\n * site stays a plain `() => import(\"./commands/x.ts\")`.\n *\n * Only `args`, `setup`, `run`, and `cleanup` are forwarded: no Blume command\n * declares `default`, `plugins`, or nested `subCommands`.\n *\n * Two behaviors every command shares live here rather than in each command:\n * `setup` rejects flags the command doesn't declare (citty accepts and drops\n * them, so `blume build --isolatd` would run a real, non-isolated build), and\n * `run` reports a {@link BlumeError} a command lets escape — a config that\n * fails validation, say — as its diagnostic instead of citty's raw stack dump.\n */\nexport const lazyCommand = <Args extends ArgsDef, Key extends string>(\n meta: CommandMeta,\n load: () => Promise<Record<Key, CommandDef<Args>>>,\n key: Key\n): CommandDef<Args> => {\n const command = async () => {\n const module = await load();\n return module[key];\n };\n const name = meta.name ?? key;\n return {\n args: async () => {\n const { args } = await command();\n // SAFETY: every Blume command passes `args` to `defineCommand` as a plain\n // object literal (the \"command registry\" test checks it); citty's\n // `Resolvable` widening is the only reason the type also admits a thunk\n // or a promise here.\n return args as Args;\n },\n cleanup: async (context) => {\n const loaded = await command();\n await loaded.cleanup?.(context);\n },\n meta,\n run: async (context) => {\n const loaded = await command();\n try {\n await loaded.run?.(context);\n } catch (error) {\n if (error instanceof BlumeError) {\n reportDiagnostics([error.diagnostic], process.cwd());\n } else {\n reportInternalError(error);\n }\n process.exit(1);\n }\n },\n setup: async (context) => {\n const loaded = await command();\n // SAFETY: as for `args` above, every command's `args` is a plain object.\n const argsDef = (loaded.args ?? {}) as ArgsDef;\n const unknown = unknownFlags(\n context.rawArgs,\n argsDef,\n COMMAND_HANDLED_FLAGS.get(name)\n );\n if (unknown.length > 0) {\n reportDiagnostics([unknownFlagsDiagnostic(name, unknown, argsDef)]);\n process.exit(1);\n }\n await loaded.setup?.(context);\n },\n };\n};\n"
15
16
  ],
16
- "mappings": "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",
17
- "debugId": "3D851F7CCD64619664756E2164756E21",
17
+ "mappings": "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",
18
+ "debugId": "3B8E364FC63CDED364756E2164756E21",
18
19
  "names": []
19
20
  }
@@ -0,0 +1,52 @@
1
+ import type { BlumeProject } from "../core/project-graph.ts";
2
+ /** The `.well-known` discovery URLs a site can publish. */
3
+ interface WellKnownArtifacts {
4
+ httpMessageSignaturesDirectory?: string;
5
+ aiCatalog?: string;
6
+ apiCatalog?: string;
7
+ agentSkills?: string;
8
+ }
9
+ /** The JSON docs API's entry points; `search` exists on server output only. */
10
+ interface ApiArtifact {
11
+ openapi: string;
12
+ pages: string;
13
+ search?: string;
14
+ }
15
+ /** The agent-facing artifact index the manifest publishes. */
16
+ interface AgentArtifacts extends WellKnownArtifacts {
17
+ markdown: {
18
+ contentNegotiation?: string;
19
+ pattern: string;
20
+ };
21
+ api?: ApiArtifact;
22
+ llmsFullTxt?: string;
23
+ llmsTxt?: string;
24
+ mcp?: {
25
+ discovery: string;
26
+ url: string;
27
+ };
28
+ askApi?: string;
29
+ sitemap?: string;
30
+ feeds?: string[];
31
+ }
32
+ /** The published `agent-readability.json` document. */
33
+ export interface AgentReadabilityManifest {
34
+ artifacts: AgentArtifacts;
35
+ description?: string;
36
+ generator?: string;
37
+ name: string;
38
+ site: string | null;
39
+ contentUsage?: Record<string, boolean>;
40
+ repository?: string;
41
+ }
42
+ /**
43
+ * Build `agent-readability.json`: a root manifest that indexes the project's
44
+ * agent-facing surface — llms.txt, the raw-Markdown mirrors, the JSON docs
45
+ * API and its OpenAPI description, the MCP server, Ask AI, sitemap, and feeds
46
+ * — so agents can discover and cite the docs without
47
+ * scraping HTML. URLs are absolute when a `site` is configured and root-relative
48
+ * (still under `deployment.base`) otherwise. Returns null when the manifest is
49
+ * disabled.
50
+ */
51
+ export declare const buildAgentReadability: (project: BlumeProject) => AgentReadabilityManifest | null;
52
+ export {};