blume 2.1.3 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +126 -0
  3. package/README.md +4 -4
  4. package/dist/cli/{chunk-74wfhv79.js → chunk-05f21r8h.js} +1 -1
  5. package/dist/cli/{chunk-9qzgg6mj.js → chunk-1cm0h819.js} +3 -3
  6. package/dist/cli/{chunk-nbyvgnnm.js → chunk-1rkxzg3n.js} +104 -47
  7. package/dist/cli/chunk-1rkxzg3n.js.map +36 -0
  8. package/dist/cli/{chunk-desvm72z.js → chunk-2nr29y95.js} +22 -26
  9. package/dist/cli/chunk-2nr29y95.js.map +13 -0
  10. package/dist/cli/{chunk-32khwcb6.js → chunk-49r370mb.js} +42 -69
  11. package/dist/cli/{chunk-32khwcb6.js.map → chunk-49r370mb.js.map} +9 -10
  12. package/dist/cli/{chunk-ms9z66nz.js → chunk-4rftmttv.js} +2 -2
  13. package/dist/cli/{chunk-s0bdnc7v.js → chunk-79bzzkx4.js} +5 -4
  14. package/dist/cli/chunk-79bzzkx4.js.map +10 -0
  15. package/dist/cli/{chunk-hvcxng5f.js → chunk-7tekknev.js} +6 -6
  16. package/dist/cli/{chunk-dv2z0rzf.js → chunk-8b489v1b.js} +38 -13
  17. package/dist/cli/{chunk-dv2z0rzf.js.map → chunk-8b489v1b.js.map} +5 -4
  18. package/dist/cli/{chunk-0pmb4tr4.js → chunk-8f8xw4x2.js} +1195 -222
  19. package/dist/cli/chunk-8f8xw4x2.js.map +44 -0
  20. package/dist/cli/chunk-96snx8yy.js +329 -0
  21. package/dist/cli/chunk-96snx8yy.js.map +13 -0
  22. package/dist/cli/{chunk-ckrcm08h.js → chunk-a3ydrqny.js} +48 -62
  23. package/dist/cli/{chunk-ckrcm08h.js.map → chunk-a3ydrqny.js.map} +4 -5
  24. package/dist/cli/{chunk-bxwhtvw8.js → chunk-ahc5gc9h.js} +5 -5
  25. package/dist/cli/{chunk-dpy8qdjf.js → chunk-as09pafp.js} +73 -182
  26. package/dist/cli/chunk-as09pafp.js.map +18 -0
  27. package/dist/cli/{chunk-tfycddbt.js → chunk-bjk964fp.js} +2 -2
  28. package/dist/cli/{chunk-gfc5fqvf.js → chunk-br0n8n3e.js} +18 -18
  29. package/dist/cli/{chunk-gfc5fqvf.js.map → chunk-br0n8n3e.js.map} +1 -1
  30. package/dist/cli/{chunk-297ajdcv.js → chunk-c69tw29j.js} +6 -6
  31. package/dist/cli/{chunk-297ajdcv.js.map → chunk-c69tw29j.js.map} +3 -3
  32. package/dist/cli/chunk-cn3dy3hz.js +146 -0
  33. package/dist/cli/chunk-cn3dy3hz.js.map +11 -0
  34. package/dist/cli/{chunk-124fvmzq.js → chunk-dm4mg9bj.js} +11064 -8742
  35. package/dist/cli/{chunk-124fvmzq.js.map → chunk-dm4mg9bj.js.map} +78 -64
  36. package/dist/cli/{chunk-dqhg54mr.js → chunk-dmx6cezx.js} +1 -1
  37. package/dist/cli/{chunk-60hz265r.js → chunk-dpcahcrb.js} +24 -11
  38. package/dist/cli/chunk-dpcahcrb.js.map +10 -0
  39. package/dist/cli/{chunk-a57yh0h9.js → chunk-dyk3r7jw.js} +7 -7
  40. package/dist/cli/{chunk-a57yh0h9.js.map → chunk-dyk3r7jw.js.map} +1 -1
  41. package/dist/cli/{chunk-twy7psdz.js → chunk-enk76qd5.js} +14 -10
  42. package/dist/cli/chunk-enk76qd5.js.map +10 -0
  43. package/dist/cli/{chunk-k3gr1nm9.js → chunk-fqy4n3q2.js} +13 -16
  44. package/dist/cli/{chunk-k3gr1nm9.js.map → chunk-fqy4n3q2.js.map} +3 -3
  45. package/dist/cli/{chunk-sc93apfs.js → chunk-frk2wdq1.js} +17 -17
  46. package/dist/cli/{chunk-sc93apfs.js.map → chunk-frk2wdq1.js.map} +2 -2
  47. package/dist/cli/{chunk-kdpzw38a.js → chunk-gprwej7h.js} +95 -7
  48. package/dist/cli/chunk-gprwej7h.js.map +11 -0
  49. package/dist/cli/chunk-kkrteb15.js +157 -0
  50. package/dist/cli/chunk-kkrteb15.js.map +10 -0
  51. package/dist/cli/{chunk-ave1wcbr.js → chunk-m9bp2hc1.js} +1 -1
  52. package/dist/cli/{chunk-58bt3hag.js → chunk-mrvh4c88.js} +4 -4
  53. package/dist/cli/{chunk-5cmts6dv.js → chunk-p8zg3a2h.js} +7 -7
  54. package/dist/cli/{chunk-5cmts6dv.js.map → chunk-p8zg3a2h.js.map} +1 -1
  55. package/dist/cli/{chunk-0w6hs479.js → chunk-rkqae7kh.js} +30 -18
  56. package/dist/cli/chunk-rkqae7kh.js.map +10 -0
  57. package/dist/cli/{chunk-bqxaqn5p.js → chunk-t5xx74rd.js} +8 -8
  58. package/dist/cli/{chunk-bqxaqn5p.js.map → chunk-t5xx74rd.js.map} +1 -1
  59. package/dist/cli/{chunk-1f882900.js → chunk-th0pgaj5.js} +2 -2
  60. package/dist/cli/{chunk-dhwtqnnd.js → chunk-vnbvhgmd.js} +2 -2
  61. package/dist/cli/{chunk-gxtg6ed2.js → chunk-vzy9rh6y.js} +21 -21
  62. package/dist/cli/{chunk-gxtg6ed2.js.map → chunk-vzy9rh6y.js.map} +3 -3
  63. package/dist/cli/{chunk-j1x92mx9.js → chunk-w6e455pz.js} +1 -1
  64. package/dist/cli/chunk-wehv26ry.js +155 -0
  65. package/dist/cli/chunk-wehv26ry.js.map +11 -0
  66. package/dist/cli/{chunk-y4msrwm9.js → chunk-xgq4eytj.js} +15 -15
  67. package/dist/cli/{chunk-36bxs9c7.js → chunk-xt0qvz1t.js} +27 -23
  68. package/dist/cli/chunk-xt0qvz1t.js.map +10 -0
  69. package/dist/cli/index.js +78 -42
  70. package/dist/cli/index.js.map +7 -6
  71. package/dist/types/ai/changelog-components.d.ts +18 -0
  72. package/dist/types/ai/changelog-markdown.d.ts +12 -0
  73. package/dist/types/ai/openapi-components.d.ts +7 -7
  74. package/dist/types/ai/operation-details.d.ts +39 -0
  75. package/dist/types/ai/relative-links.d.ts +3 -1
  76. package/dist/types/ai/serializers.d.ts +6 -4
  77. package/dist/types/analytics/head.d.ts +4 -2
  78. package/dist/types/analytics/script.d.ts +8 -2
  79. package/dist/types/components/content/youtube.d.ts +20 -0
  80. package/dist/types/components/layout/nav-utils.d.ts +8 -0
  81. package/dist/types/components/openapi/example-panels.d.ts +33 -0
  82. package/dist/types/components/openapi/helpers.d.ts +53 -11
  83. package/dist/types/components/openapi/snippets.d.ts +7 -1
  84. package/dist/types/core/alert-diagnostics.d.ts +10 -0
  85. package/dist/types/core/builtin-tags.d.ts +16 -0
  86. package/dist/types/core/changelog-list.d.ts +48 -0
  87. package/dist/types/core/closest-match.d.ts +6 -0
  88. package/dist/types/core/code-fence-diagnostics.d.ts +18 -0
  89. package/dist/types/core/code-fences.d.ts +8 -1
  90. package/dist/types/core/config-input.d.ts +1 -1
  91. package/dist/types/core/content-assets.d.ts +16 -18
  92. package/dist/types/core/diagnostics.d.ts +14 -0
  93. package/dist/types/core/directive-diagnostics.d.ts +22 -8
  94. package/dist/types/core/former-routes.d.ts +14 -0
  95. package/dist/types/core/github.d.ts +5 -4
  96. package/dist/types/core/heading-markers.d.ts +65 -2
  97. package/dist/types/core/hidden-pages.d.ts +3 -0
  98. package/dist/types/core/includes.d.ts +23 -0
  99. package/dist/types/core/last-modified.d.ts +18 -6
  100. package/dist/types/core/links.d.ts +42 -2
  101. package/dist/types/core/load-module.d.ts +19 -4
  102. package/dist/types/core/manifest.d.ts +14 -1
  103. package/dist/types/core/markdown-mirrors.d.ts +22 -0
  104. package/dist/types/core/mdx-elements.d.ts +32 -0
  105. package/dist/types/core/mdx-syntax.d.ts +100 -0
  106. package/dist/types/core/meta-diagnostics.d.ts +7 -0
  107. package/dist/types/core/meta.d.ts +32 -5
  108. package/dist/types/core/nav-diagnostics.d.ts +9 -2
  109. package/dist/types/core/navigation.d.ts +13 -0
  110. package/dist/types/core/ordering-prefix.d.ts +6 -0
  111. package/dist/types/core/pinned-ids.d.ts +23 -0
  112. package/dist/types/core/project-graph.d.ts +9 -1
  113. package/dist/types/core/redirect-patterns.d.ts +18 -0
  114. package/dist/types/core/relative-files.d.ts +31 -0
  115. package/dist/types/core/schema.d.ts +267 -7
  116. package/dist/types/core/sources/normalize.d.ts +101 -9
  117. package/dist/types/core/sources/types.d.ts +16 -0
  118. package/dist/types/core/static-files.d.ts +10 -0
  119. package/dist/types/core/static-host.d.ts +42 -0
  120. package/dist/types/core/svg-images.d.ts +26 -0
  121. package/dist/types/core/syntax-diagnostics.d.ts +14 -0
  122. package/dist/types/core/types.d.ts +42 -1
  123. package/dist/types/deploy/generated-files.d.ts +41 -0
  124. package/dist/types/deploy/redirects.d.ts +21 -7
  125. package/dist/types/markdown/code-title.d.ts +9 -5
  126. package/dist/types/markdown/directives.d.ts +8 -0
  127. package/dist/types/markdown/fence-language.d.ts +51 -0
  128. package/dist/types/markdown/fence-meta.d.ts +5 -0
  129. package/dist/types/markdown/github-alerts.d.ts +35 -0
  130. package/dist/types/openapi/asyncapi.d.ts +6 -5
  131. package/dist/types/openapi/checks.d.ts +10 -5
  132. package/dist/types/openapi/model.d.ts +55 -8
  133. package/dist/types/openapi/parse.d.ts +4 -1
  134. package/dist/types/sources/filesystem.d.ts +14 -4
  135. package/dist/types/sources/mdx-remote.d.ts +6 -3
  136. package/dist/types/sources/registry.d.ts +3 -3
  137. package/dist/types/theme/color.d.ts +33 -0
  138. package/dist/types/theme/palette.d.ts +122 -0
  139. package/docs/01-quickstart.mdx +1 -1
  140. package/docs/02-deployment.mdx +23 -8
  141. package/docs/04-migrating.mdx +16 -4
  142. package/docs/advanced/changelog.mdx +27 -1
  143. package/docs/advanced/skills.mdx +1 -1
  144. package/docs/cli/audit.mdx +1 -1
  145. package/docs/cli/doctor.mdx +2 -2
  146. package/docs/cli/evals.mdx +1 -1
  147. package/docs/cli/index.mdx +4 -2
  148. package/docs/cli/validate.mdx +10 -7
  149. package/docs/configuration/analytics.mdx +2 -0
  150. package/docs/configuration/customization.mdx +3 -1
  151. package/docs/configuration/index.mdx +2 -2
  152. package/docs/configuration/theming.mdx +5 -1
  153. package/docs/content/components.mdx +26 -6
  154. package/docs/content/frontmatter.mdx +1 -1
  155. package/docs/content/includes.mdx +6 -2
  156. package/docs/content/index.mdx +11 -1
  157. package/docs/content/islands.mdx +2 -0
  158. package/docs/content/meta.mdx +9 -3
  159. package/docs/content/navigation.mdx +14 -6
  160. package/docs/content/sources/obsidian.mdx +1 -1
  161. package/docs/content/sources/remote-mdx.mdx +3 -1
  162. package/docs/content/syntax.mdx +76 -8
  163. package/docs/content/variables.mdx +3 -1
  164. package/docs/discoverability/agent-discovery.mdx +1 -1
  165. package/docs/discoverability/json-api.mdx +1 -1
  166. package/docs/discoverability/llms-txt.mdx +1 -1
  167. package/docs/discoverability/markdown.mdx +2 -2
  168. package/docs/discoverability/open-graph.mdx +1 -1
  169. package/docs/discoverability/sitemap-and-robots.mdx +1 -1
  170. package/docs/references/graphql.mdx +2 -0
  171. package/docs/references/openapi.mdx +45 -7
  172. package/package.json +4 -4
  173. package/skills/blume/SKILL.md +2 -2
  174. package/skills/blume-migrate/SKILL.md +49 -27
  175. package/skills/blume-migrate/references/docsify.md +262 -0
  176. package/skills/blume-migrate/references/docus.md +298 -0
  177. package/skills/blume-migrate/references/docusaurus.md +3 -3
  178. package/skills/blume-migrate/references/fern.md +327 -0
  179. package/skills/blume-migrate/references/fumadocs.md +1 -1
  180. package/skills/blume-migrate/references/gitbook.md +267 -0
  181. package/skills/blume-migrate/references/github-wiki.md +259 -0
  182. package/skills/blume-migrate/references/jekyll.md +253 -0
  183. package/skills/blume-migrate/references/mdbook.md +256 -0
  184. package/skills/blume-migrate/references/mintlify.md +5 -5
  185. package/skills/blume-migrate/references/mkdocs.md +236 -0
  186. package/skills/blume-migrate/references/monorepo.md +20 -8
  187. package/skills/blume-migrate/references/nextra.md +2 -2
  188. package/skills/blume-migrate/references/readme.md +257 -0
  189. package/skills/blume-migrate/references/redocly.md +198 -0
  190. package/skills/blume-migrate/references/starlight.md +3 -3
  191. package/skills/blume-migrate/references/vitepress.md +204 -0
  192. package/skills/blume-migrate/references/vuepress.md +271 -0
  193. package/skills/blume-migrate/scripts/docsify-codemod.mjs +2387 -0
  194. package/skills/blume-migrate/scripts/docus-codemod.mjs +2542 -0
  195. package/skills/blume-migrate/scripts/fern-codemod.mjs +2633 -0
  196. package/skills/blume-migrate/scripts/github-wiki-codemod.mjs +2808 -0
  197. package/skills/blume-migrate/scripts/include-excerpts.mjs +649 -0
  198. package/skills/blume-migrate/scripts/jekyll-codemod.mjs +3649 -0
  199. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +17 -13
  200. package/skills/blume-migrate/scripts/mkdocs-codemod.mjs +2526 -0
  201. package/skills/blume-migrate/scripts/operation-routes.mjs +508 -0
  202. package/skills/blume-migrate/scripts/pin-heading-ids.mjs +1049 -0
  203. package/skills/blume-migrate/scripts/readme-codemod.mjs +4139 -0
  204. package/skills/blume-migrate/scripts/vitepress-codemod.mjs +1511 -0
  205. package/src/ai/changelog-components.ts +24 -0
  206. package/src/ai/changelog-markdown.ts +45 -41
  207. package/src/ai/component-markdown.ts +22 -9
  208. package/src/ai/llms.ts +36 -5
  209. package/src/ai/markdown.ts +2 -2
  210. package/src/ai/openapi-components.ts +25 -9
  211. package/src/ai/operation-details.ts +208 -0
  212. package/src/ai/relative-links.ts +48 -8
  213. package/src/ai/serializers.ts +7 -6
  214. package/src/ai/site-skill.ts +6 -2
  215. package/src/analytics/head.ts +11 -5
  216. package/src/analytics/script.ts +13 -3
  217. package/src/astro/generate.ts +32 -6
  218. package/src/astro/index.ts +1 -0
  219. package/src/astro/integration.ts +27 -1
  220. package/src/astro/mdx-source-errors.ts +46 -0
  221. package/src/astro/templates.ts +89 -185
  222. package/src/audit/checks/redirects.ts +5 -1
  223. package/src/audit/redirects.ts +36 -19
  224. package/src/audit/report.ts +22 -9
  225. package/src/audit/run.ts +12 -28
  226. package/src/audit/terms.ts +23 -0
  227. package/src/audit/url.ts +2 -2
  228. package/src/cli/build-failure.ts +256 -7
  229. package/src/cli/command-meta.ts +1 -1
  230. package/src/cli/commands/audit.ts +1 -1
  231. package/src/cli/commands/build.ts +12 -3
  232. package/src/cli/commands/check.ts +13 -2
  233. package/src/cli/commands/dev.ts +1 -1
  234. package/src/cli/commands/doctor.ts +4 -2
  235. package/src/cli/commands/init.ts +3 -3
  236. package/src/cli/commands/preview.ts +17 -1
  237. package/src/cli/commands/validate.ts +22 -10
  238. package/src/cli/prepare.ts +1 -1
  239. package/src/cli/preview-pages.ts +161 -0
  240. package/src/cli/unknown-flags.ts +1 -42
  241. package/src/components/code-copy.ts +51 -0
  242. package/src/components/code-language.ts +75 -0
  243. package/src/components/content/AccordionItem.astro +16 -1
  244. package/src/components/content/Callout.astro +11 -1
  245. package/src/components/content/Changelog.astro +189 -0
  246. package/src/components/content/CodeBlock.astro +8 -11
  247. package/src/components/content/Tabs.astro +16 -2
  248. package/src/components/content/YouTube.astro +6 -4
  249. package/src/components/content/code-block.ts +33 -0
  250. package/src/components/content/content-strings.ts +5 -1
  251. package/src/components/content/inline-markdown.ts +35 -8
  252. package/src/components/content/youtube.ts +49 -7
  253. package/src/components/layout/Analytics.astro +5 -1
  254. package/src/components/layout/NavTree.astro +8 -3
  255. package/src/components/layout/RootLayout.astro +18 -31
  256. package/src/components/layout/nav-utils.ts +14 -0
  257. package/src/components/layout/search/pagefind.ts +2 -1
  258. package/src/components/openapi/Operation.astro +4 -0
  259. package/src/components/openapi/PanelTabs.astro +9 -3
  260. package/src/components/openapi/RequestBody.astro +42 -8
  261. package/src/components/openapi/RequestPanel.astro +34 -53
  262. package/src/components/openapi/example-panels.ts +110 -0
  263. package/src/components/openapi/helpers.ts +195 -20
  264. package/src/components/openapi/operation-model.ts +63 -26
  265. package/src/components/openapi/request.ts +13 -0
  266. package/src/components/openapi/snippets.ts +14 -2
  267. package/src/core/alert-diagnostics.ts +89 -0
  268. package/src/core/builtin-tags.ts +76 -0
  269. package/src/core/changelog-list.ts +87 -0
  270. package/src/core/closest-match.ts +41 -0
  271. package/src/core/code-fence-diagnostics.ts +267 -0
  272. package/src/core/code-fences.ts +43 -7
  273. package/src/core/component-diagnostics.ts +65 -12
  274. package/src/core/config-input.ts +1 -1
  275. package/src/core/config.ts +46 -1
  276. package/src/core/content-assets.ts +64 -144
  277. package/src/core/diagnostics.ts +36 -3
  278. package/src/core/directive-diagnostics.ts +265 -47
  279. package/src/core/former-routes.ts +46 -0
  280. package/src/core/git-ignored.ts +53 -0
  281. package/src/core/github.ts +5 -4
  282. package/src/core/heading-markers.ts +156 -2
  283. package/src/core/hidden-pages.ts +64 -0
  284. package/src/core/includes.ts +181 -41
  285. package/src/core/last-modified.ts +47 -10
  286. package/src/core/links.ts +438 -83
  287. package/src/core/load-module.ts +98 -9
  288. package/src/core/manifest.ts +12 -9
  289. package/src/core/markdown-mirrors.ts +52 -0
  290. package/src/core/mdx-elements.ts +153 -0
  291. package/src/core/mdx-syntax.ts +377 -0
  292. package/src/core/meta-diagnostics.ts +134 -0
  293. package/src/core/meta.ts +154 -55
  294. package/src/core/nav-diagnostics.ts +16 -4
  295. package/src/core/navigation.ts +70 -10
  296. package/src/core/ordering-prefix.ts +22 -2
  297. package/src/core/pinned-ids.ts +141 -0
  298. package/src/core/project-graph.ts +221 -29
  299. package/src/core/redirect-patterns.ts +41 -0
  300. package/src/core/relative-files.ts +145 -0
  301. package/src/core/schema.ts +17 -3
  302. package/src/core/sources/mdx-remote.ts +75 -14
  303. package/src/core/sources/normalize.ts +885 -179
  304. package/src/core/sources/notion.ts +5 -4
  305. package/src/core/sources/obsidian.ts +2 -5
  306. package/src/core/sources/types.ts +17 -0
  307. package/src/core/static-files.ts +40 -0
  308. package/src/core/static-host.ts +125 -0
  309. package/src/core/svg-images.ts +98 -0
  310. package/src/core/syntax-diagnostics.ts +491 -0
  311. package/src/core/types.ts +43 -1
  312. package/src/deploy/artifacts.ts +2 -28
  313. package/src/deploy/generated-files.ts +128 -0
  314. package/src/deploy/platforms/vercel.ts +25 -1
  315. package/src/deploy/redirects.ts +43 -16
  316. package/src/deploy/sitemap.ts +2 -1
  317. package/src/markdown/base-links.ts +87 -6
  318. package/src/markdown/code-title.ts +29 -13
  319. package/src/markdown/content-assets.ts +210 -0
  320. package/src/markdown/directives.ts +69 -5
  321. package/src/markdown/fence-language.ts +106 -0
  322. package/src/markdown/fence-meta.ts +42 -0
  323. package/src/markdown/github-alerts.ts +172 -0
  324. package/src/markdown/heading-anchors.ts +265 -56
  325. package/src/markdown/include.ts +30 -3
  326. package/src/markdown/index.ts +145 -40
  327. package/src/markdown/prompt-text.ts +95 -0
  328. package/src/markdown/relative-links.ts +37 -2
  329. package/src/markdown/route-snapshot.ts +22 -12
  330. package/src/markdown/svg-fallback.ts +51 -0
  331. package/src/markdown/title-heading.ts +134 -0
  332. package/src/migrate/migrate.ts +127 -2
  333. package/src/og/card.ts +14 -4
  334. package/src/openapi/asyncapi.ts +14 -6
  335. package/src/openapi/checks.ts +160 -15
  336. package/src/openapi/model.ts +172 -33
  337. package/src/openapi/parse.ts +13 -4
  338. package/src/openapi/render-mdx.ts +55 -9
  339. package/src/openapi/source.ts +87 -6
  340. package/src/registry/eject.ts +0 -1
  341. package/src/search/documents.ts +10 -2
  342. package/src/sources/filesystem.ts +28 -3
  343. package/src/sources/mdx-remote.ts +7 -15
  344. package/src/theme/color.ts +14 -0
  345. package/src/theme/entry.ts +22 -1
  346. package/src/theme/palette.ts +74 -1
  347. package/dist/cli/chunk-0pmb4tr4.js.map +0 -35
  348. package/dist/cli/chunk-0w6hs479.js.map +0 -10
  349. package/dist/cli/chunk-150jk7km.js +0 -52
  350. package/dist/cli/chunk-150jk7km.js.map +0 -10
  351. package/dist/cli/chunk-36bxs9c7.js.map +0 -10
  352. package/dist/cli/chunk-53jqw8z0.js +0 -89
  353. package/dist/cli/chunk-53jqw8z0.js.map +0 -10
  354. package/dist/cli/chunk-60hz265r.js.map +0 -10
  355. package/dist/cli/chunk-desvm72z.js.map +0 -14
  356. package/dist/cli/chunk-dpy8qdjf.js.map +0 -17
  357. package/dist/cli/chunk-es8h0v3j.js +0 -441
  358. package/dist/cli/chunk-es8h0v3j.js.map +0 -11
  359. package/dist/cli/chunk-kdpzw38a.js.map +0 -11
  360. package/dist/cli/chunk-nbyvgnnm.js.map +0 -36
  361. package/dist/cli/chunk-s0bdnc7v.js.map +0 -10
  362. package/dist/cli/chunk-twy7psdz.js.map +0 -10
  363. package/dist/cli/chunk-ydp3065p.js +0 -64
  364. package/dist/cli/chunk-ydp3065p.js.map +0 -10
  365. /package/dist/cli/{chunk-74wfhv79.js.map → chunk-05f21r8h.js.map} +0 -0
  366. /package/dist/cli/{chunk-9qzgg6mj.js.map → chunk-1cm0h819.js.map} +0 -0
  367. /package/dist/cli/{chunk-ms9z66nz.js.map → chunk-4rftmttv.js.map} +0 -0
  368. /package/dist/cli/{chunk-hvcxng5f.js.map → chunk-7tekknev.js.map} +0 -0
  369. /package/dist/cli/{chunk-bxwhtvw8.js.map → chunk-ahc5gc9h.js.map} +0 -0
  370. /package/dist/cli/{chunk-tfycddbt.js.map → chunk-bjk964fp.js.map} +0 -0
  371. /package/dist/cli/{chunk-dqhg54mr.js.map → chunk-dmx6cezx.js.map} +0 -0
  372. /package/dist/cli/{chunk-ave1wcbr.js.map → chunk-m9bp2hc1.js.map} +0 -0
  373. /package/dist/cli/{chunk-58bt3hag.js.map → chunk-mrvh4c88.js.map} +0 -0
  374. /package/dist/cli/{chunk-1f882900.js.map → chunk-th0pgaj5.js.map} +0 -0
  375. /package/dist/cli/{chunk-dhwtqnnd.js.map → chunk-vnbvhgmd.js.map} +0 -0
  376. /package/dist/cli/{chunk-j1x92mx9.js.map → chunk-w6e455pz.js.map} +0 -0
  377. /package/dist/cli/{chunk-y4msrwm9.js.map → chunk-xgq4eytj.js.map} +0 -0
@@ -0,0 +1,64 @@
1
+ import type { ContentGraph, NavNode, PageRecord } from "./types.ts";
2
+
3
+ /**
4
+ * Hidden pages: `sidebar.hidden` (or the top-level `hidden` shorthand) takes a
5
+ * page out of the navigation, and so out of everything that lists the site's
6
+ * pages for readers, crawlers, and agents — the sitemap, site search,
7
+ * llms.txt, the site skill, the MCP server, and the JSON API.
8
+ *
9
+ * On a folder's index page the flag only drops the page's own row, the
10
+ * duplicate of the group row above it: the group row still links the page,
11
+ * so it is still in the navigation and stays listed everywhere else. Only a
12
+ * group row counts; a hidden page that an explicit sidebar lists as a page
13
+ * row is a contradiction `BLUME_NAV_HIDDEN_IN_SIDEBAR` reports instead. The
14
+ * home page — a tree's root: `/`, or a locale's `/fr` or a version's `/v1.0`
15
+ * — is the page the root URL serves, so hiding it only drops its row too.
16
+ */
17
+
18
+ /** Linked routes per graph, collected once and read for every page. */
19
+ const linkedRoutesByGraph = new WeakMap<ContentGraph, ReadonlySet<string>>();
20
+
21
+ const collectGroupRoutes = (nodes: NavNode[], into: Set<string>): void => {
22
+ for (const node of nodes) {
23
+ if (node.kind === "group") {
24
+ if (node.route) {
25
+ into.add(node.route);
26
+ }
27
+ collectGroupRoutes(node.children, into);
28
+ }
29
+ }
30
+ };
31
+
32
+ /**
33
+ * Every route a sidebar group row links to — a generated folder's index page,
34
+ * or an explicit group's `root` — and every tree's root, across the current
35
+ * docs' trees (one per locale under i18n) and every archived version's.
36
+ */
37
+ const linkedRoutes = (graph: ContentGraph): ReadonlySet<string> => {
38
+ const cached = linkedRoutesByGraph.get(graph);
39
+ if (cached) {
40
+ return cached;
41
+ }
42
+ // A graph assembled outside `buildContentGraph` (a builder under test) may
43
+ // carry pages alone; with no trees, no group row links anything.
44
+ const trees = [
45
+ graph.navigation,
46
+ ...Object.values(graph.navigationByLocale ?? {}),
47
+ ...Object.values(graph.navigationByVersion ?? {}).flatMap((byLocale) =>
48
+ Object.values(byLocale)
49
+ ),
50
+ ];
51
+ const routes = new Set<string>();
52
+ for (const tree of trees) {
53
+ if (tree?.root) {
54
+ routes.add(tree.root);
55
+ }
56
+ collectGroupRoutes(tree?.sidebar ?? [], routes);
57
+ }
58
+ linkedRoutesByGraph.set(graph, routes);
59
+ return routes;
60
+ };
61
+
62
+ /** Whether a page is hidden from the navigation (see the module comment). */
63
+ export const isHiddenPage = (page: PageRecord, graph: ContentGraph): boolean =>
64
+ page.meta.sidebar.hidden && !linkedRoutes(graph).has(page.route);
@@ -5,7 +5,17 @@ import { dirname, extname, join, relative, resolve } from "pathe";
5
5
  import { nextFenceState } from "./code-fences.ts";
6
6
  import type { FenceState } from "./code-fences.ts";
7
7
  import matter from "./frontmatter.ts";
8
- import { INLINE_CODE, MD_IMAGE, targetOffsetIn } from "./sources/normalize.ts";
8
+ import { resolveRelativeFile } from "./relative-files.ts";
9
+ import {
10
+ INLINE_CODE,
11
+ isLinkElementUrl,
12
+ linkDefinitions,
13
+ rewriteCardImages,
14
+ rewriteElementUrls,
15
+ rewriteImageTargets,
16
+ rewriteLinkTargets,
17
+ } from "./sources/normalize.ts";
18
+ import type { LinkDefinition } from "./sources/normalize.ts";
9
19
  import type { Diagnostic } from "./types.ts";
10
20
  import { substituteVariables } from "./variables.ts";
11
21
 
@@ -360,46 +370,57 @@ const resolveIncludePath = (
360
370
  return { path };
361
371
  };
362
372
 
373
+ /** A relative path written in `fromDir`, as written from `toDir`. */
374
+ const movePath = (path: string, fromDir: string, toDir: string): string => {
375
+ const moved = relative(toDir, resolve(fromDir, path));
376
+ return moved.startsWith(".") ? moved : `./${moved}`;
377
+ };
378
+
363
379
  /**
364
- * Rewrite one line's relative image targets from the included file's
365
- * directory to the including file's, so a partial's colocated
366
- * `![](./diagram.png)` still resolves once its markdown lives in the
367
- * includer. Mirrors `rewriteLine` in `content-assets.ts`: matches run on an
368
- * inline-code-masked copy while replacements splice into the real line.
380
+ * An image target written in the included file's directory, rebased onto the
381
+ * including file's, or `null` when it means the same thing from either: only
382
+ * filesystem-relative targets move with the file, while URLs, public-dir
383
+ * absolutes, and anchors stay.
369
384
  */
370
- const rebaseImageLine = (
371
- line: string,
385
+ const rebaseImageTarget = (
386
+ target: string,
372
387
  fromDir: string,
373
388
  toDir: string
374
- ): string => {
375
- const masked = line.replaceAll(INLINE_CODE, (span) =>
376
- " ".repeat(span.length)
377
- );
378
- let out = "";
379
- let cursor = 0;
380
- for (const match of masked.matchAll(MD_IMAGE)) {
381
- const target = match.groups?.target ?? "";
382
- // Only filesystem-relative targets move with the file: URLs, public-dir
383
- // absolutes, and anchors mean the same thing from either directory.
384
- if (
385
- target.startsWith("/") ||
386
- target.startsWith("#") ||
387
- URL.canParse(target)
388
- ) {
389
- continue;
390
- }
391
- const rebased = relative(toDir, resolve(fromDir, target));
392
- const url = rebased.startsWith(".") ? rebased : `./${rebased}`;
393
- const offset =
394
- (match.index ?? 0) +
395
- targetOffsetIn(match[0], target, match.groups?.title);
396
- out += line.slice(cursor, offset) + url;
397
- cursor = offset + target.length;
389
+ ): string | null =>
390
+ target.startsWith("/") || target.startsWith("#") || URL.canParse(target)
391
+ ? null
392
+ : movePath(target, fromDir, toDir);
393
+
394
+ /**
395
+ * A link to a file beside the included file (`./spec.pdf`, see
396
+ * `resolveRelativeFile`), rebased onto the including file's directory with
397
+ * its `?query#fragment` kept, or `null` for any other target. A page link
398
+ * stays as written: it resolves against the including page, wherever the
399
+ * partial lives.
400
+ */
401
+ const rebaseFileTarget = (
402
+ target: string,
403
+ fromDir: string,
404
+ toDir: string
405
+ ): string | null => {
406
+ const file = resolveRelativeFile(fromDir, target);
407
+ if (file === null) {
408
+ return null;
398
409
  }
399
- return out + line.slice(cursor);
410
+ const path = target.slice(0, target.length - file.suffix.length);
411
+ return `${movePath(path, fromDir, toDir)}${file.suffix}`;
400
412
  };
401
413
 
402
- /** Rebase every relative image target in expanded lines, skipping fences. */
414
+ /**
415
+ * Rebase every relative image target in expanded lines, skipping fences, from
416
+ * the included file's directory to the including file's, so a partial's
417
+ * colocated `![](./diagram.png)` still resolves once its markdown lives in
418
+ * the includer. Every destination form is read and written back in its own
419
+ * form (`![](<./a b.png> "Title")`; see `rewriteImageTargets`). A link,
420
+ * a reference definition, or an element URL naming a file beside the partial
421
+ * moves with it too, the way the build publishes such a file (see
422
+ * `core/content-assets.ts`).
423
+ */
403
424
  const rebaseImages = (
404
425
  lines: string[],
405
426
  fromDir: string,
@@ -409,11 +430,80 @@ const rebaseImages = (
409
430
  return lines;
410
431
  }
411
432
  let fence: FenceState = null;
412
- return lines.map((line) => {
433
+ const rebased = lines.map((line) => {
413
434
  const next = nextFenceState(line, fence);
414
435
  const inFence = fence !== null || next !== null;
415
436
  fence = next;
416
- return inFence ? line : rebaseImageLine(line, fromDir, toDir);
437
+ return inFence
438
+ ? line
439
+ : rewriteImageTargets(line, (target) =>
440
+ rebaseImageTarget(target, fromDir, toDir)
441
+ );
442
+ });
443
+ // A `<Card img>` is an image embed too, and its tag may wrap onto later
444
+ // lines, so it's rebased over the whole text, as are links and elements.
445
+ const toFile = (target: string): string | null =>
446
+ rebaseFileTarget(target, fromDir, toDir);
447
+ return rewriteElementUrls(
448
+ rewriteLinkTargets(
449
+ rewriteCardImages(rebased.join("\n"), (target) =>
450
+ rebaseImageTarget(target, fromDir, toDir)
451
+ ),
452
+ toFile
453
+ ),
454
+ (url) => (isLinkElementUrl(url) ? toFile(url.value) : null)
455
+ ).split("\n");
456
+ };
457
+
458
+ /**
459
+ * A `.md` partial's HTML comments (`<!-- … -->`), written as MDX comments
460
+ * (`{/* … *\/}`), for splicing into an `.mdx` page. The partial is read in
461
+ * the page's format, and MDX has no HTML comments: it shows one as text, so
462
+ * a note meant to stay hidden would render. A comment can span lines, and
463
+ * its text keeps every line (with any `*\/` broken up so it can't end the
464
+ * comment early), so line origins hold. Fenced code and inline code show a
465
+ * comment rather than make one, so they're left as written.
466
+ */
467
+ const htmlCommentsAsMdx = (lines: readonly string[]): string[] => {
468
+ let fence: FenceState = null;
469
+ let inComment = false;
470
+ return lines.map((line) => {
471
+ if (!inComment) {
472
+ const next = nextFenceState(line, fence);
473
+ const inFence = fence !== null || next !== null;
474
+ fence = next;
475
+ if (inFence) {
476
+ return line;
477
+ }
478
+ }
479
+ const masked = line.replaceAll(INLINE_CODE, (span) =>
480
+ " ".repeat(span.length)
481
+ );
482
+ let out = "";
483
+ let at = 0;
484
+ while (at < line.length) {
485
+ if (inComment) {
486
+ const close = line.indexOf("-->", at);
487
+ const end = close === -1 ? line.length : close;
488
+ out += line.slice(at, end).replaceAll("*/", "* /");
489
+ if (close === -1) {
490
+ break;
491
+ }
492
+ out += "*/}";
493
+ at = close + "-->".length;
494
+ inComment = false;
495
+ } else {
496
+ const open = masked.indexOf("<!--", at);
497
+ if (open === -1) {
498
+ out += line.slice(at);
499
+ break;
500
+ }
501
+ out += `${line.slice(at, open)}{/*`;
502
+ at = open + "<!--".length;
503
+ inComment = true;
504
+ }
505
+ }
506
+ return out;
417
507
  });
418
508
  };
419
509
 
@@ -532,12 +622,17 @@ const expandStatement = async (
532
622
  // Props replace their `{{name}}` references line by line, so every line
533
623
  // keeps its origin; they reach the file's own nested includes too.
534
624
  const { props } = statement.attributes;
625
+ const rebased = rebaseImages(
626
+ props ? lines.map((text) => substituteVariables(text, props)) : lines,
627
+ dirname(path),
628
+ dirname(filePath)
629
+ );
535
630
  return {
536
- lines: rebaseImages(
537
- props ? lines.map((text) => substituteVariables(text, props)) : lines,
538
- dirname(path),
539
- dirname(filePath)
540
- ),
631
+ lines:
632
+ extname(path).toLowerCase() === ".md" &&
633
+ extname(filePath).toLowerCase() === ".mdx"
634
+ ? htmlCommentsAsMdx(rebased)
635
+ : rebased,
541
636
  origins,
542
637
  };
543
638
  };
@@ -706,6 +801,51 @@ export const expandIncludes = async (
706
801
  };
707
802
  };
708
803
 
804
+ /**
805
+ * `text` with each of `definitions` it doesn't define itself appended, so a
806
+ * reference in it resolves through a definition written elsewhere in the
807
+ * page (CommonMark definitions are document-wide). Definitions render
808
+ * nothing; they're left off a text that ends in an open code fence, where
809
+ * they'd show as code.
810
+ */
811
+ export const withDefinitions = (
812
+ text: string,
813
+ definitions: readonly LinkDefinition[]
814
+ ): string => {
815
+ const own = new Set(
816
+ linkDefinitions(text).map((definition) => definition.key)
817
+ );
818
+ const missing = definitions.filter((definition) => !own.has(definition.key));
819
+ let fence: FenceState = null;
820
+ for (const line of text.split("\n")) {
821
+ fence = nextFenceState(line, fence);
822
+ }
823
+ return missing.length === 0 || fence !== null
824
+ ? text
825
+ : `${text}\n\n${missing.map((definition) => definition.text).join("\n")}\n`;
826
+ };
827
+
828
+ /**
829
+ * A page's source with the link-reference definitions its included partials
830
+ * write appended, for the render to parse. Each partial is spliced after the
831
+ * page is parsed (see `markdown/include.ts`), so a reference in the page
832
+ * (`[PEP 508]`) to a definition in a partial would otherwise stay text,
833
+ * though an include reads as if written inline. The definitions come from
834
+ * the expansion every surface shares, so a partial's definition of a file
835
+ * beside it is already rebased onto the page. The page's own definition of
836
+ * a label wins.
837
+ */
838
+ export const withIncludedDefinitions = async (
839
+ body: string,
840
+ options: { sourcePath: string; contentRoot?: string }
841
+ ): Promise<string> => {
842
+ if (!hasIncludeStatements(body)) {
843
+ return body;
844
+ }
845
+ const expanded = await expandIncludes(body, options);
846
+ return withDefinitions(body, linkDefinitions(expanded.text));
847
+ };
848
+
709
849
  /**
710
850
  * Resolve one include statement to its fully-expanded markdown text — the
711
851
  * render plugin's entry point (it finds the statements as AST nodes and only
@@ -27,7 +27,7 @@ const GIT_LOCATION_VARS = new Set([
27
27
  "GIT_WORK_TREE",
28
28
  ]);
29
29
 
30
- const gitEnv = (): NodeJS.ProcessEnv =>
30
+ export const gitEnv = (): NodeJS.ProcessEnv =>
31
31
  Object.fromEntries(
32
32
  Object.entries(process.env).filter(([key]) => !GIT_LOCATION_VARS.has(key))
33
33
  );
@@ -41,19 +41,50 @@ export const resolveLastModifiedConfig = (
41
41
  : { enabled: true, source: value };
42
42
 
43
43
  /**
44
- * Parse `git log --format=%x00%cI --name-only` output into a map of
45
- * repo-root-relative path → most recent committer ISO date. Each commit emits a
46
- * NUL-prefixed date line followed by the paths it touched; since git logs
47
- * newest-first, the first date seen for a path wins. Blank lines are ignored.
44
+ * Parse `git log --format=%x00%cI --name-status -M100%` output into a map of
45
+ * repo-root-relative path → the committer ISO date of the newest commit that
46
+ * changed the file. Each commit emits a NUL-prefixed date line followed by a
47
+ * status line per path it touched (`M\tpath`, `R100\told\tnew`); since git
48
+ * logs newest-first, the first date seen for a path wins. Blank lines are
49
+ * ignored.
50
+ *
51
+ * A rename (`-M100%` reports only exact ones, where the content is unchanged)
52
+ * follows the file the way `git log --follow` does for one path: it dates
53
+ * nothing itself, and the older commits that name the old path date the file
54
+ * under its current name, so renaming `page.md` to `page.mdx` keeps the page's
55
+ * date. A file whose visible history starts at a rename (a shallow clone cut
56
+ * off the commits before it) takes the rename's date.
48
57
  */
49
58
  export const parseGitLog = (output: string): Map<string, string> => {
50
59
  const times = new Map<string, string>();
60
+ // An older name of a file → its name now, for the commits read after the
61
+ // rename (older ones).
62
+ const currentNames = new Map<string, string>();
63
+ const renamedAt = new Map<string, string>();
51
64
  let current: string | null = null;
52
65
  for (const line of output.split("\n")) {
53
66
  if (line.startsWith("\0")) {
54
67
  current = line.slice(1);
55
- } else if (line && current && !times.has(line)) {
56
- times.set(line, current);
68
+ continue;
69
+ }
70
+ const [status = "", from = "", to] = line.split("\t");
71
+ const path = to ?? from;
72
+ if (!(current && path)) {
73
+ continue;
74
+ }
75
+ const name = currentNames.get(path) ?? path;
76
+ if (status.startsWith("R")) {
77
+ currentNames.set(from, name);
78
+ if (!renamedAt.has(name)) {
79
+ renamedAt.set(name, current);
80
+ }
81
+ } else if (!times.has(name)) {
82
+ times.set(name, current);
83
+ }
84
+ }
85
+ for (const [name, date] of renamedAt) {
86
+ if (!times.has(name)) {
87
+ times.set(name, date);
57
88
  }
58
89
  }
59
90
  return times;
@@ -99,8 +130,10 @@ export const gitRepositoryRoot = (root: string): string | null => {
99
130
  /**
100
131
  * Resolve each source file's last-modified date from git history, keyed by
101
132
  * absolute source path. Runs a single `git log` over the given content roots
102
- * (each local source's own root, which may diverge from `content.root`)
103
- * and maps repo-root-relative paths back to the given absolute paths
133
+ * (each local source's own root, which may diverge from `content.root`),
134
+ * following renames within them (see `parseGitLog`; a file moved in from
135
+ * outside every root dates from the move), and maps repo-root-relative paths
136
+ * back to the given absolute paths
104
137
  * (monorepo-safe via `rev-parse --show-toplevel`). Returns an empty map if git
105
138
  * is unavailable or the project isn't a repo — the feature then simply shows
106
139
  * no dates.
@@ -141,7 +174,11 @@ export const gitLastModifiedTimes = (
141
174
  "core.quotePath=false",
142
175
  "log",
143
176
  "--format=%x00%cI",
144
- "--name-only",
177
+ "--name-status",
178
+ // Exact renames only: git pairs them by blob id without comparing
179
+ // contents, so following them costs nothing, and a rename with edits
180
+ // dates the file at that commit either way.
181
+ "-M100%",
145
182
  "--",
146
183
  ...contentRoots.map(realPath),
147
184
  ],