@plebeiantech/lat.md 0.12.3-fork.9 → 0.13.4-fork.2

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 (340) hide show
  1. package/README.md +27 -3
  2. package/dist/src/cli/agent-invocation.d.ts +6 -0
  3. package/dist/src/cli/agent-invocation.js +23 -0
  4. package/dist/src/cli/checklist-menu.d.ts +2 -1
  5. package/dist/src/cli/checklist-menu.js +3 -2
  6. package/dist/src/cli/fork-instructions.d.ts +1 -0
  7. package/dist/src/cli/fork-instructions.js +8 -32
  8. package/dist/src/cli/fork-scaffold.js +2 -2
  9. package/dist/src/cli/graph.d.ts +1 -1
  10. package/dist/src/cli/hook.d.ts +26 -0
  11. package/dist/src/cli/hook.js +115 -64
  12. package/dist/src/cli/index.js +178 -70
  13. package/dist/src/cli/init-preferences.d.ts +4 -0
  14. package/dist/src/cli/init-preferences.js +36 -0
  15. package/dist/src/cli/init.d.ts +2 -1
  16. package/dist/src/cli/init.js +100 -60
  17. package/dist/src/cli/reindex.d.ts +1 -1
  18. package/dist/src/cli/reindex.js +7 -10
  19. package/dist/src/cli/search.d.ts +14 -4
  20. package/dist/src/cli/search.js +115 -101
  21. package/dist/src/cli/ui-build-server.d.ts +12 -0
  22. package/dist/src/cli/ui-build-server.js +26 -0
  23. package/dist/src/cli/ui-build.d.ts +1 -1
  24. package/dist/src/cli/ui-build.js +1 -1
  25. package/dist/src/cli/ui.d.ts +1 -1
  26. package/dist/src/cli/ui.js +1 -1
  27. package/dist/src/cli/wiki.d.ts +12 -0
  28. package/dist/src/cli/wiki.js +85 -0
  29. package/dist/src/fork/antigravity-hook.d.ts +47 -0
  30. package/dist/src/fork/antigravity-hook.js +424 -0
  31. package/dist/src/fork/antigravity-init.d.ts +17 -0
  32. package/dist/src/fork/antigravity-init.js +124 -0
  33. package/dist/src/fork/upstream-drift.js +1 -1
  34. package/dist/src/fork/upstream-guard.d.ts +1 -1
  35. package/dist/src/fork/upstream-guard.js +8 -7
  36. package/dist/src/graph-export.js +7 -7
  37. package/dist/src/knowledge/index.js +2 -2
  38. package/dist/src/mcp/server.js +34 -18
  39. package/dist/src/search/cache.d.ts +3 -0
  40. package/dist/src/search/cache.js +104 -0
  41. package/dist/src/search/chunks.d.ts +23 -0
  42. package/dist/src/search/chunks.js +200 -0
  43. package/dist/src/search/db.d.ts +28 -16
  44. package/dist/src/search/db.js +100 -40
  45. package/dist/src/search/embedder.d.ts +2 -1
  46. package/dist/src/search/embedder.js +7 -6
  47. package/dist/src/search/index.d.ts +6 -2
  48. package/dist/src/search/index.js +176 -70
  49. package/dist/src/search/lexical.d.ts +6 -0
  50. package/dist/src/search/lexical.js +36 -0
  51. package/dist/src/search/lock.d.ts +5 -0
  52. package/dist/src/search/lock.js +45 -0
  53. package/dist/src/search/query.d.ts +26 -0
  54. package/dist/src/search/query.js +103 -0
  55. package/dist/src/search/search.d.ts +16 -7
  56. package/dist/src/search/search.js +165 -21
  57. package/dist/src/search/types.d.ts +15 -0
  58. package/dist/src/view/client/assets/GraphView-D_xnk0bP.js +456 -0
  59. package/dist/src/view/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  60. package/dist/src/view/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  61. package/dist/src/view/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  62. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  63. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  64. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  65. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  66. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  67. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  68. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  69. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  70. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  71. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  72. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  73. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  74. package/dist/src/view/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  75. package/dist/src/view/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  76. package/dist/src/view/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  77. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  78. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  79. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  80. package/dist/src/view/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  81. package/dist/src/view/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  82. package/dist/src/view/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  83. package/dist/src/view/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  84. package/dist/src/view/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  85. package/dist/src/view/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  86. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  87. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  88. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  89. package/dist/src/view/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  90. package/dist/src/view/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  91. package/dist/src/view/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  92. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  93. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  94. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  95. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  96. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  97. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  98. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  99. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  100. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  101. package/dist/src/view/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  102. package/dist/src/view/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  103. package/dist/src/view/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  104. package/dist/src/view/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  105. package/dist/src/view/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  106. package/dist/src/view/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  107. package/dist/src/view/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  108. package/dist/src/view/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  109. package/dist/src/view/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  110. package/dist/src/view/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  111. package/dist/src/view/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  112. package/dist/src/view/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  113. package/dist/src/view/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  114. package/dist/src/view/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  115. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  116. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  117. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  118. package/dist/src/view/client/assets/MarkdownEditor-bjqt_FoF.js +28 -0
  119. package/dist/src/view/client/assets/OrbitControls-DwcpQNja.js +1 -0
  120. package/dist/src/view/client/assets/STLLoader-CLWTKt5i.js +1 -0
  121. package/dist/src/view/client/assets/_commonjsHelpers-CqkleIqs.js +1 -0
  122. package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-kWGvtRnL.js +1 -0
  123. package/dist/src/view/client/assets/arc-BPAFd7cP.js +1 -0
  124. package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-CsY39oIR.js +36 -0
  125. package/dist/src/view/client/assets/blockDiagram-I7D4REHJ-DHGBG7BJ.js +129 -0
  126. package/dist/src/view/client/assets/c4Diagram-7LVT6UL2-vywK4eb7.js +38 -0
  127. package/dist/src/view/client/assets/channel-CX71L_qV.js +1 -0
  128. package/dist/src/view/client/assets/chunk-2Q5K7J3B-Do3Hz_ci.js +1 -0
  129. package/dist/src/view/client/assets/chunk-5VM5RSS4-B5R1lSeY.js +15 -0
  130. package/dist/src/view/client/assets/chunk-F27PBJKO-Dm55FM_W.js +1 -0
  131. package/dist/src/view/client/assets/chunk-IMKFNOWR-ChptrvvM.js +231 -0
  132. package/dist/src/view/client/assets/chunk-JWPE2WC7-BRQBjrKS.js +1 -0
  133. package/dist/src/view/client/assets/chunk-POPQ4Y6H-CainVZIL.js +1 -0
  134. package/dist/src/view/client/assets/chunk-SVP7TREG-DsKsNGmM.js +88 -0
  135. package/dist/src/view/client/assets/chunk-TICWLB2K-BctkMcJc.js +206 -0
  136. package/dist/src/view/client/assets/chunk-XXDRQBXY-BN7SgOUT.js +1 -0
  137. package/dist/src/view/client/assets/classDiagram-ZZMXUADV-B1VyU6zO.js +1 -0
  138. package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-B1VyU6zO.js +1 -0
  139. package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-BszzwrMe.js +1 -0
  140. package/dist/src/view/client/assets/cynefin-OW5HDTMX-CdRyAkPs.js +166 -0
  141. package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-BLvKPZ1u.js +62 -0
  142. package/dist/src/view/client/assets/cytoscape.esm-DzSz-X2X.js +321 -0
  143. package/dist/src/view/client/assets/dagre-GXQ25YYZ-V68w_l65.js +4 -0
  144. package/dist/src/view/client/assets/defaultLocale-DX6XiGOO.js +1 -0
  145. package/dist/src/view/client/assets/diagram-S7CK7UJ4-C2i4eEMg.js +30 -0
  146. package/dist/src/view/client/assets/diagram-UQ7AKVKN-BiwWh5jC.js +41 -0
  147. package/dist/src/view/client/assets/diagram-VSXAHHWV-hkKR_vyS.js +3 -0
  148. package/dist/src/view/client/assets/diagram-VX7I27RA-DzRCSMAc.js +24 -0
  149. package/dist/src/view/client/assets/diagram-Z3DM3KII-fhSFPxyK.js +24 -0
  150. package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-CCEUDKSA.js +1 -0
  151. package/dist/src/view/client/assets/erDiagram-RLTQ6QDP-FJ2IMyTi.js +99 -0
  152. package/dist/src/view/client/assets/flowDiagram-HODETNUW-BvasdLeK.js +168 -0
  153. package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-CiwkBZvY.js +292 -0
  154. package/dist/src/view/client/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  155. package/dist/src/view/client/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  156. package/dist/src/view/client/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  157. package/dist/src/view/client/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  158. package/dist/src/view/client/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
  159. package/dist/src/view/client/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
  160. package/dist/src/view/client/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
  161. package/dist/src/view/client/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
  162. package/dist/src/view/client/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
  163. package/dist/src/view/client/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
  164. package/dist/src/view/client/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  165. package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-DYlP2_js.js +106 -0
  166. package/dist/src/view/client/assets/index-BnENo9bV.js +1 -0
  167. package/dist/src/view/client/assets/index-CQ7EOox7.css +1 -0
  168. package/dist/src/view/client/assets/index-CynNDkxt.js +13 -0
  169. package/dist/src/view/client/assets/infoDiagram-27XIBGKW-DRPB2c48.js +2 -0
  170. package/dist/src/view/client/assets/init-Gi6I4Gst.js +1 -0
  171. package/dist/src/view/client/assets/ishikawaDiagram-5VMMS53U-8VV429Cv.js +70 -0
  172. package/dist/src/view/client/assets/journeyDiagram-3NMN7TZE-Dzmwnf83.js +139 -0
  173. package/dist/src/view/client/assets/kanban-definition-UXKFOSKX-pYyZZ1i-.js +89 -0
  174. package/dist/src/view/client/assets/katex-HP8lGamR.js +257 -0
  175. package/dist/src/view/client/assets/layout-GF9k6yGo.js +1 -0
  176. package/dist/src/view/client/assets/linear-Yt2sSOYV.js +1 -0
  177. package/dist/src/view/client/assets/logo-RR_KBOAT.svg +149 -0
  178. package/dist/src/view/client/assets/maplibre-gl-CDX6Zuow.js +800 -0
  179. package/dist/src/view/client/assets/mermaid.core-ChWYCHN0.js +310 -0
  180. package/dist/src/view/client/assets/mindmap-definition-YA3MSWOX-Cc4fQvf1.js +96 -0
  181. package/dist/src/view/client/assets/ordinal-Cboi1Yqb.js +1 -0
  182. package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-C0SsB8bZ.js +1 -0
  183. package/dist/src/view/client/assets/pieDiagram-E7YTZNPT-DIJpqERZ.js +39 -0
  184. package/dist/src/view/client/assets/quadrantDiagram-AXDQQJYC--d-gl6j-.js +7 -0
  185. package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-BQxwTt7z.js +1 -0
  186. package/dist/src/view/client/assets/requirementDiagram-BXWQKSXE-B_oTeD2A.js +84 -0
  187. package/dist/src/view/client/assets/sankeyDiagram-P5KCCOFB-DLukmE8X.js +40 -0
  188. package/dist/src/view/client/assets/sequenceDiagram-WJ2MYXX4-BNjVB2sc.js +162 -0
  189. package/dist/src/view/client/assets/sizeCapture-INFHLROL-BZecQTOw.js +1 -0
  190. package/dist/src/view/client/assets/stateDiagram-D77RDMKH-Bu1urvXC.js +1 -0
  191. package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-5pc_697G.js +1 -0
  192. package/dist/src/view/client/assets/swimlanes-42K2YHIH-bLAlcepB.js +1 -0
  193. package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-BbOpZjpp.js +8 -0
  194. package/dist/src/view/client/assets/three.module-PDSP0dbZ.js +4108 -0
  195. package/dist/src/view/client/assets/timeline-definition-24CTP7MA-tbwCNvcA.js +120 -0
  196. package/dist/src/view/client/assets/vennDiagram-4TSXK5OY-D8U8Fk0N.js +34 -0
  197. package/dist/src/view/client/assets/wardleyDiagram-VM6X3IG4-LHBVIeNb.js +78 -0
  198. package/dist/src/view/client/assets/xychartDiagram-S5SC5T6Z-CN4tfaFV.js +7 -0
  199. package/dist/src/view/client/index.html +2 -2
  200. package/dist/src/view/client-shell.d.ts +2 -0
  201. package/dist/src/view/client-shell.js +5 -0
  202. package/dist/src/view/diagnostics.d.ts +3 -2
  203. package/dist/src/view/diagnostics.js +49 -58
  204. package/dist/src/view/document-edit.d.ts +8 -0
  205. package/dist/src/view/document-edit.js +25 -0
  206. package/dist/src/view/document-route.d.ts +14 -0
  207. package/dist/src/view/document-route.js +137 -0
  208. package/dist/src/view/document-tree.d.ts +18 -0
  209. package/dist/src/view/document-tree.js +139 -0
  210. package/dist/src/view/external-document-tree.d.ts +3 -0
  211. package/dist/src/view/external-document-tree.js +674 -0
  212. package/dist/src/view/git-diff.js +202 -2
  213. package/dist/src/view/git.js +1 -1
  214. package/dist/src/view/graph.d.ts +4 -3
  215. package/dist/src/view/graph.js +100 -9
  216. package/dist/src/view/highlight.d.ts +10 -2
  217. package/dist/src/view/highlight.js +50648 -3166
  218. package/dist/src/view/markdown.d.ts +3 -2
  219. package/dist/src/view/markdown.js +256 -54
  220. package/dist/src/view/preindexed-search.d.ts +15 -0
  221. package/dist/src/view/preindexed-search.js +25 -0
  222. package/dist/src/view/protocol.d.ts +53 -7
  223. package/dist/src/view/publication.d.ts +2 -0
  224. package/dist/src/view/publication.js +78 -0
  225. package/dist/src/view/references.d.ts +11 -26
  226. package/dist/src/view/references.js +121 -112
  227. package/dist/src/view/repository.d.ts +14 -4
  228. package/dist/src/view/repository.js +260 -19
  229. package/dist/src/view/request-security.d.ts +5 -0
  230. package/dist/src/view/request-security.js +46 -0
  231. package/dist/src/view/search-result.d.ts +4 -0
  232. package/dist/src/view/search-result.js +25 -0
  233. package/dist/src/view/search.d.ts +7 -2
  234. package/dist/src/view/search.js +23 -34
  235. package/dist/src/view/server-build.d.ts +21 -0
  236. package/dist/src/view/server-build.js +145 -0
  237. package/dist/src/view/server-deployment.d.ts +31 -0
  238. package/dist/src/view/server-deployment.js +123 -0
  239. package/dist/src/view/server-index-worker.d.ts +6 -0
  240. package/dist/src/view/server-index-worker.js +14 -0
  241. package/dist/src/view/server.d.ts +11 -2
  242. package/dist/src/view/server.js +245 -73
  243. package/dist/src/view/source-target.d.ts +2 -0
  244. package/dist/src/view/source-target.js +49 -8
  245. package/dist/src/view/static-build.d.ts +18 -2
  246. package/dist/src/view/static-build.js +449 -110
  247. package/dist/src/view/static-protocol.d.ts +26 -2
  248. package/dist/src/view/static-protocol.js +5 -0
  249. package/dist/src/view/store.d.ts +20 -3
  250. package/dist/src/view/store.js +304 -48
  251. package/dist/src/view/table-of-contents.d.ts +2 -2
  252. package/dist/src/view/table-of-contents.js +2 -22
  253. package/dist/src/view/vercel-build.d.ts +24 -0
  254. package/dist/src/view/vercel-build.js +152 -0
  255. package/dist/src/view/vercel-server-build.d.ts +10 -0
  256. package/dist/src/view/vercel-server-build.js +61 -0
  257. package/dist/src/wiki/catalog.d.ts +21 -0
  258. package/dist/src/wiki/catalog.js +256 -0
  259. package/dist/src/wiki/publish.d.ts +27 -0
  260. package/dist/src/wiki/publish.js +265 -0
  261. package/dist/src/wiki/render.d.ts +20 -0
  262. package/dist/src/wiki/render.js +163 -0
  263. package/dist/src/wiki/transform.d.ts +7 -0
  264. package/dist/src/wiki/transform.js +264 -0
  265. package/dist/vendor/lat.md-server/cli.d.ts +2 -0
  266. package/dist/vendor/lat.md-server/cli.js +12 -0
  267. package/dist/vendor/lat.md-server/index.d.ts +38 -0
  268. package/dist/vendor/lat.md-server/index.js +128 -0
  269. package/package.json +68 -22
  270. package/plugins/lat-md/README.md +61 -0
  271. package/plugins/lat-md/hooks.json +38 -0
  272. package/plugins/lat-md/plugin.json +9 -0
  273. package/plugins/lat-md/rules/AGENTS.md +344 -0
  274. package/plugins/lat-md/skills/lat-md/SKILL.md +210 -0
  275. package/plugins/lat-md/skills/lat-md-conventions/SKILL.md +226 -0
  276. package/templates/AGENTS.md +26 -7
  277. package/templates/cursor-rules.md +23 -7
  278. package/templates/fork/conventions.md +133 -11
  279. package/templates/opencode-plugin.ts +9 -9
  280. package/templates/pi-extension.ts +11 -11
  281. package/templates/skill/SKILL.md +35 -3
  282. package/dist/src/cli/check-coverage.d.ts +0 -2
  283. package/dist/src/cli/check-coverage.js +0 -71
  284. package/dist/src/cli/check-frontmatter.d.ts +0 -12
  285. package/dist/src/cli/check-frontmatter.js +0 -44
  286. package/dist/src/cli/check-mode.d.ts +0 -21
  287. package/dist/src/cli/check-mode.js +0 -364
  288. package/dist/src/cli/check-status.d.ts +0 -74
  289. package/dist/src/cli/check-status.js +0 -217
  290. package/dist/src/cli/check.d.ts +0 -45
  291. package/dist/src/cli/check.js +0 -781
  292. package/dist/src/cli/context.d.ts +0 -11
  293. package/dist/src/cli/context.js +0 -58
  294. package/dist/src/cli/expand.d.ts +0 -8
  295. package/dist/src/cli/expand.js +0 -94
  296. package/dist/src/cli/gen-index.d.ts +0 -45
  297. package/dist/src/cli/gen-index.js +0 -235
  298. package/dist/src/cli/link-scheme.d.ts +0 -54
  299. package/dist/src/cli/link-scheme.js +0 -101
  300. package/dist/src/cli/locate.d.ts +0 -2
  301. package/dist/src/cli/locate.js +0 -17
  302. package/dist/src/cli/refs.d.ts +0 -22
  303. package/dist/src/cli/refs.js +0 -229
  304. package/dist/src/cli/section.d.ts +0 -43
  305. package/dist/src/cli/section.js +0 -252
  306. package/dist/src/cli/select-menu.d.ts +0 -13
  307. package/dist/src/cli/select-menu.js +0 -100
  308. package/dist/src/code-refs.d.ts +0 -17
  309. package/dist/src/code-refs.js +0 -298
  310. package/dist/src/config.d.ts +0 -29
  311. package/dist/src/config.js +0 -83
  312. package/dist/src/context.d.ts +0 -23
  313. package/dist/src/context.js +0 -11
  314. package/dist/src/extensions/wiki-link/from-markdown.d.ts +0 -5
  315. package/dist/src/extensions/wiki-link/from-markdown.js +0 -34
  316. package/dist/src/extensions/wiki-link/index.d.ts +0 -4
  317. package/dist/src/extensions/wiki-link/index.js +0 -3
  318. package/dist/src/extensions/wiki-link/syntax.d.ts +0 -14
  319. package/dist/src/extensions/wiki-link/syntax.js +0 -121
  320. package/dist/src/extensions/wiki-link/to-markdown.d.ts +0 -5
  321. package/dist/src/extensions/wiki-link/to-markdown.js +0 -28
  322. package/dist/src/extensions/wiki-link/types.d.ts +0 -34
  323. package/dist/src/format.d.ts +0 -8
  324. package/dist/src/format.js +0 -43
  325. package/dist/src/init-version.d.ts +0 -10
  326. package/dist/src/init-version.js +0 -49
  327. package/dist/src/lattice.d.ts +0 -109
  328. package/dist/src/lattice.js +0 -817
  329. package/dist/src/parser.d.ts +0 -3
  330. package/dist/src/parser.js +0 -18
  331. package/dist/src/source-parser.d.ts +0 -27
  332. package/dist/src/source-parser.js +0 -916
  333. package/dist/src/untrusted.d.ts +0 -18
  334. package/dist/src/untrusted.js +0 -93
  335. package/dist/src/view/client/assets/index-C3iaZyYT.css +0 -1
  336. package/dist/src/view/client/assets/index-KWi67IMz.js +0 -334
  337. package/dist/src/view/client/assets/logo-CNF8zs47.svg +0 -182
  338. package/dist/src/walk.d.ts +0 -18
  339. package/dist/src/walk.js +0 -27
  340. /package/dist/src/{extensions/wiki-link → search}/types.js +0 -0
@@ -0,0 +1,5 @@
1
+ /** Point Vite's entry assets at the route-independent deployment prefix. */
2
+ export function rewriteClientAssetUrls(html, basePath) {
3
+ const normalizedBase = basePath.endsWith('/') ? basePath : `${basePath}/`;
4
+ return html.replace(/(["'])(?:\.\/|\/)assets\//g, (_match, quote) => `${quote}${normalizedBase}assets/`);
5
+ }
@@ -1,5 +1,6 @@
1
- import { type Section } from '../lattice.js';
1
+ import { type Section } from '@plebeiantech/lat.md-core/lattice-model';
2
+ import type { ExternalResolver } from '@plebeiantech/lat.md-core/external-sources';
2
3
  import type { ViewDocumentError } from './protocol.js';
3
4
  import type { ViewCodeReferenceFile, ViewParsedMarkdownFile } from './references.js';
4
5
  /** Build per-document validation errors entirely from the current view snapshot. */
5
- export declare function buildViewDiagnostics(markdownFiles: Iterable<ViewParsedMarkdownFile>, codeFiles: Iterable<ViewCodeReferenceFile>, allSections: Section[], projectRoot: string): Promise<ReadonlyMap<string, readonly ViewDocumentError[]>>;
6
+ export declare function buildViewDiagnostics(markdownFiles: Iterable<ViewParsedMarkdownFile>, codeFiles: Iterable<ViewCodeReferenceFile>, allSections: Section[], projectRoot: string, external?: ExternalResolver, latDir?: string): Promise<ReadonlyMap<string, readonly ViewDocumentError[]>>;
@@ -1,41 +1,10 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { extname, relative, resolve, dirname } from 'node:path';
3
- import { ambiguousRefMessage, sourceRefError } from '../cli/check.js';
4
- import { buildFileIndex, buildSectionSlugIndex, flattenSections, parseFrontmatter, resolveRef, } from '../lattice.js';
5
- import { clearSymbolCache } from '../source-parser.js';
6
- import { toPosix } from '../walk.js';
7
- const MAX_BODY_LENGTH = 250;
8
- function decodeLinkPart(value) {
9
- try {
10
- return decodeURIComponent(value);
11
- }
12
- catch {
13
- return value;
14
- }
15
- }
16
- function localLinkTarget(url) {
17
- const value = url.trim();
18
- if (value.startsWith('/'))
19
- return null;
20
- const windowsDrivePath = /^[a-zA-Z]:\\/.test(value);
21
- if (!windowsDrivePath && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)) {
22
- return null;
23
- }
24
- const queryAt = value.indexOf('?');
25
- const fragmentAt = value.indexOf('#');
26
- const pathEnd = Math.min(queryAt === -1 ? value.length : queryAt, fragmentAt === -1 ? value.length : fragmentAt);
27
- const rawPath = value.slice(0, pathEnd);
28
- const path = rawPath === '' ? null : decodeLinkPart(rawPath);
29
- const fragment = fragmentAt === -1 ? null : decodeLinkPart(value.slice(fragmentAt + 1));
30
- if (rawPath === '' && fragment === null)
31
- return null;
32
- if (path?.includes('\\'))
33
- return { kind: 'invalid-backslash' };
34
- return { kind: 'target', path, fragment };
35
- }
36
- function bodyTextLength(body) {
37
- return body.replace(/\[\[[^\]]*\]\]/g, '').length;
38
- }
3
+ import { ambiguousRefMessage, repositoryRefError, } from '@plebeiantech/lat.md-core/cli/check';
4
+ import { buildFileIndex, buildSectionSlugIndex, flattenSections, resolveRef, } from '@plebeiantech/lat.md-core/lattice-model';
5
+ import { SourceParserRuntime } from '@plebeiantech/lat.md-core/source-parser';
6
+ import { toPosix } from '@plebeiantech/lat.md-core/path';
7
+ import { parseLocalMarkdownTarget } from '@plebeiantech/lat.md-core/markdown-validation';
39
8
  function error(line, target, message, options = {}) {
40
9
  return {
41
10
  anchor: options.anchor || `user-content-markdown-error-${line}`,
@@ -64,12 +33,11 @@ function addError(errors, path, diagnostic) {
64
33
  errors.set(path, fileErrors);
65
34
  }
66
35
  async function markdownLinkError(file, filesByAbsolutePath, link, projectRoot) {
67
- const target = localLinkTarget(link.url);
36
+ const target = parseLocalMarkdownTarget(link.url);
68
37
  if (target === null)
69
38
  return null;
70
- if (target.kind === 'invalid-backslash') {
71
- return error(link.line, link.url, `invalid ${link.kind} (${link.url}) — backslashes are not path separators in Markdown; use "/" instead`);
72
- }
39
+ if (target.kind === 'invalid-backslash')
40
+ return null;
73
41
  const absolutePath = target.path
74
42
  ? resolve(dirname(file.absolutePath), target.path)
75
43
  : file.absolutePath;
@@ -90,8 +58,8 @@ async function markdownLinkError(file, filesByAbsolutePath, link, projectRoot) {
90
58
  return error(link.line, link.url, `broken link (${link.url}) — heading "#${target.fragment}" not found in "${destination.path}"`);
91
59
  }
92
60
  /** Build per-document validation errors entirely from the current view snapshot. */
93
- export async function buildViewDiagnostics(markdownFiles, codeFiles, allSections, projectRoot) {
94
- clearSymbolCache();
61
+ export async function buildViewDiagnostics(markdownFiles, codeFiles, allSections, projectRoot, external, latDir = resolve(projectRoot, 'lat.md')) {
62
+ const sourceParserRuntime = new SourceParserRuntime();
95
63
  const files = [...markdownFiles];
96
64
  const errors = new Map();
97
65
  const sections = flattenSections(allSections);
@@ -99,25 +67,58 @@ export async function buildViewDiagnostics(markdownFiles, codeFiles, allSections
99
67
  const fileIndex = buildFileIndex(allSections);
100
68
  const slugIndex = buildSectionSlugIndex(allSections);
101
69
  const filesByAbsolutePath = new Map(files.map((file) => [resolve(file.absolutePath), file]));
70
+ if (external) {
71
+ const root = files.find((file) => file.path === 'lat.md') ?? files[0];
72
+ if (root) {
73
+ for (const configError of external.snapshot.errors) {
74
+ addError(errors, root.path, error(1, 'external-sources', configError.message, {
75
+ marker: 'line',
76
+ }));
77
+ }
78
+ }
79
+ }
102
80
  for (const file of files) {
81
+ for (const diagnostic of file.diagnostics) {
82
+ addError(errors, file.path, error(diagnostic.line, diagnostic.target, diagnostic.message, {
83
+ anchor: diagnostic.anchor,
84
+ marker: diagnostic.marker,
85
+ }));
86
+ }
103
87
  for (const ref of file.wikiRefs) {
88
+ if (external) {
89
+ try {
90
+ if (external.parse(ref.target)) {
91
+ await external.resolve(ref.target);
92
+ continue;
93
+ }
94
+ }
95
+ catch (externalError) {
96
+ addError(errors, file.path, error(ref.line, ref.target, externalError.message));
97
+ continue;
98
+ }
99
+ const unknownExternal = external.unknownTargetMessage(ref.target);
100
+ if (unknownExternal) {
101
+ addError(errors, file.path, error(ref.line, ref.target, unknownExternal));
102
+ continue;
103
+ }
104
+ }
104
105
  const resolved = resolveRef(ref.target, sectionIds, fileIndex, slugIndex);
105
106
  let message = null;
106
107
  if (resolved.ambiguous) {
107
108
  message = ambiguousRefMessage(ref.target, resolved.ambiguous, resolved.suggested);
108
109
  }
109
110
  else if (!sectionIds.has(resolved.resolved.toLowerCase())) {
110
- message = await sourceRefError(ref.target, projectRoot);
111
+ message = await repositoryRefError(ref.target, projectRoot, {
112
+ latDir,
113
+ runtime: sourceParserRuntime,
114
+ });
111
115
  }
112
116
  if (message)
113
117
  addError(errors, file.path, error(ref.line, ref.target, message));
114
118
  }
115
119
  const links = new Map();
116
120
  for (const link of file.validationLinks) {
117
- if ('identifier' in link) {
118
- addError(errors, file.path, error(link.line, link.identifier, `undefined ${link.kind === 'imageReference' ? 'image' : 'link'} reference (${link.source}) — definition "[${link.identifier}]" not found`, { marker: 'line' }));
119
- }
120
- else if (link.kind !== 'definition') {
121
+ if (!('identifier' in link) && link.kind !== 'definition') {
121
122
  links.set(`${link.kind}:${link.line}:${link.url}`, {
122
123
  kind: link.kind,
123
124
  line: link.line,
@@ -133,16 +134,6 @@ export async function buildViewDiagnostics(markdownFiles, codeFiles, allSections
133
134
  if (diagnostic)
134
135
  addError(errors, file.path, diagnostic);
135
136
  }
136
- for (const section of flattenSections(file.sections)) {
137
- if (!section.firstParagraph) {
138
- addError(errors, file.path, error(section.startLine, section.id, `section "${section.id}" has no leading paragraph. Every section must start with a brief overview (≤${MAX_BODY_LENGTH} chars).`, { anchor: section.githubSlug, marker: 'heading' }));
139
- continue;
140
- }
141
- const length = bodyTextLength(section.firstParagraph);
142
- if (length > MAX_BODY_LENGTH) {
143
- addError(errors, file.path, error(section.startLine, section.id, `section "${section.id}" leading paragraph is ${length} characters (max ${MAX_BODY_LENGTH}, excluding [[wiki links]]).`, { anchor: section.githubSlug, marker: 'heading' }));
144
- }
145
- }
146
137
  }
147
138
  const mentionedSections = new Set();
148
139
  for (const file of codeFiles) {
@@ -155,7 +146,7 @@ export async function buildViewDiagnostics(markdownFiles, codeFiles, allSections
155
146
  }
156
147
  }
157
148
  for (const file of files) {
158
- if (!parseFrontmatter(file.content).requireCodeMention)
149
+ if (!file.frontmatter.requireCodeMention)
159
150
  continue;
160
151
  for (const section of flattenSections(file.sections)) {
161
152
  if (section.children.length === 0 &&
@@ -0,0 +1,8 @@
1
+ export declare class ViewDocumentConflictError extends Error {
2
+ }
3
+ export type AppliedDocumentEdit = {
4
+ content: string;
5
+ merged: boolean;
6
+ };
7
+ /** Apply the user's base-to-edited patch to the latest content on disk. */
8
+ export declare function applyDocumentEdit(baseContent: string, editedContent: string, currentContent: string): AppliedDocumentEdit;
@@ -0,0 +1,25 @@
1
+ import { applyPatch, createPatch } from 'diff';
2
+ const PATCH_CONTEXT_LINES = 3;
3
+ const PATCH_FUZZ_LINES = 2;
4
+ export class ViewDocumentConflictError extends Error {
5
+ }
6
+ /** Apply the user's base-to-edited patch to the latest content on disk. */
7
+ export function applyDocumentEdit(baseContent, editedContent, currentContent) {
8
+ if (baseContent === editedContent) {
9
+ return { content: currentContent, merged: currentContent !== baseContent };
10
+ }
11
+ if (currentContent === editedContent) {
12
+ return { content: currentContent, merged: currentContent !== baseContent };
13
+ }
14
+ if (currentContent === baseContent) {
15
+ return { content: editedContent, merged: false };
16
+ }
17
+ const patch = createPatch('document.md', baseContent, editedContent, undefined, undefined, { context: PATCH_CONTEXT_LINES });
18
+ const content = applyPatch(currentContent, patch, {
19
+ fuzzFactor: PATCH_FUZZ_LINES,
20
+ });
21
+ if (content === false) {
22
+ throw new ViewDocumentConflictError('Could not save because this file changed in the same area. Your edits are still in the editor.');
23
+ }
24
+ return { content, merged: true };
25
+ }
@@ -0,0 +1,14 @@
1
+ /** Fail explicitly when a document would shadow the UI or a generated file. */
2
+ export declare function validateDocumentRoutes(paths: readonly string[]): void;
3
+ /** Build the canonical, extensionless browser route for a Markdown file. */
4
+ export declare function documentUrl(path: string, fragment?: string): string;
5
+ /** Resolve an extensionless browser route back to its Markdown file path. */
6
+ export declare function documentPath(pathname: string): string | null;
7
+ /** Resolve an explicit `.md` route to the raw Markdown file it requests. */
8
+ export declare function rawDocumentPath(pathname: string): string | null;
9
+ /** Build the browser route for a non-Markdown file stored in the vault. */
10
+ export declare function documentResourceUrl(path: string): string;
11
+ /** Resolve a browser resource route to a safe vault-relative file path. */
12
+ export declare function documentResourcePath(pathname: string): string | null;
13
+ /** Keep relative Markdown-to-Markdown links inside the rendered document UI. */
14
+ export declare function rewriteDocumentLink(value: string, sourcePath: string): string;
@@ -0,0 +1,137 @@
1
+ const DOCUMENT_PREFIX = '/';
2
+ const RESOURCE_PREFIX = '/resources/';
3
+ const MARKDOWN_EXTENSION = '.md';
4
+ const RESERVED_ROUTES = new Set([
5
+ '@',
6
+ 'api',
7
+ 'assets',
8
+ 'data',
9
+ 'code',
10
+ 'external',
11
+ 'resources',
12
+ 'graph',
13
+ 'search',
14
+ 'index.html',
15
+ ]);
16
+ function encodePath(path) {
17
+ return path.split('/').map(encodeURIComponent).join('/');
18
+ }
19
+ function decodeDocumentPath(pathname) {
20
+ if (!pathname.startsWith(DOCUMENT_PREFIX))
21
+ return null;
22
+ try {
23
+ const segments = pathname
24
+ .slice(DOCUMENT_PREFIX.length)
25
+ .split('/')
26
+ .map(decodeURIComponent);
27
+ if (segments.some((part) => !part || part === '.' || part === '..' || /[/\\]/.test(part)))
28
+ return null;
29
+ return segments.join('/');
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ /** Fail explicitly when a document would shadow the UI or a generated file. */
36
+ export function validateDocumentRoutes(paths) {
37
+ const files = new Set(paths);
38
+ for (const path of paths) {
39
+ if (path.includes('@') || documentPath(documentUrl(path)) !== path) {
40
+ throw new Error(`Document path conflicts with a reserved UI route: ${path}`);
41
+ }
42
+ const parts = path.split('/');
43
+ if (parts.some((part) => part === 'index.html.md') ||
44
+ parts.some((_, i) => i > 0 && files.has(parts.slice(0, i).join('/')))) {
45
+ throw new Error(`Document path conflicts with an exported file: ${path}`);
46
+ }
47
+ }
48
+ }
49
+ /** Build the canonical, extensionless browser route for a Markdown file. */
50
+ export function documentUrl(path, fragment = '') {
51
+ if (path.startsWith('@/')) {
52
+ return ('/@/' +
53
+ encodePath(path.slice(2)) +
54
+ (fragment ? '#' + encodeURIComponent(fragment) : ''));
55
+ }
56
+ const routePath = path.endsWith(MARKDOWN_EXTENSION)
57
+ ? path.slice(0, -MARKDOWN_EXTENSION.length)
58
+ : path;
59
+ return `${DOCUMENT_PREFIX}${encodePath(routePath)}${fragment ? `#${encodeURIComponent(fragment)}` : ''}`;
60
+ }
61
+ /** Resolve an extensionless browser route back to its Markdown file path. */
62
+ export function documentPath(pathname) {
63
+ const path = decodeDocumentPath(pathname);
64
+ if (path?.startsWith('@/') &&
65
+ !path.slice(2).includes('@') &&
66
+ path.toLowerCase().endsWith(MARKDOWN_EXTENSION))
67
+ return path;
68
+ if (!path ||
69
+ path.includes('@') ||
70
+ RESERVED_ROUTES.has(path.split('/')[0]) ||
71
+ path.endsWith('/index.html') ||
72
+ path.toLowerCase().endsWith(MARKDOWN_EXTENSION))
73
+ return null;
74
+ return `${path}${MARKDOWN_EXTENSION}`;
75
+ }
76
+ /** Resolve an explicit `.md` route to the raw Markdown file it requests. */
77
+ export function rawDocumentPath(pathname) {
78
+ const path = decodeDocumentPath(pathname);
79
+ return path &&
80
+ !RESERVED_ROUTES.has(path.split('/')[0]) &&
81
+ path.toLowerCase().endsWith(MARKDOWN_EXTENSION)
82
+ ? path
83
+ : null;
84
+ }
85
+ /** Build the browser route for a non-Markdown file stored in the vault. */
86
+ export function documentResourceUrl(path) {
87
+ return `${RESOURCE_PREFIX}${encodePath(path)}`;
88
+ }
89
+ /** Resolve a browser resource route to a safe vault-relative file path. */
90
+ export function documentResourcePath(pathname) {
91
+ if (!pathname.startsWith(RESOURCE_PREFIX))
92
+ return null;
93
+ try {
94
+ const segments = pathname
95
+ .slice(RESOURCE_PREFIX.length)
96
+ .split('/')
97
+ .map(decodeURIComponent);
98
+ if (segments.length === 0 ||
99
+ segments.some((segment) => !segment ||
100
+ segment === '.' ||
101
+ segment === '..' ||
102
+ segment.includes('\\'))) {
103
+ return null;
104
+ }
105
+ return segments.join('/');
106
+ }
107
+ catch {
108
+ return null;
109
+ }
110
+ }
111
+ /** Keep relative Markdown-to-Markdown links inside the rendered document UI. */
112
+ export function rewriteDocumentLink(value, sourcePath) {
113
+ if (!value ||
114
+ value.startsWith('#') ||
115
+ value.startsWith('/') ||
116
+ value.startsWith('//') ||
117
+ /^[a-z][a-z\d+.-]*:/i.test(value)) {
118
+ return value;
119
+ }
120
+ let resolved;
121
+ try {
122
+ resolved = new URL(value, `http://lat.local${DOCUMENT_PREFIX}${encodePath(sourcePath)}`);
123
+ }
124
+ catch {
125
+ return value;
126
+ }
127
+ if (resolved.origin !== 'http://lat.local')
128
+ return value;
129
+ const path = rawDocumentPath(resolved.pathname);
130
+ if (path) {
131
+ return `${documentUrl(path)}${resolved.search}${resolved.hash}`;
132
+ }
133
+ const resourcePath = decodeDocumentPath(resolved.pathname);
134
+ if (!resourcePath)
135
+ return value;
136
+ return `${documentResourceUrl(resourcePath)}${resolved.search}${resolved.hash}`;
137
+ }
@@ -0,0 +1,18 @@
1
+ import type { ViewDocumentElement, ViewDocumentTree } from './protocol.js';
2
+ type HastLikeNode = {
3
+ type?: unknown;
4
+ value?: unknown;
5
+ tagName?: unknown;
6
+ properties?: unknown;
7
+ children?: unknown;
8
+ };
9
+ /** Strip a sanitized HAST tree to the stable JSON wire representation. */
10
+ export declare function toViewDocumentTree(tree: HastLikeNode): ViewDocumentTree;
11
+ export declare function documentTreeUrls(tree: ViewDocumentTree): string[];
12
+ export declare function visitDocumentElements(tree: ViewDocumentTree, visitor: (element: ViewDocumentElement) => void): void;
13
+ /** Apply parser-neutral presentation to links that leave the current site. */
14
+ export declare function decorateExternalSiteLinks(tree: ViewDocumentTree): ViewDocumentTree;
15
+ /** Clone a document tree while structurally rewriting navigable URLs. */
16
+ export declare function rewriteDocumentTreeUrls(tree: ViewDocumentTree, rewrite: (value: string) => string): ViewDocumentTree;
17
+ export declare function textDocumentTree(value: string): ViewDocumentTree;
18
+ export {};
@@ -0,0 +1,139 @@
1
+ function propertyValue(value) {
2
+ if (value === null ||
3
+ typeof value === 'string' ||
4
+ typeof value === 'number' ||
5
+ typeof value === 'boolean') {
6
+ return value;
7
+ }
8
+ if (Array.isArray(value)) {
9
+ return value.filter((item) => typeof item === 'string' || typeof item === 'number');
10
+ }
11
+ return undefined;
12
+ }
13
+ function documentNode(node) {
14
+ if (node.type === 'text' && typeof node.value === 'string') {
15
+ return { type: 'text', value: node.value };
16
+ }
17
+ if (node.type !== 'element' || typeof node.tagName !== 'string')
18
+ return null;
19
+ const properties = {};
20
+ if (node.properties && typeof node.properties === 'object') {
21
+ for (const [name, value] of Object.entries(node.properties)) {
22
+ const normalized = propertyValue(value);
23
+ if (normalized !== undefined)
24
+ properties[name] = normalized;
25
+ }
26
+ }
27
+ const children = Array.isArray(node.children)
28
+ ? node.children
29
+ .map((child) => documentNode(child))
30
+ .filter((child) => child !== null)
31
+ : [];
32
+ return {
33
+ type: 'element',
34
+ tagName: node.tagName,
35
+ properties,
36
+ children,
37
+ };
38
+ }
39
+ /** Strip a sanitized HAST tree to the stable JSON wire representation. */
40
+ export function toViewDocumentTree(tree) {
41
+ if (tree.type !== 'root' || !Array.isArray(tree.children)) {
42
+ throw new Error('Document adapter did not produce a root node');
43
+ }
44
+ return {
45
+ version: 1,
46
+ type: 'root',
47
+ children: tree.children
48
+ .map((child) => documentNode(child))
49
+ .filter((child) => child !== null),
50
+ };
51
+ }
52
+ export function documentTreeUrls(tree) {
53
+ const urls = [];
54
+ visitDocumentElements(tree, (element) => {
55
+ for (const name of ['href', 'src']) {
56
+ const value = element.properties[name];
57
+ if (typeof value === 'string')
58
+ urls.push(value);
59
+ }
60
+ });
61
+ return urls;
62
+ }
63
+ export function visitDocumentElements(tree, visitor) {
64
+ const visit = (node) => {
65
+ if (node.type !== 'element')
66
+ return;
67
+ visitor(node);
68
+ for (const child of node.children)
69
+ visit(child);
70
+ };
71
+ for (const child of tree.children)
72
+ visit(child);
73
+ }
74
+ function classNames(value) {
75
+ if (Array.isArray(value))
76
+ return value.map(String);
77
+ return typeof value === 'string' ? value.split(/\s+/).filter(Boolean) : [];
78
+ }
79
+ function isExternalSiteUrl(value) {
80
+ return /^(?:https?:)?\/\//i.test(value);
81
+ }
82
+ function containsElementTag(element, tagName) {
83
+ return element.children.some((child) => child.type === 'element' &&
84
+ (child.tagName === tagName || containsElementTag(child, tagName)));
85
+ }
86
+ /** Apply parser-neutral presentation to links that leave the current site. */
87
+ export function decorateExternalSiteLinks(tree) {
88
+ visitDocumentElements(tree, (element) => {
89
+ const href = element.properties.href;
90
+ if (element.tagName !== 'a' ||
91
+ typeof href !== 'string' ||
92
+ !isExternalSiteUrl(href)) {
93
+ return;
94
+ }
95
+ const classes = classNames(element.properties.className);
96
+ if (!classes.includes('external-link'))
97
+ classes.push('external-link');
98
+ element.properties.className = classes;
99
+ if (containsElementTag(element, 'img'))
100
+ return;
101
+ const alreadyDecorated = element.children.some((child) => child.type === 'element' &&
102
+ child.tagName === 'span' &&
103
+ classNames(child.properties.className).includes('external-link-icon'));
104
+ if (!alreadyDecorated) {
105
+ element.children.push({
106
+ type: 'element',
107
+ tagName: 'span',
108
+ properties: {
109
+ ariaHidden: 'true',
110
+ className: ['external-link-icon'],
111
+ },
112
+ children: [],
113
+ });
114
+ }
115
+ });
116
+ return tree;
117
+ }
118
+ /** Clone a document tree while structurally rewriting navigable URLs. */
119
+ export function rewriteDocumentTreeUrls(tree, rewrite) {
120
+ const cloneNode = (node) => {
121
+ if (node.type === 'text')
122
+ return { ...node };
123
+ const properties = { ...node.properties };
124
+ for (const name of ['href', 'src']) {
125
+ const value = properties[name];
126
+ if (typeof value === 'string')
127
+ properties[name] = rewrite(value);
128
+ }
129
+ return {
130
+ ...node,
131
+ properties,
132
+ children: node.children.map(cloneNode),
133
+ };
134
+ };
135
+ return { ...tree, children: tree.children.map(cloneNode) };
136
+ }
137
+ export function textDocumentTree(value) {
138
+ return { version: 1, type: 'root', children: [{ type: 'text', value }] };
139
+ }
@@ -0,0 +1,3 @@
1
+ import type { ViewDocumentTree } from './protocol.js';
2
+ /** Reflect a native non-Markdown parser AST into the browser document tree. */
3
+ export declare function renderExternalDocumentTree(format: 'asciidoc' | 'restructuredtext', content: string): Promise<ViewDocumentTree>;