@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
@@ -1,22 +1,23 @@
1
+ import { trustedLiveRequest, RESOURCE_CONTENT_SECURITY_POLICY, } from './request-security.js';
1
2
  import { readFile } from 'node:fs/promises';
2
- import { createServer } from 'node:http';
3
+ import { randomUUID } from 'node:crypto';
3
4
  import { extname, join, relative, resolve, sep } from 'node:path';
4
5
  import { fileURLToPath } from 'node:url';
6
+ import { createLatServerApp, listenLatServer, } from '../../vendor/lat.md-server/index.js';
7
+ import { plainStyler, } from '@plebeiantech/lat.md-core/context';
8
+ import { sectionCommand } from '@plebeiantech/lat.md-core/cli/section';
5
9
  import { DEFAULT_VIEW_LOGO_TEXT, } from './protocol.js';
6
- import { ViewDocumentNotFoundError, ViewSourceNotFoundError, } from './repository.js';
10
+ import { ViewDocumentConflictError } from './document-edit.js';
11
+ import { ViewExternalNotFoundError, ViewDocumentNotFoundError, ViewSourceNotFoundError, } from './repository.js';
7
12
  import { createViewSearch } from './search.js';
8
13
  import { createViewStore } from './store.js';
14
+ import { rewriteClientAssetUrls } from './client-shell.js';
15
+ import { documentResourcePath, documentPath, rawDocumentPath, validateDocumentRoutes, } from './document-route.js';
9
16
  const DEFAULT_HOST = '127.0.0.1';
10
17
  export const DEFAULT_VIEW_PORT = 4242;
18
+ const MAX_DOCUMENT_EDIT_BODY_BYTES = 16 * 1024 * 1024;
19
+ const MAX_DOCUMENT_CONTENT_LENGTH = 8 * 1024 * 1024;
11
20
  const defaultClientDir = fileURLToPath(new URL('./client/', import.meta.url));
12
- function documentUrl(path) {
13
- return `/docs/${path.split('/').map(encodeURIComponent).join('/')}`;
14
- }
15
- function setSecurityHeaders(res) {
16
- res.setHeader('Content-Security-Policy', "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; worker-src 'self' blob:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'");
17
- res.setHeader('Referrer-Policy', 'no-referrer');
18
- res.setHeader('X-Content-Type-Options', 'nosniff');
19
- }
20
21
  function send(res, status, contentType, body, headOnly = false) {
21
22
  res.statusCode = status;
22
23
  res.setHeader('Content-Type', contentType);
@@ -27,6 +28,24 @@ function sendJson(res, status, value, headOnly) {
27
28
  res.setHeader('Cache-Control', 'no-store');
28
29
  send(res, status, 'application/json; charset=utf-8', JSON.stringify(value), headOnly);
29
30
  }
31
+ async function readJsonBody(req) {
32
+ const chunks = [];
33
+ let size = 0;
34
+ for await (const value of req) {
35
+ const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
36
+ size += chunk.byteLength;
37
+ if (size > MAX_DOCUMENT_EDIT_BODY_BYTES) {
38
+ throw new RangeError('Document edit is too large');
39
+ }
40
+ chunks.push(chunk);
41
+ }
42
+ try {
43
+ return JSON.parse(Buffer.concat(chunks).toString('utf8'));
44
+ }
45
+ catch {
46
+ throw new SyntaxError('Document edit must be valid JSON');
47
+ }
48
+ }
30
49
  function contentType(path) {
31
50
  switch (extname(path)) {
32
51
  case '.css':
@@ -37,8 +56,17 @@ function contentType(path) {
37
56
  return 'text/javascript; charset=utf-8';
38
57
  case '.json':
39
58
  return 'application/json; charset=utf-8';
59
+ case '.gif':
60
+ return 'image/gif';
61
+ case '.jpeg':
62
+ case '.jpg':
63
+ return 'image/jpeg';
64
+ case '.png':
65
+ return 'image/png';
40
66
  case '.svg':
41
67
  return 'image/svg+xml';
68
+ case '.webp':
69
+ return 'image/webp';
42
70
  case '.woff2':
43
71
  return 'font/woff2';
44
72
  default:
@@ -71,23 +99,24 @@ async function sendClientFile(res, path, headOnly, immutable = false) {
71
99
  send(res, 404, 'text/plain; charset=utf-8', 'Not found', headOnly);
72
100
  }
73
101
  }
74
- function listen(server, host, port) {
75
- return new Promise((resolveListen, reject) => {
76
- const onError = (error) => {
77
- server.off('listening', onListening);
78
- reject(error);
79
- };
80
- const onListening = () => {
81
- server.off('error', onError);
82
- resolveListen();
83
- };
84
- server.once('error', onError);
85
- server.once('listening', onListening);
86
- server.listen(port, host);
87
- });
102
+ async function sendClientShell(res, path, headOnly, entry) {
103
+ try {
104
+ const html = rewriteClientAssetUrls(await readFile(path, 'utf8'), '/');
105
+ const config = `<meta name="lat-live-entry" content="${encodeURIComponent(entry)}">`;
106
+ const body = html.includes('</head>')
107
+ ? html.replace('</head>', `${config}</head>`)
108
+ : `${config}${html}`;
109
+ res.setHeader('Cache-Control', 'no-cache');
110
+ send(res, 200, 'text/html; charset=utf-8', body, headOnly);
111
+ }
112
+ catch (error) {
113
+ if (error.code !== 'ENOENT')
114
+ throw error;
115
+ send(res, 404, 'text/plain; charset=utf-8', 'Not found', headOnly);
116
+ }
88
117
  }
89
- /** Start the read-only loopback server used by `lat ui`. */
90
- export async function startViewServer(ctx, options = {}) {
118
+ /** Create the portable Express application used by live Lat UI servers. */
119
+ export async function createViewApp(ctx, options = {}) {
91
120
  const host = options.host ?? DEFAULT_HOST;
92
121
  const clientDir = options.clientDir ?? defaultClientDir;
93
122
  const logoText = options.logoText ?? DEFAULT_VIEW_LOGO_TEXT;
@@ -95,35 +124,60 @@ export async function startViewServer(ctx, options = {}) {
95
124
  git: options.git,
96
125
  gitPollMs: options.gitPollMs,
97
126
  watch: options.watch,
127
+ externalCa: options.externalCa,
98
128
  });
129
+ try {
130
+ validateDocumentRoutes(store.getIndex().files);
131
+ }
132
+ catch (error) {
133
+ await store.close();
134
+ throw error;
135
+ }
99
136
  const search = options.search ??
100
137
  createViewSearch(ctx.latDir, undefined, () => store.markdownGeneration);
101
138
  const eventClients = new Set();
139
+ const instanceId = randomUUID();
102
140
  const broadcastChange = (change) => {
103
- const message = `event: change\ndata: ${JSON.stringify(change)}\n\n`;
141
+ const message = `event: change\ndata: ${JSON.stringify({ ...change, instanceId })}\n\n`;
104
142
  for (const client of eventClients)
105
143
  client.write(message);
106
144
  };
107
145
  const unsubscribeStore = store.subscribe(broadcastChange);
108
- const server = createServer((req, res) => {
146
+ const heartbeat = setInterval(() => {
147
+ for (const client of eventClients)
148
+ client.write(': heartbeat\n\n');
149
+ }, 15_000);
150
+ heartbeat.unref();
151
+ const handleRequest = (req, res) => {
109
152
  void (async () => {
110
- setSecurityHeaders(res);
153
+ if (!trustedLiveRequest(req, host)) {
154
+ send(res, 403, 'text/plain; charset=utf-8', 'Untrusted request origin or host');
155
+ return;
156
+ }
111
157
  const method = req.method ?? 'GET';
112
158
  const headOnly = method === 'HEAD';
113
- if (method !== 'GET' && !headOnly) {
159
+ const url = new URL(req.url ?? '/', `http://${req.headers.host}`);
160
+ const documentEdit = method === 'PATCH' && url.pathname === '/api/document';
161
+ if (method !== 'GET' && !headOnly && !documentEdit) {
114
162
  res.setHeader('Allow', 'GET, HEAD');
115
163
  send(res, 405, 'text/plain; charset=utf-8', 'Method not allowed');
116
164
  return;
117
165
  }
118
- const url = new URL(req.url ?? '/', `http://${host}`);
119
166
  if (url.pathname === '/') {
120
167
  const entry = store.getIndex().entry;
121
168
  if (!entry) {
122
169
  send(res, 404, 'text/plain; charset=utf-8', 'No Markdown files found');
123
170
  return;
124
171
  }
125
- res.statusCode = 302;
126
- res.setHeader('Location', documentUrl(entry));
172
+ await sendClientShell(res, join(clientDir, 'index.html'), headOnly, entry);
173
+ return;
174
+ }
175
+ const index = store.getIndex();
176
+ const routePath = url.pathname.replace(/\/$/, '');
177
+ const markdownPath = documentPath(routePath);
178
+ if (markdownPath === index.entry) {
179
+ res.statusCode = 308;
180
+ res.setHeader('Location', `/${url.search}`);
127
181
  res.end();
128
182
  return;
129
183
  }
@@ -146,12 +200,52 @@ export async function startViewServer(ctx, options = {}) {
146
200
  return;
147
201
  }
148
202
  eventClients.add(res);
149
- res.write(`event: ready\ndata: ${JSON.stringify({ generation: store.snapshot.generation, markdownGeneration: store.markdownGeneration })}\n\n`);
203
+ res.write(`retry: 1000\nevent: ready\ndata: ${JSON.stringify({ instanceId, generation: store.snapshot.generation, markdownGeneration: store.markdownGeneration })}\n\n`);
150
204
  req.once('close', () => eventClients.delete(res));
151
205
  return;
152
206
  }
153
207
  if (url.pathname === '/api/document') {
154
208
  const path = url.searchParams.get('path') ?? '';
209
+ if (documentEdit) {
210
+ let body;
211
+ try {
212
+ body = await readJsonBody(req);
213
+ }
214
+ catch (error) {
215
+ sendJson(res, error instanceof RangeError ? 413 : 400, { error: error.message }, false);
216
+ return;
217
+ }
218
+ if (!body ||
219
+ typeof body !== 'object' ||
220
+ typeof body.baseContent !==
221
+ 'string' ||
222
+ typeof body.content !==
223
+ 'string') {
224
+ sendJson(res, 400, {
225
+ error: 'Document edit content is required',
226
+ }, false);
227
+ return;
228
+ }
229
+ const edit = body;
230
+ if (edit.baseContent.length > MAX_DOCUMENT_CONTENT_LENGTH ||
231
+ edit.content.length > MAX_DOCUMENT_CONTENT_LENGTH) {
232
+ sendJson(res, 413, { error: 'Document edit is too large' }, false);
233
+ return;
234
+ }
235
+ try {
236
+ sendJson(res, 200, await store.editDocument(path, edit.baseContent, edit.content), false);
237
+ }
238
+ catch (error) {
239
+ if (error instanceof ViewDocumentConflictError) {
240
+ sendJson(res, 409, { error: error.message }, false);
241
+ return;
242
+ }
243
+ if (!(error instanceof ViewDocumentNotFoundError))
244
+ throw error;
245
+ sendJson(res, 404, { error: error.message }, false);
246
+ }
247
+ return;
248
+ }
155
249
  try {
156
250
  sendJson(res, 200, await store.getDocument(path), headOnly);
157
251
  }
@@ -162,6 +256,18 @@ export async function startViewServer(ctx, options = {}) {
162
256
  }
163
257
  return;
164
258
  }
259
+ if (url.pathname === '/api/document-source') {
260
+ const path = url.searchParams.get('path') ?? '';
261
+ try {
262
+ sendJson(res, 200, await store.getDocumentSource(path), headOnly);
263
+ }
264
+ catch (error) {
265
+ if (!(error instanceof ViewDocumentNotFoundError))
266
+ throw error;
267
+ sendJson(res, 404, { error: error.message }, headOnly);
268
+ }
269
+ return;
270
+ }
165
271
  if (url.pathname === '/api/search') {
166
272
  const query = (url.searchParams.get('query') ?? '').trim();
167
273
  if (query.length > 500) {
@@ -171,6 +277,30 @@ export async function startViewServer(ctx, options = {}) {
171
277
  sendJson(res, 200, await search(query), headOnly);
172
278
  return;
173
279
  }
280
+ if (url.pathname === '/api/section') {
281
+ const query = (url.searchParams.get('query') ?? '').trim();
282
+ if (!query) {
283
+ sendJson(res, 400, { error: 'Section ID is required' }, headOnly);
284
+ return;
285
+ }
286
+ if (query.length > 1_000) {
287
+ sendJson(res, 400, { error: 'Section ID is too long' }, headOnly);
288
+ return;
289
+ }
290
+ const result = await sectionCommand({
291
+ latDir: ctx.latDir,
292
+ projectRoot: ctx.projectRoot,
293
+ styler: plainStyler,
294
+ mode: 'cli',
295
+ }, query);
296
+ const tree = await store.renderSectionOutput(result.output, query);
297
+ sendJson(res, 200, {
298
+ output: result.output,
299
+ tree,
300
+ isError: result.isError === true,
301
+ }, headOnly);
302
+ return;
303
+ }
174
304
  if (url.pathname === '/api/source') {
175
305
  const path = url.searchParams.get('path') ?? '';
176
306
  const symbol = url.searchParams.get('symbol') ?? '';
@@ -193,6 +323,18 @@ export async function startViewServer(ctx, options = {}) {
193
323
  }
194
324
  return;
195
325
  }
326
+ if (url.pathname === '/api/external') {
327
+ const target = url.searchParams.get('target') ?? '';
328
+ try {
329
+ sendJson(res, 200, await store.getExternal(target), headOnly);
330
+ }
331
+ catch (error) {
332
+ if (!(error instanceof ViewExternalNotFoundError))
333
+ throw error;
334
+ sendJson(res, 404, { error: error.message }, headOnly);
335
+ }
336
+ return;
337
+ }
196
338
  if (url.pathname.startsWith('/assets/')) {
197
339
  const path = clientPath(clientDir, url.pathname);
198
340
  if (!path) {
@@ -202,11 +344,47 @@ export async function startViewServer(ctx, options = {}) {
202
344
  await sendClientFile(res, path, headOnly, true);
203
345
  return;
204
346
  }
347
+ const rawMarkdownPath = rawDocumentPath(url.pathname);
348
+ if (rawMarkdownPath) {
349
+ try {
350
+ const source = await store.getDocumentSource(rawMarkdownPath);
351
+ res.setHeader('Cache-Control', 'no-cache');
352
+ send(res, 200, 'text/markdown; charset=utf-8', source.content, headOnly);
353
+ }
354
+ catch (error) {
355
+ if (!(error instanceof ViewDocumentNotFoundError))
356
+ throw error;
357
+ send(res, 404, 'text/plain; charset=utf-8', error.message, headOnly);
358
+ }
359
+ return;
360
+ }
361
+ const resourcePath = documentResourcePath(url.pathname);
362
+ if (resourcePath) {
363
+ try {
364
+ const body = await store.getDocumentResource(resourcePath);
365
+ res.setHeader('Cache-Control', 'no-cache');
366
+ res.setHeader('Content-Security-Policy', RESOURCE_CONTENT_SECURITY_POLICY);
367
+ res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
368
+ if (/\.(?:html?|xhtml|xml|[cm]?js)$/i.test(resourcePath)) {
369
+ res.setHeader('Content-Disposition', 'attachment');
370
+ }
371
+ send(res, 200, contentType(resourcePath), body, headOnly);
372
+ }
373
+ catch (error) {
374
+ if (!(error instanceof ViewDocumentNotFoundError))
375
+ throw error;
376
+ send(res, 404, 'text/plain; charset=utf-8', error.message, headOnly);
377
+ }
378
+ return;
379
+ }
205
380
  if (url.pathname === '/search' ||
206
381
  url.pathname === '/graph' ||
207
- url.pathname.startsWith('/docs/') ||
208
- url.pathname.startsWith('/code/')) {
209
- await sendClientFile(res, join(clientDir, 'index.html'), headOnly);
382
+ (markdownPath !== null &&
383
+ (markdownPath.startsWith('@/') ||
384
+ index.files.includes(markdownPath))) ||
385
+ url.pathname.startsWith('/code/') ||
386
+ url.pathname.startsWith('/external/')) {
387
+ await sendClientShell(res, join(clientDir, 'index.html'), headOnly, index.entry);
210
388
  return;
211
389
  }
212
390
  send(res, 404, 'text/plain; charset=utf-8', 'Not found', headOnly);
@@ -217,50 +395,44 @@ export async function startViewServer(ctx, options = {}) {
217
395
  }
218
396
  sendJson(res, 500, { error: error.message }, false);
219
397
  });
220
- });
221
- try {
222
- const requestedPort = options.port;
223
- let port = requestedPort ?? DEFAULT_VIEW_PORT;
224
- while (true) {
225
- try {
226
- await listen(server, host, port);
227
- break;
228
- }
229
- catch (error) {
230
- if (requestedPort !== undefined ||
231
- error.code !== 'EADDRINUSE' ||
232
- port === 65_535) {
233
- throw error;
234
- }
235
- port++;
236
- }
237
- }
238
- }
239
- catch (error) {
240
- unsubscribeStore();
241
- await store.close();
242
- throw error;
243
- }
244
- const address = server.address();
245
- if (!address || typeof address === 'string') {
246
- await new Promise((resolveClose) => server.close(() => resolveClose()));
247
- unsubscribeStore();
248
- await store.close();
249
- throw new Error('Could not determine lat ui server address');
250
- }
398
+ };
399
+ const app = createLatServerApp({ handle: handleRequest });
251
400
  return {
252
- server,
401
+ app,
253
402
  store,
254
- url: `http://${host}:${address.port}/`,
255
403
  close: async () => {
404
+ clearInterval(heartbeat);
256
405
  unsubscribeStore();
257
406
  for (const client of eventClients)
258
407
  client.end();
259
408
  eventClients.clear();
260
409
  await store.close();
261
- await new Promise((resolveClose, reject) => {
262
- server.close((error) => (error ? reject(error) : resolveClose()));
263
- });
410
+ },
411
+ };
412
+ }
413
+ /** Start the loopback server used by `lat ui`. */
414
+ export async function startViewServer(ctx, options = {}) {
415
+ const host = options.host ?? DEFAULT_HOST;
416
+ const view = await createViewApp(ctx, options);
417
+ let running;
418
+ try {
419
+ const requestedPort = options.port;
420
+ running = await listenLatServer(view.app, {
421
+ host,
422
+ port: requestedPort ?? DEFAULT_VIEW_PORT,
423
+ findAvailablePort: requestedPort === undefined,
424
+ });
425
+ }
426
+ catch (error) {
427
+ await view.close();
428
+ throw error;
429
+ }
430
+ return {
431
+ server: running.server,
432
+ store: view.store,
433
+ url: running.url,
434
+ close: async () => {
435
+ await Promise.all([running.close(), view.close()]);
264
436
  },
265
437
  };
266
438
  }
@@ -1,3 +1,5 @@
1
+ /** Resolve ordinary code links relative to their Markdown file, not the vault root. */
2
+ export declare function rewriteLocalFileLink(value: string, sourcePath: string): string;
1
3
  export type ViewSourceTarget = {
2
4
  path: string;
3
5
  symbol: string;
@@ -1,16 +1,57 @@
1
- import { extname, posix } from 'node:path';
2
- import { SOURCE_EXTENSIONS } from '../source-parser.js';
1
+ import { extname } from 'node:path';
2
+ import { normalizeRepositoryPath } from '@plebeiantech/lat.md-core/repository-path';
3
+ import { isSourceFileExtension } from '@plebeiantech/lat.md-core/source-formats';
4
+ import { documentUrl, documentResourceUrl, rewriteDocumentLink, } from './document-route.js';
5
+ /** Resolve ordinary code links relative to their Markdown file, not the vault root. */
6
+ export function rewriteLocalFileLink(value, sourcePath) {
7
+ if (value && !/^(?:[#/]|[a-z][a-z\d+.-]*:)/i.test(value)) {
8
+ try {
9
+ // Keep a project prefix so URL normalization cannot silently clamp an
10
+ // escaping relative path back into the project.
11
+ const preview = sourcePath.startsWith('@/');
12
+ const authoredPath = preview
13
+ ? sourcePath.slice(2)
14
+ : 'lat.md/' + sourcePath;
15
+ const base = authoredPath.split('/').map(encodeURIComponent).join('/');
16
+ const url = new URL(value, `http://lat.local/project/${base}`);
17
+ if (url.origin === 'http://lat.local' &&
18
+ url.pathname.startsWith('/project/')) {
19
+ const path = decodeURIComponent(url.pathname.slice('/project/'.length));
20
+ if (path.includes('@'))
21
+ return '#';
22
+ const suffix = url.search + url.hash;
23
+ if (normalizeRepositoryPath(path) &&
24
+ extname(path).toLowerCase() === '.md') {
25
+ return (documentUrl(path.startsWith('lat.md/') ? path.slice(7) : '@/' + path) + suffix);
26
+ }
27
+ if (preview &&
28
+ normalizeRepositoryPath(path) &&
29
+ !isSourceFileExtension(extname(path))) {
30
+ return (documentResourceUrl(path.startsWith('lat.md/') ? path.slice(7) : '@/' + path) + suffix);
31
+ }
32
+ if (normalizeRepositoryPath(path) &&
33
+ (!path.startsWith('lat.md/') || isSourceFileExtension(extname(path)))) {
34
+ return `/code/${path.split('/').map(encodeURIComponent).join('/')}${url.search}${url.hash}`;
35
+ }
36
+ }
37
+ }
38
+ catch {
39
+ // Malformed URLs retain the ordinary document/resource fallback.
40
+ }
41
+ }
42
+ if (sourcePath.startsWith('@/') &&
43
+ value &&
44
+ !/^(?:[#/]|[a-z][a-z\d+.-]*:)/i.test(value))
45
+ return '#';
46
+ return rewriteDocumentLink(value, sourcePath);
47
+ }
3
48
  /** Normalize a supported source wiki-link target for view indexes and routes. */
4
49
  export function viewSourceTarget(target) {
5
50
  const hash = target.indexOf('#');
6
51
  const authoredPath = hash === -1 ? target : target.slice(0, hash);
7
- if (!authoredPath ||
8
- authoredPath.includes('\\') ||
9
- posix.isAbsolute(authoredPath) ||
10
- !SOURCE_EXTENSIONS.has(extname(authoredPath))) {
52
+ const path = normalizeRepositoryPath(authoredPath);
53
+ if (!path || !isSourceFileExtension(extname(path)))
11
54
  return null;
12
- }
13
- const path = posix.normalize(authoredPath).replace(/^\.\//, '');
14
55
  const symbol = hash === -1 ? '' : target.slice(hash + 1);
15
56
  const fileKey = path.toLowerCase();
16
57
  return {
@@ -1,8 +1,13 @@
1
- import type { CmdContext } from '../context.js';
1
+ import { rename } from 'node:fs/promises';
2
+ import type { CmdContext } from '@plebeiantech/lat.md-core/context';
2
3
  export type StaticViewBuildOptions = {
3
4
  basePath?: string;
4
5
  clientDir?: string;
6
+ codeExcludePaths?: string[];
7
+ force?: boolean;
5
8
  logoText?: string;
9
+ externalCa?: string | Buffer;
10
+ searchApi?: string;
6
11
  };
7
12
  export type StaticViewBuildResult = {
8
13
  documents: number;
@@ -11,6 +16,17 @@ export type StaticViewBuildResult = {
11
16
  };
12
17
  export declare function normalizeStaticViewBasePath(value: string): string;
13
18
  /** Convert a live view route to its physical static-directory URL. */
14
- export declare function staticViewUrl(value: string, basePath: string): string;
19
+ export declare function staticViewUrl(value: string, basePath: string, entryPath?: string): string;
20
+ /** Refuse build targets that exist or could replace the project itself. */
21
+ export declare function validateViewBuildOutput(outputDir: string, projectRoot: string, kind?: string, force?: boolean): Promise<void>;
22
+ type ViewBuildMoveDependencies = {
23
+ move: typeof rename;
24
+ wait: (milliseconds: number) => Promise<void>;
25
+ };
26
+ /** Commit a staged build after transient filesystem locks have cleared. */
27
+ export declare function moveViewBuildOutput(stagingDir: string, outputDir: string, dependencies?: ViewBuildMoveDependencies): Promise<void>;
28
+ /** Remove abandoned staging after transient filesystem locks have cleared. */
29
+ export declare function removeViewBuildStaging(stagingDir: string): Promise<void>;
15
30
  /** Build a serverless snapshot of the current read-only Lat UI. */
16
31
  export declare function buildStaticView(ctx: CmdContext, requestedOutput: string, options?: StaticViewBuildOptions): Promise<StaticViewBuildResult>;
32
+ export {};