livemark 0.7.2 → 0.9.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 (627) hide show
  1. package/README.md +115 -4
  2. package/package.json +15 -14
  3. package/source/actions/changelog/build.ts +245 -0
  4. package/source/actions/changelog/build.unit.ts +69 -0
  5. package/source/actions/config/define.ts +11 -0
  6. package/source/actions/config/define.unit.ts +33 -0
  7. package/source/actions/config/load.ts +22 -0
  8. package/source/actions/config/load.unit.ts +30 -0
  9. package/source/commands/build.ts +21 -0
  10. package/source/commands/escape.ts +77 -0
  11. package/source/commands/preview.ts +25 -0
  12. package/source/commands/start.ts +26 -0
  13. package/{build/website → source}/components/Article.tsx +44 -44
  14. package/{build/website → source}/components/Callout.tsx +1 -1
  15. package/{build/website → source}/components/Layout.tsx +3 -14
  16. package/{build/website → source}/components/LinkButton.tsx +1 -1
  17. package/{build/website → source}/components/PageToolbar.tsx +21 -8
  18. package/{build/website → source}/components/Section.tsx +1 -1
  19. package/{build/website → source}/components/SectionHeader.tsx +1 -1
  20. package/{build/website/components/MiniSidebar.tsx → source/components/Sidebar.tsx} +21 -5
  21. package/{build/website/components/Sidebar.tsx → source/components/SidebarArticles.tsx} +22 -55
  22. package/source/components/SidebarPosts.tsx +129 -0
  23. package/source/components/SidebarReleases.tsx +85 -0
  24. package/{build/website → source}/content-collections.ts +12 -3
  25. package/{build/website → source}/elements/accordion.tsx +1 -1
  26. package/{build/website → source}/elements/alert-dialog.tsx +1 -1
  27. package/{build/website → source}/elements/alert.tsx +1 -1
  28. package/{build/website → source}/elements/aspect-ratio.tsx +1 -1
  29. package/{build/website → source}/elements/avatar.tsx +1 -1
  30. package/{build/website → source}/elements/badge.tsx +1 -1
  31. package/{build/website → source}/elements/breadcrumb.tsx +1 -1
  32. package/{build/website → source}/elements/button-group.tsx +1 -1
  33. package/{build/website → source}/elements/button.tsx +1 -1
  34. package/{build/website → source}/elements/calendar.tsx +1 -1
  35. package/{build/website → source}/elements/card.tsx +1 -1
  36. package/{build/website → source}/elements/carousel.tsx +1 -1
  37. package/{build/website → source}/elements/chart.tsx +1 -1
  38. package/{build/website → source}/elements/checkbox.tsx +1 -1
  39. package/{build/website → source}/elements/command.tsx +1 -1
  40. package/{build/website → source}/elements/context-menu.tsx +1 -1
  41. package/{build/website → source}/elements/dialog.tsx +1 -1
  42. package/{build/website → source}/elements/drawer.tsx +1 -1
  43. package/{build/website → source}/elements/dropdown-menu.tsx +1 -1
  44. package/{build/website → source}/elements/empty.tsx +1 -1
  45. package/{build/website → source}/elements/field.tsx +1 -1
  46. package/{build/website → source}/elements/hover-card.tsx +1 -1
  47. package/{build/website → source}/elements/input-group.tsx +1 -1
  48. package/{build/website → source}/elements/input-otp.tsx +1 -1
  49. package/{build/website → source}/elements/input.tsx +1 -1
  50. package/{build/website → source}/elements/item.tsx +1 -1
  51. package/{build/website → source}/elements/kbd.tsx +1 -1
  52. package/{build/website → source}/elements/label.tsx +1 -1
  53. package/{build/website → source}/elements/menubar.tsx +1 -1
  54. package/{build/website → source}/elements/native-select.tsx +1 -1
  55. package/{build/website → source}/elements/navigation-menu.tsx +1 -1
  56. package/{build/website → source}/elements/pagination.tsx +1 -1
  57. package/{build/website → source}/elements/popover.tsx +1 -1
  58. package/{build/website → source}/elements/progress.tsx +1 -1
  59. package/{build/website → source}/elements/radio-group.tsx +1 -1
  60. package/{build/website → source}/elements/resizable.tsx +1 -1
  61. package/{build/website → source}/elements/scroll-area.tsx +1 -1
  62. package/{build/website → source}/elements/select.tsx +1 -1
  63. package/{build/website → source}/elements/separator.tsx +1 -1
  64. package/{build/website → source}/elements/sheet.tsx +1 -1
  65. package/{build/website → source}/elements/sidebar.tsx +7 -4
  66. package/{build/website → source}/elements/skeleton.tsx +1 -1
  67. package/{build/website → source}/elements/slider.tsx +1 -1
  68. package/{build/website → source}/elements/spinner.tsx +1 -1
  69. package/{build/website → source}/elements/switch.tsx +1 -1
  70. package/{build/website → source}/elements/table.tsx +1 -1
  71. package/{build/website → source}/elements/tabs.tsx +1 -1
  72. package/{build/website → source}/elements/textarea.tsx +1 -1
  73. package/{build/website → source}/elements/toggle-group.tsx +1 -1
  74. package/{build/website → source}/elements/toggle.tsx +1 -1
  75. package/{build/website → source}/elements/tooltip.tsx +1 -1
  76. package/source/entrypoints/main.ts +12 -0
  77. package/{build/website → source}/env.d.ts +1 -1
  78. package/source/helpers/program.ts +6 -0
  79. package/{build/website → source}/helpers/section.ts +1 -1
  80. package/source/hooks/media.ts +29 -0
  81. package/source/index.ts +1 -0
  82. package/{build/website → source}/models/article.ts +5 -0
  83. package/source/models/config.ts +51 -0
  84. package/source/models/link.ts +11 -0
  85. package/source/models/patch.ts +9 -0
  86. package/source/models/section.ts +45 -0
  87. package/source/models/theme.ts +74 -0
  88. package/source/program.ts +18 -0
  89. package/source/settings.ts +6 -0
  90. package/{build/website → source}/vite.config.ts +14 -9
  91. package/{build → target}/actions/changelog/build.d.ts +1 -0
  92. package/target/actions/changelog/build.js +187 -0
  93. package/target/actions/changelog/build.unit.js +66 -0
  94. package/target/actions/config/define.js +8 -0
  95. package/target/actions/config/define.unit.js +29 -0
  96. package/target/actions/config/load.js +25 -0
  97. package/target/actions/config/load.unit.js +23 -0
  98. package/target/client.d.ts +1 -0
  99. package/target/client.js +6 -0
  100. package/target/commands/build.js +14 -0
  101. package/target/commands/escape.js +56 -0
  102. package/target/commands/preview.js +18 -0
  103. package/target/commands/start.js +19 -0
  104. package/target/components/Abbr.d.ts +5 -0
  105. package/target/components/Abbr.js +9 -0
  106. package/target/components/AnsiCode.d.ts +4 -0
  107. package/target/components/AnsiCode.js +6 -0
  108. package/target/components/Article.d.ts +5 -0
  109. package/target/components/Article.js +104 -0
  110. package/target/components/BackToTop.d.ts +3 -0
  111. package/target/components/BackToTop.js +19 -0
  112. package/target/components/Banner.d.ts +2 -0
  113. package/target/components/Banner.js +12 -0
  114. package/target/components/BlogIndex.d.ts +4 -0
  115. package/target/components/BlogIndex.js +62 -0
  116. package/target/components/Breadcrumbs.d.ts +1 -0
  117. package/target/components/Breadcrumbs.js +13 -0
  118. package/target/components/Callout.d.ts +8 -0
  119. package/target/components/Callout.js +43 -0
  120. package/target/components/Card.d.ts +7 -0
  121. package/target/components/Card.js +17 -0
  122. package/target/components/Cards.d.ts +4 -0
  123. package/target/components/Cards.js +6 -0
  124. package/target/components/ChangelogIndex.d.ts +4 -0
  125. package/target/components/ChangelogIndex.js +57 -0
  126. package/target/components/CodeBlock.d.ts +1 -0
  127. package/target/components/CodeBlock.js +47 -0
  128. package/target/components/CodeTabs.d.ts +6 -0
  129. package/target/components/CodeTabs.js +49 -0
  130. package/target/components/Column.d.ts +4 -0
  131. package/target/components/Column.js +6 -0
  132. package/target/components/Columns.d.ts +5 -0
  133. package/target/components/Columns.js +10 -0
  134. package/target/components/Content.d.ts +3 -0
  135. package/target/components/Content.js +5 -0
  136. package/target/components/ContentTab.d.ts +5 -0
  137. package/target/components/ContentTab.js +6 -0
  138. package/target/components/ContentTabs.d.ts +5 -0
  139. package/target/components/ContentTabs.js +47 -0
  140. package/target/components/DefaultCatchBoundary.d.ts +2 -0
  141. package/target/components/DefaultCatchBoundary.js +20 -0
  142. package/target/components/DefinitionList.d.ts +7 -0
  143. package/target/components/DefinitionList.js +14 -0
  144. package/target/components/Details.d.ts +5 -0
  145. package/target/components/Details.js +13 -0
  146. package/target/components/FileTree.d.ts +4 -0
  147. package/target/components/FileTree.js +17 -0
  148. package/target/components/Footer.d.ts +2 -0
  149. package/target/components/Footer.js +9 -0
  150. package/target/components/FootnoteRef.d.ts +3 -0
  151. package/target/components/FootnoteRef.js +31 -0
  152. package/target/components/Heading.d.ts +8 -0
  153. package/target/components/Heading.js +18 -0
  154. package/target/components/InlineBadge.d.ts +5 -0
  155. package/target/components/InlineBadge.js +7 -0
  156. package/target/components/InlineIcon.d.ts +5 -0
  157. package/target/components/InlineIcon.js +10 -0
  158. package/target/components/InlineToc.d.ts +4 -0
  159. package/target/components/InlineToc.js +14 -0
  160. package/target/components/Layout.d.ts +4 -0
  161. package/target/components/Layout.js +65 -0
  162. package/target/components/LinkButton.d.ts +7 -0
  163. package/target/components/LinkButton.js +11 -0
  164. package/target/components/Mermaid.d.ts +4 -0
  165. package/target/components/Mermaid.js +8 -0
  166. package/target/components/MermaidRenderer.d.ts +4 -0
  167. package/target/components/MermaidRenderer.js +32 -0
  168. package/target/components/NotFound.d.ts +3 -0
  169. package/target/components/NotFound.js +10 -0
  170. package/target/components/PackageTabs.d.ts +9 -0
  171. package/target/components/PackageTabs.js +28 -0
  172. package/target/components/PageToolbar.d.ts +7 -0
  173. package/target/components/PageToolbar.js +34 -0
  174. package/target/components/PrevNext.d.ts +4 -0
  175. package/target/components/PrevNext.js +34 -0
  176. package/target/components/Search.d.ts +2 -0
  177. package/target/components/Search.js +16 -0
  178. package/target/components/SearchDialog.d.ts +5 -0
  179. package/target/components/SearchDialog.js +139 -0
  180. package/target/components/Section.d.ts +5 -0
  181. package/target/components/Section.js +8 -0
  182. package/target/components/SectionHeader.d.ts +7 -0
  183. package/target/components/SectionHeader.js +7 -0
  184. package/target/components/Sidebar.d.ts +4 -0
  185. package/target/components/Sidebar.js +33 -0
  186. package/target/components/SidebarArticles.d.ts +2 -0
  187. package/target/components/SidebarArticles.js +45 -0
  188. package/target/components/SidebarLinks.d.ts +4 -0
  189. package/target/components/SidebarLinks.js +26 -0
  190. package/target/components/SidebarPosts.d.ts +2 -0
  191. package/target/components/SidebarPosts.js +53 -0
  192. package/target/components/SidebarReleases.d.ts +2 -0
  193. package/target/components/SidebarReleases.js +35 -0
  194. package/target/components/SidebarSections.d.ts +4 -0
  195. package/target/components/SidebarSections.js +36 -0
  196. package/target/components/SiteTitle.d.ts +2 -0
  197. package/target/components/SiteTitle.js +12 -0
  198. package/target/components/SortableTable.d.ts +5 -0
  199. package/target/components/SortableTable.js +63 -0
  200. package/target/components/SoundCloud.d.ts +4 -0
  201. package/target/components/SoundCloud.js +7 -0
  202. package/target/components/TagIndex.d.ts +5 -0
  203. package/target/components/TagIndex.js +64 -0
  204. package/target/components/Theme.d.ts +1 -0
  205. package/target/components/Theme.js +21 -0
  206. package/target/components/Toc.d.ts +12 -0
  207. package/target/components/Toc.js +128 -0
  208. package/target/components/YouTube.d.ts +4 -0
  209. package/target/components/YouTube.js +6 -0
  210. package/target/components/ZoomImage.d.ts +4 -0
  211. package/target/components/ZoomImage.js +26 -0
  212. package/target/content/article.d.ts +43 -0
  213. package/target/content/article.js +54 -0
  214. package/target/content/tag.d.ts +2 -0
  215. package/target/content/tag.js +30 -0
  216. package/target/content-collections.d.ts +2 -0
  217. package/target/content-collections.js +200 -0
  218. package/target/elements/accordion.d.ts +6 -0
  219. package/target/elements/accordion.js +19 -0
  220. package/target/elements/alert-dialog.d.ts +18 -0
  221. package/target/elements/alert-dialog.js +44 -0
  222. package/target/elements/alert.d.ts +9 -0
  223. package/target/elements/alert.js +28 -0
  224. package/target/elements/aspect-ratio.d.ts +4 -0
  225. package/target/elements/aspect-ratio.js +9 -0
  226. package/target/elements/avatar.d.ts +11 -0
  227. package/target/elements/avatar.js +23 -0
  228. package/target/elements/badge.d.ts +7 -0
  229. package/target/elements/badge.js +34 -0
  230. package/target/elements/breadcrumb.d.ts +9 -0
  231. package/target/elements/breadcrumb.js +39 -0
  232. package/target/elements/button-group.d.ts +10 -0
  233. package/target/elements/button-group.js +37 -0
  234. package/target/elements/button.d.ts +8 -0
  235. package/target/elements/button.js +35 -0
  236. package/target/elements/calendar.d.ts +10 -0
  237. package/target/elements/calendar.js +76 -0
  238. package/target/elements/card.d.ts +11 -0
  239. package/target/elements/card.js +25 -0
  240. package/target/elements/carousel.d.ts +28 -0
  241. package/target/elements/carousel.js +95 -0
  242. package/target/elements/chart.d.ts +44 -0
  243. package/target/elements/chart.js +140 -0
  244. package/target/elements/checkbox.d.ts +3 -0
  245. package/target/elements/checkbox.js +9 -0
  246. package/target/elements/collapsible.d.ts +5 -0
  247. package/target/elements/collapsible.js +13 -0
  248. package/target/elements/command.d.ts +23 -0
  249. package/target/elements/command.js +42 -0
  250. package/target/elements/context-menu.d.ts +29 -0
  251. package/target/elements/context-menu.js +54 -0
  252. package/target/elements/dialog.d.ts +16 -0
  253. package/target/elements/dialog.js +41 -0
  254. package/target/elements/direction.d.ts +1 -0
  255. package/target/elements/direction.js +2 -0
  256. package/target/elements/drawer.d.ts +12 -0
  257. package/target/elements/drawer.js +38 -0
  258. package/target/elements/dropdown-menu.d.ts +24 -0
  259. package/target/elements/dropdown-menu.js +54 -0
  260. package/target/elements/empty.d.ts +11 -0
  261. package/target/elements/empty.js +34 -0
  262. package/target/elements/field.d.ts +24 -0
  263. package/target/elements/field.js +69 -0
  264. package/target/elements/hover-card.d.ts +5 -0
  265. package/target/elements/hover-card.js +14 -0
  266. package/target/elements/input-group.d.ts +18 -0
  267. package/target/elements/input-group.js +60 -0
  268. package/target/elements/input-otp.d.ts +11 -0
  269. package/target/elements/input-otp.js +21 -0
  270. package/target/elements/input.d.ts +2 -0
  271. package/target/elements/input.js +8 -0
  272. package/target/elements/item.d.ts +21 -0
  273. package/target/elements/item.js +79 -0
  274. package/target/elements/kbd.d.ts +3 -0
  275. package/target/elements/kbd.js +10 -0
  276. package/target/elements/label.d.ts +2 -0
  277. package/target/elements/label.js +8 -0
  278. package/target/elements/menubar.d.ts +29 -0
  279. package/target/elements/menubar.js +58 -0
  280. package/target/elements/native-select.d.ts +8 -0
  281. package/target/elements/native-select.js +16 -0
  282. package/target/elements/navigation-menu.d.ts +11 -0
  283. package/target/elements/navigation-menu.js +34 -0
  284. package/target/elements/pagination.d.ts +17 -0
  285. package/target/elements/pagination.js +33 -0
  286. package/target/elements/popover.d.ts +9 -0
  287. package/target/elements/popover.js +23 -0
  288. package/target/elements/progress.d.ts +7 -0
  289. package/target/elements/progress.js +21 -0
  290. package/target/elements/radio-group.d.ts +5 -0
  291. package/target/elements/radio-group.js +12 -0
  292. package/target/elements/resizable.d.ts +7 -0
  293. package/target/elements/resizable.js +14 -0
  294. package/target/elements/scroll-area.d.ts +4 -0
  295. package/target/elements/scroll-area.js +13 -0
  296. package/target/elements/select.d.ts +15 -0
  297. package/target/elements/select.js +39 -0
  298. package/target/elements/separator.d.ts +3 -0
  299. package/target/elements/separator.js +8 -0
  300. package/target/elements/sheet.d.ts +13 -0
  301. package/target/elements/sheet.js +41 -0
  302. package/target/elements/sidebar.d.ts +63 -0
  303. package/target/elements/sidebar.js +272 -0
  304. package/target/elements/skeleton.d.ts +2 -0
  305. package/target/elements/skeleton.js +7 -0
  306. package/target/elements/slider.d.ts +3 -0
  307. package/target/elements/slider.js +15 -0
  308. package/target/elements/sonner.d.ts +3 -0
  309. package/target/elements/sonner.js +23 -0
  310. package/target/elements/spinner.d.ts +2 -0
  311. package/target/elements/spinner.js +8 -0
  312. package/target/elements/switch.d.ts +5 -0
  313. package/target/elements/switch.js +8 -0
  314. package/target/elements/table.d.ts +9 -0
  315. package/target/elements/table.js +28 -0
  316. package/target/elements/tabs.d.ts +10 -0
  317. package/target/elements/tabs.js +29 -0
  318. package/target/elements/textarea.d.ts +2 -0
  319. package/target/elements/textarea.js +7 -0
  320. package/target/elements/toggle-group.d.ts +10 -0
  321. package/target/elements/toggle-group.js +24 -0
  322. package/target/elements/toggle.d.ts +8 -0
  323. package/target/elements/toggle.js +26 -0
  324. package/target/elements/tooltip.d.ts +6 -0
  325. package/target/elements/tooltip.js +18 -0
  326. package/target/entrypoints/main.js +12 -0
  327. package/target/helpers/article-icon.d.ts +3 -0
  328. package/target/helpers/article-icon.js +34 -0
  329. package/target/helpers/article.d.ts +24 -0
  330. package/target/helpers/article.js +73 -0
  331. package/target/helpers/changelog-source.d.ts +7 -0
  332. package/target/helpers/changelog-source.js +16 -0
  333. package/target/helpers/changelog-source.unit.d.ts +1 -0
  334. package/target/helpers/changelog-source.unit.js +33 -0
  335. package/target/helpers/dynamic-icon-resolver.d.ts +5 -0
  336. package/target/helpers/dynamic-icon-resolver.js +17 -0
  337. package/target/helpers/dynamic-icon.d.ts +5 -0
  338. package/target/helpers/dynamic-icon.js +8 -0
  339. package/target/helpers/favicon.d.ts +2 -0
  340. package/target/helpers/favicon.js +11 -0
  341. package/target/helpers/model.d.ts +3 -0
  342. package/target/helpers/model.js +4 -0
  343. package/target/helpers/program.js +5 -0
  344. package/target/helpers/resolve-asset-path.d.ts +2 -0
  345. package/target/helpers/resolve-asset-path.js +9 -0
  346. package/target/helpers/resolve-includes.d.ts +2 -0
  347. package/target/helpers/resolve-includes.js +113 -0
  348. package/target/helpers/resolve-includes.unit.d.ts +1 -0
  349. package/target/helpers/resolve-includes.unit.js +76 -0
  350. package/target/helpers/search-text.d.ts +2 -0
  351. package/target/helpers/search-text.js +16 -0
  352. package/target/helpers/section.d.ts +13 -0
  353. package/target/helpers/section.js +39 -0
  354. package/target/helpers/section.unit.d.ts +1 -0
  355. package/target/helpers/section.unit.js +62 -0
  356. package/target/helpers/theme.d.ts +5 -0
  357. package/target/helpers/theme.js +23 -0
  358. package/target/helpers/toc-context.d.ts +5 -0
  359. package/target/helpers/toc-context.js +8 -0
  360. package/target/helpers/toc.d.ts +3 -0
  361. package/target/helpers/toc.js +41 -0
  362. package/target/helpers/toc.unit.d.ts +1 -0
  363. package/target/helpers/toc.unit.js +65 -0
  364. package/target/hooks/in-view.d.ts +4 -0
  365. package/target/hooks/in-view.js +23 -0
  366. package/target/hooks/media.d.ts +6 -0
  367. package/target/hooks/media.js +25 -0
  368. package/target/index.js +2 -0
  369. package/target/models/article.d.ts +58 -0
  370. package/target/models/article.js +21 -0
  371. package/{build → target}/models/config.d.ts +10 -0
  372. package/target/models/config.js +34 -0
  373. package/target/models/link.js +9 -0
  374. package/{build → target}/models/patch.d.ts +5 -0
  375. package/target/models/patch.js +7 -0
  376. package/target/models/section.js +26 -0
  377. package/target/models/theme.js +73 -0
  378. package/target/models/toc.d.ts +5 -0
  379. package/target/models/toc.js +2 -0
  380. package/target/plugins/rehype-inline-code.d.ts +19 -0
  381. package/target/plugins/rehype-inline-code.js +55 -0
  382. package/target/plugins/rehype-task-list-a11y.d.ts +10 -0
  383. package/target/plugins/rehype-task-list-a11y.js +29 -0
  384. package/target/plugins/remark-abbr.d.ts +6 -0
  385. package/target/plugins/remark-abbr.js +39 -0
  386. package/target/plugins/remark-abbr.unit.d.ts +1 -0
  387. package/target/plugins/remark-abbr.unit.js +79 -0
  388. package/target/plugins/remark-ansi.d.ts +8 -0
  389. package/target/plugins/remark-ansi.js +239 -0
  390. package/target/plugins/remark-ansi.unit.d.ts +1 -0
  391. package/target/plugins/remark-ansi.unit.js +134 -0
  392. package/target/plugins/remark-badge.d.ts +6 -0
  393. package/target/plugins/remark-badge.js +43 -0
  394. package/target/plugins/remark-badge.unit.d.ts +1 -0
  395. package/target/plugins/remark-badge.unit.js +76 -0
  396. package/target/plugins/remark-button.d.ts +6 -0
  397. package/target/plugins/remark-button.js +52 -0
  398. package/target/plugins/remark-button.unit.d.ts +1 -0
  399. package/target/plugins/remark-button.unit.js +105 -0
  400. package/target/plugins/remark-callout.d.ts +4 -0
  401. package/target/plugins/remark-callout.js +39 -0
  402. package/target/plugins/remark-card.d.ts +4 -0
  403. package/target/plugins/remark-card.js +66 -0
  404. package/target/plugins/remark-code-tabs.d.ts +4 -0
  405. package/target/plugins/remark-code-tabs.js +72 -0
  406. package/target/plugins/remark-columns.d.ts +4 -0
  407. package/target/plugins/remark-columns.js +54 -0
  408. package/target/plugins/remark-custom-heading-id.d.ts +14 -0
  409. package/target/plugins/remark-custom-heading-id.js +54 -0
  410. package/target/plugins/remark-custom-heading-id.unit.d.ts +1 -0
  411. package/target/plugins/remark-custom-heading-id.unit.js +91 -0
  412. package/target/plugins/remark-deflist.d.ts +4 -0
  413. package/target/plugins/remark-deflist.js +31 -0
  414. package/target/plugins/remark-details.d.ts +4 -0
  415. package/target/plugins/remark-details.js +33 -0
  416. package/target/plugins/remark-filetree.d.ts +12 -0
  417. package/target/plugins/remark-filetree.js +61 -0
  418. package/target/plugins/remark-filetree.unit.d.ts +1 -0
  419. package/target/plugins/remark-filetree.unit.js +87 -0
  420. package/target/plugins/remark-github-callout.d.ts +4 -0
  421. package/target/plugins/remark-github-callout.js +62 -0
  422. package/target/plugins/remark-icon.d.ts +4 -0
  423. package/target/plugins/remark-icon.js +36 -0
  424. package/target/plugins/remark-image.d.ts +9 -0
  425. package/target/plugins/remark-image.js +26 -0
  426. package/target/plugins/remark-media.d.ts +6 -0
  427. package/target/plugins/remark-media.js +52 -0
  428. package/target/plugins/remark-media.unit.d.ts +1 -0
  429. package/target/plugins/remark-media.unit.js +54 -0
  430. package/target/plugins/remark-mermaid.d.ts +4 -0
  431. package/target/plugins/remark-mermaid.js +20 -0
  432. package/target/plugins/remark-npm.d.ts +4 -0
  433. package/target/plugins/remark-npm.js +32 -0
  434. package/target/plugins/remark-steps.d.ts +6 -0
  435. package/target/plugins/remark-steps.js +30 -0
  436. package/target/plugins/remark-steps.unit.d.ts +1 -0
  437. package/target/plugins/remark-steps.unit.js +65 -0
  438. package/target/plugins/remark-tab.d.ts +6 -0
  439. package/target/plugins/remark-tab.js +76 -0
  440. package/target/plugins/remark-tab.unit.d.ts +1 -0
  441. package/target/plugins/remark-tab.unit.js +156 -0
  442. package/target/plugins/remark-toc.d.ts +6 -0
  443. package/target/plugins/remark-toc.js +33 -0
  444. package/target/plugins/remark-toc.unit.d.ts +1 -0
  445. package/target/plugins/remark-toc.unit.js +57 -0
  446. package/target/plugins/shiki-icon.d.ts +16 -0
  447. package/target/plugins/shiki-icon.js +66 -0
  448. package/target/plugins/shiki-line-highlight.d.ts +27 -0
  449. package/target/plugins/shiki-line-highlight.js +140 -0
  450. package/target/plugins/vite-livemark.d.ts +13 -0
  451. package/target/plugins/vite-livemark.js +76 -0
  452. package/target/program.js +18 -0
  453. package/target/routeTree.gen.d.ts +57 -0
  454. package/target/routeTree.gen.js +27 -0
  455. package/target/router.d.ts +6 -0
  456. package/target/router.js +26 -0
  457. package/target/routes/$.d.ts +1 -0
  458. package/target/routes/$.js +85 -0
  459. package/target/routes/__root.d.ts +1 -0
  460. package/target/routes/__root.js +69 -0
  461. package/target/server.d.ts +2 -0
  462. package/target/server.js +7 -0
  463. package/target/settings.js +7 -0
  464. package/target/utils/style.d.ts +2 -0
  465. package/target/utils/style.js +6 -0
  466. package/target/vite.config.d.ts +2 -0
  467. package/target/vite.config.js +67 -0
  468. package/build/actions/changelog/build.js +0 -158
  469. package/build/actions/changelog/build.unit.js +0 -66
  470. package/build/actions/config/define.js +0 -8
  471. package/build/actions/config/define.unit.js +0 -29
  472. package/build/actions/config/load.js +0 -25
  473. package/build/actions/config/load.unit.js +0 -23
  474. package/build/commands/build.js +0 -14
  475. package/build/commands/escape.js +0 -56
  476. package/build/commands/preview.js +0 -18
  477. package/build/commands/start.js +0 -19
  478. package/build/docs/markdown/includes/example.d.ts +0 -58
  479. package/build/docs/markdown/includes/example.js +0 -5
  480. package/build/entrypoints/main.js +0 -12
  481. package/build/helpers/program.js +0 -5
  482. package/build/index.js +0 -2
  483. package/build/livemark.config.d.ts +0 -58
  484. package/build/livemark.config.js +0 -25
  485. package/build/models/config.js +0 -34
  486. package/build/models/link.js +0 -9
  487. package/build/models/patch.js +0 -7
  488. package/build/models/section.js +0 -26
  489. package/build/models/theme.js +0 -73
  490. package/build/package.json +0 -138
  491. package/build/program.js +0 -18
  492. package/build/settings.js +0 -7
  493. package/build/vite.config.d.ts +0 -2
  494. package/build/vite.config.js +0 -48
  495. package/build/website/components/BlogSidebar.tsx +0 -162
  496. package/build/website/components/ChangelogSidebar.tsx +0 -120
  497. package/build/website/hooks/media.ts +0 -19
  498. package/build/website/routeTree.gen.ts +0 -86
  499. /package/{build/website → source}/assets/logo.svg +0 -0
  500. /package/{build/website → source}/client.tsx +0 -0
  501. /package/{build/website → source}/components/Abbr.tsx +0 -0
  502. /package/{build/website → source}/components/AnsiCode.tsx +0 -0
  503. /package/{build/website → source}/components/BackToTop.tsx +0 -0
  504. /package/{build/website → source}/components/Banner.tsx +0 -0
  505. /package/{build/website → source}/components/BlogIndex.tsx +0 -0
  506. /package/{build/website → source}/components/Breadcrumbs.tsx +0 -0
  507. /package/{build/website → source}/components/Card.tsx +0 -0
  508. /package/{build/website → source}/components/Cards.tsx +0 -0
  509. /package/{build/website → source}/components/ChangelogIndex.tsx +0 -0
  510. /package/{build/website → source}/components/CodeBlock.tsx +0 -0
  511. /package/{build/website → source}/components/CodeTabs.tsx +0 -0
  512. /package/{build/website → source}/components/Column.tsx +0 -0
  513. /package/{build/website → source}/components/Columns.tsx +0 -0
  514. /package/{build/website → source}/components/Content.tsx +0 -0
  515. /package/{build/website → source}/components/ContentTab.tsx +0 -0
  516. /package/{build/website → source}/components/ContentTabs.tsx +0 -0
  517. /package/{build/website → source}/components/DefaultCatchBoundary.tsx +0 -0
  518. /package/{build/website → source}/components/DefinitionList.tsx +0 -0
  519. /package/{build/website → source}/components/Details.tsx +0 -0
  520. /package/{build/website → source}/components/FileTree.tsx +0 -0
  521. /package/{build/website → source}/components/Footer.tsx +0 -0
  522. /package/{build/website → source}/components/FootnoteRef.tsx +0 -0
  523. /package/{build/website → source}/components/Heading.tsx +0 -0
  524. /package/{build/website → source}/components/InlineBadge.tsx +0 -0
  525. /package/{build/website → source}/components/InlineIcon.tsx +0 -0
  526. /package/{build/website → source}/components/InlineToc.tsx +0 -0
  527. /package/{build/website → source}/components/Mermaid.tsx +0 -0
  528. /package/{build/website → source}/components/MermaidRenderer.tsx +0 -0
  529. /package/{build/website → source}/components/NotFound.tsx +0 -0
  530. /package/{build/website → source}/components/PackageTabs.tsx +0 -0
  531. /package/{build/website → source}/components/PrevNext.tsx +0 -0
  532. /package/{build/website → source}/components/Search.tsx +0 -0
  533. /package/{build/website → source}/components/SearchDialog.tsx +0 -0
  534. /package/{build/website → source}/components/SidebarLinks.tsx +0 -0
  535. /package/{build/website → source}/components/SidebarSections.tsx +0 -0
  536. /package/{build/website → source}/components/SiteTitle.tsx +0 -0
  537. /package/{build/website → source}/components/SortableTable.tsx +0 -0
  538. /package/{build/website → source}/components/SoundCloud.tsx +0 -0
  539. /package/{build/website → source}/components/TagIndex.tsx +0 -0
  540. /package/{build/website → source}/components/Theme.tsx +0 -0
  541. /package/{build/website → source}/components/Toc.tsx +0 -0
  542. /package/{build/website → source}/components/YouTube.tsx +0 -0
  543. /package/{build/website → source}/components/ZoomImage.tsx +0 -0
  544. /package/{build/website → source}/content/article.ts +0 -0
  545. /package/{build/website → source}/content/tag.ts +0 -0
  546. /package/{build/website → source}/elements/collapsible.tsx +0 -0
  547. /package/{build/website → source}/elements/direction.tsx +0 -0
  548. /package/{build/website → source}/elements/sonner.tsx +0 -0
  549. /package/{build/website → source}/helpers/article-icon.ts +0 -0
  550. /package/{build/website → source}/helpers/article.ts +0 -0
  551. /package/{build/website → source}/helpers/changelog-source.ts +0 -0
  552. /package/{build/website → source}/helpers/changelog-source.unit.ts +0 -0
  553. /package/{build/website → source}/helpers/dynamic-icon-resolver.tsx +0 -0
  554. /package/{build/website → source}/helpers/dynamic-icon.tsx +0 -0
  555. /package/{build/website → source}/helpers/favicon.ts +0 -0
  556. /package/{build/website → source}/helpers/model.ts +0 -0
  557. /package/{build/website → source}/helpers/resolve-asset-path.ts +0 -0
  558. /package/{build/website → source}/helpers/resolve-includes.ts +0 -0
  559. /package/{build/website → source}/helpers/resolve-includes.unit.ts +0 -0
  560. /package/{build/website → source}/helpers/search-text.ts +0 -0
  561. /package/{build/website → source}/helpers/section.unit.ts +0 -0
  562. /package/{build/website → source}/helpers/theme.ts +0 -0
  563. /package/{build/website → source}/helpers/toc-context.ts +0 -0
  564. /package/{build/website → source}/helpers/toc.ts +0 -0
  565. /package/{build/website → source}/helpers/toc.unit.ts +0 -0
  566. /package/{build/website → source}/hooks/in-view.ts +0 -0
  567. /package/{build/website → source}/models/toc.ts +0 -0
  568. /package/{build/website → source}/plugins/rehype-inline-code.ts +0 -0
  569. /package/{build/website → source}/plugins/rehype-task-list-a11y.ts +0 -0
  570. /package/{build/website → source}/plugins/remark-abbr.ts +0 -0
  571. /package/{build/website → source}/plugins/remark-abbr.unit.ts +0 -0
  572. /package/{build/website → source}/plugins/remark-ansi.ts +0 -0
  573. /package/{build/website → source}/plugins/remark-ansi.unit.ts +0 -0
  574. /package/{build/website → source}/plugins/remark-badge.ts +0 -0
  575. /package/{build/website → source}/plugins/remark-badge.unit.ts +0 -0
  576. /package/{build/website → source}/plugins/remark-button.ts +0 -0
  577. /package/{build/website → source}/plugins/remark-button.unit.ts +0 -0
  578. /package/{build/website → source}/plugins/remark-callout.ts +0 -0
  579. /package/{build/website → source}/plugins/remark-card.ts +0 -0
  580. /package/{build/website → source}/plugins/remark-code-tabs.ts +0 -0
  581. /package/{build/website → source}/plugins/remark-columns.ts +0 -0
  582. /package/{build/website → source}/plugins/remark-custom-heading-id.ts +0 -0
  583. /package/{build/website → source}/plugins/remark-custom-heading-id.unit.ts +0 -0
  584. /package/{build/website → source}/plugins/remark-deflist.ts +0 -0
  585. /package/{build/website → source}/plugins/remark-details.ts +0 -0
  586. /package/{build/website → source}/plugins/remark-filetree.ts +0 -0
  587. /package/{build/website → source}/plugins/remark-filetree.unit.ts +0 -0
  588. /package/{build/website → source}/plugins/remark-github-callout.ts +0 -0
  589. /package/{build/website → source}/plugins/remark-icon.ts +0 -0
  590. /package/{build/website → source}/plugins/remark-image.ts +0 -0
  591. /package/{build/website → source}/plugins/remark-media.ts +0 -0
  592. /package/{build/website → source}/plugins/remark-media.unit.ts +0 -0
  593. /package/{build/website → source}/plugins/remark-mermaid.ts +0 -0
  594. /package/{build/website → source}/plugins/remark-npm.ts +0 -0
  595. /package/{build/website → source}/plugins/remark-steps.ts +0 -0
  596. /package/{build/website → source}/plugins/remark-steps.unit.ts +0 -0
  597. /package/{build/website → source}/plugins/remark-tab.ts +0 -0
  598. /package/{build/website → source}/plugins/remark-tab.unit.ts +0 -0
  599. /package/{build/website → source}/plugins/remark-toc.ts +0 -0
  600. /package/{build/website → source}/plugins/remark-toc.unit.ts +0 -0
  601. /package/{build/website → source}/plugins/shiki-icon.ts +0 -0
  602. /package/{build/website → source}/plugins/shiki-line-highlight.ts +0 -0
  603. /package/{build/website → source}/plugins/vite-livemark.ts +0 -0
  604. /package/{build/website → source}/router.tsx +0 -0
  605. /package/{build/website → source}/routes/$.tsx +0 -0
  606. /package/{build/website → source}/routes/__root.tsx +0 -0
  607. /package/{build/website → source}/server.ts +0 -0
  608. /package/{build/website → source}/styles/general.css +0 -0
  609. /package/{build/website → source}/styles/markdown.css +0 -0
  610. /package/{build/website/helpers → source/utils}/style.ts +0 -0
  611. /package/{build → target}/actions/changelog/build.unit.d.ts +0 -0
  612. /package/{build → target}/actions/config/define.d.ts +0 -0
  613. /package/{build → target}/actions/config/define.unit.d.ts +0 -0
  614. /package/{build → target}/actions/config/load.d.ts +0 -0
  615. /package/{build → target}/actions/config/load.unit.d.ts +0 -0
  616. /package/{build → target}/commands/build.d.ts +0 -0
  617. /package/{build → target}/commands/escape.d.ts +0 -0
  618. /package/{build → target}/commands/preview.d.ts +0 -0
  619. /package/{build → target}/commands/start.d.ts +0 -0
  620. /package/{build → target}/entrypoints/main.d.ts +0 -0
  621. /package/{build → target}/helpers/program.d.ts +0 -0
  622. /package/{build → target}/index.d.ts +0 -0
  623. /package/{build → target}/models/link.d.ts +0 -0
  624. /package/{build → target}/models/section.d.ts +0 -0
  625. /package/{build → target}/models/theme.d.ts +0 -0
  626. /package/{build → target}/program.d.ts +0 -0
  627. /package/{build → target}/settings.d.ts +0 -0
package/README.md CHANGED
@@ -1,7 +1,118 @@
1
1
  # Livemark
2
2
 
3
- [![Build](https://img.shields.io/github/actions/workflow/status/datisthq/livemark/general.yaml?branch=main)](https://github.com/datisthq/livemark/actions)
4
- [![Coverage](https://img.shields.io/codecov/c/github/datisthq/livemark/main)](https://codecov.io/gh/datisthq/livemark)
5
- [![Version](https://img.shields.io/npm/v/livemark)](https://www.npmjs.com/package/livemark)
3
+ Livemark turns plain Markdown into a fast, modern documentation site. Point it at a folder of `.md` files and it gives you a deployable React + Vite site with search, syntax highlighting, blog and changelog sections, dark mode, and a customizable component library — all built in.
6
4
 
7
- Livemark turns your .md files into a fast, modern documentation site — with Shiki, Mermaid, LaTeX, MDX components, blog and changelog sections, all built in. For more information, please read the [project's documentation](https://livemark.dev).
5
+ ## What you get
6
+
7
+ - 📝 **Just write Markdown.** GitHub-flavored Markdown works out of the box, with frontmatter, custom heading IDs, footnotes, definition lists, and gemoji.
8
+ - 🎨 **Beautiful code blocks.** Syntax highlighting via [Shiki](https://shiki.style/) with 100+ languages, dual light/dark themes, line highlights, diffs, and TwoSlash type hints.
9
+ - 📊 **Diagrams and math.** [Mermaid](https://mermaid.js.org/) flowcharts and KaTeX equations, theme-aware, zero config.
10
+ - 🧩 **Rich elements.** Callouts, tabs, file trees, cards, columns, badges, package tabs (npm/pnpm/yarn/bun), embeds (YouTube, SoundCloud), and more — all as Markdown directives or MDX components.
11
+ - 📚 **Sections.** First-class support for docs, blog (with tags + RSS), and changelog (local `CHANGELOG.md` or GitHub releases).
12
+ - 🔍 **Search.** Full-text search powered by [Orama](https://oramasearch.com/), keyboard shortcuts, smart table-of-contents.
13
+ - 🌗 **Themable.** Tailwind v4, shadcn-style primitives, dark mode, and per-file overrides via a `.livemark/` folder.
14
+ - ⚡ **Built on TanStack Start.** SSR, prerendering, sitemap, and routing for free.
15
+
16
+ ## Quick start
17
+
18
+ You need [Node.js](https://nodejs.org/) 24+ and a package manager (pnpm, npm, yarn, or bun).
19
+
20
+ ### Install
21
+
22
+ ```bash
23
+ npm install livemark
24
+ ```
25
+
26
+ ### Configure
27
+
28
+ Create `livemark.config.ts` at the root of your project:
29
+
30
+ ```ts title="livemark.config.ts"
31
+ import { defineConfig } from "livemark"
32
+
33
+ export default defineConfig({
34
+ title: "My docs",
35
+ description: "Documentation for my project",
36
+ include: ["docs/**/*.md"],
37
+ })
38
+ ```
39
+
40
+ ### Add content
41
+
42
+ ```text title="docs/"
43
+ docs/
44
+ ├── getting-started.md
45
+ └── usage.md
46
+ ```
47
+
48
+ Each `.md` file supports frontmatter:
49
+
50
+ ```md title="docs/getting-started.md"
51
+ ---
52
+ title: Getting Started
53
+ description: Set up the project in five minutes.
54
+ icon: rocket
55
+ order: 1
56
+ ---
57
+
58
+ # Getting Started
59
+
60
+ Welcome!
61
+ ```
62
+
63
+ ### Run
64
+
65
+ ```bash
66
+ npx livemark start # dev server with HMR at http://localhost:8000
67
+ npx livemark build # production build to .livemark/build/
68
+ npx livemark preview # serve the production build locally
69
+ ```
70
+
71
+ That's the whole loop.
72
+
73
+ ## Project structure
74
+
75
+ A typical Livemark site:
76
+
77
+ ```text title="my-project/"
78
+ my-project/
79
+ ├── livemark.config.ts # configuration
80
+ ├── docs/ # markdown content
81
+ ├── blog/ # blog posts (optional)
82
+ ├── CHANGELOG.md # changelog source (optional)
83
+ └── .livemark/ # overrides + build cache (generated)
84
+ ```
85
+
86
+ Anything under `.livemark/components/`, `.livemark/elements/`, or `.livemark/styles/` shadows the Livemark default with the same path — so you can customize components, primitives, and base CSS without forking the package. Run `npx livemark escape <path>` to copy a default into `.livemark/` ready to edit.
87
+
88
+ ## Customization
89
+
90
+ Livemark is meant to look great with zero configuration and stay out of your way when you need more. Common customizations:
91
+
92
+ - **Site metadata** — title, description, favicon, logo. See the [Site Metadata guide](https://livemark.dev/customization/site-metadata/).
93
+ - **Sections** — split content into Docs / Blog / Changelog with their own URL prefixes. See [Sections](https://livemark.dev/customization/sections/).
94
+ - **Navigation links** — header and sidebar links to anywhere. See [Navigation Links](https://livemark.dev/customization/navigation-links/).
95
+ - **Syntax themes** — Shiki theme per light/dark. See [Syntax Themes](https://livemark.dev/customization/syntax-themes/).
96
+ - **Content patches** — override a markdown file's frontmatter from `livemark.config.ts` without touching the file. See [Content Patches](https://livemark.dev/customization/content-patches/).
97
+ - **File overrides** — replace any built-in component or stylesheet from your project. See [File Overrides](https://livemark.dev/customization/file-overrides/).
98
+ - **Custom routes** — drop a `.tsx` file into `.livemark/routes/` to add a fully custom page. See [Custom Routes](https://livemark.dev/customization/custom-routes/).
99
+
100
+ ## Documentation
101
+
102
+ Full documentation lives at **[livemark.dev](https://livemark.dev)**:
103
+
104
+ - [Markdown reference](https://livemark.dev/markdown/) — every Markdown / MDX feature with examples
105
+ - [Customization](https://livemark.dev/customization/) — every knob, with copy-pasteable snippets
106
+ - [Changelog](https://livemark.dev/changelog/) — release notes
107
+ - [Contributing](https://livemark.dev/contributing/) — local setup and PR flow
108
+
109
+ ## Resources
110
+
111
+ - **npm**: [npmjs.com/package/livemark](https://www.npmjs.com/package/livemark)
112
+ - **GitHub**: [github.com/datisthq/livemark](https://github.com/datisthq/livemark)
113
+ - **Issues**: [github.com/datisthq/livemark/issues](https://github.com/datisthq/livemark/issues)
114
+ - **Discussions**: [github.com/datisthq/livemark/discussions](https://github.com/datisthq/livemark/discussions)
115
+
116
+ ## License
117
+
118
+ MIT — see [LICENSE.md](LICENSE.md).
package/package.json CHANGED
@@ -1,27 +1,28 @@
1
1
  {
2
2
  "name": "livemark",
3
- "version": "0.7.2",
3
+ "version": "0.9.0",
4
4
  "description": "Livemark description",
5
5
  "license": "MIT",
6
6
  "author": "Evgeny Karev",
7
7
  "repository": "https://github.com/datisthq/livemark",
8
8
  "bin": {
9
- "livemark": "./build/entrypoints/main.js"
9
+ "livemark": "./target/entrypoints/main.js"
10
10
  },
11
11
  "files": [
12
- "build",
12
+ "target",
13
+ "source",
14
+ "!source/routeTree.gen.ts",
13
15
  "skills"
14
16
  ],
15
17
  "type": "module",
16
18
  "sideEffects": false,
17
- "imports": {
18
- "#*": "./*"
19
- },
20
19
  "exports": {
21
- ".": "./build/index.js",
22
- "./components/*": "./build/website/components/*.tsx",
23
- "./elements/*": "./build/website/elements/*.tsx",
24
- "./styles/*": "./build/website/styles/*.css"
20
+ ".": "./target/index.js",
21
+ "./components/*": "./source/components/*.tsx",
22
+ "./elements/*": "./source/elements/*.tsx",
23
+ "./hooks/*": "./source/hooks/*.ts",
24
+ "./styles/*": "./source/styles/*.css",
25
+ "./utils/*": "./source/utils/*.ts"
25
26
  },
26
27
  "dependencies": {
27
28
  "@base-ui/react": "1.3.0",
@@ -113,11 +114,11 @@
113
114
  "pnpm": "^10.0.0"
114
115
  },
115
116
  "scripts": {
116
- "build": "tsgo && rm -rf build/website && cp -r website build",
117
+ "build": "tsgo",
117
118
  "bump": "ncu -u",
118
- "clean": "rm -rf pnpm-lock.yaml node_modules build",
119
- "docs:build": "node entrypoints/main.ts build",
120
- "docs:start": "node entrypoints/main.ts start",
119
+ "clean": "rm -rf pnpm-lock.yaml node_modules target",
120
+ "docs:build": "node source/entrypoints/main.ts build",
121
+ "docs:start": "node source/entrypoints/main.ts start",
121
122
  "format": "vp fmt",
122
123
  "lint": "vp fmt --check && vp lint",
123
124
  "release": "pnpm publish --access public --ignore-scripts --no-git-checks",
@@ -0,0 +1,245 @@
1
+ import { access, mkdir, readFile, rm, writeFile } from "node:fs/promises"
2
+ import { dirname, join, resolve } from "node:path"
3
+ import slugify from "@sindresorhus/slugify"
4
+ import type { Root, RootContent } from "mdast"
5
+ import { toString as mdastToString } from "mdast-util-to-string"
6
+ import remarkParse from "remark-parse"
7
+ import remarkStringify from "remark-stringify"
8
+ import { unified } from "unified"
9
+ import { visit } from "unist-util-visit"
10
+ import type { Config } from "../../models/config.ts"
11
+ import type { ChangelogSection } from "../../models/section.ts"
12
+ import { isGitHubUrl, parseGitHubRepo } from "../../helpers/changelog-source.ts"
13
+
14
+ interface Release {
15
+ tag_name: string
16
+ name?: string | null
17
+ published_at?: string | null
18
+ body?: string | null
19
+ html_url?: string | null
20
+ }
21
+
22
+ interface CacheMeta {
23
+ etag: string
24
+ fetchedAt: string
25
+ }
26
+
27
+ interface ChangelogEntry {
28
+ slug: string
29
+ title: string
30
+ date?: string
31
+ body: string
32
+ sourceUrl?: string
33
+ }
34
+
35
+ const CACHE_DIR = ".livemark/cache/changelog"
36
+ const META_FILE = ".livemark/cache/changelog.meta.json"
37
+
38
+ const parser = unified().use(remarkParse)
39
+ const stringifier = unified().use(remarkStringify, {
40
+ bullet: "-",
41
+ fences: true,
42
+ emphasis: "_",
43
+ })
44
+
45
+ export function cacheIncludeGlob() {
46
+ return `${CACHE_DIR}/**/*.md`
47
+ }
48
+
49
+ /** Build the per-version changelog cache files for a changelog section */
50
+ export async function buildChangelog(
51
+ section: ChangelogSection,
52
+ config: Config,
53
+ ) {
54
+ const cacheDir = join(config.root, CACHE_DIR)
55
+ const metaPath = join(config.root, META_FILE)
56
+
57
+ const entries = isGitHubUrl(section.source)
58
+ ? await buildFromGitHub(section.source, metaPath, cacheDir)
59
+ : await buildFromLocal(section.source, config.root)
60
+
61
+ if (entries === undefined) return
62
+
63
+ await rm(cacheDir, { recursive: true, force: true })
64
+ await mkdir(cacheDir, { recursive: true })
65
+
66
+ for (const entry of entries) {
67
+ const markdown = wrapFrontmatter(entry, section)
68
+ await writeFile(join(cacheDir, `${entry.slug}.md`), markdown, "utf-8")
69
+ }
70
+ }
71
+
72
+ async function buildFromLocal(source: string, root: string) {
73
+ const filePath = resolve(root, source)
74
+ const body = await readFile(filePath, "utf-8")
75
+ return splitLocalChangelog(body)
76
+ }
77
+
78
+ /** Parse CHANGELOG.md into per-version entries using mdast */
79
+ export function splitLocalChangelog(body: string): ChangelogEntry[] {
80
+ const tree = parser.parse(body) as Root
81
+ const entries: ChangelogEntry[] = []
82
+ let current: { heading: string; children: RootContent[] } | undefined
83
+
84
+ for (const child of tree.children) {
85
+ if (child.type === "heading" && child.depth === 2) {
86
+ if (current) entries.push(finalizeEntry(current))
87
+ current = { heading: mdastToString(child), children: [] }
88
+ } else if (current) {
89
+ current.children.push(child)
90
+ }
91
+ }
92
+ if (current) entries.push(finalizeEntry(current))
93
+ return entries
94
+ }
95
+
96
+ function finalizeEntry(input: {
97
+ heading: string
98
+ children: RootContent[]
99
+ }): ChangelogEntry {
100
+ const versionMatch = input.heading.match(/^\[?([^\]\s]+)\]?/)
101
+ const version = versionMatch?.[1] ?? input.heading
102
+ const dateMatch = input.heading.match(/\d{4}-\d{2}-\d{2}/)
103
+ const body = renderEntryBody(input.children)
104
+ return {
105
+ slug: slugify(version),
106
+ title: version,
107
+ date: dateMatch?.[0],
108
+ body,
109
+ }
110
+ }
111
+
112
+ /** Serialize an entry's mdast children back to markdown */
113
+ function renderEntryBody(children: RootContent[]) {
114
+ const root: Root = { type: "root", children }
115
+ return stringifier.stringify(root).trimEnd()
116
+ }
117
+
118
+ /** Drop the body's leading h1 (typically the conventional-changelog
119
+ * `# 0.7.2 (2026-04-25)` boilerplate that duplicates the article's title),
120
+ * shift h2–h6 up by one so subsection headings become h1 / h2 / …, and
121
+ * escape stray `<` outside code so MDX doesn't mistake them for JSX. */
122
+ function processBody(body: string) {
123
+ const tree = parser.parse(body) as Root
124
+ visit(tree, "heading", node => {
125
+ if (node.depth > 1) node.depth = (node.depth - 1) as 1 | 2 | 3 | 4 | 5
126
+ })
127
+ if (tree.children[0]?.type === "heading" && tree.children[0].depth === 1) {
128
+ tree.children.shift()
129
+ }
130
+ return escapeMdxAngles(stringifier.stringify(tree).trimEnd())
131
+ }
132
+
133
+ /** Escape `<` to `\<` outside fenced code blocks and inline backtick spans
134
+ * so commit messages with placeholders like `<subdir>` don't get parsed as
135
+ * JSX by MDX. */
136
+ function escapeMdxAngles(markdown: string) {
137
+ let inFence = false
138
+ return markdown
139
+ .split("\n")
140
+ .map(line => {
141
+ if (line.startsWith("```")) {
142
+ inFence = !inFence
143
+ return line
144
+ }
145
+ if (inFence) return line
146
+ return line.replace(/`[^`]*`|</g, match =>
147
+ match === "<" ? "\\<" : match,
148
+ )
149
+ })
150
+ .join("\n")
151
+ }
152
+
153
+ async function buildFromGitHub(
154
+ source: string,
155
+ metaPath: string,
156
+ cacheDir: string,
157
+ ): Promise<ChangelogEntry[] | undefined> {
158
+ const parsed = parseGitHubRepo(source)
159
+ if (!parsed) {
160
+ throw new Error(`Could not parse GitHub repo from source: ${source}`)
161
+ }
162
+
163
+ const url = `https://api.github.com/repos/${parsed.owner}/${parsed.repo}/releases?per_page=100`
164
+ const headers: Record<string, string> = {
165
+ Accept: "application/vnd.github+json",
166
+ "X-GitHub-Api-Version": "2022-11-28",
167
+ }
168
+
169
+ const token = process.env.GITHUB_TOKEN
170
+ if (token) headers.Authorization = `Bearer ${token}`
171
+
172
+ const meta = await readMeta(metaPath)
173
+ const hasCache = await exists(cacheDir)
174
+ if (meta && hasCache) headers["If-None-Match"] = meta.etag
175
+
176
+ const res = await fetch(url, { headers })
177
+
178
+ if (res.status === 304) return undefined
179
+
180
+ if (!res.ok) {
181
+ const remaining = res.headers.get("x-ratelimit-remaining")
182
+ const reset = res.headers.get("x-ratelimit-reset")
183
+ const msg = `GitHub API ${res.status} ${res.statusText} (rate-limit remaining: ${remaining ?? "?"}, reset: ${reset ?? "?"})`
184
+ if (hasCache) {
185
+ console.warn(`${msg} — falling back to cached changelog`)
186
+ return undefined
187
+ }
188
+ throw new Error(msg)
189
+ }
190
+
191
+ const releases = (await res.json()) as Release[]
192
+ const etag = res.headers.get("etag")
193
+ if (etag) {
194
+ await mkdir(dirname(metaPath), { recursive: true })
195
+ await writeFile(
196
+ metaPath,
197
+ JSON.stringify(
198
+ { etag, fetchedAt: new Date().toISOString() } satisfies CacheMeta,
199
+ null,
200
+ 2,
201
+ ),
202
+ "utf-8",
203
+ )
204
+ }
205
+
206
+ return releases.map(release => ({
207
+ slug: slugify(release.tag_name),
208
+ title: release.tag_name,
209
+ date: release.published_at ?? undefined,
210
+ body: (release.body ?? "").trim(),
211
+ sourceUrl: release.html_url ?? undefined,
212
+ }))
213
+ }
214
+
215
+ function wrapFrontmatter(entry: ChangelogEntry, section: ChangelogSection) {
216
+ const lines = [
217
+ "---",
218
+ `title: ${entry.title}`,
219
+ `path: ${section.prefix}${entry.slug}/`,
220
+ ]
221
+ if (entry.date) lines.push(`date: ${entry.date}`)
222
+ if (entry.sourceUrl) {
223
+ lines.push(`sourceUrl: ${entry.sourceUrl}`, "sourceAction: view")
224
+ }
225
+ lines.push("---", "", `# ${entry.title}`, "", processBody(entry.body))
226
+ return lines.join("\n")
227
+ }
228
+
229
+ async function readMeta(metaPath: string): Promise<CacheMeta | undefined> {
230
+ try {
231
+ const raw = await readFile(metaPath, "utf-8")
232
+ return JSON.parse(raw) as CacheMeta
233
+ } catch {
234
+ return undefined
235
+ }
236
+ }
237
+
238
+ async function exists(path: string) {
239
+ try {
240
+ await access(path)
241
+ return true
242
+ } catch {
243
+ return false
244
+ }
245
+ }
@@ -0,0 +1,69 @@
1
+ import { describe, expect, it } from "vite-plus/test"
2
+ import { splitLocalChangelog } from "./build.ts"
3
+
4
+ describe("splitLocalChangelog", () => {
5
+ it("splits by h2 headings", () => {
6
+ const input = `# Changelog
7
+
8
+ ## [0.2.0] - 2026-04-15
9
+
10
+ ### Added
11
+
12
+ - Foo
13
+
14
+ ## [0.1.0] - 2026-04-10
15
+
16
+ Initial release.
17
+ `
18
+ const entries = splitLocalChangelog(input)
19
+ expect(entries).toHaveLength(2)
20
+ expect(entries[0]?.title).toBe("0.2.0")
21
+ expect(entries[0]?.date).toBe("2026-04-15")
22
+ expect(entries[0]?.slug).toBe("0-2-0")
23
+ expect(entries[1]?.title).toBe("0.1.0")
24
+ expect(entries[1]?.date).toBe("2026-04-10")
25
+ })
26
+
27
+ it("preserves h3 heading structure in body", () => {
28
+ const input = `## 1.0.0
29
+
30
+ ### Added
31
+
32
+ - Thing one
33
+ `
34
+ const entries = splitLocalChangelog(input)
35
+ expect(entries[0]?.body).toContain("### Added")
36
+ expect(entries[0]?.body).toContain("- Thing one")
37
+ })
38
+
39
+ it("ignores ## inside fenced code blocks", () => {
40
+ const input = `## 1.0.0
41
+
42
+ Some prose.
43
+
44
+ \`\`\`md
45
+ ## Not a real version heading
46
+ \`\`\`
47
+
48
+ ## 0.9.0
49
+
50
+ Older.
51
+ `
52
+ const entries = splitLocalChangelog(input)
53
+ expect(entries).toHaveLength(2)
54
+ expect(entries[0]?.title).toBe("1.0.0")
55
+ expect(entries[0]?.body).toContain("Not a real version heading")
56
+ expect(entries[1]?.title).toBe("0.9.0")
57
+ })
58
+
59
+ it("handles bare version headings without brackets or date", () => {
60
+ const input = `## v1.2.3
61
+
62
+ Release notes.
63
+ `
64
+ const entries = splitLocalChangelog(input)
65
+ expect(entries[0]?.title).toBe("v1.2.3")
66
+ expect(entries[0]?.slug).toBe("v1-2-3")
67
+ expect(entries[0]?.date).toBeUndefined()
68
+ })
69
+ })
@@ -0,0 +1,11 @@
1
+ import type { z } from "zod"
2
+ import { UserConfig } from "../../models/config.ts"
3
+
4
+ /**
5
+ * Validate and fill defaults for a partial config object.
6
+ */
7
+ export function defineConfig(
8
+ input: z.input<typeof UserConfig>,
9
+ ): z.output<typeof UserConfig> {
10
+ return UserConfig.parse(input)
11
+ }
@@ -0,0 +1,33 @@
1
+ import { describe, expect, it } from "vite-plus/test"
2
+ import { defineConfig } from "./define.ts"
3
+
4
+ describe("defineConfig", () => {
5
+ it("should accept include as a string", () => {
6
+ const config = defineConfig({ include: "articles/**/*.mdx" })
7
+ expect(config.include).toBe("articles/**/*.mdx")
8
+ })
9
+
10
+ it("should accept include as an array", () => {
11
+ const config = defineConfig({
12
+ include: ["articles/**/*.mdx", "guides/**/*.mdx"],
13
+ })
14
+ expect(config.include).toEqual(["articles/**/*.mdx", "guides/**/*.mdx"])
15
+ })
16
+
17
+ it("should accept optional exclude", () => {
18
+ const config = defineConfig({
19
+ include: "**/*.mdx",
20
+ exclude: "drafts/**",
21
+ })
22
+ expect(config.exclude).toBe("drafts/**")
23
+ })
24
+
25
+ it("should allow omitting exclude", () => {
26
+ const config = defineConfig({ include: "**/*.mdx" })
27
+ expect(config.exclude).toBeUndefined()
28
+ })
29
+
30
+ it("should reject missing include", () => {
31
+ expect(() => defineConfig({} as any)).toThrow()
32
+ })
33
+ })
@@ -0,0 +1,22 @@
1
+ import { dirname, resolve } from "node:path"
2
+ import { pathToFileURL } from "node:url"
3
+ import type { z } from "zod"
4
+ import type { Config } from "../../models/config.ts"
5
+ import { UserConfig } from "../../models/config.ts"
6
+ import { defineConfig } from "./define.ts"
7
+
8
+ /**
9
+ * Load and validate a config file, checking --config/-c CLI arg, then cwd.
10
+ */
11
+ export async function loadConfig(path?: string): Promise<Config> {
12
+ const configIndex = process.argv.findIndex(
13
+ a => a === "-c" || a === "--config",
14
+ )
15
+ const cliPath = configIndex !== -1 ? process.argv[configIndex + 1] : undefined
16
+ const resolved = resolve(path ?? cliPath ?? "livemark.config.ts")
17
+ // Cache-bust the ESM import so dev-server restart reloads edits on disk.
18
+ const url = `${pathToFileURL(resolved).href}?t=${Date.now()}`
19
+ const module: Record<string, unknown> = await import(url)
20
+ const input = defineConfig(module.default as z.input<typeof UserConfig>)
21
+ return { ...input, root: dirname(resolved), configPath: resolved }
22
+ }
@@ -0,0 +1,30 @@
1
+ import fs from "node:fs"
2
+ import { join } from "node:path"
3
+ import { temporaryDirectoryTask } from "tempy"
4
+ import { describe, expect, it } from "vite-plus/test"
5
+ import { loadConfig } from "./load.ts"
6
+
7
+ describe("loadConfig", () => {
8
+ it("should throw when no config file exists", async () => {
9
+ await expect(loadConfig("/nonexistent/config.ts")).rejects.toThrow()
10
+ })
11
+
12
+ it("should load config from explicit path", () =>
13
+ temporaryDirectoryTask(async tmpDir => {
14
+ const configPath = join(tmpDir, "livemark.config.ts")
15
+ fs.writeFileSync(
16
+ configPath,
17
+ 'export default { include: "articles/**/*.mdx" }\n',
18
+ )
19
+ const config = await loadConfig(configPath)
20
+ expect(config.include).toBe("articles/**/*.mdx")
21
+ expect(config.root).toBe(tmpDir)
22
+ }))
23
+
24
+ it("should validate loaded config", () =>
25
+ temporaryDirectoryTask(async tmpDir => {
26
+ const configPath = join(tmpDir, "livemark.config.ts")
27
+ fs.writeFileSync(configPath, "export default {}\n")
28
+ await expect(loadConfig(configPath)).rejects.toThrow()
29
+ }))
30
+ })
@@ -0,0 +1,21 @@
1
+ import { join } from "node:path"
2
+ import { Command } from "commander"
3
+ import { createBuilder } from "vite"
4
+
5
+ const configFile = join(
6
+ import.meta.dirname,
7
+ "..",
8
+ "..",
9
+ "source",
10
+ "vite.config.ts",
11
+ )
12
+
13
+ /**
14
+ * Build the site for production.
15
+ */
16
+ export const build = new Command("build")
17
+ .description("Build the site for production")
18
+ .action(async () => {
19
+ const builder = await createBuilder({ configFile })
20
+ await builder.buildApp()
21
+ })