blume 2.0.2 → 2.0.3

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 (293) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/dist/cli/{chunk-6k4ftwze.js → chunk-1d7ve1dm.js} +1 -1
  3. package/dist/cli/{chunk-zp79m0ts.js → chunk-2eytanqx.js} +2 -2
  4. package/dist/cli/{chunk-8g8ytmgx.js → chunk-2hsdwb9n.js} +19 -19
  5. package/dist/cli/{chunk-8g8ytmgx.js.map → chunk-2hsdwb9n.js.map} +1 -1
  6. package/dist/cli/{chunk-g698a744.js → chunk-2z928egk.js} +5 -5
  7. package/dist/cli/{chunk-ppzjqwx2.js → chunk-35d4wj9f.js} +17 -18
  8. package/dist/cli/{chunk-ppzjqwx2.js.map → chunk-35d4wj9f.js.map} +3 -3
  9. package/dist/cli/{chunk-mqc662a6.js → chunk-364znk6q.js} +2 -2
  10. package/dist/cli/{chunk-gs7r695n.js → chunk-3em5wd2y.js} +21 -8
  11. package/dist/cli/{chunk-gs7r695n.js.map → chunk-3em5wd2y.js.map} +3 -3
  12. package/dist/cli/{chunk-k7pj68a8.js → chunk-5f86nr5m.js} +15 -15
  13. package/dist/cli/{chunk-hr8ne106.js → chunk-5m5nmvyq.js} +68 -43
  14. package/dist/cli/chunk-5m5nmvyq.js.map +13 -0
  15. package/dist/cli/{chunk-91ws1n6j.js → chunk-5xvm6tfj.js} +14 -14
  16. package/dist/cli/{chunk-w4bxdvsa.js → chunk-6dsbexzp.js} +14 -14
  17. package/dist/cli/{chunk-00gs3wqs.js → chunk-8ktnccpt.js} +1 -1
  18. package/dist/cli/{chunk-j85scx15.js → chunk-9t7a85s3.js} +130 -44
  19. package/dist/cli/chunk-9t7a85s3.js.map +10 -0
  20. package/dist/cli/{chunk-bbnwccaz.js → chunk-a58773jm.js} +2 -2
  21. package/dist/cli/{chunk-nfcyttvj.js → chunk-acanzt5p.js} +9 -9
  22. package/dist/cli/{chunk-nfcyttvj.js.map → chunk-acanzt5p.js.map} +1 -1
  23. package/dist/cli/{chunk-wdrt2k2v.js → chunk-akbpwfxc.js} +90 -26
  24. package/dist/cli/chunk-akbpwfxc.js.map +10 -0
  25. package/dist/cli/{chunk-sqw4ekg1.js → chunk-b07cmahc.js} +2 -2
  26. package/dist/cli/{chunk-xh43dwgw.js → chunk-c8chx29p.js} +42 -29
  27. package/dist/cli/{chunk-xh43dwgw.js.map → chunk-c8chx29p.js.map} +9 -9
  28. package/dist/cli/{chunk-7mbqtmgb.js → chunk-crgn1q09.js} +21 -12
  29. package/dist/cli/chunk-crgn1q09.js.map +10 -0
  30. package/dist/cli/chunk-e04dxsz1.js +39 -0
  31. package/dist/cli/chunk-e04dxsz1.js.map +10 -0
  32. package/dist/cli/{chunk-4e9b9ra6.js → chunk-ey84smr6.js} +3 -3
  33. package/dist/cli/{chunk-d1v5rhy0.js → chunk-g4hq16wv.js} +13 -13
  34. package/dist/cli/{chunk-273ygyr4.js → chunk-ga0pf4aj.js} +7 -7
  35. package/dist/cli/{chunk-273ygyr4.js.map → chunk-ga0pf4aj.js.map} +3 -3
  36. package/dist/cli/{chunk-pbg5a4s3.js → chunk-hm3vjy5s.js} +64 -45
  37. package/dist/cli/chunk-hm3vjy5s.js.map +19 -0
  38. package/dist/cli/{chunk-5r8g91qn.js → chunk-j85vccga.js} +306 -107
  39. package/dist/cli/chunk-j85vccga.js.map +36 -0
  40. package/dist/cli/{chunk-n1yg3tj3.js → chunk-p3v96n38.js} +6 -6
  41. package/dist/cli/{chunk-n1yg3tj3.js.map → chunk-p3v96n38.js.map} +3 -3
  42. package/dist/cli/{chunk-7vtckvaw.js → chunk-p73c0m7w.js} +14 -14
  43. package/dist/cli/{chunk-7vtckvaw.js.map → chunk-p73c0m7w.js.map} +1 -1
  44. package/dist/cli/{chunk-qkb5a8sa.js → chunk-pehfxfta.js} +3 -3
  45. package/dist/cli/{chunk-v6ya5kcb.js → chunk-pv29h0wf.js} +1223 -978
  46. package/dist/cli/{chunk-v6ya5kcb.js.map → chunk-pv29h0wf.js.map} +47 -46
  47. package/dist/cli/{chunk-6dtt0zfn.js → chunk-q58y5e6a.js} +10 -10
  48. package/dist/cli/{chunk-6dtt0zfn.js.map → chunk-q58y5e6a.js.map} +3 -3
  49. package/dist/cli/{chunk-fsmrqk8a.js → chunk-r20tn01b.js} +1 -1
  50. package/dist/cli/{chunk-bfwp9vp6.js → chunk-r9rcc4w7.js} +7 -7
  51. package/dist/cli/{chunk-h7k3nq3v.js → chunk-tkacnehg.js} +2 -2
  52. package/dist/cli/{chunk-h2ez8dzb.js → chunk-tzmab476.js} +4 -4
  53. package/dist/cli/{chunk-3yce002v.js → chunk-vg9r4eb9.js} +6 -6
  54. package/dist/cli/{chunk-3yce002v.js.map → chunk-vg9r4eb9.js.map} +4 -4
  55. package/dist/cli/{chunk-hqp2ajnh.js → chunk-wrr3j9w9.js} +16 -17
  56. package/dist/cli/{chunk-hqp2ajnh.js.map → chunk-wrr3j9w9.js.map} +7 -7
  57. package/dist/cli/{chunk-ddndchfr.js → chunk-yfyb25rh.js} +38 -26
  58. package/dist/cli/chunk-yfyb25rh.js.map +14 -0
  59. package/dist/cli/index.js +20 -18
  60. package/dist/cli/index.js.map +3 -3
  61. package/dist/types/ai/link-headers.d.ts +8 -1
  62. package/dist/types/ai/openapi-components.d.ts +5 -2
  63. package/dist/types/ai/relative-links.d.ts +9 -7
  64. package/dist/types/ai/skills.d.ts +4 -1
  65. package/dist/types/ai/tar.d.ts +1 -3
  66. package/dist/types/analytics/index.d.ts +2 -0
  67. package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
  68. package/dist/types/analytics/schema.d.ts +14 -0
  69. package/dist/types/astro/integration.d.ts +3 -2
  70. package/dist/types/core/base-path.d.ts +21 -7
  71. package/dist/types/core/config-input.d.ts +9 -7
  72. package/dist/types/core/directive-diagnostics.d.ts +12 -0
  73. package/dist/types/core/heading-markers.d.ts +5 -7
  74. package/dist/types/core/i18n.d.ts +2 -0
  75. package/dist/types/core/last-modified.d.ts +10 -0
  76. package/dist/types/core/meta.d.ts +8 -0
  77. package/dist/types/core/schema.d.ts +7 -0
  78. package/dist/types/core/sources/lower.d.ts +29 -16
  79. package/dist/types/core/sources/normalize.d.ts +13 -1
  80. package/dist/types/core/sources/watch.d.ts +12 -5
  81. package/dist/types/core/standard-schema.d.ts +5 -0
  82. package/dist/types/deploy/artifacts.d.ts +6 -4
  83. package/dist/types/deploy/headers.d.ts +5 -0
  84. package/dist/types/deploy/platforms/types.d.ts +8 -0
  85. package/dist/types/deploy/redirects.d.ts +24 -13
  86. package/dist/types/markdown/directives.d.ts +62 -0
  87. package/dist/types/markdown/features.d.ts +21 -0
  88. package/dist/types/markdown/mdast.d.ts +63 -0
  89. package/dist/types/openapi/asyncapi.d.ts +4 -2
  90. package/docs/02-deployment.mdx +4 -2
  91. package/docs/08-faq.mdx +1 -1
  92. package/docs/advanced/custom-pages.mdx +3 -3
  93. package/docs/cli/audit.mdx +17 -1
  94. package/docs/cli/evals.mdx +3 -3
  95. package/docs/cli/translate.mdx +3 -3
  96. package/docs/cli/version.mdx +1 -1
  97. package/docs/configuration/analytics.mdx +20 -1
  98. package/docs/configuration/customization.mdx +2 -0
  99. package/docs/configuration/search.mdx +1 -1
  100. package/docs/content/components.mdx +1 -1
  101. package/docs/content/frontmatter.mdx +1 -1
  102. package/docs/content/i18n.mdx +2 -0
  103. package/docs/content/index.mdx +4 -2
  104. package/docs/content/islands.mdx +1 -1
  105. package/docs/content/meta.mdx +3 -1
  106. package/docs/content/sources.mdx +1 -5
  107. package/docs/content/syntax.mdx +14 -0
  108. package/docs/content/versioning.mdx +1 -1
  109. package/docs/discoverability/agent-discovery.mdx +1 -1
  110. package/docs/discoverability/index.mdx +2 -1
  111. package/docs/discoverability/markdown.mdx +2 -2
  112. package/docs/discoverability/open-graph.mdx +5 -3
  113. package/docs/discoverability/rss.mdx +1 -1
  114. package/docs/references/asyncapi.mdx +1 -1
  115. package/docs/references/graphql.mdx +1 -1
  116. package/docs/references/openapi.mdx +5 -3
  117. package/package.json +1 -1
  118. package/skills/blume-migrate/references/fumadocs.md +1 -1
  119. package/skills/blume-migrate/references/nextra.md +1 -1
  120. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +7 -2
  121. package/src/ai/agent-readability.ts +2 -2
  122. package/src/ai/ai-catalog.ts +6 -2
  123. package/src/ai/api/handlers.ts +2 -2
  124. package/src/ai/api/spec.ts +2 -2
  125. package/src/ai/api-catalog.ts +6 -2
  126. package/src/ai/changelog-markdown.ts +2 -2
  127. package/src/ai/link-headers.ts +14 -5
  128. package/src/ai/llms.ts +18 -7
  129. package/src/ai/mcp/discovery.ts +2 -2
  130. package/src/ai/mcp/query.ts +2 -2
  131. package/src/ai/mcp/server.ts +2 -2
  132. package/src/ai/openapi-components.ts +22 -6
  133. package/src/ai/relative-links.ts +42 -26
  134. package/src/ai/serializers.ts +2 -1
  135. package/src/ai/skills.ts +14 -1
  136. package/src/ai/tar.ts +139 -12
  137. package/src/analytics/head.ts +4 -0
  138. package/src/analytics/index.ts +5 -0
  139. package/src/analytics/one-dollar-stats.ts +86 -0
  140. package/src/analytics/schema.ts +2 -0
  141. package/src/astro/generate.ts +1 -1
  142. package/src/astro/include-hmr.ts +31 -12
  143. package/src/astro/include-refresh.ts +19 -8
  144. package/src/astro/integration.ts +108 -14
  145. package/src/astro/runtime-modules.ts +28 -13
  146. package/src/astro/templates.ts +81 -37
  147. package/src/audit/checks/links.ts +8 -1
  148. package/src/audit/graph.ts +3 -1
  149. package/src/audit/run.ts +12 -9
  150. package/src/audit/snapshot.ts +5 -0
  151. package/src/cli/args.ts +32 -0
  152. package/src/cli/commands/audit.ts +4 -1
  153. package/src/cli/commands/doctor.ts +3 -1
  154. package/src/cli/commands/eval.ts +19 -11
  155. package/src/cli/commands/translate.ts +9 -12
  156. package/src/cli/commands/validate.ts +3 -1
  157. package/src/cli/dev-lock.ts +157 -37
  158. package/src/cli/report-format.ts +11 -6
  159. package/src/components/colors.ts +19 -0
  160. package/src/components/content/Badge.astro +5 -3
  161. package/src/components/content/Component.astro +2 -2
  162. package/src/components/content/Tab.astro +0 -1
  163. package/src/components/content/Tabs.astro +4 -0
  164. package/src/components/content/badge-color.ts +5 -2
  165. package/src/components/content/base-href.ts +13 -36
  166. package/src/components/islands/assistant.tsx +21 -4
  167. package/src/components/islands/base-path.ts +47 -10
  168. package/src/components/islands/hooks.ts +35 -19
  169. package/src/components/islands/webmcp.ts +4 -2
  170. package/src/components/layout/Breadcrumbs.astro +5 -2
  171. package/src/components/layout/DiscoveryLinks.astro +9 -5
  172. package/src/components/layout/Header.astro +2 -2
  173. package/src/components/layout/LanguageSwitcher.astro +2 -2
  174. package/src/components/layout/NavSelector.astro +2 -2
  175. package/src/components/layout/NavTabMenu.astro +3 -3
  176. package/src/components/layout/NavTree.astro +16 -6
  177. package/src/components/layout/PageActions.astro +4 -3
  178. package/src/components/layout/PageLayout.astro +7 -6
  179. package/src/components/layout/Pagination.astro +3 -3
  180. package/src/components/layout/RootLayout.astro +5 -5
  181. package/src/components/layout/Search.astro +33 -13
  182. package/src/components/layout/VersionBanner.astro +2 -2
  183. package/src/components/layout/analytics-client.ts +12 -0
  184. package/src/components/layout/toc-active.ts +41 -0
  185. package/src/components/layout/toc-element.ts +8 -14
  186. package/src/components/openapi/ApiTagOperations.astro +2 -2
  187. package/src/components/openapi/AsyncApiOperation.astro +7 -4
  188. package/src/components/openapi/GraphqlChip.astro +2 -2
  189. package/src/components/openapi/Operation.astro +2 -0
  190. package/src/components/openapi/Playground.astro +4 -4
  191. package/src/components/openapi/RequestPanel.astro +5 -2
  192. package/src/components/openapi/SchemaTable.astro +7 -0
  193. package/src/components/openapi/async.ts +38 -6
  194. package/src/components/openapi/helpers.ts +19 -9
  195. package/src/components/openapi/message-composer.ts +6 -1
  196. package/src/components/openapi/message.ts +17 -2
  197. package/src/components/openapi/operation-model.ts +81 -11
  198. package/src/components/openapi/panel.ts +4 -2
  199. package/src/components/openapi/param-style.ts +181 -0
  200. package/src/components/openapi/playground-client.ts +73 -16
  201. package/src/components/openapi/request.ts +190 -26
  202. package/src/components/openapi/schema-tree.ts +30 -24
  203. package/src/components/openapi/snippets.ts +85 -6
  204. package/src/components/openapi/ws-client.ts +18 -2
  205. package/src/core/base-path.ts +62 -16
  206. package/src/core/config-input.ts +9 -7
  207. package/src/core/diagnostics.ts +2 -0
  208. package/src/core/directive-diagnostics.ts +99 -0
  209. package/src/core/frontmatter.ts +21 -18
  210. package/src/core/heading-markers.ts +5 -18
  211. package/src/core/i18n.ts +31 -3
  212. package/src/core/last-modified.ts +25 -3
  213. package/src/core/locale-links.ts +5 -1
  214. package/src/core/meta.ts +33 -19
  215. package/src/core/navigation.ts +28 -8
  216. package/src/core/project-graph.ts +27 -5
  217. package/src/core/schema.ts +24 -4
  218. package/src/core/sources/contentful-rich-text.ts +27 -20
  219. package/src/core/sources/filesystem.ts +20 -2
  220. package/src/core/sources/github-releases.ts +25 -6
  221. package/src/core/sources/lexical.ts +23 -18
  222. package/src/core/sources/lower.ts +201 -34
  223. package/src/core/sources/mdx-remote.ts +51 -16
  224. package/src/core/sources/normalize.ts +325 -90
  225. package/src/core/sources/notion.ts +52 -25
  226. package/src/core/sources/obsidian.ts +23 -6
  227. package/src/core/sources/portable-text.ts +38 -21
  228. package/src/core/sources/strapi-blocks.ts +20 -16
  229. package/src/core/sources/watch.ts +20 -7
  230. package/src/core/standard-schema.ts +10 -6
  231. package/src/core/version-cut.ts +52 -15
  232. package/src/deploy/artifacts.ts +27 -6
  233. package/src/deploy/cloudflare-negotiation.ts +4 -12
  234. package/src/deploy/headers.ts +8 -4
  235. package/src/deploy/node-headers.ts +1 -1
  236. package/src/deploy/platforms/cloudflare.ts +12 -3
  237. package/src/deploy/platforms/netlify.ts +1 -0
  238. package/src/deploy/platforms/node.ts +1 -0
  239. package/src/deploy/platforms/static.ts +1 -0
  240. package/src/deploy/platforms/types.ts +8 -0
  241. package/src/deploy/platforms/vercel.ts +1 -0
  242. package/src/deploy/redirects.ts +54 -18
  243. package/src/deploy/robots.ts +2 -2
  244. package/src/deploy/rss.ts +4 -3
  245. package/src/deploy/sitemap.ts +7 -5
  246. package/src/markdown/base-links.ts +34 -36
  247. package/src/markdown/directives.ts +242 -36
  248. package/src/markdown/features.ts +17 -0
  249. package/src/markdown/index.ts +7 -6
  250. package/src/markdown/mdast.ts +5 -2
  251. package/src/markdown/relative-links.ts +12 -4
  252. package/src/og/card.ts +129 -5
  253. package/src/og/derive.ts +41 -31
  254. package/src/og/index.ts +1 -0
  255. package/src/openapi/asyncapi.ts +4 -2
  256. package/src/openapi/model.ts +22 -14
  257. package/src/openapi/proxy.ts +63 -10
  258. package/src/openapi/render-mdx.ts +41 -2
  259. package/src/registry/eject.ts +181 -24
  260. package/src/search/adapters/version-scope.ts +30 -0
  261. package/src/search/documents.ts +67 -26
  262. package/src/search/popular.ts +2 -1
  263. package/src/seo/jsonld.ts +7 -3
  264. package/src/translate/meta.ts +68 -24
  265. package/src/translate/run.ts +3 -3
  266. package/src/translate/validate.ts +4 -1
  267. package/src/translate/work-list.ts +56 -17
  268. package/dist/cli/chunk-5r8g91qn.js.map +0 -34
  269. package/dist/cli/chunk-7mbqtmgb.js.map +0 -10
  270. package/dist/cli/chunk-ddndchfr.js.map +0 -14
  271. package/dist/cli/chunk-esh98wmb.js +0 -23
  272. package/dist/cli/chunk-esh98wmb.js.map +0 -10
  273. package/dist/cli/chunk-hr8ne106.js.map +0 -13
  274. package/dist/cli/chunk-j85scx15.js.map +0 -10
  275. package/dist/cli/chunk-pbg5a4s3.js.map +0 -19
  276. package/dist/cli/chunk-wdrt2k2v.js.map +0 -10
  277. /package/dist/cli/{chunk-6k4ftwze.js.map → chunk-1d7ve1dm.js.map} +0 -0
  278. /package/dist/cli/{chunk-zp79m0ts.js.map → chunk-2eytanqx.js.map} +0 -0
  279. /package/dist/cli/{chunk-g698a744.js.map → chunk-2z928egk.js.map} +0 -0
  280. /package/dist/cli/{chunk-mqc662a6.js.map → chunk-364znk6q.js.map} +0 -0
  281. /package/dist/cli/{chunk-k7pj68a8.js.map → chunk-5f86nr5m.js.map} +0 -0
  282. /package/dist/cli/{chunk-91ws1n6j.js.map → chunk-5xvm6tfj.js.map} +0 -0
  283. /package/dist/cli/{chunk-w4bxdvsa.js.map → chunk-6dsbexzp.js.map} +0 -0
  284. /package/dist/cli/{chunk-00gs3wqs.js.map → chunk-8ktnccpt.js.map} +0 -0
  285. /package/dist/cli/{chunk-bbnwccaz.js.map → chunk-a58773jm.js.map} +0 -0
  286. /package/dist/cli/{chunk-sqw4ekg1.js.map → chunk-b07cmahc.js.map} +0 -0
  287. /package/dist/cli/{chunk-4e9b9ra6.js.map → chunk-ey84smr6.js.map} +0 -0
  288. /package/dist/cli/{chunk-d1v5rhy0.js.map → chunk-g4hq16wv.js.map} +0 -0
  289. /package/dist/cli/{chunk-qkb5a8sa.js.map → chunk-pehfxfta.js.map} +0 -0
  290. /package/dist/cli/{chunk-fsmrqk8a.js.map → chunk-r20tn01b.js.map} +0 -0
  291. /package/dist/cli/{chunk-bfwp9vp6.js.map → chunk-r9rcc4w7.js.map} +0 -0
  292. /package/dist/cli/{chunk-h7k3nq3v.js.map → chunk-tkacnehg.js.map} +0 -0
  293. /package/dist/cli/{chunk-h2ez8dzb.js.map → chunk-tzmab476.js.map} +0 -0
@@ -37,11 +37,16 @@ var normalizeRoute = (input) => {
37
37
  return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
38
38
  };
39
39
  var isInternalPath = (target) => target.startsWith("/") && !target.startsWith("//");
40
+ var pathPart = (target) => {
41
+ const at = target.search(/[#?]/u);
42
+ return at === -1 ? target : target.slice(0, at);
43
+ };
44
+ var isUnderBase = (base, route) => {
45
+ const path = pathPart(route);
46
+ return path === base || path.startsWith(`${base}/`);
47
+ };
40
48
  var withBasePath = (basePath, route) => {
41
- if (!basePath || !isInternalPath(route)) {
42
- return route;
43
- }
44
- if (route === basePath || route.startsWith(`${basePath}/`)) {
49
+ if (!basePath || !isInternalPath(route) || isUnderBase(basePath, route)) {
45
50
  return route;
46
51
  }
47
52
  return route === "/" ? basePath : `${basePath}${route}`;
@@ -54,11 +59,19 @@ var mountBasePath = (basePath, route) => {
54
59
  };
55
60
  var withComposedBasePath = (deployBase, basePath, route) => {
56
61
  const composed = `${deployBase}${basePath}`;
57
- if (composed && isInternalPath(route) && (route === composed || route.startsWith(`${composed}/`))) {
62
+ if (composed && isInternalPath(route) && isUnderBase(composed, route)) {
58
63
  return route;
59
64
  }
60
65
  return withBasePath(deployBase, withBasePath(basePath, route));
61
66
  };
67
+ var DOTTED_PATH = /\.[a-z0-9]+$/iu;
68
+ var withAuthoredBasePath = (deployBase, basePath, target, servesPage) => {
69
+ if (!isInternalPath(target)) {
70
+ return target;
71
+ }
72
+ const path = pathPart(target);
73
+ return DOTTED_PATH.test(path) && !servesPage(withBasePath(basePath, path)) ? withBasePath(deployBase, target) : withComposedBasePath(deployBase, basePath, target);
74
+ };
62
75
  var stripBasePath = (basePath, route) => {
63
76
  if (!basePath) {
64
77
  return route;
@@ -106,7 +119,7 @@ var MCP_TOOLS = [
106
119
  }
107
120
  ];
108
121
 
109
- export { trimEnd, trimChar, normalizeBasePath, normalizePath, normalizeRoute, isInternalPath, withBasePath, mountBasePath, withComposedBasePath, stripBasePath, siteRoot, absoluteUrl2, MCP_TOOLS };
122
+ export { trimEnd, trimChar, normalizeBasePath, normalizePath, normalizeRoute, isInternalPath, withBasePath, mountBasePath, withComposedBasePath, withAuthoredBasePath, stripBasePath, siteRoot, absoluteUrl2, MCP_TOOLS };
110
123
 
111
- //# debugId=1822C67532B8BE8464756E2164756E21
112
- //# sourceMappingURL=chunk-gs7r695n.js.map
124
+ //# debugId=23E38A1AF0C2C43564756E2164756E21
125
+ //# sourceMappingURL=chunk-3em5wd2y.js.map
@@ -3,11 +3,11 @@
3
3
  "sources": ["../src/core/trim.ts", "../src/core/base-path.ts", "../src/core/site-url.ts", "../src/ai/mcp/tools.ts"],
4
4
  "sourcesContent": [
5
5
  "/**\n * Single-character trimming, done without regular expressions.\n *\n * The obvious spellings — `/^\\/+/`, `/\\/+$/`, `/^\\/+|\\/+$/g` — take quadratic\n * time on a run of the trimmed character, because a failed match at one start\n * position tells the engine nothing about the next one. Every caller here trims\n * a value that comes from outside Blume (a configured route, a spec URL, a site\n * origin), so the slow path is reachable from user input rather than only from\n * our own literals. These loops are linear and allocation-free.\n */\n\n/** Drop every leading `char` (`\"///a\"` -> `\"a\"` for `\"/\"`). */\nexport const trimStart = (text: string, char: string): string => {\n let start = 0;\n while (start < text.length && text[start] === char) {\n start += 1;\n }\n return text.slice(start);\n};\n\n/** Drop every trailing `char` (`\"a///\"` -> `\"a\"` for `\"/\"`). */\nexport const trimEnd = (text: string, char: string): string => {\n let end = text.length;\n while (end > 0 && text[end - 1] === char) {\n end -= 1;\n }\n return text.slice(0, end);\n};\n\n/** Drop every leading *and* trailing `char` (`\"///a///\"` -> `\"a\"`). */\nexport const trimChar = (text: string, char: string): string =>\n trimEnd(trimStart(text, char), char);\n",
6
- "/**\n * The site-wide `basePath` — a mount point that prepends a segment to every\n * generated route (`/docs/getting-started`) while staying invisible to the\n * navigation tree (see `core/navigation.ts`, which builds groups from a page's\n * base-less `navPath` and takes URLs from its based `route`). This is distinct\n * from a per-source `prefix` (a namespace that *does* create a sidebar group)\n * and from `deployment.base` (Astro's host-subdirectory base); the two compose,\n * stacking as `{deployment.base}/{basePath}/page`.\n *\n * These helpers run server-side (config, route construction, the link checker,\n * redirects, the markdown link plugin). The client-side counterpart lives in\n * `components/islands/base-path.ts` and serves `deployment.base` via `BASE_URL`.\n */\n\nimport { trimEnd } from \"./trim.ts\";\n\n/**\n * Canonicalize a configured base path to either `\"\"` (none) or `/seg[/seg…]`\n * (leading slash, no trailing slash, collapsed inner slashes). A blank value or\n * bare `/` normalizes to `\"\"`, so an unset/`\"/\"` base is a clean no-op.\n */\nexport const normalizeBasePath = (input?: string): string => {\n if (!input) {\n return \"\";\n }\n // Splitting on \"/\" and dropping the empty parts trims the edges and collapses\n // inner runs in one linear pass; the regex spellings of both are quadratic on\n // a long run of slashes (see `core/trim.ts`).\n const trimmed = input.trim().split(\"/\").filter(Boolean).join(\"/\");\n return trimmed === \"\" ? \"\" : `/${trimmed}`;\n};\n\n/**\n * Normalize a served path for comparison: drop the trailing slash (Astro serves\n * `/docs` and `/docs/` as the same page) and collapse an empty path to `/`.\n */\nexport const normalizePath = (path: string): string => {\n const trimmed = trimEnd(path, \"/\");\n return trimmed === \"\" ? \"/\" : trimmed;\n};\n\n/**\n * Canonicalize a route-ish string (a configured route, a page path, an agent-\n * supplied route) to `/` or `/seg[/seg…]`: trimmed, exactly one leading slash,\n * no trailing slash. The shared spelling of what openapi/references,\n * ai/ask-context, and ai/mcp/server each hand-rolled with slightly different\n * regexes.\n */\nexport const normalizeRoute = (input: string): string => {\n const trimmed = trimEnd(input.trim(), \"/\");\n if (trimmed === \"\") {\n return \"/\";\n }\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n};\n\n/**\n * Whether a link target is a root-relative internal path (`/x`) — the only\n * shape a base path applies to. Protocol-relative (`//host`), absolute URLs,\n * other schemes (`mailto:`), fragments (`#x`), and relative paths are excluded.\n */\nexport const isInternalPath = (target: string): boolean =>\n target.startsWith(\"/\") && !target.startsWith(\"//\");\n\n/**\n * Whether a rendered link should open in a new tab: an absolute http(s) URL or\n * a protocol-relative one (`//host/path`). Other schemes (`mailto:`, `tel:`)\n * also leave the site but hand off to another application, where a `_blank`\n * target only opens an empty tab beside it. The one predicate behind every\n * chrome link, so a header action and a sidebar featured link treat the same\n * href alike.\n */\nexport const isExternalUrl = (target: string): boolean =>\n /^https?:\\/\\//iu.test(target) || target.startsWith(\"//\");\n\n/**\n * Idempotently prepend `basePath` to a root-relative route. A route already\n * equal to or nested under the base is returned unchanged, so authors who write\n * the base by hand (`/docs/x`) aren't double-prefixed to `/docs/docs/x`.\n */\nexport const withBasePath = (basePath: string, route: string): string => {\n if (!basePath || !isInternalPath(route)) {\n return route;\n }\n if (route === basePath || route.startsWith(`${basePath}/`)) {\n return route;\n }\n return route === \"/\" ? basePath : `${basePath}${route}`;\n};\n\n/**\n * Mount a route Blume generates from content under `basePath`,\n * unconditionally. {@link withBasePath} leaves a route that already starts\n * with the base alone, which is right for a link an author based by hand but\n * wrong for a content route: with `basePath: \"/docs\"`, `docs/guide.md` routes\n * to `/docs/guide` before the base and publishes at `/docs/docs/guide`, not on\n * top of the root `guide.md`.\n */\nexport const mountBasePath = (basePath: string, route: string): string => {\n if (!basePath) {\n return route;\n }\n return route === \"/\" ? basePath : `${basePath}${route}`;\n};\n\n/**\n * {@link withBasePath} for the composed `deployment.base` + `basePath` stack\n * (`/base` + `/docs` serves pages at `/base/docs/x`). The hand-written-base\n * promise applies per layer: authors write `basePath` by hand (see\n * `markdown/base-links.ts`), so a `/docs/x` link gains only the deployment base\n * (`/base/docs/x`) rather than being double-prefixed to `/base/docs/docs/x`,\n * and a route already under the full composite is returned unchanged.\n */\nexport const withComposedBasePath = (\n deployBase: string,\n basePath: string,\n route: string\n): string => {\n const composed = `${deployBase}${basePath}`;\n if (\n composed &&\n isInternalPath(route) &&\n (route === composed || route.startsWith(`${composed}/`))\n ) {\n return route;\n }\n return withBasePath(deployBase, withBasePath(basePath, route));\n};\n\n/**\n * Remove `basePath` from the front of a route (`/docs/guide` -> `/guide`,\n * `/docs` -> `/`). A route not under the base is returned unchanged. Inverse of\n * {@link withBasePath}; used to resolve public assets, which live at the site\n * root regardless of the base.\n */\nexport const stripBasePath = (basePath: string, route: string): string => {\n if (!basePath) {\n return route;\n }\n if (route === basePath) {\n return \"/\";\n }\n return route.startsWith(`${basePath}/`)\n ? route.slice(basePath.length)\n : route;\n};\n",
6
+ "/**\n * The site-wide `basePath` — a mount point that prepends a segment to every\n * generated route (`/docs/getting-started`) while staying invisible to the\n * navigation tree (see `core/navigation.ts`, which builds groups from a page's\n * base-less `navPath` and takes URLs from its based `route`). This is distinct\n * from a per-source `prefix` (a namespace that *does* create a sidebar group)\n * and from `deployment.base` (Astro's host-subdirectory base); the two compose,\n * stacking as `{deployment.base}/{basePath}/page`.\n *\n * These helpers run server-side (config, route construction, the link checker,\n * redirects, the markdown link plugin). The client-side counterpart lives in\n * `components/islands/base-path.ts` and serves `deployment.base` via `BASE_URL`.\n */\n\nimport { trimEnd } from \"./trim.ts\";\n\n/**\n * Canonicalize a configured base path to either `\"\"` (none) or `/seg[/seg…]`\n * (leading slash, no trailing slash, collapsed inner slashes). A blank value or\n * bare `/` normalizes to `\"\"`, so an unset/`\"/\"` base is a clean no-op.\n */\nexport const normalizeBasePath = (input?: string): string => {\n if (!input) {\n return \"\";\n }\n // Splitting on \"/\" and dropping the empty parts trims the edges and collapses\n // inner runs in one linear pass; the regex spellings of both are quadratic on\n // a long run of slashes (see `core/trim.ts`).\n const trimmed = input.trim().split(\"/\").filter(Boolean).join(\"/\");\n return trimmed === \"\" ? \"\" : `/${trimmed}`;\n};\n\n/**\n * Normalize a served path for comparison: drop the trailing slash (Astro serves\n * `/docs` and `/docs/` as the same page) and collapse an empty path to `/`.\n */\nexport const normalizePath = (path: string): string => {\n const trimmed = trimEnd(path, \"/\");\n return trimmed === \"\" ? \"/\" : trimmed;\n};\n\n/**\n * Canonicalize a route-ish string (a configured route, a page path, an agent-\n * supplied route) to `/` or `/seg[/seg…]`: trimmed, exactly one leading slash,\n * no trailing slash. The shared spelling of what openapi/references,\n * ai/ask-context, and ai/mcp/server each hand-rolled with slightly different\n * regexes.\n */\nexport const normalizeRoute = (input: string): string => {\n const trimmed = trimEnd(input.trim(), \"/\");\n if (trimmed === \"\") {\n return \"/\";\n }\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n};\n\n/**\n * Whether a link target is a root-relative internal path (`/x`) — the only\n * shape a base path applies to. Protocol-relative (`//host`), absolute URLs,\n * other schemes (`mailto:`), fragments (`#x`), and relative paths are excluded.\n */\nexport const isInternalPath = (target: string): boolean =>\n target.startsWith(\"/\") && !target.startsWith(\"//\");\n\n/**\n * Whether a rendered link should open in a new tab: an absolute http(s) URL or\n * a protocol-relative one (`//host/path`). Other schemes (`mailto:`, `tel:`)\n * also leave the site but hand off to another application, where a `_blank`\n * target only opens an empty tab beside it. The one predicate behind every\n * chrome link, so a header action and a sidebar featured link treat the same\n * href alike.\n */\nexport const isExternalUrl = (target: string): boolean =>\n /^https?:\\/\\//iu.test(target) || target.startsWith(\"//\");\n\n/**\n * The path part of a root-relative target, before any `?query` or `#fragment`\n * (`/docs#install` -> `/docs`).\n */\nconst pathPart = (target: string): string => {\n const at = target.search(/[#?]/u);\n return at === -1 ? target : target.slice(0, at);\n};\n\n/**\n * Whether `route`'s path already equals or sits under `base`. Only the path\n * part is compared, so a fragment or query (`/docs#install`) doesn't hide a\n * base written by hand.\n */\nconst isUnderBase = (base: string, route: string): boolean => {\n const path = pathPart(route);\n return path === base || path.startsWith(`${base}/`);\n};\n\n/**\n * Idempotently prepend `basePath` to a root-relative route. A route already\n * equal to or nested under the base is returned unchanged, so authors who write\n * the base by hand (`/docs/x`, `/docs#install`) aren't double-prefixed to\n * `/docs/docs/x`.\n */\nexport const withBasePath = (basePath: string, route: string): string => {\n if (!basePath || !isInternalPath(route) || isUnderBase(basePath, route)) {\n return route;\n }\n return route === \"/\" ? basePath : `${basePath}${route}`;\n};\n\n/**\n * Mount a route Blume generates under a base, unconditionally: `basePath` for\n * a content route, `deployment.base` for any generated URL (a sitemap entry,\n * a feed item). {@link withBasePath} leaves a route that already starts with\n * the base alone, which is right for a link an author based by hand but wrong\n * for a generated route: with `basePath: \"/docs\"`, `docs/guide.md` routes to\n * `/docs/guide` before the base and publishes at `/docs/docs/guide`, not on\n * top of the root `guide.md` — and likewise under `deployment.base: \"/docs\"`.\n */\nexport const mountBasePath = (basePath: string, route: string): string => {\n if (!basePath) {\n return route;\n }\n return route === \"/\" ? basePath : `${basePath}${route}`;\n};\n\n/**\n * {@link withBasePath} for the composed `deployment.base` + `basePath` stack\n * (`/base` + `/docs` serves pages at `/base/docs/x`). The hand-written-base\n * promise applies per layer: authors write `basePath` by hand (see\n * `markdown/base-links.ts`), so a `/docs/x` link gains only the deployment base\n * (`/base/docs/x`) rather than being double-prefixed to `/base/docs/docs/x`,\n * and a route already under the full composite is returned unchanged.\n */\nexport const withComposedBasePath = (\n deployBase: string,\n basePath: string,\n route: string\n): string => {\n const composed = `${deployBase}${basePath}`;\n if (composed && isInternalPath(route) && isUnderBase(composed, route)) {\n return route;\n }\n return withBasePath(deployBase, withBasePath(basePath, route));\n};\n\n/**\n * A path whose final segment carries a file extension (`/spec.pdf`,\n * `/logo.svg`) — a public asset, unless a page is served there.\n */\nconst DOTTED_PATH = /\\.[a-z0-9]+$/iu;\n\n/**\n * Base a root-relative link an author wrote as if mounted at root — a content\n * link (`markdown/base-links.ts`, `components/content/base-href.ts`) or a\n * redirect target (`deploy/redirects.ts`) — by what it names. A page gains the\n * composed stack ({@link withComposedBasePath}). A public asset — a path whose\n * final segment carries a file extension, with no page served there (a dotted\n * route like `/releases/v1.2` is still a page) — gains the deployment base\n * alone: Astro serves `public/` under `deployment.base`, but never under\n * `basePath`. `servesPage` answers whether a page is served at a\n * `basePath`-prefixed, fragment-less path. Other targets pass through.\n */\nexport const withAuthoredBasePath = (\n deployBase: string,\n basePath: string,\n target: string,\n servesPage: (route: string) => boolean\n): string => {\n if (!isInternalPath(target)) {\n return target;\n }\n const path = pathPart(target);\n return DOTTED_PATH.test(path) && !servesPage(withBasePath(basePath, path))\n ? withBasePath(deployBase, target)\n : withComposedBasePath(deployBase, basePath, target);\n};\n\n/**\n * Remove `basePath` from the front of a route (`/docs/guide` -> `/guide`,\n * `/docs` -> `/`). A route not under the base is returned unchanged. Inverse of\n * {@link withBasePath}; used to resolve public assets, which live at the site\n * root regardless of the base.\n */\nexport const stripBasePath = (basePath: string, route: string): string => {\n if (!basePath) {\n return route;\n }\n if (route === basePath) {\n return \"/\";\n }\n return route.startsWith(`${basePath}/`)\n ? route.slice(basePath.length)\n : route;\n};\n",
7
7
  "import { joinURL } from \"ufo\";\n\nimport { trimEnd } from \"./trim.ts\";\n\n/**\n * Absolute-URL building for the configured `deployment.site`, shared by every\n * emitter that prints site URLs (sitemap, RSS, robots, llms.txt, the MCP and\n * agent-discovery documents). One implementation replaces eight per-file\n * copies that had drifted across three different trailing-slash treatments.\n *\n * Deliberately not `new URL(path, site)`: a root-absolute path would drop the\n * base path of a subpath deployment (`acme.com/docs`). ufo's `joinURL` joins\n * without that footgun; the site is first trimmed with the ReDoS-safe\n * `trimEnd` loop so even a malformed `site` with piled-up trailing slashes\n * joins cleanly.\n */\n\n/** The configured site with any trailing slashes dropped. */\nexport const siteRoot = (site: string): string => trimEnd(site, \"/\");\n\n/** `site` + root-absolute `path` (already carrying any deployment base). */\nexport const absoluteUrl = (site: string, path: string): string => {\n const root = siteRoot(site);\n // joinURL folds a lone \"/\" away entirely; the homepage keeps its slash\n // (`https://example.com/`), matching what every emitter always printed.\n return path === \"/\" ? `${root}/` : joinURL(root, path);\n};\n",
8
8
  "/**\n * Static metadata for the MCP tools Blume exposes. Shared by the server (which\n * pairs each entry with a Zod input schema and handler) and the `.well-known`\n * discovery documents, so tool names and descriptions never drift between the\n * live server and its advertised capabilities.\n */\n\n/** A read-only, non-mutating tool hint set (every Blume tool is read-only). */\nconst READ_ONLY = { openWorldHint: false, readOnlyHint: true } as const;\n\nexport interface McpToolMeta {\n annotations: { openWorldHint: boolean; readOnlyHint: boolean };\n description: string;\n name: string;\n title: string;\n}\n\nexport const MCP_TOOLS: McpToolMeta[] = [\n {\n annotations: READ_ONLY,\n description:\n 'Full-text search across the documentation. Returns matching pages with their title, route, content type, and a short excerpt; pass `contentTypes` to search only pages of certain types (e.g. `rfc`, `changelog`), `filters` to require facet values the site declares per type (e.g. `{\"status\": \"enforced\"}`), and `locale` to search one language. On a versioned site results default to the current docs — pass `version` to search an archived version (e.g. `\"v1.0\"`) or `\"all\"` for every version. Use this first to discover relevant pages, then `get_page` to read one in full.',\n name: \"search_docs\",\n title: \"Search documentation\",\n },\n {\n annotations: READ_ONLY,\n description:\n \"Fetch a single documentation page as agent-optimized Markdown (frontmatter included, components downleveled to plain Markdown). Pass a route from `search_docs` or `list_pages`, e.g. `/guides/install`.\",\n name: \"get_page\",\n title: \"Get page Markdown\",\n },\n {\n annotations: READ_ONLY,\n description:\n 'List every documentation page with its route, title, description, content type, and any declared facet values; pass `contentTypes`, `filters`, and/or `locale` to narrow the list. On a versioned site the list defaults to the current docs — pass `version` for an archived version or `\"all\"`. Useful for enumerating the docs, discovering the types and facets in use, or finding a page when search is too narrow.',\n name: \"list_pages\",\n title: \"List pages\",\n },\n {\n annotations: READ_ONLY,\n description:\n \"Return the documentation navigation tree (header tabs and the sidebar hierarchy), reflecting how the docs are organized for readers. Pass `locale` for a language's tree and, on a versioned site, `version` for an archived snapshot's tree.\",\n name: \"get_navigation\",\n title: \"Get navigation\",\n },\n];\n"
9
9
  ],
10
- "mappings": "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",
11
- "debugId": "1822C67532B8BE8464756E2164756E21",
10
+ "mappings": "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",
11
+ "debugId": "23E38A1AF0C2C43564756E2164756E21",
12
12
  "names": []
13
13
  }
@@ -7,45 +7,45 @@ import {
7
7
  } from "./index.js";
8
8
  import {
9
9
  deployPlatform
10
- } from "./chunk-v6ya5kcb.js";
11
- import"./chunk-gs7r695n.js";
12
- import"./chunk-5r8g91qn.js";
10
+ } from "./chunk-pv29h0wf.js";
11
+ import"./chunk-3em5wd2y.js";
12
+ import"./chunk-j85vccga.js";
13
13
  import {
14
14
  publishBuildProject,
15
15
  ogCacheDir,
16
16
  pruneCardCache,
17
17
  cardCacheTally
18
- } from "./chunk-xh43dwgw.js";
19
- import"./chunk-ddndchfr.js";
18
+ } from "./chunk-c8chx29p.js";
19
+ import"./chunk-yfyb25rh.js";
20
20
  import {
21
21
  deployOutputDir,
22
22
  deployStaticDir,
23
23
  surfaceAdapterOutput
24
- } from "./chunk-hr8ne106.js";
24
+ } from "./chunk-5m5nmvyq.js";
25
25
  import {
26
26
  ensureGitignore
27
27
  } from "./chunk-yzhm0j9q.js";
28
- import"./chunk-00gs3wqs.js";
28
+ import"./chunk-8ktnccpt.js";
29
29
  import {
30
30
  removedBuildFlags,
31
31
  flagList,
32
32
  removedBuildFlagsAdvice
33
- } from "./chunk-qkb5a8sa.js";
33
+ } from "./chunk-pehfxfta.js";
34
34
  import {
35
35
  refuseIfDevRunning
36
- } from "./chunk-wdrt2k2v.js";
36
+ } from "./chunk-akbpwfxc.js";
37
37
  import {
38
38
  refuseIfEjected
39
- } from "./chunk-4e9b9ra6.js";
39
+ } from "./chunk-ey84smr6.js";
40
40
  import"./chunk-jq5n4avg.js";
41
- import"./chunk-fsmrqk8a.js";
42
- import"./chunk-sqw4ekg1.js";
41
+ import"./chunk-r20tn01b.js";
42
+ import"./chunk-b07cmahc.js";
43
43
  import {
44
44
  prepareProject
45
- } from "./chunk-h2ez8dzb.js";
45
+ } from "./chunk-tzmab476.js";
46
46
  import {
47
47
  serverFeatures
48
- } from "./chunk-mqc662a6.js";
48
+ } from "./chunk-364znk6q.js";
49
49
 
50
50
  // src/cli/commands/build.ts
51
51
  import { existsSync } from "node:fs";
@@ -299,4 +299,4 @@ export {
299
299
  };
300
300
 
301
301
  //# debugId=D6CABD020883D7E964756E2164756E21
302
- //# sourceMappingURL=chunk-k7pj68a8.js.map
302
+ //# sourceMappingURL=chunk-5f86nr5m.js.map
@@ -12,11 +12,11 @@ import {
12
12
  adapterRoot,
13
13
  deployPlatform,
14
14
  BLUME_IGNORE_DIRS
15
- } from "./chunk-v6ya5kcb.js";
15
+ } from "./chunk-pv29h0wf.js";
16
16
  import {
17
17
  trimChar,
18
18
  normalizeBasePath
19
- } from "./chunk-gs7r695n.js";
19
+ } from "./chunk-3em5wd2y.js";
20
20
 
21
21
  // src/deploy/adapter-output.ts
22
22
  import { existsSync } from "node:fs";
@@ -195,10 +195,12 @@ var publishRuntimeModules = (modules) => {
195
195
  return changed;
196
196
  }
197
197
  for (const server of servers) {
198
- for (const id of changed) {
199
- const mod = server.moduleGraph.getModuleById(`${RESOLVED_PREFIX}${id}`);
200
- if (mod) {
201
- server.moduleGraph.invalidateModule(mod);
198
+ for (const { moduleGraph } of Object.values(server.environments)) {
199
+ for (const id of changed) {
200
+ const mod = moduleGraph.getModuleById(`${RESOLVED_PREFIX}${id}`);
201
+ if (mod) {
202
+ moduleGraph.invalidateModule(mod);
203
+ }
202
204
  }
203
205
  }
204
206
  server.ws.send({ type: "full-reload" });
@@ -356,8 +358,16 @@ const blumeConfig = await loadBlumeConfig(resolve(dirname(fileURLToPath(import.m
356
358
  var renderImageOption = (config) => config.image.domains.length > 0 || config.image.remotePatterns.length > 0 ? `
357
359
  image: ${JSON.stringify(config.image)},` : "";
358
360
  var ALL_CLIENT_FEATURES = { epub: true, mermaid: true };
361
+ var SEARCH_CLIENT_DEPS = {
362
+ algolia: "algoliasearch/lite",
363
+ flexsearch: "flexsearch",
364
+ orama: "@orama/orama",
365
+ "orama-cloud": "@oramacloud/client",
366
+ typesense: "typesense"
367
+ };
359
368
  var resolveOptimizeDeps = (options) => {
360
369
  const { context, features } = options;
370
+ const searchDep = SEARCH_CLIENT_DEPS[options.searchKind];
361
371
  const optimizeDepsEntries = [
362
372
  ...context.pagesRoot ? [`${context.pagesRoot}/**/*.astro`] : [],
363
373
  `${context.root}/islands/**/*.{jsx,svelte,tsx,vue}`,
@@ -366,6 +376,7 @@ var resolveOptimizeDeps = (options) => {
366
376
  const optimizeDepsInclude = [
367
377
  ...features.mermaid ? ["blume > mermaid"] : [],
368
378
  ...features.epub ? ["blume > epub-gen-memory/bundle"] : [],
379
+ ...searchDep ? [`blume > ${searchDep}`] : [],
369
380
  ...options.needsReact && options.reactCompilerPath ? ["react/compiler-runtime"] : []
370
381
  ];
371
382
  return { optimizeDepsEntries, optimizeDepsInclude };
@@ -396,7 +407,7 @@ var renderRuntimeModuleWiring = (generatedModulesDir) => {
396
407
  var blumeIntegrationOptions = (options) => options.ejected ? {
397
408
  buildArtifactsRoot: ".",
398
409
  contentRoutes: options.contentRoutes,
399
- homeLinkHeader: buildHomeLinkHeader(options.config, options.contentRoutes) ?? undefined,
410
+ homeLinkHeader: buildHomeLinkHeader(options.config, options.contentRoutes, "dev") ?? undefined,
400
411
  pages: options.pages
401
412
  } : { pages: options.pages };
402
413
  var astroConfigTemplate = (options) => {
@@ -428,7 +439,8 @@ var astroConfigTemplate = (options) => {
428
439
  context,
429
440
  features,
430
441
  needsReact,
431
- reactCompilerPath: options.reactCompilerPath
442
+ reactCompilerPath: options.reactCompilerPath,
443
+ searchKind: config.search.provider.kind
432
444
  });
433
445
  const {
434
446
  configEntries: adapterConfigEntries,
@@ -448,7 +460,7 @@ var astroConfigTemplate = (options) => {
448
460
  prefixDefaultLocale: !config.i18n.hideDefaultLocalePrefix
449
461
  }
450
462
  })},` : "";
451
- const basedRedirects = applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.options.base ?? "");
463
+ const basedRedirects = applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.options.base ?? "", new Set(contentRoutes));
452
464
  const redirectsOption = basedRedirects.length > 0 ? `
453
465
  redirects: ${JSON.stringify(Object.fromEntries(basedRedirects.map((redirect) => [
454
466
  redirect.from,
@@ -601,6 +613,10 @@ ${userConfigSetup}export default defineConfig({
601
613
  // \`/bundle\` subpath that is actually imported: optimizing the package
602
614
  // root leaves that entry out. Production (Rollup) already handles the
603
615
  // interop, so all of this only affects dev.
616
+ //
617
+ // The search adapter's client library rides the list for the same reason
618
+ // as the compiler runtime: the search dialog lazy-imports it on first
619
+ // open, and discovering it then re-optimizes and reloads the page.
604
620
  optimizeDeps: {
605
621
  entries: ${JSON.stringify(optimizeDepsEntries)},
606
622
  include: ${JSON.stringify(optimizeDepsInclude)},
@@ -792,6 +808,7 @@ const ground = createAskContext(askData${groundOptions});
792
808
  ${streamFields.join(`,
793
809
  `)},
794
810
  ${onError}
811
+ abortSignal: request.signal,
795
812
  });`;
796
813
  const stream = grounded ? ` const instructions =
797
814
  (await ground(messages, body.page)) ??
@@ -1154,7 +1171,7 @@ export function GET({ props }: { props: { section: string } }) {
1154
1171
  var navFragmentTemplate = () => `---
1155
1172
  // Generated by Blume. Do not edit.
1156
1173
  import NavTree from "blume/components/layout/NavTree.astro";
1157
- import { withBase } from "blume/components/islands/base-path.ts";
1174
+ import { withMountedBase } from "blume/components/islands/base-path.ts";
1158
1175
  import {
1159
1176
  hiddenDefaultLocale,
1160
1177
  navGroupIds,
@@ -1193,7 +1210,7 @@ if (!(variant && node && node.kind === "group")) {
1193
1210
  }
1194
1211
  const strings =
1195
1212
  locale === "default" ? data.ui.nav : (data.uiByLocale[locale] ?? data.ui).nav;
1196
- const fragmentBase = withBase(\`/blume-nav/\${version}/\${locale}\`);
1213
+ const fragmentBase = withMountedBase(\`/blume-nav/\${version}/\${locale}\`);
1197
1214
  ---
1198
1215
 
1199
1216
  <NavTree
@@ -1209,7 +1226,7 @@ const fragmentBase = withBase(\`/blume-nav/\${version}/\${locale}\`);
1209
1226
  `;
1210
1227
  var ogEndpointTemplate = (customRoutes = [], og = {}, includeChangelog = false) => `// Generated by Blume. Do not edit.
1211
1228
  import { cachedOgImage } from "blume/og";
1212
- import type { OgCache, OgFont, OgFontFamilies } from "blume/og";
1229
+ import type { OgCache, OgFont, OgFontFamilies, OgGoogleFont } from "blume/og";
1213
1230
  import data from "blume:data";
1214
1231
 
1215
1232
  export const prerender = true;
@@ -1225,6 +1242,9 @@ const customRoutes: { slug: string; title: string }[] = ${JSON.stringify(customR
1225
1242
  // data that pages serialize into HTML.
1226
1243
  const fonts: OgFont[] = ${JSON.stringify(og.fonts ?? [])};
1227
1244
  const families: OgFontFamilies | undefined = ${og.families ? JSON.stringify(og.families) : "undefined"};
1245
+ // Script fallbacks (Noto families, the configured locales' first). A card
1246
+ // fetches them only when its text has a glyph Takumi's built-in font lacks.
1247
+ const fallbacks: OgGoogleFont[] = ${JSON.stringify(og.fallbacks ?? [])};
1228
1248
 
1229
1249
  // Rendered cards are kept on disk between builds, keyed by everything that
1230
1250
  // decides their pixels, so a rebuild renders only the cards whose title,
@@ -1291,6 +1311,7 @@ export async function GET({ props }: { props: CardProps }) {
1291
1311
  accent: data.config.og.palette?.accent ?? data.config.theme.accent.light,
1292
1312
  brand: data.config.title,
1293
1313
  description: props.description ?? data.config.og.description,
1314
+ fallbacks,
1294
1315
  families,
1295
1316
  fonts,
1296
1317
  logo: data.config.og.logo,
@@ -1443,8 +1464,8 @@ var catchAllPageTemplate = (options) => {
1443
1464
  import { getEntry, render } from "astro:content";
1444
1465
  import type { CollectionKey } from "astro:content";
1445
1466
  import RootLayout from "blume/components/layout/RootLayout.astro";
1446
- import { withBase } from "blume/components/islands/base-path.ts";
1447
- import { stripBasePath, withBasePath } from "blume/core/base-path.ts";
1467
+ import { withBase, withMountedBase } from "blume/components/islands/base-path.ts";
1468
+ import { mountBasePath, stripBasePath } from "blume/core/base-path.ts";
1448
1469
  import { resolveSlot } from "blume/components/layout/overrides.ts";
1449
1470
  ${componentImports}
1450
1471
  import data from "blume:data";
@@ -1509,12 +1530,16 @@ const base = data.config.site ? data.config.site.replace(/\\/$/, "") : null;
1509
1530
  const ogPath = data.config.og.enabled
1510
1531
  ? encodeURI(\`/og/\${route === "/" ? "index" : route.slice(1)}.png\`)
1511
1532
  : null;
1512
- const ogRel = seo.image ?? ogPath;
1513
1533
  // Absolute URLs also carry the deployment base (the page is served under it):
1514
1534
  // \`site + base + path\`. Only absolutize root-relative paths: \`seo.image\` may be
1515
- // an external URL, which passes through verbatim (mirrors PageLayout).
1516
- const ogImage =
1517
- ogRel && base && ogRel.startsWith("/") ? \`\${base}\${withBase(ogRel)}\` : ogRel;
1535
+ // an external URL, which passes through verbatim (mirrors PageLayout). An
1536
+ // authored \`seo.image\` keeps a base written by hand; the generated card is
1537
+ // always mounted under it.
1538
+ const absoluteOg = (path: string, based: (path: string) => string) =>
1539
+ base && path.startsWith("/") ? \`\${base}\${based(path)}\` : path;
1540
+ const ogImage = seo.image
1541
+ ? absoluteOg(seo.image, withBase)
1542
+ : ogPath && absoluteOg(ogPath, withMountedBase);
1518
1543
  // Blume's generated card has known dimensions the layout can declare; a user's
1519
1544
  // \`seo.image\` could be any size or format, so it gets none.
1520
1545
  const ogGenerated = !seo.image && Boolean(ogPath);
@@ -1523,7 +1548,7 @@ const ogGenerated = !seo.image && Boolean(ogPath);
1523
1548
  // itself (a guest post crediting its own author) over the configured default.
1524
1549
  const x = { ...data.config.x, ...(seo.x?.creator ? { creator: seo.x.creator } : {}) };
1525
1550
 
1526
- const basedRoute = withBase(route);
1551
+ const basedRoute = withMountedBase(route);
1527
1552
 
1528
1553
  // Locale resolution. With i18n on, pick the active locale's nav + dictionary,
1529
1554
  // build hreflang alternates, and derive the language-switcher targets.
@@ -1571,7 +1596,7 @@ const contentDir = i18n
1571
1596
  : "ltr";
1572
1597
  // The root route keeps its trailing slash (\`https://site/\`) so canonical and
1573
1598
  // hreflang URLs byte-match the sitemap's <loc> for the home page.
1574
- const absolute = (path: string) => base + withBase(path);
1599
+ const absolute = (path: string) => base + withMountedBase(path);
1575
1600
 
1576
1601
  // A fallback page renders the fallback locale's page at this locale's URL, so
1577
1602
  // its canonical names the page it copies, and search engines never rank the
@@ -1616,7 +1641,7 @@ const xDefault = defaultAlt && base ? absolute(defaultAlt.path) : null;
1616
1641
  // carries sits *after* the base (\`/docs/ja/guide\`), while \`localePrefix\` is
1617
1642
  // base-less (\`/ja\`). Stripping and re-adding a locale therefore happen in
1618
1643
  // base-less space, with the base re-applied at the end — the same
1619
- // \`withBasePath(basePath, localizeRoute(...))\` composition the manifest uses to
1644
+ // \`mountBasePath(basePath, localizeRoute(...))\` composition the manifest uses to
1620
1645
  // build every real route. Done in based space, \`stripLocale\` matches nothing
1621
1646
  // and \`localizeRoute\` prepends a second prefix (\`/ja/docs/ja/guide\`). Only a
1622
1647
  // switcher entry for a locale with no real translation reaches this fallback:
@@ -1624,7 +1649,7 @@ const xDefault = defaultAlt && base ? absolute(defaultAlt.path) : null;
1624
1649
  // generated reference (which has no \`alternates\` at all) for every locale
1625
1650
  // but its own.
1626
1651
  const mountLocalized = (logical: string, codeArg: string) =>
1627
- withBasePath(data.config.basePath, localizeRoute(logical, codeArg));
1652
+ mountBasePath(data.config.basePath, localizeRoute(logical, codeArg));
1628
1653
  const logicalRoute = i18n
1629
1654
  ? stripLocale(stripBasePath(data.config.basePath, route), locale)
1630
1655
  : route;
@@ -1653,7 +1678,7 @@ const versionRootFor = (id: string) => {
1653
1678
  const logical = id ? \`/\${id}\` : "/";
1654
1679
  return i18n
1655
1680
  ? mountLocalized(logical, locale)
1656
- : withBasePath(data.config.basePath, logical);
1681
+ : mountBasePath(data.config.basePath, logical);
1657
1682
  };
1658
1683
  const samePageSwitch = versionsConfig
1659
1684
  ? versionsConfig.switcher.redirect === "same-page"
@@ -1751,7 +1776,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
1751
1776
  feedback={data.config.feedback}
1752
1777
  exportPdf={${options.exportPdf}}
1753
1778
  exportEpub={${options.exportEpub}}${options.navFragments ? `
1754
- navFragmentBase={withBase(\`/blume-nav/\${version || "current"}/\${i18n && localePrefix(locale) ? locale : "default"}\`)}` : ""}
1779
+ navFragmentBase={withMountedBase(\`/blume-nav/\${version || "current"}/\${i18n && localePrefix(locale) ? locale : "default"}\`)}` : ""}
1755
1780
  openInChat={data.config.openInChat}
1756
1781
  feeds={data.feeds}
1757
1782
  discovery={data.config.discovery}
@@ -1779,7 +1804,7 @@ var changelogIndexTemplate = (options) => {
1779
1804
  // Generated by Blume. Do not edit.
1780
1805
  import { getCollection } from "astro:content";
1781
1806
  import RootLayout from "blume/components/layout/RootLayout.astro";
1782
- import { withBase } from "blume/components/islands/base-path.ts";
1807
+ import { withMountedBase } from "blume/components/islands/base-path.ts";
1783
1808
  import { resolveSlot } from "blume/components/layout/overrides.ts";
1784
1809
  import { resolveDateFormatOptions } from "blume/core/date-format.ts";
1785
1810
  import { layoutOverrides } from "../generated/components.ts";
@@ -1878,7 +1903,7 @@ const items = changelogEntries.map((entry) => {
1878
1903
  return {
1879
1904
  date: date ? formatRowDate(date) : null,
1880
1905
  dateTime: date ? date.toISOString().slice(0, 10) : null,
1881
- href: route ? withBase(route) : null,
1906
+ href: route ? withMountedBase(route) : null,
1882
1907
  id: slugify(label),
1883
1908
  label,
1884
1909
  tag: entry.data.changelog?.category ?? null,
@@ -1914,14 +1939,14 @@ for (const item of items) {
1914
1939
 
1915
1940
  const base = data.config.site ? data.config.site.replace(/\\/$/, "") : null;
1916
1941
  // The canonical URL carries the deployment base (the page is served under it),
1917
- // matching how the catch-all canonicalizes via \`withBase(route)\`.
1918
- const basedRoute = withBase("/changelog");
1942
+ // matching how the catch-all canonicalizes via \`withMountedBase(route)\`.
1943
+ const basedRoute = withMountedBase("/changelog");
1919
1944
  const canonical = base ? base + basedRoute : null;
1920
1945
 
1921
1946
  // The generated OG card for this route (the /og endpoint emits it alongside
1922
1947
  // the content-route cards), absolutized like the catch-all's so crawlers get
1923
1948
  // a full URL when the site is known.
1924
- const ogPath = data.config.og.enabled ? withBase("/og/changelog.png") : null;
1949
+ const ogPath = data.config.og.enabled ? withMountedBase("/og/changelog.png") : null;
1925
1950
  const ogImage = ogPath && base ? base + ogPath : ogPath;
1926
1951
 
1927
1952
  // The page chrome (h1, title, description) comes from the translatable
@@ -2033,8 +2058,8 @@ var notFoundPageTemplate = () => `---
2033
2058
  // Generated by Blume. Do not edit. Override by adding \`pages/404.astro\`.
2034
2059
  import Icon from "blume/components/Icon.astro";
2035
2060
  import PageLayout from "blume/components/layout/PageLayout.astro";
2036
- import { withBase } from "blume/components/islands/base-path.ts";
2037
- import { withBasePath } from "blume/core/base-path.ts";
2061
+ import { withMountedBase } from "blume/components/islands/base-path.ts";
2062
+ import { mountBasePath } from "blume/core/base-path.ts";
2038
2063
  import data from "blume:data";
2039
2064
 
2040
2065
  export const prerender = true;
@@ -2058,14 +2083,14 @@ const htmlLang = i18n ? i18n.defaultLocale : "en";
2058
2083
  // their resolved target when the section has no index page of its own.
2059
2084
  const suggestions = [
2060
2085
  ...data.navigation.tabs.map((tab) => ({
2061
- href: withBase(tab.href ?? tab.path),
2086
+ href: withMountedBase(tab.href ?? tab.path),
2062
2087
  label: tab.label,
2063
2088
  })),
2064
2089
  ...(data.config.discovery.sitemap
2065
- ? [{ href: withBase("/sitemap.xml"), label: nf.sitemap }]
2090
+ ? [{ href: withMountedBase("/sitemap.xml"), label: nf.sitemap }]
2066
2091
  : []),
2067
2092
  ...(data.config.discovery.llmsTxt
2068
- ? [{ href: withBase("/llms.txt"), label: nf.llms }]
2093
+ ? [{ href: withMountedBase("/llms.txt"), label: nf.llms }]
2069
2094
  : []),
2070
2095
  ];
2071
2096
 
@@ -2077,7 +2102,7 @@ const suggestions = [
2077
2102
  // Localized routes sit under both bases (\`{deployment.base}/{basePath}/ar/…\`),
2078
2103
  // so the script strips the two together, trailing slash included.
2079
2104
  const { basePath } = data.config;
2080
- const siteRoot = withBase(withBasePath(basePath, "/"));
2105
+ const siteRoot = withMountedBase(mountBasePath(basePath, "/"));
2081
2106
  const localeBase = siteRoot.endsWith("/") ? siteRoot : siteRoot + "/";
2082
2107
  const localized = Object.fromEntries(
2083
2108
  (i18n?.locales ?? [])
@@ -2090,7 +2115,7 @@ const localized = Object.fromEntries(
2090
2115
  description: strings.description,
2091
2116
  dir: l.dir ?? "ltr",
2092
2117
  home: strings.home,
2093
- homeHref: withBase(withBasePath(basePath, "/" + l.code)),
2118
+ homeHref: withMountedBase(mountBasePath(basePath, "/" + l.code)),
2094
2119
  suggestions: strings.suggestions,
2095
2120
  title: strings.title,
2096
2121
  },
@@ -2140,7 +2165,7 @@ const localizedJson = JSON.stringify(localized).replaceAll("<", "\\\\u003c");
2140
2165
  <a
2141
2166
  class="mt-8 inline-flex items-center gap-1.5 rounded-full bg-accent py-2 pe-4 ps-3.5 text-sm font-medium text-accent-foreground transition-opacity hover:opacity-90"
2142
2167
  data-nf-home
2143
- href={withBase("/")}
2168
+ href={withMountedBase("/")}
2144
2169
  >
2145
2170
  <Icon class="rtl:-scale-x-100" name="arrow-left" size={14} />
2146
2171
  <span data-nf="home">{nf.home}</span>
@@ -2207,7 +2232,7 @@ const localizedJson = JSON.stringify(localized).replaceAll("<", "\\\\u003c");
2207
2232
  </PageLayout>
2208
2233
  `;
2209
2234
  var notFoundMarkdownTemplate = () => `// Generated by Blume. Do not edit. Override by adding \`pages/404.astro\`.
2210
- import { withBase } from "blume/components/islands/base-path.ts";
2235
+ import { withMountedBase } from "blume/components/islands/base-path.ts";
2211
2236
  import { absoluteUrl } from "blume/core/site-url.ts";
2212
2237
  import data from "blume:data";
2213
2238
 
@@ -2218,7 +2243,7 @@ const nf = data.ui.notFound;
2218
2243
  // Absolute for internal routes when the site is known; an external tab href
2219
2244
  // passes through untouched.
2220
2245
  const href = (path: string): string => {
2221
- const based = withBase(path);
2246
+ const based = withMountedBase(path);
2222
2247
  return data.config.site && based.startsWith("/") && !based.startsWith("//")
2223
2248
  ? absoluteUrl(data.config.site, based)
2224
2249
  : based;
@@ -2266,7 +2291,7 @@ export function GET() {
2266
2291
  `;
2267
2292
  var notFoundJsonTemplate = () => `// Generated by Blume. Do not edit. Override by adding \`pages/404.astro\`.
2268
2293
  import { problem } from "blume/ai/api/problem.ts";
2269
- import { withBase } from "blume/components/islands/base-path.ts";
2294
+ import { withMountedBase } from "blume/components/islands/base-path.ts";
2270
2295
  import { absoluteUrl } from "blume/core/site-url.ts";
2271
2296
  import data from "blume:data";
2272
2297
 
@@ -2277,7 +2302,7 @@ const nf = data.ui.notFound;
2277
2302
  // Absolute for internal routes when the site is known; an external tab href
2278
2303
  // passes through untouched.
2279
2304
  const href = (path: string): string => {
2280
- const based = withBase(path);
2305
+ const based = withMountedBase(path);
2281
2306
  return data.config.site && based.startsWith("/") && !based.startsWith("//")
2282
2307
  ? absoluteUrl(data.config.site, based)
2283
2308
  : based;
@@ -2536,5 +2561,5 @@ var runtimeTsconfigTemplate = () => `${JSON.stringify({
2536
2561
 
2537
2562
  export { deployOutputDir, deployStaticDir, surfaceAdapterOutput, planComponentSlots, publishRuntimeModules, runtimeDependencies, EJECTED_CONFIG_HEADER, astroConfigTemplate, stagedContentDir, contentConfigTemplate, askEndpointTemplate, askComponentTemplate, searchEndpointTemplate, featuresTemplate, searchClientTemplate, mixedbreadSearchEndpointTemplate, rawMarkdownEndpointTemplate, contentAssetsEndpointTemplate, mcpPageFile, mcpEndpointTemplate, playgroundProxyTemplate, staticJsonEndpointTemplate, rssEndpointTemplate, navFragmentTemplate, ogEndpointTemplate, scalarReferenceTemplate, catchAllPageTemplate, changelogIndexTemplate, notFoundPageTemplate, notFoundMarkdownTemplate, notFoundJsonTemplate, apiPagesIndexTemplate, apiPageTemplate, apiNavigationTemplate, apiSearchTemplate, apiNotFoundTemplate, exampleSlug, exampleWrapperTemplate, examplesRouteBase, exampleMapTemplate, examplesPageTemplate, runtimePackageTemplate, runtimeTsconfigTemplate };
2538
2563
 
2539
- //# debugId=941D4E587200F86C64756E2164756E21
2540
- //# sourceMappingURL=chunk-hr8ne106.js.map
2564
+ //# debugId=D53DB1B1EA2E6A3764756E2164756E21
2565
+ //# sourceMappingURL=chunk-5m5nmvyq.js.map