blume 2.0.0 → 2.0.2

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 (454) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +110 -0
  3. package/README.md +2 -2
  4. package/dist/cli/{chunk-f2972sbt.js → chunk-00gs3wqs.js} +1 -1
  5. package/dist/cli/{chunk-fa25z98p.js → chunk-273ygyr4.js} +4 -3
  6. package/dist/cli/chunk-273ygyr4.js.map +11 -0
  7. package/dist/cli/{chunk-pat2zzwc.js → chunk-3yce002v.js} +21 -8
  8. package/dist/cli/{chunk-pat2zzwc.js.map → chunk-3yce002v.js.map} +4 -4
  9. package/dist/cli/{chunk-d1tadaw7.js → chunk-4e9b9ra6.js} +17 -7
  10. package/dist/cli/chunk-4e9b9ra6.js.map +10 -0
  11. package/dist/cli/{chunk-zg2gtj10.js → chunk-5r8g91qn.js} +352 -676
  12. package/dist/cli/chunk-5r8g91qn.js.map +34 -0
  13. package/dist/cli/{chunk-11j0384y.js → chunk-6dtt0zfn.js} +14 -14
  14. package/dist/cli/{chunk-11j0384y.js.map → chunk-6dtt0zfn.js.map} +3 -3
  15. package/dist/cli/{chunk-bw22s759.js → chunk-6k4ftwze.js} +38 -19
  16. package/dist/cli/{chunk-bw22s759.js.map → chunk-6k4ftwze.js.map} +4 -4
  17. package/dist/cli/{chunk-sqn5t4q0.js → chunk-7mbqtmgb.js} +16 -7
  18. package/dist/cli/chunk-7mbqtmgb.js.map +10 -0
  19. package/dist/cli/{chunk-79njf86q.js → chunk-7vtckvaw.js} +21 -19
  20. package/dist/cli/chunk-7vtckvaw.js.map +11 -0
  21. package/dist/cli/{chunk-fh5hj5jt.js → chunk-8g8ytmgx.js} +17 -18
  22. package/dist/cli/{chunk-fh5hj5jt.js.map → chunk-8g8ytmgx.js.map} +2 -2
  23. package/dist/cli/{chunk-1w8dp3qb.js → chunk-91ws1n6j.js} +18 -15
  24. package/dist/cli/chunk-91ws1n6j.js.map +10 -0
  25. package/dist/cli/{chunk-7ez8ny0t.js → chunk-bbnwccaz.js} +2 -2
  26. package/dist/cli/{chunk-5a2z0198.js → chunk-bfwp9vp6.js} +18 -10
  27. package/dist/cli/chunk-bfwp9vp6.js.map +10 -0
  28. package/dist/cli/{chunk-ernrthtr.js → chunk-d1v5rhy0.js} +14 -15
  29. package/dist/cli/{chunk-ernrthtr.js.map → chunk-d1v5rhy0.js.map} +2 -2
  30. package/dist/cli/{chunk-a9kptbw5.js → chunk-ddndchfr.js} +21 -6
  31. package/dist/cli/chunk-ddndchfr.js.map +14 -0
  32. package/dist/cli/{chunk-zxccj738.js → chunk-esh98wmb.js} +1 -1
  33. package/dist/cli/{chunk-88cpgt6h.js → chunk-fsmrqk8a.js} +1 -1
  34. package/dist/cli/{chunk-b5aj94ah.js → chunk-g698a744.js} +5 -5
  35. package/dist/cli/{chunk-jts8mvcz.js → chunk-gs7r695n.js} +9 -3
  36. package/dist/cli/{chunk-jts8mvcz.js.map → chunk-gs7r695n.js.map} +3 -3
  37. package/dist/cli/{chunk-41za066z.js → chunk-h2ez8dzb.js} +4 -4
  38. package/dist/cli/{chunk-by2290sx.js → chunk-h7k3nq3v.js} +2 -2
  39. package/dist/cli/{chunk-j8mw0za6.js → chunk-hqp2ajnh.js} +252 -123
  40. package/dist/cli/chunk-hqp2ajnh.js.map +35 -0
  41. package/dist/cli/{chunk-mnqj32sj.js → chunk-hr8ne106.js} +119 -50
  42. package/dist/cli/chunk-hr8ne106.js.map +13 -0
  43. package/dist/cli/{chunk-mwt1k8n7.js → chunk-j85scx15.js} +74 -30
  44. package/dist/cli/chunk-j85scx15.js.map +10 -0
  45. package/dist/cli/{chunk-z01ze5c1.js → chunk-k7pj68a8.js} +63 -22
  46. package/dist/cli/chunk-k7pj68a8.js.map +11 -0
  47. package/dist/cli/{chunk-2q1dwty4.js → chunk-mqc662a6.js} +8 -8
  48. package/dist/cli/{chunk-2q1dwty4.js.map → chunk-mqc662a6.js.map} +4 -4
  49. package/dist/cli/{chunk-y3e45rc8.js → chunk-n1yg3tj3.js} +4 -4
  50. package/dist/cli/{chunk-bctazmbk.js → chunk-nfcyttvj.js} +17 -6
  51. package/dist/cli/chunk-nfcyttvj.js.map +10 -0
  52. package/dist/cli/{chunk-6k8vp3ta.js → chunk-pbg5a4s3.js} +60 -28
  53. package/dist/cli/chunk-pbg5a4s3.js.map +19 -0
  54. package/dist/cli/{chunk-d80hr03s.js → chunk-ppzjqwx2.js} +24 -17
  55. package/dist/cli/{chunk-d80hr03s.js.map → chunk-ppzjqwx2.js.map} +4 -4
  56. package/dist/cli/{chunk-beat36xx.js → chunk-qkb5a8sa.js} +25 -10
  57. package/dist/cli/chunk-qkb5a8sa.js.map +10 -0
  58. package/dist/cli/{chunk-bnbmcwfb.js → chunk-sqw4ekg1.js} +5 -5
  59. package/dist/cli/{chunk-bnbmcwfb.js.map → chunk-sqw4ekg1.js.map} +3 -3
  60. package/dist/cli/{chunk-xaz13gwg.js → chunk-v6ya5kcb.js} +3268 -1150
  61. package/dist/cli/chunk-v6ya5kcb.js.map +189 -0
  62. package/dist/cli/{chunk-tzne8qfq.js → chunk-w4bxdvsa.js} +18 -15
  63. package/dist/cli/chunk-w4bxdvsa.js.map +10 -0
  64. package/dist/cli/{chunk-f7t03s3g.js → chunk-wdrt2k2v.js} +2 -2
  65. package/dist/cli/{chunk-z1f5arsg.js → chunk-xh43dwgw.js} +170 -55
  66. package/dist/cli/chunk-xh43dwgw.js.map +36 -0
  67. package/dist/cli/{chunk-pnnvybbk.js → chunk-zp79m0ts.js} +5 -5
  68. package/dist/cli/{chunk-pnnvybbk.js.map → chunk-zp79m0ts.js.map} +2 -2
  69. package/dist/cli/index.js +160 -35
  70. package/dist/cli/index.js.map +4 -4
  71. package/dist/types/ai/agent-readability.d.ts +1 -1
  72. package/dist/types/ai/agent-surface.d.ts +32 -0
  73. package/dist/types/ai/api/paths.d.ts +1 -1
  74. package/dist/types/ai/api-catalog.d.ts +7 -1
  75. package/dist/types/ai/ask-context.d.ts +14 -7
  76. package/dist/types/ai/ask.d.ts +43 -43
  77. package/dist/types/ai/component-markdown.d.ts +4 -4
  78. package/dist/types/ai/index.d.ts +3 -3
  79. package/dist/types/ai/openapi-components.d.ts +1 -1
  80. package/dist/types/ai/relative-links.d.ts +9 -4
  81. package/dist/types/ai/serializers.d.ts +1 -1
  82. package/dist/types/ai/static-expression.d.ts +28 -0
  83. package/dist/types/ai/visibility.d.ts +1 -1
  84. package/dist/types/analytics/databuddy.d.ts +43 -0
  85. package/dist/types/analytics/index.d.ts +2 -0
  86. package/dist/types/analytics/schema.d.ts +14 -0
  87. package/dist/types/cli/env.d.ts +5 -0
  88. package/dist/types/cli/init/scaffold.d.ts +19 -3
  89. package/dist/types/cli/init/starter-spec.d.ts +11 -0
  90. package/dist/types/core/base-path.d.ts +9 -0
  91. package/dist/types/core/config-input.d.ts +21 -21
  92. package/dist/types/core/config.d.ts +5 -5
  93. package/dist/types/core/data.d.ts +3 -3
  94. package/dist/types/core/graph.d.ts +2 -0
  95. package/dist/types/core/i18n-ui.d.ts +37 -8
  96. package/dist/types/core/i18n.d.ts +7 -1
  97. package/dist/types/core/links.d.ts +3 -1
  98. package/dist/types/core/load-module.d.ts +10 -0
  99. package/dist/types/core/locale-links.d.ts +12 -2
  100. package/dist/types/core/meta.d.ts +5 -1
  101. package/dist/types/core/nav-diagnostics.d.ts +10 -0
  102. package/dist/types/core/navigation.d.ts +38 -0
  103. package/dist/types/core/ordering-prefix.d.ts +4 -0
  104. package/dist/types/core/safe-links.d.ts +3 -1
  105. package/dist/types/core/schema.d.ts +57 -18
  106. package/dist/types/core/sources/github-releases.d.ts +5 -0
  107. package/dist/types/core/sources/lower.d.ts +14 -2
  108. package/dist/types/core/sources/normalize.d.ts +10 -1
  109. package/dist/types/core/sources/remote.d.ts +11 -1
  110. package/dist/types/core/sources/resolve.d.ts +12 -0
  111. package/dist/types/core/sources/types.d.ts +31 -0
  112. package/dist/types/core/types.d.ts +9 -0
  113. package/dist/types/core/unrecognized-keys.d.ts +1 -1
  114. package/dist/types/deploy/adapters/node.d.ts +5 -2
  115. package/dist/types/deploy/adapters/types.d.ts +7 -0
  116. package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
  117. package/dist/types/deploy/headers.d.ts +31 -7
  118. package/dist/types/deploy/node-headers.d.ts +43 -8
  119. package/dist/types/deploy/platforms/netlify.d.ts +27 -2
  120. package/dist/types/deploy/platforms/node.d.ts +6 -5
  121. package/dist/types/deploy/platforms/types.d.ts +7 -0
  122. package/dist/types/deploy/platforms/vercel.d.ts +3 -2
  123. package/dist/types/deploy/redirects.d.ts +7 -2
  124. package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
  125. package/dist/types/openapi/model.d.ts +20 -6
  126. package/dist/types/search/documents.d.ts +1 -1
  127. package/dist/types/search/orama-index.d.ts +1 -1
  128. package/dist/types/search/sync/algolia.d.ts +3 -1
  129. package/docs/01-quickstart.mdx +3 -2
  130. package/docs/02-deployment.mdx +21 -12
  131. package/docs/03-upgrading.mdx +22 -9
  132. package/docs/04-migrating.mdx +4 -4
  133. package/docs/08-faq.mdx +12 -5
  134. package/docs/advanced/changelog.mdx +1 -1
  135. package/docs/advanced/custom-pages.mdx +5 -3
  136. package/docs/advanced/skills.mdx +1 -1
  137. package/docs/cli/audit.mdx +5 -5
  138. package/docs/cli/doctor.mdx +4 -4
  139. package/docs/cli/evals.mdx +9 -9
  140. package/docs/cli/index.mdx +6 -3
  141. package/docs/cli/translate.mdx +8 -8
  142. package/docs/configuration/analytics.mdx +23 -2
  143. package/docs/configuration/{ask-ai.mdx → assistant.mdx} +20 -20
  144. package/docs/configuration/customization.mdx +5 -4
  145. package/docs/configuration/index.mdx +7 -5
  146. package/docs/configuration/meta.ts +1 -1
  147. package/docs/configuration/search.mdx +2 -2
  148. package/docs/content/components.mdx +1 -1
  149. package/docs/content/frontmatter.mdx +5 -1
  150. package/docs/content/i18n.mdx +3 -3
  151. package/docs/content/index.mdx +4 -2
  152. package/docs/content/islands.mdx +1 -1
  153. package/docs/content/meta.mdx +5 -3
  154. package/docs/content/navigation.mdx +29 -4
  155. package/docs/content/sources.mdx +18 -12
  156. package/docs/content/versioning.mdx +1 -0
  157. package/docs/discoverability/agent-discovery.mdx +22 -8
  158. package/docs/discoverability/index.mdx +3 -3
  159. package/docs/discoverability/llms-txt.mdx +2 -5
  160. package/docs/discoverability/markdown.mdx +5 -3
  161. package/docs/discoverability/mcp.mdx +4 -0
  162. package/docs/discoverability/metadata.mdx +3 -2
  163. package/docs/discoverability/open-graph.mdx +6 -4
  164. package/docs/discoverability/rss.mdx +3 -1
  165. package/docs/index.mdx +2 -2
  166. package/docs/references/asyncapi.mdx +1 -1
  167. package/docs/references/graphql.mdx +2 -2
  168. package/docs/references/openapi.mdx +3 -3
  169. package/package.json +1 -1
  170. package/skills/blume/SKILL.md +5 -5
  171. package/skills/blume-migrate/SKILL.md +6 -6
  172. package/skills/blume-migrate/references/docusaurus.md +6 -6
  173. package/skills/blume-migrate/references/mintlify.md +3 -3
  174. package/skills/blume-migrate/references/monorepo.md +1 -1
  175. package/skills/blume-migrate/references/nextra.md +1 -1
  176. package/skills/blume-migrate/references/starlight.md +5 -5
  177. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +2 -2
  178. package/skills/blume-update-docs/references/audit-checklist.md +1 -1
  179. package/src/ai/agent-readability.ts +4 -4
  180. package/src/ai/agent-surface.ts +56 -0
  181. package/src/ai/api/paths.ts +1 -1
  182. package/src/ai/api/spec.ts +15 -2
  183. package/src/ai/api-catalog.ts +7 -1
  184. package/src/ai/ask-context.ts +21 -9
  185. package/src/ai/ask-data.ts +28 -14
  186. package/src/ai/ask.ts +84 -71
  187. package/src/ai/component-markdown.ts +43 -37
  188. package/src/ai/cors.ts +3 -3
  189. package/src/ai/index.ts +16 -16
  190. package/src/ai/link-headers.ts +8 -3
  191. package/src/ai/llms.ts +4 -3
  192. package/src/ai/markdown.ts +23 -11
  193. package/src/ai/mcp/server.ts +78 -7
  194. package/src/ai/openapi-components.ts +1 -1
  195. package/src/ai/relative-links.ts +78 -10
  196. package/src/ai/serializers.ts +1 -1
  197. package/src/ai/static-expression.ts +416 -0
  198. package/src/ai/visibility.ts +46 -15
  199. package/src/analytics/databuddy.ts +67 -0
  200. package/src/analytics/head.ts +4 -0
  201. package/src/analytics/index.ts +2 -0
  202. package/src/analytics/posthog.ts +21 -3
  203. package/src/analytics/schema.ts +2 -0
  204. package/src/astro/generate.ts +90 -45
  205. package/src/astro/module-types.ts +1 -1
  206. package/src/astro/runtime-deps.ts +6 -6
  207. package/src/astro/templates.ts +87 -49
  208. package/src/audit/catalog.ts +2 -2
  209. package/src/audit/checks/assets.ts +25 -5
  210. package/src/audit/checks/content.ts +20 -2
  211. package/src/audit/checks/i18n.ts +46 -8
  212. package/src/audit/checks/indexability.ts +39 -19
  213. package/src/audit/checks/links.ts +14 -0
  214. package/src/audit/checks/llms.ts +6 -3
  215. package/src/audit/checks/network.ts +3 -1
  216. package/src/audit/checks/og-image.ts +10 -0
  217. package/src/audit/checks/robots.ts +6 -1
  218. package/src/audit/checks/sitemap.ts +56 -31
  219. package/src/audit/checks/social.ts +21 -2
  220. package/src/audit/crawl.ts +88 -15
  221. package/src/audit/report.ts +54 -17
  222. package/src/audit/run.ts +1 -0
  223. package/src/audit/types.ts +18 -0
  224. package/src/audit/url.ts +37 -6
  225. package/src/blume-modules.d.ts +2 -2
  226. package/src/cli/build-failure.ts +50 -0
  227. package/src/cli/commands/audit.ts +8 -1
  228. package/src/cli/commands/build.ts +19 -5
  229. package/src/cli/commands/check.ts +2 -0
  230. package/src/cli/commands/doctor.ts +7 -5
  231. package/src/cli/commands/eval.ts +4 -10
  232. package/src/cli/commands/init.ts +15 -5
  233. package/src/cli/commands/migrate.ts +2 -2
  234. package/src/cli/commands/preview.ts +15 -0
  235. package/src/cli/commands/sync.ts +2 -0
  236. package/src/cli/commands/translate.ts +12 -9
  237. package/src/cli/commands/upgrade.ts +13 -2
  238. package/src/cli/eject-scripts.ts +32 -7
  239. package/src/cli/env.ts +12 -1
  240. package/src/cli/init/scaffold.ts +117 -11
  241. package/src/cli/init/starter-spec.ts +235 -0
  242. package/src/cli/required-secrets.ts +3 -3
  243. package/src/components/content/AccordionItem.astro +26 -22
  244. package/src/components/content/Badge.astro +2 -9
  245. package/src/components/content/Card.astro +2 -2
  246. package/src/components/content/Component.astro +9 -3
  247. package/src/components/content/Expandable.astro +5 -1
  248. package/src/components/content/Frame.astro +2 -7
  249. package/src/components/content/GithubInfo.astro +12 -2
  250. package/src/components/content/Prompt.astro +2 -7
  251. package/src/components/content/Tabs.astro +54 -5
  252. package/src/components/content/Tile.astro +1 -1
  253. package/src/components/content/Tooltip.astro +69 -7
  254. package/src/components/content/Tree.astro +7 -2
  255. package/src/components/content/TypeTable.astro +10 -5
  256. package/src/components/content/Update.astro +8 -2
  257. package/src/components/content/auto-type-table.ts +4 -1
  258. package/src/components/content/badge-color.ts +17 -0
  259. package/src/components/content/base-href.ts +18 -3
  260. package/src/components/content/inline-markdown.ts +27 -7
  261. package/src/components/copy-feedback.ts +36 -9
  262. package/src/components/islands/{AskAI.astro → Assistant.astro} +10 -10
  263. package/src/components/islands/{ask-ai.tsx → assistant.tsx} +39 -25
  264. package/src/components/islands/hooks.ts +21 -14
  265. package/src/components/islands/webmcp.ts +12 -8
  266. package/src/components/layout/Banner.astro +23 -4
  267. package/src/components/layout/Header.astro +32 -19
  268. package/src/components/layout/Logo.astro +5 -0
  269. package/src/components/layout/NavSelector.astro +6 -1
  270. package/src/components/layout/NavTabMenu.astro +133 -0
  271. package/src/components/layout/NavTree.astro +15 -6
  272. package/src/components/layout/NavTreeCache.astro +5 -2
  273. package/src/components/layout/NavTreeScript.astro +45 -5
  274. package/src/components/layout/PageLayout.astro +28 -14
  275. package/src/components/layout/Pagination.astro +7 -7
  276. package/src/components/layout/ReferenceLayout.astro +5 -2
  277. package/src/components/layout/RootLayout.astro +27 -14
  278. package/src/components/layout/Search.astro +18 -14
  279. package/src/components/layout/analytics-client.ts +3 -1
  280. package/src/components/layout/drawer-inert.ts +1 -1
  281. package/src/components/openapi/GraphqlType.astro +11 -3
  282. package/src/components/openapi/MessageComposer.astro +1 -1
  283. package/src/components/openapi/Operation.astro +21 -5
  284. package/src/components/openapi/PanelTabs.astro +4 -1
  285. package/src/components/openapi/Playground.astro +8 -2
  286. package/src/components/openapi/RequestPanel.astro +9 -5
  287. package/src/components/openapi/SchemaProperty.astro +11 -33
  288. package/src/components/openapi/SchemaTable.astro +27 -52
  289. package/src/components/openapi/description.ts +2 -2
  290. package/src/components/openapi/helpers.ts +90 -12
  291. package/src/components/openapi/message-composer.ts +8 -0
  292. package/src/components/openapi/message-model.ts +12 -2
  293. package/src/components/openapi/message.ts +4 -1
  294. package/src/components/openapi/operation-model.ts +40 -8
  295. package/src/components/openapi/panel.ts +29 -5
  296. package/src/components/openapi/playground-client.ts +37 -7
  297. package/src/components/openapi/playground-schema.ts +25 -6
  298. package/src/components/openapi/request.ts +2 -0
  299. package/src/components/openapi/schema-tree.ts +203 -0
  300. package/src/components/openapi/snippets.ts +30 -15
  301. package/src/components/openapi/validate-json.ts +1 -1
  302. package/src/core/base-path.ts +15 -0
  303. package/src/core/code-fences.ts +1 -1
  304. package/src/core/config-input.ts +23 -23
  305. package/src/core/config.ts +21 -7
  306. package/src/core/data.ts +3 -3
  307. package/src/core/diagnostics.ts +217 -30
  308. package/src/core/graph.ts +120 -11
  309. package/src/core/i18n-ui.ts +74 -11
  310. package/src/core/i18n.ts +13 -2
  311. package/src/core/links.ts +7 -4
  312. package/src/core/load-module.ts +20 -0
  313. package/src/core/locale-links.ts +17 -17
  314. package/src/core/manifest.ts +3 -2
  315. package/src/core/meta.ts +69 -6
  316. package/src/core/nav-diagnostics.ts +56 -1
  317. package/src/core/navigation.ts +245 -76
  318. package/src/core/ordering-prefix.ts +27 -0
  319. package/src/core/project-graph.ts +23 -1
  320. package/src/core/request-body.ts +1 -1
  321. package/src/core/safe-href.ts +53 -1
  322. package/src/core/safe-links.ts +11 -2
  323. package/src/core/schema.ts +95 -34
  324. package/src/core/server-features.ts +2 -2
  325. package/src/core/sources/assets.ts +83 -41
  326. package/src/core/sources/contentful-rich-text.ts +3 -2
  327. package/src/core/sources/contentful.ts +25 -12
  328. package/src/core/sources/filesystem.ts +5 -1
  329. package/src/core/sources/github-releases.ts +106 -5
  330. package/src/core/sources/lexical.ts +9 -4
  331. package/src/core/sources/lower.ts +79 -26
  332. package/src/core/sources/mdx-remote.ts +1 -0
  333. package/src/core/sources/normalize.ts +132 -30
  334. package/src/core/sources/notion.ts +26 -10
  335. package/src/core/sources/obsidian.ts +17 -3
  336. package/src/core/sources/payload.ts +1 -0
  337. package/src/core/sources/portable-text.ts +63 -44
  338. package/src/core/sources/remote.ts +18 -2
  339. package/src/core/sources/resolve.ts +52 -33
  340. package/src/core/sources/sanity.ts +1 -0
  341. package/src/core/sources/strapi-blocks.ts +9 -4
  342. package/src/core/sources/strapi.ts +1 -0
  343. package/src/core/sources/types.ts +31 -0
  344. package/src/core/types.ts +9 -0
  345. package/src/core/ui-packs/ar.ts +17 -5
  346. package/src/core/ui-packs/bg.ts +17 -5
  347. package/src/core/ui-packs/bn.ts +17 -5
  348. package/src/core/ui-packs/ca.ts +17 -5
  349. package/src/core/ui-packs/cs.ts +17 -5
  350. package/src/core/ui-packs/da.ts +17 -5
  351. package/src/core/ui-packs/de.ts +17 -5
  352. package/src/core/ui-packs/el.ts +17 -5
  353. package/src/core/ui-packs/es.ts +17 -5
  354. package/src/core/ui-packs/fa.ts +17 -5
  355. package/src/core/ui-packs/fi.ts +17 -5
  356. package/src/core/ui-packs/fr.ts +17 -5
  357. package/src/core/ui-packs/he.ts +17 -5
  358. package/src/core/ui-packs/hi.ts +17 -5
  359. package/src/core/ui-packs/hr.ts +17 -5
  360. package/src/core/ui-packs/hu.ts +17 -5
  361. package/src/core/ui-packs/id.ts +17 -5
  362. package/src/core/ui-packs/it.ts +17 -5
  363. package/src/core/ui-packs/ja.ts +17 -5
  364. package/src/core/ui-packs/ko.ts +17 -5
  365. package/src/core/ui-packs/nl.ts +17 -5
  366. package/src/core/ui-packs/no.ts +17 -5
  367. package/src/core/ui-packs/pl.ts +17 -5
  368. package/src/core/ui-packs/pt-br.ts +17 -5
  369. package/src/core/ui-packs/pt.ts +17 -5
  370. package/src/core/ui-packs/ro.ts +17 -5
  371. package/src/core/ui-packs/ru.ts +17 -5
  372. package/src/core/ui-packs/sk.ts +17 -5
  373. package/src/core/ui-packs/sr.ts +17 -5
  374. package/src/core/ui-packs/sv.ts +17 -5
  375. package/src/core/ui-packs/th.ts +17 -5
  376. package/src/core/ui-packs/tr.ts +17 -5
  377. package/src/core/ui-packs/uk.ts +17 -5
  378. package/src/core/ui-packs/vi.ts +17 -5
  379. package/src/core/ui-packs/zh-tw.ts +17 -5
  380. package/src/core/ui-packs/zh.ts +17 -5
  381. package/src/core/unrecognized-keys.ts +1 -1
  382. package/src/core/version-cut.ts +17 -2
  383. package/src/core/versions.ts +4 -1
  384. package/src/deploy/adapters/node.ts +5 -2
  385. package/src/deploy/adapters/registry.ts +2 -1
  386. package/src/deploy/adapters/types.ts +13 -1
  387. package/src/deploy/artifacts.ts +25 -5
  388. package/src/deploy/cloudflare-negotiation.ts +23 -4
  389. package/src/deploy/headers.ts +67 -51
  390. package/src/deploy/node-headers.ts +148 -27
  391. package/src/deploy/platforms/cloudflare.ts +1 -0
  392. package/src/deploy/platforms/netlify.ts +82 -5
  393. package/src/deploy/platforms/node.ts +7 -5
  394. package/src/deploy/platforms/static.ts +1 -0
  395. package/src/deploy/platforms/types.ts +7 -0
  396. package/src/deploy/platforms/vercel.ts +9 -3
  397. package/src/deploy/redirects.ts +14 -3
  398. package/src/deploy/vercel-negotiation.ts +35 -3
  399. package/src/eval/agents.ts +10 -2
  400. package/src/eval/run.ts +25 -0
  401. package/src/markdown/base-links.ts +55 -8
  402. package/src/markdown/index.ts +6 -3
  403. package/src/markdown/relative-links.ts +3 -23
  404. package/src/markdown/route-snapshot.ts +37 -0
  405. package/src/og/card.ts +20 -4
  406. package/src/og/derive.ts +145 -4
  407. package/src/openapi/graphql-build.ts +28 -2
  408. package/src/openapi/model.ts +77 -13
  409. package/src/openapi/render-mdx.ts +10 -1
  410. package/src/registry/eject.ts +135 -37
  411. package/src/search/documents.ts +24 -3
  412. package/src/search/orama-index.ts +1 -1
  413. package/src/search/sync/algolia.ts +36 -2
  414. package/src/sources/registry.ts +5 -0
  415. package/src/theme/entry.ts +11 -4
  416. package/src/translate/agents.ts +6 -1
  417. package/src/translate/ledger.ts +26 -3
  418. package/src/translate/meta.ts +11 -3
  419. package/src/translate/report.ts +1 -1
  420. package/src/translate/run.ts +11 -5
  421. package/src/translate/validate.ts +10 -1
  422. package/src/translate/work-list.ts +36 -3
  423. package/src/upgrade/upgrade.ts +37 -5
  424. package/dist/cli/chunk-1w8dp3qb.js.map +0 -10
  425. package/dist/cli/chunk-5a2z0198.js.map +0 -10
  426. package/dist/cli/chunk-6k8vp3ta.js.map +0 -19
  427. package/dist/cli/chunk-79njf86q.js.map +0 -11
  428. package/dist/cli/chunk-a9kptbw5.js.map +0 -14
  429. package/dist/cli/chunk-abh8yjkn.js +0 -31
  430. package/dist/cli/chunk-abh8yjkn.js.map +0 -10
  431. package/dist/cli/chunk-bctazmbk.js.map +0 -10
  432. package/dist/cli/chunk-beat36xx.js.map +0 -10
  433. package/dist/cli/chunk-d1tadaw7.js.map +0 -10
  434. package/dist/cli/chunk-fa25z98p.js.map +0 -11
  435. package/dist/cli/chunk-j8mw0za6.js.map +0 -35
  436. package/dist/cli/chunk-mnqj32sj.js.map +0 -12
  437. package/dist/cli/chunk-mwt1k8n7.js.map +0 -10
  438. package/dist/cli/chunk-nk3ts2xk.js +0 -51
  439. package/dist/cli/chunk-nk3ts2xk.js.map +0 -10
  440. package/dist/cli/chunk-sqn5t4q0.js.map +0 -10
  441. package/dist/cli/chunk-tzne8qfq.js.map +0 -10
  442. package/dist/cli/chunk-xaz13gwg.js.map +0 -182
  443. package/dist/cli/chunk-z01ze5c1.js.map +0 -10
  444. package/dist/cli/chunk-z1f5arsg.js.map +0 -36
  445. package/dist/cli/chunk-zg2gtj10.js.map +0 -35
  446. /package/dist/cli/{chunk-f2972sbt.js.map → chunk-00gs3wqs.js.map} +0 -0
  447. /package/dist/cli/{chunk-7ez8ny0t.js.map → chunk-bbnwccaz.js.map} +0 -0
  448. /package/dist/cli/{chunk-zxccj738.js.map → chunk-esh98wmb.js.map} +0 -0
  449. /package/dist/cli/{chunk-88cpgt6h.js.map → chunk-fsmrqk8a.js.map} +0 -0
  450. /package/dist/cli/{chunk-b5aj94ah.js.map → chunk-g698a744.js.map} +0 -0
  451. /package/dist/cli/{chunk-41za066z.js.map → chunk-h2ez8dzb.js.map} +0 -0
  452. /package/dist/cli/{chunk-by2290sx.js.map → chunk-h7k3nq3v.js.map} +0 -0
  453. /package/dist/cli/{chunk-y3e45rc8.js.map → chunk-n1yg3tj3.js.map} +0 -0
  454. /package/dist/cli/{chunk-f7t03s3g.js.map → chunk-wdrt2k2v.js.map} +0 -0
@@ -2,10 +2,10 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/core/server-features.ts", "../src/cli/required-secrets.ts"],
4
4
  "sourcesContent": [
5
- "import { needsPlaygroundProxy } from \"../openapi/references.ts\";\nimport type { ResolvedConfig } from \"./schema.ts\";\n\n/**\n * List the enabled features that require Astro server output. Static builds\n * fail clearly when any of these are enabled.\n */\nexport const serverFeatures = (config: ResolvedConfig): string[] => {\n const features: string[] = [];\n if (config.ai.ask?.enabled && !config.ai.ask.endpoint) {\n features.push(\"Ask AI\");\n }\n // The hosted MCP server is a live JSON-RPC endpoint, so it needs a runtime.\n if (config.agents.mcp.enabled) {\n features.push(\"MCP server\");\n }\n // The built-in playground proxy (`playground.proxy: true` on an `openapi()`\n // or `graphql()` adapter) is a live fetch endpoint at `/_api-proxy`; an\n // external proxy URL (string) or a proxy-less playground stays fully static.\n if (needsPlaygroundProxy(config)) {\n features.push(\"API playground proxy\");\n }\n // A `server` adapter (Mixedbread) proxies queries through a secret server\n // endpoint, so it can't run on a static build.\n if (config.search.provider.mode === \"server\") {\n features.push(`Search (${config.search.provider.kind})`);\n }\n return features;\n};\n",
6
- "import { resolveAskBackend } from \"../ai/ask.ts\";\nimport type { ResolvedConfig } from \"../core/schema.ts\";\nimport type { Diagnostic } from \"../core/types.ts\";\n\n/**\n * Warn early when an enabled feature needs a secret env var that isn't set, so\n * the failure surfaces at `blume dev`/`build` instead of at the first request in\n * production. These are runtime secrets (the endpoint reads them on the server),\n * so this warns rather than hard-fails — the value may live only in the deploy\n * environment. Build-time secrets (search-index sync) already warn during sync.\n */\nexport const checkRequiredSecrets = (config: ResolvedConfig): Diagnostic[] => {\n const diagnostics: Diagnostic[] = [];\n const requireSecret = (feature: string, env: string, note?: string): void => {\n if (process.env[env]) {\n return;\n }\n const noteSuffix = note ? ` (${note})` : \"\";\n diagnostics.push({\n code: \"BLUME_MISSING_SECRET\",\n message: `${feature} is enabled but ${env} is not set${noteSuffix}.`,\n severity: \"warning\",\n suggestion: `Set ${env} in .env.local for local dev, or in your host's environment for production.`,\n });\n };\n\n if (config.ai.ask?.enabled && !config.ai.ask.endpoint) {\n // The adapter descriptor names the env vars its route reads.\n const { provider } = config.ai.ask;\n const backend = resolveAskBackend(provider);\n for (const env of provider.requiredSecrets) {\n requireSecret(`Ask AI (${backend.label})`, env, backend.secretNote);\n }\n }\n\n // Each search adapter declares the secrets its generated runtime reads.\n const { provider } = config.search;\n for (const env of provider.requiredSecrets) {\n requireSecret(`Search (${provider.kind})`, env);\n }\n\n // Adapters name their own secrets; the built-in analytics adapters ship\n // public tokens in the page and declare none.\n for (const adapter of config.analytics) {\n for (const env of adapter.requiredSecrets) {\n requireSecret(`Analytics (${adapter.kind})`, env);\n }\n }\n\n // Each content source adapter declares the env vars its fetch reads.\n for (const source of config.content.sources) {\n for (const env of source.requiredSecrets) {\n requireSecret(`Content source (${source.kind})`, env);\n }\n }\n\n // Adapters name their own secrets; the built-in reference adapters read\n // public specs and declare none.\n for (const adapter of config.reference) {\n for (const env of adapter.requiredSecrets) {\n requireSecret(`API reference (${adapter.kind})`, env);\n }\n }\n\n // The deployment adapter names its own secrets; the built-in host adapters\n // read platform-injected env and declare none.\n for (const env of config.deployment.requiredSecrets) {\n requireSecret(`Deployment (${config.deployment.kind})`, env);\n }\n\n return diagnostics;\n};\n"
5
+ "import { needsPlaygroundProxy } from \"../openapi/references.ts\";\nimport type { ResolvedConfig } from \"./schema.ts\";\n\n/**\n * List the enabled features that require Astro server output. Static builds\n * fail clearly when any of these are enabled.\n */\nexport const serverFeatures = (config: ResolvedConfig): string[] => {\n const features: string[] = [];\n if (config.ai.assistant?.enabled && !config.ai.assistant.endpoint) {\n features.push(\"Assistant\");\n }\n // The hosted MCP server is a live JSON-RPC endpoint, so it needs a runtime.\n if (config.agents.mcp.enabled) {\n features.push(\"MCP server\");\n }\n // The built-in playground proxy (`playground.proxy: true` on an `openapi()`\n // or `graphql()` adapter) is a live fetch endpoint at `/_api-proxy`; an\n // external proxy URL (string) or a proxy-less playground stays fully static.\n if (needsPlaygroundProxy(config)) {\n features.push(\"API playground proxy\");\n }\n // A `server` adapter (Mixedbread) proxies queries through a secret server\n // endpoint, so it can't run on a static build.\n if (config.search.provider.mode === \"server\") {\n features.push(`Search (${config.search.provider.kind})`);\n }\n return features;\n};\n",
6
+ "import { resolveAskBackend } from \"../ai/ask.ts\";\nimport type { ResolvedConfig } from \"../core/schema.ts\";\nimport type { Diagnostic } from \"../core/types.ts\";\n\n/**\n * Warn early when an enabled feature needs a secret env var that isn't set, so\n * the failure surfaces at `blume dev`/`build` instead of at the first request in\n * production. These are runtime secrets (the endpoint reads them on the server),\n * so this warns rather than hard-fails — the value may live only in the deploy\n * environment. Build-time secrets (search-index sync) already warn during sync.\n */\nexport const checkRequiredSecrets = (config: ResolvedConfig): Diagnostic[] => {\n const diagnostics: Diagnostic[] = [];\n const requireSecret = (feature: string, env: string, note?: string): void => {\n if (process.env[env]) {\n return;\n }\n const noteSuffix = note ? ` (${note})` : \"\";\n diagnostics.push({\n code: \"BLUME_MISSING_SECRET\",\n message: `${feature} is enabled but ${env} is not set${noteSuffix}.`,\n severity: \"warning\",\n suggestion: `Set ${env} in .env.local for local dev, or in your host's environment for production.`,\n });\n };\n\n if (config.ai.assistant?.enabled && !config.ai.assistant.endpoint) {\n // The adapter descriptor names the env vars its route reads.\n const { provider } = config.ai.assistant;\n const backend = resolveAskBackend(provider);\n for (const env of provider.requiredSecrets) {\n requireSecret(`Assistant (${backend.label})`, env, backend.secretNote);\n }\n }\n\n // Each search adapter declares the secrets its generated runtime reads.\n const { provider } = config.search;\n for (const env of provider.requiredSecrets) {\n requireSecret(`Search (${provider.kind})`, env);\n }\n\n // Adapters name their own secrets; the built-in analytics adapters ship\n // public tokens in the page and declare none.\n for (const adapter of config.analytics) {\n for (const env of adapter.requiredSecrets) {\n requireSecret(`Analytics (${adapter.kind})`, env);\n }\n }\n\n // Each content source adapter declares the env vars its fetch reads.\n for (const source of config.content.sources) {\n for (const env of source.requiredSecrets) {\n requireSecret(`Content source (${source.kind})`, env);\n }\n }\n\n // Adapters name their own secrets; the built-in reference adapters read\n // public specs and declare none.\n for (const adapter of config.reference) {\n for (const env of adapter.requiredSecrets) {\n requireSecret(`API reference (${adapter.kind})`, env);\n }\n }\n\n // The deployment adapter names its own secrets; the built-in host adapters\n // read platform-injected env and declare none.\n for (const env of config.deployment.requiredSecrets) {\n requireSecret(`Deployment (${config.deployment.kind})`, env);\n }\n\n return diagnostics;\n};\n"
7
7
  ],
8
- "mappings": ";;;;;;;AAOO,IAAM,iBAAiB,CAAC,WAAqC;AAAA,EAClE,MAAM,WAAqB,CAAC;AAAA,EAC5B,IAAI,OAAO,GAAG,KAAK,WAAW,CAAC,OAAO,GAAG,IAAI,UAAU;AAAA,IACrD,SAAS,KAAK,QAAQ;AAAA,EACxB;AAAA,EAEA,IAAI,OAAO,OAAO,IAAI,SAAS;AAAA,IAC7B,SAAS,KAAK,YAAY;AAAA,EAC5B;AAAA,EAIA,IAAI,qBAAqB,MAAM,GAAG;AAAA,IAChC,SAAS,KAAK,sBAAsB;AAAA,EACtC;AAAA,EAGA,IAAI,OAAO,OAAO,SAAS,SAAS,UAAU;AAAA,IAC5C,SAAS,KAAK,WAAW,OAAO,OAAO,SAAS,OAAO;AAAA,EACzD;AAAA,EACA,OAAO;AAAA;;;AChBF,IAAM,uBAAuB,CAAC,WAAyC;AAAA,EAC5E,MAAM,cAA4B,CAAC;AAAA,EACnC,MAAM,gBAAgB,CAAC,SAAiB,KAAa,SAAwB;AAAA,IAC3E,IAAI,QAAQ,IAAI,MAAM;AAAA,MACpB;AAAA,IACF;AAAA,IACA,MAAM,aAAa,OAAO,KAAK,UAAU;AAAA,IACzC,YAAY,KAAK;AAAA,MACf,MAAM;AAAA,MACN,SAAS,GAAG,0BAA0B,iBAAiB;AAAA,MACvD,UAAU;AAAA,MACV,YAAY,OAAO;AAAA,IACrB,CAAC;AAAA;AAAA,EAGH,IAAI,OAAO,GAAG,KAAK,WAAW,CAAC,OAAO,GAAG,IAAI,UAAU;AAAA,IAErD,QAAQ,aAAa,OAAO,GAAG;AAAA,IAC/B,MAAM,UAAU,kBAAkB,QAAQ;AAAA,IAC1C,WAAW,OAAO,SAAS,iBAAiB;AAAA,MAC1C,cAAc,WAAW,QAAQ,UAAU,KAAK,QAAQ,UAAU;AAAA,IACpE;AAAA,EACF;AAAA,EAGA,QAAQ,aAAa,OAAO;AAAA,EAC5B,WAAW,OAAO,SAAS,iBAAiB;AAAA,IAC1C,cAAc,WAAW,SAAS,SAAS,GAAG;AAAA,EAChD;AAAA,EAIA,WAAW,WAAW,OAAO,WAAW;AAAA,IACtC,WAAW,OAAO,QAAQ,iBAAiB;AAAA,MACzC,cAAc,cAAc,QAAQ,SAAS,GAAG;AAAA,IAClD;AAAA,EACF;AAAA,EAGA,WAAW,UAAU,OAAO,QAAQ,SAAS;AAAA,IAC3C,WAAW,OAAO,OAAO,iBAAiB;AAAA,MACxC,cAAc,mBAAmB,OAAO,SAAS,GAAG;AAAA,IACtD;AAAA,EACF;AAAA,EAIA,WAAW,WAAW,OAAO,WAAW;AAAA,IACtC,WAAW,OAAO,QAAQ,iBAAiB;AAAA,MACzC,cAAc,kBAAkB,QAAQ,SAAS,GAAG;AAAA,IACtD;AAAA,EACF;AAAA,EAIA,WAAW,OAAO,OAAO,WAAW,iBAAiB;AAAA,IACnD,cAAc,eAAe,OAAO,WAAW,SAAS,GAAG;AAAA,EAC7D;AAAA,EAEA,OAAO;AAAA;",
9
- "debugId": "FF74BC88ADA489ED64756E2164756E21",
8
+ "mappings": ";;;;;;;AAOO,IAAM,iBAAiB,CAAC,WAAqC;AAAA,EAClE,MAAM,WAAqB,CAAC;AAAA,EAC5B,IAAI,OAAO,GAAG,WAAW,WAAW,CAAC,OAAO,GAAG,UAAU,UAAU;AAAA,IACjE,SAAS,KAAK,WAAW;AAAA,EAC3B;AAAA,EAEA,IAAI,OAAO,OAAO,IAAI,SAAS;AAAA,IAC7B,SAAS,KAAK,YAAY;AAAA,EAC5B;AAAA,EAIA,IAAI,qBAAqB,MAAM,GAAG;AAAA,IAChC,SAAS,KAAK,sBAAsB;AAAA,EACtC;AAAA,EAGA,IAAI,OAAO,OAAO,SAAS,SAAS,UAAU;AAAA,IAC5C,SAAS,KAAK,WAAW,OAAO,OAAO,SAAS,OAAO;AAAA,EACzD;AAAA,EACA,OAAO;AAAA;;;AChBF,IAAM,uBAAuB,CAAC,WAAyC;AAAA,EAC5E,MAAM,cAA4B,CAAC;AAAA,EACnC,MAAM,gBAAgB,CAAC,SAAiB,KAAa,SAAwB;AAAA,IAC3E,IAAI,QAAQ,IAAI,MAAM;AAAA,MACpB;AAAA,IACF;AAAA,IACA,MAAM,aAAa,OAAO,KAAK,UAAU;AAAA,IACzC,YAAY,KAAK;AAAA,MACf,MAAM;AAAA,MACN,SAAS,GAAG,0BAA0B,iBAAiB;AAAA,MACvD,UAAU;AAAA,MACV,YAAY,OAAO;AAAA,IACrB,CAAC;AAAA;AAAA,EAGH,IAAI,OAAO,GAAG,WAAW,WAAW,CAAC,OAAO,GAAG,UAAU,UAAU;AAAA,IAEjE,QAAQ,aAAa,OAAO,GAAG;AAAA,IAC/B,MAAM,UAAU,kBAAkB,QAAQ;AAAA,IAC1C,WAAW,OAAO,SAAS,iBAAiB;AAAA,MAC1C,cAAc,cAAc,QAAQ,UAAU,KAAK,QAAQ,UAAU;AAAA,IACvE;AAAA,EACF;AAAA,EAGA,QAAQ,aAAa,OAAO;AAAA,EAC5B,WAAW,OAAO,SAAS,iBAAiB;AAAA,IAC1C,cAAc,WAAW,SAAS,SAAS,GAAG;AAAA,EAChD;AAAA,EAIA,WAAW,WAAW,OAAO,WAAW;AAAA,IACtC,WAAW,OAAO,QAAQ,iBAAiB;AAAA,MACzC,cAAc,cAAc,QAAQ,SAAS,GAAG;AAAA,IAClD;AAAA,EACF;AAAA,EAGA,WAAW,UAAU,OAAO,QAAQ,SAAS;AAAA,IAC3C,WAAW,OAAO,OAAO,iBAAiB;AAAA,MACxC,cAAc,mBAAmB,OAAO,SAAS,GAAG;AAAA,IACtD;AAAA,EACF;AAAA,EAIA,WAAW,WAAW,OAAO,WAAW;AAAA,IACtC,WAAW,OAAO,QAAQ,iBAAiB;AAAA,MACzC,cAAc,kBAAkB,QAAQ,SAAS,GAAG;AAAA,IACtD;AAAA,EACF;AAAA,EAIA,WAAW,OAAO,OAAO,WAAW,iBAAiB;AAAA,IACnD,cAAc,eAAe,OAAO,WAAW,SAAS,GAAG;AAAA,EAC7D;AAAA,EAEA,OAAO;AAAA;",
9
+ "debugId": "26CFBC953FC234CC64756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -4,7 +4,7 @@ import {
4
4
  customStaticRoutes,
5
5
  hasGeneratedChangelog,
6
6
  validateLinks
7
- } from "./chunk-xaz13gwg.js";
7
+ } from "./chunk-v6ya5kcb.js";
8
8
  import {
9
9
  commandMeta,
10
10
  reportInternalError,
@@ -14,11 +14,11 @@ import {
14
14
  reportDiagnosticsJson,
15
15
  reportDiagnostics
16
16
  } from "./index.js";
17
- import"./chunk-jts8mvcz.js";
17
+ import"./chunk-gs7r695n.js";
18
18
  import {
19
19
  buildManifest,
20
20
  scanProject
21
- } from "./chunk-zg2gtj10.js";
21
+ } from "./chunk-5r8g91qn.js";
22
22
 
23
23
  // src/cli/commands/validate.ts
24
24
  import { existsSync } from "node:fs";
@@ -99,4 +99,4 @@ export {
99
99
  };
100
100
 
101
101
  //# debugId=1EEBE4960D9C18F364756E2164756E21
102
- //# sourceMappingURL=chunk-y3e45rc8.js.map
102
+ //# sourceMappingURL=chunk-n1yg3tj3.js.map
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ deployPlatform,
3
4
  resolveProjectContext,
4
5
  loadConfig
5
- } from "./chunk-xaz13gwg.js";
6
- import"./chunk-jts8mvcz.js";
6
+ } from "./chunk-v6ya5kcb.js";
7
+ import"./chunk-gs7r695n.js";
7
8
  import {
8
9
  commandMeta,
9
10
  normalizeHost,
@@ -11,10 +12,13 @@ import {
11
12
  } from "./index.js";
12
13
  import {
13
14
  deployOutputDir
14
- } from "./chunk-nk3ts2xk.js";
15
+ } from "./chunk-hr8ne106.js";
16
+ import {
17
+ refuseIfEjected
18
+ } from "./chunk-4e9b9ra6.js";
15
19
  import {
16
20
  parsePort
17
- } from "./chunk-zxccj738.js";
21
+ } from "./chunk-esh98wmb.js";
18
22
 
19
23
  // src/cli/commands/preview.ts
20
24
  import { existsSync } from "node:fs";
@@ -29,8 +33,15 @@ var previewCommand = defineCommand({
29
33
  meta: commandMeta.preview,
30
34
  async run({ args }) {
31
35
  const root = process.cwd();
36
+ await refuseIfEjected(root, "preview");
32
37
  const { config } = await loadConfig(root);
33
38
  const context = resolveProjectContext(root, config);
39
+ const { deployment } = config;
40
+ const platform = deployPlatform(deployment);
41
+ if (deployment.options.output === "server" && platform.previewDeploy) {
42
+ logger.error(`\`blume preview\` can't serve a ${deployment.kind}() server build: ${platform.astro?.package} has no local preview server. Run \`blume dev\` to try the site locally, or deploy a preview with \`${platform.previewDeploy}\`.`);
43
+ process.exit(1);
44
+ }
34
45
  if (!existsSync(join(context.outDir, "astro.config.mjs")) || !existsSync(deployOutputDir(config, context))) {
35
46
  logger.error("No build found. Run `blume build` first.");
36
47
  process.exit(1);
@@ -49,5 +60,5 @@ export {
49
60
  previewCommand
50
61
  };
51
62
 
52
- //# debugId=7FC21538FC698FBD64756E2164756E21
53
- //# sourceMappingURL=chunk-bctazmbk.js.map
63
+ //# debugId=C7A2F5CE34388C8C64756E2164756E21
64
+ //# sourceMappingURL=chunk-nfcyttvj.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/cli/commands/preview.ts"],
4
+ "sourcesContent": [
5
+ "import { existsSync } from \"node:fs\";\n\nimport { preview } from \"astro\";\nimport { defineCommand } from \"citty\";\nimport { join } from \"pathe\";\n\nimport { loadConfig } from \"../../core/config.ts\";\nimport { resolveProjectContext } from \"../../core/project.ts\";\nimport { deployOutputDir } from \"../../deploy/adapter-output.ts\";\nimport { deployPlatform } from \"../../deploy/platforms/index.ts\";\nimport { parsePort } from \"../args.ts\";\nimport { commandMeta } from \"../command-meta.ts\";\nimport { refuseIfEjected } from \"../eject-scripts.ts\";\nimport { normalizeHost } from \"../host-args.ts\";\nimport { logger } from \"../log.ts\";\n\nexport const previewCommand = defineCommand({\n args: {\n host: { description: \"Network host to bind.\", type: \"string\" },\n port: { description: \"Port to listen on.\", type: \"string\" },\n },\n meta: commandMeta.preview,\n async run({ args }) {\n const root = process.cwd();\n await refuseIfEjected(root, \"preview\");\n const { config } = await loadConfig(root);\n const context = resolveProjectContext(root, config);\n\n // Astro previews a server build through its adapter's preview entrypoint,\n // and the Vercel and Netlify adapters declare none, so Astro would throw\n // mid-command. Say so up front, with what to run instead.\n const { deployment } = config;\n const platform = deployPlatform(deployment);\n if (deployment.options.output === \"server\" && platform.previewDeploy) {\n logger.error(\n `\\`blume preview\\` can't serve a ${deployment.kind}() server build: ${platform.astro?.package} has no local preview server. Run \\`blume dev\\` to try the site locally, or deploy a preview with \\`${platform.previewDeploy}\\`.`\n );\n process.exit(1);\n }\n\n // `blume dev` writes `.blume/astro.config.mjs` too, so the runtime alone\n // doesn't mean there's anything to serve: the build output must exist.\n if (\n !existsSync(join(context.outDir, \"astro.config.mjs\")) ||\n !existsSync(deployOutputDir(config, context))\n ) {\n logger.error(\"No build found. Run `blume build` first.\");\n process.exit(1);\n }\n\n await preview({\n logLevel: \"info\",\n root: context.outDir,\n server: {\n // `normalizeHost` maps a bare `--host` (citty parses it as \"\") to\n // `true` so Vite binds all interfaces instead of the hostname \"\".\n host: normalizeHost(args.host),\n port: parsePort(args.port),\n },\n });\n },\n});\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAEA;AACA;AACA;AAYO,IAAM,iBAAiB,cAAc;AAAA,EAC1C,MAAM;AAAA,IACJ,MAAM,EAAE,aAAa,yBAAyB,MAAM,SAAS;AAAA,IAC7D,MAAM,EAAE,aAAa,sBAAsB,MAAM,SAAS;AAAA,EAC5D;AAAA,EACA,MAAM,YAAY;AAAA,OACZ,IAAG,GAAG,QAAQ;AAAA,IAClB,MAAM,OAAO,QAAQ,IAAI;AAAA,IACzB,MAAM,gBAAgB,MAAM,SAAS;AAAA,IACrC,QAAQ,WAAW,MAAM,WAAW,IAAI;AAAA,IACxC,MAAM,UAAU,sBAAsB,MAAM,MAAM;AAAA,IAKlD,QAAQ,eAAe;AAAA,IACvB,MAAM,WAAW,eAAe,UAAU;AAAA,IAC1C,IAAI,WAAW,QAAQ,WAAW,YAAY,SAAS,eAAe;AAAA,MACpE,OAAO,MACL,mCAAmC,WAAW,wBAAwB,SAAS,OAAO,8GAA8G,SAAS,kBAC/M;AAAA,MACA,QAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,IAIA,IACE,CAAC,WAAW,KAAK,QAAQ,QAAQ,kBAAkB,CAAC,KACpD,CAAC,WAAW,gBAAgB,QAAQ,OAAO,CAAC,GAC5C;AAAA,MACA,OAAO,MAAM,0CAA0C;AAAA,MACvD,QAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,IAEA,MAAM,QAAQ;AAAA,MACZ,UAAU;AAAA,MACV,MAAM,QAAQ;AAAA,MACd,QAAQ;AAAA,QAGN,MAAM,cAAc,KAAK,IAAI;AAAA,QAC7B,MAAM,UAAU,KAAK,IAAI;AAAA,MAC3B;AAAA,IACF,CAAC;AAAA;AAEL,CAAC;",
8
+ "debugId": "C7A2F5CE34388C8C64756E2164756E21",
9
+ "names": []
10
+ }
@@ -10,7 +10,7 @@ import {
10
10
  } from "./index.js";
11
11
  import {
12
12
  AGENTS
13
- } from "./chunk-bw22s759.js";
13
+ } from "./chunk-6k4ftwze.js";
14
14
  import {
15
15
  frontmatter_default,
16
16
  i18nEnabled,
@@ -19,22 +19,23 @@ import {
19
19
  folderMetaSchema,
20
20
  scanBody,
21
21
  createModuleLoader
22
- } from "./chunk-xaz13gwg.js";
23
- import"./chunk-jts8mvcz.js";
24
- import {
25
- scanProject
26
- } from "./chunk-zg2gtj10.js";
22
+ } from "./chunk-v6ya5kcb.js";
27
23
  import {
28
24
  seconds,
29
25
  money,
30
26
  duration,
31
27
  DISALLOWED_TOOLS,
32
28
  runAgentHeadless,
29
+ CODEX_LOCKDOWN,
33
30
  readAgentOutput
34
- } from "./chunk-fa25z98p.js";
31
+ } from "./chunk-273ygyr4.js";
35
32
  import {
36
33
  writeTextAtomic
37
34
  } from "./chunk-jq5n4avg.js";
35
+ import"./chunk-gs7r695n.js";
36
+ import {
37
+ scanProject
38
+ } from "./chunk-5r8g91qn.js";
38
39
 
39
40
  // src/cli/commands/translate.ts
40
41
  import { defineCommand } from "citty";
@@ -58,6 +59,7 @@ var codexArgs = (lastMessagePath) => [
58
59
  "--ephemeral",
59
60
  "--sandbox",
60
61
  "read-only",
62
+ ...CODEX_LOCKDOWN,
61
63
  "--output-last-message",
62
64
  lastMessagePath,
63
65
  "-"
@@ -78,11 +80,15 @@ var emptyLedger = () => ({
78
80
  files: {},
79
81
  version: 1
80
82
  });
81
- var hashSource = (text) => createHash("sha256").update(text).digest("hex").slice(0, 16);
83
+ var hashSource = (text) => createHash("sha256").update(text.replaceAll(`\r
84
+ `, `
85
+ `)).digest("hex").slice(0, 16);
86
+ var CONFLICT_MARKER = /^(?:<{7}|={7}|>{7})(?:[ \r]|$)/mu;
82
87
  var readLedger = async (root) => {
88
+ const path = join(root, LEDGER_FILE);
83
89
  let raw;
84
90
  try {
85
- raw = await readFile(join(root, LEDGER_FILE), "utf-8");
91
+ raw = await readFile(path, "utf-8");
86
92
  } catch {
87
93
  return emptyLedger();
88
94
  }
@@ -90,6 +96,15 @@ var readLedger = async (root) => {
90
96
  try {
91
97
  data = JSON.parse(raw);
92
98
  } catch {
99
+ if (CONFLICT_MARKER.test(raw)) {
100
+ throw new BlumeError({
101
+ code: "BLUME_TRANSLATE_LEDGER_CONFLICT",
102
+ file: path,
103
+ message: `${LEDGER_FILE} has unresolved merge-conflict markers, so it can't say which translations are current.`,
104
+ severity: "error",
105
+ suggestion: `Resolve the merge conflict in ${LEDGER_FILE}, then rerun.`
106
+ });
107
+ }
93
108
  return emptyLedger();
94
109
  }
95
110
  const parsed = ledgerSchema.safeParse(data);
@@ -215,7 +230,7 @@ var driftDiagnostics = (workList) => driftRows(workList).map((row) => ({
215
230
  file: row.file,
216
231
  message: row.status === "missing" ? `${row.sourceRel} has no "${row.locale}" translation.` : `The "${row.locale}" translation of ${row.sourceRel} is stale: its source changed since it was translated.`,
217
232
  severity: "error",
218
- suggestion: "Run `blume translate --claude` (or `--codex`) to bring the translations up to date."
233
+ suggestion: "Run `blume translate --codex` (or `--claude`) to bring the translations up to date."
219
234
  }));
220
235
  var checkLines = (workList) => [
221
236
  ...driftRows(workList).map((row) => ` ${colors.red("✖")} ${row.sourceRel} → ${row.locale} ${colors.dim(row.status)}`),
@@ -345,7 +360,7 @@ import { mkdtemp, readFile as readFile3 } from "node:fs/promises";
345
360
  import { tmpdir } from "node:os";
346
361
  import pLimit from "p-limit";
347
362
  import pMap from "p-map";
348
- import { join as join3 } from "pathe";
363
+ import { dirname as dirname2, join as join3 } from "pathe";
349
364
 
350
365
  // src/translate/meta.ts
351
366
  import { readFile as readFile2 } from "node:fs/promises";
@@ -360,6 +375,7 @@ var discoverTranslatableMeta = async (project) => {
360
375
  return { diagnostics: [], metas: [] };
361
376
  }
362
377
  const localeDirs = new Set(i18n.locales.flatMap((locale) => locale.code === i18n.defaultLocale ? [] : [locale.code.toLowerCase()]));
378
+ const versionDirs = new Set(project.config.versions?.archived.map((version) => version.id));
363
379
  const load = createModuleLoader();
364
380
  const metas = [];
365
381
  const diagnostics = [];
@@ -373,8 +389,8 @@ var discoverTranslatableMeta = async (project) => {
373
389
  });
374
390
  for (const file of files.toSorted()) {
375
391
  const dir = relative(contentRoot, dirname(file));
376
- const first = dir.split("/")[0]?.toLowerCase();
377
- if (first && localeDirs.has(first)) {
392
+ const [head] = dir.split("/");
393
+ if (head && (localeDirs.has(head.toLowerCase()) || versionDirs.has(head))) {
378
394
  continue;
379
395
  }
380
396
  const [raw, mod] = await Promise.all([
@@ -549,7 +565,8 @@ var ensureTrailingNewline = (text) => text.endsWith(`
549
565
  `) ? text : `${text}
550
566
  `;
551
567
  var validateTranslation = (sourceText, agentText) => {
552
- const candidate = stripOuterFence(agentText);
568
+ const sourceIsFenced = stripOuterFence(sourceText) !== sourceText.trim();
569
+ const candidate = sourceIsFenced && countFenceLines(agentText) <= countFenceLines(sourceText) ? agentText.trim() : stripOuterFence(agentText);
553
570
  if (candidate === "") {
554
571
  return { ok: false, reason: "agent returned empty output" };
555
572
  }
@@ -622,7 +639,7 @@ var parseMetaTitles = (agentText, expectedKeys) => {
622
639
  };
623
640
 
624
641
  // src/translate/run.ts
625
- var metaDirKey = (dir) => dir === "" ? "." : dir;
642
+ var metaKey = (meta) => dirname2(meta.sourceRel);
626
643
  var invokeAgent = async (context, prompt, index) => {
627
644
  const messagePath = join3(context.dir, `message-${index}.txt`);
628
645
  const result = await context.run(context.bin, translateAgentArgs(context.kind, messagePath), { cwd: context.dir, prompt, timeoutMs: context.timeoutMs });
@@ -666,7 +683,7 @@ var runMetaItem = async (item, index, context, ledger) => {
666
683
  item,
667
684
  status
668
685
  });
669
- const titles = Object.fromEntries(item.entries.map((entry) => [metaDirKey(entry.meta.dir), entry.meta.title]));
686
+ const titles = Object.fromEntries(item.entries.map((entry) => [metaKey(entry.meta), entry.meta.title]));
670
687
  const target = context.targets.get(item.locale);
671
688
  const output = await invokeAgent(context, metaPrompt(titles, target, context.source), index);
672
689
  if (output.isError) {
@@ -674,7 +691,7 @@ var runMetaItem = async (item, index, context, ledger) => {
674
691
  }
675
692
  const parsed = parseMetaTitles(output.text, Object.keys(titles));
676
693
  for (const entry of item.entries) {
677
- const translated = parsed.titles[metaDirKey(entry.meta.dir)];
694
+ const translated = parsed.titles[metaKey(entry.meta)];
678
695
  if (translated === undefined) {
679
696
  continue;
680
697
  }
@@ -765,10 +782,23 @@ var runTranslate = async (options) => {
765
782
  };
766
783
 
767
784
  // src/translate/work-list.ts
768
- import { existsSync as existsSync2 } from "node:fs";
785
+ import { existsSync as existsSync2, readdirSync } from "node:fs";
769
786
  import { readFile as readFile4 } from "node:fs/promises";
770
- import { dirname as dirname2, extname, join as join4, relative as relative2 } from "pathe";
787
+ import { dirname as dirname3, extname, join as join4, relative as relative2 } from "pathe";
771
788
  var PAGE_EXTENSIONS = new Set([".md", ".mdx"]);
789
+ var rootFolders = () => {
790
+ const read = new Map;
791
+ return (contentRoot) => {
792
+ const cached = read.get(contentRoot);
793
+ if (cached) {
794
+ return cached;
795
+ }
796
+ const names = readdirSync(contentRoot);
797
+ read.set(contentRoot, names);
798
+ return names;
799
+ };
800
+ };
801
+ var scanForTranslation = (root) => scanProject(root, { mode: "dev" });
772
802
  var translatablePages = (project, i18n) => {
773
803
  const rootsByName = new Map(project.sources.flatMap((source) => source.staged || !source.contentRoot ? [] : [[source.name, source.contentRoot]]));
774
804
  const seen = new Set;
@@ -809,6 +839,7 @@ var partialWorkItems = async (universe, project, i18n, ledger, targetLocales, fo
809
839
  }
810
840
  const { root } = project.context;
811
841
  const pagePaths = new Set(project.graph.pages.flatMap((page) => page.sourcePath ? [page.sourcePath] : []));
842
+ const folders = rootFolders();
812
843
  const partials = new Map;
813
844
  for (const { page, contentRoot } of universe) {
814
845
  for (const partial of page.includes ?? []) {
@@ -825,7 +856,7 @@ var partialWorkItems = async (universe, project, i18n, ledger, targetLocales, fo
825
856
  const verbatim = !PAGE_EXTENSIONS.has(ext.toLowerCase());
826
857
  const contentRel = relative2(contentRoot, partialPath);
827
858
  for (const locale of targetLocales) {
828
- const targetPath = join4(contentRoot, localeTargetPath(contentRel, ext, locale, i18n));
859
+ const targetPath = join4(contentRoot, localeTargetPath(contentRel, ext, locale, i18n, folders(contentRoot)));
829
860
  const item = (status) => {
830
861
  const partialItem = {
831
862
  kind: "page",
@@ -874,13 +905,14 @@ var computeWorkList = async (project, ledger, options = {}) => {
874
905
  const pageItems = [];
875
906
  let upToDate = 0;
876
907
  const universe = translatablePages(project, i18n);
908
+ const folders = rootFolders();
877
909
  for (const { page, contentRoot, ext, sourcePath } of universe) {
878
910
  const sourceRel = relative2(root, sourcePath);
879
911
  knownSources.add(sourceRel);
880
912
  const hash = hashSource(await readFile4(sourcePath, "utf-8"));
881
913
  const contentRel = relative2(contentRoot, sourcePath);
882
914
  for (const locale of targetLocales) {
883
- const targetPath = join4(contentRoot, localeTargetPath(contentRel, ext, locale, i18n));
915
+ const targetPath = join4(contentRoot, localeTargetPath(contentRel, ext, locale, i18n, folders(contentRoot)));
884
916
  const item = (status) => ({
885
917
  kind: "page",
886
918
  locale,
@@ -915,7 +947,7 @@ var computeWorkList = async (project, ledger, options = {}) => {
915
947
  const entries = [];
916
948
  for (const source of meta.metas) {
917
949
  knownSources.add(source.sourceRel);
918
- const targetDir = dirname2(metaTargetPath(source, locale));
950
+ const targetDir = dirname3(metaTargetPath(source, locale));
919
951
  const exists = ["meta.ts", "meta.js", "meta.mjs"].some((name) => existsSync2(join4(targetDir, name)));
920
952
  const hash = hashSource(source.raw);
921
953
  const stamp = ledger.files[source.sourceRel]?.[locale];
@@ -961,15 +993,15 @@ var MAX_CONCURRENCY = 16;
961
993
  var parseFlags = (args) => {
962
994
  const agents = Object.keys(AGENTS).filter((kind) => args[kind]);
963
995
  if (agents.length > 1) {
964
- logger.error("Pass exactly one of --claude or --codex.");
996
+ logger.error("Pass exactly one of --codex or --claude.");
965
997
  process.exit(1);
966
998
  }
967
999
  if (args.check && agents.length > 0) {
968
- logger.error("--check is read-only and never runs an agent; drop --claude/--codex.");
1000
+ logger.error("--check is read-only and never runs an agent; drop --codex/--claude.");
969
1001
  process.exit(1);
970
1002
  }
971
1003
  if (!args.check && agents.length === 0) {
972
- logger.error("Pass --claude or --codex to choose the agent CLI that translates.");
1004
+ logger.error("Pass --codex or --claude to choose the agent CLI that translates.");
973
1005
  process.exit(1);
974
1006
  }
975
1007
  const timeoutS = args.timeout === undefined ? DEFAULT_TIMEOUT_S : Number(args.timeout);
@@ -1049,7 +1081,7 @@ var translateCommand = defineCommand({
1049
1081
  const root = process.cwd();
1050
1082
  const { agent, concurrency, timeoutS } = parseFlags(args);
1051
1083
  try {
1052
- const project = await scanProject(root, { mode: "build" });
1084
+ const project = await scanForTranslation(root);
1053
1085
  if (!i18nEnabled(project.config)) {
1054
1086
  logger.error("i18n is not configured — add `i18n.locales` to blume.config to use `blume translate`.");
1055
1087
  process.exit(1);
@@ -1142,5 +1174,5 @@ export {
1142
1174
  translateCommand
1143
1175
  };
1144
1176
 
1145
- //# debugId=0C250DC05B03939864756E2164756E21
1146
- //# sourceMappingURL=chunk-6k8vp3ta.js.map
1177
+ //# debugId=85D111C5AFB273C164756E2164756E21
1178
+ //# sourceMappingURL=chunk-pbg5a4s3.js.map