livemark 0.23.0 → 0.24.1

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 (281) hide show
  1. package/.agents/skills/change-review/SKILL.md +47 -0
  2. package/{skills/configuration → .agents/skills/livemark-configuration}/SKILL.md +2 -4
  3. package/build/actions/changelog/build.d.ts +21 -9
  4. package/build/actions/changelog/build.js +31 -23
  5. package/build/actions/changelog/build.unit.js +156 -2
  6. package/build/actions/config/load.js +1 -1
  7. package/build/actions/config/load.unit.js +1 -1
  8. package/build/actions/target/build.js +2 -5
  9. package/build/commands/build.js +1 -1
  10. package/build/commands/escape.js +1 -1
  11. package/build/commands/preview.js +1 -1
  12. package/build/commands/start.js +1 -1
  13. package/build/components/Abbr.js +2 -2
  14. package/build/components/Article.js +2 -2
  15. package/build/components/BlogIndex.js +2 -4
  16. package/build/components/Callout.js +2 -2
  17. package/build/components/ChangelogIndex.js +1 -1
  18. package/build/components/CodeBlock.js +3 -5
  19. package/build/components/CodeTabs.js +1 -1
  20. package/build/components/Columns.js +2 -4
  21. package/build/components/Content.js +2 -2
  22. package/build/components/ContentTab.js +1 -1
  23. package/build/components/ContentTabs.js +1 -1
  24. package/build/components/DefinitionList.js +1 -1
  25. package/build/components/FileTree.js +1 -1
  26. package/build/components/FootnoteRef.js +2 -2
  27. package/build/components/InlineToc.js +1 -1
  28. package/build/components/Layout.js +1 -1
  29. package/build/components/LinkButton.js +2 -2
  30. package/build/components/Mermaid.js +1 -1
  31. package/build/components/PackageTabs.js +2 -2
  32. package/build/components/PageToolbar.js +2 -2
  33. package/build/components/PrevNext.js +3 -7
  34. package/build/components/SearchDialog.js +1 -1
  35. package/build/components/Section.js +2 -2
  36. package/build/components/SectionHeader.js +2 -2
  37. package/build/components/Sidebar.js +2 -2
  38. package/build/components/SidebarArticles.js +2 -2
  39. package/build/components/SidebarLinks.js +2 -2
  40. package/build/components/TagIndex.js +2 -4
  41. package/build/components/Toc.js +1 -1
  42. package/build/content/article.js +1 -1
  43. package/build/content-collections.js +6 -7
  44. package/build/elements/accordion.js +2 -2
  45. package/build/elements/alert-dialog.js +5 -5
  46. package/build/elements/alert.js +2 -2
  47. package/build/elements/aspect-ratio.js +2 -2
  48. package/build/elements/avatar.d.ts +1 -1
  49. package/build/elements/avatar.js +3 -3
  50. package/build/elements/badge.js +2 -2
  51. package/build/elements/breadcrumb.js +2 -2
  52. package/build/elements/button-group.d.ts +1 -1
  53. package/build/elements/button-group.js +3 -3
  54. package/build/elements/button.js +2 -2
  55. package/build/elements/calendar.js +5 -5
  56. package/build/elements/card.js +2 -2
  57. package/build/elements/carousel.js +2 -2
  58. package/build/elements/chart.js +5 -15
  59. package/build/elements/checkbox.js +2 -2
  60. package/build/elements/collapsible.js +3 -3
  61. package/build/elements/command.js +2 -2
  62. package/build/elements/context-menu.js +5 -5
  63. package/build/elements/dialog.js +2 -2
  64. package/build/elements/direction.d.ts +1 -1
  65. package/build/elements/direction.js +2 -2
  66. package/build/elements/drawer.js +2 -2
  67. package/build/elements/dropdown-menu.js +3 -3
  68. package/build/elements/empty.d.ts +1 -1
  69. package/build/elements/empty.js +3 -3
  70. package/build/elements/field.js +2 -2
  71. package/build/elements/hover-card.js +3 -3
  72. package/build/elements/input-group.js +2 -2
  73. package/build/elements/input-otp.js +2 -2
  74. package/build/elements/input.js +2 -2
  75. package/build/elements/item.js +2 -2
  76. package/build/elements/kbd.js +2 -2
  77. package/build/elements/label.js +2 -2
  78. package/build/elements/menubar.js +2 -2
  79. package/build/elements/native-select.js +2 -2
  80. package/build/elements/navigation-menu.js +2 -2
  81. package/build/elements/pagination.js +3 -3
  82. package/build/elements/popover.js +2 -2
  83. package/build/elements/progress.d.ts +1 -1
  84. package/build/elements/progress.js +3 -3
  85. package/build/elements/radio-group.js +2 -2
  86. package/build/elements/resizable.js +3 -3
  87. package/build/elements/scroll-area.js +2 -2
  88. package/build/elements/select.js +2 -2
  89. package/build/elements/separator.js +2 -2
  90. package/build/elements/sheet.js +2 -2
  91. package/build/elements/sidebar.js +3 -4
  92. package/build/elements/skeleton.js +2 -2
  93. package/build/elements/slider.js +2 -2
  94. package/build/elements/spinner.js +2 -2
  95. package/build/elements/switch.js +2 -2
  96. package/build/elements/table.js +2 -2
  97. package/build/elements/tabs.js +2 -2
  98. package/build/elements/textarea.js +2 -2
  99. package/build/elements/toggle-group.js +2 -2
  100. package/build/elements/toggle.js +2 -2
  101. package/build/elements/tooltip.js +2 -2
  102. package/build/helpers/changelog-source.js +1 -1
  103. package/build/helpers/dynamic-icon-resolver.js +1 -1
  104. package/build/helpers/resolve-asset-path.unit.js +1 -1
  105. package/build/helpers/resolve-base.unit.js +2 -2
  106. package/build/helpers/resolve-includes.js +2 -2
  107. package/build/helpers/resolve-includes.unit.js +1 -1
  108. package/build/helpers/rss.js +2 -4
  109. package/build/helpers/rss.unit.js +1 -1
  110. package/build/helpers/section.js +2 -3
  111. package/build/helpers/section.unit.js +4 -13
  112. package/build/helpers/toc.unit.js +2 -4
  113. package/build/plugins/rehype-inline-code.js +2 -2
  114. package/build/plugins/rehype-task-list-a11y.js +1 -1
  115. package/build/plugins/remark-abbr.js +2 -4
  116. package/build/plugins/remark-ansi.js +2 -4
  117. package/build/plugins/remark-ansi.unit.js +1 -1
  118. package/build/plugins/remark-badge.js +2 -4
  119. package/build/plugins/remark-button.unit.js +1 -1
  120. package/build/plugins/remark-callout.js +1 -1
  121. package/build/plugins/remark-card.js +1 -1
  122. package/build/plugins/remark-code-tabs.js +4 -8
  123. package/build/plugins/remark-columns.js +1 -1
  124. package/build/plugins/remark-custom-heading-id.unit.js +1 -1
  125. package/build/plugins/remark-deflist.js +1 -1
  126. package/build/plugins/remark-details.js +2 -4
  127. package/build/plugins/remark-filetree.js +1 -1
  128. package/build/plugins/remark-filetree.unit.js +1 -1
  129. package/build/plugins/remark-media.js +3 -7
  130. package/build/plugins/remark-media.unit.js +1 -1
  131. package/build/plugins/remark-steps.unit.js +1 -1
  132. package/build/plugins/remark-tab.js +4 -2
  133. package/build/plugins/remark-tab.unit.js +3 -7
  134. package/build/plugins/remark-toc.unit.js +1 -1
  135. package/build/plugins/shiki-icon.js +1 -1
  136. package/build/plugins/shiki-line-highlight.js +1 -1
  137. package/build/plugins/vite-livemark.js +1 -1
  138. package/build/plugins/vite-robots.js +1 -1
  139. package/build/plugins/vite-robots.unit.js +1 -1
  140. package/build/routes/$.js +1 -1
  141. package/build/vite.config.js +3 -8
  142. package/package.json +17 -19
  143. package/source/actions/changelog/build.ts +32 -35
  144. package/source/actions/changelog/build.unit.ts +191 -1
  145. package/source/actions/config/load.ts +1 -3
  146. package/source/actions/config/load.unit.ts +2 -7
  147. package/source/actions/target/build.ts +1 -4
  148. package/source/commands/build.ts +1 -7
  149. package/source/commands/escape.ts +3 -8
  150. package/source/commands/preview.ts +1 -7
  151. package/source/commands/start.ts +1 -7
  152. package/source/components/Abbr.tsx +1 -5
  153. package/source/components/Article.tsx +1 -5
  154. package/source/components/BlogIndex.tsx +3 -9
  155. package/source/components/Callout.tsx +2 -7
  156. package/source/components/ChangelogIndex.tsx +1 -3
  157. package/source/components/CodeBlock.tsx +4 -14
  158. package/source/components/CodeTabs.tsx +1 -3
  159. package/source/components/Columns.tsx +1 -3
  160. package/source/components/Content.tsx +1 -5
  161. package/source/components/ContentTab.tsx +1 -4
  162. package/source/components/ContentTabs.tsx +3 -10
  163. package/source/components/DefinitionList.tsx +1 -4
  164. package/source/components/FileTree.tsx +1 -5
  165. package/source/components/FootnoteRef.tsx +1 -5
  166. package/source/components/InlineToc.tsx +1 -4
  167. package/source/components/Layout.tsx +3 -10
  168. package/source/components/LinkButton.tsx +2 -8
  169. package/source/components/Mermaid.tsx +1 -3
  170. package/source/components/PackageTabs.tsx +1 -5
  171. package/source/components/PageToolbar.tsx +1 -5
  172. package/source/components/PrevNext.tsx +2 -6
  173. package/source/components/SearchDialog.tsx +2 -6
  174. package/source/components/Section.tsx +1 -1
  175. package/source/components/SectionHeader.tsx +2 -8
  176. package/source/components/Sidebar.tsx +2 -7
  177. package/source/components/SidebarArticles.tsx +4 -20
  178. package/source/components/SidebarLinks.tsx +2 -6
  179. package/source/components/TagIndex.tsx +3 -9
  180. package/source/components/Toc.tsx +2 -7
  181. package/source/content/article.ts +1 -2
  182. package/source/content-collections.ts +6 -8
  183. package/source/elements/accordion.tsx +1 -1
  184. package/source/elements/alert-dialog.tsx +8 -30
  185. package/source/elements/alert.tsx +2 -5
  186. package/source/elements/aspect-ratio.tsx +1 -1
  187. package/source/elements/avatar.tsx +5 -21
  188. package/source/elements/badge.tsx +3 -5
  189. package/source/elements/breadcrumb.tsx +4 -14
  190. package/source/elements/button-group.tsx +2 -7
  191. package/source/elements/button.tsx +1 -1
  192. package/source/elements/calendar.tsx +7 -24
  193. package/source/elements/card.tsx +1 -1
  194. package/source/elements/carousel.tsx +4 -11
  195. package/source/elements/chart.tsx +9 -34
  196. package/source/elements/checkbox.tsx +1 -1
  197. package/source/elements/collapsible.tsx +2 -6
  198. package/source/elements/command.tsx +4 -13
  199. package/source/elements/context-menu.tsx +8 -25
  200. package/source/elements/dialog.tsx +4 -14
  201. package/source/elements/direction.tsx +1 -4
  202. package/source/elements/drawer.tsx +4 -10
  203. package/source/elements/dropdown-menu.tsx +5 -19
  204. package/source/elements/empty.tsx +3 -13
  205. package/source/elements/field.tsx +3 -7
  206. package/source/elements/hover-card.tsx +2 -4
  207. package/source/elements/input-group.tsx +15 -28
  208. package/source/elements/input-otp.tsx +1 -1
  209. package/source/elements/input.tsx +1 -1
  210. package/source/elements/item.tsx +4 -13
  211. package/source/elements/kbd.tsx +1 -1
  212. package/source/elements/label.tsx +1 -1
  213. package/source/elements/menubar.tsx +5 -14
  214. package/source/elements/native-select.tsx +4 -15
  215. package/source/elements/navigation-menu.tsx +2 -5
  216. package/source/elements/pagination.tsx +4 -14
  217. package/source/elements/popover.tsx +2 -5
  218. package/source/elements/progress.tsx +4 -16
  219. package/source/elements/radio-group.tsx +1 -1
  220. package/source/elements/resizable.tsx +4 -12
  221. package/source/elements/scroll-area.tsx +2 -6
  222. package/source/elements/select.tsx +4 -14
  223. package/source/elements/separator.tsx +1 -1
  224. package/source/elements/sheet.tsx +3 -10
  225. package/source/elements/sidebar.tsx +7 -25
  226. package/source/elements/skeleton.tsx +1 -1
  227. package/source/elements/slider.tsx +1 -1
  228. package/source/elements/spinner.tsx +1 -1
  229. package/source/elements/switch.tsx +1 -1
  230. package/source/elements/table.tsx +4 -13
  231. package/source/elements/tabs.tsx +1 -1
  232. package/source/elements/textarea.tsx +1 -1
  233. package/source/elements/toggle-group.tsx +2 -4
  234. package/source/elements/toggle.tsx +1 -1
  235. package/source/elements/tooltip.tsx +3 -10
  236. package/source/helpers/changelog-source.ts +1 -3
  237. package/source/helpers/dynamic-icon-resolver.tsx +1 -4
  238. package/source/helpers/resolve-asset-path.unit.ts +6 -12
  239. package/source/helpers/resolve-base.unit.ts +1 -2
  240. package/source/helpers/resolve-includes.ts +2 -8
  241. package/source/helpers/resolve-includes.unit.ts +9 -36
  242. package/source/helpers/rss.ts +3 -9
  243. package/source/helpers/rss.unit.ts +1 -3
  244. package/source/helpers/section.ts +1 -4
  245. package/source/helpers/section.unit.ts +5 -18
  246. package/source/helpers/toc.unit.ts +1 -3
  247. package/source/plugins/rehype-inline-code.ts +5 -21
  248. package/source/plugins/rehype-task-list-a11y.ts +1 -2
  249. package/source/plugins/remark-abbr.ts +1 -3
  250. package/source/plugins/remark-ansi.ts +2 -5
  251. package/source/plugins/remark-ansi.unit.ts +6 -18
  252. package/source/plugins/remark-badge.ts +1 -3
  253. package/source/plugins/remark-button.unit.ts +3 -9
  254. package/source/plugins/remark-callout.ts +35 -40
  255. package/source/plugins/remark-card.ts +25 -29
  256. package/source/plugins/remark-code-tabs.ts +3 -7
  257. package/source/plugins/remark-columns.ts +13 -17
  258. package/source/plugins/remark-custom-heading-id.unit.ts +2 -6
  259. package/source/plugins/remark-deflist.ts +1 -2
  260. package/source/plugins/remark-details.ts +28 -34
  261. package/source/plugins/remark-filetree.ts +28 -34
  262. package/source/plugins/remark-filetree.unit.ts +1 -4
  263. package/source/plugins/remark-media.ts +2 -6
  264. package/source/plugins/remark-media.unit.ts +2 -6
  265. package/source/plugins/remark-steps.unit.ts +2 -7
  266. package/source/plugins/remark-tab.ts +26 -30
  267. package/source/plugins/remark-tab.unit.ts +2 -6
  268. package/source/plugins/remark-toc.unit.ts +1 -3
  269. package/source/plugins/shiki-icon.ts +1 -4
  270. package/source/plugins/shiki-line-highlight.ts +4 -11
  271. package/source/plugins/vite-livemark.ts +3 -10
  272. package/source/plugins/vite-robots.ts +1 -6
  273. package/source/plugins/vite-robots.unit.ts +1 -3
  274. package/source/routes/$.tsx +1 -3
  275. package/source/styles/general.css +1 -5
  276. package/source/vite.config.ts +2 -7
  277. package/build/utils/style.d.ts +0 -2
  278. package/build/utils/style.js +0 -6
  279. package/source/utils/style.ts +0 -6
  280. /package/{skills/authoring → .agents/skills/livemark-authoring}/SKILL.md +0 -0
  281. /package/{skills/customization → .agents/skills/livemark-customization}/SKILL.md +0 -0
@@ -1,10 +1,6 @@
1
1
  import { Check, ChevronDown, Clipboard, WrapText } from "lucide-react"
2
2
  import { useRef, useState } from "react"
3
- import {
4
- Tooltip,
5
- TooltipContent,
6
- TooltipTrigger,
7
- } from "../elements/tooltip.tsx"
3
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../elements/tooltip.tsx"
8
4
 
9
5
  export function CodeBlock(props: React.ComponentProps<"pre">) {
10
6
  const [copied, setCopied] = useState(false)
@@ -17,9 +13,7 @@ export function CodeBlock(props: React.ComponentProps<"pre">) {
17
13
  const maxLines = meta?.match(/maxLines=(\d+)/)?.[1]
18
14
  const icon = extra.icon as string | undefined
19
15
  const style = props.style as Record<string, string> | undefined
20
- const collapsedHeight = maxLines
21
- ? `${Number(maxLines) * 1.5 + 1.75}rem`
22
- : undefined
16
+ const collapsedHeight = maxLines ? `${Number(maxLines) * 1.5 + 1.75}rem` : undefined
23
17
 
24
18
  const handleCopy = () => {
25
19
  const text = preRef.current?.textContent ?? ""
@@ -54,9 +48,7 @@ export function CodeBlock(props: React.ComponentProps<"pre">) {
54
48
  >
55
49
  <WrapText className="size-3.5" />
56
50
  </TooltipTrigger>
57
- <TooltipContent>
58
- {wrap ? "Disable wrap" : "Enable wrap"}
59
- </TooltipContent>
51
+ <TooltipContent>{wrap ? "Disable wrap" : "Enable wrap"}</TooltipContent>
60
52
  </Tooltip>
61
53
  <Tooltip>
62
54
  <TooltipTrigger
@@ -83,9 +75,7 @@ export function CodeBlock(props: React.ComponentProps<"pre">) {
83
75
  >
84
76
  <WrapText className="size-3.5" />
85
77
  </TooltipTrigger>
86
- <TooltipContent>
87
- {wrap ? "Disable wrap" : "Enable wrap"}
88
- </TooltipContent>
78
+ <TooltipContent>{wrap ? "Disable wrap" : "Enable wrap"}</TooltipContent>
89
79
  </Tooltip>
90
80
  <Tooltip>
91
81
  <TooltipTrigger
@@ -37,9 +37,7 @@ export function CodeTabs(props: {
37
37
  useEffect(() => {
38
38
  if (!props.sync) return
39
39
  const handler = (e: Event) => {
40
- const { sync, title } = (
41
- e as CustomEvent<{ sync: string; title: string }>
42
- ).detail
40
+ const { sync, title } = (e as CustomEvent<{ sync: string; title: string }>).detail
43
41
  if (sync !== props.sync) return
44
42
  const idx = names.indexOf(title)
45
43
  if (idx >= 0) setActive(idx)
@@ -1,9 +1,7 @@
1
1
  /** Grid layout for arranging content side by side */
2
2
  export function Columns(props: { cols?: string; children: React.ReactNode }) {
3
3
  const cols = props.cols ? parseInt(props.cols, 10) : undefined
4
- const style = cols
5
- ? { gridTemplateColumns: `repeat(${cols}, 1fr)` }
6
- : undefined
4
+ const style = cols ? { gridTemplateColumns: `repeat(${cols}, 1fr)` } : undefined
7
5
  return (
8
6
  <div className="grid gap-6 my-4 sm:grid-cols-2" style={style}>
9
7
  {props.children}
@@ -1,7 +1,3 @@
1
1
  export function Content(props: { children: React.ReactNode }) {
2
- return (
3
- <div className="w-full max-w-7xl mx-auto px-4 md:px-10">
4
- {props.children}
5
- </div>
6
- )
2
+ return <div className="w-full max-w-7xl mx-auto px-4 md:px-10">{props.children}</div>
7
3
  }
@@ -1,7 +1,4 @@
1
1
  /** Simple wrapper that provides a title prop for ContentTabs to read */
2
- export function ContentTab(props: {
3
- title: string
4
- children: React.ReactNode
5
- }) {
2
+ export function ContentTab(props: { title: string; children: React.ReactNode }) {
6
3
  return <div>{props.children}</div>
7
4
  }
@@ -1,10 +1,7 @@
1
1
  import { Children, isValidElement, useEffect, useState } from "react"
2
2
 
3
3
  /** Tabbed container component for grouping content tabs with optional sync across groups */
4
- export function ContentTabs(props: {
5
- sync?: string
6
- children: React.ReactNode
7
- }) {
4
+ export function ContentTabs(props: { sync?: string; children: React.ReactNode }) {
8
5
  const children = Children.toArray(props.children)
9
6
  const titles = children.map(child =>
10
7
  isValidElement<{ title: string }>(child) ? child.props.title : "",
@@ -38,9 +35,7 @@ export function ContentTabs(props: {
38
35
  useEffect(() => {
39
36
  if (!props.sync) return
40
37
  const handler = (e: Event) => {
41
- const { sync, title } = (
42
- e as CustomEvent<{ sync: string; title: string }>
43
- ).detail
38
+ const { sync, title } = (e as CustomEvent<{ sync: string; title: string }>).detail
44
39
  if (sync !== props.sync) return
45
40
  const idx = titles.indexOf(title)
46
41
  if (idx >= 0) setActive(idx)
@@ -70,9 +65,7 @@ export function ContentTabs(props: {
70
65
  {children.map((child, i) => (
71
66
  <div
72
67
  key={titles[i]}
73
- className={
74
- i === active ? "p-4 prose dark:prose-invert max-w-none" : "hidden"
75
- }
68
+ className={i === active ? "p-4 prose dark:prose-invert max-w-none" : "hidden"}
76
69
  >
77
70
  {child}
78
71
  </div>
@@ -13,9 +13,6 @@ export function DefinitionTerm(props: ComponentProps<"dt">) {
13
13
  /** Styled definition detail with a left border accent */
14
14
  export function DefinitionDetail(props: ComponentProps<"dd">) {
15
15
  return (
16
- <dd
17
- {...props}
18
- className="ml-0 pl-4 border-l-2 border-border text-muted-foreground"
19
- />
16
+ <dd {...props} className="ml-0 pl-4 border-l-2 border-border text-muted-foreground" />
20
17
  )
21
18
  }
@@ -21,11 +21,7 @@ function TreeItems(props: { items: TreeItem[]; depth: number }) {
21
21
  return (
22
22
  <ul className={props.depth > 0 ? "ml-4 border-l border-border pl-2" : ""}>
23
23
  {props.items.map((item, index) => (
24
- <TreeNode
25
- key={`${item.name}-${index}`}
26
- item={item}
27
- depth={props.depth}
28
- />
24
+ <TreeNode key={`${item.name}-${index}`} item={item} depth={props.depth} />
29
25
  ))}
30
26
  </ul>
31
27
  )
@@ -1,9 +1,5 @@
1
1
  import { type ComponentProps, useEffect, useState } from "react"
2
- import {
3
- HoverCard,
4
- HoverCardContent,
5
- HoverCardTrigger,
6
- } from "../elements/hover-card.tsx"
2
+ import { HoverCard, HoverCardContent, HoverCardTrigger } from "../elements/hover-card.tsx"
7
3
 
8
4
  const FOOTNOTE_PREFIX = "#user-content-fn-"
9
5
 
@@ -13,10 +13,7 @@ export function InlineToc(props: { maxLevel?: string }) {
13
13
  <p className="text-base font-semibold mb-4">Table of Contents</p>
14
14
  <ul className="text-base space-y-2.5">
15
15
  {items.map(item => (
16
- <li
17
- key={item.url}
18
- style={{ paddingLeft: `${(item.depth - 2) * 1.25}rem` }}
19
- >
16
+ <li key={item.url} style={{ paddingLeft: `${(item.depth - 2) * 1.25}rem` }}>
20
17
  <a
21
18
  href={item.url}
22
19
  className="text-muted-foreground hover:text-primary transition-colors"
@@ -26,10 +26,7 @@ function splatFor(pathname: string) {
26
26
  return { _splat: pathname.replace(/^\/|\/$/g, "") }
27
27
  }
28
28
 
29
- export function Layout(props: {
30
- withSidebar?: boolean
31
- children?: React.ReactNode
32
- }) {
29
+ export function Layout(props: { withSidebar?: boolean; children?: React.ReactNode }) {
33
30
  const pathname = useLocation({ select: l => l.pathname })
34
31
  const articleRoute = useMatch({ from: "/$", shouldThrow: false })
35
32
  const activeSection = articleRoute
@@ -56,10 +53,7 @@ export function Layout(props: {
56
53
  <div className="hidden lg:flex">
57
54
  <SidebarTrigger />
58
55
  </div>
59
- <SiteLink
60
- to={siteLinkTarget}
61
- className="lg:hidden flex items-center gap-2"
62
- >
56
+ <SiteLink to={siteLinkTarget} className="lg:hidden flex items-center gap-2">
63
57
  <SiteTitle />
64
58
  </SiteLink>
65
59
  </>
@@ -100,8 +94,7 @@ export function Layout(props: {
100
94
  const latestVersion =
101
95
  section.type === "changelog" && section.version
102
96
  ? sortedArticles.find(
103
- a =>
104
- a.path === sectionFlatArticles.get(section.prefix)?.[0],
97
+ a => a.path === sectionFlatArticles.get(section.prefix)?.[0],
105
98
  )?.title
106
99
  : undefined
107
100
  return (
@@ -1,17 +1,11 @@
1
1
  import { buttonVariants } from "../elements/button.tsx"
2
- import { cn } from "../utils/style.ts"
2
+ import { cn } from "cn"
3
3
 
4
4
  /** Styled link button rendered from ::button leaf directives */
5
5
  export function LinkButton(props: {
6
6
  href: string
7
7
  label: string
8
- variant?:
9
- | "default"
10
- | "outline"
11
- | "secondary"
12
- | "ghost"
13
- | "destructive"
14
- | "link"
8
+ variant?: "default" | "outline" | "secondary" | "ghost" | "destructive" | "link"
15
9
  size?: "default" | "sm" | "lg"
16
10
  }) {
17
11
  return (
@@ -7,9 +7,7 @@ export function Mermaid(props: { children: string }) {
7
7
  return (
8
8
  <Suspense
9
9
  fallback={
10
- <div className="not-prose mermaid flex justify-center">
11
- Loading diagram…
12
- </div>
10
+ <div className="not-prose mermaid flex justify-center">Loading diagram…</div>
13
11
  }
14
12
  >
15
13
  <MermaidRenderer>{props.children}</MermaidRenderer>
@@ -55,11 +55,7 @@ export function PackageTabs(props: PackageTabsProps) {
55
55
  className="me-2 p-1 rounded-md text-muted-foreground hover:text-foreground transition-colors"
56
56
  aria-label="Copy code"
57
57
  >
58
- {copied ? (
59
- <Check className="size-3.5" />
60
- ) : (
61
- <Clipboard className="size-3.5" />
62
- )}
58
+ {copied ? <Check className="size-3.5" /> : <Clipboard className="size-3.5" />}
63
59
  </button>
64
60
  </div>
65
61
  <div className="text-[0.8125rem] py-3.5 overflow-auto max-h-[600px]">
@@ -59,11 +59,7 @@ export function PageToolbar(props: {
59
59
  </span>
60
60
  )}
61
61
  <button type="button" onClick={handleCopy} className={buttonClass}>
62
- {copied ? (
63
- <Check className="size-3.5" />
64
- ) : (
65
- <Copy className="size-3.5" />
66
- )}
62
+ {copied ? <Check className="size-3.5" /> : <Copy className="size-3.5" />}
67
63
  Copy Markdown
68
64
  </button>
69
65
  <button
@@ -18,12 +18,8 @@ export function PrevNext(props: { path: string }) {
18
18
 
19
19
  const prevPath = index > 0 ? flat[index - 1] : undefined
20
20
  const nextPath = index < flat.length - 1 ? flat[index + 1] : undefined
21
- const prev = prevPath
22
- ? sortedArticles.find(a => a.path === prevPath)
23
- : undefined
24
- const next = nextPath
25
- ? sortedArticles.find(a => a.path === nextPath)
26
- : undefined
21
+ const prev = prevPath ? sortedArticles.find(a => a.path === prevPath) : undefined
22
+ const next = nextPath ? sortedArticles.find(a => a.path === nextPath) : undefined
27
23
 
28
24
  if (!prev && !next) return null
29
25
 
@@ -80,9 +80,7 @@ export function SearchDialog(props: {
80
80
  })
81
81
  setResults(
82
82
  hits.hits.map(hit => {
83
- const article = sortedArticles.find(
84
- a => a.title === hit.document.title,
85
- )
83
+ const article = sortedArticles.find(a => a.title === hit.document.title)
86
84
  if (!article)
87
85
  return toResult(
88
86
  {
@@ -161,9 +159,7 @@ export function SearchDialog(props: {
161
159
  <Icon className="size-5 shrink-0 mt-0.5 self-start opacity-60" />
162
160
  )}
163
161
  <div className="flex flex-col gap-0.5 min-w-0">
164
- <span className="text-base font-medium">
165
- {result.title}
166
- </span>
162
+ <span className="text-base font-medium">{result.title}</span>
167
163
  {result.snippet && (
168
164
  <span className="text-sm text-muted-foreground line-clamp-1">
169
165
  <HighlightedText text={result.snippet} term={query} />
@@ -1,4 +1,4 @@
1
- import { cn } from "../utils/style.ts"
1
+ import { cn } from "cn"
2
2
  import { useInView } from "../hooks/in-view.ts"
3
3
 
4
4
  export function Section(props: {
@@ -1,4 +1,4 @@
1
- import { cn } from "../utils/style.ts"
1
+ import { cn } from "cn"
2
2
 
3
3
  export function SectionHeader(props: {
4
4
  label?: string
@@ -10,13 +10,7 @@ export function SectionHeader(props: {
10
10
  const align = props.align ?? "center"
11
11
 
12
12
  return (
13
- <div
14
- className={cn(
15
- align === "center" && "text-center",
16
- "mb-12",
17
- props.className,
18
- )}
19
- >
13
+ <div className={cn(align === "center" && "text-center", "mb-12", props.className)}>
20
14
  {props.label && (
21
15
  <p className="text-primary text-xs uppercase tracking-[0.2em] font-medium mb-3">
22
16
  {props.label}
@@ -44,10 +44,7 @@ export function Sidebar(props: { withSidebar?: boolean }) {
44
44
  <SidebarHeader>
45
45
  <SidebarMenu>
46
46
  <SidebarMenuItem>
47
- <SidebarMenuButton
48
- size="lg"
49
- render={<SiteLink to={siteLinkTarget} />}
50
- >
47
+ <SidebarMenuButton size="lg" render={<SiteLink to={siteLinkTarget} />}>
51
48
  <SiteTitle />
52
49
  </SidebarMenuButton>
53
50
  </SidebarMenuItem>
@@ -56,9 +53,7 @@ export function Sidebar(props: { withSidebar?: boolean }) {
56
53
  <SidebarContent>
57
54
  <SidebarSections />
58
55
  {props.withSidebar && section?.type === "blog" && <SidebarPosts />}
59
- {props.withSidebar && section?.type === "changelog" && (
60
- <SidebarReleases />
61
- )}
56
+ {props.withSidebar && section?.type === "changelog" && <SidebarReleases />}
62
57
  {props.withSidebar &&
63
58
  section?.type !== "blog" &&
64
59
  section?.type !== "changelog" && <SidebarArticles />}
@@ -1,11 +1,7 @@
1
1
  import { config } from "livemark:virtual"
2
2
  import { Link, useLocation } from "@tanstack/react-router"
3
3
  import { ChevronRight } from "lucide-react"
4
- import {
5
- articleTree,
6
- currentSection,
7
- sectionArticleTrees,
8
- } from "../content/article.ts"
4
+ import { articleTree, currentSection, sectionArticleTrees } from "../content/article.ts"
9
5
  import {
10
6
  Collapsible,
11
7
  CollapsibleContent,
@@ -61,11 +57,7 @@ function isActive(articlePathname: string, currentPath: string) {
61
57
  return articlePathname === normalized
62
58
  }
63
59
 
64
- function NavNode(props: {
65
- node: ArticleNode
66
- currentPath: string
67
- depth?: number
68
- }) {
60
+ function NavNode(props: { node: ArticleNode; currentPath: string; depth?: number }) {
69
61
  const { node, currentPath, depth = 0 } = props
70
62
  const Icon = resolveArticleIcon(node.icon)
71
63
  const active = isActive(node.path, currentPath)
@@ -79,11 +71,7 @@ function NavNode(props: {
79
71
  if (node.children.length === 0) {
80
72
  return (
81
73
  <Item>
82
- <Button
83
- isActive={active}
84
- className={active ? "" : "opacity-75"}
85
- render={link}
86
- >
74
+ <Button isActive={active} className={active ? "" : "opacity-75"} render={link}>
87
75
  {!isSub && Icon && <Icon className="size-4" />}
88
76
  {label}
89
77
  </Button>
@@ -94,11 +82,7 @@ function NavNode(props: {
94
82
  return (
95
83
  <Item>
96
84
  <Collapsible defaultOpen className="group/collapsible">
97
- <Button
98
- isActive={active}
99
- className={active ? "" : "opacity-75"}
100
- render={link}
101
- >
85
+ <Button isActive={active} className={active ? "" : "opacity-75"} render={link}>
102
86
  {!isSub && Icon && <Icon className="size-4" />}
103
87
  {label}
104
88
  </Button>
@@ -19,9 +19,7 @@ export function SidebarLinks() {
19
19
  const pathname = useLocation({ select: l => l.pathname })
20
20
  const section = currentSection(`/${pathname.replace(/^\/|\/$/g, "")}/`)
21
21
  const links =
22
- config.links?.filter(
23
- link => !link.prefix || link.prefix === section?.prefix,
24
- ) ?? []
22
+ config.links?.filter(link => !link.prefix || link.prefix === section?.prefix) ?? []
25
23
 
26
24
  if (!links.length) return null
27
25
  const hasDesktopItems = links.some(l => l.position === "sidebar")
@@ -44,9 +42,7 @@ export function SidebarLinks() {
44
42
  className="text-muted-foreground"
45
43
  render={<a href={prefixUrl(link.url, config.base)} />}
46
44
  >
47
- {link.icon && (
48
- <DynamicIcon name={link.icon} className="size-4" />
49
- )}
45
+ {link.icon && <DynamicIcon name={link.icon} className="size-4" />}
50
46
  <span>{link.title}</span>
51
47
  </SidebarMenuButton>
52
48
  </SidebarMenuItem>
@@ -30,9 +30,7 @@ export function TagIndex(props: { sectionPrefix: string; tag: string }) {
30
30
  const parts = [`## ${post.title}`]
31
31
  if (post.date) parts.push(formatDate(post.date))
32
32
  if (post.author) {
33
- parts.push(
34
- Array.isArray(post.author) ? post.author.join(", ") : post.author,
35
- )
33
+ parts.push(Array.isArray(post.author) ? post.author.join(", ") : post.author)
36
34
  }
37
35
  if (post.description) parts.push("", post.description)
38
36
  return parts.join("\n")
@@ -76,16 +74,12 @@ export function TagIndex(props: { sectionPrefix: string; tag: string }) {
76
74
  {post.date && <span>{formatDate(post.date)}</span>}
77
75
  {post.author && (
78
76
  <span>
79
- {Array.isArray(post.author)
80
- ? post.author.join(", ")
81
- : post.author}
77
+ {Array.isArray(post.author) ? post.author.join(", ") : post.author}
82
78
  </span>
83
79
  )}
84
80
  </p>
85
81
  {post.description && (
86
- <p className="text-muted-foreground mt-2">
87
- {post.description}
88
- </p>
82
+ <p className="text-muted-foreground mt-2">{post.description}</p>
89
83
  )}
90
84
  </article>
91
85
  ))}
@@ -63,10 +63,7 @@ export function MobileToc(props: { items: TocItem[]; children?: ReactNode }) {
63
63
  const title = active?.title ?? props.items[0]?.title ?? "Contents"
64
64
 
65
65
  return (
66
- <div
67
- ref={wrapperRef}
68
- className="xl:hidden sticky top-16 z-20 border-b bg-background"
69
- >
66
+ <div ref={wrapperRef} className="xl:hidden sticky top-16 z-20 border-b bg-background">
70
67
  <button
71
68
  type="button"
72
69
  onClick={() => setOpen(v => !v)}
@@ -91,9 +88,7 @@ export function MobileToc(props: { items: TocItem[]; children?: ReactNode }) {
91
88
  <li key={item.url}>
92
89
  <a
93
90
  href={item.url}
94
- data-active={
95
- activeId === item.url.slice(1) || undefined
96
- }
91
+ data-active={activeId === item.url.slice(1) || undefined}
97
92
  onClick={() => setOpen(false)}
98
93
  className={`-ms-px block border-l border-transparent py-1.5 text-muted-foreground transition-colors hover:text-foreground data-[active]:border-primary data-[active]:font-medium data-[active]:text-primary ${item.depth <= 2 ? "ps-3" : item.depth === 3 ? "ps-6" : "ps-8"}`}
99
94
  >
@@ -54,8 +54,7 @@ if (routedSections.length) {
54
54
  const sorted =
55
55
  section?.type === "blog" || section?.type === "changelog"
56
56
  ? [...bucket].sort(
57
- (a, b) =>
58
- new Date(b.date ?? 0).getTime() - new Date(a.date ?? 0).getTime(),
57
+ (a, b) => new Date(b.date ?? 0).getTime() - new Date(a.date ?? 0).getTime(),
59
58
  )
60
59
  : bucket
61
60
  const tree = buildArticleTree(sorted)
@@ -53,18 +53,16 @@ import { extractToc } from "./helpers/toc.ts"
53
53
 
54
54
  const config = await loadConfig()
55
55
 
56
- const changelogSections =
57
- config.sections?.filter(s => s.type === "changelog") ?? []
56
+ const changelogSections = config.sections?.filter(s => s.type === "changelog") ?? []
58
57
  for (const section of changelogSections) {
59
58
  await buildChangelog(section, config)
60
59
  }
61
60
 
62
- const configInclude = Array.isArray(config.include)
63
- ? config.include
64
- : [config.include]
65
- const include = changelogSections.length
66
- ? [...configInclude, cacheIncludeGlob(config)]
67
- : configInclude
61
+ const configInclude = Array.isArray(config.include) ? config.include : [config.include]
62
+ const include = [
63
+ ...configInclude,
64
+ ...changelogSections.map(section => cacheIncludeGlob(section, config)),
65
+ ]
68
66
 
69
67
  const userExclude = config.exclude
70
68
  ? Array.isArray(config.exclude)
@@ -1,7 +1,7 @@
1
1
  import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion"
2
2
  import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"
3
3
 
4
- import { cn } from "../utils/style.ts"
4
+ import { cn } from "cn"
5
5
 
6
6
  function Accordion({ className, ...props }: AccordionPrimitive.Root.Props) {
7
7
  return (
@@ -1,7 +1,7 @@
1
1
  import * as React from "react"
2
2
  import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog"
3
3
 
4
- import { cn } from "../utils/style.ts"
4
+ import { cn } from "cn"
5
5
  import { Button } from "./button.tsx"
6
6
 
7
7
  function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {
@@ -9,15 +9,11 @@ function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {
9
9
  }
10
10
 
11
11
  function AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {
12
- return (
13
- <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
14
- )
12
+ return <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
15
13
  }
16
14
 
17
15
  function AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {
18
- return (
19
- <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
20
- )
16
+ return <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
21
17
  }
22
18
 
23
19
  function AlertDialogOverlay({
@@ -59,10 +55,7 @@ function AlertDialogContent({
59
55
  )
60
56
  }
61
57
 
62
- function AlertDialogHeader({
63
- className,
64
- ...props
65
- }: React.ComponentProps<"div">) {
58
+ function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">) {
66
59
  return (
67
60
  <div
68
61
  data-slot="alert-dialog-header"
@@ -75,10 +68,7 @@ function AlertDialogHeader({
75
68
  )
76
69
  }
77
70
 
78
- function AlertDialogFooter({
79
- className,
80
- ...props
81
- }: React.ComponentProps<"div">) {
71
+ function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">) {
82
72
  return (
83
73
  <div
84
74
  data-slot="alert-dialog-footer"
@@ -91,10 +81,7 @@ function AlertDialogFooter({
91
81
  )
92
82
  }
93
83
 
94
- function AlertDialogMedia({
95
- className,
96
- ...props
97
- }: React.ComponentProps<"div">) {
84
+ function AlertDialogMedia({ className, ...props }: React.ComponentProps<"div">) {
98
85
  return (
99
86
  <div
100
87
  data-slot="alert-dialog-media"
@@ -139,17 +126,8 @@ function AlertDialogDescription({
139
126
  )
140
127
  }
141
128
 
142
- function AlertDialogAction({
143
- className,
144
- ...props
145
- }: React.ComponentProps<typeof Button>) {
146
- return (
147
- <Button
148
- data-slot="alert-dialog-action"
149
- className={cn(className)}
150
- {...props}
151
- />
152
- )
129
+ function AlertDialogAction({ className, ...props }: React.ComponentProps<typeof Button>) {
130
+ return <Button data-slot="alert-dialog-action" className={cn(className)} {...props} />
153
131
  }
154
132
 
155
133
  function AlertDialogCancel({
@@ -1,5 +1,5 @@
1
1
  import { cva, type VariantProps } from "class-variance-authority"
2
- import { cn } from "../utils/style.ts"
2
+ import { cn } from "cn"
3
3
 
4
4
  const alertVariants = cva(
5
5
  "grid gap-0.5 rounded-lg border px-4 py-3 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 w-full relative group/alert",
@@ -45,10 +45,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
45
45
  )
46
46
  }
47
47
 
48
- function AlertDescription({
49
- className,
50
- ...props
51
- }: React.ComponentProps<"div">) {
48
+ function AlertDescription({ className, ...props }: React.ComponentProps<"div">) {
52
49
  return (
53
50
  <div
54
51
  data-slot="alert-description"
@@ -1,4 +1,4 @@
1
- import { cn } from "../utils/style.ts"
1
+ import { cn } from "cn"
2
2
 
3
3
  function AspectRatio({
4
4
  ratio,