@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,21 +1,30 @@
1
+ import { repositoryFilePath } from '@plebeiantech/lat.md-core/repository-path';
2
+ import { randomUUID } from 'node:crypto';
1
3
  import { watch as watchFiles } from 'node:fs';
2
- import { readFile, realpath } from 'node:fs/promises';
4
+ import { readFile, realpath, rename, rm, stat, writeFile, } from 'node:fs/promises';
3
5
  import { basename, extname, isAbsolute, relative, resolve, sep, } from 'node:path';
4
- import { LAT_REF_RE, scanCodeRefs } from '../code-refs.js';
5
- import { listLatticeFiles, parseFrontmatter, } from '../lattice.js';
6
- import { SOURCE_EXTENSIONS } from '../source-parser.js';
7
- import { toPosix } from '../walk.js';
6
+ import { createCodeReferenceDiscovery, extractCodeRefTargets, } from '@plebeiantech/lat.md-core/code-refs';
7
+ import { createExternalResolver, } from '@plebeiantech/lat.md-core/external-sources';
8
+ import { listLatticeFiles } from '@plebeiantech/lat.md-core/project-discovery';
9
+ import { analyzeMarkdownPath } from '@plebeiantech/lat.md-core/markdown-analysis-cache';
10
+ import { isSourceFileExtension } from '@plebeiantech/lat.md-core/source-formats';
11
+ import { toPosix } from '@plebeiantech/lat.md-core/path';
8
12
  import { renderMarkdown } from './markdown.js';
9
13
  import { buildViewDiagnostics } from './diagnostics.js';
14
+ import { applyDocumentEdit, ViewDocumentConflictError, } from './document-edit.js';
10
15
  import { buildGitDiffTree } from './git-diff.js';
11
16
  import { buildViewGraph } from './graph.js';
12
17
  import { buildViewTableOfContents } from './table-of-contents.js';
13
18
  import { emptyViewGitSnapshot, findViewGitRepository, readViewGitSnapshot, sameViewGitSnapshot, } from './git.js';
14
19
  import { DEFAULT_VIEW_LOGO_TEXT } from './protocol.js';
15
- import { createMarkdownWikiLinkResolver, getViewSource, ViewDocumentNotFoundError, } from './repository.js';
16
- import { buildViewReferenceIndex, parseViewMarkdownFile, renderSectionBackReferences, } from './references.js';
20
+ import { createMarkdownWikiLinkResolver, getViewExternal, getViewSource, ViewDocumentNotFoundError, ViewSourceNotFoundError, } from './repository.js';
21
+ import { buildViewReferenceIndex, renderSectionBackReferences, } from './references.js';
22
+ import { rewriteLocalFileLink } from './source-target.js';
17
23
  const DEFAULT_DEBOUNCE_MS = 75;
18
24
  const DEFAULT_GIT_POLL_MS = 2_000;
25
+ const EXTERNAL_REFRESH_PATH = '@lat-external-refresh';
26
+ const DOCUMENT_EDIT_WRITE_ATTEMPTS = 3;
27
+ const DOCUMENT_EDIT_TEMP_PREFIX = '.lat-edit-';
19
28
  function isInside(root, candidate) {
20
29
  const rel = relative(root, candidate);
21
30
  return (rel === '' ||
@@ -25,12 +34,16 @@ function projectPath(projectRoot, path) {
25
34
  const normalized = isAbsolute(path) ? relative(projectRoot, path) : path;
26
35
  return toPosix(normalized).replace(/^\.\//, '');
27
36
  }
37
+ function isInternalLatCachePath(path, latPath) {
38
+ const cachePath = latPath ? `${latPath}/.cache` : '.cache';
39
+ return path === cachePath || path.startsWith(`${cachePath}/`);
40
+ }
28
41
  function excludedCodePath(projectRoot, path, excludedPaths) {
29
42
  const absolutePath = resolve(projectRoot, path);
30
43
  return excludedPaths.some((root) => isInside(resolve(root), absolutePath));
31
44
  }
32
45
  function sourcePath(path) {
33
- return SOURCE_EXTENSIONS.has(extname(path).toLowerCase());
46
+ return isSourceFileExtension(extname(path).toLowerCase());
34
47
  }
35
48
  function obviouslyIgnoredCodePath(path, latPath) {
36
49
  const parts = path.split('/');
@@ -44,10 +57,8 @@ function codeRefsFromContent(path, content) {
44
57
  const refs = [];
45
58
  const lines = content.split('\n');
46
59
  for (let index = 0; index < lines.length; index++) {
47
- LAT_REF_RE.lastIndex = 0;
48
- let match;
49
- while ((match = LAT_REF_RE.exec(lines[index])) !== null) {
50
- refs.push({ target: match[1], file: path, line: index + 1 });
60
+ for (const target of extractCodeRefTargets(lines[index])) {
61
+ refs.push({ target, file: path, line: index + 1 });
51
62
  }
52
63
  }
53
64
  return refs;
@@ -63,7 +74,10 @@ async function loadCodeReferenceFiles(projectRoot, refs) {
63
74
  const files = new Map();
64
75
  await Promise.all([...refsByFile].map(async ([path, fileRefs]) => {
65
76
  try {
66
- const content = await readFile(resolve(projectRoot, path), 'utf8');
77
+ const safePath = await repositoryFilePath(projectRoot, path);
78
+ if (!safePath)
79
+ return;
80
+ const content = await readFile(safePath, 'utf8');
67
81
  files.set(path, { path, lines: content.split('\n'), refs: fileRefs });
68
82
  }
69
83
  catch {
@@ -72,25 +86,61 @@ async function loadCodeReferenceFiles(projectRoot, refs) {
72
86
  }));
73
87
  return files;
74
88
  }
75
- async function scanCodeState(projectRoot, excludedPaths = []) {
76
- const scan = await scanCodeRefs(projectRoot);
89
+ async function scanCodeState(projectRoot, excludedPaths = [], publishable) {
90
+ const discovery = createCodeReferenceDiscovery(projectRoot);
91
+ const [scan, sourceFiles] = await Promise.all([
92
+ discovery.scan(),
93
+ discovery.listSourceFiles(),
94
+ ]);
77
95
  const allowed = (path) => !excludedCodePath(projectRoot, path, excludedPaths);
78
- const files = scan.files.filter(allowed);
79
- const refs = scan.refs.filter((ref) => allowed(ref.file));
96
+ const candidates = sourceFiles.filter(allowed);
97
+ const decisions = await Promise.all(candidates.map((path) => publishable?.(projectPath(projectRoot, path)) ?? true));
98
+ const files = candidates.filter((_, index) => decisions[index]);
80
99
  const scope = new Set(files.map((path) => projectPath(projectRoot, path)));
100
+ const refs = scan.refs.filter((ref) => allowed(ref.file) && scope.has(ref.file));
81
101
  return {
82
102
  files: await loadCodeReferenceFiles(projectRoot, refs),
83
103
  scope,
84
104
  };
85
105
  }
86
- function viewIndex(latDir, paths, diagnostics, git) {
87
- const files = [...paths].sort();
106
+ function viewIndex(latDir, markdownFiles, diagnostics, git, references, external) {
107
+ const files = [...markdownFiles.keys()].sort();
108
+ const externalFiles = new Map();
109
+ for (const target of references.externalByTarget.keys()) {
110
+ try {
111
+ const parsed = external.parse(target);
112
+ if (!parsed)
113
+ continue;
114
+ const hash = parsed.identity.indexOf('#');
115
+ const baseTarget = hash === -1 ? parsed.identity : parsed.identity.slice(0, hash);
116
+ externalFiles.set(baseTarget, {
117
+ handle: parsed.handle,
118
+ path: parsed.resolvedPath,
119
+ target: baseTarget,
120
+ });
121
+ }
122
+ catch {
123
+ // Invalid external targets remain diagnostics, not sidebar entries.
124
+ }
125
+ }
88
126
  const directoryName = basename(latDir);
89
127
  const indexName = directoryName.endsWith('.md')
90
128
  ? directoryName
91
129
  : `${directoryName}.md`;
130
+ const directoryOrder = Object.fromEntries([...markdownFiles].flatMap(([path, file]) => {
131
+ const separator = path.lastIndexOf('/');
132
+ const directory = separator === -1 ? '' : path.slice(0, separator);
133
+ const name = directory ? basename(directory) : directoryName;
134
+ const filename = name.endsWith('.md') ? name : `${name}.md`;
135
+ if (path.slice(separator + 1) !== filename)
136
+ return [];
137
+ return [[directory, file.indexEntries]];
138
+ }));
92
139
  return {
93
140
  files,
141
+ directoryOrder,
142
+ externalFiles: [...externalFiles.values()].sort((left, right) => left.handle.localeCompare(right.handle) ||
143
+ left.path.localeCompare(right.path)),
94
144
  entry: files.includes(indexName) ? indexName : (files[0] ?? ''),
95
145
  errorCounts: Object.fromEntries([...diagnostics]
96
146
  .filter(([, errors]) => errors.length > 0)
@@ -103,21 +153,34 @@ function viewIndex(latDir, paths, diagnostics, git) {
103
153
  logoText: DEFAULT_VIEW_LOGO_TEXT,
104
154
  };
105
155
  }
106
- async function buildSnapshot(latDir, projectRoot, markdownFiles, codeFiles, git, generation, markdownGeneration) {
156
+ async function buildSnapshot(latDir, projectRoot, markdownFiles, codeFiles, git, generation, markdownGeneration, options) {
107
157
  const files = new Map([...markdownFiles].sort(([left], [right]) => left.localeCompare(right)));
108
158
  const allSections = [...files.values()].flatMap((file) => file.sections);
109
- const diagnostics = await buildViewDiagnostics(files.values(), codeFiles.values(), allSections, projectRoot);
110
- const references = buildViewReferenceIndex(files.values(), codeFiles.values(), allSections);
159
+ const external = await createExternalResolver(latDir, projectRoot, {
160
+ ignoreLocal: options.externalIgnoreLocal,
161
+ ca: options.externalCa,
162
+ });
163
+ await external.reconcile();
164
+ const diagnostics = await buildViewDiagnostics(files.values(), codeFiles.values(), allSections, projectRoot, external, latDir);
165
+ const references = buildViewReferenceIndex(files.values(), codeFiles.values(), allSections, (target) => {
166
+ try {
167
+ return external.parse(target)?.identity ?? null;
168
+ }
169
+ catch {
170
+ return target;
171
+ }
172
+ });
111
173
  return {
112
174
  generation,
113
175
  markdownGeneration,
114
176
  files,
115
177
  allSections,
116
178
  references,
117
- graph: buildViewGraph(files.values(), codeFiles.values(), allSections, diagnostics, git, generation),
179
+ graph: buildViewGraph(files.values(), codeFiles.values(), allSections, diagnostics, git, generation, references, external),
118
180
  diagnostics,
119
181
  git,
120
- index: viewIndex(latDir, [...files.keys()], diagnostics, git),
182
+ index: viewIndex(latDir, files, diagnostics, git, references, external),
183
+ external,
121
184
  };
122
185
  }
123
186
  /** Own the immutable, incrementally refreshed project snapshot for `lat ui`. */
@@ -133,11 +196,13 @@ export class ViewStore {
133
196
  ignoredCodePaths = new Set();
134
197
  listeners = new Set();
135
198
  watcher = null;
199
+ externalWatchers = [];
136
200
  pendingPaths = new Set();
137
201
  debounceTimer = null;
138
202
  gitPollTimer = null;
139
203
  gitPollQueued = false;
140
204
  refreshTail = Promise.resolve();
205
+ editTail = Promise.resolve();
141
206
  closed = false;
142
207
  constructor(latDir, projectRoot, realLatDir, snapshot, codeFiles, codeScope, gitRepository, options) {
143
208
  this.latDir = latDir;
@@ -168,6 +233,29 @@ export class ViewStore {
168
233
  catch (error) {
169
234
  process.stderr.write(`lat ui watcher: ${error.message}\n`);
170
235
  }
236
+ this.refreshExternalWatchers();
237
+ }
238
+ refreshExternalWatchers() {
239
+ for (const watcher of this.externalWatchers)
240
+ watcher.close();
241
+ this.externalWatchers = [];
242
+ if (this.options.watch === false)
243
+ return;
244
+ const paths = new Set([...this.snapshotValue.external.snapshot.sources.values()]
245
+ .map((source) => source.localPath)
246
+ .filter((path) => Boolean(path)));
247
+ for (const path of paths) {
248
+ try {
249
+ const watcher = watchFiles(path, { recursive: true }, () => this.scheduleRefresh(EXTERNAL_REFRESH_PATH));
250
+ watcher.on('error', (error) => {
251
+ process.stderr.write(`lat ui external watcher: ${error.message}\n`);
252
+ });
253
+ this.externalWatchers.push(watcher);
254
+ }
255
+ catch (error) {
256
+ process.stderr.write(`lat ui external watcher: ${error.message}\n`);
257
+ }
258
+ }
171
259
  }
172
260
  subscribe(listener) {
173
261
  this.listeners.add(listener);
@@ -179,7 +267,54 @@ export class ViewStore {
179
267
  getGraph() {
180
268
  return this.snapshotValue.graph;
181
269
  }
270
+ async renderSectionOutput(markdown, sectionId) {
271
+ const snapshot = this.snapshotValue;
272
+ const section = snapshot.allSections.find((candidate) => candidate.id.toLowerCase() === sectionId.toLowerCase());
273
+ const requestedPath = section
274
+ ? toPosix(relative(this.latDir, resolve(this.projectRoot, section.filePath)))
275
+ : 'section-output.md';
276
+ const resolver = await createMarkdownWikiLinkResolver(this.latDir, requestedPath, snapshot.allSections, snapshot.references, snapshot.external, this.options.publishable);
277
+ return (await renderMarkdown(markdown, requestedPath, resolver)).tree;
278
+ }
279
+ async projectPreviewFile(path) {
280
+ if (!path ||
281
+ path.includes('@') ||
282
+ path.includes('\\') ||
283
+ path.split('/').some((part) => !part || part === '.' || part === '..')) {
284
+ throw new ViewDocumentNotFoundError('Project file not found');
285
+ }
286
+ if (this.options.publishable && !(await this.options.publishable(path))) {
287
+ throw new ViewDocumentNotFoundError('Project file is excluded from publication');
288
+ }
289
+ const file = await repositoryFilePath(this.projectRoot, path);
290
+ if (!file)
291
+ throw new ViewDocumentNotFoundError('Project file not found');
292
+ return file;
293
+ }
294
+ async getProjectDocument(path) {
295
+ const file = await this.projectPreviewFile(path);
296
+ if (!path.toLowerCase().endsWith('.md'))
297
+ throw new ViewDocumentNotFoundError('Markdown document not found');
298
+ const analysis = await analyzeMarkdownPath(file, this.latDir, this.projectRoot);
299
+ const requestedPath = '@/' + path;
300
+ const resolver = await createMarkdownWikiLinkResolver(this.latDir, toPosix(relative(this.latDir, file)), this.snapshotValue.allSections, this.snapshotValue.references, this.snapshotValue.external, this.options.publishable);
301
+ const rendered = await renderMarkdown(analysis.content, requestedPath, resolver, {
302
+ rewriteMarkdownLink: (url) => rewriteLocalFileLink(url, requestedPath),
303
+ });
304
+ return {
305
+ ...rendered,
306
+ path: requestedPath,
307
+ gitTree: null,
308
+ tableOfContents: buildViewTableOfContents(analysis.sections, analysis.headingTitles, { errors: [], gitTree: null }),
309
+ graphNodeIds: {},
310
+ errors: [],
311
+ backReferences: [],
312
+ frontmatter: { requireCodeMention: false },
313
+ };
314
+ }
182
315
  async getDocument(requestedPath) {
316
+ if (requestedPath.startsWith('@/'))
317
+ return this.getProjectDocument(requestedPath.slice(2));
183
318
  if (!requestedPath ||
184
319
  requestedPath.includes('\\') ||
185
320
  isAbsolute(requestedPath) ||
@@ -191,24 +326,27 @@ export class ViewStore {
191
326
  if (!file) {
192
327
  throw new ViewDocumentNotFoundError('Markdown document not found');
193
328
  }
194
- const resolver = await createMarkdownWikiLinkResolver(this.latDir, requestedPath, snapshot.allSections, snapshot.references);
195
- const rendered = await renderMarkdown(file.content, requestedPath, resolver, { errors: [...(snapshot.diagnostics.get(requestedPath) ?? [])] }, file.tree);
329
+ const resolver = await createMarkdownWikiLinkResolver(this.latDir, requestedPath, snapshot.allSections, snapshot.references, snapshot.external, this.options.publishable);
330
+ const rendered = await renderMarkdown(file.content, requestedPath, resolver, {
331
+ errors: [...(snapshot.diagnostics.get(requestedPath) ?? [])],
332
+ rewriteMarkdownLink: (url) => rewriteLocalFileLink(url, requestedPath),
333
+ });
196
334
  const errors = [...(snapshot.diagnostics.get(requestedPath) ?? [])];
197
335
  const gitFile = snapshot.git.files.get(requestedPath);
198
336
  const gitTree = gitFile
199
- ? buildGitDiffTree(gitFile.baseContent, file.content, file.tree)
337
+ ? buildGitDiffTree(gitFile.baseContent, file.content)
200
338
  : null;
201
339
  const gitRendered = gitTree
202
- ? await renderMarkdown(file.content, requestedPath, resolver, { errors }, gitTree)
340
+ ? await renderMarkdown(file.content, requestedPath, resolver, {
341
+ errors,
342
+ rewriteMarkdownLink: (url) => rewriteLocalFileLink(url, requestedPath),
343
+ }, gitTree)
203
344
  : null;
204
345
  return {
205
346
  path: requestedPath,
206
347
  ...rendered,
207
- gitHtml: gitRendered?.html ?? null,
208
- tableOfContents: buildViewTableOfContents(file.sections, file.tree, {
209
- errors,
210
- gitTree,
211
- }),
348
+ gitTree: gitRendered?.tree ?? null,
349
+ tableOfContents: buildViewTableOfContents(file.sections, file.headingTitles, { errors, gitTree }),
212
350
  graphNodeIds: Object.fromEntries(snapshot.graph.nodes
213
351
  .filter((node) => node.documentPath === requestedPath && node.kind === 'document')
214
352
  .map((node) => {
@@ -223,20 +361,119 @@ export class ViewStore {
223
361
  return [headingId, node.id];
224
362
  })),
225
363
  errors,
226
- backReferences: await renderSectionBackReferences(snapshot.references, file.sections, this.latDir, this.projectRoot, (path) => createMarkdownWikiLinkResolver(this.latDir, path, snapshot.allSections, snapshot.references)),
364
+ backReferences: await renderSectionBackReferences(snapshot.references, file.sections, this.latDir, this.projectRoot, (path) => createMarkdownWikiLinkResolver(this.latDir, path, snapshot.allSections, snapshot.references, snapshot.external, this.options.publishable)),
227
365
  frontmatter: {
228
- requireCodeMention: parseFrontmatter(file.content).requireCodeMention === true,
366
+ requireCodeMention: file.frontmatter.requireCodeMention === true,
229
367
  },
230
368
  };
231
369
  }
232
- getSource(requestedPath, requestedSymbol = '', origin, requestedLine = 0) {
370
+ async editableDocumentPath(requestedPath) {
371
+ if (!requestedPath ||
372
+ requestedPath.includes('\\') ||
373
+ isAbsolute(requestedPath) ||
374
+ !requestedPath.toLowerCase().endsWith('.md') ||
375
+ !this.snapshotValue.files.has(requestedPath)) {
376
+ throw new ViewDocumentNotFoundError('Markdown document not found');
377
+ }
378
+ let realFile;
379
+ try {
380
+ realFile = await realpath(resolve(this.latDir, requestedPath));
381
+ }
382
+ catch {
383
+ throw new ViewDocumentNotFoundError('Markdown document not found');
384
+ }
385
+ if (!isInside(this.realLatDir, realFile)) {
386
+ throw new ViewDocumentNotFoundError('Markdown document not found');
387
+ }
388
+ return realFile;
389
+ }
390
+ async getDocumentSource(requestedPath) {
391
+ const path = await this.editableDocumentPath(requestedPath);
392
+ return { path: requestedPath, content: await readFile(path, 'utf8') };
393
+ }
394
+ async getDocumentResource(requestedPath) {
395
+ if (requestedPath.startsWith('@/')) {
396
+ const path = requestedPath.slice(2);
397
+ if (path.toLowerCase().endsWith('.md'))
398
+ throw new ViewDocumentNotFoundError('Document resource not found');
399
+ return readFile(await this.projectPreviewFile(path));
400
+ }
401
+ if (this.options.publishable &&
402
+ !(await this.options.publishable(projectPath(this.projectRoot, resolve(this.latDir, requestedPath)))))
403
+ throw new ViewDocumentNotFoundError(`Resource is excluded from publication: ${requestedPath}`);
404
+ if (!requestedPath ||
405
+ requestedPath.includes('\\') ||
406
+ isAbsolute(requestedPath) ||
407
+ requestedPath.toLowerCase().endsWith('.md')) {
408
+ throw new ViewDocumentNotFoundError('Document resource not found');
409
+ }
410
+ let path;
411
+ try {
412
+ path = await realpath(resolve(this.latDir, requestedPath));
413
+ if (!isInside(this.realLatDir, path) || !(await stat(path)).isFile()) {
414
+ throw new ViewDocumentNotFoundError('Document resource not found');
415
+ }
416
+ return await readFile(path);
417
+ }
418
+ catch (error) {
419
+ if (error instanceof ViewDocumentNotFoundError)
420
+ throw error;
421
+ throw new ViewDocumentNotFoundError('Document resource not found');
422
+ }
423
+ }
424
+ editDocument(requestedPath, baseContent, editedContent) {
425
+ const operation = this.editTail.then(async () => {
426
+ const path = await this.editableDocumentPath(requestedPath);
427
+ for (let attempt = 0; attempt < DOCUMENT_EDIT_WRITE_ATTEMPTS; attempt++) {
428
+ const currentContent = await readFile(path, 'utf8');
429
+ const edit = applyDocumentEdit(baseContent, editedContent, currentContent);
430
+ if (edit.content === currentContent) {
431
+ return { path: requestedPath, ...edit };
432
+ }
433
+ const currentStat = await stat(path);
434
+ const temporaryPath = resolve(this.latDir, `${DOCUMENT_EDIT_TEMP_PREFIX}${process.pid}-${randomUUID()}.tmp`);
435
+ try {
436
+ await writeFile(temporaryPath, edit.content, {
437
+ encoding: 'utf8',
438
+ flag: 'wx',
439
+ mode: currentStat.mode,
440
+ });
441
+ if ((await readFile(path, 'utf8')) !== currentContent)
442
+ continue;
443
+ await rename(temporaryPath, path);
444
+ }
445
+ finally {
446
+ await rm(temporaryPath, { force: true });
447
+ }
448
+ await this.refresh([resolve(this.latDir, requestedPath)]);
449
+ return { path: requestedPath, ...edit };
450
+ }
451
+ throw new ViewDocumentConflictError('Could not save because this file kept changing. Your edits are still in the editor.');
452
+ });
453
+ this.editTail = operation.then(() => undefined, () => undefined);
454
+ return operation;
455
+ }
456
+ async getSource(requestedPath, requestedSymbol = '', origin, requestedLine = 0) {
457
+ if (this.options.publishable &&
458
+ !(await this.options.publishable(requestedPath)))
459
+ throw new ViewSourceNotFoundError(`Source is excluded from publication: ${requestedPath}`);
233
460
  const snapshot = this.snapshotValue;
234
- return getViewSource(this.latDir, this.projectRoot, requestedPath, requestedSymbol, origin, requestedLine, snapshot.allSections, snapshot.references);
461
+ return getViewSource(this.latDir, this.projectRoot, requestedPath, requestedSymbol, origin, requestedLine, snapshot.allSections, snapshot.references, this.options.publishable);
462
+ }
463
+ getExternal(target) {
464
+ const snapshot = this.snapshotValue;
465
+ return getViewExternal(this.latDir, this.projectRoot, target, snapshot.external, snapshot.allSections, snapshot.references, this.options.publishable);
235
466
  }
236
467
  refresh(paths) {
237
468
  if (this.closed)
238
469
  return Promise.resolve();
239
- const normalized = paths.map((path) => path ? projectPath(this.projectRoot, path) : '');
470
+ const latPath = projectPath(this.projectRoot, this.latDir);
471
+ const normalized = paths
472
+ .map((path) => (path ? projectPath(this.projectRoot, path) : ''))
473
+ .filter((path) => !isInternalLatCachePath(path, latPath));
474
+ if (paths.length > 0 && normalized.length === 0) {
475
+ return Promise.resolve();
476
+ }
240
477
  return this.queueRefresh(normalized, false);
241
478
  }
242
479
  queueRefresh(paths, pollGit) {
@@ -254,13 +491,30 @@ export class ViewStore {
254
491
  this.gitPollTimer = null;
255
492
  this.watcher?.close();
256
493
  this.watcher = null;
494
+ for (const watcher of this.externalWatchers)
495
+ watcher.close();
496
+ this.externalWatchers = [];
497
+ await this.editTail;
257
498
  await this.refreshTail;
258
499
  this.listeners.clear();
259
500
  }
260
501
  scheduleRefresh(path) {
261
502
  if (this.closed)
262
503
  return;
263
- this.pendingPaths.add(path ? projectPath(this.projectRoot, path) : '');
504
+ if (path !== EXTERNAL_REFRESH_PATH &&
505
+ basename(path).startsWith(DOCUMENT_EDIT_TEMP_PREFIX) &&
506
+ path.endsWith('.tmp')) {
507
+ return;
508
+ }
509
+ const normalizedPath = path === EXTERNAL_REFRESH_PATH
510
+ ? path
511
+ : path
512
+ ? projectPath(this.projectRoot, path)
513
+ : '';
514
+ const latPath = projectPath(this.projectRoot, this.latDir);
515
+ if (isInternalLatCachePath(normalizedPath, latPath))
516
+ return;
517
+ this.pendingPaths.add(normalizedPath);
264
518
  if (this.debounceTimer)
265
519
  clearTimeout(this.debounceTimer);
266
520
  this.debounceTimer = setTimeout(() => {
@@ -300,12 +554,13 @@ export class ViewStore {
300
554
  }
301
555
  if (!isInside(this.realLatDir, realFile))
302
556
  return null;
303
- const content = await readFile(realFile, 'utf8');
304
- return parseViewMarkdownFile(absolutePath, content, this.latDir, this.projectRoot);
557
+ return analyzeMarkdownPath(absolutePath, this.latDir, this.projectRoot);
305
558
  }
306
559
  async applyRefresh(paths, pollGit) {
307
560
  const fullRefresh = paths.includes('');
308
561
  const latPath = projectPath(this.projectRoot, this.latDir);
562
+ const externalChanged = paths.includes(EXTERNAL_REFRESH_PATH) ||
563
+ paths.includes(`${latPath}/config.local.yaml`);
309
564
  const touchesMarkdown = fullRefresh ||
310
565
  paths.some((path) => path === latPath || path.startsWith(`${latPath}/`));
311
566
  let markdownFiles = new Map(this.snapshotValue.files);
@@ -380,7 +635,7 @@ export class ViewStore {
380
635
  paths.some((path) => path === '.gitignore' || path.endsWith('/.gitignore')) ||
381
636
  codePaths.some((path) => !this.codeScope.has(path) && !this.ignoredCodePaths.has(path));
382
637
  if (refreshCodeScope) {
383
- const nextCode = await scanCodeState(this.projectRoot, this.options.codeExcludePaths);
638
+ const nextCode = await scanCodeState(this.projectRoot, this.options.codeExcludePaths, this.options.publishable);
384
639
  codeFiles = nextCode.files;
385
640
  this.codeScope = nextCode.scope;
386
641
  this.ignoredCodePaths.clear();
@@ -419,10 +674,12 @@ export class ViewStore {
419
674
  if (!markdownChanged &&
420
675
  !codeChanged &&
421
676
  !gitChanged &&
422
- !linkedResourceChanged)
677
+ !linkedResourceChanged &&
678
+ !externalChanged)
423
679
  return;
424
680
  this.codeFiles = codeFiles;
425
- this.snapshotValue = await buildSnapshot(this.latDir, this.projectRoot, markdownFiles, codeFiles, git, this.snapshotValue.generation + 1, this.snapshotValue.markdownGeneration + (markdownChanged ? 1 : 0));
681
+ this.snapshotValue = await buildSnapshot(this.latDir, this.projectRoot, markdownFiles, codeFiles, git, this.snapshotValue.generation + 1, this.snapshotValue.markdownGeneration + (markdownChanged ? 1 : 0), this.options);
682
+ this.refreshExternalWatchers();
426
683
  const change = {
427
684
  generation: this.snapshotValue.generation,
428
685
  markdownGeneration: this.snapshotValue.markdownGeneration,
@@ -436,7 +693,7 @@ export async function createViewStore(latDir, projectRoot, options = {}) {
436
693
  const [realLatDir, markdownPaths, codeState, gitRepository] = await Promise.all([
437
694
  realpath(latDir),
438
695
  listLatticeFiles(latDir),
439
- scanCodeState(projectRoot, options.codeExcludePaths),
696
+ scanCodeState(projectRoot, options.codeExcludePaths, options.publishable),
440
697
  options.git === false
441
698
  ? Promise.resolve(null)
442
699
  : findViewGitRepository(projectRoot, latDir),
@@ -449,8 +706,7 @@ export async function createViewStore(latDir, projectRoot, options = {}) {
449
706
  const realFile = await realpath(absolutePath);
450
707
  if (!isInside(realLatDir, realFile))
451
708
  return;
452
- const content = await readFile(realFile, 'utf8');
453
- const parsed = parseViewMarkdownFile(absolutePath, content, latDir, projectRoot);
709
+ const parsed = await analyzeMarkdownPath(absolutePath, latDir, projectRoot);
454
710
  markdownFiles.set(parsed.path, parsed);
455
711
  }));
456
712
  if (markdownFiles.size === 0) {
@@ -465,7 +721,7 @@ export async function createViewStore(latDir, projectRoot, options = {}) {
465
721
  process.stderr.write(`lat ui git: ${error.message}\n`);
466
722
  }
467
723
  }
468
- const store = new ViewStore(latDir, projectRoot, realLatDir, await buildSnapshot(latDir, projectRoot, markdownFiles, codeState.files, git, 0, 0), codeState.files, codeState.scope, gitRepository, options);
724
+ const store = new ViewStore(latDir, projectRoot, realLatDir, await buildSnapshot(latDir, projectRoot, markdownFiles, codeState.files, git, 0, 0, options), codeState.files, codeState.scope, gitRepository, options);
469
725
  store.startWatching();
470
726
  return store;
471
727
  }
@@ -1,9 +1,9 @@
1
1
  import type { Root } from 'mdast';
2
- import { type Section } from '../lattice.js';
2
+ import { type Section } from '@plebeiantech/lat.md-core/lattice-model';
3
3
  import type { ViewDocumentError, ViewDocumentTocItem } from './protocol.js';
4
4
  export type ViewTableOfContentsOptions = {
5
5
  errors?: readonly ViewDocumentError[];
6
6
  gitTree?: Root | null;
7
7
  };
8
8
  /** Project rendered headings into the document's local navigation. */
9
- export declare function buildViewTableOfContents(sections: Section[], tree: Root, options?: ViewTableOfContentsOptions): ViewDocumentTocItem[];
9
+ export declare function buildViewTableOfContents(sections: Section[], titles: readonly string[], options?: ViewTableOfContentsOptions): ViewDocumentTocItem[];
@@ -1,20 +1,4 @@
1
- import { visit } from 'unist-util-visit';
2
- import { flattenSections } from '../lattice.js';
3
- function headingText(node) {
4
- if (!node || typeof node !== 'object')
5
- return '';
6
- const value = node;
7
- if (value.type === 'text' || value.type === 'inlineCode') {
8
- return value.value ?? '';
9
- }
10
- if (value.type === 'image' || value.type === 'imageReference') {
11
- return value.alt ?? '';
12
- }
13
- if (value.type === 'wikiLink') {
14
- return value.data?.alias ?? value.value ?? '';
15
- }
16
- return value.children?.map(headingText).join('') ?? '';
17
- }
1
+ import { flattenSections, } from '@plebeiantech/lat.md-core/lattice-model';
18
2
  function sectionAtLine(sections, line) {
19
3
  let owner = null;
20
4
  for (const section of sections) {
@@ -76,12 +60,8 @@ function gitChangedSections(sections, tree) {
76
60
  return changed;
77
61
  }
78
62
  /** Project rendered headings into the document's local navigation. */
79
- export function buildViewTableOfContents(sections, tree, options = {}) {
63
+ export function buildViewTableOfContents(sections, titles, options = {}) {
80
64
  const flatSections = flattenSections(sections);
81
- const titles = [];
82
- visit(tree, 'heading', (node) => {
83
- titles.push(headingText(node));
84
- });
85
65
  const errorCounts = new Map();
86
66
  for (const error of options.errors ?? []) {
87
67
  const owner = sectionAtLine(flatSections, error.line);
@@ -0,0 +1,24 @@
1
+ type FileTraceResult = {
2
+ fileList: Set<string>;
3
+ warnings: Set<Error>;
4
+ };
5
+ export type VercelBuildDependencies = {
6
+ traceFiles: (files: string[], options: {
7
+ base: string;
8
+ conditions: string[];
9
+ exportsOnly: boolean;
10
+ processCwd: string;
11
+ }) => Promise<FileTraceResult>;
12
+ };
13
+ export type VercelBuildOptions = {
14
+ force?: boolean;
15
+ warn?: (message: string) => void;
16
+ };
17
+ export type VercelBuildResult = {
18
+ files: number;
19
+ functionPath: string;
20
+ outputDir: string;
21
+ };
22
+ /** Convert an installed portable Lat UI server into Vercel Build Output API v3. */
23
+ export declare function buildVercelOutput(requestedArtifact: string, requestedOutput?: string, options?: VercelBuildOptions, dependencies?: VercelBuildDependencies): Promise<VercelBuildResult>;
24
+ export {};