blume 2.0.1 → 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 (410) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/dist/cli/{chunk-vtk4a6dg.js → chunk-00gs3wqs.js} +1 -1
  3. package/dist/cli/{chunk-fa25z98p.js → chunk-273ygyr4.js} +4 -3
  4. package/dist/cli/chunk-273ygyr4.js.map +11 -0
  5. package/dist/cli/{chunk-yw7dm696.js → chunk-3yce002v.js} +21 -8
  6. package/dist/cli/{chunk-yw7dm696.js.map → chunk-3yce002v.js.map} +3 -3
  7. package/dist/cli/{chunk-yt5n7ppj.js → chunk-4e9b9ra6.js} +17 -7
  8. package/dist/cli/chunk-4e9b9ra6.js.map +10 -0
  9. package/dist/cli/{chunk-fs23ddbb.js → chunk-5r8g91qn.js} +352 -676
  10. package/dist/cli/chunk-5r8g91qn.js.map +34 -0
  11. package/dist/cli/{chunk-6vm74dry.js → chunk-6dtt0zfn.js} +8 -8
  12. package/dist/cli/{chunk-qwsrynx5.js → chunk-6k4ftwze.js} +38 -19
  13. package/dist/cli/{chunk-qwsrynx5.js.map → chunk-6k4ftwze.js.map} +4 -4
  14. package/dist/cli/{chunk-qs4q5p4e.js → chunk-7mbqtmgb.js} +16 -7
  15. package/dist/cli/chunk-7mbqtmgb.js.map +10 -0
  16. package/dist/cli/{chunk-q5163e60.js → chunk-7vtckvaw.js} +21 -19
  17. package/dist/cli/chunk-7vtckvaw.js.map +11 -0
  18. package/dist/cli/{chunk-kdp5q7ke.js → chunk-8g8ytmgx.js} +17 -18
  19. package/dist/cli/{chunk-kdp5q7ke.js.map → chunk-8g8ytmgx.js.map} +2 -2
  20. package/dist/cli/{chunk-epjnccmv.js → chunk-91ws1n6j.js} +18 -15
  21. package/dist/cli/chunk-91ws1n6j.js.map +10 -0
  22. package/dist/cli/{chunk-fxypxtvm.js → chunk-bbnwccaz.js} +2 -2
  23. package/dist/cli/{chunk-m3vmjgmq.js → chunk-bfwp9vp6.js} +16 -8
  24. package/dist/cli/chunk-bfwp9vp6.js.map +10 -0
  25. package/dist/cli/{chunk-f2z5v128.js → chunk-d1v5rhy0.js} +14 -15
  26. package/dist/cli/{chunk-f2z5v128.js.map → chunk-d1v5rhy0.js.map} +2 -2
  27. package/dist/cli/{chunk-6crbhc3x.js → chunk-ddndchfr.js} +21 -6
  28. package/dist/cli/chunk-ddndchfr.js.map +14 -0
  29. package/dist/cli/{chunk-ce574jw2.js → chunk-esh98wmb.js} +1 -1
  30. package/dist/cli/{chunk-zxcczpyx.js → chunk-fsmrqk8a.js} +1 -1
  31. package/dist/cli/{chunk-hdpx1tax.js → chunk-g698a744.js} +5 -5
  32. package/dist/cli/{chunk-jts8mvcz.js → chunk-gs7r695n.js} +9 -3
  33. package/dist/cli/{chunk-jts8mvcz.js.map → chunk-gs7r695n.js.map} +3 -3
  34. package/dist/cli/{chunk-zxh4d9vy.js → chunk-h2ez8dzb.js} +4 -4
  35. package/dist/cli/{chunk-5shv93fd.js → chunk-h7k3nq3v.js} +2 -2
  36. package/dist/cli/{chunk-79jhk4py.js → chunk-hqp2ajnh.js} +251 -122
  37. package/dist/cli/chunk-hqp2ajnh.js.map +35 -0
  38. package/dist/cli/{chunk-2hn4b8z7.js → chunk-hr8ne106.js} +109 -40
  39. package/dist/cli/chunk-hr8ne106.js.map +13 -0
  40. package/dist/cli/{chunk-6hsn950k.js → chunk-j85scx15.js} +62 -18
  41. package/dist/cli/chunk-j85scx15.js.map +10 -0
  42. package/dist/cli/{chunk-s1p84fyh.js → chunk-k7pj68a8.js} +63 -22
  43. package/dist/cli/chunk-k7pj68a8.js.map +11 -0
  44. package/dist/cli/{chunk-ah61y8py.js → chunk-mqc662a6.js} +2 -2
  45. package/dist/cli/{chunk-ch6g3ar0.js → chunk-n1yg3tj3.js} +4 -4
  46. package/dist/cli/{chunk-mb2919y2.js → chunk-nfcyttvj.js} +17 -6
  47. package/dist/cli/chunk-nfcyttvj.js.map +10 -0
  48. package/dist/cli/{chunk-kpf8rrjc.js → chunk-pbg5a4s3.js} +56 -24
  49. package/dist/cli/chunk-pbg5a4s3.js.map +19 -0
  50. package/dist/cli/{chunk-jwyddg7y.js → chunk-ppzjqwx2.js} +21 -14
  51. package/dist/cli/{chunk-jwyddg7y.js.map → chunk-ppzjqwx2.js.map} +4 -4
  52. package/dist/cli/{chunk-dh8cwk36.js → chunk-qkb5a8sa.js} +24 -9
  53. package/dist/cli/chunk-qkb5a8sa.js.map +10 -0
  54. package/dist/cli/{chunk-wm7js3j9.js → chunk-sqw4ekg1.js} +2 -2
  55. package/dist/cli/{chunk-qkqwkpte.js → chunk-v6ya5kcb.js} +3083 -953
  56. package/dist/cli/chunk-v6ya5kcb.js.map +189 -0
  57. package/dist/cli/{chunk-fz5wtpmh.js → chunk-w4bxdvsa.js} +18 -15
  58. package/dist/cli/chunk-w4bxdvsa.js.map +10 -0
  59. package/dist/cli/{chunk-27g6wdth.js → chunk-wdrt2k2v.js} +2 -2
  60. package/dist/cli/{chunk-wgm7m9qk.js → chunk-xh43dwgw.js} +158 -43
  61. package/dist/cli/chunk-xh43dwgw.js.map +36 -0
  62. package/dist/cli/{chunk-s6jhgk0q.js → chunk-zp79m0ts.js} +2 -2
  63. package/dist/cli/index.js +160 -35
  64. package/dist/cli/index.js.map +4 -4
  65. package/dist/types/ai/agent-surface.d.ts +32 -0
  66. package/dist/types/ai/api-catalog.d.ts +7 -1
  67. package/dist/types/ai/ask-context.d.ts +7 -0
  68. package/dist/types/ai/component-markdown.d.ts +4 -4
  69. package/dist/types/ai/relative-links.d.ts +9 -4
  70. package/dist/types/ai/static-expression.d.ts +28 -0
  71. package/dist/types/analytics/databuddy.d.ts +43 -0
  72. package/dist/types/analytics/index.d.ts +2 -0
  73. package/dist/types/analytics/schema.d.ts +14 -0
  74. package/dist/types/cli/env.d.ts +5 -0
  75. package/dist/types/cli/init/scaffold.d.ts +19 -3
  76. package/dist/types/cli/init/starter-spec.d.ts +11 -0
  77. package/dist/types/core/base-path.d.ts +9 -0
  78. package/dist/types/core/config-input.d.ts +4 -4
  79. package/dist/types/core/config.d.ts +2 -2
  80. package/dist/types/core/graph.d.ts +2 -0
  81. package/dist/types/core/i18n-ui.d.ts +31 -0
  82. package/dist/types/core/i18n.d.ts +7 -1
  83. package/dist/types/core/links.d.ts +3 -1
  84. package/dist/types/core/load-module.d.ts +10 -0
  85. package/dist/types/core/locale-links.d.ts +12 -2
  86. package/dist/types/core/meta.d.ts +5 -1
  87. package/dist/types/core/nav-diagnostics.d.ts +10 -0
  88. package/dist/types/core/navigation.d.ts +38 -0
  89. package/dist/types/core/ordering-prefix.d.ts +4 -0
  90. package/dist/types/core/safe-links.d.ts +3 -1
  91. package/dist/types/core/schema.d.ts +52 -13
  92. package/dist/types/core/sources/github-releases.d.ts +5 -0
  93. package/dist/types/core/sources/lower.d.ts +14 -2
  94. package/dist/types/core/sources/normalize.d.ts +10 -1
  95. package/dist/types/core/sources/remote.d.ts +11 -1
  96. package/dist/types/core/sources/resolve.d.ts +12 -0
  97. package/dist/types/core/sources/types.d.ts +31 -0
  98. package/dist/types/core/types.d.ts +9 -0
  99. package/dist/types/deploy/adapters/node.d.ts +5 -2
  100. package/dist/types/deploy/adapters/types.d.ts +7 -0
  101. package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
  102. package/dist/types/deploy/headers.d.ts +31 -7
  103. package/dist/types/deploy/node-headers.d.ts +43 -8
  104. package/dist/types/deploy/platforms/netlify.d.ts +27 -2
  105. package/dist/types/deploy/platforms/node.d.ts +6 -5
  106. package/dist/types/deploy/platforms/types.d.ts +7 -0
  107. package/dist/types/deploy/platforms/vercel.d.ts +3 -2
  108. package/dist/types/deploy/redirects.d.ts +7 -2
  109. package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
  110. package/dist/types/openapi/model.d.ts +20 -6
  111. package/dist/types/search/sync/algolia.d.ts +3 -1
  112. package/docs/01-quickstart.mdx +3 -2
  113. package/docs/02-deployment.mdx +17 -8
  114. package/docs/08-faq.mdx +9 -2
  115. package/docs/advanced/changelog.mdx +1 -1
  116. package/docs/advanced/custom-pages.mdx +4 -2
  117. package/docs/cli/audit.mdx +2 -2
  118. package/docs/cli/doctor.mdx +2 -2
  119. package/docs/cli/evals.mdx +2 -2
  120. package/docs/cli/index.mdx +4 -1
  121. package/docs/cli/translate.mdx +1 -1
  122. package/docs/configuration/analytics.mdx +23 -2
  123. package/docs/configuration/assistant.mdx +1 -1
  124. package/docs/configuration/customization.mdx +4 -3
  125. package/docs/configuration/index.mdx +5 -3
  126. package/docs/configuration/search.mdx +1 -1
  127. package/docs/content/components.mdx +1 -1
  128. package/docs/content/frontmatter.mdx +5 -1
  129. package/docs/content/i18n.mdx +1 -1
  130. package/docs/content/index.mdx +4 -2
  131. package/docs/content/meta.mdx +5 -3
  132. package/docs/content/navigation.mdx +29 -4
  133. package/docs/content/sources.mdx +18 -12
  134. package/docs/content/versioning.mdx +1 -0
  135. package/docs/discoverability/agent-discovery.mdx +21 -7
  136. package/docs/discoverability/index.mdx +2 -2
  137. package/docs/discoverability/llms-txt.mdx +2 -5
  138. package/docs/discoverability/markdown.mdx +5 -3
  139. package/docs/discoverability/mcp.mdx +4 -0
  140. package/docs/discoverability/metadata.mdx +3 -2
  141. package/docs/discoverability/open-graph.mdx +6 -4
  142. package/docs/discoverability/rss.mdx +3 -1
  143. package/docs/references/asyncapi.mdx +1 -1
  144. package/docs/references/graphql.mdx +2 -2
  145. package/docs/references/openapi.mdx +3 -3
  146. package/package.json +1 -1
  147. package/skills/blume-migrate/SKILL.md +6 -6
  148. package/skills/blume-migrate/references/docusaurus.md +6 -6
  149. package/skills/blume-migrate/references/mintlify.md +3 -3
  150. package/skills/blume-migrate/references/monorepo.md +1 -1
  151. package/skills/blume-migrate/references/nextra.md +1 -1
  152. package/skills/blume-migrate/references/starlight.md +5 -5
  153. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +2 -2
  154. package/skills/blume-update-docs/references/audit-checklist.md +1 -1
  155. package/src/ai/agent-surface.ts +56 -0
  156. package/src/ai/api/spec.ts +15 -2
  157. package/src/ai/api-catalog.ts +7 -1
  158. package/src/ai/ask-context.ts +14 -2
  159. package/src/ai/ask-data.ts +26 -12
  160. package/src/ai/component-markdown.ts +43 -37
  161. package/src/ai/link-headers.ts +8 -3
  162. package/src/ai/llms.ts +4 -3
  163. package/src/ai/markdown.ts +23 -11
  164. package/src/ai/mcp/server.ts +78 -7
  165. package/src/ai/relative-links.ts +78 -10
  166. package/src/ai/static-expression.ts +416 -0
  167. package/src/ai/visibility.ts +45 -14
  168. package/src/analytics/databuddy.ts +67 -0
  169. package/src/analytics/head.ts +4 -0
  170. package/src/analytics/index.ts +2 -0
  171. package/src/analytics/posthog.ts +21 -3
  172. package/src/analytics/schema.ts +2 -0
  173. package/src/astro/generate.ts +71 -27
  174. package/src/astro/templates.ts +61 -23
  175. package/src/audit/catalog.ts +2 -2
  176. package/src/audit/checks/assets.ts +25 -5
  177. package/src/audit/checks/content.ts +20 -2
  178. package/src/audit/checks/i18n.ts +46 -8
  179. package/src/audit/checks/indexability.ts +39 -19
  180. package/src/audit/checks/links.ts +14 -0
  181. package/src/audit/checks/llms.ts +6 -3
  182. package/src/audit/checks/network.ts +3 -1
  183. package/src/audit/checks/og-image.ts +10 -0
  184. package/src/audit/checks/robots.ts +6 -1
  185. package/src/audit/checks/sitemap.ts +56 -31
  186. package/src/audit/checks/social.ts +21 -2
  187. package/src/audit/crawl.ts +88 -15
  188. package/src/audit/report.ts +54 -17
  189. package/src/audit/run.ts +1 -0
  190. package/src/audit/types.ts +18 -0
  191. package/src/audit/url.ts +37 -6
  192. package/src/cli/build-failure.ts +50 -0
  193. package/src/cli/commands/audit.ts +7 -0
  194. package/src/cli/commands/build.ts +19 -5
  195. package/src/cli/commands/check.ts +2 -0
  196. package/src/cli/commands/eval.ts +1 -7
  197. package/src/cli/commands/init.ts +15 -5
  198. package/src/cli/commands/preview.ts +15 -0
  199. package/src/cli/commands/sync.ts +2 -0
  200. package/src/cli/commands/translate.ts +9 -6
  201. package/src/cli/commands/upgrade.ts +11 -0
  202. package/src/cli/eject-scripts.ts +32 -7
  203. package/src/cli/env.ts +12 -1
  204. package/src/cli/init/scaffold.ts +117 -11
  205. package/src/cli/init/starter-spec.ts +235 -0
  206. package/src/components/content/AccordionItem.astro +26 -22
  207. package/src/components/content/Badge.astro +2 -9
  208. package/src/components/content/Card.astro +2 -2
  209. package/src/components/content/Component.astro +9 -3
  210. package/src/components/content/Expandable.astro +5 -1
  211. package/src/components/content/Frame.astro +2 -7
  212. package/src/components/content/GithubInfo.astro +12 -2
  213. package/src/components/content/Prompt.astro +2 -7
  214. package/src/components/content/Tabs.astro +54 -5
  215. package/src/components/content/Tile.astro +1 -1
  216. package/src/components/content/Tooltip.astro +69 -7
  217. package/src/components/content/Tree.astro +7 -2
  218. package/src/components/content/TypeTable.astro +10 -5
  219. package/src/components/content/Update.astro +8 -2
  220. package/src/components/content/auto-type-table.ts +4 -1
  221. package/src/components/content/badge-color.ts +17 -0
  222. package/src/components/content/base-href.ts +18 -3
  223. package/src/components/content/inline-markdown.ts +27 -7
  224. package/src/components/copy-feedback.ts +35 -8
  225. package/src/components/islands/assistant.tsx +16 -2
  226. package/src/components/islands/hooks.ts +7 -2
  227. package/src/components/islands/webmcp.ts +12 -8
  228. package/src/components/layout/Banner.astro +23 -4
  229. package/src/components/layout/Header.astro +22 -9
  230. package/src/components/layout/Logo.astro +5 -0
  231. package/src/components/layout/NavSelector.astro +6 -1
  232. package/src/components/layout/NavTabMenu.astro +133 -0
  233. package/src/components/layout/NavTree.astro +15 -6
  234. package/src/components/layout/NavTreeCache.astro +5 -2
  235. package/src/components/layout/NavTreeScript.astro +45 -5
  236. package/src/components/layout/PageLayout.astro +22 -8
  237. package/src/components/layout/ReferenceLayout.astro +4 -1
  238. package/src/components/layout/RootLayout.astro +21 -8
  239. package/src/components/layout/Search.astro +5 -1
  240. package/src/components/layout/analytics-client.ts +2 -0
  241. package/src/components/openapi/GraphqlType.astro +11 -3
  242. package/src/components/openapi/MessageComposer.astro +1 -1
  243. package/src/components/openapi/Operation.astro +21 -5
  244. package/src/components/openapi/PanelTabs.astro +4 -1
  245. package/src/components/openapi/Playground.astro +8 -2
  246. package/src/components/openapi/RequestPanel.astro +9 -5
  247. package/src/components/openapi/SchemaProperty.astro +11 -33
  248. package/src/components/openapi/SchemaTable.astro +27 -52
  249. package/src/components/openapi/helpers.ts +90 -12
  250. package/src/components/openapi/message-composer.ts +8 -0
  251. package/src/components/openapi/message-model.ts +12 -2
  252. package/src/components/openapi/message.ts +4 -1
  253. package/src/components/openapi/operation-model.ts +40 -8
  254. package/src/components/openapi/panel.ts +29 -5
  255. package/src/components/openapi/playground-client.ts +37 -7
  256. package/src/components/openapi/playground-schema.ts +25 -6
  257. package/src/components/openapi/request.ts +2 -0
  258. package/src/components/openapi/schema-tree.ts +203 -0
  259. package/src/components/openapi/snippets.ts +30 -15
  260. package/src/components/openapi/validate-json.ts +1 -1
  261. package/src/core/base-path.ts +15 -0
  262. package/src/core/config-input.ts +4 -4
  263. package/src/core/config.ts +18 -4
  264. package/src/core/diagnostics.ts +217 -30
  265. package/src/core/graph.ts +120 -11
  266. package/src/core/i18n-ui.ts +39 -2
  267. package/src/core/i18n.ts +13 -2
  268. package/src/core/links.ts +7 -4
  269. package/src/core/load-module.ts +20 -0
  270. package/src/core/locale-links.ts +17 -17
  271. package/src/core/manifest.ts +3 -2
  272. package/src/core/meta.ts +69 -6
  273. package/src/core/nav-diagnostics.ts +56 -1
  274. package/src/core/navigation.ts +245 -76
  275. package/src/core/ordering-prefix.ts +27 -0
  276. package/src/core/project-graph.ts +23 -1
  277. package/src/core/safe-href.ts +53 -1
  278. package/src/core/safe-links.ts +11 -2
  279. package/src/core/schema.ts +70 -14
  280. package/src/core/sources/assets.ts +83 -41
  281. package/src/core/sources/contentful-rich-text.ts +3 -2
  282. package/src/core/sources/contentful.ts +25 -12
  283. package/src/core/sources/filesystem.ts +5 -1
  284. package/src/core/sources/github-releases.ts +106 -5
  285. package/src/core/sources/lexical.ts +9 -4
  286. package/src/core/sources/lower.ts +79 -26
  287. package/src/core/sources/mdx-remote.ts +1 -0
  288. package/src/core/sources/normalize.ts +132 -30
  289. package/src/core/sources/notion.ts +26 -10
  290. package/src/core/sources/obsidian.ts +17 -3
  291. package/src/core/sources/payload.ts +1 -0
  292. package/src/core/sources/portable-text.ts +63 -44
  293. package/src/core/sources/remote.ts +18 -2
  294. package/src/core/sources/resolve.ts +52 -33
  295. package/src/core/sources/sanity.ts +1 -0
  296. package/src/core/sources/strapi-blocks.ts +9 -4
  297. package/src/core/sources/strapi.ts +1 -0
  298. package/src/core/sources/types.ts +31 -0
  299. package/src/core/types.ts +9 -0
  300. package/src/core/ui-packs/ar.ts +13 -0
  301. package/src/core/ui-packs/bg.ts +13 -0
  302. package/src/core/ui-packs/bn.ts +13 -0
  303. package/src/core/ui-packs/ca.ts +13 -0
  304. package/src/core/ui-packs/cs.ts +13 -0
  305. package/src/core/ui-packs/da.ts +13 -0
  306. package/src/core/ui-packs/de.ts +13 -0
  307. package/src/core/ui-packs/el.ts +13 -0
  308. package/src/core/ui-packs/es.ts +13 -0
  309. package/src/core/ui-packs/fa.ts +13 -0
  310. package/src/core/ui-packs/fi.ts +13 -0
  311. package/src/core/ui-packs/fr.ts +13 -0
  312. package/src/core/ui-packs/he.ts +13 -0
  313. package/src/core/ui-packs/hi.ts +13 -0
  314. package/src/core/ui-packs/hr.ts +13 -0
  315. package/src/core/ui-packs/hu.ts +13 -0
  316. package/src/core/ui-packs/id.ts +13 -0
  317. package/src/core/ui-packs/it.ts +13 -0
  318. package/src/core/ui-packs/ja.ts +13 -0
  319. package/src/core/ui-packs/ko.ts +13 -0
  320. package/src/core/ui-packs/nl.ts +13 -0
  321. package/src/core/ui-packs/no.ts +13 -0
  322. package/src/core/ui-packs/pl.ts +13 -0
  323. package/src/core/ui-packs/pt-br.ts +13 -0
  324. package/src/core/ui-packs/pt.ts +13 -0
  325. package/src/core/ui-packs/ro.ts +13 -0
  326. package/src/core/ui-packs/ru.ts +13 -0
  327. package/src/core/ui-packs/sk.ts +13 -0
  328. package/src/core/ui-packs/sr.ts +13 -0
  329. package/src/core/ui-packs/sv.ts +13 -0
  330. package/src/core/ui-packs/th.ts +13 -0
  331. package/src/core/ui-packs/tr.ts +13 -0
  332. package/src/core/ui-packs/uk.ts +13 -0
  333. package/src/core/ui-packs/vi.ts +13 -0
  334. package/src/core/ui-packs/zh-tw.ts +13 -0
  335. package/src/core/ui-packs/zh.ts +13 -0
  336. package/src/core/version-cut.ts +17 -2
  337. package/src/core/versions.ts +4 -1
  338. package/src/deploy/adapters/node.ts +5 -2
  339. package/src/deploy/adapters/registry.ts +2 -1
  340. package/src/deploy/adapters/types.ts +13 -1
  341. package/src/deploy/artifacts.ts +25 -5
  342. package/src/deploy/cloudflare-negotiation.ts +23 -4
  343. package/src/deploy/headers.ts +67 -51
  344. package/src/deploy/node-headers.ts +148 -27
  345. package/src/deploy/platforms/cloudflare.ts +1 -0
  346. package/src/deploy/platforms/netlify.ts +82 -5
  347. package/src/deploy/platforms/node.ts +7 -5
  348. package/src/deploy/platforms/static.ts +1 -0
  349. package/src/deploy/platforms/types.ts +7 -0
  350. package/src/deploy/platforms/vercel.ts +9 -3
  351. package/src/deploy/redirects.ts +14 -3
  352. package/src/deploy/vercel-negotiation.ts +35 -3
  353. package/src/eval/agents.ts +10 -2
  354. package/src/eval/run.ts +25 -0
  355. package/src/markdown/base-links.ts +55 -8
  356. package/src/markdown/index.ts +6 -3
  357. package/src/markdown/relative-links.ts +3 -23
  358. package/src/markdown/route-snapshot.ts +37 -0
  359. package/src/og/card.ts +20 -4
  360. package/src/og/derive.ts +145 -4
  361. package/src/openapi/graphql-build.ts +28 -2
  362. package/src/openapi/model.ts +77 -13
  363. package/src/openapi/render-mdx.ts +10 -1
  364. package/src/registry/eject.ts +119 -22
  365. package/src/search/documents.ts +22 -1
  366. package/src/search/sync/algolia.ts +36 -2
  367. package/src/sources/registry.ts +5 -0
  368. package/src/theme/entry.ts +11 -4
  369. package/src/translate/agents.ts +6 -1
  370. package/src/translate/ledger.ts +26 -3
  371. package/src/translate/meta.ts +11 -3
  372. package/src/translate/run.ts +11 -5
  373. package/src/translate/validate.ts +10 -1
  374. package/src/translate/work-list.ts +36 -3
  375. package/src/upgrade/upgrade.ts +36 -4
  376. package/dist/cli/chunk-2hn4b8z7.js.map +0 -12
  377. package/dist/cli/chunk-6crbhc3x.js.map +0 -14
  378. package/dist/cli/chunk-6hsn950k.js.map +0 -10
  379. package/dist/cli/chunk-79jhk4py.js.map +0 -35
  380. package/dist/cli/chunk-82bbrxdn.js +0 -51
  381. package/dist/cli/chunk-82bbrxdn.js.map +0 -10
  382. package/dist/cli/chunk-abh8yjkn.js +0 -31
  383. package/dist/cli/chunk-abh8yjkn.js.map +0 -10
  384. package/dist/cli/chunk-dh8cwk36.js.map +0 -10
  385. package/dist/cli/chunk-epjnccmv.js.map +0 -10
  386. package/dist/cli/chunk-fa25z98p.js.map +0 -11
  387. package/dist/cli/chunk-fs23ddbb.js.map +0 -35
  388. package/dist/cli/chunk-fz5wtpmh.js.map +0 -10
  389. package/dist/cli/chunk-kpf8rrjc.js.map +0 -19
  390. package/dist/cli/chunk-m3vmjgmq.js.map +0 -10
  391. package/dist/cli/chunk-mb2919y2.js.map +0 -10
  392. package/dist/cli/chunk-q5163e60.js.map +0 -11
  393. package/dist/cli/chunk-qkqwkpte.js.map +0 -182
  394. package/dist/cli/chunk-qs4q5p4e.js.map +0 -10
  395. package/dist/cli/chunk-s1p84fyh.js.map +0 -10
  396. package/dist/cli/chunk-wgm7m9qk.js.map +0 -36
  397. package/dist/cli/chunk-yt5n7ppj.js.map +0 -10
  398. /package/dist/cli/{chunk-vtk4a6dg.js.map → chunk-00gs3wqs.js.map} +0 -0
  399. /package/dist/cli/{chunk-6vm74dry.js.map → chunk-6dtt0zfn.js.map} +0 -0
  400. /package/dist/cli/{chunk-fxypxtvm.js.map → chunk-bbnwccaz.js.map} +0 -0
  401. /package/dist/cli/{chunk-ce574jw2.js.map → chunk-esh98wmb.js.map} +0 -0
  402. /package/dist/cli/{chunk-zxcczpyx.js.map → chunk-fsmrqk8a.js.map} +0 -0
  403. /package/dist/cli/{chunk-hdpx1tax.js.map → chunk-g698a744.js.map} +0 -0
  404. /package/dist/cli/{chunk-zxh4d9vy.js.map → chunk-h2ez8dzb.js.map} +0 -0
  405. /package/dist/cli/{chunk-5shv93fd.js.map → chunk-h7k3nq3v.js.map} +0 -0
  406. /package/dist/cli/{chunk-ah61y8py.js.map → chunk-mqc662a6.js.map} +0 -0
  407. /package/dist/cli/{chunk-ch6g3ar0.js.map → chunk-n1yg3tj3.js.map} +0 -0
  408. /package/dist/cli/{chunk-wm7js3j9.js.map → chunk-sqw4ekg1.js.map} +0 -0
  409. /package/dist/cli/{chunk-27g6wdth.js.map → chunk-wdrt2k2v.js.map} +0 -0
  410. /package/dist/cli/{chunk-s6jhgk0q.js.map → chunk-zp79m0ts.js.map} +0 -0
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/deploy/adapter-output.ts"],
4
- "sourcesContent": [
5
- "import { existsSync } from \"node:fs\";\nimport { cp, mkdir, rm } from \"node:fs/promises\";\n\nimport { dirname, join } from \"pathe\";\n\nimport type { ResolvedConfig } from \"../core/schema.ts\";\nimport type { ProjectContext } from \"../core/types.ts\";\nimport type { ResolvedDeployment } from \"./adapters/registry.ts\";\nimport { deployPlatform } from \"./platforms/index.ts\";\nimport { distDir } from \"./platforms/paths.ts\";\n\n/**\n * Where a build's output lands. Every static build and most server builds\n * write to Astro's `outDir`; the Vercel adapter writes its Build Output tree\n * beside it instead. Each platform declares its own (see `deploy/platforms`).\n */\nexport const deployOutputDir = (\n config: ResolvedConfig,\n context: ProjectContext\n): string => {\n const { deployment } = config;\n return deployment.options.output === \"server\"\n ? deployPlatform(deployment).serverOutputDir(context)\n : distDir(context);\n};\n\n/**\n * Directory whose contents the deploy platform serves as static files. Build\n * artifacts (robots.txt, sitemap.xml, llms.txt, …) must be written here to be\n * served. A static build serves `dist/` wherever it lands; a server build\n * serves what its platform declares — the Build Output tree's `static/` half\n * on Vercel, Astro's `build.client` dir (`dist/client/`) on Node and\n * Cloudflare, `dist/` on Netlify.\n */\nexport const deployStaticDir = (\n config: ResolvedConfig,\n context: ProjectContext\n): string => {\n const { deployment } = config;\n return deployment.options.output === \"server\"\n ? deployPlatform(deployment).serverStaticDir(context)\n : distDir(context);\n};\n\n/**\n * Whether the platform applies a `_headers` file to the static assets it\n * serves — true where Netlify or Cloudflare read one, including a Cloudflare\n * **server** build (the Worker serves `dist/client` through its ASSETS\n * binding, which honors `_headers` exactly as Pages does), and for a static\n * build with no named host. Deliberately false where the file would be inert:\n * Node's standalone server has its own static handler with no `_headers`\n * support, and Vercel's headers arrive through the routing config instead.\n * Reporting a header that is not applied is worse than omitting it.\n */\nexport const readsHeaderFiles = (deployment: ResolvedDeployment): boolean =>\n deployPlatform(deployment).readsHeaderFiles[deployment.options.output];\n\n/** Outcome of {@link surfaceAdapterOutput}, for logging. */\nexport type SurfaceResult =\n | { moved: false }\n | { from: string; moved: true; to: string };\n\n/**\n * Move a server adapter's deploy bundle out of the hidden `.blume` runtime and\n * up to the project root, where the deploy platform expects it. A no-op for\n * static builds, for platforms whose bundle already lands where they look\n * (`hiddenRuntime.surfacePath` is null), and when the expected output is\n * absent.\n */\nexport const surfaceAdapterOutput = async (\n config: ResolvedConfig,\n context: ProjectContext\n): Promise<SurfaceResult> => {\n const { deployment } = config;\n if (deployment.options.output !== \"server\") {\n return { moved: false };\n }\n const rel = deployPlatform(deployment).hiddenRuntime.surfacePath;\n if (!rel) {\n return { moved: false };\n }\n const from = join(context.outDir, rel);\n const to = join(context.root, rel);\n if (!existsSync(from)) {\n return { moved: false };\n }\n await mkdir(dirname(to), { recursive: true });\n await rm(to, { force: true, recursive: true });\n // `verbatimSymlinks` keeps each symlink's target text as written. Without it,\n // `cp` resolves every relative target against the *source*, rewriting it to an\n // absolute path under `.blume` — which this function then deletes. Adapters\n // that trace dependencies into their function bundle link one package to\n // another that way (under an isolated linker — Bun's `isolated` mode, pnpm —\n // that is every external dependency the function imports), so the resolved\n // links leave the deployed function dying on its first external import with\n // ERR_MODULE_NOT_FOUND. Verbatim, the links stay relative and internal to the\n // bundle, surviving both this move and the platform's own (Vercel mounts the\n // bundle at `/var/task`).\n try {\n await cp(from, to, { recursive: true, verbatimSymlinks: true });\n } catch (error) {\n // SAFETY: a rejected `cp` always yields a Node system error, whose `code`\n // is the only field read here.\n if ((error as NodeJS.ErrnoException).code !== \"EPERM\") {\n throw error;\n }\n // `EPERM` is Windows refusing to create a symlink without Developer Mode\n // or admin rights (the same answer `symlinkDir` handles for the deps\n // link). Copy through the links instead: each becomes an ordinary\n // directory holding its target's files — bigger, but self-contained.\n await rm(to, { force: true, recursive: true });\n await cp(from, to, { dereference: true, recursive: true });\n }\n await rm(from, { force: true, recursive: true });\n return { from, moved: true, to };\n};\n"
6
- ],
7
- "mappings": ";;;;;;;AAAA;AACA;AAEA;AAaO,IAAM,kBAAkB,CAC7B,QACA,YACW;AAAA,EACX,QAAQ,eAAe;AAAA,EACvB,OAAO,WAAW,QAAQ,WAAW,WACjC,eAAe,UAAU,EAAE,gBAAgB,OAAO,IAClD,QAAQ,OAAO;AAAA;AAWd,IAAM,kBAAkB,CAC7B,QACA,YACW;AAAA,EACX,QAAQ,eAAe;AAAA,EACvB,OAAO,WAAW,QAAQ,WAAW,WACjC,eAAe,UAAU,EAAE,gBAAgB,OAAO,IAClD,QAAQ,OAAO;AAAA;AA4Bd,IAAM,uBAAuB,OAClC,QACA,YAC2B;AAAA,EAC3B,QAAQ,eAAe;AAAA,EACvB,IAAI,WAAW,QAAQ,WAAW,UAAU;AAAA,IAC1C,OAAO,EAAE,OAAO,MAAM;AAAA,EACxB;AAAA,EACA,MAAM,MAAM,eAAe,UAAU,EAAE,cAAc;AAAA,EACrD,IAAI,CAAC,KAAK;AAAA,IACR,OAAO,EAAE,OAAO,MAAM;AAAA,EACxB;AAAA,EACA,MAAM,OAAO,KAAK,QAAQ,QAAQ,GAAG;AAAA,EACrC,MAAM,KAAK,KAAK,QAAQ,MAAM,GAAG;AAAA,EACjC,IAAI,CAAC,WAAW,IAAI,GAAG;AAAA,IACrB,OAAO,EAAE,OAAO,MAAM;AAAA,EACxB;AAAA,EACA,MAAM,MAAM,QAAQ,EAAE,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5C,MAAM,GAAG,IAAI,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AAAA,EAW7C,IAAI;AAAA,IACF,MAAM,GAAG,MAAM,IAAI,EAAE,WAAW,MAAM,kBAAkB,KAAK,CAAC;AAAA,IAC9D,OAAO,OAAO;AAAA,IAGd,IAAK,MAAgC,SAAS,SAAS;AAAA,MACrD,MAAM;AAAA,IACR;AAAA,IAKA,MAAM,GAAG,IAAI,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AAAA,IAC7C,MAAM,GAAG,MAAM,IAAI,EAAE,aAAa,MAAM,WAAW,KAAK,CAAC;AAAA;AAAA,EAE3D,MAAM,GAAG,MAAM,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AAAA,EAC/C,OAAO,EAAE,MAAM,OAAO,MAAM,GAAG;AAAA;",
8
- "debugId": "8B79889B6B3550F964756E2164756E21",
9
- "names": []
10
- }
@@ -1,31 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/core/sources/watch.ts
4
- var BLUME_IGNORE_DIRS = [
5
- ".blume",
6
- ".blume-verify",
7
- ".cache",
8
- ".git",
9
- ".next",
10
- ".turbo",
11
- ".vercel",
12
- "dist",
13
- "node_modules"
14
- ];
15
- var baselineScanIgnore = () => BLUME_IGNORE_DIRS.map((dir) => `**/${dir}/**`);
16
- var BLUME_WATCH_IGNORE_DIRS = BLUME_IGNORE_DIRS;
17
- var excludeDirSegments = (patterns) => patterns.map((pattern) => /^(?<dir>[^*/]+)\/\*\*$/u.exec(pattern)?.groups?.dir).filter((dir) => dir !== undefined);
18
- var ignoringWatchListener = (onChange, ignoreDirs = BLUME_WATCH_IGNORE_DIRS, ignoreSegment = () => false) => {
19
- const ignore = new Set(ignoreDirs);
20
- return (_event, filename) => {
21
- if (filename !== null && filename.split(/[/\\]/u).some((segment) => ignore.has(segment) || ignoreSegment(segment))) {
22
- return;
23
- }
24
- onChange();
25
- };
26
- };
27
-
28
- export { BLUME_IGNORE_DIRS, baselineScanIgnore, BLUME_WATCH_IGNORE_DIRS, excludeDirSegments, ignoringWatchListener };
29
-
30
- //# debugId=E327C8C451E6563064756E2164756E21
31
- //# sourceMappingURL=chunk-abh8yjkn.js.map
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/core/sources/watch.ts"],
4
- "sourcesContent": [
5
- "import type { WatchListener } from \"node:fs\";\n\n/**\n * Directory segments that are never authored content: VCS, dependency trees,\n * Blume's own generated project and build output, and framework/deploy caches.\n * Both the content scan and the dev watcher skip these unconditionally, on top\n * of the user's `content.exclude`.\n *\n * The scan needs them because a broadly-scoped `content.root` — `\".\"` or an app\n * dir that also holds `node_modules`/`dist`, the common shape when migrating a\n * docs app that lives at the repo or app root — would otherwise glob thousands\n * of stray markdown files out of dependencies and build artifacts. `content.root`\n * defaults to `docs/` where this rarely bites, but any wider root hits it.\n *\n * The watcher needs them because a recursive `fs.watch` rooted at the project\n * also sees Blume's own `.blume/` output, which the dev server rewrites on every\n * render (e.g. `.blume/.astro/data-store.json`). Left unfiltered, each such write\n * re-triggers a rescan + runtime regeneration whose writes land back under\n * `.blume/` and fire the watcher again: a self-sustaining loop that stalls page\n * renders and floods the console. `fs.watch` has no ignore option, so we filter\n * by the changed path in the callback.\n */\nexport const BLUME_IGNORE_DIRS = [\n \".blume\",\n // The isolated `blume check --isolated` runtime. A sibling of `.blume`, it is\n // written while a dev server runs; without this the content-layer watcher (or\n // a `.`-rooted fs.watch) would treat its generation as a content change and\n // reload — the very thing `--isolated` promises not to do.\n \".blume-verify\",\n \".cache\",\n \".git\",\n \".next\",\n \".turbo\",\n \".vercel\",\n \"dist\",\n \"node_modules\",\n];\n\n/**\n * Baseline scan-ignore globs applied to every filesystem source, unioned with\n * the user's `content.exclude`. Kept in sync with the watcher via the shared\n * {@link BLUME_IGNORE_DIRS} so `load()` and `watch()` never disagree on what is\n * content. `**\\/<dir>/**` matches the directory at the content root or nested.\n */\nexport const baselineScanIgnore = (): string[] =>\n BLUME_IGNORE_DIRS.map((dir) => `**/${dir}/**`);\n\n/**\n * Alias retained for the dev watcher's call site and its tests; the watcher and\n * the scan share the same never-content directory set.\n */\nexport const BLUME_WATCH_IGNORE_DIRS = BLUME_IGNORE_DIRS;\n\n/** Extract single-segment ignore dirs (`foo`) from `foo/**`-style excludes. */\nexport const excludeDirSegments = (patterns: readonly string[]): string[] =>\n patterns\n .map((pattern) => /^(?<dir>[^*/]+)\\/\\*\\*$/u.exec(pattern)?.groups?.dir)\n .filter((dir): dir is string => dir !== undefined);\n\n/**\n * Build a recursive-watch listener that fires `onChange` for content changes but\n * ignores events whose path crosses an ignored directory segment — one in\n * `ignoreDirs`, or one `ignoreSegment` rejects, for a scan whose skip rule is\n * a shape (every dot-name) rather than a list. A missing `filename` — rare;\n * the platform couldn't name the changed path — falls through to `onChange`\n * rather than silently dropping a real edit. Exported for testing.\n */\nexport const ignoringWatchListener = (\n onChange: () => void,\n ignoreDirs: Iterable<string> = BLUME_WATCH_IGNORE_DIRS,\n ignoreSegment: (segment: string) => boolean = () => false\n): WatchListener<string> => {\n const ignore = new Set(ignoreDirs);\n return (_event, filename) => {\n if (\n filename !== null &&\n filename\n .split(/[/\\\\]/u)\n .some((segment) => ignore.has(segment) || ignoreSegment(segment))\n ) {\n return;\n }\n onChange();\n };\n};\n"
6
- ],
7
- "mappings": ";;;AAsBO,IAAM,oBAAoB;AAAA,EAC/B;AAAA,EAKA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,IAAM,qBAAqB,MAChC,kBAAkB,IAAI,CAAC,QAAQ,MAAM,QAAQ;AAMxC,IAAM,0BAA0B;AAGhC,IAAM,qBAAqB,CAAC,aACjC,SACG,IAAI,CAAC,YAAY,0BAA0B,KAAK,OAAO,GAAG,QAAQ,GAAG,EACrE,OAAO,CAAC,QAAuB,QAAQ,SAAS;AAU9C,IAAM,wBAAwB,CACnC,UACA,aAA+B,yBAC/B,gBAA8C,MAAM,UAC1B;AAAA,EAC1B,MAAM,SAAS,IAAI,IAAI,UAAU;AAAA,EACjC,OAAO,CAAC,QAAQ,aAAa;AAAA,IAC3B,IACE,aAAa,QACb,SACG,MAAM,QAAQ,EACd,KAAK,CAAC,YAAY,OAAO,IAAI,OAAO,KAAK,cAAc,OAAO,CAAC,GAClE;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;",
8
- "debugId": "E327C8C451E6563064756E2164756E21",
9
- "names": []
10
- }
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/upgrade/upgrade.ts"],
4
- "sourcesContent": [
5
- "import { existsSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\n\nimport { join, relative, resolve } from \"pathe\";\nimport { glob } from \"tinyglobby\";\nimport { z } from \"zod\";\n\nimport {\n analyzeComponentOverrides,\n ComponentOverridesError,\n} from \"../core/component-overrides.ts\";\nimport { ConfigValidationError, loadConfig } from \"../core/config.ts\";\nimport { BlumeError, locateFrontmatterKey } from \"../core/diagnostics.ts\";\nimport matter from \"../core/frontmatter.ts\";\nimport { createModuleLoader } from \"../core/load-module.ts\";\nimport { findComponentsFile, findConfigFile } from \"../core/project.ts\";\nimport { pageMetaSchema } from \"../core/schema.ts\";\nimport { baselineScanIgnore } from \"../core/sources/watch.ts\";\nimport type { Diagnostic } from \"../core/types.ts\";\nimport {\n DEFAULT_CONTENT_EXCLUDE,\n DEFAULT_CONTENT_INCLUDE,\n} from \"../sources/filesystem.ts\";\n\n/**\n * `blume upgrade`'s logic, kept out of the command module so it runs (and is\n * covered) in-process: bump the `blume` dependency to the running CLI's major,\n * then check the project against it — the config through the same loader\n * every command uses, which names each removed or renamed field and its\n * replacement, `components.ts` through the same static planner the build\n * runs, and each page's front matter for fields the schema removed. The\n * command prints the findings or hands them to a coding agent.\n */\n\n/** The upgrade guide's route on the Blume docs site. */\nexport const UPGRADE_GUIDE_URL = \"https://useblume.dev/docs/upgrading\";\n\n/** The upgrade guide's file inside the published package's bundled docs. */\nexport const UPGRADE_GUIDE_FILE = join(\"docs\", \"03-upgrading.mdx\");\n\n/** What `bumpBlumeDependency` did to `package.json`. */\nexport type DependencyBump =\n | {\n field: DependencyField;\n from: string;\n status: \"bumped\";\n to: string;\n }\n | { range: string; status: \"current\" }\n | { status: \"missing\" };\n\ntype DependencyField = \"dependencies\" | \"devDependencies\";\n\nconst DEPENDENCY_FIELDS: DependencyField[] = [\n \"dependencies\",\n \"devDependencies\",\n];\n\n/** The slice of `package.json` the bump reads and rewrites. */\ninterface PackageJson {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\n// Leading comparators and a `v` may precede the major (`^1.7.3`, `>=1 <2`,\n// `v1`); a protocol (`workspace:`, `file:`, `npm:`) or a tag (`latest`) names\n// no major at all, and those ranges are left to the user.\nconst RANGE_MAJOR = /^[\\s<=>^~v]*(?<major>\\d+)/u;\n\n/** The major version a dependency range pins, or null when it names none. */\nexport const rangeMajor = (range: string): number | null => {\n const major = RANGE_MAJOR.exec(range)?.groups?.major;\n return major === undefined ? null : Number(major);\n};\n\n// The file's own indentation (two spaces, four, or a tab), so a fallback\n// rewrite doesn't reformat a package.json the user keeps differently.\nconst INDENT = /^(?<indent>[ \\t]+)\"/mu;\n\nconst REGEXP_SPECIAL = /[$()*+.?[\\\\\\]^{|}]/gu;\nconst escapeRegExp = (value: string): string =>\n value.replaceAll(REGEXP_SPECIAL, String.raw`\\$&`);\n\n/**\n * `text` with the `blume` range under `field` replaced in place, so the file\n * keeps its own formatting, key order, and inline objects; null when the entry\n * isn't written the plain way (an escaped key or value).\n */\nconst replaceRange = (\n text: string,\n field: DependencyField,\n from: string,\n to: string\n): string | null => {\n const value = JSON.stringify(from);\n const entry = new RegExp(`\"blume\"\\\\s*:\\\\s*${escapeRegExp(value)}`, \"gu\");\n entry.lastIndex = Math.max(text.indexOf(JSON.stringify(field)), 0);\n const match = entry.exec(text);\n if (!match) {\n return null;\n }\n const end = match.index + match[0].length;\n return `${text.slice(0, end - value.length)}${JSON.stringify(to)}${text.slice(end)}`;\n};\n\n/**\n * Point `package.json`'s `blume` dependency at `^version` when it pins an\n * older major. A range already on this major, or one that names no version\n * (`workspace:*`, `latest`), is reported as current and left alone; a\n * project with no `package.json`, or none that lists `blume`, is `missing`.\n * Only the range changes: the rest of the file is kept byte for byte.\n */\nexport const bumpBlumeDependency = async (\n root: string,\n version: string\n): Promise<DependencyBump> => {\n const path = join(root, \"package.json\");\n if (!existsSync(path)) {\n return { status: \"missing\" };\n }\n const text = await readFile(path, \"utf-8\");\n // SAFETY: package.json is a JSON object; only its dependency maps, which\n // map package names to range strings, are read.\n const pkg = JSON.parse(text) as PackageJson;\n const field = DEPENDENCY_FIELDS.find(\n (name) => pkg[name]?.blume !== undefined\n );\n const from = field ? pkg[field]?.blume : undefined;\n if (!(field && from)) {\n return { status: \"missing\" };\n }\n const current = rangeMajor(from);\n const target = rangeMajor(version);\n if (current === null || target === null || current >= target) {\n return { range: from, status: \"current\" };\n }\n const to = `^${version}`;\n const indent = INDENT.exec(text)?.groups?.indent ?? \" \";\n const updated = { ...pkg, [field]: { ...pkg[field], blume: to } };\n await writeFile(\n path,\n replaceRange(text, field, from, to) ??\n `${JSON.stringify(updated, null, indent)}\\n`\n );\n return { field, from, status: \"bumped\", to };\n};\n\n/**\n * Whether `root` is no Blume project at all: no config file and no `blume`\n * dependency, so the upgrade would only check the defaults and report the\n * folder ready. A zero-config project still lists `blume`.\n */\nexport const isOutsideBlumeProject = (\n root: string,\n bump: DependencyBump\n): boolean => bump.status === \"missing\" && findConfigFile(root) === null;\n\n// ---------------------------------------------------------------------------\n// Removed `blume build` flags\n// ---------------------------------------------------------------------------\n\n/** A `blume build` flag Blume 2 removed, bare or with an `=value`. */\nconst REMOVED_BUILD_FLAG = /^--(?<flag>adapter|base|output)(?:=|$)/u;\n\n/** The removed `blume build` flags among `args`, in order, each once. */\nexport const removedBuildFlags = (args: readonly string[]): string[] => [\n ...new Set(\n args.flatMap((arg) => {\n const flag = REMOVED_BUILD_FLAG.exec(arg)?.groups?.flag;\n return flag ? [flag] : [];\n })\n ),\n];\n\n/** The flags as the reader typed them: `--adapter, --output`. */\nexport const flagList = (flags: string[]): string =>\n flags.map((flag) => `--${flag}`).join(\", \");\n\n/** What replaces each removed flag: the `deployment` config. */\nexport const removedBuildFlagsAdvice = (flags: string[]): string => {\n const advice: string[] = [];\n if (flags.includes(\"adapter\") || flags.includes(\"output\")) {\n advice.push(\n 'name the host in blume.config.ts with `deployment: vercel()` (or `netlify()`, `cloudflare()`, `node()`) from \"blume/deploy\" — a host adapter builds for the server, and `output: \"static\"` keeps it static'\n );\n }\n if (flags.includes(\"base\")) {\n advice.push(\n 'set the subpath with `deployment: { base: \"/docs\" }`, or the host adapter\\'s `base` option'\n );\n }\n return `Drop ${flagList(flags)} and ${advice.join(\"; \")}.`;\n};\n\n// A command that runs the Blume CLI: the bare bin, a versioned package\n// (`blume@2`), or a path to it (`./node_modules/.bin/blume`).\nconst BLUME_BIN = /(?:^|[/\\\\])blume(?:@\\S+)?$/u;\nconst COMMAND_SEPARATOR = /&&|\\|\\||[;|]/u;\nconst WHITESPACE = /\\s+/u;\n\n/** The arguments each `blume build` in a script passes, flattened. */\nconst buildArgs = (script: string): string[] =>\n script.split(COMMAND_SEPARATOR).flatMap((command) => {\n const words = command.trim().split(WHITESPACE);\n const at = words.findIndex(\n (word, index) => BLUME_BIN.test(word) && words[index + 1] === \"build\"\n );\n return at === -1 ? [] : words.slice(at + 2);\n });\n\n/** The slice of package.json the script check reads. */\nconst scriptsSchema = z.looseObject({\n scripts: z.record(z.string(), z.string()).default({}),\n});\n\nconst lineOf = (text: string, index: number): number =>\n text.slice(0, index).split(\"\\n\").length;\n\n/**\n * A finding for each package.json script that still passes a removed flag to\n * `blume build` — it would otherwise build a static site without a word.\n */\nconst scriptFindings = async (root: string): Promise<Diagnostic[]> => {\n const path = join(root, \"package.json\");\n if (!existsSync(path)) {\n return [];\n }\n const text = await readFile(path, \"utf-8\");\n const pkg = scriptsSchema.safeParse(JSON.parse(text));\n const scripts = pkg.success ? pkg.data.scripts : {};\n const scriptsAt = text.indexOf('\"scripts\"');\n return Object.entries(scripts).flatMap(([name, script]) => {\n const flags = removedBuildFlags(buildArgs(script));\n if (flags.length === 0) {\n return [];\n }\n const at = text.indexOf(JSON.stringify(name), scriptsAt);\n return [\n {\n code: \"BLUME_BUILD_FLAG_REMOVED\",\n file: path,\n line: at === -1 ? undefined : lineOf(text, at),\n message: `The \"${name}\" script passes ${flagList(flags)} to \\`blume build\\`, which Blume 2 removed.`,\n severity: \"error\",\n suggestion: removedBuildFlagsAdvice(flags),\n } satisfies Diagnostic,\n ];\n });\n};\n\n// ---------------------------------------------------------------------------\n// Removed front matter fields\n// ---------------------------------------------------------------------------\n\n/** Where a project's local content lives, as its config names it. */\ninterface ContentGlobs {\n exclude: string[];\n include: string[];\n root: string;\n}\n\nconst globFields = {\n exclude: z.array(z.string()).optional(),\n include: z.array(z.string()).optional(),\n root: z.string().optional(),\n};\n\n/**\n * A filesystem source in either form a config being upgraded may hold: the\n * `filesystem()` descriptor, or Blume 1's `{ type: \"filesystem\" }` object.\n */\nconst rawFilesystemSourceSchema = z.union([\n z\n .looseObject({\n kind: z.literal(\"filesystem\"),\n options: z.looseObject(globFields).default({}),\n })\n .transform((source) => source.options),\n z.looseObject({ type: z.literal(\"filesystem\"), ...globFields }),\n]);\n\n/** The `content` slice of a config as written, before validation. */\nconst rawContentSchema = z.looseObject({\n content: z\n .looseObject({ ...globFields, sources: z.array(z.unknown()).optional() })\n .optional(),\n});\n\n/**\n * The content roots to scan, read from the config as written rather than the\n * validated config: the upgrade runs on configs that don't validate yet. Its\n * filesystem sources when it lists any, else the `content.root` shorthand,\n * else the zero-config `docs` folder.\n */\nexport const contentGlobs = ({\n content,\n}: z.infer<typeof rawContentSchema>): ContentGlobs[] => {\n const sources = (content?.sources ?? []).flatMap((source) => {\n const filesystem = rawFilesystemSourceSchema.safeParse(source);\n return filesystem.success ? [filesystem.data] : [];\n });\n return (sources.length > 0 ? sources : [content ?? {}]).map((globs) => ({\n exclude: globs.exclude ?? DEFAULT_CONTENT_EXCLUDE,\n include: globs.include ?? DEFAULT_CONTENT_INCLUDE,\n root: globs.root ?? \"docs\",\n }));\n};\n\n/** The content roots the project's config names, loaded as written. */\nconst configContentGlobs = async (root: string): Promise<ContentGlobs[]> => {\n const file = findConfigFile(root);\n let raw: z.infer<typeof rawContentSchema> = {};\n if (file) {\n try {\n const parsed = rawContentSchema.safeParse(\n await createModuleLoader()(file)\n );\n raw = parsed.success ? parsed.data : {};\n } catch {\n // A config that won't load is already reported by the config check;\n // its content still gets the zero-config scan.\n }\n }\n return contentGlobs(raw);\n};\n\nconst isPathKey = (segment: PropertyKey): segment is number | string =>\n typeof segment !== \"symbol\";\n\n// Zod's own wording for an unknown key; a removed field's hint replaces it.\nconst PLAIN_UNKNOWN_KEY = \"Unrecognized key\";\n\n/**\n * The removed fields among one page's front matter issues, each at its own\n * line. Only issues the page schema words as a removed-field hint count: a\n * key a project declares through `frontmatter.extend` is unknown to the bare\n * schema, and any other invalid value was already an error on Blume 1.\n */\nconst removedFieldFindings = (\n file: string,\n text: string,\n issues: readonly z.core.$ZodIssue[]\n): Diagnostic[] =>\n issues.flatMap((issue) => {\n if (\n issue.code !== \"unrecognized_keys\" ||\n issue.message.startsWith(PLAIN_UNKNOWN_KEY)\n ) {\n return [];\n }\n const path = issue.path.filter(isPathKey);\n const position =\n locateFrontmatterKey(text, [...path, ...issue.keys.slice(0, 1)]) ??\n locateFrontmatterKey(text, path);\n return [\n {\n code: \"BLUME_FRONTMATTER_INVALID\",\n column: position?.column,\n file,\n line: position?.line,\n message: issue.message,\n severity: \"error\",\n } satisfies Diagnostic,\n ];\n });\n\n/** The removed front matter fields in one page, or none it can't parse. */\nconst pageFindings = async (file: string): Promise<Diagnostic[]> => {\n const text = await readFile(file, \"utf-8\");\n let parsed: ReturnType<typeof pageMetaSchema.safeParse>;\n try {\n parsed = pageMetaSchema.safeParse(matter(text).data);\n } catch {\n // Unparseable front matter fails the build with its own diagnostic.\n return [];\n }\n return parsed.success\n ? []\n : removedFieldFindings(file, text, parsed.error.issues);\n};\n\n/**\n * A finding for each front matter field Blume 2 removed, across the project's\n * local content. A page with one fails validation and drops out of the build,\n * which the config and components checks alone would report as ready.\n */\nconst frontmatterFindings = async (root: string): Promise<Diagnostic[]> => {\n const roots = await configContentGlobs(root);\n const matches = await Promise.all(\n roots.map((globs) => {\n const cwd = resolve(root, globs.root);\n return existsSync(cwd)\n ? glob(globs.include, {\n absolute: true,\n cwd,\n ignore: [...globs.exclude, ...baselineScanIgnore()],\n onlyFiles: true,\n })\n : [];\n })\n );\n // Two sources can share a folder; each page is checked once.\n const files = [...new Set(matches.flat())].toSorted();\n const findings = await Promise.all(files.map(pageFindings));\n return findings.flat();\n};\n\n/**\n * Run one check, turning the {@link BlumeError} it throws into its findings:\n * each config issue or `components.ts` entry on its own, or the one diagnostic\n * any other check has.\n */\nconst findingsOf = async (\n check: () => Promise<void>\n): Promise<Diagnostic[]> => {\n try {\n await check();\n return [];\n } catch (error) {\n if (\n error instanceof ConfigValidationError ||\n error instanceof ComponentOverridesError\n ) {\n return error.issues;\n }\n if (error instanceof BlumeError) {\n return [error.diagnostic];\n }\n throw error;\n }\n};\n\n/**\n * Check a project against this version of Blume: its config through the\n * loader (every invalid field, each with its line and replacement), its\n * `components.ts` through the static override planner (each entry at its\n * line), its pages' front matter for removed fields, and its package.json\n * scripts for `blume build` flags that no longer exist. Returns the failures;\n * an empty list means the project is ready.\n */\nexport const collectUpgradeFindings = async (\n root: string\n): Promise<Diagnostic[]> => {\n const componentsFile = findComponentsFile(root);\n return [\n ...(await findingsOf(async () => {\n await loadConfig(root);\n })),\n ...(componentsFile\n ? await findingsOf(async () => {\n analyzeComponentOverrides(\n await readFile(componentsFile, \"utf-8\"),\n componentsFile\n );\n })\n : []),\n ...(await frontmatterFindings(root)),\n ...(await scriptFindings(root)),\n ];\n};\n\n/** A finding as plain text for the agent: where, what, and the fix. */\nconst plainFinding = (finding: Diagnostic, root: string): string => {\n const where = finding.file\n ? `${relative(root, finding.file)}${finding.line === undefined ? \"\" : `:${finding.line}`}`\n : \"blume.config.ts\";\n const fix = finding.suggestion ? `\\n Fix: ${finding.suggestion}` : \"\";\n return `- ${where} (${finding.code})\\n ${finding.message.replaceAll(\"\\n\", \"\\n \")}${fix}`;\n};\n\n/**\n * The handoff prompt: the findings inline (they're few, and each already\n * names its replacement), where the guide is, and the ground rules — change\n * the config's shape, never the site's behavior, and verify with the site's\n * own checks, run through the project's package runner (`npx`, `pnpm exec`),\n * since a local install puts no `blume` on PATH.\n */\nexport const upgradePrompt = (options: {\n findings: Diagnostic[];\n guidePath: string;\n root: string;\n runner: string;\n version: string;\n}): string =>\n `Upgrade this Blume project to Blume ${options.version}. \\`blume upgrade\\` has bumped the \\`blume\\` dependency in package.json where it could; what's left is the config.\n\nThe upgrade guide is at ${options.guidePath} (online at ${UPGRADE_GUIDE_URL}). It covers every change between Blume 1 and 2 with before-and-after examples: search, deployment, content sources, API references, analytics, and the assistant's model provider become adapters imported from \\`blume/*\\` subpaths; the machine-readable settings move from \\`ai\\` to \\`agents\\`; Ask AI is renamed the assistant, so \\`ai.ask\\` becomes \\`ai.assistant\\`; and \\`components.ts\\` entries must be one of the static forms.\n\n\\`blume upgrade\\` found:\n\n${options.findings.map((finding) => plainFinding(finding, options.root)).join(\"\\n\\n\")}\n\nWork through every finding:\n1. Read the guide section for each change before editing.\n2. Rewrite the config to the Blume 2 form, adding the adapter imports it needs. Keep the site's behavior the same: the same content, routes, search backend, deployment target, analytics, and credentials (keep reading secrets from the same environment variables).\n3. The config loader reports every invalid field at once, but some changes only surface once earlier ones are fixed, so rerun \\`${options.runner} blume doctor\\` after each round of edits.\n4. Never delete content, or remove a setting only to silence an error; if something needs a human decision, leave it and say so in your summary.\n\nWhen \\`${options.runner} blume doctor\\` reports no errors, run \\`${options.runner} blume build\\` and fix anything it reports until it succeeds.`;\n"
6
- ],
7
- "mappings": "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",
8
- "debugId": "9BE967FC7391289164756E2164756E21",
9
- "names": []
10
- }
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/cli/commands/check.ts"],
4
- "sourcesContent": [
5
- "import { existsSync } from \"node:fs\";\n\nimport { check } from \"@astrojs/check\";\nimport { sync } from \"astro\";\nimport { defineCommand } from \"citty\";\nimport { join } from \"pathe\";\n\nimport { ensureGitignore } from \"../../core/gitignore.ts\";\nimport { commandMeta } from \"../command-meta.ts\";\nimport { refuseIfDevRunning } from \"../dev-lock.ts\";\nimport { logger } from \"../log.ts\";\nimport { prepareProject } from \"../prepare.ts\";\n\nexport const checkCommand = defineCommand({\n args: {\n isolated: {\n description:\n \"Type-check in an isolated .blume-verify runtime so a running dev server is untouched. For verifying changes while `blume dev` runs.\",\n type: \"boolean\",\n },\n preview: {\n description: \"Include drafts and unpublished CMS content.\",\n type: \"boolean\",\n },\n strict: {\n description: \"Fail on content diagnostics as well as type errors.\",\n type: \"boolean\",\n },\n },\n meta: commandMeta.check,\n async run({ args }) {\n const root = process.cwd();\n\n // `blume check` regenerates `.blume` just like `build`, so it must refuse a\n // live dev server unless isolated. `--isolated` (or BLUME_RUNTIME_DIR)\n // relocates the runtime to `.blume-verify`, which dev never locks.\n const runtimeDir = args.isolated\n ? \".blume-verify\"\n : process.env.BLUME_RUNTIME_DIR;\n refuseIfDevRunning(root, \"checking\", { isolatedHint: true, runtimeDir });\n if (args.isolated) {\n await ensureGitignore(root, [\".blume-verify/\"]);\n }\n\n const project = await prepareProject({\n mode: \"build\",\n preview: args.preview,\n root,\n runtimeDir,\n strict: args.strict,\n strictOptIn: true,\n });\n\n const { outDir } = project.context;\n\n // Generate Astro's content/collection and font types into `.blume/.astro`\n // so `astro:*` virtual modules resolve during the check.\n await sync({ logLevel: \"warn\", root: outDir });\n\n // The project-root tsconfig is what covers the authored `pages/` and config;\n // without it astro check only sees the generated `.blume` project. Falls back\n // to the generated project's own tsconfig when the project has none.\n const tsconfig = join(root, \"tsconfig.json\");\n\n logger.start(`Type-checking ${project.graph.pages.length} page(s)`);\n const failed = await check({\n minimumFailingSeverity: \"error\",\n minimumSeverity: \"hint\",\n root: outDir,\n tsconfig: existsSync(tsconfig) ? tsconfig : undefined,\n watch: false,\n });\n\n if (failed) {\n logger.error(\"Type check failed.\");\n process.exit(1);\n }\n\n logger.success(\"No type errors.\");\n },\n});\n"
6
- ],
7
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAEA;AACA;AACA;AACA;AAQO,IAAM,eAAe,cAAc;AAAA,EACxC,MAAM;AAAA,IACJ,UAAU;AAAA,MACR,aACE;AAAA,MACF,MAAM;AAAA,IACR;AAAA,IACA,SAAS;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,IACR;AAAA,IACA,QAAQ;AAAA,MACN,aAAa;AAAA,MACb,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,MAAM,YAAY;AAAA,OACZ,IAAG,GAAG,QAAQ;AAAA,IAClB,MAAM,OAAO,QAAQ,IAAI;AAAA,IAKzB,MAAM,aAAa,KAAK,WACpB,kBACA,QAAQ,IAAI;AAAA,IAChB,mBAAmB,MAAM,YAAY,EAAE,cAAc,MAAM,WAAW,CAAC;AAAA,IACvE,IAAI,KAAK,UAAU;AAAA,MACjB,MAAM,gBAAgB,MAAM,CAAC,gBAAgB,CAAC;AAAA,IAChD;AAAA,IAEA,MAAM,UAAU,MAAM,eAAe;AAAA,MACnC,MAAM;AAAA,MACN,SAAS,KAAK;AAAA,MACd;AAAA,MACA;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,aAAa;AAAA,IACf,CAAC;AAAA,IAED,QAAQ,WAAW,QAAQ;AAAA,IAI3B,MAAM,KAAK,EAAE,UAAU,QAAQ,MAAM,OAAO,CAAC;AAAA,IAK7C,MAAM,WAAW,KAAK,MAAM,eAAe;AAAA,IAE3C,OAAO,MAAM,iBAAiB,QAAQ,MAAM,MAAM,gBAAgB;AAAA,IAClE,MAAM,SAAS,MAAM,MAAM;AAAA,MACzB,wBAAwB;AAAA,MACxB,iBAAiB;AAAA,MACjB,MAAM;AAAA,MACN,UAAU,WAAW,QAAQ,IAAI,WAAW;AAAA,MAC5C,OAAO;AAAA,IACT,CAAC;AAAA,IAED,IAAI,QAAQ;AAAA,MACV,OAAO,MAAM,oBAAoB;AAAA,MACjC,QAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,IAEA,OAAO,QAAQ,iBAAiB;AAAA;AAEpC,CAAC;",
8
- "debugId": "DC0C35E4A8FB3C3E64756E2164756E21",
9
- "names": []
10
- }
@@ -1,11 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/cli/report-format.ts", "../src/eval/agents.ts"],
4
- "sourcesContent": [
5
- "/**\n * Number formatting shared by the translate and eval report renderers. The\n * `1.5s` / `4m 12s` shapes are asserted in both suites — change them in both\n * minds at once.\n */\n\n/** Milliseconds as `1.5s`. */\nexport const seconds = (ms: number): string => `${(ms / 1000).toFixed(1)}s`;\n\n/** A dollar cost as `$1.23`, or nothing when the run reported none. */\nexport const money = (cost: number | undefined): string =>\n cost === undefined ? \"\" : `$${cost.toFixed(2)}`;\n\n/** Milliseconds as `12.3s` under a minute, `4m 12s` from there up. */\nexport const duration = (ms: number): string => {\n if (ms < 60_000) {\n return seconds(ms);\n }\n const minutes = Math.floor(ms / 60_000);\n const rest = Math.round((ms % 60_000) / 1000);\n return `${minutes}m ${rest}s`;\n};\n",
6
- "import { readFile, writeFile } from \"node:fs/promises\";\n\nimport spawn from \"cross-spawn\";\nimport { join } from \"pathe\";\nimport { z } from \"zod\";\n\nimport type { AgentKind } from \"../audit/agent.ts\";\n\n/** How long the SIGTERM on timeout gets to work before SIGKILL follows. */\nconst KILL_GRACE_MS = 5000;\n\n/** The MCP tools a reader run may use — nothing else. */\nexport const MCP_TOOL_NAMES = [\n \"search_docs\",\n \"get_page\",\n \"list_pages\",\n \"get_navigation\",\n] as const;\n\n/** The MCP server name in the generated config; tool ids derive from it. */\nconst MCP_SERVER_NAME = \"docs\";\n\n/**\n * Claude Code built-ins that would let the agent escape the docs-only\n * sandbox: the reader must not read the repo, run commands, or search the\n * web — it sees the documentation the way a stranger does, through MCP.\n */\nexport const DISALLOWED_TOOLS = [\n \"Bash\",\n \"Read\",\n \"Glob\",\n \"Grep\",\n \"Write\",\n \"Edit\",\n \"NotebookEdit\",\n \"WebFetch\",\n \"WebSearch\",\n \"Task\",\n];\n\n/** The captured outcome of one headless agent invocation. */\nexport interface HeadlessResult {\n code: number;\n stderr: string;\n stdout: string;\n timedOut: boolean;\n}\n\nexport interface HeadlessOptions {\n cwd: string;\n /** How long the SIGTERM gets before SIGKILL follows (default 5s). */\n killGraceMs?: number;\n prompt: string;\n timeoutMs: number;\n}\n\n/**\n * Run an agent CLI headlessly: prompt over stdin (dodging argv limits and\n * cmd.exe newline quoting alike), stdout and stderr captured, SIGTERM at the\n * deadline with a SIGKILL follow-up. Resolves with the captured result;\n * rejects only when the executable cannot be spawned at all (ENOENT).\n *\n * Spawned through cross-spawn, which runs npm's `.cmd` shims on Windows with\n * its own cmd.exe escaping — under the old `shell: true` launch, cmd.exe was\n * free to mangle the JSON carried by codex's `-c` arguments, and a missing\n * executable surfaced as exit code 9009 instead of an ENOENT rejection.\n * execa was evaluated and rejected here: it waits for the stdio streams to\n * close, and the `exit`-beats-`close` resolution below exists precisely\n * because a killed agent's own children (an MCP server, a shell) hold the\n * pipes open past the SIGTERM.\n */\nexport const runAgentHeadless = (\n bin: string,\n args: string[],\n options: HeadlessOptions\n): Promise<HeadlessResult> =>\n // oxlint-disable-next-line promise/avoid-new -- adapt spawn's event callbacks\n new Promise((resolve, reject) => {\n const child = spawn(bin, args, {\n cwd: options.cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString(\"utf-8\");\n });\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString(\"utf-8\");\n });\n\n let hardKill: ReturnType<typeof setTimeout> | undefined;\n const deadline = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n hardKill = setTimeout(\n () => child.kill(\"SIGKILL\"),\n options.killGraceMs ?? KILL_GRACE_MS\n );\n hardKill.unref();\n }, options.timeoutMs);\n deadline.unref();\n\n child.once(\"error\", (error) => {\n clearTimeout(deadline);\n reject(error);\n });\n child.once(\"close\", (code) => {\n clearTimeout(deadline);\n resolve({ code: code ?? 1, stderr, stdout, timedOut });\n });\n // `close` waits for the stdio pipes, which a killed agent's own children\n // (an MCP server, a shell) can hold open past the SIGTERM. A timed-out\n // run's output is discarded anyway, so the process dying is enough.\n child.once(\"exit\", (code) => {\n // Once the process is gone the SIGKILL follow-up has nothing to do, and\n // firing it later could signal an unrelated process that reused the pid.\n clearTimeout(hardKill);\n if (timedOut) {\n clearTimeout(deadline);\n resolve({ code: code ?? 1, stderr, stdout, timedOut });\n }\n });\n\n child.stdin?.end(options.prompt);\n });\n\n/** The spawn signature `runEval` accepts, injectable for tests. */\nexport type HeadlessRunner = typeof runAgentHeadless;\n\n/** How the eval reaches the MCP stdio bridge from a spawned agent. */\nexport interface McpLaunch {\n /** The generated MCP config file (claude's `--mcp-config`). */\n configPath: string;\n /** argv for the bridge process (codex's `-c mcp_servers` override). */\n serverArgs: string[];\n /** The executable launching the bridge. */\n serverCommand: string;\n}\n\n/**\n * Write the MCP config a reader run points its agent CLI at. The bridge is\n * this same CLI relaunched (`blume mcp-stdio`), which resolves correctly from\n * both a source checkout (bun + src/cli/index.ts) and an installed package\n * (node + bin/blume.mjs).\n */\nexport const writeMcpConfig = async (\n dir: string,\n snapshotPath: string,\n launcher?: { args: string[]; command: string }\n): Promise<McpLaunch> => {\n const resolved = launcher ?? {\n args: [process.argv[1] ?? \"\", \"mcp-stdio\", \"--data\", snapshotPath],\n command: process.execPath,\n };\n const configPath = join(dir, \"mcp-config.json\");\n const config = {\n mcpServers: {\n [MCP_SERVER_NAME]: { args: resolved.args, command: resolved.command },\n },\n };\n await writeFile(configPath, JSON.stringify(config, null, 2));\n return {\n configPath,\n serverArgs: resolved.args,\n serverCommand: resolved.command,\n };\n};\n\nexport interface InvocationContext {\n /** Where codex writes its final message; unused by claude. */\n lastMessagePath: string;\n /** The MCP bridge for reader runs; omitted for the judge. */\n mcp?: McpLaunch;\n}\n\nconst CLAUDE_READER_MAX_TURNS = \"25\";\nconst CLAUDE_JUDGE_MAX_TURNS = \"1\";\n\nconst claudeArgs = (context: InvocationContext): string[] => {\n const base = [\"-p\", \"--output-format\", \"json\", \"--strict-mcp-config\"];\n if (context.mcp) {\n const allowed = MCP_TOOL_NAMES.map(\n (tool) => `mcp__${MCP_SERVER_NAME}__${tool}`\n ).join(\",\");\n return [\n ...base,\n \"--mcp-config\",\n context.mcp.configPath,\n \"--allowedTools\",\n allowed,\n \"--disallowedTools\",\n DISALLOWED_TOOLS.join(\",\"),\n \"--max-turns\",\n CLAUDE_READER_MAX_TURNS,\n ];\n }\n return [\n ...base,\n \"--disallowedTools\",\n DISALLOWED_TOOLS.join(\",\"),\n \"--max-turns\",\n CLAUDE_JUDGE_MAX_TURNS,\n ];\n};\n\n/**\n * Codex config overrides that leave an eval run nothing but its prompt and the\n * docs MCP tools. `--sandbox read-only` blocks writes and the network but still\n * lets the shell tool read any file the user can, and the docs a reader\n * searches — or the answer a judge grades — can come from a remote source, so\n * an instruction planted there could otherwise pull a local secret into the\n * transcript sent to the model provider. With both command tools and the\n * local-image tool off, and any subprocess started with no inherited\n * environment, there is nothing on the machine for a run to read.\n */\nconst CODEX_LOCKDOWN = [\n \"-c\",\n \"features.shell_tool=false\",\n \"-c\",\n \"features.unified_exec=false\",\n \"-c\",\n \"tools.view_image=false\",\n \"-c\",\n 'shell_environment_policy.inherit=\"none\"',\n];\n\nconst codexArgs = (context: InvocationContext): string[] => {\n const base = [\n \"exec\",\n \"--skip-git-repo-check\",\n \"--ignore-user-config\",\n \"--ephemeral\",\n \"--sandbox\",\n \"read-only\",\n ...CODEX_LOCKDOWN,\n \"--output-last-message\",\n context.lastMessagePath,\n ];\n if (context.mcp) {\n // `-c` values parse as TOML; JSON string/array literals are valid TOML\n // values, so JSON.stringify produces exactly the quoting codex expects.\n return [\n ...base,\n \"-c\",\n `mcp_servers.${MCP_SERVER_NAME}.command=${JSON.stringify(\n context.mcp.serverCommand\n )}`,\n \"-c\",\n `mcp_servers.${MCP_SERVER_NAME}.args=${JSON.stringify(\n context.mcp.serverArgs\n )}`,\n \"-\",\n ];\n }\n return [...base, \"-\"];\n};\n\n/** Build the argv for one headless run; pass `mcp` for the reader role. */\nexport const agentArgs = (\n kind: AgentKind,\n context: InvocationContext\n): string[] => (kind === \"claude\" ? claudeArgs(context) : codexArgs(context));\n\n/** What one headless run produced, normalized across agent CLIs. */\nexport interface AgentOutput {\n costUsd?: number;\n detail?: string;\n isError: boolean;\n text: string;\n}\n\nconst claudeResultSchema = z.object({\n is_error: z.boolean().default(false),\n result: z.string().default(\"\"),\n total_cost_usd: z.number().optional(),\n});\n\nconst tail = (value: string, max = 300): string => {\n const trimmed = value.trim();\n return trimmed.length > max ? trimmed.slice(-max) : trimmed;\n};\n\n/**\n * Normalize a finished run into the answer text. Claude prints one JSON\n * object on stdout (`--output-format json`); codex writes the final message\n * to `--output-last-message` because its stdout interleaves progress.\n */\nexport const readAgentOutput = async (\n kind: AgentKind,\n result: HeadlessResult,\n lastMessagePath: string\n): Promise<AgentOutput> => {\n if (result.timedOut) {\n return { detail: \"timed out\", isError: true, text: \"\" };\n }\n if (result.code !== 0) {\n return {\n detail: tail(result.stderr) || `exited with code ${result.code}`,\n isError: true,\n text: \"\",\n };\n }\n\n if (kind === \"claude\") {\n let parsed: unknown;\n try {\n parsed = JSON.parse(result.stdout);\n } catch {\n return {\n detail: \"unparseable --output-format json payload\",\n isError: true,\n text: \"\",\n };\n }\n const payload = claudeResultSchema.safeParse(parsed);\n if (!payload.success) {\n return {\n detail: \"unexpected --output-format json shape\",\n isError: true,\n text: \"\",\n };\n }\n return {\n costUsd: payload.data.total_cost_usd,\n isError: payload.data.is_error,\n text: payload.data.result,\n };\n }\n\n let text: string;\n try {\n const raw = await readFile(lastMessagePath, \"utf-8\");\n text = raw.trim();\n } catch {\n return { detail: \"no last message written\", isError: true, text: \"\" };\n }\n if (text === \"\") {\n return { detail: \"empty last message\", isError: true, text: \"\" };\n }\n return { isError: false, text };\n};\n\nconst verdictSchema = z.object({\n missing: z.array(z.string()).default([]),\n notes: z.string().default(\"\"),\n pass: z.boolean(),\n score: z.number().min(0).max(1).optional(),\n});\n\n/** The judge's grade for one answer. */\nexport type Verdict = z.infer<typeof verdictSchema>;\n\n/**\n * Extract the verdict JSON from a judge reply. Tolerates markdown fences and\n * surrounding prose; returns undefined when no valid verdict can be found.\n */\nexport const parseVerdict = (text: string): Verdict | undefined => {\n const start = text.indexOf(\"{\");\n const end = text.lastIndexOf(\"}\");\n if (start === -1 || end <= start) {\n return;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text.slice(start, end + 1));\n } catch {\n return;\n }\n const result = verdictSchema.safeParse(parsed);\n return result.success ? result.data : undefined;\n};\n"
7
- ],
8
- "mappings": "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",
9
- "debugId": "FE1BEE26F1BB6F4964756E2164756E21",
10
- "names": []
11
- }