livemark 0.25.0 → 0.27.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 (427) hide show
  1. package/README.md +3 -2
  2. package/build/actions/config/define.d.ts +12 -0
  3. package/build/actions/config/define.unit.js +8 -1
  4. package/build/actions/escape/copy.d.ts +11 -0
  5. package/build/actions/escape/copy.js +29 -0
  6. package/build/actions/escape/copy.unit.d.ts +1 -0
  7. package/build/actions/escape/copy.unit.js +37 -0
  8. package/build/actions/escape/list.d.ts +12 -0
  9. package/build/actions/escape/list.js +27 -0
  10. package/build/actions/escape/list.unit.d.ts +1 -0
  11. package/build/actions/escape/list.unit.js +36 -0
  12. package/build/actions/target/build.d.ts +9 -26
  13. package/build/actions/target/build.js +50 -71
  14. package/build/actions/target/build.unit.d.ts +1 -0
  15. package/build/actions/target/build.unit.js +76 -0
  16. package/build/actions/target/clear.d.ts +4 -0
  17. package/build/actions/target/clear.js +14 -0
  18. package/build/actions/target/clear.unit.d.ts +1 -0
  19. package/build/actions/target/clear.unit.js +23 -0
  20. package/build/commands/build.js +1 -2
  21. package/build/commands/clear.d.ts +5 -0
  22. package/build/commands/clear.js +15 -0
  23. package/build/commands/escape.d.ts +4 -3
  24. package/build/commands/escape.js +45 -48
  25. package/build/commands/preview.js +1 -2
  26. package/build/commands/start.js +1 -2
  27. package/build/components/Abbr.d.ts +1 -1
  28. package/build/components/Abbr.js +2 -4
  29. package/build/components/AnsiCode.d.ts +1 -1
  30. package/build/components/AnsiCode.js +2 -2
  31. package/build/components/Article.d.ts +2 -1
  32. package/build/components/Article.js +7 -14
  33. package/build/components/BackToTop.d.ts +1 -1
  34. package/build/components/Banner.d.ts +2 -2
  35. package/build/components/Banner.js +7 -3
  36. package/build/components/BlogIndex.d.ts +1 -1
  37. package/build/components/BlogIndex.js +2 -11
  38. package/build/components/Breadcrumbs.d.ts +1 -1
  39. package/build/components/Breadcrumbs.js +2 -3
  40. package/build/components/Callout.d.ts +1 -1
  41. package/build/components/Callout.js +5 -9
  42. package/build/components/Card.d.ts +1 -1
  43. package/build/components/Card.js +2 -3
  44. package/build/components/Cards.d.ts +1 -1
  45. package/build/components/ChangelogIndex.d.ts +1 -1
  46. package/build/components/ChangelogIndex.js +2 -11
  47. package/build/components/ChoiceList.d.ts +15 -0
  48. package/build/components/ChoiceList.js +13 -0
  49. package/build/components/CodeBlock.d.ts +1 -1
  50. package/build/components/CodeBlock.js +3 -16
  51. package/build/components/CodeTabs.d.ts +1 -1
  52. package/build/components/CodeTabs.js +2 -3
  53. package/build/components/Column.d.ts +1 -1
  54. package/build/components/Columns.d.ts +1 -1
  55. package/build/components/Content.d.ts +1 -1
  56. package/build/components/ContentTab.d.ts +1 -1
  57. package/build/components/ContentTabs.d.ts +1 -1
  58. package/build/components/ContentTabs.js +2 -3
  59. package/build/components/DefaultCatchBoundary.d.ts +1 -1
  60. package/build/components/DefaultCatchBoundary.js +5 -7
  61. package/build/components/DefinitionList.d.ts +3 -3
  62. package/build/components/Details.d.ts +1 -1
  63. package/build/components/Details.js +2 -5
  64. package/build/components/FileTree.d.ts +1 -1
  65. package/build/components/FileTree.js +3 -5
  66. package/build/components/Footer.d.ts +1 -1
  67. package/build/components/Footer.js +2 -5
  68. package/build/components/FootnoteRef.d.ts +1 -1
  69. package/build/components/FootnoteRef.js +2 -4
  70. package/build/components/Header.d.ts +6 -0
  71. package/build/components/Header.js +26 -0
  72. package/build/components/HeaderMenu.d.ts +2 -0
  73. package/build/components/HeaderMenu.js +27 -0
  74. package/build/components/HeaderNav.d.ts +6 -0
  75. package/build/components/HeaderNav.js +74 -0
  76. package/build/components/HeaderSearch.d.ts +4 -0
  77. package/build/components/HeaderSearch.js +33 -0
  78. package/build/components/Heading.d.ts +6 -6
  79. package/build/components/InlineBadge.d.ts +2 -2
  80. package/build/components/InlineBadge.js +1 -1
  81. package/build/components/InlineIcon.d.ts +1 -1
  82. package/build/components/InlineToc.d.ts +1 -1
  83. package/build/components/InlineToc.js +2 -4
  84. package/build/components/Layout.d.ts +2 -1
  85. package/build/components/Layout.js +5 -58
  86. package/build/components/LinkButton.d.ts +2 -2
  87. package/build/components/LinkButton.js +1 -1
  88. package/build/components/MenuSheet.d.ts +22 -0
  89. package/build/components/MenuSheet.js +27 -0
  90. package/build/components/Mermaid.d.ts +1 -1
  91. package/build/components/MermaidRenderer.d.ts +1 -1
  92. package/build/components/MermaidRenderer.js +20 -8
  93. package/build/components/NotFound.d.ts +1 -1
  94. package/build/components/NotFound.js +3 -6
  95. package/build/components/PackageTabs.d.ts +1 -1
  96. package/build/components/PackageTabs.js +3 -7
  97. package/build/components/PageToolbar.d.ts +1 -1
  98. package/build/components/PageToolbar.js +2 -10
  99. package/build/components/PrevNext.d.ts +1 -1
  100. package/build/components/PrevNext.js +2 -10
  101. package/build/components/Root.d.ts +4 -0
  102. package/build/components/Root.js +8 -0
  103. package/build/components/Search.d.ts +5 -2
  104. package/build/components/Search.js +11 -9
  105. package/build/components/SearchDialog.d.ts +1 -1
  106. package/build/components/SearchDialog.js +10 -133
  107. package/build/components/Section.d.ts +1 -1
  108. package/build/components/SectionHeader.d.ts +1 -1
  109. package/build/components/SheetPanel.d.ts +12 -0
  110. package/build/components/SheetPanel.js +19 -0
  111. package/build/components/Sidebar.d.ts +1 -1
  112. package/build/components/Sidebar.js +12 -14
  113. package/build/components/SidebarArticles.d.ts +4 -1
  114. package/build/components/SidebarArticles.js +5 -9
  115. package/build/components/SidebarLinks.d.ts +4 -1
  116. package/build/components/SidebarLinks.js +6 -9
  117. package/build/components/SidebarPosts.d.ts +4 -1
  118. package/build/components/SidebarPosts.js +7 -23
  119. package/build/components/SidebarReleases.d.ts +4 -1
  120. package/build/components/SidebarReleases.js +5 -15
  121. package/build/components/SidebarSectionPicker.d.ts +8 -0
  122. package/build/components/SidebarSectionPicker.js +31 -0
  123. package/build/components/SidebarSections.d.ts +1 -1
  124. package/build/components/SidebarSections.js +5 -9
  125. package/build/components/SiteLink.d.ts +1 -1
  126. package/build/components/SiteTitle.d.ts +1 -1
  127. package/build/components/SiteTitle.js +2 -6
  128. package/build/components/SortableTable.d.ts +1 -1
  129. package/build/components/SoundCloud.d.ts +1 -1
  130. package/build/components/SoundCloud.js +2 -2
  131. package/build/components/TagIndex.d.ts +1 -1
  132. package/build/components/TagIndex.js +2 -11
  133. package/build/components/Theme.d.ts +2 -1
  134. package/build/components/Theme.js +35 -15
  135. package/build/components/Toc.d.ts +5 -4
  136. package/build/components/Toc.js +35 -35
  137. package/build/components/YouTube.d.ts +1 -1
  138. package/build/components/YouTube.js +2 -2
  139. package/build/components/ZoomImage.d.ts +1 -1
  140. package/build/content/article.js +4 -11
  141. package/build/content-collections.js +6 -4
  142. package/build/elements/accordion.d.ts +4 -4
  143. package/build/elements/accordion.js +2 -3
  144. package/build/elements/alert-dialog.d.ts +12 -12
  145. package/build/elements/alert-dialog.js +2 -4
  146. package/build/elements/alert.d.ts +4 -4
  147. package/build/elements/alert.js +2 -2
  148. package/build/elements/aspect-ratio.d.ts +1 -1
  149. package/build/elements/avatar.d.ts +6 -6
  150. package/build/elements/badge.d.ts +1 -1
  151. package/build/elements/badge.js +3 -1
  152. package/build/elements/breadcrumb.d.ts +6 -6
  153. package/build/elements/breadcrumb.js +2 -4
  154. package/build/elements/button-group.d.ts +2 -2
  155. package/build/elements/button-group.js +5 -5
  156. package/build/elements/button.d.ts +2 -2
  157. package/build/elements/button.js +9 -7
  158. package/build/elements/calendar.d.ts +2 -2
  159. package/build/elements/calendar.js +2 -2
  160. package/build/elements/card.d.ts +7 -7
  161. package/build/elements/card.js +4 -4
  162. package/build/elements/carousel.d.ts +5 -5
  163. package/build/elements/carousel.js +3 -7
  164. package/build/elements/chart.d.ts +6 -6
  165. package/build/elements/chart.js +5 -11
  166. package/build/elements/checkbox.d.ts +1 -1
  167. package/build/elements/collapsible.d.ts +3 -3
  168. package/build/elements/command.d.ts +9 -9
  169. package/build/elements/command.js +5 -11
  170. package/build/elements/context-menu.d.ts +15 -15
  171. package/build/elements/context-menu.js +6 -9
  172. package/build/elements/dialog.d.ts +10 -10
  173. package/build/elements/dialog.js +2 -6
  174. package/build/elements/drawer.d.ts +14 -12
  175. package/build/elements/drawer.js +14 -15
  176. package/build/elements/dropdown-menu.d.ts +15 -15
  177. package/build/elements/dropdown-menu.js +7 -10
  178. package/build/elements/empty.d.ts +6 -6
  179. package/build/elements/empty.js +2 -2
  180. package/build/elements/field.d.ts +10 -10
  181. package/build/elements/field.js +3 -4
  182. package/build/elements/hover-card.d.ts +3 -3
  183. package/build/elements/hover-card.js +2 -2
  184. package/build/elements/input-group.d.ts +7 -7
  185. package/build/elements/input-group.js +5 -5
  186. package/build/elements/input-otp.d.ts +4 -4
  187. package/build/elements/input.d.ts +1 -1
  188. package/build/elements/input.js +2 -2
  189. package/build/elements/item.d.ts +9 -9
  190. package/build/elements/item.js +2 -2
  191. package/build/elements/kbd.d.ts +2 -2
  192. package/build/elements/label.d.ts +1 -1
  193. package/build/elements/menubar.d.ts +16 -16
  194. package/build/elements/menubar.js +9 -11
  195. package/build/elements/native-select.d.ts +3 -3
  196. package/build/elements/native-select.js +2 -4
  197. package/build/elements/navigation-menu.d.ts +8 -8
  198. package/build/elements/navigation-menu.js +3 -5
  199. package/build/elements/pagination.d.ts +7 -7
  200. package/build/elements/pagination.js +4 -10
  201. package/build/elements/popover.d.ts +6 -6
  202. package/build/elements/popover.js +2 -2
  203. package/build/elements/progress.d.ts +5 -5
  204. package/build/elements/progress.js +2 -3
  205. package/build/elements/radio-group.d.ts +2 -2
  206. package/build/elements/resizable.d.ts +3 -3
  207. package/build/elements/scroll-area.d.ts +2 -2
  208. package/build/elements/scroll-area.js +2 -4
  209. package/build/elements/select.d.ts +9 -9
  210. package/build/elements/select.js +4 -9
  211. package/build/elements/separator.d.ts +1 -1
  212. package/build/elements/sheet.d.ts +8 -8
  213. package/build/elements/sheet.js +2 -6
  214. package/build/elements/sidebar.d.ts +19 -19
  215. package/build/elements/sidebar.js +15 -37
  216. package/build/elements/skeleton.d.ts +1 -1
  217. package/build/elements/slider.d.ts +2 -1
  218. package/build/elements/slider.js +2 -3
  219. package/build/elements/sonner.d.ts +1 -1
  220. package/build/elements/spinner.d.ts +1 -1
  221. package/build/elements/switch.d.ts +1 -1
  222. package/build/elements/table.d.ts +8 -8
  223. package/build/elements/tabs.d.ts +4 -4
  224. package/build/elements/tabs.js +3 -3
  225. package/build/elements/textarea.d.ts +1 -1
  226. package/build/elements/textarea.js +2 -2
  227. package/build/elements/toggle-group.d.ts +3 -2
  228. package/build/elements/toggle-group.js +3 -3
  229. package/build/elements/toggle.d.ts +1 -1
  230. package/build/elements/toggle.js +2 -2
  231. package/build/elements/tooltip.d.ts +4 -4
  232. package/build/elements/tooltip.js +2 -3
  233. package/build/head.d.ts +4 -0
  234. package/build/head.js +6 -0
  235. package/build/helpers/agent-skills.d.ts +22 -0
  236. package/build/helpers/agent-skills.js +46 -0
  237. package/build/helpers/agent-skills.unit.d.ts +1 -0
  238. package/build/helpers/agent-skills.unit.js +49 -0
  239. package/build/helpers/article-search.d.ts +19 -0
  240. package/build/helpers/article-search.js +134 -0
  241. package/build/helpers/article.d.ts +13 -0
  242. package/build/helpers/article.js +17 -1
  243. package/build/helpers/dependency-dir.d.ts +5 -0
  244. package/build/helpers/dependency-dir.js +20 -0
  245. package/build/helpers/dependency-dir.unit.d.ts +1 -0
  246. package/build/helpers/dependency-dir.unit.js +25 -0
  247. package/build/helpers/dynamic-icon-resolver.d.ts +1 -1
  248. package/build/helpers/dynamic-icon.d.ts +1 -1
  249. package/build/helpers/head.d.ts +58 -0
  250. package/build/helpers/head.js +80 -0
  251. package/build/helpers/head.unit.d.ts +1 -0
  252. package/build/helpers/head.unit.js +110 -0
  253. package/build/helpers/llms.d.ts +33 -0
  254. package/build/helpers/llms.js +72 -0
  255. package/build/helpers/llms.unit.d.ts +1 -0
  256. package/build/helpers/llms.unit.js +98 -0
  257. package/build/helpers/nav-items.d.ts +11 -0
  258. package/build/helpers/nav-items.js +65 -0
  259. package/build/helpers/render-inline-markdown.d.ts +1 -0
  260. package/build/helpers/render-inline-markdown.js +34 -0
  261. package/build/helpers/render-inline-markdown.unit.d.ts +1 -0
  262. package/build/helpers/render-inline-markdown.unit.js +20 -0
  263. package/build/helpers/search-highlight.d.ts +8 -0
  264. package/build/helpers/search-highlight.js +59 -0
  265. package/build/helpers/search-highlight.unit.d.ts +1 -0
  266. package/build/helpers/search-highlight.unit.js +36 -0
  267. package/build/helpers/target-export.d.ts +9 -0
  268. package/build/helpers/target-export.js +24 -0
  269. package/build/helpers/target-export.unit.d.ts +1 -0
  270. package/build/helpers/target-export.unit.js +25 -0
  271. package/build/helpers/theme.d.ts +6 -2
  272. package/build/helpers/theme.js +40 -7
  273. package/build/helpers/theme.unit.d.ts +1 -0
  274. package/build/helpers/theme.unit.js +30 -0
  275. package/build/hooks/hydrated.d.ts +2 -0
  276. package/build/hooks/hydrated.js +15 -0
  277. package/build/index.d.ts +1 -0
  278. package/build/index.js +1 -1
  279. package/build/models/config.d.ts +52 -6
  280. package/build/models/config.js +17 -1
  281. package/build/models/section.d.ts +4 -2
  282. package/build/models/section.js +1 -1
  283. package/build/plugins/vite-agents.d.ts +17 -0
  284. package/build/plugins/vite-agents.js +109 -0
  285. package/build/plugins/vite-agents.unit.d.ts +1 -0
  286. package/build/plugins/vite-agents.unit.js +20 -0
  287. package/build/plugins/vite-livemark.d.ts +4 -5
  288. package/build/plugins/vite-livemark.js +56 -90
  289. package/build/plugins/vite-robots.d.ts +4 -2
  290. package/build/plugins/vite-robots.js +15 -2
  291. package/build/plugins/vite-robots.unit.js +5 -1
  292. package/build/program.js +4 -2
  293. package/build/routes/$.d.ts +4 -1
  294. package/build/routes/$.js +20 -9
  295. package/build/routes/__root.js +29 -63
  296. package/build/settings.js +2 -1
  297. package/build/vite.config.js +3 -1
  298. package/package.json +69 -66
  299. package/{.agents/skills → skills}/livemark-authoring/SKILL.md +2 -2
  300. package/{.agents/skills → skills}/livemark-configuration/SKILL.md +16 -5
  301. package/skills/livemark-customization/SKILL.md +146 -0
  302. package/source/actions/config/define.unit.ts +9 -0
  303. package/source/actions/escape/copy.ts +35 -0
  304. package/source/actions/escape/copy.unit.ts +51 -0
  305. package/source/actions/escape/list.ts +30 -0
  306. package/source/actions/escape/list.unit.ts +42 -0
  307. package/source/actions/target/build.ts +49 -69
  308. package/source/actions/target/build.unit.ts +95 -0
  309. package/source/actions/target/clear.ts +14 -0
  310. package/source/actions/target/clear.unit.ts +25 -0
  311. package/source/commands/build.ts +0 -1
  312. package/source/commands/clear.ts +15 -0
  313. package/source/commands/escape.ts +42 -59
  314. package/source/commands/preview.ts +0 -1
  315. package/source/commands/start.ts +0 -1
  316. package/source/components/AnsiCode.tsx +1 -1
  317. package/source/components/Article.tsx +8 -4
  318. package/source/components/Banner.tsx +12 -2
  319. package/source/components/BlogIndex.tsx +1 -1
  320. package/source/components/Callout.tsx +4 -6
  321. package/source/components/ChangelogIndex.tsx +1 -1
  322. package/source/components/ChoiceList.tsx +69 -0
  323. package/source/components/CodeBlock.tsx +6 -6
  324. package/source/components/CodeTabs.tsx +1 -1
  325. package/source/components/ContentTabs.tsx +1 -1
  326. package/source/components/DefaultCatchBoundary.tsx +4 -6
  327. package/source/components/Details.tsx +1 -1
  328. package/source/components/FileTree.tsx +1 -1
  329. package/source/components/Header.tsx +52 -0
  330. package/source/components/HeaderMenu.tsx +41 -0
  331. package/source/components/HeaderNav.tsx +145 -0
  332. package/source/components/HeaderSearch.tsx +77 -0
  333. package/source/components/InlineBadge.tsx +1 -1
  334. package/source/components/InlineToc.tsx +1 -1
  335. package/source/components/Layout.tsx +16 -160
  336. package/source/components/LinkButton.tsx +9 -1
  337. package/source/components/MenuSheet.tsx +92 -0
  338. package/source/components/MermaidRenderer.tsx +19 -8
  339. package/source/components/NotFound.tsx +3 -5
  340. package/source/components/PackageTabs.tsx +2 -2
  341. package/source/components/PageToolbar.tsx +11 -3
  342. package/source/components/PrevNext.tsx +2 -2
  343. package/source/components/Root.tsx +13 -0
  344. package/source/components/Search.tsx +28 -8
  345. package/source/components/SearchDialog.tsx +15 -189
  346. package/source/components/SheetPanel.tsx +69 -0
  347. package/source/components/Sidebar.tsx +27 -14
  348. package/source/components/SidebarArticles.tsx +4 -3
  349. package/source/components/SidebarLinks.tsx +3 -2
  350. package/source/components/SidebarPosts.tsx +3 -2
  351. package/source/components/SidebarReleases.tsx +3 -2
  352. package/source/components/SidebarSectionPicker.tsx +70 -0
  353. package/source/components/SiteTitle.tsx +5 -5
  354. package/source/components/SoundCloud.tsx +1 -1
  355. package/source/components/TagIndex.tsx +1 -1
  356. package/source/components/Theme.tsx +55 -29
  357. package/source/components/Toc.tsx +76 -55
  358. package/source/components/YouTube.tsx +1 -1
  359. package/source/content/article.ts +8 -13
  360. package/source/content-collections.ts +5 -4
  361. package/source/elements/alert-dialog.tsx +1 -1
  362. package/source/elements/alert.tsx +1 -1
  363. package/source/elements/badge.tsx +4 -0
  364. package/source/elements/button-group.tsx +4 -4
  365. package/source/elements/button.tsx +10 -6
  366. package/source/elements/calendar.tsx +1 -1
  367. package/source/elements/card.tsx +3 -3
  368. package/source/elements/command.tsx +7 -4
  369. package/source/elements/context-menu.tsx +5 -5
  370. package/source/elements/dialog.tsx +1 -1
  371. package/source/elements/drawer.tsx +59 -43
  372. package/source/elements/dropdown-menu.tsx +6 -6
  373. package/source/elements/empty.tsx +1 -1
  374. package/source/elements/field.tsx +1 -1
  375. package/source/elements/hover-card.tsx +1 -1
  376. package/source/elements/input-group.tsx +4 -4
  377. package/source/elements/input.tsx +1 -1
  378. package/source/elements/item.tsx +1 -1
  379. package/source/elements/menubar.tsx +8 -8
  380. package/source/elements/native-select.tsx +1 -1
  381. package/source/elements/popover.tsx +1 -1
  382. package/source/elements/select.tsx +3 -3
  383. package/source/elements/sidebar.tsx +8 -21
  384. package/source/elements/tabs.tsx +2 -2
  385. package/source/elements/textarea.tsx +1 -1
  386. package/source/elements/toggle-group.tsx +2 -2
  387. package/source/elements/toggle.tsx +1 -1
  388. package/source/env.d.ts +1 -0
  389. package/source/head.ts +7 -0
  390. package/source/helpers/agent-skills.ts +59 -0
  391. package/source/helpers/agent-skills.unit.ts +56 -0
  392. package/source/helpers/article-search.tsx +192 -0
  393. package/source/helpers/article.ts +17 -0
  394. package/source/helpers/dependency-dir.ts +20 -0
  395. package/source/helpers/dependency-dir.unit.ts +39 -0
  396. package/source/helpers/head.ts +105 -0
  397. package/source/helpers/head.unit.ts +118 -0
  398. package/source/helpers/llms.ts +109 -0
  399. package/source/helpers/llms.unit.ts +115 -0
  400. package/source/helpers/nav-items.tsx +102 -0
  401. package/source/helpers/render-inline-markdown.ts +44 -0
  402. package/source/helpers/render-inline-markdown.unit.ts +30 -0
  403. package/source/helpers/search-highlight.ts +73 -0
  404. package/source/helpers/search-highlight.unit.ts +42 -0
  405. package/source/helpers/target-export.ts +28 -0
  406. package/source/helpers/target-export.unit.ts +37 -0
  407. package/source/helpers/theme.ts +40 -6
  408. package/source/helpers/theme.unit.ts +32 -0
  409. package/source/hooks/hydrated.ts +18 -0
  410. package/source/index.ts +1 -0
  411. package/source/models/config.ts +24 -0
  412. package/source/models/section.ts +3 -0
  413. package/source/plugins/vite-agents.ts +135 -0
  414. package/source/plugins/vite-agents.unit.ts +26 -0
  415. package/source/plugins/vite-livemark.ts +54 -95
  416. package/source/plugins/vite-robots.ts +18 -3
  417. package/source/plugins/vite-robots.unit.ts +7 -0
  418. package/source/program.ts +2 -0
  419. package/source/routes/$.tsx +27 -9
  420. package/source/routes/__root.tsx +51 -71
  421. package/source/settings.ts +1 -0
  422. package/source/styles/general.css +59 -11
  423. package/source/styles/markdown.css +13 -7
  424. package/source/styles/shape.css +14 -0
  425. package/source/vite.config.ts +2 -0
  426. package/.agents/skills/change-review/SKILL.md +0 -47
  427. package/.agents/skills/livemark-customization/SKILL.md +0 -118
@@ -1,72 +1,39 @@
1
1
  import { config } from "livemark:virtual"
2
2
  import { TanStackDevtools } from "@tanstack/react-devtools"
3
3
  import { ReactQueryDevtoolsPanel } from "@tanstack/react-query-devtools"
4
- import {
5
- createRootRoute,
6
- HeadContent,
7
- Outlet,
8
- Scripts,
9
- useMatch,
10
- } from "@tanstack/react-router"
4
+ import { createRootRoute, HeadContent, Outlet, Scripts } from "@tanstack/react-router"
11
5
  import { TanStackRouterDevtoolsPanel } from "@tanstack/react-router-devtools"
12
6
  import type * as React from "react"
7
+ import { useEffect } from "react"
13
8
  import { Layout } from "../components/Layout.tsx"
9
+ import { Root } from "../components/Root.tsx"
14
10
  import { DefaultCatchBoundary } from "../components/DefaultCatchBoundary.tsx"
15
11
  import { NotFound } from "../components/NotFound.tsx"
12
+ import { useHydrated } from "../hooks/hydrated.ts"
16
13
  import { Toaster } from "../elements/sonner.tsx"
17
- import { faviconType } from "../helpers/favicon.ts"
18
- import { prefixUrl } from "../helpers/prefix-url.ts"
14
+ import { buildRootHead } from "../helpers/head.ts"
15
+ import { startTheme } from "../helpers/theme.ts"
16
+ import { customizeHead } from "../head.ts"
19
17
  import defaultFavicon from "../assets/logo.svg"
20
18
  import generalCss from "../styles/general.css?url"
21
19
  import markdownCss from "../styles/markdown.css?url"
22
20
 
23
21
  export const Route = createRootRoute({
24
- head: () => {
25
- const favicon = prefixUrl(
26
- config.favicon ?? config.logo ?? defaultFavicon,
27
- config.base,
28
- )
29
- const feedLinks = config.site
30
- ? (config.sections ?? [])
31
- .filter(s => s.type === "blog")
32
- .map(s => ({
33
- rel: "alternate",
34
- type: "application/rss+xml",
35
- title: `${s.siteTitle ?? s.title} RSS Feed`,
36
- href: prefixUrl(`${s.prefix}rss.xml`, config.base),
37
- }))
38
- : []
39
- return {
40
- meta: [
41
- { charSet: "utf-8" },
42
- { title: config.title },
43
- { name: "description", content: config.description },
44
- { property: "og:title", content: config.title },
45
- {
46
- property: "og:description",
47
- content: config.description,
48
- },
49
- { property: "og:site_name", content: config.title },
50
- { property: "og:type", content: "website" },
51
- {
52
- name: "viewport",
53
- content: "width=device-width, initial-scale=1",
54
- },
55
- ],
56
- links: [
57
- { rel: "icon", href: favicon, type: faviconType(favicon) },
58
- { rel: "shortcut icon", href: favicon, type: faviconType(favicon) },
59
- { rel: "stylesheet", href: generalCss },
60
- { rel: "stylesheet", href: markdownCss },
61
- ...feedLinks,
62
- ],
63
- }
64
- },
65
- notFoundComponent: () => <NotFound />,
22
+ head: () =>
23
+ customizeHead(
24
+ buildRootHead({ config, defaultFavicon, stylesheets: [generalCss, markdownCss] }),
25
+ ),
26
+ notFoundComponent: () => (
27
+ <Layout>
28
+ <NotFound />
29
+ </Layout>
30
+ ),
66
31
  errorComponent: props => {
67
32
  return (
68
33
  <Document>
69
- <DefaultCatchBoundary {...props} />
34
+ <Layout>
35
+ <DefaultCatchBoundary {...props} />
36
+ </Layout>
70
37
  </Document>
71
38
  )
72
39
  },
@@ -80,32 +47,45 @@ export const Route = createRootRoute({
80
47
  })
81
48
 
82
49
  function Document(props: { children: React.ReactNode }) {
83
- const articleRoute = useMatch({ from: "/$", shouldThrow: false })
84
- const withSidebar = articleRoute?.loaderData?.sidebar
50
+ // Off the raw URL, not the router's parsed search: a route whose validateSearch
51
+ // does not declare this key strips it.
52
+ const hydrated = useHydrated()
53
+ const devtools = hydrated && window.location.search.includes("tanstack-devtools")
54
+
55
+ useEffect(startTheme, [])
85
56
 
86
57
  return (
87
- <html lang="en">
58
+ <html lang="en" suppressHydrationWarning>
88
59
  <head>
89
60
  <HeadContent />
90
61
  </head>
91
62
  <body>
92
- <Layout withSidebar={withSidebar}>{props.children}</Layout>
63
+ <Root>{props.children}</Root>
93
64
  <Toaster position="top-center" />
94
- <TanStackDevtools
95
- config={{ hideUntilHover: true, position: "bottom-left" }}
96
- plugins={[
97
- {
98
- name: "TanStack Query",
99
- render: <ReactQueryDevtoolsPanel />,
100
- defaultOpen: true,
101
- },
102
- {
103
- name: "TanStack Router",
104
- render: <TanStackRouterDevtoolsPanel />,
105
- defaultOpen: false,
106
- },
107
- ]}
108
- />
65
+ {/* Gated here, not by the devtools' own `requireUrlFlag`: that setting seeds
66
+ localStorage on a browser's first run and is read from there afterwards,
67
+ so a browser that loaded the site before it was set keeps the trigger. */}
68
+ {/* The build strips the devtools element alone; the fragment keeps
69
+ `devtools && (<></>)` valid instead of the syntax error `&& ()`. */}
70
+ {devtools && (
71
+ <>
72
+ <TanStackDevtools
73
+ config={{ requireUrlFlag: true, position: "bottom-left" }}
74
+ plugins={[
75
+ {
76
+ name: "TanStack Query",
77
+ render: <ReactQueryDevtoolsPanel />,
78
+ defaultOpen: true,
79
+ },
80
+ {
81
+ name: "TanStack Router",
82
+ render: <TanStackRouterDevtoolsPanel />,
83
+ defaultOpen: false,
84
+ },
85
+ ]}
86
+ />
87
+ </>
88
+ )}
109
89
  <Scripts />
110
90
  </body>
111
91
  </html>
@@ -14,6 +14,7 @@ export const ESCAPABLE_FILES: readonly string[] = [
14
14
  "client.tsx",
15
15
  "server.ts",
16
16
  "router.tsx",
17
+ "head.ts",
17
18
  ]
18
19
 
19
20
  /** Glob patterns auto-excluded from content scanning when the consumer's
@@ -1,5 +1,6 @@
1
1
  @import "tailwindcss";
2
2
  @import "tw-animate-css";
3
+ @import "./shape.css";
3
4
  @plugin "@tailwindcss/typography";
4
5
 
5
6
  @custom-variant dark (&:is(.dark *));
@@ -13,14 +14,28 @@
13
14
  --popover-foreground: oklch(0.145 0 0);
14
15
  --primary: oklch(54.6% 0.245 262.881);
15
16
  --primary-foreground: oklch(0.985 0 0);
16
- --secondary: oklch(89.4% 0.057 293.283);
17
- --secondary-foreground: oklch(0.205 0 0);
18
- --muted: oklch(0.97 0 0);
17
+ --secondary: oklch(54.1% 0.281 293.009);
18
+ --secondary-foreground: oklch(0.985 0 0);
19
+ --banner: oklch(89.4% 0.057 293.283);
20
+ --banner-foreground: oklch(0.205 0 0);
21
+ --muted: oklch(0.985 0 0);
19
22
  --muted-foreground: oklch(0.5 0 0);
20
23
  --accent: oklch(0.97 0 0);
21
24
  --accent-foreground: oklch(0.205 0 0);
22
- --destructive: oklch(0.577 0.245 27.325);
23
- --destructive-foreground: oklch(0.577 0.245 27.325);
25
+ --positive: oklch(0.648 0.2 131.684);
26
+ --positive-foreground: oklch(0.205 0 0);
27
+ --positive-tint: oklch(96.7% 0.067 122.328);
28
+ --positive-tint-foreground: oklch(53.2% 0.157 131.589);
29
+ --warning: oklch(79.5% 0.184 86.047);
30
+ --warning-foreground: oklch(0.205 0 0);
31
+ --warning-tint: oklch(97.3% 0.071 103.193);
32
+ --warning-tint-foreground: oklch(47.6% 0.114 61.907);
33
+ --highlight: oklch(90.5% 0.182 98.111);
34
+ --highlight-foreground: oklch(0.205 0 0);
35
+ --destructive: oklch(0.55 0.2 25);
36
+ --destructive-foreground: oklch(0.985 0 0);
37
+ --destructive-tint: oklch(93.6% 0.032 17.717);
38
+ --destructive-tint-foreground: oklch(50.5% 0.213 27.518);
24
39
  --border: oklch(0.922 0 0);
25
40
  --input: oklch(0.922 0 0);
26
41
  --ring: oklch(0.708 0 0);
@@ -30,7 +45,7 @@
30
45
  --chart-4: oklch(0.828 0.189 84.429);
31
46
  --chart-5: oklch(0.769 0.188 70.08);
32
47
  --radius: 0.625rem;
33
- --sidebar: oklch(0.985 0 0);
48
+ --sidebar: var(--muted);
34
49
  --sidebar-foreground: oklch(0.145 0 0);
35
50
  --sidebar-primary: oklch(0.205 0 0);
36
51
  --sidebar-primary-foreground: oklch(0.985 0 0);
@@ -49,14 +64,28 @@
49
64
  --popover-foreground: oklch(0.985 0 0);
50
65
  --primary: oklch(0.623 0.214 259.815);
51
66
  --primary-foreground: oklch(0.985 0 0);
52
- --secondary: oklch(0.269 0 0);
67
+ --secondary: oklch(60.6% 0.25 292.717);
53
68
  --secondary-foreground: oklch(0.985 0 0);
54
- --muted: oklch(0.269 0 0);
69
+ --banner: oklch(0.269 0 0);
70
+ --banner-foreground: oklch(0.985 0 0);
71
+ --muted: oklch(0.205 0 0);
55
72
  --muted-foreground: oklch(0.708 0 0);
56
73
  --accent: oklch(0.269 0 0);
57
74
  --accent-foreground: oklch(0.985 0 0);
58
- --destructive: oklch(0.396 0.141 25.723);
59
- --destructive-foreground: oklch(0.637 0.237 25.331);
75
+ --positive: oklch(0.841 0.238 128.85);
76
+ --positive-foreground: oklch(0.205 0 0);
77
+ --positive-tint: oklch(27.4% 0.072 132.109);
78
+ --positive-tint-foreground: oklch(84.1% 0.238 128.85);
79
+ --warning: oklch(85.2% 0.199 91.936);
80
+ --warning-foreground: oklch(0.22 0.04 70);
81
+ --warning-tint: oklch(28.6% 0.066 53.813);
82
+ --warning-tint-foreground: oklch(85.2% 0.199 91.936);
83
+ --highlight: oklch(55.4% 0.135 66.442);
84
+ --highlight-foreground: oklch(0.985 0 0);
85
+ --destructive: oklch(0.7 0.17 25);
86
+ --destructive-foreground: oklch(0.2 0.03 25);
87
+ --destructive-tint: oklch(25.8% 0.092 26.042);
88
+ --destructive-tint-foreground: oklch(70.4% 0.191 22.216);
60
89
  --border: oklch(0.269 0 0);
61
90
  --input: oklch(0.269 0 0);
62
91
  --ring: oklch(0.439 0 0);
@@ -65,7 +94,7 @@
65
94
  --chart-3: oklch(0.769 0.188 70.08);
66
95
  --chart-4: oklch(0.627 0.265 303.9);
67
96
  --chart-5: oklch(0.645 0.246 16.439);
68
- --sidebar: oklch(0.205 0 0);
97
+ --sidebar: var(--muted);
69
98
  --sidebar-foreground: oklch(0.985 0 0);
70
99
  --sidebar-primary: oklch(0.488 0.243 264.376);
71
100
  --sidebar-primary-foreground: oklch(0.985 0 0);
@@ -86,12 +115,26 @@
86
115
  --color-primary-foreground: var(--primary-foreground);
87
116
  --color-secondary: var(--secondary);
88
117
  --color-secondary-foreground: var(--secondary-foreground);
118
+ --color-banner: var(--banner);
119
+ --color-banner-foreground: var(--banner-foreground);
89
120
  --color-muted: var(--muted);
90
121
  --color-muted-foreground: var(--muted-foreground);
91
122
  --color-accent: var(--accent);
92
123
  --color-accent-foreground: var(--accent-foreground);
124
+ --color-positive: var(--positive);
125
+ --color-positive-foreground: var(--positive-foreground);
126
+ --color-positive-tint: var(--positive-tint);
127
+ --color-positive-tint-foreground: var(--positive-tint-foreground);
128
+ --color-warning: var(--warning);
129
+ --color-warning-foreground: var(--warning-foreground);
130
+ --color-warning-tint: var(--warning-tint);
131
+ --color-warning-tint-foreground: var(--warning-tint-foreground);
132
+ --color-highlight: var(--highlight);
133
+ --color-highlight-foreground: var(--highlight-foreground);
93
134
  --color-destructive: var(--destructive);
94
135
  --color-destructive-foreground: var(--destructive-foreground);
136
+ --color-destructive-tint: var(--destructive-tint);
137
+ --color-destructive-tint-foreground: var(--destructive-tint-foreground);
95
138
  --color-border: var(--border);
96
139
  --color-input: var(--input);
97
140
  --color-ring: var(--ring);
@@ -122,6 +165,11 @@
122
165
  @apply bg-background text-foreground;
123
166
  }
124
167
 
168
+ ::highlight(search-match) {
169
+ background-color: var(--highlight);
170
+ color: var(--highlight-foreground);
171
+ }
172
+
125
173
  html {
126
174
  scroll-behavior: smooth;
127
175
  scrollbar-color: #ddd transparent;
@@ -2,6 +2,12 @@
2
2
  @reference "./general.css";
3
3
 
4
4
  @layer components {
5
+ /* A bare URL or long inline code is one unbreakable word that widens the whole
6
+ page on a phone, so it scrolls sideways. */
7
+ .prose {
8
+ overflow-wrap: break-word;
9
+ }
10
+
5
11
  .prose :is(h1, h2, h3, h4, h5, h6) {
6
12
  @apply scroll-mt-28 md:scroll-mt-20;
7
13
  }
@@ -43,29 +49,29 @@
43
49
  }
44
50
 
45
51
  .prose pre code .line[data-diff="add"] {
46
- @apply bg-green-500/15;
52
+ @apply bg-positive/15;
47
53
  }
48
54
 
49
55
  .prose pre code .line[data-diff="remove"] {
50
- @apply bg-red-500/15;
56
+ @apply bg-destructive/15;
51
57
  }
52
58
 
53
59
  .prose pre code .line[data-diff="add"]::before {
54
60
  content: "+";
55
- @apply text-green-600 absolute left-1;
61
+ @apply text-positive-tint-foreground absolute left-1;
56
62
  }
57
63
 
58
64
  .prose pre code .line[data-diff="remove"]::before {
59
65
  content: "-";
60
- @apply text-red-600 absolute left-1;
66
+ @apply text-destructive-tint-foreground absolute left-1;
61
67
  }
62
68
 
63
69
  .prose pre code .line[data-line-status="error"] {
64
- @apply bg-red-500/15;
70
+ @apply bg-destructive/15;
65
71
  }
66
72
 
67
73
  .prose pre code .line[data-line-status="warning"] {
68
- @apply bg-yellow-500/15;
74
+ @apply bg-warning/15;
69
75
  }
70
76
 
71
77
  .prose pre[data-has-focus] code .line:not([data-focus]) {
@@ -100,7 +106,7 @@
100
106
  }
101
107
 
102
108
  .prose pre code .twoslash-error-line {
103
- @apply bg-red-500/10;
109
+ @apply bg-destructive/10;
104
110
  }
105
111
 
106
112
  .prose pre code .twoslash-tag-line {
@@ -0,0 +1,14 @@
1
+ /* Elements name these, never a raw `rounded-md`: controls are pills, rows and cards 1rem,
2
+ panels 1.5rem. Pills ignore `--radius`; only the `sm`…`xl` scale follows it. */
3
+ @theme inline {
4
+ --radius-control: 9999px;
5
+ --radius-control-sm: 9999px;
6
+ --radius-control-xs: 9999px;
7
+ --radius-control-inset: 9999px;
8
+ --radius-textarea: 1rem;
9
+ --radius-row: 1rem;
10
+ --radius-card: 1rem;
11
+ --radius-panel: 1.5rem;
12
+ --radius-menu: 1rem;
13
+ --radius-menu-item: calc(1rem - 4px);
14
+ }
@@ -6,6 +6,7 @@ import react from "@vitejs/plugin-react"
6
6
  import { defineConfig } from "vite"
7
7
  import svgr from "vite-plugin-svgr"
8
8
  import { loadConfig } from "./actions/config/load.ts"
9
+ import { agents } from "./plugins/vite-agents.ts"
9
10
  import { livemark } from "./plugins/vite-livemark.ts"
10
11
  import { robots } from "./plugins/vite-robots.ts"
11
12
 
@@ -28,6 +29,7 @@ export default defineConfig({
28
29
  plugins: [
29
30
  livemark({ config }),
30
31
  robots({ config }),
32
+ agents({ config }),
31
33
  devtools(),
32
34
  tailwind(),
33
35
  contentCollections({ configPath: "content-collections.ts" }),
@@ -1,47 +0,0 @@
1
- ---
2
- name: change-review
3
- description: Review a pull request for correctness, security and repo conventions, posting findings as inline comments. Invoked by the review workflow and by a person; never fires on its own.
4
- disable-model-invocation: true
5
- ---
6
-
7
- # Review a pull request
8
-
9
- Read the diff, judge it, post findings as inline comments. Be useful, not thorough-looking:
10
- a review that flags twenty things teaches nothing, and the twenty-first — the real one — is lost
11
- in it.
12
-
13
- ## What to look for
14
-
15
- **Correctness**
16
-
17
- - Logic that is wrong for an input the change makes reachable, not merely unusual.
18
- - Error handling that swallows a failure or reports success on a partial write.
19
- - Concurrency: two requests, two sessions, a retry, a replay.
20
- - Performance where the change makes it structurally worse (a query in a loop, an unbounded
21
- scan), not where it is merely not optimal.
22
-
23
- **Security — OWASP-shaped, but reported only when reachable**
24
-
25
- - Injection (SQL and otherwise), XSS, SSRF, XXE, unsafe deserialisation.
26
- - Broken authentication or access control: a route that skips the permission it needs, a scope
27
- resolved from user input, an id trusted because it came from the client.
28
- - Sensitive data exposure: secrets in code or logs, PII widening, a credential recoverable from
29
- the database.
30
- - Insecure cryptography, race conditions and TOCTOU, missing logging on a security-relevant
31
- action.
32
-
33
- **This repo's own conventions** — these are where a generic reviewer is blind, and they matter
34
- more than the generic checklist. Read `AGENTS.md` and the sibling skills before judging: a
35
- change that violates a documented invariant is a finding even when the code is otherwise
36
- correct.
37
-
38
- ## How to report
39
-
40
- Rate each finding **CRITICAL / HIGH / MEDIUM / LOW**, and say what input or sequence produces
41
- the failure. A finding that cannot name the case that breaks is a hunch: either verify it or
42
- leave it out.
43
-
44
- Post specific issues as inline comments on the lines they concern. Keep the summary short.
45
- Silence on the parts that are fine is not laziness — it is what makes the flagged parts legible.
46
-
47
- If the change is good, say so briefly and stop. Do not manufacture findings to justify the run.
@@ -1,118 +0,0 @@
1
- ---
2
- name: livemark-customization
3
- description: Use when overriding Livemark's built-in UI or adding custom routes — drop same-named files under .livemark/{components,elements,styles} to shadow defaults, author .livemark/routes/*.tsx for new pages, or copy defaults with the `livemark escape` command.
4
- ---
5
-
6
- # Livemark Customization
7
-
8
- Guidance for customizing the UI layer of a Livemark project beyond what `livemark.config.ts` exposes.
9
-
10
- ## When to use this skill
11
-
12
- Invoke when the user asks to:
13
-
14
- - Change a built-in component's layout or markup (Footer, Sidebar, Banner, …).
15
- - Restyle a shared primitive (buttons, inputs, cards, sheet, …).
16
- - Rebrand via CSS tokens (colors, radii, typography).
17
- - Add a brand-new page that isn't a Markdown article (landing hero, pricing page, about page).
18
- - Replace Livemark's default landing page with a custom React component.
19
- - Serve a custom `favicon.svg`, `robots.txt`, `og-image.png`, or other static asset.
20
-
21
- ## Three overlapping mechanisms
22
-
23
- | Goal | Mechanism |
24
- | --------------------------------- | ----------------------------------------------------- |
25
- | Replace a default component/style | Drop a file at `.livemark/components/<Name>.tsx` etc. |
26
- | Add a new page at an exact URL | Create `.livemark/routes/<path>.tsx` |
27
- | Serve a static asset at `/<path>` | Put the file in `.livemark/public/<path>` |
28
-
29
- None require config changes. The Vite plugin (`website/plugins/vite-livemark.ts`) watches `.livemark/**` and hot-reloads.
30
-
31
- ## Discovering what's overridable
32
-
33
- Run the `escape` command. No arg lists every overridable file:
34
-
35
- ```bash
36
- livemark escape
37
- ```
38
-
39
- Output is a flat `<subdir>/<file>` list across `components/`, `elements/`, and `styles/`. With an argument, the command copies the default into `.livemark/`:
40
-
41
- ```bash
42
- livemark escape components/Footer.tsx # → .livemark/components/Footer.tsx
43
- livemark escape elements/button.tsx # → .livemark/elements/button.tsx
44
- livemark escape styles/general.css # → .livemark/styles/general.css
45
- ```
46
-
47
- The command refuses to overwrite an existing override. Delete the override first if you want a fresh start.
48
-
49
- ## Typical workflow: override a component
50
-
51
- 1. `livemark escape components/Footer.tsx` — copy the default.
52
- 2. Edit `.livemark/components/Footer.tsx`. All the site's Footer renders shift to the new file on save.
53
- 3. Inside the override, import other Livemark modules from the `livemark/<subdir>/*` subpath exports:
54
- ```tsx
55
- import { cn } from "livemark/helpers/style"
56
- import { Button } from "livemark/elements/button"
57
- ```
58
-
59
- ## Typical workflow: rebrand
60
-
61
- 1. `livemark escape styles/general.css`.
62
- 2. Edit the `:root` and `.dark` blocks in `.livemark/styles/general.css`:
63
- - `--primary` — brand accent (Tailwind-flavoured oklch values work).
64
- - `--radius` — corner roundness base.
65
- - Sidebar / chart tokens if you want deeper tweaks.
66
- 3. Save — the dev server applies immediately.
67
-
68
- Whole-site contrast is audited: light mode targets blue-600, dark mode targets blue-500. Keep new token values AA-compliant on both backgrounds (≥4.5:1 for text).
69
-
70
- ## Typical workflow: add a page
71
-
72
- Custom routes use [TanStack Router](https://tanstack.com/router). Minimal example:
73
-
74
- ```tsx title=".livemark/routes/about.tsx"
75
- import { createFileRoute } from "@tanstack/react-router"
76
-
77
- export const Route = createFileRoute("/about")({
78
- component: () => (
79
- <main className="mx-auto max-w-3xl px-6 py-16 prose">
80
- <h1>About</h1>
81
- <p>Hello.</p>
82
- </main>
83
- ),
84
- })
85
- ```
86
-
87
- Filename maps to URL path: `.livemark/routes/pricing.tsx` → `/pricing/`. Nested paths work via nested folders.
88
-
89
- An `index.tsx` in `.livemark/routes/` **replaces** Livemark's default landing at `/`.
90
-
91
- Custom routes win over the Markdown catch-all at exact URLs. Don't create a route that collides with an article URL unless you intend to hide the article.
92
-
93
- ## Rules of thumb
94
-
95
- 1. **Don't fork the repo** for routine customization. Use `.livemark/` first — it reliably survives Livemark upgrades.
96
- 2. **Same filename, same path under `.livemark/`.** The override plugin is case-sensitive and mirrors the subdirectory structure exactly.
97
- 3. **Override files are full replacements**, not diffs. Copy the default first (via `escape`), then edit.
98
- 4. **Import Livemark internals via `livemark/*`**, not via relative paths — the plugin routes those through the override resolver, so chained overrides (e.g., your Layout using your Sidebar) compose correctly.
99
- 5. **Static files belong in `.livemark/public/`**, which Vite exposes at the site root.
100
-
101
- ## What's NOT overridable
102
-
103
- - `actions/`, `commands/`, `program.ts` — server/CLI code. Fork upstream if you need to change these.
104
- - `livemark.config.ts` schema — fixed.
105
- - Content-collections transform pipeline. Customize markdown via remark/rehype plugins in a fork (or PR upstream).
106
-
107
- ## Verification
108
-
109
- - `pnpm type` — confirms overrides typecheck.
110
- - `pnpm docs:build` — smoke-test the override lands in the bundle.
111
- - Browser: load an article page with the dev server; custom Footer/Sidebar/etc. should render without a full reload.
112
-
113
- ## References
114
-
115
- - Narrative docs: `docs/customization/file-overrides.md`, `docs/customization/custom-routes.md`.
116
- - Plugin implementation: `website/plugins/vite-livemark.ts`.
117
- - Escape command: `commands/escape.ts`.
118
- - Subpath exports: `package.json` `exports` block.