livemark 0.7.2 → 0.8.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 (626) hide show
  1. package/package.json +14 -14
  2. package/source/actions/changelog/build.ts +245 -0
  3. package/source/actions/changelog/build.unit.ts +69 -0
  4. package/source/actions/config/define.ts +11 -0
  5. package/source/actions/config/define.unit.ts +33 -0
  6. package/source/actions/config/load.ts +22 -0
  7. package/source/actions/config/load.unit.ts +30 -0
  8. package/source/commands/build.ts +21 -0
  9. package/source/commands/escape.ts +77 -0
  10. package/source/commands/preview.ts +25 -0
  11. package/source/commands/start.ts +26 -0
  12. package/{build/website → source}/components/Article.tsx +12 -2
  13. package/{build/website → source}/components/Callout.tsx +1 -1
  14. package/{build/website → source}/components/Layout.tsx +3 -14
  15. package/{build/website → source}/components/LinkButton.tsx +1 -1
  16. package/{build/website → source}/components/PageToolbar.tsx +21 -8
  17. package/{build/website → source}/components/Section.tsx +1 -1
  18. package/{build/website → source}/components/SectionHeader.tsx +1 -1
  19. package/{build/website/components/MiniSidebar.tsx → source/components/Sidebar.tsx} +21 -5
  20. package/{build/website/components/Sidebar.tsx → source/components/SidebarArticles.tsx} +22 -55
  21. package/source/components/SidebarPosts.tsx +129 -0
  22. package/source/components/SidebarReleases.tsx +85 -0
  23. package/{build/website → source}/content-collections.ts +2 -2
  24. package/{build/website → source}/elements/accordion.tsx +1 -1
  25. package/{build/website → source}/elements/alert-dialog.tsx +1 -1
  26. package/{build/website → source}/elements/alert.tsx +1 -1
  27. package/{build/website → source}/elements/aspect-ratio.tsx +1 -1
  28. package/{build/website → source}/elements/avatar.tsx +1 -1
  29. package/{build/website → source}/elements/badge.tsx +1 -1
  30. package/{build/website → source}/elements/breadcrumb.tsx +1 -1
  31. package/{build/website → source}/elements/button-group.tsx +1 -1
  32. package/{build/website → source}/elements/button.tsx +1 -1
  33. package/{build/website → source}/elements/calendar.tsx +1 -1
  34. package/{build/website → source}/elements/card.tsx +1 -1
  35. package/{build/website → source}/elements/carousel.tsx +1 -1
  36. package/{build/website → source}/elements/chart.tsx +1 -1
  37. package/{build/website → source}/elements/checkbox.tsx +1 -1
  38. package/{build/website → source}/elements/command.tsx +1 -1
  39. package/{build/website → source}/elements/context-menu.tsx +1 -1
  40. package/{build/website → source}/elements/dialog.tsx +1 -1
  41. package/{build/website → source}/elements/drawer.tsx +1 -1
  42. package/{build/website → source}/elements/dropdown-menu.tsx +1 -1
  43. package/{build/website → source}/elements/empty.tsx +1 -1
  44. package/{build/website → source}/elements/field.tsx +1 -1
  45. package/{build/website → source}/elements/hover-card.tsx +1 -1
  46. package/{build/website → source}/elements/input-group.tsx +1 -1
  47. package/{build/website → source}/elements/input-otp.tsx +1 -1
  48. package/{build/website → source}/elements/input.tsx +1 -1
  49. package/{build/website → source}/elements/item.tsx +1 -1
  50. package/{build/website → source}/elements/kbd.tsx +1 -1
  51. package/{build/website → source}/elements/label.tsx +1 -1
  52. package/{build/website → source}/elements/menubar.tsx +1 -1
  53. package/{build/website → source}/elements/native-select.tsx +1 -1
  54. package/{build/website → source}/elements/navigation-menu.tsx +1 -1
  55. package/{build/website → source}/elements/pagination.tsx +1 -1
  56. package/{build/website → source}/elements/popover.tsx +1 -1
  57. package/{build/website → source}/elements/progress.tsx +1 -1
  58. package/{build/website → source}/elements/radio-group.tsx +1 -1
  59. package/{build/website → source}/elements/resizable.tsx +1 -1
  60. package/{build/website → source}/elements/scroll-area.tsx +1 -1
  61. package/{build/website → source}/elements/select.tsx +1 -1
  62. package/{build/website → source}/elements/separator.tsx +1 -1
  63. package/{build/website → source}/elements/sheet.tsx +1 -1
  64. package/{build/website → source}/elements/sidebar.tsx +7 -4
  65. package/{build/website → source}/elements/skeleton.tsx +1 -1
  66. package/{build/website → source}/elements/slider.tsx +1 -1
  67. package/{build/website → source}/elements/spinner.tsx +1 -1
  68. package/{build/website → source}/elements/switch.tsx +1 -1
  69. package/{build/website → source}/elements/table.tsx +1 -1
  70. package/{build/website → source}/elements/tabs.tsx +1 -1
  71. package/{build/website → source}/elements/textarea.tsx +1 -1
  72. package/{build/website → source}/elements/toggle-group.tsx +1 -1
  73. package/{build/website → source}/elements/toggle.tsx +1 -1
  74. package/{build/website → source}/elements/tooltip.tsx +1 -1
  75. package/source/entrypoints/main.ts +12 -0
  76. package/{build/website → source}/env.d.ts +1 -1
  77. package/source/helpers/program.ts +6 -0
  78. package/{build/website → source}/helpers/section.ts +1 -1
  79. package/source/hooks/media.ts +29 -0
  80. package/source/index.ts +1 -0
  81. package/{build/website → source}/models/article.ts +4 -0
  82. package/source/models/config.ts +51 -0
  83. package/source/models/link.ts +11 -0
  84. package/source/models/patch.ts +9 -0
  85. package/source/models/section.ts +45 -0
  86. package/source/models/theme.ts +74 -0
  87. package/source/program.ts +18 -0
  88. package/source/settings.ts +6 -0
  89. package/{build/website → source}/vite.config.ts +3 -3
  90. package/{build → target}/actions/changelog/build.d.ts +1 -0
  91. package/target/actions/changelog/build.js +187 -0
  92. package/target/actions/changelog/build.unit.js +66 -0
  93. package/target/actions/config/define.js +8 -0
  94. package/target/actions/config/define.unit.js +29 -0
  95. package/target/actions/config/load.js +25 -0
  96. package/target/actions/config/load.unit.js +23 -0
  97. package/target/client.d.ts +1 -0
  98. package/target/client.js +6 -0
  99. package/target/commands/build.js +14 -0
  100. package/target/commands/escape.js +56 -0
  101. package/target/commands/preview.js +18 -0
  102. package/target/commands/start.js +19 -0
  103. package/target/components/Abbr.d.ts +5 -0
  104. package/target/components/Abbr.js +9 -0
  105. package/target/components/AnsiCode.d.ts +4 -0
  106. package/target/components/AnsiCode.js +6 -0
  107. package/target/components/Article.d.ts +5 -0
  108. package/target/components/Article.js +105 -0
  109. package/target/components/BackToTop.d.ts +3 -0
  110. package/target/components/BackToTop.js +19 -0
  111. package/target/components/Banner.d.ts +2 -0
  112. package/target/components/Banner.js +12 -0
  113. package/target/components/BlogIndex.d.ts +4 -0
  114. package/target/components/BlogIndex.js +62 -0
  115. package/target/components/Breadcrumbs.d.ts +1 -0
  116. package/target/components/Breadcrumbs.js +13 -0
  117. package/target/components/Callout.d.ts +8 -0
  118. package/target/components/Callout.js +43 -0
  119. package/target/components/Card.d.ts +7 -0
  120. package/target/components/Card.js +17 -0
  121. package/target/components/Cards.d.ts +4 -0
  122. package/target/components/Cards.js +6 -0
  123. package/target/components/ChangelogIndex.d.ts +4 -0
  124. package/target/components/ChangelogIndex.js +57 -0
  125. package/target/components/CodeBlock.d.ts +1 -0
  126. package/target/components/CodeBlock.js +47 -0
  127. package/target/components/CodeTabs.d.ts +6 -0
  128. package/target/components/CodeTabs.js +49 -0
  129. package/target/components/Column.d.ts +4 -0
  130. package/target/components/Column.js +6 -0
  131. package/target/components/Columns.d.ts +5 -0
  132. package/target/components/Columns.js +10 -0
  133. package/target/components/Content.d.ts +3 -0
  134. package/target/components/Content.js +5 -0
  135. package/target/components/ContentTab.d.ts +5 -0
  136. package/target/components/ContentTab.js +6 -0
  137. package/target/components/ContentTabs.d.ts +5 -0
  138. package/target/components/ContentTabs.js +47 -0
  139. package/target/components/DefaultCatchBoundary.d.ts +2 -0
  140. package/target/components/DefaultCatchBoundary.js +20 -0
  141. package/target/components/DefinitionList.d.ts +7 -0
  142. package/target/components/DefinitionList.js +14 -0
  143. package/target/components/Details.d.ts +5 -0
  144. package/target/components/Details.js +13 -0
  145. package/target/components/FileTree.d.ts +4 -0
  146. package/target/components/FileTree.js +17 -0
  147. package/target/components/Footer.d.ts +2 -0
  148. package/target/components/Footer.js +9 -0
  149. package/target/components/FootnoteRef.d.ts +3 -0
  150. package/target/components/FootnoteRef.js +31 -0
  151. package/target/components/Heading.d.ts +8 -0
  152. package/target/components/Heading.js +18 -0
  153. package/target/components/InlineBadge.d.ts +5 -0
  154. package/target/components/InlineBadge.js +7 -0
  155. package/target/components/InlineIcon.d.ts +5 -0
  156. package/target/components/InlineIcon.js +10 -0
  157. package/target/components/InlineToc.d.ts +4 -0
  158. package/target/components/InlineToc.js +14 -0
  159. package/target/components/Layout.d.ts +4 -0
  160. package/target/components/Layout.js +65 -0
  161. package/target/components/LinkButton.d.ts +7 -0
  162. package/target/components/LinkButton.js +11 -0
  163. package/target/components/Mermaid.d.ts +4 -0
  164. package/target/components/Mermaid.js +8 -0
  165. package/target/components/MermaidRenderer.d.ts +4 -0
  166. package/target/components/MermaidRenderer.js +32 -0
  167. package/target/components/NotFound.d.ts +3 -0
  168. package/target/components/NotFound.js +10 -0
  169. package/target/components/PackageTabs.d.ts +9 -0
  170. package/target/components/PackageTabs.js +28 -0
  171. package/target/components/PageToolbar.d.ts +7 -0
  172. package/target/components/PageToolbar.js +34 -0
  173. package/target/components/PrevNext.d.ts +4 -0
  174. package/target/components/PrevNext.js +34 -0
  175. package/target/components/Search.d.ts +2 -0
  176. package/target/components/Search.js +16 -0
  177. package/target/components/SearchDialog.d.ts +5 -0
  178. package/target/components/SearchDialog.js +139 -0
  179. package/target/components/Section.d.ts +5 -0
  180. package/target/components/Section.js +8 -0
  181. package/target/components/SectionHeader.d.ts +7 -0
  182. package/target/components/SectionHeader.js +7 -0
  183. package/target/components/Sidebar.d.ts +4 -0
  184. package/target/components/Sidebar.js +33 -0
  185. package/target/components/SidebarArticles.d.ts +2 -0
  186. package/target/components/SidebarArticles.js +45 -0
  187. package/target/components/SidebarLinks.d.ts +4 -0
  188. package/target/components/SidebarLinks.js +26 -0
  189. package/target/components/SidebarPosts.d.ts +2 -0
  190. package/target/components/SidebarPosts.js +53 -0
  191. package/target/components/SidebarReleases.d.ts +2 -0
  192. package/target/components/SidebarReleases.js +35 -0
  193. package/target/components/SidebarSections.d.ts +4 -0
  194. package/target/components/SidebarSections.js +36 -0
  195. package/target/components/SiteTitle.d.ts +2 -0
  196. package/target/components/SiteTitle.js +12 -0
  197. package/target/components/SortableTable.d.ts +5 -0
  198. package/target/components/SortableTable.js +63 -0
  199. package/target/components/SoundCloud.d.ts +4 -0
  200. package/target/components/SoundCloud.js +7 -0
  201. package/target/components/TagIndex.d.ts +5 -0
  202. package/target/components/TagIndex.js +64 -0
  203. package/target/components/Theme.d.ts +1 -0
  204. package/target/components/Theme.js +21 -0
  205. package/target/components/Toc.d.ts +12 -0
  206. package/target/components/Toc.js +128 -0
  207. package/target/components/YouTube.d.ts +4 -0
  208. package/target/components/YouTube.js +6 -0
  209. package/target/components/ZoomImage.d.ts +4 -0
  210. package/target/components/ZoomImage.js +26 -0
  211. package/target/content/article.d.ts +43 -0
  212. package/target/content/article.js +54 -0
  213. package/target/content/tag.d.ts +2 -0
  214. package/target/content/tag.js +30 -0
  215. package/target/content-collections.d.ts +2 -0
  216. package/target/content-collections.js +192 -0
  217. package/target/elements/accordion.d.ts +6 -0
  218. package/target/elements/accordion.js +19 -0
  219. package/target/elements/alert-dialog.d.ts +18 -0
  220. package/target/elements/alert-dialog.js +44 -0
  221. package/target/elements/alert.d.ts +9 -0
  222. package/target/elements/alert.js +28 -0
  223. package/target/elements/aspect-ratio.d.ts +4 -0
  224. package/target/elements/aspect-ratio.js +9 -0
  225. package/target/elements/avatar.d.ts +11 -0
  226. package/target/elements/avatar.js +23 -0
  227. package/target/elements/badge.d.ts +7 -0
  228. package/target/elements/badge.js +34 -0
  229. package/target/elements/breadcrumb.d.ts +9 -0
  230. package/target/elements/breadcrumb.js +39 -0
  231. package/target/elements/button-group.d.ts +10 -0
  232. package/target/elements/button-group.js +37 -0
  233. package/target/elements/button.d.ts +8 -0
  234. package/target/elements/button.js +35 -0
  235. package/target/elements/calendar.d.ts +10 -0
  236. package/target/elements/calendar.js +76 -0
  237. package/target/elements/card.d.ts +11 -0
  238. package/target/elements/card.js +25 -0
  239. package/target/elements/carousel.d.ts +28 -0
  240. package/target/elements/carousel.js +95 -0
  241. package/target/elements/chart.d.ts +44 -0
  242. package/target/elements/chart.js +140 -0
  243. package/target/elements/checkbox.d.ts +3 -0
  244. package/target/elements/checkbox.js +9 -0
  245. package/target/elements/collapsible.d.ts +5 -0
  246. package/target/elements/collapsible.js +13 -0
  247. package/target/elements/command.d.ts +23 -0
  248. package/target/elements/command.js +42 -0
  249. package/target/elements/context-menu.d.ts +29 -0
  250. package/target/elements/context-menu.js +54 -0
  251. package/target/elements/dialog.d.ts +16 -0
  252. package/target/elements/dialog.js +41 -0
  253. package/target/elements/direction.d.ts +1 -0
  254. package/target/elements/direction.js +2 -0
  255. package/target/elements/drawer.d.ts +12 -0
  256. package/target/elements/drawer.js +38 -0
  257. package/target/elements/dropdown-menu.d.ts +24 -0
  258. package/target/elements/dropdown-menu.js +54 -0
  259. package/target/elements/empty.d.ts +11 -0
  260. package/target/elements/empty.js +34 -0
  261. package/target/elements/field.d.ts +24 -0
  262. package/target/elements/field.js +69 -0
  263. package/target/elements/hover-card.d.ts +5 -0
  264. package/target/elements/hover-card.js +14 -0
  265. package/target/elements/input-group.d.ts +18 -0
  266. package/target/elements/input-group.js +60 -0
  267. package/target/elements/input-otp.d.ts +11 -0
  268. package/target/elements/input-otp.js +21 -0
  269. package/target/elements/input.d.ts +2 -0
  270. package/target/elements/input.js +8 -0
  271. package/target/elements/item.d.ts +21 -0
  272. package/target/elements/item.js +79 -0
  273. package/target/elements/kbd.d.ts +3 -0
  274. package/target/elements/kbd.js +10 -0
  275. package/target/elements/label.d.ts +2 -0
  276. package/target/elements/label.js +8 -0
  277. package/target/elements/menubar.d.ts +29 -0
  278. package/target/elements/menubar.js +58 -0
  279. package/target/elements/native-select.d.ts +8 -0
  280. package/target/elements/native-select.js +16 -0
  281. package/target/elements/navigation-menu.d.ts +11 -0
  282. package/target/elements/navigation-menu.js +34 -0
  283. package/target/elements/pagination.d.ts +17 -0
  284. package/target/elements/pagination.js +33 -0
  285. package/target/elements/popover.d.ts +9 -0
  286. package/target/elements/popover.js +23 -0
  287. package/target/elements/progress.d.ts +7 -0
  288. package/target/elements/progress.js +21 -0
  289. package/target/elements/radio-group.d.ts +5 -0
  290. package/target/elements/radio-group.js +12 -0
  291. package/target/elements/resizable.d.ts +7 -0
  292. package/target/elements/resizable.js +14 -0
  293. package/target/elements/scroll-area.d.ts +4 -0
  294. package/target/elements/scroll-area.js +13 -0
  295. package/target/elements/select.d.ts +15 -0
  296. package/target/elements/select.js +39 -0
  297. package/target/elements/separator.d.ts +3 -0
  298. package/target/elements/separator.js +8 -0
  299. package/target/elements/sheet.d.ts +13 -0
  300. package/target/elements/sheet.js +41 -0
  301. package/target/elements/sidebar.d.ts +63 -0
  302. package/target/elements/sidebar.js +272 -0
  303. package/target/elements/skeleton.d.ts +2 -0
  304. package/target/elements/skeleton.js +7 -0
  305. package/target/elements/slider.d.ts +3 -0
  306. package/target/elements/slider.js +15 -0
  307. package/target/elements/sonner.d.ts +3 -0
  308. package/target/elements/sonner.js +23 -0
  309. package/target/elements/spinner.d.ts +2 -0
  310. package/target/elements/spinner.js +8 -0
  311. package/target/elements/switch.d.ts +5 -0
  312. package/target/elements/switch.js +8 -0
  313. package/target/elements/table.d.ts +9 -0
  314. package/target/elements/table.js +28 -0
  315. package/target/elements/tabs.d.ts +10 -0
  316. package/target/elements/tabs.js +29 -0
  317. package/target/elements/textarea.d.ts +2 -0
  318. package/target/elements/textarea.js +7 -0
  319. package/target/elements/toggle-group.d.ts +10 -0
  320. package/target/elements/toggle-group.js +24 -0
  321. package/target/elements/toggle.d.ts +8 -0
  322. package/target/elements/toggle.js +26 -0
  323. package/target/elements/tooltip.d.ts +6 -0
  324. package/target/elements/tooltip.js +18 -0
  325. package/target/entrypoints/main.js +12 -0
  326. package/target/helpers/article-icon.d.ts +3 -0
  327. package/target/helpers/article-icon.js +34 -0
  328. package/target/helpers/article.d.ts +24 -0
  329. package/target/helpers/article.js +73 -0
  330. package/target/helpers/changelog-source.d.ts +7 -0
  331. package/target/helpers/changelog-source.js +16 -0
  332. package/target/helpers/changelog-source.unit.d.ts +1 -0
  333. package/target/helpers/changelog-source.unit.js +33 -0
  334. package/target/helpers/dynamic-icon-resolver.d.ts +5 -0
  335. package/target/helpers/dynamic-icon-resolver.js +17 -0
  336. package/target/helpers/dynamic-icon.d.ts +5 -0
  337. package/target/helpers/dynamic-icon.js +8 -0
  338. package/target/helpers/favicon.d.ts +2 -0
  339. package/target/helpers/favicon.js +11 -0
  340. package/target/helpers/model.d.ts +3 -0
  341. package/target/helpers/model.js +4 -0
  342. package/target/helpers/program.js +5 -0
  343. package/target/helpers/resolve-asset-path.d.ts +2 -0
  344. package/target/helpers/resolve-asset-path.js +9 -0
  345. package/target/helpers/resolve-includes.d.ts +2 -0
  346. package/target/helpers/resolve-includes.js +113 -0
  347. package/target/helpers/resolve-includes.unit.d.ts +1 -0
  348. package/target/helpers/resolve-includes.unit.js +76 -0
  349. package/target/helpers/search-text.d.ts +2 -0
  350. package/target/helpers/search-text.js +16 -0
  351. package/target/helpers/section.d.ts +13 -0
  352. package/target/helpers/section.js +39 -0
  353. package/target/helpers/section.unit.d.ts +1 -0
  354. package/target/helpers/section.unit.js +62 -0
  355. package/target/helpers/theme.d.ts +5 -0
  356. package/target/helpers/theme.js +23 -0
  357. package/target/helpers/toc-context.d.ts +5 -0
  358. package/target/helpers/toc-context.js +8 -0
  359. package/target/helpers/toc.d.ts +3 -0
  360. package/target/helpers/toc.js +41 -0
  361. package/target/helpers/toc.unit.d.ts +1 -0
  362. package/target/helpers/toc.unit.js +65 -0
  363. package/target/hooks/in-view.d.ts +4 -0
  364. package/target/hooks/in-view.js +23 -0
  365. package/target/hooks/media.d.ts +6 -0
  366. package/target/hooks/media.js +25 -0
  367. package/target/index.js +2 -0
  368. package/target/models/article.d.ts +57 -0
  369. package/target/models/article.js +21 -0
  370. package/{build → target}/models/config.d.ts +10 -0
  371. package/target/models/config.js +34 -0
  372. package/target/models/link.js +9 -0
  373. package/{build → target}/models/patch.d.ts +5 -0
  374. package/target/models/patch.js +7 -0
  375. package/target/models/section.js +26 -0
  376. package/target/models/theme.js +73 -0
  377. package/target/models/toc.d.ts +5 -0
  378. package/target/models/toc.js +2 -0
  379. package/target/plugins/rehype-inline-code.d.ts +19 -0
  380. package/target/plugins/rehype-inline-code.js +55 -0
  381. package/target/plugins/rehype-task-list-a11y.d.ts +10 -0
  382. package/target/plugins/rehype-task-list-a11y.js +29 -0
  383. package/target/plugins/remark-abbr.d.ts +6 -0
  384. package/target/plugins/remark-abbr.js +39 -0
  385. package/target/plugins/remark-abbr.unit.d.ts +1 -0
  386. package/target/plugins/remark-abbr.unit.js +79 -0
  387. package/target/plugins/remark-ansi.d.ts +8 -0
  388. package/target/plugins/remark-ansi.js +239 -0
  389. package/target/plugins/remark-ansi.unit.d.ts +1 -0
  390. package/target/plugins/remark-ansi.unit.js +134 -0
  391. package/target/plugins/remark-badge.d.ts +6 -0
  392. package/target/plugins/remark-badge.js +43 -0
  393. package/target/plugins/remark-badge.unit.d.ts +1 -0
  394. package/target/plugins/remark-badge.unit.js +76 -0
  395. package/target/plugins/remark-button.d.ts +6 -0
  396. package/target/plugins/remark-button.js +52 -0
  397. package/target/plugins/remark-button.unit.d.ts +1 -0
  398. package/target/plugins/remark-button.unit.js +105 -0
  399. package/target/plugins/remark-callout.d.ts +4 -0
  400. package/target/plugins/remark-callout.js +39 -0
  401. package/target/plugins/remark-card.d.ts +4 -0
  402. package/target/plugins/remark-card.js +66 -0
  403. package/target/plugins/remark-code-tabs.d.ts +4 -0
  404. package/target/plugins/remark-code-tabs.js +72 -0
  405. package/target/plugins/remark-columns.d.ts +4 -0
  406. package/target/plugins/remark-columns.js +54 -0
  407. package/target/plugins/remark-custom-heading-id.d.ts +14 -0
  408. package/target/plugins/remark-custom-heading-id.js +54 -0
  409. package/target/plugins/remark-custom-heading-id.unit.d.ts +1 -0
  410. package/target/plugins/remark-custom-heading-id.unit.js +91 -0
  411. package/target/plugins/remark-deflist.d.ts +4 -0
  412. package/target/plugins/remark-deflist.js +31 -0
  413. package/target/plugins/remark-details.d.ts +4 -0
  414. package/target/plugins/remark-details.js +33 -0
  415. package/target/plugins/remark-filetree.d.ts +12 -0
  416. package/target/plugins/remark-filetree.js +61 -0
  417. package/target/plugins/remark-filetree.unit.d.ts +1 -0
  418. package/target/plugins/remark-filetree.unit.js +87 -0
  419. package/target/plugins/remark-github-callout.d.ts +4 -0
  420. package/target/plugins/remark-github-callout.js +62 -0
  421. package/target/plugins/remark-icon.d.ts +4 -0
  422. package/target/plugins/remark-icon.js +36 -0
  423. package/target/plugins/remark-image.d.ts +9 -0
  424. package/target/plugins/remark-image.js +26 -0
  425. package/target/plugins/remark-media.d.ts +6 -0
  426. package/target/plugins/remark-media.js +52 -0
  427. package/target/plugins/remark-media.unit.d.ts +1 -0
  428. package/target/plugins/remark-media.unit.js +54 -0
  429. package/target/plugins/remark-mermaid.d.ts +4 -0
  430. package/target/plugins/remark-mermaid.js +20 -0
  431. package/target/plugins/remark-npm.d.ts +4 -0
  432. package/target/plugins/remark-npm.js +32 -0
  433. package/target/plugins/remark-steps.d.ts +6 -0
  434. package/target/plugins/remark-steps.js +30 -0
  435. package/target/plugins/remark-steps.unit.d.ts +1 -0
  436. package/target/plugins/remark-steps.unit.js +65 -0
  437. package/target/plugins/remark-tab.d.ts +6 -0
  438. package/target/plugins/remark-tab.js +76 -0
  439. package/target/plugins/remark-tab.unit.d.ts +1 -0
  440. package/target/plugins/remark-tab.unit.js +156 -0
  441. package/target/plugins/remark-toc.d.ts +6 -0
  442. package/target/plugins/remark-toc.js +33 -0
  443. package/target/plugins/remark-toc.unit.d.ts +1 -0
  444. package/target/plugins/remark-toc.unit.js +57 -0
  445. package/target/plugins/shiki-icon.d.ts +16 -0
  446. package/target/plugins/shiki-icon.js +66 -0
  447. package/target/plugins/shiki-line-highlight.d.ts +27 -0
  448. package/target/plugins/shiki-line-highlight.js +140 -0
  449. package/target/plugins/vite-livemark.d.ts +13 -0
  450. package/target/plugins/vite-livemark.js +76 -0
  451. package/target/program.js +18 -0
  452. package/target/routeTree.gen.d.ts +57 -0
  453. package/target/routeTree.gen.js +27 -0
  454. package/target/router.d.ts +6 -0
  455. package/target/router.js +26 -0
  456. package/target/routes/$.d.ts +1 -0
  457. package/target/routes/$.js +85 -0
  458. package/target/routes/__root.d.ts +1 -0
  459. package/target/routes/__root.js +69 -0
  460. package/target/server.d.ts +2 -0
  461. package/target/server.js +7 -0
  462. package/target/settings.js +7 -0
  463. package/target/utils/style.d.ts +2 -0
  464. package/target/utils/style.js +6 -0
  465. package/target/vite.config.d.ts +2 -0
  466. package/target/vite.config.js +64 -0
  467. package/build/actions/changelog/build.js +0 -158
  468. package/build/actions/changelog/build.unit.js +0 -66
  469. package/build/actions/config/define.js +0 -8
  470. package/build/actions/config/define.unit.js +0 -29
  471. package/build/actions/config/load.js +0 -25
  472. package/build/actions/config/load.unit.js +0 -23
  473. package/build/commands/build.js +0 -14
  474. package/build/commands/escape.js +0 -56
  475. package/build/commands/preview.js +0 -18
  476. package/build/commands/start.js +0 -19
  477. package/build/docs/markdown/includes/example.d.ts +0 -58
  478. package/build/docs/markdown/includes/example.js +0 -5
  479. package/build/entrypoints/main.js +0 -12
  480. package/build/helpers/program.js +0 -5
  481. package/build/index.js +0 -2
  482. package/build/livemark.config.d.ts +0 -58
  483. package/build/livemark.config.js +0 -25
  484. package/build/models/config.js +0 -34
  485. package/build/models/link.js +0 -9
  486. package/build/models/patch.js +0 -7
  487. package/build/models/section.js +0 -26
  488. package/build/models/theme.js +0 -73
  489. package/build/package.json +0 -138
  490. package/build/program.js +0 -18
  491. package/build/settings.js +0 -7
  492. package/build/vite.config.d.ts +0 -2
  493. package/build/vite.config.js +0 -48
  494. package/build/website/components/BlogSidebar.tsx +0 -162
  495. package/build/website/components/ChangelogSidebar.tsx +0 -120
  496. package/build/website/hooks/media.ts +0 -19
  497. /package/{build/website → source}/assets/logo.svg +0 -0
  498. /package/{build/website → source}/client.tsx +0 -0
  499. /package/{build/website → source}/components/Abbr.tsx +0 -0
  500. /package/{build/website → source}/components/AnsiCode.tsx +0 -0
  501. /package/{build/website → source}/components/BackToTop.tsx +0 -0
  502. /package/{build/website → source}/components/Banner.tsx +0 -0
  503. /package/{build/website → source}/components/BlogIndex.tsx +0 -0
  504. /package/{build/website → source}/components/Breadcrumbs.tsx +0 -0
  505. /package/{build/website → source}/components/Card.tsx +0 -0
  506. /package/{build/website → source}/components/Cards.tsx +0 -0
  507. /package/{build/website → source}/components/ChangelogIndex.tsx +0 -0
  508. /package/{build/website → source}/components/CodeBlock.tsx +0 -0
  509. /package/{build/website → source}/components/CodeTabs.tsx +0 -0
  510. /package/{build/website → source}/components/Column.tsx +0 -0
  511. /package/{build/website → source}/components/Columns.tsx +0 -0
  512. /package/{build/website → source}/components/Content.tsx +0 -0
  513. /package/{build/website → source}/components/ContentTab.tsx +0 -0
  514. /package/{build/website → source}/components/ContentTabs.tsx +0 -0
  515. /package/{build/website → source}/components/DefaultCatchBoundary.tsx +0 -0
  516. /package/{build/website → source}/components/DefinitionList.tsx +0 -0
  517. /package/{build/website → source}/components/Details.tsx +0 -0
  518. /package/{build/website → source}/components/FileTree.tsx +0 -0
  519. /package/{build/website → source}/components/Footer.tsx +0 -0
  520. /package/{build/website → source}/components/FootnoteRef.tsx +0 -0
  521. /package/{build/website → source}/components/Heading.tsx +0 -0
  522. /package/{build/website → source}/components/InlineBadge.tsx +0 -0
  523. /package/{build/website → source}/components/InlineIcon.tsx +0 -0
  524. /package/{build/website → source}/components/InlineToc.tsx +0 -0
  525. /package/{build/website → source}/components/Mermaid.tsx +0 -0
  526. /package/{build/website → source}/components/MermaidRenderer.tsx +0 -0
  527. /package/{build/website → source}/components/NotFound.tsx +0 -0
  528. /package/{build/website → source}/components/PackageTabs.tsx +0 -0
  529. /package/{build/website → source}/components/PrevNext.tsx +0 -0
  530. /package/{build/website → source}/components/Search.tsx +0 -0
  531. /package/{build/website → source}/components/SearchDialog.tsx +0 -0
  532. /package/{build/website → source}/components/SidebarLinks.tsx +0 -0
  533. /package/{build/website → source}/components/SidebarSections.tsx +0 -0
  534. /package/{build/website → source}/components/SiteTitle.tsx +0 -0
  535. /package/{build/website → source}/components/SortableTable.tsx +0 -0
  536. /package/{build/website → source}/components/SoundCloud.tsx +0 -0
  537. /package/{build/website → source}/components/TagIndex.tsx +0 -0
  538. /package/{build/website → source}/components/Theme.tsx +0 -0
  539. /package/{build/website → source}/components/Toc.tsx +0 -0
  540. /package/{build/website → source}/components/YouTube.tsx +0 -0
  541. /package/{build/website → source}/components/ZoomImage.tsx +0 -0
  542. /package/{build/website → source}/content/article.ts +0 -0
  543. /package/{build/website → source}/content/tag.ts +0 -0
  544. /package/{build/website → source}/elements/collapsible.tsx +0 -0
  545. /package/{build/website → source}/elements/direction.tsx +0 -0
  546. /package/{build/website → source}/elements/sonner.tsx +0 -0
  547. /package/{build/website → source}/helpers/article-icon.ts +0 -0
  548. /package/{build/website → source}/helpers/article.ts +0 -0
  549. /package/{build/website → source}/helpers/changelog-source.ts +0 -0
  550. /package/{build/website → source}/helpers/changelog-source.unit.ts +0 -0
  551. /package/{build/website → source}/helpers/dynamic-icon-resolver.tsx +0 -0
  552. /package/{build/website → source}/helpers/dynamic-icon.tsx +0 -0
  553. /package/{build/website → source}/helpers/favicon.ts +0 -0
  554. /package/{build/website → source}/helpers/model.ts +0 -0
  555. /package/{build/website → source}/helpers/resolve-asset-path.ts +0 -0
  556. /package/{build/website → source}/helpers/resolve-includes.ts +0 -0
  557. /package/{build/website → source}/helpers/resolve-includes.unit.ts +0 -0
  558. /package/{build/website → source}/helpers/search-text.ts +0 -0
  559. /package/{build/website → source}/helpers/section.unit.ts +0 -0
  560. /package/{build/website → source}/helpers/theme.ts +0 -0
  561. /package/{build/website → source}/helpers/toc-context.ts +0 -0
  562. /package/{build/website → source}/helpers/toc.ts +0 -0
  563. /package/{build/website → source}/helpers/toc.unit.ts +0 -0
  564. /package/{build/website → source}/hooks/in-view.ts +0 -0
  565. /package/{build/website → source}/models/toc.ts +0 -0
  566. /package/{build/website → source}/plugins/rehype-inline-code.ts +0 -0
  567. /package/{build/website → source}/plugins/rehype-task-list-a11y.ts +0 -0
  568. /package/{build/website → source}/plugins/remark-abbr.ts +0 -0
  569. /package/{build/website → source}/plugins/remark-abbr.unit.ts +0 -0
  570. /package/{build/website → source}/plugins/remark-ansi.ts +0 -0
  571. /package/{build/website → source}/plugins/remark-ansi.unit.ts +0 -0
  572. /package/{build/website → source}/plugins/remark-badge.ts +0 -0
  573. /package/{build/website → source}/plugins/remark-badge.unit.ts +0 -0
  574. /package/{build/website → source}/plugins/remark-button.ts +0 -0
  575. /package/{build/website → source}/plugins/remark-button.unit.ts +0 -0
  576. /package/{build/website → source}/plugins/remark-callout.ts +0 -0
  577. /package/{build/website → source}/plugins/remark-card.ts +0 -0
  578. /package/{build/website → source}/plugins/remark-code-tabs.ts +0 -0
  579. /package/{build/website → source}/plugins/remark-columns.ts +0 -0
  580. /package/{build/website → source}/plugins/remark-custom-heading-id.ts +0 -0
  581. /package/{build/website → source}/plugins/remark-custom-heading-id.unit.ts +0 -0
  582. /package/{build/website → source}/plugins/remark-deflist.ts +0 -0
  583. /package/{build/website → source}/plugins/remark-details.ts +0 -0
  584. /package/{build/website → source}/plugins/remark-filetree.ts +0 -0
  585. /package/{build/website → source}/plugins/remark-filetree.unit.ts +0 -0
  586. /package/{build/website → source}/plugins/remark-github-callout.ts +0 -0
  587. /package/{build/website → source}/plugins/remark-icon.ts +0 -0
  588. /package/{build/website → source}/plugins/remark-image.ts +0 -0
  589. /package/{build/website → source}/plugins/remark-media.ts +0 -0
  590. /package/{build/website → source}/plugins/remark-media.unit.ts +0 -0
  591. /package/{build/website → source}/plugins/remark-mermaid.ts +0 -0
  592. /package/{build/website → source}/plugins/remark-npm.ts +0 -0
  593. /package/{build/website → source}/plugins/remark-steps.ts +0 -0
  594. /package/{build/website → source}/plugins/remark-steps.unit.ts +0 -0
  595. /package/{build/website → source}/plugins/remark-tab.ts +0 -0
  596. /package/{build/website → source}/plugins/remark-tab.unit.ts +0 -0
  597. /package/{build/website → source}/plugins/remark-toc.ts +0 -0
  598. /package/{build/website → source}/plugins/remark-toc.unit.ts +0 -0
  599. /package/{build/website → source}/plugins/shiki-icon.ts +0 -0
  600. /package/{build/website → source}/plugins/shiki-line-highlight.ts +0 -0
  601. /package/{build/website → source}/plugins/vite-livemark.ts +0 -0
  602. /package/{build/website → source}/routeTree.gen.ts +0 -0
  603. /package/{build/website → source}/router.tsx +0 -0
  604. /package/{build/website → source}/routes/$.tsx +0 -0
  605. /package/{build/website → source}/routes/__root.tsx +0 -0
  606. /package/{build/website → source}/server.ts +0 -0
  607. /package/{build/website → source}/styles/general.css +0 -0
  608. /package/{build/website → source}/styles/markdown.css +0 -0
  609. /package/{build/website/helpers → source/utils}/style.ts +0 -0
  610. /package/{build → target}/actions/changelog/build.unit.d.ts +0 -0
  611. /package/{build → target}/actions/config/define.d.ts +0 -0
  612. /package/{build → target}/actions/config/define.unit.d.ts +0 -0
  613. /package/{build → target}/actions/config/load.d.ts +0 -0
  614. /package/{build → target}/actions/config/load.unit.d.ts +0 -0
  615. /package/{build → target}/commands/build.d.ts +0 -0
  616. /package/{build → target}/commands/escape.d.ts +0 -0
  617. /package/{build → target}/commands/preview.d.ts +0 -0
  618. /package/{build → target}/commands/start.d.ts +0 -0
  619. /package/{build → target}/entrypoints/main.d.ts +0 -0
  620. /package/{build → target}/helpers/program.d.ts +0 -0
  621. /package/{build → target}/index.d.ts +0 -0
  622. /package/{build → target}/models/link.d.ts +0 -0
  623. /package/{build → target}/models/section.d.ts +0 -0
  624. /package/{build → target}/models/theme.d.ts +0 -0
  625. /package/{build → target}/program.d.ts +0 -0
  626. /package/{build → target}/settings.d.ts +0 -0
package/package.json CHANGED
@@ -1,27 +1,27 @@
1
1
  {
2
2
  "name": "livemark",
3
- "version": "0.7.2",
3
+ "version": "0.8.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",
13
14
  "skills"
14
15
  ],
15
16
  "type": "module",
16
17
  "sideEffects": false,
17
- "imports": {
18
- "#*": "./*"
19
- },
20
18
  "exports": {
21
- ".": "./build/index.js",
22
- "./components/*": "./build/website/components/*.tsx",
23
- "./elements/*": "./build/website/elements/*.tsx",
24
- "./styles/*": "./build/website/styles/*.css"
19
+ ".": "./target/index.js",
20
+ "./components/*": "./source/components/*.tsx",
21
+ "./elements/*": "./source/elements/*.tsx",
22
+ "./hooks/*": "./source/hooks/*.ts",
23
+ "./styles/*": "./source/styles/*.css",
24
+ "./utils/*": "./source/utils/*.ts"
25
25
  },
26
26
  "dependencies": {
27
27
  "@base-ui/react": "1.3.0",
@@ -113,11 +113,11 @@
113
113
  "pnpm": "^10.0.0"
114
114
  },
115
115
  "scripts": {
116
- "build": "tsgo && rm -rf build/website && cp -r website build",
116
+ "build": "tsgo",
117
117
  "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",
118
+ "clean": "rm -rf pnpm-lock.yaml node_modules target",
119
+ "docs:build": "node source/entrypoints/main.ts build",
120
+ "docs:start": "node source/entrypoints/main.ts start",
121
121
  "format": "vp fmt",
122
122
  "lint": "vp fmt --check && vp lint",
123
123
  "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
+ })
@@ -0,0 +1,77 @@
1
+ import {
2
+ existsSync,
3
+ mkdirSync,
4
+ readdirSync,
5
+ readFileSync,
6
+ statSync,
7
+ writeFileSync,
8
+ } from "node:fs"
9
+ import { dirname, join } from "node:path"
10
+ import { Command } from "commander"
11
+ import pc from "picocolors"
12
+ import { OVERRIDE_SUBDIRS } from "../settings.ts"
13
+
14
+ const defaultsRoot = join(import.meta.dirname, "..", "..", "source")
15
+
16
+ /**
17
+ * List or copy overridable livemark files into `.livemark/`.
18
+ *
19
+ * Without an argument, prints every file you can shadow. With a path, copies
20
+ * the default from the livemark package into `.livemark/<path>`; fails if the
21
+ * destination already exists.
22
+ */
23
+ export const escape = new Command("escape")
24
+ .description("List or copy overridable livemark files into .livemark/")
25
+ .argument(
26
+ "[path]",
27
+ "path relative to .livemark/ (e.g. components/Footer.tsx)",
28
+ )
29
+ .action((relPath?: string) => {
30
+ if (!relPath) {
31
+ for (const file of listOverridable()) console.log(file)
32
+ console.log(
33
+ pc.dim("\nRun 'livemark escape <path>' to copy a file into .livemark/"),
34
+ )
35
+ return
36
+ }
37
+
38
+ const [first] = relPath.split("/")
39
+ if (!first || !OVERRIDE_SUBDIRS.includes(first) || relPath.includes("..")) {
40
+ console.error(
41
+ pc.red(
42
+ `Error: '${relPath}' is not under an overridable subdir (${OVERRIDE_SUBDIRS.join(", ")})`,
43
+ ),
44
+ )
45
+ process.exit(1)
46
+ }
47
+
48
+ const src = join(defaultsRoot, relPath)
49
+ if (!existsSync(src) || !statSync(src).isFile()) {
50
+ console.error(pc.red(`Error: '${relPath}' is not a livemark file`))
51
+ process.exit(1)
52
+ }
53
+
54
+ const dest = join(process.cwd(), ".livemark", relPath)
55
+ if (existsSync(dest)) {
56
+ console.error(pc.red(`Error: .livemark/${relPath} already exists`))
57
+ process.exit(1)
58
+ }
59
+
60
+ mkdirSync(dirname(dest), { recursive: true })
61
+ writeFileSync(dest, readFileSync(src))
62
+ console.log(
63
+ `Copied ${pc.dim(relPath)} → ${pc.green(`.livemark/${relPath}`)}`,
64
+ )
65
+ })
66
+
67
+ function listOverridable() {
68
+ const files: string[] = []
69
+ for (const subdir of OVERRIDE_SUBDIRS) {
70
+ const dir = join(defaultsRoot, subdir)
71
+ if (!existsSync(dir)) continue
72
+ for (const entry of readdirSync(dir)) {
73
+ if (statSync(join(dir, entry)).isFile()) files.push(`${subdir}/${entry}`)
74
+ }
75
+ }
76
+ return files.sort()
77
+ }
@@ -0,0 +1,25 @@
1
+ import { join } from "node:path"
2
+ import { Command } from "commander"
3
+ import { preview as vitePreview } from "vite"
4
+
5
+ const configFile = join(
6
+ import.meta.dirname,
7
+ "..",
8
+ "..",
9
+ "source",
10
+ "vite.config.ts",
11
+ )
12
+
13
+ /**
14
+ * Preview the production build locally.
15
+ */
16
+ export const preview = new Command("preview")
17
+ .description("Preview the production build locally")
18
+ .action(async () => {
19
+ const server = await vitePreview({
20
+ configFile,
21
+ preview: { port: 8000, host: true },
22
+ })
23
+ server.printUrls()
24
+ server.bindCLIShortcuts({ print: true })
25
+ })
@@ -0,0 +1,26 @@
1
+ import { join } from "node:path"
2
+ import { Command } from "commander"
3
+ import { createServer } from "vite"
4
+
5
+ const configFile = join(
6
+ import.meta.dirname,
7
+ "..",
8
+ "..",
9
+ "source",
10
+ "vite.config.ts",
11
+ )
12
+
13
+ /**
14
+ * Start a development server.
15
+ */
16
+ export const start = new Command("start")
17
+ .description("Start a live server")
18
+ .action(async () => {
19
+ const server = await createServer({
20
+ configFile,
21
+ server: { port: 8000, host: true },
22
+ })
23
+ await server.listen()
24
+ server.printUrls()
25
+ server.bindCLIShortcuts({ print: true })
26
+ })
@@ -102,7 +102,12 @@ export function Article(props: { article: ArticleView }) {
102
102
  <TocContext.Provider value={article.tocItems}>
103
103
  {article.toc !== false && (
104
104
  <MobileToc items={article.tocItems}>
105
- <PageToolbar file={article.file} content={article.content} />
105
+ <PageToolbar
106
+ file={article.file}
107
+ sourceUrl={article.sourceUrl}
108
+ sourceAction={article.sourceAction}
109
+ content={article.content}
110
+ />
106
111
  </MobileToc>
107
112
  )}
108
113
  <div className="flex flex-1 gap-10 p-4 pt-8 md:p-10">
@@ -154,7 +159,12 @@ export function Article(props: { article: ArticleView }) {
154
159
  </div>
155
160
  {article.toc !== false && (
156
161
  <Toc items={article.tocItems}>
157
- <PageToolbar file={article.file} content={article.content} />
162
+ <PageToolbar
163
+ file={article.file}
164
+ sourceUrl={article.sourceUrl}
165
+ sourceAction={article.sourceAction}
166
+ content={article.content}
167
+ />
158
168
  </Toc>
159
169
  )}
160
170
  </div>
@@ -1,5 +1,5 @@
1
1
  import { AlertTriangle, Flame, Info, Lightbulb } from "lucide-react"
2
- import { cn } from "../helpers/style.ts"
2
+ import { cn } from "../utils/style.ts"
3
3
 
4
4
  type CalloutType = "note" | "tip" | "info" | "warning" | "danger"
5
5