blume 1.7.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (673) hide show
  1. package/AGENTS.md +19 -0
  2. package/CHANGELOG.md +217 -0
  3. package/README.md +34 -21
  4. package/dist/cli/chunk-11j0384y.js +148 -0
  5. package/dist/cli/chunk-11j0384y.js.map +10 -0
  6. package/dist/cli/{chunk-rqy0s5wh.js → chunk-1w8dp3qb.js} +17 -16
  7. package/dist/cli/{chunk-rqy0s5wh.js.map → chunk-1w8dp3qb.js.map} +3 -3
  8. package/dist/cli/chunk-2q1dwty4.js +75 -0
  9. package/dist/cli/chunk-2q1dwty4.js.map +11 -0
  10. package/dist/cli/chunk-41za066z.js +122 -0
  11. package/dist/cli/chunk-41za066z.js.map +11 -0
  12. package/dist/cli/chunk-5a2z0198.js +133 -0
  13. package/dist/cli/chunk-5a2z0198.js.map +10 -0
  14. package/dist/cli/{chunk-5g0w1e2c.js → chunk-6k8vp3ta.js} +25 -13
  15. package/dist/cli/{chunk-5g0w1e2c.js.map → chunk-6k8vp3ta.js.map} +4 -4
  16. package/dist/cli/{chunk-5qk08vmp.js → chunk-79njf86q.js} +133 -54
  17. package/dist/cli/chunk-79njf86q.js.map +11 -0
  18. package/dist/cli/{chunk-e7f42gdj.js → chunk-7ez8ny0t.js} +2 -2
  19. package/dist/cli/{chunk-nn13znc2.js → chunk-88cpgt6h.js} +1 -1
  20. package/dist/cli/chunk-a9kptbw5.js +361 -0
  21. package/dist/cli/chunk-a9kptbw5.js.map +14 -0
  22. package/dist/cli/chunk-abh8yjkn.js +31 -0
  23. package/dist/cli/chunk-abh8yjkn.js.map +10 -0
  24. package/dist/cli/chunk-b5aj94ah.js +91 -0
  25. package/dist/cli/chunk-b5aj94ah.js.map +10 -0
  26. package/dist/cli/{chunk-b27xqwn9.js → chunk-bctazmbk.js} +9 -5
  27. package/dist/cli/chunk-bctazmbk.js.map +10 -0
  28. package/dist/cli/chunk-beat36xx.js +279 -0
  29. package/dist/cli/chunk-beat36xx.js.map +10 -0
  30. package/dist/cli/chunk-bnbmcwfb.js +145 -0
  31. package/dist/cli/chunk-bnbmcwfb.js.map +11 -0
  32. package/dist/cli/{chunk-0xjyb285.js → chunk-bw22s759.js} +15 -5
  33. package/dist/cli/{chunk-0xjyb285.js.map → chunk-bw22s759.js.map} +4 -4
  34. package/dist/cli/chunk-by2290sx.js +39 -0
  35. package/dist/cli/chunk-by2290sx.js.map +10 -0
  36. package/dist/cli/chunk-d1tadaw7.js +79 -0
  37. package/dist/cli/chunk-d1tadaw7.js.map +10 -0
  38. package/dist/cli/{chunk-ahnw3kxw.js → chunk-d80hr03s.js} +24 -19
  39. package/dist/cli/chunk-d80hr03s.js.map +15 -0
  40. package/dist/cli/chunk-ernrthtr.js +97 -0
  41. package/dist/cli/chunk-ernrthtr.js.map +10 -0
  42. package/dist/cli/chunk-f2972sbt.js +374 -0
  43. package/dist/cli/chunk-f2972sbt.js.map +10 -0
  44. package/dist/cli/{chunk-vacwm2hv.js → chunk-f7t03s3g.js} +2 -2
  45. package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
  46. package/dist/cli/chunk-fa25z98p.js.map +11 -0
  47. package/dist/cli/{chunk-cjtn640a.js → chunk-fh5hj5jt.js} +43 -20
  48. package/dist/cli/chunk-fh5hj5jt.js.map +10 -0
  49. package/dist/cli/{chunk-yg63d42r.js → chunk-j8mw0za6.js} +86 -57
  50. package/dist/cli/chunk-j8mw0za6.js.map +35 -0
  51. package/dist/cli/{chunk-ct47dqpx.js → chunk-jts8mvcz.js} +67 -7
  52. package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
  53. package/dist/cli/{chunk-ps4m1xh4.js → chunk-mnqj32sj.js} +505 -542
  54. package/dist/cli/chunk-mnqj32sj.js.map +12 -0
  55. package/dist/cli/{chunk-8cjtbafj.js → chunk-mwt1k8n7.js} +100 -374
  56. package/dist/cli/chunk-mwt1k8n7.js.map +10 -0
  57. package/dist/cli/chunk-nk3ts2xk.js +51 -0
  58. package/dist/cli/chunk-nk3ts2xk.js.map +10 -0
  59. package/dist/cli/{chunk-3r45185y.js → chunk-pat2zzwc.js} +9 -11
  60. package/dist/cli/{chunk-3r45185y.js.map → chunk-pat2zzwc.js.map} +2 -2
  61. package/dist/cli/chunk-pnnvybbk.js +176 -0
  62. package/dist/cli/chunk-pnnvybbk.js.map +11 -0
  63. package/dist/cli/{chunk-4x36ddpw.js → chunk-sqn5t4q0.js} +81 -87
  64. package/dist/cli/chunk-sqn5t4q0.js.map +10 -0
  65. package/dist/cli/{chunk-bvwwhd84.js → chunk-tzne8qfq.js} +15 -15
  66. package/dist/cli/{chunk-bvwwhd84.js.map → chunk-tzne8qfq.js.map} +1 -1
  67. package/dist/cli/chunk-xaz13gwg.js +12449 -0
  68. package/dist/cli/chunk-xaz13gwg.js.map +182 -0
  69. package/dist/cli/chunk-y3e45rc8.js +102 -0
  70. package/dist/cli/chunk-y3e45rc8.js.map +10 -0
  71. package/dist/cli/chunk-z01ze5c1.js +261 -0
  72. package/dist/cli/chunk-z01ze5c1.js.map +10 -0
  73. package/dist/cli/{chunk-k79xp7av.js → chunk-z1f5arsg.js} +219 -689
  74. package/dist/cli/chunk-z1f5arsg.js.map +36 -0
  75. package/dist/cli/{chunk-1jefwnfs.js → chunk-zg2gtj10.js} +1076 -2592
  76. package/dist/cli/chunk-zg2gtj10.js.map +35 -0
  77. package/dist/cli/{chunk-dwgcp5sm.js → chunk-zxccj738.js} +1 -1
  78. package/dist/cli/index.js +214 -57
  79. package/dist/cli/index.js.map +8 -7
  80. package/dist/types/ai/agent-readability.d.ts +52 -0
  81. package/dist/types/ai/ai-catalog.d.ts +42 -0
  82. package/dist/types/ai/api/paths.d.ts +17 -0
  83. package/dist/types/ai/api-catalog.d.ts +18 -0
  84. package/dist/types/ai/ask.d.ts +368 -0
  85. package/dist/types/ai/changelog-markdown.d.ts +2 -0
  86. package/dist/types/ai/component-markdown.d.ts +2 -2
  87. package/dist/types/ai/index.d.ts +24 -0
  88. package/dist/types/ai/link-headers.d.ts +24 -0
  89. package/dist/types/ai/llms.d.ts +25 -0
  90. package/dist/types/ai/markdown.d.ts +45 -0
  91. package/dist/types/ai/mcp/discovery.d.ts +68 -0
  92. package/dist/types/ai/mcp/tools.d.ts +16 -0
  93. package/dist/types/ai/openapi-components.d.ts +43 -0
  94. package/dist/types/ai/relative-links.d.ts +26 -0
  95. package/dist/types/ai/serializers.d.ts +15 -0
  96. package/dist/types/ai/skills.d.ts +42 -0
  97. package/dist/types/ai/tar.d.ts +25 -0
  98. package/dist/types/ai/visibility.d.ts +17 -0
  99. package/dist/types/ai/web-bot-auth.d.ts +16 -0
  100. package/dist/types/analytics/adobe.d.ts +35 -0
  101. package/dist/types/analytics/amplitude.d.ts +50 -0
  102. package/dist/types/analytics/clarity.d.ts +31 -0
  103. package/dist/types/analytics/clearbit.d.ts +29 -0
  104. package/dist/types/analytics/cloudflare.d.ts +41 -0
  105. package/dist/types/analytics/fathom.d.ts +41 -0
  106. package/dist/types/analytics/google-analytics.d.ts +44 -0
  107. package/dist/types/analytics/google-tag-manager.d.ts +40 -0
  108. package/dist/types/analytics/head.d.ts +30 -0
  109. package/dist/types/analytics/heap.d.ts +40 -0
  110. package/dist/types/analytics/hightouch.d.ts +44 -0
  111. package/dist/types/analytics/hotjar.d.ts +33 -0
  112. package/dist/types/analytics/index.d.ts +61 -0
  113. package/dist/types/analytics/inline.d.ts +17 -0
  114. package/dist/types/analytics/logrocket.d.ts +44 -0
  115. package/dist/types/analytics/mixpanel.d.ts +67 -0
  116. package/dist/types/analytics/pirsch.d.ts +42 -0
  117. package/dist/types/analytics/plausible.d.ts +56 -0
  118. package/dist/types/analytics/posthog.d.ts +45 -0
  119. package/dist/types/analytics/schema.d.ts +320 -0
  120. package/dist/types/analytics/script.d.ts +46 -0
  121. package/dist/types/analytics/segment.d.ts +50 -0
  122. package/dist/types/analytics/vercel.d.ts +48 -0
  123. package/dist/types/astro/integration.d.ts +76 -0
  124. package/dist/types/astro/markdown-negotiation.d.ts +23 -0
  125. package/dist/types/astro/module-types.d.ts +14 -0
  126. package/dist/types/astro/pages.d.ts +44 -0
  127. package/dist/types/cli/env.d.ts +12 -0
  128. package/dist/types/cli/init/scaffold.d.ts +154 -0
  129. package/dist/types/components/layout/nav-utils.d.ts +11 -0
  130. package/dist/types/core/adapter.d.ts +47 -0
  131. package/dist/types/core/api-name.d.ts +7 -0
  132. package/dist/types/core/changelog-index.d.ts +13 -0
  133. package/dist/types/core/config-input.d.ts +186 -515
  134. package/dist/types/core/config.d.ts +60 -34
  135. package/dist/types/core/content-assets.d.ts +76 -0
  136. package/dist/types/core/custom-pages.d.ts +33 -0
  137. package/dist/types/core/data.d.ts +27 -12
  138. package/dist/types/core/define-components.d.ts +12 -9
  139. package/dist/types/core/deployment-env.d.ts +6 -11
  140. package/dist/types/core/frontmatter.d.ts +10 -0
  141. package/dist/types/core/graph.d.ts +18 -0
  142. package/dist/types/core/heading-markers.d.ts +54 -0
  143. package/dist/types/core/i18n-ui.d.ts +6 -2
  144. package/dist/types/core/i18n.d.ts +87 -0
  145. package/dist/types/core/includes.d.ts +138 -0
  146. package/dist/types/core/last-modified.d.ts +47 -0
  147. package/dist/types/core/links.d.ts +95 -0
  148. package/dist/types/core/locale-links.d.ts +60 -0
  149. package/dist/types/core/manifest.d.ts +17 -0
  150. package/dist/types/core/meta.d.ts +38 -0
  151. package/dist/types/core/nav-diagnostics.d.ts +26 -0
  152. package/dist/types/core/navigation.d.ts +6 -0
  153. package/dist/types/core/node-require.d.ts +19 -0
  154. package/dist/types/core/package-json.d.ts +13 -0
  155. package/dist/types/core/probe.d.ts +42 -0
  156. package/dist/types/core/project-graph.d.ts +51 -0
  157. package/dist/types/core/project.d.ts +2 -0
  158. package/dist/types/core/safe-href.d.ts +2 -0
  159. package/dist/types/core/safe-links.d.ts +26 -0
  160. package/dist/types/core/schema.d.ts +2282 -452
  161. package/dist/types/core/site-url.d.ts +16 -0
  162. package/dist/types/core/sources/assets.d.ts +36 -0
  163. package/dist/types/core/sources/cache.d.ts +37 -0
  164. package/dist/types/core/sources/collection.d.ts +28 -0
  165. package/dist/types/core/sources/contentful-rich-text.d.ts +31 -0
  166. package/dist/types/core/sources/contentful.d.ts +40 -0
  167. package/dist/types/core/sources/filesystem.d.ts +24 -0
  168. package/dist/types/core/sources/github-releases.d.ts +31 -0
  169. package/dist/types/core/sources/json.d.ts +30 -0
  170. package/dist/types/core/sources/lexical.d.ts +19 -0
  171. package/dist/types/core/sources/lower.d.ts +75 -0
  172. package/dist/types/core/sources/mdx-remote.d.ts +28 -0
  173. package/dist/types/core/sources/normalize.d.ts +147 -0
  174. package/dist/types/core/sources/notion.d.ts +131 -0
  175. package/dist/types/core/sources/obsidian.d.ts +46 -0
  176. package/dist/types/core/sources/payload.d.ts +39 -0
  177. package/dist/types/core/sources/portable-text.d.ts +42 -0
  178. package/dist/types/core/sources/read.d.ts +23 -0
  179. package/dist/types/core/sources/remote.d.ts +74 -0
  180. package/dist/types/core/sources/resolve.d.ts +19 -0
  181. package/dist/types/core/sources/sanity.d.ts +43 -0
  182. package/dist/types/core/sources/strapi-blocks.d.ts +12 -0
  183. package/dist/types/core/sources/strapi.d.ts +33 -0
  184. package/dist/types/core/sources/types.d.ts +7 -0
  185. package/dist/types/core/sources/watch.d.ts +45 -0
  186. package/dist/types/core/text-width.d.ts +11 -0
  187. package/dist/types/core/types.d.ts +15 -1
  188. package/dist/types/core/unrecognized-keys.d.ts +7 -0
  189. package/dist/types/core/versions.d.ts +72 -0
  190. package/dist/types/core/yaml.d.ts +9 -0
  191. package/dist/types/deploy/adapter-output.d.ts +45 -0
  192. package/dist/types/deploy/adapters/cloudflare.d.ts +40 -0
  193. package/dist/types/deploy/adapters/index.d.ts +29 -0
  194. package/dist/types/deploy/adapters/netlify.d.ts +37 -0
  195. package/dist/types/deploy/adapters/node.d.ts +37 -0
  196. package/dist/types/deploy/adapters/registry.d.ts +133 -0
  197. package/dist/types/deploy/adapters/types.d.ts +71 -0
  198. package/dist/types/deploy/adapters/vercel.d.ts +38 -0
  199. package/dist/types/deploy/artifacts.d.ts +65 -0
  200. package/dist/types/deploy/cloudflare-negotiation.d.ts +196 -0
  201. package/dist/types/deploy/function-bundle.d.ts +80 -0
  202. package/dist/types/deploy/headers.d.ts +50 -0
  203. package/dist/types/deploy/node-headers.d.ts +42 -0
  204. package/dist/types/deploy/platforms/cloudflare.d.ts +40 -0
  205. package/dist/types/deploy/platforms/index.d.ts +18 -0
  206. package/dist/types/deploy/platforms/netlify.d.ts +13 -0
  207. package/dist/types/deploy/platforms/node.d.ts +11 -0
  208. package/dist/types/deploy/platforms/paths.d.ts +27 -0
  209. package/dist/types/deploy/platforms/static.d.ts +10 -0
  210. package/dist/types/deploy/platforms/types.d.ts +104 -0
  211. package/dist/types/deploy/platforms/vercel.d.ts +32 -0
  212. package/dist/types/deploy/redirects.d.ts +53 -0
  213. package/dist/types/deploy/robots.d.ts +8 -0
  214. package/dist/types/deploy/rss.d.ts +31 -0
  215. package/dist/types/deploy/sitemap.d.ts +21 -0
  216. package/dist/types/deploy/vercel-negotiation.d.ts +109 -0
  217. package/dist/types/markdown/code-title.d.ts +32 -0
  218. package/dist/types/markdown/fence-meta.d.ts +23 -0
  219. package/dist/types/markdown/themes.d.ts +3 -3
  220. package/dist/types/openapi/asyncapi.d.ts +129 -0
  221. package/dist/types/openapi/graphql-build.d.ts +8 -0
  222. package/dist/types/openapi/graphql.d.ts +122 -0
  223. package/dist/types/openapi/model.d.ts +158 -0
  224. package/dist/types/openapi/parse.d.ts +57 -0
  225. package/dist/types/openapi/references.d.ts +37 -25
  226. package/dist/types/openapi/render-mdx.d.ts +33 -0
  227. package/dist/types/openapi/sentence.d.ts +7 -0
  228. package/dist/types/openapi/signature.d.ts +10 -0
  229. package/dist/types/openapi/source.d.ts +22 -0
  230. package/dist/types/openapi/spec-dependency-error.d.ts +10 -0
  231. package/dist/types/reference/asyncapi.d.ts +166 -0
  232. package/dist/types/reference/graphql.d.ts +181 -0
  233. package/dist/types/reference/index.d.ts +32 -0
  234. package/dist/types/reference/openapi.d.ts +165 -0
  235. package/dist/types/reference/options.d.ts +157 -0
  236. package/dist/types/reference/scalar.d.ts +136 -0
  237. package/dist/types/reference/schema.d.ts +630 -0
  238. package/dist/types/search/adapters/algolia.d.ts +32 -0
  239. package/dist/types/search/adapters/flexsearch.d.ts +12 -0
  240. package/dist/types/search/adapters/index.d.ts +31 -0
  241. package/dist/types/search/adapters/mixedbread.d.ts +22 -0
  242. package/dist/types/search/adapters/orama-cloud.d.ts +33 -0
  243. package/dist/types/search/adapters/orama.d.ts +13 -0
  244. package/dist/types/search/adapters/pagefind.d.ts +12 -0
  245. package/dist/types/search/adapters/registry.d.ts +228 -0
  246. package/dist/types/search/adapters/types.d.ts +34 -0
  247. package/dist/types/search/adapters/typesense.d.ts +42 -0
  248. package/dist/types/search/build.d.ts +23 -0
  249. package/dist/types/search/documents.d.ts +90 -0
  250. package/dist/types/search/facets.d.ts +3 -0
  251. package/dist/types/search/sync/algolia.d.ts +14 -0
  252. package/dist/types/search/sync/index.d.ts +14 -0
  253. package/dist/types/search/sync/orama-cloud.d.ts +10 -0
  254. package/dist/types/search/sync/typesense.d.ts +14 -0
  255. package/dist/types/sources/contentful.d.ts +68 -0
  256. package/dist/types/sources/custom.d.ts +20 -0
  257. package/dist/types/sources/filesystem.d.ts +42 -0
  258. package/dist/types/sources/github-releases.d.ts +46 -0
  259. package/dist/types/sources/index.d.ts +48 -0
  260. package/dist/types/sources/mdx-remote.d.ts +63 -0
  261. package/dist/types/sources/notion.d.ts +65 -0
  262. package/dist/types/sources/obsidian.d.ts +34 -0
  263. package/dist/types/sources/payload.d.ts +68 -0
  264. package/dist/types/sources/registry.d.ts +1414 -0
  265. package/dist/types/sources/sanity.d.ts +69 -0
  266. package/dist/types/sources/shared.d.ts +46 -0
  267. package/dist/types/sources/strapi.d.ts +66 -0
  268. package/dist/types/theme/icon-kind.d.ts +11 -0
  269. package/dist/types/theme/icons.d.ts +20 -0
  270. package/docs/01-quickstart.mdx +18 -18
  271. package/docs/02-deployment.mdx +50 -26
  272. package/docs/03-upgrading.mdx +351 -0
  273. package/docs/04-migrating.mdx +58 -0
  274. package/docs/08-faq.mdx +3 -3
  275. package/docs/advanced/blog.mdx +13 -6
  276. package/docs/advanced/changelog.mdx +23 -35
  277. package/docs/advanced/custom-pages.mdx +20 -8
  278. package/docs/advanced/meta.ts +1 -8
  279. package/docs/advanced/skills.mdx +8 -0
  280. package/docs/cli/audit.mdx +646 -0
  281. package/docs/cli/doctor.mdx +29 -0
  282. package/docs/{reference/eval.mdx → cli/evals.mdx} +9 -8
  283. package/docs/cli/index.mdx +105 -0
  284. package/docs/cli/meta.ts +7 -0
  285. package/docs/{reference → cli}/translate.mdx +1 -1
  286. package/docs/cli/validate.mdx +41 -0
  287. package/docs/cli/version.mdx +40 -0
  288. package/docs/configuration/analytics.mdx +350 -59
  289. package/docs/configuration/ask-ai.mdx +162 -61
  290. package/docs/configuration/customization.mdx +15 -9
  291. package/docs/configuration/index.mdx +50 -31
  292. package/docs/configuration/search.mdx +75 -54
  293. package/docs/configuration/theming.mdx +24 -15
  294. package/docs/content/components.mdx +21 -5
  295. package/docs/{reference → content}/frontmatter.mdx +35 -1
  296. package/docs/content/i18n.mdx +8 -6
  297. package/docs/content/includes.mdx +2 -4
  298. package/docs/content/index.mdx +1 -1
  299. package/docs/content/islands.mdx +10 -5
  300. package/docs/content/meta.mdx +1 -1
  301. package/docs/content/meta.ts +1 -0
  302. package/docs/content/navigation.mdx +9 -7
  303. package/docs/content/sources.mdx +145 -50
  304. package/docs/content/syntax.mdx +16 -12
  305. package/docs/content/versioning.mdx +3 -3
  306. package/docs/discoverability/agent-discovery.mdx +11 -11
  307. package/docs/discoverability/index.mdx +4 -4
  308. package/docs/discoverability/json-api.mdx +4 -4
  309. package/docs/discoverability/llms-txt.mdx +6 -6
  310. package/docs/discoverability/markdown.mdx +4 -4
  311. package/docs/discoverability/mcp.mdx +11 -11
  312. package/docs/discoverability/sitemap-and-robots.mdx +3 -3
  313. package/docs/index.mdx +2 -2
  314. package/docs/references/asyncapi.mdx +59 -0
  315. package/docs/{advanced → references}/graphql.mdx +45 -32
  316. package/docs/{reference → references}/meta.ts +2 -2
  317. package/docs/references/openapi.mdx +171 -0
  318. package/docs/references/scalar.mdx +64 -0
  319. package/package.json +42 -8
  320. package/skills/blume/SKILL.md +21 -8
  321. package/skills/blume-migrate/SKILL.md +22 -21
  322. package/skills/blume-migrate/assets/oxfmt@0.67.0.patch +49 -0
  323. package/skills/blume-migrate/references/docusaurus.md +5 -4
  324. package/skills/blume-migrate/references/fumadocs.md +4 -4
  325. package/skills/blume-migrate/references/mintlify.md +23 -8
  326. package/skills/blume-migrate/references/monorepo.md +6 -6
  327. package/skills/blume-migrate/references/starlight.md +4 -4
  328. package/src/ai/agent-readability.ts +21 -22
  329. package/src/ai/ai-catalog.ts +50 -32
  330. package/src/ai/api/handlers.ts +46 -11
  331. package/src/ai/api-catalog.ts +8 -8
  332. package/src/ai/ask-data.ts +1 -1
  333. package/src/ai/ask.ts +624 -100
  334. package/src/ai/changelog-markdown.ts +91 -0
  335. package/src/ai/component-markdown.ts +328 -12
  336. package/src/ai/index.ts +45 -0
  337. package/src/ai/link-headers.ts +7 -6
  338. package/src/ai/llms.ts +20 -15
  339. package/src/ai/markdown.ts +35 -5
  340. package/src/ai/mcp/data.ts +9 -5
  341. package/src/ai/openapi-components.ts +4 -1
  342. package/src/ai/relative-links.ts +170 -0
  343. package/src/ai/serializers.ts +2 -2
  344. package/src/ai/skills.ts +1 -1
  345. package/src/ai/web-bot-auth.ts +2 -2
  346. package/src/analytics/adobe.ts +46 -0
  347. package/src/analytics/amplitude.ts +79 -0
  348. package/src/analytics/clarity.ts +46 -0
  349. package/src/analytics/clearbit.ts +47 -0
  350. package/src/analytics/cloudflare.ts +67 -0
  351. package/src/analytics/fathom.ts +64 -0
  352. package/src/analytics/google-analytics.ts +84 -0
  353. package/src/analytics/google-tag-manager.ts +61 -0
  354. package/src/analytics/head.ts +130 -0
  355. package/src/analytics/heap.ts +65 -0
  356. package/src/analytics/hightouch.ts +77 -0
  357. package/src/analytics/hotjar.ts +47 -0
  358. package/src/analytics/index.ts +71 -0
  359. package/src/analytics/inline.ts +21 -0
  360. package/src/analytics/logrocket.ts +71 -0
  361. package/src/analytics/mixpanel.ts +92 -0
  362. package/src/analytics/pirsch.ts +66 -0
  363. package/src/analytics/plausible.ts +83 -0
  364. package/src/analytics/posthog.ts +78 -0
  365. package/src/analytics/schema.ts +60 -0
  366. package/src/analytics/script.ts +60 -0
  367. package/src/analytics/segment.ts +85 -0
  368. package/src/analytics/vercel.ts +50 -0
  369. package/src/astro/adapter-root.ts +7 -9
  370. package/src/astro/component-slots.ts +131 -91
  371. package/src/astro/generate.ts +112 -345
  372. package/src/astro/integration.ts +2 -6
  373. package/src/astro/pages.ts +13 -101
  374. package/src/astro/render-deps.ts +379 -0
  375. package/src/astro/runtime-deps.ts +201 -0
  376. package/src/astro/templates.ts +554 -541
  377. package/src/audit/agent.ts +24 -0
  378. package/src/audit/catalog.ts +2 -2
  379. package/src/audit/checks/assets.ts +2 -2
  380. package/src/audit/checks/dns-aid.ts +1 -1
  381. package/src/audit/checks/duplicates.ts +3 -1
  382. package/src/audit/checks/i18n.ts +1 -1
  383. package/src/audit/checks/indexability.ts +7 -7
  384. package/src/audit/checks/links.ts +2 -2
  385. package/src/audit/checks/llms.ts +6 -6
  386. package/src/audit/checks/network.ts +3 -3
  387. package/src/audit/checks/og-image.ts +2 -2
  388. package/src/audit/checks/robots.ts +1 -1
  389. package/src/audit/checks/sitemap.ts +2 -2
  390. package/src/audit/checks/social.ts +1 -1
  391. package/src/audit/run.ts +4 -3
  392. package/src/audit/terms.ts +31 -0
  393. package/src/audit/url.ts +13 -13
  394. package/src/cli/command-meta.ts +10 -0
  395. package/src/cli/commands/audit.ts +39 -20
  396. package/src/cli/commands/build.ts +71 -316
  397. package/src/cli/commands/check.ts +1 -0
  398. package/src/cli/commands/dev.ts +40 -1
  399. package/src/cli/commands/doctor.ts +90 -14
  400. package/src/cli/commands/eject.ts +44 -7
  401. package/src/cli/commands/eval.ts +2 -2
  402. package/src/cli/commands/init.ts +161 -41
  403. package/src/cli/commands/migrate.ts +121 -0
  404. package/src/cli/commands/preview.ts +7 -1
  405. package/src/cli/commands/translate.ts +2 -2
  406. package/src/cli/commands/upgrade.ts +141 -0
  407. package/src/cli/commands/version.ts +57 -44
  408. package/src/cli/eject-scripts.ts +121 -6
  409. package/src/cli/index.ts +11 -1
  410. package/src/cli/init/install.ts +70 -0
  411. package/src/cli/init/questions.ts +7 -0
  412. package/src/cli/init/scaffold.ts +459 -75
  413. package/src/cli/lazy-command.ts +37 -1
  414. package/src/cli/prepare.ts +40 -6
  415. package/src/cli/required-secrets.ts +38 -11
  416. package/src/cli/unknown-flags.ts +266 -0
  417. package/src/cli/yarn-pnp.ts +52 -0
  418. package/src/components/content/AccordionItem.astro +7 -1
  419. package/src/components/content/Card.astro +4 -3
  420. package/src/components/content/ColorItem.astro +22 -4
  421. package/src/components/content/GithubInfo.astro +2 -2
  422. package/src/components/content/Prompt.astro +25 -25
  423. package/src/components/content/Tabs.astro +3 -1
  424. package/src/components/content/Tile.astro +2 -3
  425. package/src/components/content/Tooltip.astro +57 -9
  426. package/src/components/content/content-strings.ts +34 -0
  427. package/src/components/content/diff.ts +1 -1
  428. package/src/components/content/mermaid-element.ts +13 -2
  429. package/src/components/content/prompt-markdown.ts +292 -0
  430. package/src/components/content/tooltip-id.ts +41 -0
  431. package/src/components/islands/hooks.ts +25 -2
  432. package/src/components/layout/Analytics.astro +21 -79
  433. package/src/components/layout/Banner.astro +3 -1
  434. package/src/components/layout/DiscoveryLinks.astro +69 -0
  435. package/src/components/layout/Header.astro +83 -20
  436. package/src/components/layout/LanguageSwitcher.astro +4 -1
  437. package/src/components/layout/Logo.astro +23 -2
  438. package/src/components/layout/NavSelector.astro +13 -2
  439. package/src/components/layout/NavTree.astro +12 -3
  440. package/src/components/layout/NavTreeScript.astro +17 -3
  441. package/src/components/layout/PageActions.astro +3 -3
  442. package/src/components/layout/PageFeedback.astro +11 -1
  443. package/src/components/layout/PageLayout.astro +52 -5
  444. package/src/components/layout/ReferenceLayout.astro +21 -12
  445. package/src/components/layout/RootLayout.astro +69 -66
  446. package/src/components/layout/Search.astro +30 -6
  447. package/src/components/layout/WebMcp.astro +1 -1
  448. package/src/components/layout/analytics-client.ts +72 -15
  449. package/src/components/layout/drawer-inert.ts +113 -15
  450. package/src/components/layout/dropdown-clamp.ts +105 -0
  451. package/src/components/layout/head-scripts.ts +15 -6
  452. package/src/components/layout/nav-utils.ts +17 -0
  453. package/src/components/layout/search/algolia.ts +8 -8
  454. package/src/components/layout/search/orama-cloud.ts +9 -7
  455. package/src/components/layout/search/typesense.ts +11 -17
  456. package/src/components/openapi/MessageComposer.astro +2 -2
  457. package/src/components/openapi/Playground.astro +2 -2
  458. package/src/components/openapi/playground-client.ts +79 -10
  459. package/src/core/changelog-index.ts +24 -0
  460. package/src/core/component-overrides.ts +399 -154
  461. package/src/core/config-input.ts +188 -553
  462. package/src/core/config.ts +130 -41
  463. package/src/core/custom-pages.ts +105 -0
  464. package/src/core/data.ts +31 -12
  465. package/src/core/define-components.ts +12 -9
  466. package/src/core/deployment-env.ts +18 -74
  467. package/src/core/diagnostics.ts +14 -7
  468. package/src/core/graph.ts +69 -25
  469. package/src/core/i18n-ui.ts +6 -2
  470. package/src/core/i18n.ts +17 -0
  471. package/src/core/includes.ts +156 -38
  472. package/src/core/last-modified.ts +6 -11
  473. package/src/core/links.ts +166 -2
  474. package/src/core/manifest.ts +10 -3
  475. package/src/core/navigation.ts +115 -16
  476. package/src/core/new-tab.ts +35 -0
  477. package/src/core/node-require.ts +21 -0
  478. package/src/core/project-graph.ts +42 -26
  479. package/src/core/project.ts +9 -4
  480. package/src/core/request-body.ts +61 -0
  481. package/src/core/safe-href.ts +28 -0
  482. package/src/core/safe-links.ts +68 -0
  483. package/src/core/schema.ts +517 -739
  484. package/src/core/server-features.ts +8 -9
  485. package/src/core/sources/assets.ts +47 -11
  486. package/src/core/sources/collection.ts +67 -0
  487. package/src/core/sources/contentful-rich-text.ts +285 -0
  488. package/src/core/sources/contentful.ts +173 -0
  489. package/src/core/sources/github-releases.ts +51 -1
  490. package/src/core/sources/json.ts +71 -0
  491. package/src/core/sources/lexical.ts +195 -0
  492. package/src/core/sources/lower.ts +226 -0
  493. package/src/core/sources/normalize.ts +52 -2
  494. package/src/core/sources/notion.ts +39 -28
  495. package/src/core/sources/payload.ts +135 -0
  496. package/src/core/sources/portable-text.ts +11 -16
  497. package/src/core/sources/remote.ts +226 -0
  498. package/src/core/sources/resolve.ts +104 -166
  499. package/src/core/sources/sanity.ts +16 -49
  500. package/src/core/sources/strapi-blocks.ts +124 -0
  501. package/src/core/sources/strapi.ts +191 -0
  502. package/src/core/sources/types.ts +12 -1
  503. package/src/core/types.ts +15 -1
  504. package/src/core/ui-packs/ar.ts +6 -2
  505. package/src/core/ui-packs/bg.ts +6 -2
  506. package/src/core/ui-packs/bn.ts +6 -2
  507. package/src/core/ui-packs/ca.ts +3 -1
  508. package/src/core/ui-packs/cs.ts +6 -2
  509. package/src/core/ui-packs/da.ts +6 -2
  510. package/src/core/ui-packs/de.ts +6 -2
  511. package/src/core/ui-packs/el.ts +3 -1
  512. package/src/core/ui-packs/es.ts +3 -1
  513. package/src/core/ui-packs/fa.ts +6 -2
  514. package/src/core/ui-packs/fi.ts +6 -2
  515. package/src/core/ui-packs/fr.ts +3 -1
  516. package/src/core/ui-packs/he.ts +6 -2
  517. package/src/core/ui-packs/hi.ts +6 -2
  518. package/src/core/ui-packs/hr.ts +6 -2
  519. package/src/core/ui-packs/hu.ts +6 -2
  520. package/src/core/ui-packs/id.ts +6 -2
  521. package/src/core/ui-packs/it.ts +3 -1
  522. package/src/core/ui-packs/ja.ts +3 -1
  523. package/src/core/ui-packs/ko.ts +3 -1
  524. package/src/core/ui-packs/nl.ts +6 -2
  525. package/src/core/ui-packs/no.ts +6 -2
  526. package/src/core/ui-packs/pl.ts +6 -2
  527. package/src/core/ui-packs/pt-br.ts +3 -1
  528. package/src/core/ui-packs/pt.ts +3 -1
  529. package/src/core/ui-packs/ro.ts +6 -2
  530. package/src/core/ui-packs/ru.ts +6 -2
  531. package/src/core/ui-packs/sk.ts +6 -2
  532. package/src/core/ui-packs/sr.ts +6 -2
  533. package/src/core/ui-packs/sv.ts +6 -2
  534. package/src/core/ui-packs/th.ts +3 -1
  535. package/src/core/ui-packs/tr.ts +6 -2
  536. package/src/core/ui-packs/uk.ts +6 -2
  537. package/src/core/ui-packs/vi.ts +3 -1
  538. package/src/core/ui-packs/zh-tw.ts +3 -1
  539. package/src/core/ui-packs/zh.ts +3 -1
  540. package/src/core/unrecognized-keys.ts +10 -0
  541. package/src/core/version-cut.ts +116 -8
  542. package/src/deploy/adapter-output.ts +57 -97
  543. package/src/deploy/adapters/cloudflare.ts +39 -0
  544. package/src/deploy/adapters/index.ts +41 -0
  545. package/src/deploy/adapters/netlify.ts +34 -0
  546. package/src/deploy/adapters/node.ts +34 -0
  547. package/src/deploy/adapters/registry.ts +127 -0
  548. package/src/deploy/adapters/types.ts +92 -0
  549. package/src/deploy/adapters/vercel.ts +35 -0
  550. package/src/deploy/artifacts.ts +55 -27
  551. package/src/deploy/cloudflare-negotiation.ts +179 -100
  552. package/src/deploy/function-bundle.ts +18 -3
  553. package/src/deploy/headers.ts +124 -23
  554. package/src/deploy/node-headers.ts +198 -0
  555. package/src/deploy/platforms/cloudflare.ts +312 -0
  556. package/src/deploy/platforms/index.ts +67 -0
  557. package/src/deploy/platforms/netlify.ts +52 -0
  558. package/src/deploy/platforms/node.ts +40 -0
  559. package/src/deploy/platforms/paths.ts +42 -0
  560. package/src/deploy/platforms/static.ts +29 -0
  561. package/src/deploy/platforms/types.ts +112 -0
  562. package/src/deploy/platforms/vercel.ts +193 -0
  563. package/src/deploy/redirects.ts +30 -18
  564. package/src/deploy/robots.ts +3 -3
  565. package/src/deploy/rss.ts +2 -2
  566. package/src/deploy/sitemap.ts +2 -2
  567. package/src/deploy/vercel-negotiation.ts +2 -2
  568. package/src/eval/agents.ts +32 -1
  569. package/src/eval/findings.ts +19 -11
  570. package/src/eval/report.ts +10 -2
  571. package/src/markdown/external-links.ts +65 -0
  572. package/src/markdown/include.ts +45 -27
  573. package/src/markdown/index.ts +34 -9
  574. package/src/markdown/inline-code.ts +12 -6
  575. package/src/markdown/relative-links.ts +324 -0
  576. package/src/markdown/themes.ts +3 -3
  577. package/src/migrate/migrate.ts +149 -0
  578. package/src/openapi/parse.ts +64 -16
  579. package/src/openapi/proxy.ts +62 -10
  580. package/src/openapi/references.ts +147 -147
  581. package/src/openapi/render-mdx.ts +32 -10
  582. package/src/openapi/scalar.ts +15 -13
  583. package/src/openapi/sentence.ts +14 -0
  584. package/src/openapi/source.ts +37 -21
  585. package/src/openapi/spec-dependency-error.ts +15 -0
  586. package/src/reference/asyncapi.ts +83 -0
  587. package/src/reference/graphql.ts +89 -0
  588. package/src/reference/index.ts +40 -0
  589. package/src/reference/openapi.ts +83 -0
  590. package/src/reference/options.ts +201 -0
  591. package/src/reference/scalar.ts +136 -0
  592. package/src/reference/schema.ts +88 -0
  593. package/src/registry/eject.ts +97 -42
  594. package/src/search/adapters/algolia.ts +46 -0
  595. package/src/search/adapters/flexsearch.ts +29 -0
  596. package/src/search/adapters/index.ts +39 -0
  597. package/src/search/adapters/mixedbread.ts +39 -0
  598. package/src/search/adapters/orama-cloud.ts +51 -0
  599. package/src/search/adapters/orama.ts +24 -0
  600. package/src/search/adapters/pagefind.ts +27 -0
  601. package/src/search/adapters/registry.ts +131 -0
  602. package/src/search/adapters/types.ts +46 -0
  603. package/src/search/adapters/typesense.ts +57 -0
  604. package/src/search/build.ts +8 -4
  605. package/src/search/documents.ts +6 -0
  606. package/src/search/sync/algolia.ts +12 -11
  607. package/src/search/sync/index.ts +35 -20
  608. package/src/search/sync/orama-cloud.ts +12 -9
  609. package/src/search/sync/typesense.ts +15 -13
  610. package/src/sources/contentful.ts +63 -0
  611. package/src/sources/custom.ts +38 -0
  612. package/src/sources/filesystem.ts +51 -0
  613. package/src/sources/github-releases.ts +52 -0
  614. package/src/sources/index.ts +60 -0
  615. package/src/sources/mdx-remote.ts +76 -0
  616. package/src/sources/notion.ts +63 -0
  617. package/src/sources/obsidian.ts +38 -0
  618. package/src/sources/payload.ts +60 -0
  619. package/src/sources/registry.ts +182 -0
  620. package/src/sources/sanity.ts +66 -0
  621. package/src/sources/shared.ts +52 -0
  622. package/src/sources/strapi.ts +58 -0
  623. package/src/theme/entry.ts +24 -2
  624. package/src/translate/report.ts +40 -7
  625. package/src/upgrade/upgrade.ts +499 -0
  626. package/dist/cli/chunk-0qymqwzz.js +0 -164
  627. package/dist/cli/chunk-0qymqwzz.js.map +0 -15
  628. package/dist/cli/chunk-1jefwnfs.js.map +0 -48
  629. package/dist/cli/chunk-2mzebbbz.js +0 -69
  630. package/dist/cli/chunk-2z47ypj8.js.map +0 -11
  631. package/dist/cli/chunk-4x36ddpw.js.map +0 -11
  632. package/dist/cli/chunk-5093q3n7.js +0 -68
  633. package/dist/cli/chunk-5093q3n7.js.map +0 -10
  634. package/dist/cli/chunk-5qk08vmp.js.map +0 -11
  635. package/dist/cli/chunk-7s8hm3b6.js +0 -5347
  636. package/dist/cli/chunk-7s8hm3b6.js.map +0 -58
  637. package/dist/cli/chunk-8cjtbafj.js.map +0 -13
  638. package/dist/cli/chunk-97r59kpr.js +0 -381
  639. package/dist/cli/chunk-97r59kpr.js.map +0 -12
  640. package/dist/cli/chunk-ahnw3kxw.js.map +0 -15
  641. package/dist/cli/chunk-b27xqwn9.js.map +0 -10
  642. package/dist/cli/chunk-bf6bt1xt.js +0 -185
  643. package/dist/cli/chunk-bf6bt1xt.js.map +0 -11
  644. package/dist/cli/chunk-cjtn640a.js.map +0 -10
  645. package/dist/cli/chunk-ct47dqpx.js.map +0 -11
  646. package/dist/cli/chunk-esphfr8p.js +0 -107
  647. package/dist/cli/chunk-esphfr8p.js.map +0 -11
  648. package/dist/cli/chunk-ex56aa81.js +0 -1016
  649. package/dist/cli/chunk-ex56aa81.js.map +0 -13
  650. package/dist/cli/chunk-garjf5z9.js +0 -30
  651. package/dist/cli/chunk-garjf5z9.js.map +0 -10
  652. package/dist/cli/chunk-js7saxwm.js +0 -1045
  653. package/dist/cli/chunk-js7saxwm.js.map +0 -22
  654. package/dist/cli/chunk-k79xp7av.js.map +0 -39
  655. package/dist/cli/chunk-ps4m1xh4.js.map +0 -15
  656. package/dist/cli/chunk-q4rae3bg.js +0 -60
  657. package/dist/cli/chunk-q4rae3bg.js.map +0 -10
  658. package/dist/cli/chunk-rz9jmfhz.js +0 -108
  659. package/dist/cli/chunk-rz9jmfhz.js.map +0 -10
  660. package/dist/cli/chunk-vh9w1sgp.js +0 -73
  661. package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
  662. package/dist/cli/chunk-vrfp10qk.js +0 -81
  663. package/dist/cli/chunk-vrfp10qk.js.map +0 -10
  664. package/dist/cli/chunk-yg63d42r.js.map +0 -34
  665. package/docs/advanced/api-reference.mdx +0 -240
  666. package/docs/reference/cli.mdx +0 -197
  667. package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
  668. package/src/components/content/changelog-element.ts +0 -69
  669. package/src/search/providers.ts +0 -91
  670. /package/dist/cli/{chunk-e7f42gdj.js.map → chunk-7ez8ny0t.js.map} +0 -0
  671. /package/dist/cli/{chunk-nn13znc2.js.map → chunk-88cpgt6h.js.map} +0 -0
  672. /package/dist/cli/{chunk-vacwm2hv.js.map → chunk-f7t03s3g.js.map} +0 -0
  673. /package/dist/cli/{chunk-dwgcp5sm.js.map → chunk-zxccj738.js.map} +0 -0
package/src/ai/llms.ts CHANGED
@@ -10,6 +10,7 @@ import { AI_CATALOG_PATH, hasAiCatalog } from "./ai-catalog.ts";
10
10
  import { API_CATALOG_PATH, hasApiCatalog } from "./api-catalog.ts";
11
11
  import { API_PAGES_PATH, OPENAPI_PATH } from "./api/paths.ts";
12
12
  import { downlevelComponents } from "./component-markdown.ts";
13
+ import { relativeLinkRewriter } from "./relative-links.ts";
13
14
  import { projectComponentSerializers } from "./serializers.ts";
14
15
  import { AGENT_SKILLS_DIR, AGENT_SKILLS_INDEX_PATH } from "./skills.ts";
15
16
  import type { SkillArtifact } from "./skills.ts";
@@ -49,24 +50,24 @@ const oneLine = (text: string): string => text.replaceAll(/\s+/gu, " ").trim();
49
50
  */
50
51
  const agentResourceLines = (project: BlumeProject): string[] => {
51
52
  const { config } = project;
52
- const { site } = config.deployment;
53
+ const { site } = config.deployment.options;
53
54
  const url = (path: string): string =>
54
- pageUrl(path, site, normalizeBasePath(config.deployment.base));
55
+ pageUrl(path, site, normalizeBasePath(config.deployment.options.base));
55
56
  const lines = [
56
57
  `- [llms-full.txt](${url("/llms-full.txt")}): The full Markdown of every page in one file.`,
57
58
  `- [Page Markdown](${url("/index.md")}): Append \`.md\` to any page URL to fetch that page as raw Markdown.`,
58
59
  ];
59
- if (config.ai.api) {
60
+ if (config.agents.api) {
60
61
  lines.push(
61
62
  `- [JSON API](${url(API_PAGES_PATH)}): Page index of the JSON docs API; each entry links the page's JSON and Markdown forms. Described by the OpenAPI document at ${url(OPENAPI_PATH)}.`
62
63
  );
63
64
  }
64
- if (config.ai.mcp.enabled) {
65
+ if (config.agents.mcp.enabled) {
65
66
  lines.push(
66
- `- [MCP server](${url(config.ai.mcp.route)}): Streamable HTTP Model Context Protocol server with search_docs, get_page, list_pages, and get_navigation tools, plus every page as a resource. Discovery document: ${url("/.well-known/mcp.json")}`
67
+ `- [MCP server](${url(config.agents.mcp.route)}): Streamable HTTP Model Context Protocol server with search_docs, get_page, list_pages, and get_navigation tools, plus every page as a resource. Discovery document: ${url("/.well-known/mcp.json")}`
67
68
  );
68
69
  }
69
- if (config.ai.skills) {
70
+ if (config.agents.skills) {
70
71
  lines.push(
71
72
  `- [Agent skills](${url(AGENT_SKILLS_INDEX_PATH)}): Agent Skills discovery index of the skills this site publishes.`
72
73
  );
@@ -81,7 +82,7 @@ const agentResourceLines = (project: BlumeProject): string[] => {
81
82
  `- [AI catalog](${url(AI_CATALOG_PATH)}): ARD manifest of the agent-facing resources on this site (MCP server, skills, APIs).`
82
83
  );
83
84
  }
84
- if (config.seo.agentReadability) {
85
+ if (config.agents.agentReadability) {
85
86
  lines.push(
86
87
  `- [agent-readability.json](${url("/agent-readability.json")}): Manifest of every agent-facing artifact on this site.`
87
88
  );
@@ -96,7 +97,7 @@ const agentResourceLines = (project: BlumeProject): string[] => {
96
97
 
97
98
  // Drafts, hidden, and ordinary `noindex` pages are excluded. Generated API
98
99
  // references keep crawler visibility (`noindex`) separate from LLM visibility
99
- // (`ai.exclude`), and are excluded wholesale when `ai.llmsTxt.openapi` is off.
100
+ // (`ai.exclude`), and are excluded wholesale when `agents.llmsTxt.openapi` is off.
100
101
  // `versions: "current"` additionally drops archived-snapshot pages — the flat
101
102
  // llms-full.txt dump serves agents the live docs, not every frozen copy.
102
103
  const eligiblePages = (
@@ -112,7 +113,7 @@ const eligiblePages = (
112
113
  (page.meta.seo.noindex && page.source.name !== "openapi") ||
113
114
  (options.versions === "current" && page.version !== "")
114
115
  ) &&
115
- (project.config.ai.llmsTxt.openapi || page.source.name !== "openapi")
116
+ (project.config.agents.llmsTxt.openapi || page.source.name !== "openapi")
116
117
  );
117
118
 
118
119
  /**
@@ -166,8 +167,8 @@ export const buildLlmsIndex = (
166
167
  options: LlmsIndexOptions = {}
167
168
  ): string => {
168
169
  const { config } = project;
169
- const { site } = config.deployment;
170
- const base = normalizeBasePath(config.deployment.base);
170
+ const { site } = config.deployment.options;
171
+ const base = normalizeBasePath(config.deployment.options.base);
171
172
  const eligible = eligiblePages(project);
172
173
  const byRoute = new Map(eligible.map((page) => [page.route, page]));
173
174
  const seen = new Set<string>();
@@ -285,7 +286,7 @@ export const buildLlmsIndex = (
285
286
  : `# ${config.title}`;
286
287
  // `details` is the llms.txt spec's free-form block between the summary and
287
288
  // the file sections — "when to use this" guidance in the site's own words.
288
- const { details } = config.ai.llmsTxt;
289
+ const { details } = config.agents.llmsTxt;
289
290
  const lead = details ? `${header}\n\n${details}` : header;
290
291
  return `${[lead, ...blocks].join("\n\n")}\n`;
291
292
  };
@@ -297,6 +298,7 @@ const buildFull = async (project: BlumeProject): Promise<string> => {
297
298
  (a, b) => a.route.localeCompare(b.route)
298
299
  );
299
300
  const components = projectComponentSerializers(project);
301
+ const rewriteLinks = relativeLinkRewriter(project);
300
302
 
301
303
  const sections = await Promise.all(
302
304
  pages.map(async (page) => {
@@ -305,11 +307,14 @@ const buildFull = async (project: BlumeProject): Promise<string> => {
305
307
  // llms-full.txt; point them at the served originals instead.
306
308
  if (page.sourcePath) {
307
309
  raw = rewriteRelativeImages({
308
- deployBase: config.deployment.base,
310
+ deployBase: config.deployment.options.base,
309
311
  projectRoot: project.context.root,
310
312
  source: raw,
311
313
  sourcePath: page.sourcePath,
312
314
  });
315
+ // Relative page links too: a reader of one flat file has no page URL
316
+ // to resolve `./install` against.
317
+ raw = rewriteLinks(raw, page);
313
318
  }
314
319
  // Resolve `<Visibility>` audiences (web-only content omitted from the
315
320
  // agent-facing output, agents-only unwrapped), then downlevel supported
@@ -322,8 +327,8 @@ const buildFull = async (project: BlumeProject): Promise<string> => {
322
327
  ).trim();
323
328
  const url = pageUrl(
324
329
  page.route,
325
- config.deployment.site,
326
- normalizeBasePath(config.deployment.base)
330
+ config.deployment.options.site,
331
+ normalizeBasePath(config.deployment.options.base)
327
332
  );
328
333
  return [`# ${page.title}`, `Source: ${url}`, "", body].join("\n");
329
334
  })
@@ -1,12 +1,17 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
 
3
+ import { hasGeneratedChangelog } from "../astro/pages.ts";
4
+ import { CHANGELOG_INDEX_ROUTE } from "../core/changelog-index.ts";
3
5
  import { rewriteRelativeImages } from "../core/content-assets.ts";
6
+ import { discoverPages, discoverPagesSync } from "../core/custom-pages.ts";
4
7
  import matter from "../core/frontmatter.ts";
5
8
  import type { BlumeProject } from "../core/project-graph.ts";
6
9
  import { readExpandedEntryText } from "../core/sources/read.ts";
7
10
  import type { RouteManifestEntry } from "../core/types.ts";
11
+ import { buildChangelogIndexMarkdown } from "./changelog-markdown.ts";
8
12
  import { downlevelComponents } from "./component-markdown.ts";
9
13
  import { buildLlmsIndex } from "./llms.ts";
14
+ import { relativeLinkRewriter } from "./relative-links.ts";
10
15
  import { projectComponentSerializers } from "./serializers.ts";
11
16
  import { applyAgentVisibility } from "./visibility.ts";
12
17
 
@@ -46,7 +51,8 @@ export const markdownTokenCount = (text: string): number =>
46
51
  * removed, agents-only unwrapped. Relative image references are rewritten to
47
52
  * their served `/blume-assets/content/…` URLs in both variants too — an agent
48
53
  * fetches these endpoints by URL, where a colocated `./diagram.png` resolves
49
- * to nothing.
54
+ * to nothing — and relative page links to the routes they mean, as the
55
+ * rendered page's are (see `relative-links.ts`).
50
56
  */
51
57
  export const buildRawMarkdown = async (
52
58
  project: BlumeProject
@@ -54,6 +60,7 @@ export const buildRawMarkdown = async (
54
60
  const pageById = new Map(project.graph.pages.map((page) => [page.id, page]));
55
61
 
56
62
  const components = projectComponentSerializers(project);
63
+ const rewriteLinks = relativeLinkRewriter(project);
57
64
 
58
65
  const readRoute = async (route: RouteManifestEntry): Promise<string> => {
59
66
  const page = pageById.get(route.id);
@@ -68,11 +75,17 @@ export const buildRawMarkdown = async (
68
75
  let text = await readRoute(route);
69
76
  if (route.sourcePath) {
70
77
  text = rewriteRelativeImages({
71
- deployBase: project.config.deployment.base,
78
+ deployBase: project.config.deployment.options.base,
72
79
  projectRoot: project.context.root,
73
80
  source: text,
74
81
  sourcePath: route.sourcePath,
75
82
  });
83
+ // `./install` means the page's sibling, not whatever the `.md` URL
84
+ // an agent fetched resolves it to.
85
+ text = rewriteLinks(text, {
86
+ route: route.path,
87
+ sourcePath: route.sourcePath,
88
+ });
76
89
  }
77
90
  const source = applyAgentVisibility(text);
78
91
  // The `.md` variant keeps the front-matter block in the output, but its
@@ -92,18 +105,35 @@ export const buildRawMarkdown = async (
92
105
  if (!map["/"]) {
93
106
  map["/"] = { mdx: buildLlmsIndex(project) };
94
107
  }
108
+ // The generated changelog index has no source either; its release list is
109
+ // its mirror, so `/changelog.md` and `get_page` answer as the page does.
110
+ const userPages = project.context.pagesRoot
111
+ ? await discoverPages(project.context.pagesRoot)
112
+ : [];
113
+ if (hasGeneratedChangelog(project, userPages)) {
114
+ map[CHANGELOG_INDEX_ROUTE] = { mdx: buildChangelogIndexMarkdown(project) };
115
+ }
95
116
  return map;
96
117
  };
97
118
 
98
119
  /**
99
120
  * Every route path with a raw-Markdown mirror: the manifest routes, plus the
100
- * homepage when its mirror is the synthesized llms.txt fallback (see
101
- * `buildRawMarkdown`). This is the route list the negotiation surfaces (dev
121
+ * homepage when its mirror is the synthesized llms.txt fallback and the
122
+ * generated changelog index (see `buildRawMarkdown`). This is the route list the negotiation surfaces (dev
102
123
  * middleware, Vercel routing config) and the homepage `Link` header build
103
124
  * from, so `Accept: text/markdown` on `/` resolves even when the homepage is
104
125
  * a landing page.
105
126
  */
106
127
  export const markdownRoutePaths = (project: BlumeProject): string[] => {
107
128
  const paths = project.manifest.routes.map((route) => route.path);
108
- return paths.includes("/") ? paths : [...paths, "/"];
129
+ if (!paths.includes("/")) {
130
+ paths.push("/");
131
+ }
132
+ const userPages = project.context.pagesRoot
133
+ ? discoverPagesSync(project.context.pagesRoot)
134
+ : [];
135
+ if (hasGeneratedChangelog(project, userPages)) {
136
+ paths.push(CHANGELOG_INDEX_ROUTE);
137
+ }
138
+ return paths;
109
139
  };
@@ -88,8 +88,12 @@ export const buildMcpData = async (project: BlumeProject): Promise<McpData> => {
88
88
  const pageById = new Map(graph.pages.map((page) => [page.id, page]));
89
89
 
90
90
  const routes: McpRoute[] = [];
91
+ // Fallback routes render the fallback locale's page at another locale's
92
+ // URL: listing them would pass that page off as a translation, once per
93
+ // locale. `get_page` still resolves them through `pages`, as llms.txt and
94
+ // search leave them out.
91
95
  for (const route of manifest.routes) {
92
- if (route.hidden) {
96
+ if (route.hidden || route.fallback) {
93
97
  continue;
94
98
  }
95
99
  const page = pageById.get(route.id);
@@ -111,7 +115,7 @@ export const buildMcpData = async (project: BlumeProject): Promise<McpData> => {
111
115
  }
112
116
 
113
117
  const data: McpData = {
114
- base: normalizeBasePath(config.deployment.base),
118
+ base: normalizeBasePath(config.deployment.options.base),
115
119
  defaultLocale: config.i18n?.defaultLocale,
116
120
  documents: documents.map((doc) => {
117
121
  const document: OramaDoc = {
@@ -128,12 +132,12 @@ export const buildMcpData = async (project: BlumeProject): Promise<McpData> => {
128
132
  }
129
133
  return document;
130
134
  }),
131
- instructions: config.ai.mcp.instructions,
132
- name: config.ai.mcp.name ?? config.title,
135
+ instructions: config.agents.mcp.instructions,
136
+ name: config.agents.mcp.name ?? config.title,
133
137
  navigation: graph.navigation,
134
138
  pages,
135
139
  routes,
136
- site: config.deployment.site ?? null,
140
+ site: config.deployment.options.site ?? null,
137
141
  version: manifest.blumeVersion,
138
142
  };
139
143
  if (config.versions) {
@@ -1,5 +1,6 @@
1
1
  import type { ApiOperationRef, OpenApiData } from "../openapi/model.ts";
2
2
  import { operationOf, specAddresses, specOf } from "../openapi/model.ts";
3
+ import { asSentence } from "../openapi/sentence.ts";
3
4
  import { operationSignature } from "../openapi/signature.ts";
4
5
  import type {
5
6
  ComponentMarkdown,
@@ -25,7 +26,9 @@ const listItem = (
25
26
  operation: Pick<ApiOperationRef, "deprecated" | "route" | "summary">
26
27
  ): string => {
27
28
  const tail = [
28
- inlineText(operation.summary),
29
+ // Title-like summaries ("Get a flag") need their own period before the
30
+ // "Deprecated." that may follow.
31
+ inlineText(asSentence(operation.summary.trim())),
29
32
  operation.deprecated ? "Deprecated." : "",
30
33
  ]
31
34
  .filter(Boolean)
@@ -0,0 +1,170 @@
1
+ import { basename } from "pathe";
2
+
3
+ import { normalizeBasePath, withBasePath } from "../core/base-path.ts";
4
+ import { nextFenceState } from "../core/code-fences.ts";
5
+ import type { FenceState } from "../core/code-fences.ts";
6
+ import {
7
+ buildFileRouteIndex,
8
+ isIndexFileName,
9
+ resolveRelativeHref,
10
+ routeOfLinkedFile,
11
+ } from "../core/links.ts";
12
+ import type { RelativeLinkBase } from "../core/links.ts";
13
+ import type { BlumeProject } from "../core/project-graph.ts";
14
+ import { extractLinks } from "../core/sources/normalize.ts";
15
+
16
+ /**
17
+ * Relative page links on the agent surfaces — the `.md`/`.mdx` mirrors,
18
+ * llms-full.txt, MCP `get_page` and `resources/read`. An agent resolves
19
+ * `[Install](./install)` against the URL it fetched (`/guides.md`), so the
20
+ * link lands on `/install`; the rendered page rewrites it to the route it
21
+ * means (`markdown/relative-links.ts`), and the Markdown an agent reads gets
22
+ * the same rewrite from the same resolver (`resolveRelativeHref`), so both
23
+ * point at one page. Inline links and reference definitions are rewritten;
24
+ * fenced and inline code, images, and anything not a relative page link are
25
+ * left as written.
26
+ */
27
+
28
+ /** The page a Markdown text was written for. */
29
+ export interface LinkedPage {
30
+ route: string;
31
+ sourcePath?: string;
32
+ }
33
+
34
+ /** Rewrite a page's relative page links to the routes they mean. */
35
+ export type RelativeLinkRewriter = (text: string, page: LinkedPage) => string;
36
+
37
+ /** A reference definition's target: `[label]: ./install` or `<./install>`. */
38
+ const DEFINITION =
39
+ /^(?<lead> {0,3}\[(?:[^\]\\]|\\.)+\]:[\t ]*)(?:<(?<angled>[^>]*)>|(?<bare>\S+))/u;
40
+
41
+ /**
42
+ * Whether a text could hold a relative page link at all: an inline link, a
43
+ * reference definition, or a component `href` whose target isn't a URL with
44
+ * a scheme, a root path, or a fragment. Most pages hold none, and those skip
45
+ * the link parse and the line-by-line fence scan entirely.
46
+ */
47
+ const MAYBE_RELATIVE =
48
+ /\]\([\t ]*<?(?![a-z][\d+.a-z-]*:|\/|#)|^ {0,3}\[[^\]\n]+\]:[\t ]*<?(?![a-z][\d+.a-z-]*:|\/|#)|\shref=["'](?![a-z][\d+.a-z-]*:|\/|#)/imu;
49
+
50
+ interface Splice {
51
+ column: number;
52
+ length: number;
53
+ text: string;
54
+ }
55
+
56
+ /** Apply same-line splices, right to left so earlier columns stay valid. */
57
+ const spliceLine = (line: string, splices: readonly Splice[]): string => {
58
+ let out = line;
59
+ for (const splice of splices.toSorted((a, b) => b.column - a.column)) {
60
+ out =
61
+ out.slice(0, splice.column) +
62
+ splice.text +
63
+ out.slice(splice.column + splice.length);
64
+ }
65
+ return out;
66
+ };
67
+
68
+ /** One line's reference-definition splice, when it defines a routed target. */
69
+ const definitionSplice = (
70
+ line: string,
71
+ routed: (target: string) => string | undefined
72
+ ): Splice | undefined => {
73
+ const groups = DEFINITION.exec(line)?.groups;
74
+ const lead = groups?.lead;
75
+ const target = groups?.angled ?? groups?.bare;
76
+ const route = target === undefined ? undefined : routed(target);
77
+ if (lead === undefined || target === undefined || route === undefined) {
78
+ return undefined;
79
+ }
80
+ // An angle-bracketed target starts one past its `<`.
81
+ const angled = groups?.angled === undefined ? 0 : 1;
82
+ return { column: lead.length + angled, length: target.length, text: route };
83
+ };
84
+
85
+ /** Every routed splice in `text`, by 0-based line: links, then definitions. */
86
+ const collectSplices = (
87
+ text: string,
88
+ lines: readonly string[],
89
+ routed: (target: string) => string | undefined
90
+ ): Map<number, Splice[]> => {
91
+ const splices = new Map<number, Splice[]>();
92
+ const add = (index: number, splice: Splice): void => {
93
+ splices.set(index, [...(splices.get(index) ?? []), splice]);
94
+ };
95
+ for (const link of extractLinks(text)) {
96
+ const route = link.image ? undefined : routed(link.target);
97
+ if (route !== undefined) {
98
+ add(link.line - 1, {
99
+ column: link.column - 1,
100
+ length: link.target.length,
101
+ text: route,
102
+ });
103
+ }
104
+ }
105
+ let fence: FenceState = null;
106
+ for (const [index, line] of lines.entries()) {
107
+ const next = nextFenceState(line, fence);
108
+ const inFence = fence !== null || next !== null;
109
+ fence = next;
110
+ const splice = inFence ? undefined : definitionSplice(line, routed);
111
+ if (splice !== undefined) {
112
+ add(index, splice);
113
+ }
114
+ }
115
+ return splices;
116
+ };
117
+
118
+ /**
119
+ * Build the rewriter for a project: the file → route lookup a `.md`/`.mdx`
120
+ * link resolves through is built once. A file shared by every locale
121
+ * publishes once per locale, and the default locale's route stands for it;
122
+ * fallback copies render another locale's file, so they never stand for one.
123
+ */
124
+ export const relativeLinkRewriter = (
125
+ project: BlumeProject
126
+ ): RelativeLinkRewriter => {
127
+ const { deployment, i18n } = project.config;
128
+ const deployBase = normalizeBasePath(deployment.options.base);
129
+ const localeTokens = i18n
130
+ ? ["$", ...i18n.locales.map((locale) => locale.code)]
131
+ : [];
132
+ const fileRoutes = buildFileRouteIndex(project.graph.pages, i18n ?? null);
133
+ const navPathBySource = new Map(
134
+ project.graph.pages.map((graphPage) => [
135
+ graphPage.sourcePath,
136
+ graphPage.navPath,
137
+ ])
138
+ );
139
+ const routes = new Set(project.manifest.routes.map((route) => route.path));
140
+
141
+ return (text, page) => {
142
+ const { sourcePath } = page;
143
+ if (!sourcePath || !MAYBE_RELATIVE.test(text)) {
144
+ return text;
145
+ }
146
+ const from: RelativeLinkBase = {
147
+ isIndex: isIndexFileName(basename(sourcePath), localeTokens),
148
+ route: page.route,
149
+ };
150
+ const navPath = navPathBySource.get(sourcePath) ?? basename(sourcePath);
151
+ const resolveFile = (path: string): string | undefined =>
152
+ routeOfLinkedFile(fileRoutes, { navPath, sourcePath }, path);
153
+ const routed = (target: string): string | undefined => {
154
+ const route = resolveRelativeHref(target, from, resolveFile, (path) =>
155
+ routes.has(path)
156
+ );
157
+ return route === undefined ? undefined : withBasePath(deployBase, route);
158
+ };
159
+
160
+ const lines = text.split("\n");
161
+ const splices = collectSplices(text, lines, routed);
162
+
163
+ return lines
164
+ .map((line, index) => {
165
+ const lineSplices = splices.get(index);
166
+ return lineSplices ? spliceLine(line, lineSplices) : line;
167
+ })
168
+ .join("\n");
169
+ };
170
+ };
@@ -8,7 +8,7 @@ import { openapiComponentSerializers } from "./openapi-components.ts";
8
8
  * Every serializer a project brings to a downlevel pass, layered once for all
9
9
  * the agent surfaces (`<route>.md`, llms-full.txt, the search and Ask AI
10
10
  * corpora): the built-in families that read project data — examples, then the
11
- * API reference — under the user's `ai.markdownComponents`, which is spread
11
+ * API reference — under the user's `agents.markdownComponents`, which is spread
12
12
  * last so an entry of the same name still wins. One layering, so a new family
13
13
  * or a new surface cannot leave one consumer printing raw JSX.
14
14
  */
@@ -20,5 +20,5 @@ export const projectComponentSerializers = (
20
20
  ...openapiComponentSerializers(
21
21
  project.sources.find(isOpenApiSource)?.openApiData() ?? {}
22
22
  ),
23
- ...project.config.ai.markdownComponents,
23
+ ...project.config.agents.markdownComponents,
24
24
  }) satisfies Record<string, ComponentMarkdown>;
package/src/ai/skills.ts CHANGED
@@ -201,7 +201,7 @@ export const buildSkillsIndex = (
201
201
  skills: readonly SkillArtifact[],
202
202
  config: ResolvedConfig
203
203
  ): string => {
204
- const deployBase = normalizeBasePath(config.deployment.base);
204
+ const deployBase = normalizeBasePath(config.deployment.options.base);
205
205
  const index = {
206
206
  $schema: AGENT_SKILLS_SCHEMA,
207
207
  skills: skills.map((skill) => ({
@@ -4,7 +4,7 @@ import type { ResolvedConfig } from "../core/schema.ts";
4
4
  * Web Bot Auth (IETF `webbotauth` WG): an org that runs agents publishes the
5
5
  * agents' HTTP Message Signature public keys in a JWKS at a well-known path
6
6
  * on its domain; sites receiving the signed requests fetch it to verify them.
7
- * Blume publishes the directory from `ai.webBotAuth.keys` — the schema admits
7
+ * Blume publishes the directory from `agents.webBotAuth.keys` — the schema admits
8
8
  * public keys only, so the site can never leak signing credentials.
9
9
  */
10
10
 
@@ -22,7 +22,7 @@ export const SIGNATURES_DIRECTORY_TYPE =
22
22
  export const buildSignaturesDirectory = (
23
23
  config: ResolvedConfig
24
24
  ): string | null => {
25
- const { keys } = config.ai.webBotAuth;
25
+ const { keys } = config.agents.webBotAuth;
26
26
  if (keys.length === 0) {
27
27
  return null;
28
28
  }
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+
3
+ import type { AdapterDescriptor } from "../core/adapter.ts";
4
+ import { adapterDescriptorSchema } from "../core/adapter.ts";
5
+ import type { HeadScript } from "./head.ts";
6
+
7
+ /** Options for {@link adobe}. */
8
+ export interface AdobeOptions {
9
+ /**
10
+ * The Launch (Adobe Experience Platform Tags) embed script URL for the
11
+ * environment to load, e.g. `https://assets.adobedtm.com/…/launch-….min.js`.
12
+ */
13
+ url: string;
14
+ }
15
+
16
+ export const adobeOptionsSchema = z.strictObject({
17
+ url: z.string().min(1),
18
+ });
19
+
20
+ export type AdobeAdapter = AdapterDescriptor<"adobe", AdobeOptions>;
21
+
22
+ export const adobeAdapterSchema = adapterDescriptorSchema(
23
+ "adobe",
24
+ adobeOptionsSchema
25
+ );
26
+
27
+ /**
28
+ * Adobe Analytics through a Launch property: Blume loads the environment's
29
+ * embed script, and the property's own rules decide what to track. Copy the
30
+ * URL from the environment's install instructions in Data Collection.
31
+ */
32
+ export const adobe = (options: AdobeOptions): AdobeAdapter => ({
33
+ kind: "adobe",
34
+ options,
35
+ requiredSecrets: [],
36
+ runtimeDeps: [],
37
+ });
38
+
39
+ /**
40
+ * The async embed tag, as Launch's install instructions render it. Pageviews
41
+ * on client-router navigations are the property's business: give it a rule on
42
+ * history changes (or `_satellite.track` from a `script()` adapter).
43
+ */
44
+ export const adobeHead = (options: AdobeOptions): HeadScript[] => [
45
+ { attributes: { async: true, src: options.url }, content: null },
46
+ ];
@@ -0,0 +1,79 @@
1
+ import { z } from "zod";
2
+
3
+ import type { AdapterDescriptor, JsonValue } from "../core/adapter.ts";
4
+ import { adapterDescriptorSchema } from "../core/adapter.ts";
5
+ import type { HeadScript } from "./head.ts";
6
+ import { inlineJson } from "./inline.ts";
7
+
8
+ /** The options {@link amplitude} maps itself. */
9
+ export interface AmplitudeNamedOptions {
10
+ /** Project API key. */
11
+ key: string;
12
+ }
13
+
14
+ /**
15
+ * Options for {@link amplitude}: the key plus any other Browser SDK
16
+ * `amplitude.init` option, forwarded verbatim (`serverZone`, `autocapture`,
17
+ * `defaultTracking`, …). JSON values only.
18
+ */
19
+ export type AmplitudeOptions = AmplitudeNamedOptions & {
20
+ [option: string]: JsonValue;
21
+ };
22
+
23
+ export const amplitudeOptionsSchema = z
24
+ .object({
25
+ key: z.string().min(1),
26
+ })
27
+ .catchall(z.json());
28
+
29
+ export type AmplitudeAdapter = AdapterDescriptor<"amplitude", AmplitudeOptions>;
30
+
31
+ export const amplitudeAdapterSchema = adapterDescriptorSchema(
32
+ "amplitude",
33
+ amplitudeOptionsSchema
34
+ );
35
+
36
+ /**
37
+ * Amplitude product analytics through the Browser SDK's script loader. The
38
+ * project API key is public — it's what every browser event carries.
39
+ */
40
+ export const amplitude = (options: AmplitudeOptions): AmplitudeAdapter => ({
41
+ kind: "amplitude",
42
+ options,
43
+ requiredSecrets: [],
44
+ runtimeDeps: [],
45
+ });
46
+
47
+ /** The script loader's CDN; the key picks the bundle. */
48
+ export const AMPLITUDE_SCRIPT_ORIGIN = "https://cdn.amplitude.com/script/";
49
+
50
+ /**
51
+ * The init options the dashboard snippet ships with. `autocapture` covers page
52
+ * views, sessions, and history changes, so client-router navigations count
53
+ * without any extra hook; a passthrough option overrides either.
54
+ */
55
+ export const AMPLITUDE_DEFAULT_INIT = {
56
+ autocapture: true,
57
+ fetchRemoteConfig: true,
58
+ };
59
+
60
+ /**
61
+ * The two tags from the dashboard's install snippet: the keyed SDK bundle
62
+ * (synchronous, so `window.amplitude` exists for the next tag) and the init
63
+ * call, with `key` mapped and everything else forwarded to `init` verbatim.
64
+ */
65
+ export const amplitudeHead = (options: AmplitudeOptions): HeadScript[] => {
66
+ const { key, ...init } = options;
67
+ return [
68
+ {
69
+ attributes: {
70
+ src: `${AMPLITUDE_SCRIPT_ORIGIN}${encodeURIComponent(key)}.js`,
71
+ },
72
+ content: null,
73
+ },
74
+ {
75
+ attributes: {},
76
+ content: `window.amplitude.init(${inlineJson(key)},${inlineJson({ ...AMPLITUDE_DEFAULT_INIT, ...init })});`,
77
+ },
78
+ ];
79
+ };
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+
3
+ import type { AdapterDescriptor } from "../core/adapter.ts";
4
+ import { adapterDescriptorSchema } from "../core/adapter.ts";
5
+ import type { HeadScript } from "./head.ts";
6
+ import { inlineJson } from "./inline.ts";
7
+
8
+ /** Options for {@link clarity}. */
9
+ export interface ClarityOptions {
10
+ /** Project ID, from the project's tracking code in the Clarity dashboard. */
11
+ id: string;
12
+ }
13
+
14
+ export const clarityOptionsSchema = z.strictObject({
15
+ id: z.string().min(1),
16
+ });
17
+
18
+ export type ClarityAdapter = AdapterDescriptor<"clarity", ClarityOptions>;
19
+
20
+ export const clarityAdapterSchema = adapterDescriptorSchema(
21
+ "clarity",
22
+ clarityOptionsSchema
23
+ );
24
+
25
+ /**
26
+ * Microsoft Clarity session recordings and heatmaps. The project ID is public;
27
+ * it only picks the project the tag reports to.
28
+ */
29
+ export const clarity = (options: ClarityOptions): ClarityAdapter => ({
30
+ kind: "clarity",
31
+ options,
32
+ requiredSecrets: [],
33
+ runtimeDeps: [],
34
+ });
35
+
36
+ /**
37
+ * The dashboard's tracking code: a `window.clarity` queue and the async tag
38
+ * load. Clarity follows history changes itself, so client-router navigations
39
+ * need no extra hook.
40
+ */
41
+ export const clarityHead = (options: ClarityOptions): HeadScript[] => [
42
+ {
43
+ attributes: {},
44
+ content: `(function(c,l,a,r,i,t,y){c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);})(window,document,"clarity","script",${inlineJson(encodeURIComponent(options.id))});`,
45
+ },
46
+ ];