blume 2.0.1 → 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 (492) hide show
  1. package/CHANGELOG.md +147 -0
  2. package/dist/cli/{chunk-qwsrynx5.js → chunk-1d7ve1dm.js} +38 -19
  3. package/dist/cli/{chunk-qwsrynx5.js.map → chunk-1d7ve1dm.js.map} +4 -4
  4. package/dist/cli/{chunk-s6jhgk0q.js → chunk-2eytanqx.js} +2 -2
  5. package/dist/cli/{chunk-kdp5q7ke.js → chunk-2hsdwb9n.js} +18 -19
  6. package/dist/cli/{chunk-kdp5q7ke.js.map → chunk-2hsdwb9n.js.map} +2 -2
  7. package/dist/cli/{chunk-hdpx1tax.js → chunk-2z928egk.js} +5 -5
  8. package/dist/cli/{chunk-jwyddg7y.js → chunk-35d4wj9f.js} +30 -24
  9. package/dist/cli/chunk-35d4wj9f.js.map +15 -0
  10. package/dist/cli/{chunk-ah61y8py.js → chunk-364znk6q.js} +2 -2
  11. package/dist/cli/{chunk-jts8mvcz.js → chunk-3em5wd2y.js} +25 -6
  12. package/dist/cli/{chunk-jts8mvcz.js.map → chunk-3em5wd2y.js.map} +3 -3
  13. package/dist/cli/{chunk-s1p84fyh.js → chunk-5f86nr5m.js} +63 -22
  14. package/dist/cli/chunk-5f86nr5m.js.map +11 -0
  15. package/dist/cli/{chunk-2hn4b8z7.js → chunk-5m5nmvyq.js} +170 -76
  16. package/dist/cli/chunk-5m5nmvyq.js.map +13 -0
  17. package/dist/cli/{chunk-epjnccmv.js → chunk-5xvm6tfj.js} +18 -15
  18. package/dist/cli/chunk-5xvm6tfj.js.map +10 -0
  19. package/dist/cli/{chunk-fz5wtpmh.js → chunk-6dsbexzp.js} +18 -15
  20. package/dist/cli/chunk-6dsbexzp.js.map +10 -0
  21. package/dist/cli/{chunk-vtk4a6dg.js → chunk-8ktnccpt.js} +1 -1
  22. package/dist/cli/{chunk-6hsn950k.js → chunk-9t7a85s3.js} +178 -48
  23. package/dist/cli/chunk-9t7a85s3.js.map +10 -0
  24. package/dist/cli/{chunk-fxypxtvm.js → chunk-a58773jm.js} +2 -2
  25. package/dist/cli/{chunk-mb2919y2.js → chunk-acanzt5p.js} +17 -6
  26. package/dist/cli/chunk-acanzt5p.js.map +10 -0
  27. package/dist/cli/{chunk-27g6wdth.js → chunk-akbpwfxc.js} +90 -26
  28. package/dist/cli/chunk-akbpwfxc.js.map +10 -0
  29. package/dist/cli/{chunk-wm7js3j9.js → chunk-b07cmahc.js} +2 -2
  30. package/dist/cli/{chunk-wgm7m9qk.js → chunk-c8chx29p.js} +179 -51
  31. package/dist/cli/chunk-c8chx29p.js.map +36 -0
  32. package/dist/cli/{chunk-qs4q5p4e.js → chunk-crgn1q09.js} +32 -14
  33. package/dist/cli/chunk-crgn1q09.js.map +10 -0
  34. package/dist/cli/chunk-e04dxsz1.js +39 -0
  35. package/dist/cli/chunk-e04dxsz1.js.map +10 -0
  36. package/dist/cli/{chunk-yt5n7ppj.js → chunk-ey84smr6.js} +17 -7
  37. package/dist/cli/chunk-ey84smr6.js.map +10 -0
  38. package/dist/cli/{chunk-f2z5v128.js → chunk-g4hq16wv.js} +14 -15
  39. package/dist/cli/{chunk-f2z5v128.js.map → chunk-g4hq16wv.js.map} +2 -2
  40. package/dist/cli/{chunk-fa25z98p.js → chunk-ga0pf4aj.js} +9 -8
  41. package/dist/cli/chunk-ga0pf4aj.js.map +11 -0
  42. package/dist/cli/{chunk-kpf8rrjc.js → chunk-hm3vjy5s.js} +109 -58
  43. package/dist/cli/chunk-hm3vjy5s.js.map +19 -0
  44. package/dist/cli/{chunk-fs23ddbb.js → chunk-j85vccga.js} +625 -750
  45. package/dist/cli/chunk-j85vccga.js.map +36 -0
  46. package/dist/cli/{chunk-ch6g3ar0.js → chunk-p3v96n38.js} +6 -6
  47. package/dist/cli/{chunk-ch6g3ar0.js.map → chunk-p3v96n38.js.map} +3 -3
  48. package/dist/cli/{chunk-q5163e60.js → chunk-p73c0m7w.js} +21 -19
  49. package/dist/cli/chunk-p73c0m7w.js.map +11 -0
  50. package/dist/cli/{chunk-dh8cwk36.js → chunk-pehfxfta.js} +24 -9
  51. package/dist/cli/chunk-pehfxfta.js.map +10 -0
  52. package/dist/cli/{chunk-qkqwkpte.js → chunk-pv29h0wf.js} +3688 -1313
  53. package/dist/cli/chunk-pv29h0wf.js.map +190 -0
  54. package/dist/cli/{chunk-6vm74dry.js → chunk-q58y5e6a.js} +10 -10
  55. package/dist/cli/{chunk-6vm74dry.js.map → chunk-q58y5e6a.js.map} +3 -3
  56. package/dist/cli/{chunk-zxcczpyx.js → chunk-r20tn01b.js} +1 -1
  57. package/dist/cli/{chunk-m3vmjgmq.js → chunk-r9rcc4w7.js} +16 -8
  58. package/dist/cli/chunk-r9rcc4w7.js.map +10 -0
  59. package/dist/cli/{chunk-5shv93fd.js → chunk-tkacnehg.js} +2 -2
  60. package/dist/cli/{chunk-zxh4d9vy.js → chunk-tzmab476.js} +4 -4
  61. package/dist/cli/{chunk-yw7dm696.js → chunk-vg9r4eb9.js} +24 -11
  62. package/dist/cli/chunk-vg9r4eb9.js.map +14 -0
  63. package/dist/cli/{chunk-79jhk4py.js → chunk-wrr3j9w9.js} +260 -132
  64. package/dist/cli/chunk-wrr3j9w9.js.map +35 -0
  65. package/dist/cli/{chunk-6crbhc3x.js → chunk-yfyb25rh.js} +54 -27
  66. package/dist/cli/chunk-yfyb25rh.js.map +14 -0
  67. package/dist/cli/index.js +162 -35
  68. package/dist/cli/index.js.map +4 -4
  69. package/dist/types/ai/agent-surface.d.ts +32 -0
  70. package/dist/types/ai/api-catalog.d.ts +7 -1
  71. package/dist/types/ai/ask-context.d.ts +7 -0
  72. package/dist/types/ai/component-markdown.d.ts +4 -4
  73. package/dist/types/ai/link-headers.d.ts +8 -1
  74. package/dist/types/ai/openapi-components.d.ts +5 -2
  75. package/dist/types/ai/relative-links.d.ts +11 -4
  76. package/dist/types/ai/skills.d.ts +4 -1
  77. package/dist/types/ai/static-expression.d.ts +28 -0
  78. package/dist/types/ai/tar.d.ts +1 -3
  79. package/dist/types/analytics/databuddy.d.ts +43 -0
  80. package/dist/types/analytics/index.d.ts +4 -0
  81. package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
  82. package/dist/types/analytics/schema.d.ts +28 -0
  83. package/dist/types/astro/integration.d.ts +3 -2
  84. package/dist/types/cli/env.d.ts +5 -0
  85. package/dist/types/cli/init/scaffold.d.ts +19 -3
  86. package/dist/types/cli/init/starter-spec.d.ts +11 -0
  87. package/dist/types/core/base-path.d.ts +24 -1
  88. package/dist/types/core/config-input.d.ts +13 -11
  89. package/dist/types/core/config.d.ts +2 -2
  90. package/dist/types/core/directive-diagnostics.d.ts +12 -0
  91. package/dist/types/core/graph.d.ts +2 -0
  92. package/dist/types/core/heading-markers.d.ts +5 -7
  93. package/dist/types/core/i18n-ui.d.ts +31 -0
  94. package/dist/types/core/i18n.d.ts +9 -1
  95. package/dist/types/core/last-modified.d.ts +10 -0
  96. package/dist/types/core/links.d.ts +3 -1
  97. package/dist/types/core/load-module.d.ts +10 -0
  98. package/dist/types/core/locale-links.d.ts +12 -2
  99. package/dist/types/core/meta.d.ts +13 -1
  100. package/dist/types/core/nav-diagnostics.d.ts +10 -0
  101. package/dist/types/core/navigation.d.ts +38 -0
  102. package/dist/types/core/ordering-prefix.d.ts +4 -0
  103. package/dist/types/core/safe-links.d.ts +3 -1
  104. package/dist/types/core/schema.d.ts +59 -13
  105. package/dist/types/core/sources/github-releases.d.ts +5 -0
  106. package/dist/types/core/sources/lower.d.ts +38 -13
  107. package/dist/types/core/sources/normalize.d.ts +23 -2
  108. package/dist/types/core/sources/remote.d.ts +11 -1
  109. package/dist/types/core/sources/resolve.d.ts +12 -0
  110. package/dist/types/core/sources/types.d.ts +31 -0
  111. package/dist/types/core/sources/watch.d.ts +12 -5
  112. package/dist/types/core/standard-schema.d.ts +5 -0
  113. package/dist/types/core/types.d.ts +9 -0
  114. package/dist/types/deploy/adapters/node.d.ts +5 -2
  115. package/dist/types/deploy/adapters/types.d.ts +7 -0
  116. package/dist/types/deploy/artifacts.d.ts +6 -4
  117. package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
  118. package/dist/types/deploy/headers.d.ts +36 -7
  119. package/dist/types/deploy/node-headers.d.ts +43 -8
  120. package/dist/types/deploy/platforms/netlify.d.ts +27 -2
  121. package/dist/types/deploy/platforms/node.d.ts +6 -5
  122. package/dist/types/deploy/platforms/types.d.ts +15 -0
  123. package/dist/types/deploy/platforms/vercel.d.ts +3 -2
  124. package/dist/types/deploy/redirects.d.ts +31 -15
  125. package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
  126. package/dist/types/markdown/directives.d.ts +62 -0
  127. package/dist/types/markdown/features.d.ts +21 -0
  128. package/dist/types/markdown/mdast.d.ts +63 -0
  129. package/dist/types/openapi/asyncapi.d.ts +4 -2
  130. package/dist/types/openapi/model.d.ts +20 -6
  131. package/dist/types/search/sync/algolia.d.ts +3 -1
  132. package/docs/01-quickstart.mdx +3 -2
  133. package/docs/02-deployment.mdx +20 -9
  134. package/docs/08-faq.mdx +10 -3
  135. package/docs/advanced/changelog.mdx +1 -1
  136. package/docs/advanced/custom-pages.mdx +7 -5
  137. package/docs/cli/audit.mdx +19 -3
  138. package/docs/cli/doctor.mdx +2 -2
  139. package/docs/cli/evals.mdx +4 -4
  140. package/docs/cli/index.mdx +4 -1
  141. package/docs/cli/translate.mdx +4 -4
  142. package/docs/cli/version.mdx +1 -1
  143. package/docs/configuration/analytics.mdx +42 -2
  144. package/docs/configuration/assistant.mdx +1 -1
  145. package/docs/configuration/customization.mdx +6 -3
  146. package/docs/configuration/index.mdx +5 -3
  147. package/docs/configuration/search.mdx +2 -2
  148. package/docs/content/components.mdx +2 -2
  149. package/docs/content/frontmatter.mdx +5 -1
  150. package/docs/content/i18n.mdx +3 -1
  151. package/docs/content/index.mdx +8 -4
  152. package/docs/content/islands.mdx +1 -1
  153. package/docs/content/meta.mdx +7 -3
  154. package/docs/content/navigation.mdx +29 -4
  155. package/docs/content/sources.mdx +18 -16
  156. package/docs/content/syntax.mdx +14 -0
  157. package/docs/content/versioning.mdx +2 -1
  158. package/docs/discoverability/agent-discovery.mdx +22 -8
  159. package/docs/discoverability/index.mdx +4 -3
  160. package/docs/discoverability/llms-txt.mdx +2 -5
  161. package/docs/discoverability/markdown.mdx +6 -4
  162. package/docs/discoverability/mcp.mdx +4 -0
  163. package/docs/discoverability/metadata.mdx +3 -2
  164. package/docs/discoverability/open-graph.mdx +8 -4
  165. package/docs/discoverability/rss.mdx +4 -2
  166. package/docs/references/asyncapi.mdx +2 -2
  167. package/docs/references/graphql.mdx +2 -2
  168. package/docs/references/openapi.mdx +6 -4
  169. package/package.json +1 -1
  170. package/skills/blume-migrate/SKILL.md +6 -6
  171. package/skills/blume-migrate/references/docusaurus.md +6 -6
  172. package/skills/blume-migrate/references/fumadocs.md +1 -1
  173. package/skills/blume-migrate/references/mintlify.md +3 -3
  174. package/skills/blume-migrate/references/monorepo.md +1 -1
  175. package/skills/blume-migrate/references/nextra.md +2 -2
  176. package/skills/blume-migrate/references/starlight.md +5 -5
  177. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +9 -4
  178. package/skills/blume-update-docs/references/audit-checklist.md +1 -1
  179. package/src/ai/agent-readability.ts +2 -2
  180. package/src/ai/agent-surface.ts +56 -0
  181. package/src/ai/ai-catalog.ts +6 -2
  182. package/src/ai/api/handlers.ts +2 -2
  183. package/src/ai/api/spec.ts +17 -4
  184. package/src/ai/api-catalog.ts +13 -3
  185. package/src/ai/ask-context.ts +14 -2
  186. package/src/ai/ask-data.ts +26 -12
  187. package/src/ai/changelog-markdown.ts +2 -2
  188. package/src/ai/component-markdown.ts +43 -37
  189. package/src/ai/link-headers.ts +22 -8
  190. package/src/ai/llms.ts +22 -10
  191. package/src/ai/markdown.ts +23 -11
  192. package/src/ai/mcp/discovery.ts +2 -2
  193. package/src/ai/mcp/query.ts +2 -2
  194. package/src/ai/mcp/server.ts +80 -9
  195. package/src/ai/openapi-components.ts +22 -6
  196. package/src/ai/relative-links.ts +99 -15
  197. package/src/ai/serializers.ts +2 -1
  198. package/src/ai/skills.ts +14 -1
  199. package/src/ai/static-expression.ts +416 -0
  200. package/src/ai/tar.ts +139 -12
  201. package/src/ai/visibility.ts +45 -14
  202. package/src/analytics/databuddy.ts +67 -0
  203. package/src/analytics/head.ts +8 -0
  204. package/src/analytics/index.ts +7 -0
  205. package/src/analytics/one-dollar-stats.ts +86 -0
  206. package/src/analytics/posthog.ts +21 -3
  207. package/src/analytics/schema.ts +4 -0
  208. package/src/astro/generate.ts +72 -28
  209. package/src/astro/include-hmr.ts +31 -12
  210. package/src/astro/include-refresh.ts +19 -8
  211. package/src/astro/integration.ts +108 -14
  212. package/src/astro/runtime-modules.ts +28 -13
  213. package/src/astro/templates.ts +139 -57
  214. package/src/audit/catalog.ts +2 -2
  215. package/src/audit/checks/assets.ts +25 -5
  216. package/src/audit/checks/content.ts +20 -2
  217. package/src/audit/checks/i18n.ts +46 -8
  218. package/src/audit/checks/indexability.ts +39 -19
  219. package/src/audit/checks/links.ts +22 -1
  220. package/src/audit/checks/llms.ts +6 -3
  221. package/src/audit/checks/network.ts +3 -1
  222. package/src/audit/checks/og-image.ts +10 -0
  223. package/src/audit/checks/robots.ts +6 -1
  224. package/src/audit/checks/sitemap.ts +56 -31
  225. package/src/audit/checks/social.ts +21 -2
  226. package/src/audit/crawl.ts +88 -15
  227. package/src/audit/graph.ts +3 -1
  228. package/src/audit/report.ts +54 -17
  229. package/src/audit/run.ts +13 -9
  230. package/src/audit/snapshot.ts +5 -0
  231. package/src/audit/types.ts +18 -0
  232. package/src/audit/url.ts +37 -6
  233. package/src/cli/args.ts +32 -0
  234. package/src/cli/build-failure.ts +50 -0
  235. package/src/cli/commands/audit.ts +11 -1
  236. package/src/cli/commands/build.ts +19 -5
  237. package/src/cli/commands/check.ts +2 -0
  238. package/src/cli/commands/doctor.ts +3 -1
  239. package/src/cli/commands/eval.ts +20 -18
  240. package/src/cli/commands/init.ts +15 -5
  241. package/src/cli/commands/preview.ts +15 -0
  242. package/src/cli/commands/sync.ts +2 -0
  243. package/src/cli/commands/translate.ts +18 -18
  244. package/src/cli/commands/upgrade.ts +11 -0
  245. package/src/cli/commands/validate.ts +3 -1
  246. package/src/cli/dev-lock.ts +157 -37
  247. package/src/cli/eject-scripts.ts +32 -7
  248. package/src/cli/env.ts +12 -1
  249. package/src/cli/init/scaffold.ts +117 -11
  250. package/src/cli/init/starter-spec.ts +235 -0
  251. package/src/cli/report-format.ts +11 -6
  252. package/src/components/colors.ts +19 -0
  253. package/src/components/content/AccordionItem.astro +26 -22
  254. package/src/components/content/Badge.astro +7 -12
  255. package/src/components/content/Card.astro +2 -2
  256. package/src/components/content/Component.astro +11 -5
  257. package/src/components/content/Expandable.astro +5 -1
  258. package/src/components/content/Frame.astro +2 -7
  259. package/src/components/content/GithubInfo.astro +12 -2
  260. package/src/components/content/Prompt.astro +2 -7
  261. package/src/components/content/Tab.astro +0 -1
  262. package/src/components/content/Tabs.astro +58 -5
  263. package/src/components/content/Tile.astro +1 -1
  264. package/src/components/content/Tooltip.astro +69 -7
  265. package/src/components/content/Tree.astro +7 -2
  266. package/src/components/content/TypeTable.astro +10 -5
  267. package/src/components/content/Update.astro +8 -2
  268. package/src/components/content/auto-type-table.ts +4 -1
  269. package/src/components/content/badge-color.ts +20 -0
  270. package/src/components/content/base-href.ts +14 -22
  271. package/src/components/content/inline-markdown.ts +27 -7
  272. package/src/components/copy-feedback.ts +35 -8
  273. package/src/components/islands/assistant.tsx +37 -6
  274. package/src/components/islands/base-path.ts +47 -10
  275. package/src/components/islands/hooks.ts +42 -21
  276. package/src/components/islands/webmcp.ts +16 -10
  277. package/src/components/layout/Banner.astro +23 -4
  278. package/src/components/layout/Breadcrumbs.astro +5 -2
  279. package/src/components/layout/DiscoveryLinks.astro +9 -5
  280. package/src/components/layout/Header.astro +23 -10
  281. package/src/components/layout/LanguageSwitcher.astro +2 -2
  282. package/src/components/layout/Logo.astro +5 -0
  283. package/src/components/layout/NavSelector.astro +8 -3
  284. package/src/components/layout/NavTabMenu.astro +133 -0
  285. package/src/components/layout/NavTree.astro +31 -12
  286. package/src/components/layout/NavTreeCache.astro +5 -2
  287. package/src/components/layout/NavTreeScript.astro +45 -5
  288. package/src/components/layout/PageActions.astro +4 -3
  289. package/src/components/layout/PageLayout.astro +28 -13
  290. package/src/components/layout/Pagination.astro +3 -3
  291. package/src/components/layout/ReferenceLayout.astro +4 -1
  292. package/src/components/layout/RootLayout.astro +25 -12
  293. package/src/components/layout/Search.astro +38 -14
  294. package/src/components/layout/VersionBanner.astro +2 -2
  295. package/src/components/layout/analytics-client.ts +14 -0
  296. package/src/components/layout/toc-active.ts +41 -0
  297. package/src/components/layout/toc-element.ts +8 -14
  298. package/src/components/openapi/ApiTagOperations.astro +2 -2
  299. package/src/components/openapi/AsyncApiOperation.astro +7 -4
  300. package/src/components/openapi/GraphqlChip.astro +2 -2
  301. package/src/components/openapi/GraphqlType.astro +11 -3
  302. package/src/components/openapi/MessageComposer.astro +1 -1
  303. package/src/components/openapi/Operation.astro +23 -5
  304. package/src/components/openapi/PanelTabs.astro +4 -1
  305. package/src/components/openapi/Playground.astro +8 -2
  306. package/src/components/openapi/RequestPanel.astro +13 -6
  307. package/src/components/openapi/SchemaProperty.astro +11 -33
  308. package/src/components/openapi/SchemaTable.astro +34 -52
  309. package/src/components/openapi/async.ts +38 -6
  310. package/src/components/openapi/helpers.ts +100 -12
  311. package/src/components/openapi/message-composer.ts +14 -1
  312. package/src/components/openapi/message-model.ts +12 -2
  313. package/src/components/openapi/message.ts +21 -3
  314. package/src/components/openapi/operation-model.ts +119 -17
  315. package/src/components/openapi/panel.ts +31 -5
  316. package/src/components/openapi/param-style.ts +181 -0
  317. package/src/components/openapi/playground-client.ts +110 -23
  318. package/src/components/openapi/playground-schema.ts +25 -6
  319. package/src/components/openapi/request.ts +192 -26
  320. package/src/components/openapi/schema-tree.ts +209 -0
  321. package/src/components/openapi/snippets.ts +113 -19
  322. package/src/components/openapi/validate-json.ts +1 -1
  323. package/src/components/openapi/ws-client.ts +18 -2
  324. package/src/core/base-path.ts +69 -8
  325. package/src/core/config-input.ts +13 -11
  326. package/src/core/config.ts +18 -4
  327. package/src/core/diagnostics.ts +219 -30
  328. package/src/core/directive-diagnostics.ts +99 -0
  329. package/src/core/frontmatter.ts +21 -18
  330. package/src/core/graph.ts +120 -11
  331. package/src/core/heading-markers.ts +5 -18
  332. package/src/core/i18n-ui.ts +39 -2
  333. package/src/core/i18n.ts +44 -5
  334. package/src/core/last-modified.ts +25 -3
  335. package/src/core/links.ts +7 -4
  336. package/src/core/load-module.ts +20 -0
  337. package/src/core/locale-links.ts +22 -18
  338. package/src/core/manifest.ts +3 -2
  339. package/src/core/meta.ts +89 -12
  340. package/src/core/nav-diagnostics.ts +56 -1
  341. package/src/core/navigation.ts +272 -83
  342. package/src/core/ordering-prefix.ts +27 -0
  343. package/src/core/project-graph.ts +50 -6
  344. package/src/core/safe-href.ts +53 -1
  345. package/src/core/safe-links.ts +11 -2
  346. package/src/core/schema.ts +94 -18
  347. package/src/core/sources/assets.ts +83 -41
  348. package/src/core/sources/contentful-rich-text.ts +28 -20
  349. package/src/core/sources/contentful.ts +25 -12
  350. package/src/core/sources/filesystem.ts +25 -3
  351. package/src/core/sources/github-releases.ts +131 -11
  352. package/src/core/sources/lexical.ts +30 -20
  353. package/src/core/sources/lower.ts +276 -56
  354. package/src/core/sources/mdx-remote.ts +52 -16
  355. package/src/core/sources/normalize.ts +456 -119
  356. package/src/core/sources/notion.ts +77 -34
  357. package/src/core/sources/obsidian.ts +40 -9
  358. package/src/core/sources/payload.ts +1 -0
  359. package/src/core/sources/portable-text.ts +85 -49
  360. package/src/core/sources/remote.ts +18 -2
  361. package/src/core/sources/resolve.ts +52 -33
  362. package/src/core/sources/sanity.ts +1 -0
  363. package/src/core/sources/strapi-blocks.ts +28 -19
  364. package/src/core/sources/strapi.ts +1 -0
  365. package/src/core/sources/types.ts +31 -0
  366. package/src/core/sources/watch.ts +20 -7
  367. package/src/core/standard-schema.ts +10 -6
  368. package/src/core/types.ts +9 -0
  369. package/src/core/ui-packs/ar.ts +13 -0
  370. package/src/core/ui-packs/bg.ts +13 -0
  371. package/src/core/ui-packs/bn.ts +13 -0
  372. package/src/core/ui-packs/ca.ts +13 -0
  373. package/src/core/ui-packs/cs.ts +13 -0
  374. package/src/core/ui-packs/da.ts +13 -0
  375. package/src/core/ui-packs/de.ts +13 -0
  376. package/src/core/ui-packs/el.ts +13 -0
  377. package/src/core/ui-packs/es.ts +13 -0
  378. package/src/core/ui-packs/fa.ts +13 -0
  379. package/src/core/ui-packs/fi.ts +13 -0
  380. package/src/core/ui-packs/fr.ts +13 -0
  381. package/src/core/ui-packs/he.ts +13 -0
  382. package/src/core/ui-packs/hi.ts +13 -0
  383. package/src/core/ui-packs/hr.ts +13 -0
  384. package/src/core/ui-packs/hu.ts +13 -0
  385. package/src/core/ui-packs/id.ts +13 -0
  386. package/src/core/ui-packs/it.ts +13 -0
  387. package/src/core/ui-packs/ja.ts +13 -0
  388. package/src/core/ui-packs/ko.ts +13 -0
  389. package/src/core/ui-packs/nl.ts +13 -0
  390. package/src/core/ui-packs/no.ts +13 -0
  391. package/src/core/ui-packs/pl.ts +13 -0
  392. package/src/core/ui-packs/pt-br.ts +13 -0
  393. package/src/core/ui-packs/pt.ts +13 -0
  394. package/src/core/ui-packs/ro.ts +13 -0
  395. package/src/core/ui-packs/ru.ts +13 -0
  396. package/src/core/ui-packs/sk.ts +13 -0
  397. package/src/core/ui-packs/sr.ts +13 -0
  398. package/src/core/ui-packs/sv.ts +13 -0
  399. package/src/core/ui-packs/th.ts +13 -0
  400. package/src/core/ui-packs/tr.ts +13 -0
  401. package/src/core/ui-packs/uk.ts +13 -0
  402. package/src/core/ui-packs/vi.ts +13 -0
  403. package/src/core/ui-packs/zh-tw.ts +13 -0
  404. package/src/core/ui-packs/zh.ts +13 -0
  405. package/src/core/version-cut.ts +69 -17
  406. package/src/core/versions.ts +4 -1
  407. package/src/deploy/adapters/node.ts +5 -2
  408. package/src/deploy/adapters/registry.ts +2 -1
  409. package/src/deploy/adapters/types.ts +13 -1
  410. package/src/deploy/artifacts.ts +52 -11
  411. package/src/deploy/cloudflare-negotiation.ts +27 -16
  412. package/src/deploy/headers.ts +75 -55
  413. package/src/deploy/node-headers.ts +148 -27
  414. package/src/deploy/platforms/cloudflare.ts +13 -3
  415. package/src/deploy/platforms/netlify.ts +83 -5
  416. package/src/deploy/platforms/node.ts +8 -5
  417. package/src/deploy/platforms/static.ts +2 -0
  418. package/src/deploy/platforms/types.ts +15 -0
  419. package/src/deploy/platforms/vercel.ts +10 -3
  420. package/src/deploy/redirects.ts +68 -21
  421. package/src/deploy/robots.ts +2 -2
  422. package/src/deploy/rss.ts +4 -3
  423. package/src/deploy/sitemap.ts +7 -5
  424. package/src/deploy/vercel-negotiation.ts +35 -3
  425. package/src/eval/agents.ts +10 -2
  426. package/src/eval/run.ts +25 -0
  427. package/src/markdown/base-links.ts +74 -29
  428. package/src/markdown/directives.ts +242 -36
  429. package/src/markdown/features.ts +17 -0
  430. package/src/markdown/index.ts +13 -9
  431. package/src/markdown/mdast.ts +5 -2
  432. package/src/markdown/relative-links.ts +15 -27
  433. package/src/markdown/route-snapshot.ts +37 -0
  434. package/src/og/card.ts +149 -9
  435. package/src/og/derive.ts +156 -5
  436. package/src/og/index.ts +1 -0
  437. package/src/openapi/asyncapi.ts +4 -2
  438. package/src/openapi/graphql-build.ts +28 -2
  439. package/src/openapi/model.ts +99 -27
  440. package/src/openapi/proxy.ts +63 -10
  441. package/src/openapi/render-mdx.ts +51 -3
  442. package/src/registry/eject.ts +297 -43
  443. package/src/search/adapters/version-scope.ts +30 -0
  444. package/src/search/documents.ts +89 -27
  445. package/src/search/popular.ts +2 -1
  446. package/src/search/sync/algolia.ts +36 -2
  447. package/src/seo/jsonld.ts +7 -3
  448. package/src/sources/registry.ts +5 -0
  449. package/src/theme/entry.ts +11 -4
  450. package/src/translate/agents.ts +6 -1
  451. package/src/translate/ledger.ts +26 -3
  452. package/src/translate/meta.ts +76 -24
  453. package/src/translate/run.ts +14 -8
  454. package/src/translate/validate.ts +14 -2
  455. package/src/translate/work-list.ts +91 -19
  456. package/src/upgrade/upgrade.ts +36 -4
  457. package/dist/cli/chunk-27g6wdth.js.map +0 -10
  458. package/dist/cli/chunk-2hn4b8z7.js.map +0 -12
  459. package/dist/cli/chunk-6crbhc3x.js.map +0 -14
  460. package/dist/cli/chunk-6hsn950k.js.map +0 -10
  461. package/dist/cli/chunk-79jhk4py.js.map +0 -35
  462. package/dist/cli/chunk-82bbrxdn.js +0 -51
  463. package/dist/cli/chunk-82bbrxdn.js.map +0 -10
  464. package/dist/cli/chunk-abh8yjkn.js +0 -31
  465. package/dist/cli/chunk-abh8yjkn.js.map +0 -10
  466. package/dist/cli/chunk-ce574jw2.js +0 -23
  467. package/dist/cli/chunk-ce574jw2.js.map +0 -10
  468. package/dist/cli/chunk-dh8cwk36.js.map +0 -10
  469. package/dist/cli/chunk-epjnccmv.js.map +0 -10
  470. package/dist/cli/chunk-fa25z98p.js.map +0 -11
  471. package/dist/cli/chunk-fs23ddbb.js.map +0 -35
  472. package/dist/cli/chunk-fz5wtpmh.js.map +0 -10
  473. package/dist/cli/chunk-jwyddg7y.js.map +0 -15
  474. package/dist/cli/chunk-kpf8rrjc.js.map +0 -19
  475. package/dist/cli/chunk-m3vmjgmq.js.map +0 -10
  476. package/dist/cli/chunk-mb2919y2.js.map +0 -10
  477. package/dist/cli/chunk-q5163e60.js.map +0 -11
  478. package/dist/cli/chunk-qkqwkpte.js.map +0 -182
  479. package/dist/cli/chunk-qs4q5p4e.js.map +0 -10
  480. package/dist/cli/chunk-s1p84fyh.js.map +0 -10
  481. package/dist/cli/chunk-wgm7m9qk.js.map +0 -36
  482. package/dist/cli/chunk-yt5n7ppj.js.map +0 -10
  483. package/dist/cli/chunk-yw7dm696.js.map +0 -14
  484. /package/dist/cli/{chunk-s6jhgk0q.js.map → chunk-2eytanqx.js.map} +0 -0
  485. /package/dist/cli/{chunk-hdpx1tax.js.map → chunk-2z928egk.js.map} +0 -0
  486. /package/dist/cli/{chunk-ah61y8py.js.map → chunk-364znk6q.js.map} +0 -0
  487. /package/dist/cli/{chunk-vtk4a6dg.js.map → chunk-8ktnccpt.js.map} +0 -0
  488. /package/dist/cli/{chunk-fxypxtvm.js.map → chunk-a58773jm.js.map} +0 -0
  489. /package/dist/cli/{chunk-wm7js3j9.js.map → chunk-b07cmahc.js.map} +0 -0
  490. /package/dist/cli/{chunk-zxcczpyx.js.map → chunk-r20tn01b.js.map} +0 -0
  491. /package/dist/cli/{chunk-5shv93fd.js.map → chunk-tkacnehg.js.map} +0 -0
  492. /package/dist/cli/{chunk-zxh4d9vy.js.map → chunk-tzmab476.js.map} +0 -0
@@ -4,7 +4,9 @@ import { blumeReferences } from "../../openapi/references.ts";
4
4
  import { openApiSource } from "../../openapi/source.ts";
5
5
  import type { ContentSourceAdapter } from "../../sources/registry.ts";
6
6
  import type { ResolvedConfig } from "../schema.ts";
7
+ import { trimChar } from "../trim.ts";
7
8
  import type { ProjectContext } from "../types.ts";
9
+ import { hashText } from "./cache.ts";
8
10
  import { contentfulSource } from "./contentful.ts";
9
11
  import { filesystemSource } from "./filesystem.ts";
10
12
  import { githubReleasesSource } from "./github-releases.ts";
@@ -45,14 +47,40 @@ export interface SourceRuntime {
45
47
  refresh?: boolean;
46
48
  }
47
49
 
50
+ /**
51
+ * The directory under `.blume/cache/<source>/` a source keeps its snapshot in:
52
+ * one per preview mode and set of adapter options. A preview snapshot holds
53
+ * drafts, so a published load must never read it, neither as dev's cache-first
54
+ * snapshot nor as a build's offline fallback; and a snapshot fetched with
55
+ * another `query` or `fields` is another result, not a cached copy of this
56
+ * one. `pollInterval` only paces dev re-fetches, so it is left out. A
57
+ * `custom()` source is a live instance rather than options, so its snapshot
58
+ * is keyed by preview mode alone.
59
+ */
60
+ export const snapshotKey = (
61
+ adapter: ContentSourceAdapter,
62
+ runtime: SourceRuntime
63
+ ): string => {
64
+ const mode = runtime.preview ? "preview" : "published";
65
+ if (adapter.kind === "custom") {
66
+ return mode;
67
+ }
68
+ const { pollInterval: _paced, ...fetched } = adapter.options;
69
+ return `${mode}-${hashText(JSON.stringify(fetched))}`;
70
+ };
71
+
48
72
  const sourceContext = (
49
73
  context: ProjectContext,
50
74
  name: string,
51
- runtime: SourceRuntime
75
+ runtime: SourceRuntime,
76
+ snapshot?: string
52
77
  ): SourceContext => ({
53
78
  assetsBaseUrl: `/blume-assets/${name}`,
54
79
  assetsDir: join(context.outDir, "public", "blume-assets", name),
55
- cacheDir: join(context.outDir, "cache", name),
80
+ cacheDir:
81
+ snapshot === undefined
82
+ ? join(context.outDir, "cache", name)
83
+ : join(context.outDir, "cache", name, snapshot),
56
84
  mode: runtime.mode,
57
85
  preview: runtime.preview,
58
86
  projectRoot: context.root,
@@ -86,46 +114,37 @@ const buildSource = (
86
114
  context: ProjectContext,
87
115
  runtime: SourceRuntime
88
116
  ): ContentSource => {
117
+ const ctx = (): SourceContext =>
118
+ sourceContext(context, name, runtime, snapshotKey(adapter, runtime));
89
119
  switch (adapter.kind) {
90
120
  case "filesystem": {
91
121
  const { pollInterval: _ignored, ...options } = adapter.options;
92
122
  return filesystemSource({ ...options, name, projectRoot: context.root });
93
123
  }
94
124
  case "custom": {
95
- // A user-provided instance manages its own context/caching; we only ensure
96
- // its name is unique across the project for id namespacing.
97
- const source = adapter.options;
125
+ // An instance built by one of Blume's engine factories rebuilds itself
126
+ // on this scan's context, so `custom(sanitySource({…}))` reads drafts
127
+ // under `--preview` and caches in the runtime directory like the
128
+ // built-in adapter. Any other instance manages its own context and
129
+ // caching. Either way its name is made unique across the project for
130
+ // id namespacing.
131
+ const source = adapter.options.withContext?.(ctx()) ?? adapter.options;
98
132
  return source.name === name ? source : { ...source, name };
99
133
  }
100
134
  case "sanity": {
101
- return sanitySource(
102
- { ...adapter.options, name },
103
- sourceContext(context, name, runtime)
104
- );
135
+ return sanitySource({ ...adapter.options, name }, ctx());
105
136
  }
106
137
  case "notion": {
107
- return notionSource(
108
- { ...adapter.options, name },
109
- sourceContext(context, name, runtime)
110
- );
138
+ return notionSource({ ...adapter.options, name }, ctx());
111
139
  }
112
140
  case "contentful": {
113
- return contentfulSource(
114
- { ...adapter.options, name },
115
- sourceContext(context, name, runtime)
116
- );
141
+ return contentfulSource({ ...adapter.options, name }, ctx());
117
142
  }
118
143
  case "payload": {
119
- return payloadSource(
120
- { ...adapter.options, name },
121
- sourceContext(context, name, runtime)
122
- );
144
+ return payloadSource({ ...adapter.options, name }, ctx());
123
145
  }
124
146
  case "strapi": {
125
- return strapiSource(
126
- { ...adapter.options, name },
127
- sourceContext(context, name, runtime)
128
- );
147
+ return strapiSource({ ...adapter.options, name }, ctx());
129
148
  }
130
149
  case "obsidian": {
131
150
  const { pollInterval: _ignored, ...options } = adapter.options;
@@ -139,13 +158,13 @@ const buildSource = (
139
158
  typeFrontmatterKeys: typeFrontmatterKeys(config),
140
159
  versions: config.versions,
141
160
  },
142
- sourceContext(context, name, runtime)
161
+ ctx()
143
162
  );
144
163
  }
145
164
  case "github-releases": {
146
165
  return githubReleasesSource(
147
- { ...adapter.options, name },
148
- sourceContext(context, name, runtime)
166
+ { ...adapter.options, name, site: config.deployment.options.site },
167
+ ctx()
149
168
  );
150
169
  }
151
170
  default: {
@@ -156,10 +175,7 @@ const buildSource = (
156
175
  break;
157
176
  }
158
177
  }
159
- return mdxRemoteSource(
160
- { ...adapter.options, name },
161
- sourceContext(context, name, runtime)
162
- );
178
+ return mdxRemoteSource({ ...adapter.options, name }, ctx());
163
179
  };
164
180
 
165
181
  /** The base name to allocate for a descriptor (before deduplication). */
@@ -167,7 +183,10 @@ const baseName = (adapter: ContentSourceAdapter): string => {
167
183
  if (adapter.kind === "custom") {
168
184
  return adapter.options.name;
169
185
  }
170
- return adapter.options.prefix ?? adapter.kind;
186
+ // The name is the prefix as a route spells it: `/guides` and `guides/`
187
+ // route under `guides`, so the source's staged entry ids, cache directory,
188
+ // and asset URLs must use `guides` too.
189
+ return trimChar(adapter.options.prefix ?? "", "/") || adapter.kind;
171
190
  };
172
191
 
173
192
  /**
@@ -247,5 +247,6 @@ export const sanitySource = (
247
247
  () => load()
248
248
  )
249
249
  : undefined,
250
+ withContext: (next) => sanitySource(options, next),
250
251
  };
251
252
  };
@@ -5,16 +5,18 @@
5
5
  */
6
6
  import type { JsonObject, JsonValue } from "./json.ts";
7
7
  import { asNumber, asObject, asString, objectsIn } from "./json.ts";
8
+ import type { InlinePart } from "./lower.ts";
8
9
  import {
9
10
  absoluteUrl,
10
11
  blockquote,
11
12
  codeFence,
13
+ guardBlockStart,
12
14
  headingPrefix,
13
15
  image,
16
+ linkParts,
14
17
  listItem,
15
18
  markdownDocument,
16
19
  renderInline,
17
- renderLink,
18
20
  unsupported,
19
21
  } from "./lower.ts";
20
22
 
@@ -27,37 +29,44 @@ const children = (node: JsonObject): JsonObject[] => objectsIn(node.children);
27
29
 
28
30
  const typeOf = (node: JsonObject): string => asString(node.type) ?? "";
29
31
 
30
- const renderInlines = (nodes: JsonObject[]): string =>
31
- nodes
32
- // oxlint-disable-next-line no-use-before-define -- mutual recursion: a link's label is itself inline content
33
- .map((node) => renderInlineNode(node))
34
- .join("");
32
+ const inlineParts = (nodes: JsonObject[]): InlinePart[] =>
33
+ // oxlint-disable-next-line no-use-before-define -- mutual recursion: a link's label is itself inline content
34
+ nodes.flatMap((node) => inlineNodeParts(node));
35
35
 
36
- const renderInlineNode = (node: JsonObject): string => {
36
+ const inlineNodeParts = (node: JsonObject): InlinePart[] => {
37
37
  switch (typeOf(node)) {
38
38
  case "text": {
39
- return renderInline(asString(node.text) ?? "", {
40
- bold: node.bold === true,
41
- code: node.code === true,
42
- italic: node.italic === true,
43
- strike: node.strikethrough === true,
44
- });
39
+ return [
40
+ {
41
+ marks: {
42
+ bold: node.bold === true,
43
+ code: node.code === true,
44
+ italic: node.italic === true,
45
+ strike: node.strikethrough === true,
46
+ },
47
+ text: asString(node.text) ?? "",
48
+ },
49
+ ];
45
50
  }
46
51
  case "link": {
47
- return renderLink(renderInlines(children(node)), asString(node.url));
52
+ return linkParts(inlineParts(children(node)), asString(node.url));
48
53
  }
49
54
  default: {
50
- return renderInlines(children(node));
55
+ return inlineParts(children(node));
51
56
  }
52
57
  }
53
58
  };
54
59
 
60
+ /** A text block's inline nodes, joined and guarded as one block. */
61
+ const blockText = (nodes: JsonObject[]): string =>
62
+ guardBlockStart(renderInline(inlineParts(nodes)));
63
+
55
64
  const renderList = (node: JsonObject): string => {
56
65
  const ordered = asString(node.format) === "ordered";
57
66
  return children(node)
58
67
  .map((item, index) => {
59
68
  const kids = children(item);
60
- const line = renderInlines(kids.filter((kid) => typeOf(kid) !== "list"));
69
+ const line = blockText(kids.filter((kid) => typeOf(kid) !== "list"));
61
70
  const sub = kids
62
71
  .filter((kid) => typeOf(kid) === "list")
63
72
  .map((list) => renderList(list))
@@ -89,13 +98,13 @@ const renderBlock = (
89
98
  ): string => {
90
99
  switch (typeOf(node)) {
91
100
  case "paragraph": {
92
- return renderInlines(children(node));
101
+ return blockText(children(node));
93
102
  }
94
103
  case "heading": {
95
- return `${headingPrefix(asNumber(node.level) ?? 1)}${renderInlines(children(node))}`;
104
+ return `${headingPrefix(asNumber(node.level) ?? 1)}${blockText(children(node))}`;
96
105
  }
97
106
  case "quote": {
98
- return blockquote(renderInlines(children(node)));
107
+ return blockquote(blockText(children(node)));
99
108
  }
100
109
  case "list": {
101
110
  return renderList(node);
@@ -185,6 +185,7 @@ export const strapiSource = (
185
185
  name: options.name,
186
186
  pollInterval: options.pollInterval,
187
187
  prefix: options.prefix,
188
+ withContext: (next) => strapiSource(options, next),
188
189
  },
189
190
  ctx
190
191
  );
@@ -39,6 +39,13 @@ export interface SourceEntry {
39
39
  * the owning source to expose a `contentRoot` to bound the log's pathspec.
40
40
  */
41
41
  sourcePath?: string;
42
+ /**
43
+ * How many lines of the file at `sourcePath` sit above `body.text`, when
44
+ * `raw` is not that file's text: a source that rewrites a local file's
45
+ * front matter (an Obsidian note) sets it, so a diagnostic points at the
46
+ * line the author wrote. Otherwise the height of `raw`'s front matter.
47
+ */
48
+ bodyLineOffset?: number;
42
49
  /** Optional provenance for "edit this page". */
43
50
  editUrl?: string;
44
51
  /** Optional last-modified ISO date supplied by the adapter (non-filesystem). */
@@ -123,6 +130,14 @@ export interface ContentSource {
123
130
  * switcher, since every other locale would only repeat the same text.
124
131
  */
125
132
  readonly monolingual?: boolean;
133
+ /**
134
+ * True for a staged source whose entry refs are file and folder names (an
135
+ * Obsidian vault), so their ordering prefixes (`01 Intro`) sort the sidebar
136
+ * and drop from the route the way a filesystem source's do. Filesystem
137
+ * sources always do; other staged refs are slugs and release tags, kept
138
+ * whole.
139
+ */
140
+ readonly orderedNames?: boolean;
126
141
  /**
127
142
  * Resolved on-disk root, set by sources whose entries live on disk. For
128
143
  * filesystem sources it drives folder-meta discovery (scan under this root)
@@ -132,6 +147,13 @@ export interface ContentSource {
132
147
  * no local tree.
133
148
  */
134
149
  readonly contentRoot?: string;
150
+ /**
151
+ * The globs a filesystem source reads under `contentRoot`, and the ones it
152
+ * skips. Folder-meta discovery honors them, so a `meta.ts` outside the
153
+ * content the source reads is never imported.
154
+ */
155
+ readonly include?: readonly string[];
156
+ readonly exclude?: readonly string[];
135
157
  /** Pull every entry. Called once per scan. */
136
158
  load: () => Promise<SourceLoadResult>;
137
159
  /** Validate the source is usable; throws a BlumeError when not. */
@@ -143,6 +165,14 @@ export interface ContentSource {
143
165
  * remote/static sources omit it (content is frozen for the session).
144
166
  */
145
167
  watch?: (onChange: () => void) => () => void;
168
+ /**
169
+ * This source rebuilt on another runtime context. A source passed to
170
+ * `custom()` is constructed before Blume knows the scan's preview flag,
171
+ * refresh policy, or runtime directory; Blume rebuilds it on them through
172
+ * this, so it previews and caches the way the built-in adapter does. The
173
+ * engine factories (`sanitySource`, `contentfulSource`, …) all set it.
174
+ */
175
+ withContext?: (ctx: SourceContext) => ContentSource;
146
176
  }
147
177
 
148
178
  /** Context passed to `normalizeEntry`, describing the owning source. */
@@ -150,6 +180,7 @@ export interface NormalizeContext {
150
180
  source: {
151
181
  monolingual?: boolean;
152
182
  name: string;
183
+ orderedNames?: boolean;
153
184
  prefix?: string;
154
185
  staged: boolean;
155
186
  };
@@ -51,18 +51,26 @@ export const baselineScanIgnore = (): string[] =>
51
51
  */
52
52
  export const BLUME_WATCH_IGNORE_DIRS = BLUME_IGNORE_DIRS;
53
53
 
54
- /** Extract single-segment ignore dirs (`foo`) from `foo/**`-style excludes. */
54
+ /**
55
+ * Extract root-anchored ignore dirs (`/foo`) from `foo/**`-style excludes. The
56
+ * scan's glob `foo/**` matches `foo` at the source root only, so the watcher
57
+ * skips that one directory: a nested `guides/foo/` is still content, and an
58
+ * edit there must still reload.
59
+ */
55
60
  export const excludeDirSegments = (patterns: readonly string[]): string[] =>
56
61
  patterns
57
62
  .map((pattern) => /^(?<dir>[^*/]+)\/\*\*$/u.exec(pattern)?.groups?.dir)
58
- .filter((dir): dir is string => dir !== undefined);
63
+ .filter((dir): dir is string => dir !== undefined)
64
+ .map((dir) => `/${dir}`);
59
65
 
60
66
  /**
61
67
  * Build a recursive-watch listener that fires `onChange` for content changes but
62
- * ignores events whose path crosses an ignored directory segment — one in
63
- * `ignoreDirs`, or one `ignoreSegment` rejects, for a scan whose skip rule is
64
- * a shape (every dot-name) rather than a list. A missing `filename` — rare;
65
- * the platform couldn't name the changed path — falls through to `onChange`
68
+ * ignores events whose path crosses an ignored directory — a segment named in
69
+ * `ignoreDirs` at any depth, or one `ignoreSegment` rejects, for a scan whose
70
+ * skip rule is a shape (every dot-name) rather than a list. An entry written
71
+ * with a leading slash (`/drafts`, see {@link excludeDirSegments}) names a
72
+ * directory at the watched root only. A missing `filename` — rare; the
73
+ * platform couldn't name the changed path — falls through to `onChange`
66
74
  * rather than silently dropping a real edit. Exported for testing.
67
75
  */
68
76
  export const ignoringWatchListener = (
@@ -76,7 +84,12 @@ export const ignoringWatchListener = (
76
84
  filename !== null &&
77
85
  filename
78
86
  .split(/[/\\]/u)
79
- .some((segment) => ignore.has(segment) || ignoreSegment(segment))
87
+ .some(
88
+ (segment, index) =>
89
+ ignore.has(segment) ||
90
+ (index === 0 && ignore.has(`/${segment}`)) ||
91
+ ignoreSegment(segment)
92
+ )
80
93
  ) {
81
94
  return;
82
95
  }
@@ -50,11 +50,15 @@ export interface StandardSchema<Input = unknown, Output = Input> {
50
50
  * Whether a config-supplied value implements the `~standard` contract. Generic
51
51
  * so it can decode any input at the config boundary (`z.custom` hands it the
52
52
  * raw config value) while narrowing whatever type the caller holds.
53
+ *
54
+ * The contract is the `~standard` property, whatever carries it: Zod and
55
+ * Valibot schemas are objects, but an ArkType type is a callable function. The
56
+ * optional-chained probe reads the property off either, and off `null`,
57
+ * `undefined`, or a primitive it finds nothing.
53
58
  */
54
59
  export const isStandardSchema = <T>(value: T): value is T & StandardSchema =>
55
- typeof value === "object" &&
56
- value !== null &&
57
- // SAFETY: the assertion only widens the checked object for property probing;
58
- // the trailing typeof check is what verifies `~standard.validate` exists.
59
- typeof (value as { "~standard"?: { validate?: unknown } })["~standard"]
60
- ?.validate === "function";
60
+ // SAFETY: the assertion only widens the value for property probing; the
61
+ // typeof check is what verifies `~standard.validate` exists.
62
+ typeof (
63
+ value as { "~standard"?: { validate?: unknown } } | null | undefined
64
+ )?.["~standard"]?.validate === "function";
package/src/core/types.ts CHANGED
@@ -325,6 +325,13 @@ export interface Navigation {
325
325
  * locale trees.
326
326
  */
327
327
  brandHref?: string;
328
+ /**
329
+ * Where the banner's link points in this locale: `banner.link.href`
330
+ * localized like a featured link, then mounted under `basePath` (a route
331
+ * served outside the content tree keeps its own path). Set when the banner
332
+ * has a link.
333
+ */
334
+ bannerHref?: string;
328
335
  }
329
336
 
330
337
  /** The full content graph: the source of truth for generated modules. */
@@ -413,6 +420,8 @@ export interface RouteManifestEntry {
413
420
  fallback?: boolean;
414
421
  /** True when the page's source publishes one language only (no switcher). */
415
422
  monolingual?: boolean;
423
+ /** True when front matter `ai.exclude` keeps the page out of llms.txt. */
424
+ aiExclude?: boolean;
416
425
  /** Resolved "last updated" ISO date, when the feature is enabled. */
417
426
  lastModified?: string;
418
427
  }
@@ -43,9 +43,20 @@ export const ar: UIStringsOverride = {
43
43
  title: "سجل التغييرات",
44
44
  },
45
45
  content: {
46
+ code: "الكود",
46
47
  copyColor: "نسخ اللون {name} {value}",
47
48
  copyPrompt: "نسخ الموجّه",
49
+ default: "الافتراضي",
48
50
  diagramError: "تعذّر عرض هذا المخطط.",
51
+ forks: "التفرعات",
52
+ preview: "معاينة",
53
+ prop: "الخاصية",
54
+ selectTab: "اختيار علامة تبويب",
55
+ showMore: "عرض المزيد",
56
+ stars: "النجوم",
57
+ tab: "علامة التبويب {n}",
58
+ type: "النوع",
59
+ update: "تحديث",
49
60
  },
50
61
  feedback: {
51
62
  no: "لا",
@@ -87,8 +98,10 @@ export const ar: UIStringsOverride = {
87
98
  assistantHint: "احصل على إجابة فورية من الذكاء الاصطناعي",
88
99
  button: "بحث",
89
100
  devOnly: "البحث متاح في إصدار الإنتاج.",
101
+ docs: "الوثائق",
90
102
  error: "حدث خطأ ما. يرجى المحاولة مرة أخرى.",
91
103
  label: "البحث في الوثائق",
104
+ latest: "الأحدث",
92
105
  navigate: "تنقل",
93
106
  noResults: "لم يتم العثور على نتائج.",
94
107
  open: "فتح",
@@ -44,9 +44,20 @@ export const bg: UIStringsOverride = {
44
44
  title: "Дневник на промените",
45
45
  },
46
46
  content: {
47
+ code: "Код",
47
48
  copyColor: "Копирай цвета {name} {value}",
48
49
  copyPrompt: "Копирай подканата",
50
+ default: "По подразбиране",
49
51
  diagramError: "Тази диаграма не можа да бъде показана.",
52
+ forks: "Разклонения",
53
+ preview: "Преглед",
54
+ prop: "Свойство",
55
+ selectTab: "Избери раздел",
56
+ showMore: "Покажи още",
57
+ stars: "Звезди",
58
+ tab: "Раздел {n}",
59
+ type: "Тип",
60
+ update: "Актуализация",
50
61
  },
51
62
  feedback: {
52
63
  no: "Не",
@@ -88,8 +99,10 @@ export const bg: UIStringsOverride = {
88
99
  assistantHint: "Получете незабавен отговор от ИИ",
89
100
  button: "Търсене",
90
101
  devOnly: "Търсенето е достъпно в производствената компилация.",
102
+ docs: "Документация",
91
103
  error: "Нещо се обърка. Моля, опитайте отново.",
92
104
  label: "Търсене в документацията",
105
+ latest: "най-нова",
93
106
  navigate: "навигация",
94
107
  noResults: "Няма намерени резултати.",
95
108
  open: "отвори",
@@ -43,9 +43,20 @@ export const bn: UIStringsOverride = {
43
43
  title: "পরিবর্তন লগ",
44
44
  },
45
45
  content: {
46
+ code: "কোড",
46
47
  copyColor: "{name} রং {value} অনুলিপি করুন",
47
48
  copyPrompt: "প্রম্পট অনুলিপি করুন",
49
+ default: "ডিফল্ট",
48
50
  diagramError: "এই ডায়াগ্রামটি রেন্ডার করা যায়নি।",
51
+ forks: "ফর্ক",
52
+ preview: "প্রিভিউ",
53
+ prop: "প্রপ",
54
+ selectTab: "ট্যাব নির্বাচন করুন",
55
+ showMore: "আরও দেখান",
56
+ stars: "স্টার",
57
+ tab: "ট্যাব {n}",
58
+ type: "টাইপ",
59
+ update: "আপডেট",
49
60
  },
50
61
  feedback: {
51
62
  no: "না",
@@ -87,8 +98,10 @@ export const bn: UIStringsOverride = {
87
98
  assistantHint: "AI থেকে তাৎক্ষণিক উত্তর পান",
88
99
  button: "অনুসন্ধান",
89
100
  devOnly: "অনুসন্ধান প্রোডাকশন বিল্ডে উপলব্ধ।",
101
+ docs: "ডকুমেন্টেশন",
90
102
  error: "কিছু একটা ভুল হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।",
91
103
  label: "ডকুমেন্টেশন অনুসন্ধান করুন",
104
+ latest: "সর্বশেষ",
92
105
  navigate: "নেভিগেট",
93
106
  noResults: "কোনো ফলাফল পাওয়া যায়নি।",
94
107
  open: "খুলুন",
@@ -44,9 +44,20 @@ export const ca: UIStringsOverride = {
44
44
  title: "Registre de canvis",
45
45
  },
46
46
  content: {
47
+ code: "Codi",
47
48
  copyColor: "Copia el color {name} {value}",
48
49
  copyPrompt: "Copia la indicació",
50
+ default: "Per defecte",
49
51
  diagramError: "No s'ha pogut mostrar aquest diagrama.",
52
+ forks: "Forks",
53
+ preview: "Previsualització",
54
+ prop: "Propietat",
55
+ selectTab: "Selecciona una pestanya",
56
+ showMore: "Mostra'n més",
57
+ stars: "Estrelles",
58
+ tab: "Pestanya {n}",
59
+ type: "Tipus",
60
+ update: "Actualització",
50
61
  },
51
62
  feedback: {
52
63
  no: "No",
@@ -88,8 +99,10 @@ export const ca: UIStringsOverride = {
88
99
  assistantHint: "Obtén una resposta instantània de la IA",
89
100
  button: "Cerca",
90
101
  devOnly: "La cerca està disponible a la compilació de producció.",
102
+ docs: "Documentació",
91
103
  error: "Alguna cosa ha anat malament. Torna-ho a provar.",
92
104
  label: "Cerca a la documentació",
105
+ latest: "darrera",
93
106
  navigate: "navega",
94
107
  noResults: "No s'ha trobat cap resultat.",
95
108
  open: "obre",
@@ -43,9 +43,20 @@ export const cs: UIStringsOverride = {
43
43
  title: "Seznam změn",
44
44
  },
45
45
  content: {
46
+ code: "Kód",
46
47
  copyColor: "Kopírovat barvu {name} {value}",
47
48
  copyPrompt: "Kopírovat prompt",
49
+ default: "Výchozí",
48
50
  diagramError: "Tento diagram se nepodařilo vykreslit.",
51
+ forks: "Forky",
52
+ preview: "Náhled",
53
+ prop: "Vlastnost",
54
+ selectTab: "Vybrat kartu",
55
+ showMore: "Zobrazit více",
56
+ stars: "Hvězdy",
57
+ tab: "Karta {n}",
58
+ type: "Typ",
59
+ update: "Aktualizace",
49
60
  },
50
61
  feedback: {
51
62
  no: "Ne",
@@ -87,8 +98,10 @@ export const cs: UIStringsOverride = {
87
98
  assistantHint: "Získejte okamžitou odpověď od AI",
88
99
  button: "Hledat",
89
100
  devOnly: "Vyhledávání je dostupné v produkčním buildu.",
101
+ docs: "Dokumentace",
90
102
  error: "Něco se pokazilo. Zkuste to prosím znovu.",
91
103
  label: "Prohledat dokumentaci",
104
+ latest: "nejnovější",
92
105
  navigate: "navigace",
93
106
  noResults: "Nebyly nalezeny žádné výsledky.",
94
107
  open: "otevřít",
@@ -43,9 +43,20 @@ export const da: UIStringsOverride = {
43
43
  title: "Ændringslog",
44
44
  },
45
45
  content: {
46
+ code: "Kode",
46
47
  copyColor: "Kopiér farven {name} {value}",
47
48
  copyPrompt: "Kopiér prompt",
49
+ default: "Standard",
48
50
  diagramError: "Dette diagram kunne ikke vises.",
51
+ forks: "Forks",
52
+ preview: "Forhåndsvisning",
53
+ prop: "Egenskab",
54
+ selectTab: "Vælg fane",
55
+ showMore: "Vis mere",
56
+ stars: "Stjerner",
57
+ tab: "Fane {n}",
58
+ type: "Type",
59
+ update: "Opdatering",
49
60
  },
50
61
  feedback: {
51
62
  no: "Nej",
@@ -87,8 +98,10 @@ export const da: UIStringsOverride = {
87
98
  assistantHint: "Få et øjeblikkeligt svar fra AI",
88
99
  button: "Søg",
89
100
  devOnly: "Søgning er tilgængelig i produktionsbygningen.",
101
+ docs: "Dokumentation",
90
102
  error: "Noget gik galt. Prøv igen.",
91
103
  label: "Søg i dokumentationen",
104
+ latest: "nyeste",
92
105
  navigate: "navigér",
93
106
  noResults: "Ingen resultater fundet.",
94
107
  open: "åbn",
@@ -44,9 +44,20 @@ export const de: UIStringsOverride = {
44
44
  title: "Änderungsprotokoll",
45
45
  },
46
46
  content: {
47
+ code: "Code",
47
48
  copyColor: "Farbe {name} {value} kopieren",
48
49
  copyPrompt: "Prompt kopieren",
50
+ default: "Standard",
49
51
  diagramError: "Dieses Diagramm konnte nicht dargestellt werden.",
52
+ forks: "Forks",
53
+ preview: "Vorschau",
54
+ prop: "Eigenschaft",
55
+ selectTab: "Tab auswählen",
56
+ showMore: "Mehr anzeigen",
57
+ stars: "Sterne",
58
+ tab: "Tab {n}",
59
+ type: "Typ",
60
+ update: "Update",
50
61
  },
51
62
  feedback: {
52
63
  no: "Nein",
@@ -88,8 +99,10 @@ export const de: UIStringsOverride = {
88
99
  assistantHint: "Erhalte sofort eine Antwort von der KI",
89
100
  button: "Suchen",
90
101
  devOnly: "Die Suche ist im Produktions-Build verfügbar.",
102
+ docs: "Dokumentation",
91
103
  error: "Etwas ist schiefgelaufen. Bitte versuche es erneut.",
92
104
  label: "Dokumentation durchsuchen",
105
+ latest: "neueste",
93
106
  navigate: "navigieren",
94
107
  noResults: "Keine Ergebnisse gefunden.",
95
108
  open: "öffnen",