@plebeiantech/lat.md 0.12.3-fork.2 → 0.12.3-fork.20

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 (341) hide show
  1. package/README.md +31 -2
  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/comment-guard.d.ts +14 -0
  7. package/dist/src/cli/comment-guard.js +10 -33
  8. package/dist/src/cli/comment-reminder.d.ts +65 -6
  9. package/dist/src/cli/comment-reminder.js +164 -28
  10. package/dist/src/cli/fork-instructions.d.ts +20 -0
  11. package/dist/src/cli/fork-instructions.js +184 -0
  12. package/dist/src/cli/fork-scaffold.d.ts +106 -0
  13. package/dist/src/cli/fork-scaffold.js +490 -0
  14. package/dist/src/cli/graph.d.ts +1 -1
  15. package/dist/src/cli/hook.d.ts +26 -0
  16. package/dist/src/cli/hook.js +118 -46
  17. package/dist/src/cli/index.js +166 -64
  18. package/dist/src/cli/init-preferences.d.ts +4 -0
  19. package/dist/src/cli/init-preferences.js +36 -0
  20. package/dist/src/cli/init.d.ts +2 -1
  21. package/dist/src/cli/init.js +107 -50
  22. package/dist/src/cli/reindex.d.ts +1 -1
  23. package/dist/src/cli/reindex.js +7 -10
  24. package/dist/src/cli/search.d.ts +14 -4
  25. package/dist/src/cli/search.js +116 -100
  26. package/dist/src/cli/ui-build-server.d.ts +12 -0
  27. package/dist/src/cli/ui-build-server.js +26 -0
  28. package/dist/src/cli/ui-build.d.ts +4 -0
  29. package/dist/src/cli/ui-build.js +13 -0
  30. package/dist/src/cli/ui.d.ts +1 -1
  31. package/dist/src/cli/ui.js +18 -2
  32. package/dist/src/fork/antigravity-hook.d.ts +47 -0
  33. package/dist/src/fork/antigravity-hook.js +424 -0
  34. package/dist/src/fork/antigravity-init.d.ts +17 -0
  35. package/dist/src/fork/antigravity-init.js +124 -0
  36. package/dist/src/fork/upstream-drift-cli.js +2 -0
  37. package/dist/src/fork/upstream-drift.d.ts +26 -0
  38. package/dist/src/fork/upstream-drift.js +185 -0
  39. package/dist/src/fork/upstream-guard-cli.d.ts +1 -0
  40. package/dist/src/fork/upstream-guard-cli.js +2 -0
  41. package/dist/src/fork/upstream-guard.d.ts +72 -0
  42. package/dist/src/fork/upstream-guard.js +445 -0
  43. package/dist/src/graph-export.d.ts +2 -0
  44. package/dist/src/graph-export.js +38 -19
  45. package/dist/src/knowledge/claude-memory.d.ts +1 -0
  46. package/dist/src/knowledge/claude-memory.js +33 -4
  47. package/dist/src/knowledge/index.js +2 -2
  48. package/dist/src/mcp/server.js +34 -18
  49. package/dist/src/search/cache.d.ts +3 -0
  50. package/dist/src/search/cache.js +104 -0
  51. package/dist/src/search/chunks.d.ts +23 -0
  52. package/dist/src/search/chunks.js +197 -0
  53. package/dist/src/search/db.d.ts +28 -16
  54. package/dist/src/search/db.js +106 -40
  55. package/dist/src/search/embedder.d.ts +2 -1
  56. package/dist/src/search/embedder.js +7 -6
  57. package/dist/src/search/index.d.ts +6 -2
  58. package/dist/src/search/index.js +176 -53
  59. package/dist/src/search/lexical.d.ts +6 -0
  60. package/dist/src/search/lexical.js +36 -0
  61. package/dist/src/search/lock.d.ts +5 -0
  62. package/dist/src/search/lock.js +45 -0
  63. package/dist/src/search/query.d.ts +26 -0
  64. package/dist/src/search/query.js +103 -0
  65. package/dist/src/search/search.d.ts +17 -7
  66. package/dist/src/search/search.js +164 -14
  67. package/dist/src/search/types.d.ts +15 -0
  68. package/dist/src/search/types.js +1 -0
  69. package/dist/src/view/client/assets/GraphView-Dij8mAA_.js +456 -0
  70. package/dist/src/view/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  71. package/dist/src/view/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  72. package/dist/src/view/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  73. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  74. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  75. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  76. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  77. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  78. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  79. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  80. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  81. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  82. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  83. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  84. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  85. package/dist/src/view/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  86. package/dist/src/view/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  87. package/dist/src/view/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  88. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  89. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  90. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  91. package/dist/src/view/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  92. package/dist/src/view/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  93. package/dist/src/view/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  94. package/dist/src/view/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  95. package/dist/src/view/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  96. package/dist/src/view/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  97. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  98. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  99. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  100. package/dist/src/view/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  101. package/dist/src/view/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  102. package/dist/src/view/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  103. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  104. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  105. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  106. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  107. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  108. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  109. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  110. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  111. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  112. package/dist/src/view/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  113. package/dist/src/view/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  114. package/dist/src/view/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  115. package/dist/src/view/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  116. package/dist/src/view/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  117. package/dist/src/view/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  118. package/dist/src/view/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  119. package/dist/src/view/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  120. package/dist/src/view/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  121. package/dist/src/view/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  122. package/dist/src/view/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  123. package/dist/src/view/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  124. package/dist/src/view/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  125. package/dist/src/view/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  126. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  127. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  128. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  129. package/dist/src/view/client/assets/MarkdownEditor-88Wbt0M1.js +28 -0
  130. package/dist/src/view/client/assets/OrbitControls-DwcpQNja.js +1 -0
  131. package/dist/src/view/client/assets/STLLoader-CLWTKt5i.js +1 -0
  132. package/dist/src/view/client/assets/_commonjsHelpers-CqkleIqs.js +1 -0
  133. package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-y0DlYa8E.js +1 -0
  134. package/dist/src/view/client/assets/arc-FlMu8dnO.js +1 -0
  135. package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-DA_uWZW1.js +36 -0
  136. package/dist/src/view/client/assets/blockDiagram-I7D4REHJ-BHQ5LU85.js +129 -0
  137. package/dist/src/view/client/assets/c4Diagram-7LVT6UL2-BRucKCt2.js +38 -0
  138. package/dist/src/view/client/assets/channel-BgDNA_Ay.js +1 -0
  139. package/dist/src/view/client/assets/chunk-2Q5K7J3B-BJPcFivt.js +1 -0
  140. package/dist/src/view/client/assets/chunk-5VM5RSS4-v2q99bGz.js +15 -0
  141. package/dist/src/view/client/assets/chunk-F27PBJKO-CcHOuJCs.js +1 -0
  142. package/dist/src/view/client/assets/chunk-IMKFNOWR-DNxYuJNq.js +231 -0
  143. package/dist/src/view/client/assets/chunk-JWPE2WC7-C0eHKvLW.js +1 -0
  144. package/dist/src/view/client/assets/chunk-POPQ4Y6H-57CWp2Ve.js +1 -0
  145. package/dist/src/view/client/assets/chunk-SVP7TREG-BqcoxIJw.js +88 -0
  146. package/dist/src/view/client/assets/chunk-TICWLB2K-DRUJR5zH.js +206 -0
  147. package/dist/src/view/client/assets/chunk-XXDRQBXY-Dez0oRoM.js +1 -0
  148. package/dist/src/view/client/assets/classDiagram-ZZMXUADV-CFZ_Sgh5.js +1 -0
  149. package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-CFZ_Sgh5.js +1 -0
  150. package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-BHtud6Hg.js +1 -0
  151. package/dist/src/view/client/assets/cynefin-OW5HDTMX-BjBW8VGk.js +166 -0
  152. package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-DwGuD7oF.js +62 -0
  153. package/dist/src/view/client/assets/cytoscape.esm-DzSz-X2X.js +321 -0
  154. package/dist/src/view/client/assets/dagre-GXQ25YYZ-C5zSlGK9.js +4 -0
  155. package/dist/src/view/client/assets/defaultLocale-DX6XiGOO.js +1 -0
  156. package/dist/src/view/client/assets/diagram-S7CK7UJ4-C_NhA3bj.js +30 -0
  157. package/dist/src/view/client/assets/diagram-UQ7AKVKN-az7QPYNb.js +41 -0
  158. package/dist/src/view/client/assets/diagram-VSXAHHWV-BRvDuM8_.js +3 -0
  159. package/dist/src/view/client/assets/diagram-VX7I27RA-BWLgF6S-.js +24 -0
  160. package/dist/src/view/client/assets/diagram-Z3DM3KII-DV3d6mL5.js +24 -0
  161. package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-yUXrEAvK.js +1 -0
  162. package/dist/src/view/client/assets/erDiagram-RLTQ6QDP-D35FN1Pt.js +99 -0
  163. package/dist/src/view/client/assets/flowDiagram-HODETNUW-BciZqsjT.js +168 -0
  164. package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-BysPGgXS.js +292 -0
  165. package/dist/src/view/client/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  166. package/dist/src/view/client/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  167. package/dist/src/view/client/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  168. package/dist/src/view/client/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  169. package/dist/src/view/client/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
  170. package/dist/src/view/client/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
  171. package/dist/src/view/client/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
  172. package/dist/src/view/client/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
  173. package/dist/src/view/client/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
  174. package/dist/src/view/client/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
  175. package/dist/src/view/client/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  176. package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-C3DdJ5xG.js +106 -0
  177. package/dist/src/view/client/assets/index-BnENo9bV.js +1 -0
  178. package/dist/src/view/client/assets/index-CJokoRSp.js +13 -0
  179. package/dist/src/view/client/assets/index-DG0Ez15D.css +1 -0
  180. package/dist/src/view/client/assets/infoDiagram-27XIBGKW-D3HZrDRb.js +2 -0
  181. package/dist/src/view/client/assets/init-Gi6I4Gst.js +1 -0
  182. package/dist/src/view/client/assets/ishikawaDiagram-5VMMS53U-BXyVIXTU.js +70 -0
  183. package/dist/src/view/client/assets/journeyDiagram-3NMN7TZE-D4-1NxVU.js +139 -0
  184. package/dist/src/view/client/assets/kanban-definition-UXKFOSKX-4Gu_5yBA.js +89 -0
  185. package/dist/src/view/client/assets/katex-HP8lGamR.js +257 -0
  186. package/dist/src/view/client/assets/layout-Jf1K3TMM.js +1 -0
  187. package/dist/src/view/client/assets/linear-DWfwzUT_.js +1 -0
  188. package/dist/src/view/client/assets/logo-RR_KBOAT.svg +149 -0
  189. package/dist/src/view/client/assets/maplibre-gl-CDX6Zuow.js +800 -0
  190. package/dist/src/view/client/assets/mermaid.core-DMx_DAl8.js +310 -0
  191. package/dist/src/view/client/assets/mindmap-definition-YA3MSWOX-8pxY_RWi.js +96 -0
  192. package/dist/src/view/client/assets/ordinal-Cboi1Yqb.js +1 -0
  193. package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-DNAw_O5t.js +1 -0
  194. package/dist/src/view/client/assets/pieDiagram-E7YTZNPT-uuvRCDkC.js +39 -0
  195. package/dist/src/view/client/assets/quadrantDiagram-AXDQQJYC-BER2O4Aq.js +7 -0
  196. package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-CxEsJ_0n.js +1 -0
  197. package/dist/src/view/client/assets/requirementDiagram-BXWQKSXE-yS9rspca.js +84 -0
  198. package/dist/src/view/client/assets/sankeyDiagram-P5KCCOFB-Bqt70a2j.js +40 -0
  199. package/dist/src/view/client/assets/sequenceDiagram-WJ2MYXX4-BvOOEJNr.js +162 -0
  200. package/dist/src/view/client/assets/sizeCapture-INFHLROL-CvO_Pjjo.js +1 -0
  201. package/dist/src/view/client/assets/stateDiagram-D77RDMKH-KLmVOZkq.js +1 -0
  202. package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-KCS8Mdzu.js +1 -0
  203. package/dist/src/view/client/assets/swimlanes-42K2YHIH-DC1r4_sq.js +1 -0
  204. package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-B2TcAwis.js +8 -0
  205. package/dist/src/view/client/assets/three.module-PDSP0dbZ.js +4108 -0
  206. package/dist/src/view/client/assets/timeline-definition-24CTP7MA-ChXLOuBL.js +120 -0
  207. package/dist/src/view/client/assets/vennDiagram-4TSXK5OY-D9_h25-Y.js +34 -0
  208. package/dist/src/view/client/assets/wardleyDiagram-VM6X3IG4-CsQJGGW0.js +78 -0
  209. package/dist/src/view/client/assets/xychartDiagram-S5SC5T6Z-DGMuPMlm.js +7 -0
  210. package/dist/src/view/client/index.html +2 -2
  211. package/dist/src/view/client-shell.d.ts +2 -0
  212. package/dist/src/view/client-shell.js +5 -0
  213. package/dist/src/view/diagnostics.d.ts +3 -2
  214. package/dist/src/view/diagnostics.js +49 -58
  215. package/dist/src/view/document-edit.d.ts +8 -0
  216. package/dist/src/view/document-edit.js +25 -0
  217. package/dist/src/view/document-route.d.ts +14 -0
  218. package/dist/src/view/document-route.js +126 -0
  219. package/dist/src/view/document-tree.d.ts +18 -0
  220. package/dist/src/view/document-tree.js +139 -0
  221. package/dist/src/view/external-document-tree.d.ts +3 -0
  222. package/dist/src/view/external-document-tree.js +674 -0
  223. package/dist/src/view/git-diff.js +205 -1
  224. package/dist/src/view/git.js +1 -1
  225. package/dist/src/view/graph.d.ts +7 -0
  226. package/dist/src/view/graph.js +267 -0
  227. package/dist/src/view/highlight.d.ts +10 -2
  228. package/dist/src/view/highlight.js +4547 -1363
  229. package/dist/src/view/markdown.d.ts +8 -3
  230. package/dist/src/view/markdown.js +308 -41
  231. package/dist/src/view/preindexed-search.d.ts +15 -0
  232. package/dist/src/view/preindexed-search.js +25 -0
  233. package/dist/src/view/protocol.d.ts +95 -6
  234. package/dist/src/view/protocol.js +1 -1
  235. package/dist/src/view/publication.d.ts +2 -0
  236. package/dist/src/view/publication.js +78 -0
  237. package/dist/src/view/references.d.ts +13 -26
  238. package/dist/src/view/references.js +150 -119
  239. package/dist/src/view/repository.d.ts +18 -5
  240. package/dist/src/view/repository.js +269 -27
  241. package/dist/src/view/request-security.d.ts +5 -0
  242. package/dist/src/view/request-security.js +46 -0
  243. package/dist/src/view/search-result.d.ts +4 -0
  244. package/dist/src/view/search-result.js +25 -0
  245. package/dist/src/view/search.d.ts +7 -2
  246. package/dist/src/view/search.js +23 -33
  247. package/dist/src/view/server-build.d.ts +21 -0
  248. package/dist/src/view/server-build.js +145 -0
  249. package/dist/src/view/server-deployment.d.ts +31 -0
  250. package/dist/src/view/server-deployment.js +94 -0
  251. package/dist/src/view/server-index-worker.d.ts +6 -0
  252. package/dist/src/view/server-index-worker.js +14 -0
  253. package/dist/src/view/server.d.ts +14 -2
  254. package/dist/src/view/server.js +254 -51
  255. package/dist/src/view/source-target.d.ts +10 -0
  256. package/dist/src/view/source-target.js +43 -0
  257. package/dist/src/view/static-build.d.ts +32 -0
  258. package/dist/src/view/static-build.js +741 -0
  259. package/dist/src/view/static-protocol.d.ts +47 -0
  260. package/dist/src/view/static-protocol.js +15 -0
  261. package/dist/src/view/store.d.ts +26 -3
  262. package/dist/src/view/store.js +325 -44
  263. package/dist/src/view/table-of-contents.d.ts +9 -0
  264. package/dist/src/view/table-of-contents.js +83 -0
  265. package/dist/src/view/vercel-build.d.ts +24 -0
  266. package/dist/src/view/vercel-build.js +140 -0
  267. package/dist/src/view/vercel-server-build.d.ts +10 -0
  268. package/dist/src/view/vercel-server-build.js +61 -0
  269. package/dist/vendor/lat.md-server/cli.d.ts +2 -0
  270. package/dist/vendor/lat.md-server/cli.js +12 -0
  271. package/dist/vendor/lat.md-server/index.d.ts +38 -0
  272. package/dist/vendor/lat.md-server/index.js +128 -0
  273. package/package.json +72 -25
  274. package/plugins/lat-md/README.md +61 -0
  275. package/plugins/lat-md/hooks.json +38 -0
  276. package/plugins/lat-md/plugin.json +9 -0
  277. package/plugins/lat-md/rules/AGENTS.md +118 -0
  278. package/plugins/lat-md/skills/lat-md/SKILL.md +178 -0
  279. package/plugins/lat-md/skills/lat-md-conventions/SKILL.md +182 -0
  280. package/templates/AGENTS.md +19 -18
  281. package/templates/cursor-rules.md +14 -5
  282. package/templates/fork/conventions.md +173 -0
  283. package/templates/opencode-plugin.ts +9 -9
  284. package/templates/pi-extension.ts +11 -11
  285. package/templates/skill/SKILL.md +28 -17
  286. package/dist/src/cli/check-frontmatter.d.ts +0 -12
  287. package/dist/src/cli/check-frontmatter.js +0 -44
  288. package/dist/src/cli/check-mode.d.ts +0 -6
  289. package/dist/src/cli/check-mode.js +0 -303
  290. package/dist/src/cli/check-status.d.ts +0 -74
  291. package/dist/src/cli/check-status.js +0 -217
  292. package/dist/src/cli/check.d.ts +0 -45
  293. package/dist/src/cli/check.js +0 -777
  294. package/dist/src/cli/context.d.ts +0 -11
  295. package/dist/src/cli/context.js +0 -58
  296. package/dist/src/cli/expand.d.ts +0 -8
  297. package/dist/src/cli/expand.js +0 -94
  298. package/dist/src/cli/gen-index.d.ts +0 -45
  299. package/dist/src/cli/gen-index.js +0 -235
  300. package/dist/src/cli/link-scheme.d.ts +0 -54
  301. package/dist/src/cli/link-scheme.js +0 -101
  302. package/dist/src/cli/locate.d.ts +0 -2
  303. package/dist/src/cli/locate.js +0 -17
  304. package/dist/src/cli/refs.d.ts +0 -22
  305. package/dist/src/cli/refs.js +0 -229
  306. package/dist/src/cli/section.d.ts +0 -43
  307. package/dist/src/cli/section.js +0 -252
  308. package/dist/src/cli/select-menu.d.ts +0 -13
  309. package/dist/src/cli/select-menu.js +0 -100
  310. package/dist/src/code-refs.d.ts +0 -17
  311. package/dist/src/code-refs.js +0 -277
  312. package/dist/src/config.d.ts +0 -29
  313. package/dist/src/config.js +0 -83
  314. package/dist/src/context.d.ts +0 -23
  315. package/dist/src/context.js +0 -11
  316. package/dist/src/extensions/wiki-link/from-markdown.d.ts +0 -5
  317. package/dist/src/extensions/wiki-link/from-markdown.js +0 -34
  318. package/dist/src/extensions/wiki-link/index.d.ts +0 -4
  319. package/dist/src/extensions/wiki-link/index.js +0 -3
  320. package/dist/src/extensions/wiki-link/syntax.d.ts +0 -14
  321. package/dist/src/extensions/wiki-link/syntax.js +0 -121
  322. package/dist/src/extensions/wiki-link/to-markdown.d.ts +0 -5
  323. package/dist/src/extensions/wiki-link/to-markdown.js +0 -28
  324. package/dist/src/extensions/wiki-link/types.d.ts +0 -34
  325. package/dist/src/format.d.ts +0 -8
  326. package/dist/src/format.js +0 -43
  327. package/dist/src/init-version.d.ts +0 -10
  328. package/dist/src/init-version.js +0 -49
  329. package/dist/src/lattice.d.ts +0 -108
  330. package/dist/src/lattice.js +0 -816
  331. package/dist/src/parser.d.ts +0 -3
  332. package/dist/src/parser.js +0 -18
  333. package/dist/src/source-parser.d.ts +0 -27
  334. package/dist/src/source-parser.js +0 -916
  335. package/dist/src/untrusted.d.ts +0 -24
  336. package/dist/src/untrusted.js +0 -97
  337. package/dist/src/view/client/assets/index-B0n0u03y.css +0 -1
  338. package/dist/src/view/client/assets/index-xm2_px4q.js +0 -23
  339. package/dist/src/walk.d.ts +0 -18
  340. package/dist/src/walk.js +0 -27
  341. /package/dist/src/{extensions/wiki-link/types.js → fork/upstream-drift-cli.d.ts} +0 -0
@@ -1,17 +1,23 @@
1
1
  import { execSync } from 'node:child_process';
2
- import { dirname, extname } from 'node:path';
3
- import { findLatticeDir, loadAllSections, findSections, } from '../lattice.js';
4
- import { plainStyler } from '../context.js';
5
- import { expandPrompt } from './expand.js';
2
+ import { lstatSync, readFileSync } from 'node:fs';
3
+ import { dirname, extname, join } from 'node:path';
4
+ import { findLatticeDir } from '@plebeiantech/lat.md-core/project-discovery';
5
+ import { findSections } from '@plebeiantech/lat.md-core/lattice-model';
6
+ import { plainStyler, } from '@plebeiantech/lat.md-core/context';
7
+ import { expandPrompt } from '@plebeiantech/lat.md-core/cli/expand';
6
8
  import { runSearch } from './search.js';
7
- import { getSection, formatSectionOutput } from './section.js';
8
- import { checkMd, checkCodeRefs, checkIndex, checkSections } from './check.js';
9
- import { checkMode } from './check-mode.js';
10
- import { SOURCE_EXTENSIONS } from '../source-parser.js';
9
+ import { DEFAULT_SEARCH_LIMIT } from '../search/search.js';
10
+ import { getSection, formatSectionOutput, } from '@plebeiantech/lat.md-core/cli/section';
11
+ import { checkMd, checkCodeRefs, checkIndex, checkSections, } from '@plebeiantech/lat.md-core/cli/check';
12
+ import { CheckRunContext } from '@plebeiantech/lat.md-core/cli/check-context';
13
+ import { isSourceFileExtension } from '@plebeiantech/lat.md-core/source-formats';
14
+ import { commandProjectAnalysis } from '@plebeiantech/lat.md-core/project-analysis';
15
+ import { checkMode } from '@plebeiantech/lat.md-core/cli/check-mode';
11
16
  import { federateTags, taggedDocsForFiles } from '../knowledge/index.js';
12
17
  import { loadSessionMarkers, saveSessionMarkers, } from '../knowledge/session.js';
13
18
  import { computeCommentReminder, } from './comment-reminder.js';
14
19
  import { handlePreToolUse } from './comment-guard.js';
20
+ import { handleAntigravityHook } from '../fork/antigravity-hook.js';
15
21
  function outputPromptSubmit(context) {
16
22
  process.stdout.write(JSON.stringify({
17
23
  hookSpecificOutput: {
@@ -64,15 +70,15 @@ function makeHookCtx(latDir) {
64
70
  mode: 'cli',
65
71
  };
66
72
  }
67
- async function searchAndExpand(ctx, userPrompt, preloadedSections) {
73
+ async function searchAndExpand(ctx, userPrompt) {
68
74
  let result;
69
75
  try {
70
76
  // Read-only: search an existing index but never build/update it here. A fresh
71
77
  // repo's first prompt must not trigger a full local embed pass — that's what
72
78
  // `lat search` / `lat reindex` are for. Returns no matches until then.
73
- result = await runSearch(ctx.latDir, userPrompt, 5, undefined, {
79
+ result = await runSearch(ctx.latDir, userPrompt, DEFAULT_SEARCH_LIMIT, undefined, {
74
80
  buildIndex: false,
75
- preloadedSections,
81
+ project: await commandProjectAnalysis(ctx),
76
82
  });
77
83
  }
78
84
  catch {
@@ -109,17 +115,18 @@ async function handleUserPromptSubmit() {
109
115
  // If we can't parse stdin, still emit the reminder
110
116
  }
111
117
  const parts = [];
112
- parts.push("Before starting work, run `lat search` with one or more queries describing the user's intent.", 'ALWAYS do this, even when the task seems straightforward — search results may reveal critical design details, protocols, or constraints.', 'Use `lat section` to read the full content of relevant matches.', 'Do not read files, write code, or run commands until you have searched.', '', 'Remember: `lat.md/` must stay in sync with meaningful codebase state. If you change behavior, architecture, tests, or planned work, update the relevant current-state sections and run `lat check` before finishing. Do not use `lat.md/` as a journal/changelog or add notes for insignificant details.');
118
+ parts.push("Before starting work, run `lat search` with one or more queries describing the user's intent.", 'ALWAYS do this, even when the task seems straightforward — search results may reveal critical design details, protocols, or constraints.', 'Use `lat section` to read the full content of relevant matches.', 'Do not read files, write code, or run commands until you have searched.', '', 'Remember: `lat.md/` must stay in sync with meaningful codebase state. If you change implemented behavior, architecture, or tests, update the relevant current-state sections and run `lat check` before finishing. Plans may be drafted in `lat.md/` alongside implementation, with the intent that by commit time they describe what was implemented. Otherwise, keep proposals, hypothetical designs, and future work outside `lat.md/` unless the user explicitly requests them there. Do not use `lat.md/` as a journal/changelog or add notes for insignificant details.');
113
119
  const latDir = findLatticeDir();
114
120
  if (latDir && userPrompt) {
115
121
  const ctx = makeHookCtx(latDir);
116
- // Loaded once and threaded through expansion, search, and federation
117
- // below — each of those otherwise walks and parses the whole tree itself.
118
- const allSections = await loadAllSections(latDir);
122
+ // Parsed once for expansion, search, and federation below. The analysis is
123
+ // memoised on `ctx`, so passing that one object everywhere is what keeps
124
+ // the three of them from walking and parsing the tree three times.
125
+ const { allSections } = await commandProjectAnalysis(ctx);
119
126
  // If the user prompt contains [[refs]], resolve them inline
120
127
  if (hasWikiLinks(userPrompt)) {
121
128
  try {
122
- const expanded = await expandPrompt(ctx, userPrompt, allSections);
129
+ const expanded = await expandPrompt(ctx, userPrompt);
123
130
  if (expanded) {
124
131
  parts.push('', 'Expanded user prompt with resolved [[refs]]:', expanded);
125
132
  }
@@ -134,7 +141,7 @@ async function handleUserPromptSubmit() {
134
141
  // Search for relevant sections and include their full content
135
142
  let searchFilePaths = [];
136
143
  try {
137
- const searchContext = await searchAndExpand(ctx, userPrompt, allSections);
144
+ const searchContext = await searchAndExpand(ctx, userPrompt);
138
145
  searchFilePaths = searchContext.filePaths;
139
146
  if (searchContext.text) {
140
147
  parts.push('', searchContext.text);
@@ -252,55 +259,116 @@ const DIFF_THRESHOLD = 5;
252
259
  const LATMD_RATIO = 0.05;
253
260
  /** If lat.md/ changes exceed this many lines, skip the ratio check entirely. */
254
261
  const LATMD_UPPER_THRESHOLD = 50;
255
- /** Run `git diff --numstat` and return { codeLines, latMdLines }. */
256
- function analyzeDiff(projectRoot) {
257
- let output;
262
+ function diffFileKind(file) {
263
+ if (file.startsWith('lat.md/'))
264
+ return 'latMd';
265
+ if (isSourceFileExtension(extname(file)))
266
+ return 'code';
267
+ return null;
268
+ }
269
+ /** Count a regular text file's lines as additions, matching Git numstat. */
270
+ function countUntrackedFileLines(projectRoot, file) {
258
271
  try {
259
- output = execSync('git diff HEAD --numstat', {
260
- cwd: projectRoot,
261
- encoding: 'utf-8',
262
- timeout: 2000,
263
- });
272
+ const path = join(projectRoot, file);
273
+ if (!lstatSync(path).isFile())
274
+ return 0;
275
+ const text = readFileSync(path, 'utf-8');
276
+ if (text.length === 0)
277
+ return 0;
278
+ return text.split('\n').length - (text.endsWith('\n') ? 1 : 0);
264
279
  }
265
280
  catch {
266
- return { codeLines: 0, latMdLines: 0 };
281
+ return 0;
267
282
  }
283
+ }
284
+ /**
285
+ * Measure code vs `lat.md/` churn since HEAD, in lines. Combines tracked
286
+ * changes (`git diff HEAD --numstat`) with untracked files
287
+ * (`git ls-files --others --exclude-standard -z`). Counting untracked files is
288
+ * what makes a freshly scaffolded, never-committed `lat.md/` register as
289
+ * updated — otherwise its edits are invisible to `git diff HEAD` and the sync
290
+ * reminder fires on every turn until `lat.md/` is committed (issue #61).
291
+ * Both scans are scoped and made relative to `projectRoot`, so a Lat project
292
+ * nested in a larger worktree neither misses its own `lat.md/` paths nor counts
293
+ * changes from sibling projects.
294
+ * Outside a Git worktree both scans contribute zero churn by design: Git is
295
+ * optional, so the hook still validates the project but skips the sync ratio.
296
+ */
297
+ export function analyzeDiff(projectRoot) {
268
298
  let codeLines = 0;
269
299
  let latMdLines = 0;
270
- // Each line: "added\tremoved\tfile" (e.g. "42\t11\tsrc/cli/hook.ts")
271
- for (const line of output.split('\n')) {
272
- const parts = line.split('\t');
273
- if (parts.length < 3)
274
- continue;
275
- const added = parseInt(parts[0], 10) || 0;
276
- const removed = parseInt(parts[1], 10) || 0;
277
- const file = parts[2];
278
- const changed = added + removed;
279
- if (file.startsWith('lat.md/')) {
300
+ const tally = (kind, changed) => {
301
+ if (kind === 'latMd') {
280
302
  latMdLines += changed;
281
303
  }
282
- else if (SOURCE_EXTENSIONS.has(extname(file))) {
304
+ else {
283
305
  codeLines += changed;
284
306
  }
307
+ };
308
+ // Tracked changes vs HEAD. Throws when there is no HEAD yet (a repo with no
309
+ // commits) or no repo at all; the untracked scan below still runs.
310
+ try {
311
+ const output = execSync('git diff HEAD --numstat --relative -- .', {
312
+ cwd: projectRoot,
313
+ encoding: 'utf-8',
314
+ stdio: ['ignore', 'pipe', 'ignore'],
315
+ });
316
+ // Each line: "added\tremoved\tfile" (e.g. "42\t11\tsrc/cli/hook.ts")
317
+ for (const line of output.split('\n')) {
318
+ const parts = line.split('\t');
319
+ if (parts.length < 3)
320
+ continue;
321
+ const added = parseInt(parts[0], 10) || 0;
322
+ const removed = parseInt(parts[1], 10) || 0;
323
+ const kind = diffFileKind(parts[2]);
324
+ if (kind)
325
+ tally(kind, added + removed);
326
+ }
327
+ }
328
+ catch {
329
+ // Not a git repo, or no HEAD — fall through to the untracked scan.
330
+ }
331
+ // NUL-delimited output preserves spaces, non-ASCII names, and newlines.
332
+ // Classify paths before reading so unrelated untracked files are never read.
333
+ try {
334
+ const output = execSync('git ls-files --others --exclude-standard -z -- .', {
335
+ cwd: projectRoot,
336
+ encoding: 'utf-8',
337
+ stdio: ['ignore', 'pipe', 'ignore'],
338
+ });
339
+ for (const file of output.split('\0')) {
340
+ if (!file)
341
+ continue;
342
+ const kind = diffFileKind(file);
343
+ if (!kind)
344
+ continue;
345
+ tally(kind, countUntrackedFileLines(projectRoot, file));
346
+ }
347
+ }
348
+ catch {
349
+ // Not a Git repo — diff-based sync analysis is intentionally disabled.
285
350
  }
286
351
  return { codeLines, latMdLines };
287
352
  }
288
- async function getStopStatus(latDir) {
289
- const md = await checkMd(latDir);
290
- const code = await checkCodeRefs(latDir);
291
- const indexErrors = await checkIndex(latDir);
292
- const sectionErrors = await checkSections(latDir);
353
+ export async function getStopStatus(latDir) {
354
+ const projectRoot = dirname(latDir);
355
+ const run = new CheckRunContext(latDir, projectRoot);
293
356
  // Must stay in step with `checkAllCommand` in check.ts. A check counted
294
357
  // there but not here lets the Stop hook call a failing tree clean, which
295
358
  // silently disables the very enforcement the check was added for.
296
- const modeErrors = await checkMode(latDir);
359
+ const [md, code, indexErrors, sectionErrors, modeErrors] = await Promise.all([
360
+ checkMd(latDir, projectRoot, run),
361
+ checkCodeRefs(latDir, projectRoot, run),
362
+ checkIndex(latDir, run),
363
+ checkSections(latDir, projectRoot, run),
364
+ checkMode(latDir, projectRoot),
365
+ ]);
297
366
  const totalErrors = md.errors.length +
298
367
  code.errors.length +
299
368
  indexErrors.length +
300
369
  sectionErrors.length +
301
370
  modeErrors.length;
302
371
  const checkFailed = totalErrors > 0;
303
- const projectRoot = dirname(latDir);
304
372
  const { codeLines, latMdLines } = analyzeDiff(projectRoot);
305
373
  let needsSync = false;
306
374
  if (codeLines >= DIFF_THRESHOLD && latMdLines < LATMD_UPPER_THRESHOLD) {
@@ -315,7 +383,7 @@ async function getStopStatus(latDir) {
315
383
  latMdLines,
316
384
  };
317
385
  }
318
- function formatStopReason({ checkFailed, totalErrors, needsSync, codeLines, latMdLines, }) {
386
+ export function formatStopReason({ checkFailed, totalErrors, needsSync, codeLines, latMdLines, }) {
319
387
  if (!checkFailed && !needsSync)
320
388
  return null;
321
389
  const parts = [];
@@ -425,8 +493,12 @@ export async function hookCmd(agent, event) {
425
493
  console.error(`Unknown hook event for cursor: ${event}. Supported: stop, postToolUse`);
426
494
  process.exit(1);
427
495
  }
496
+ case 'antigravity':
497
+ case 'gemini':
498
+ await handleAntigravityHook(event);
499
+ return;
428
500
  default:
429
- console.error(`Unknown agent: ${agent}. Supported: claude, codex, cursor`);
501
+ console.error(`Unknown agent: ${agent}. Supported: claude, codex, cursor, antigravity, gemini`);
430
502
  process.exit(1);
431
503
  }
432
504
  }
@@ -1,15 +1,39 @@
1
1
  #!/usr/bin/env node
2
- // Suppress deprecation warnings from transitive dependencies unless --verbose
3
- if (!process.argv.includes('--verbose')) {
4
- process.noDeprecation = true;
2
+ import { Command, InvalidArgumentError } from 'commander';
3
+ import { handleResult, packageVersion, } from '@plebeiantech/lat.md-core/cli';
4
+ import { resolveContext } from '@plebeiantech/lat.md-core/cli/context';
5
+ import { DEFAULT_SEARCH_LIMIT, DEFAULT_MIN_SIMILARITY, } from '../search/search.js';
6
+ function parsePort(value) {
7
+ if (!/^\d+$/.test(value)) {
8
+ throw new InvalidArgumentError('port must be an integer from 1 to 65535');
9
+ }
10
+ const port = Number(value);
11
+ if (port < 1 || port > 65_535) {
12
+ throw new InvalidArgumentError('port must be an integer from 1 to 65535');
13
+ }
14
+ return port;
15
+ }
16
+ function parseUiServerBuildTarget(value) {
17
+ if (value !== 'node' && value !== 'vercel') {
18
+ throw new InvalidArgumentError('target must be node or vercel');
19
+ }
20
+ return value;
21
+ }
22
+ function configureUiRun(command) {
23
+ return command
24
+ .option('--logo-text <text>', 'top-left logo text')
25
+ .option('--no-git', 'disable Git working-tree integration')
26
+ .option('--port <number>', 'server port (default: 4242; explicit ports are strict)', parsePort);
27
+ }
28
+ function parseSimilarityThreshold(value) {
29
+ const threshold = Number(value);
30
+ if (!Number.isFinite(threshold) || threshold < 0 || threshold > 1) {
31
+ throw new InvalidArgumentError('min-similarity must be a number from 0 to 1');
32
+ }
33
+ return threshold;
5
34
  }
6
- import { existsSync, readFileSync } from 'node:fs';
7
- import { dirname, join } from 'node:path';
8
- import { fileURLToPath } from 'node:url';
9
- import { Command } from 'commander';
10
- import { resolveCheckContext, resolveContext } from './context.js';
11
- /** Reserve `-- <directory>` for an explicit check target. */
12
- function splitCheckTarget(args) {
35
+ import { resolveCheckContext } from '@plebeiantech/lat.md-core/cli/context';
36
+ function splitCheckTarget(args, name) {
13
37
  let commandIndex = -1;
14
38
  for (let i = 0; i < args.length; i++) {
15
39
  const arg = args[i];
@@ -32,7 +56,7 @@ function splitCheckTarget(args) {
32
56
  return { args };
33
57
  const targets = args.slice(separatorIndex + 1);
34
58
  if (targets.length !== 1 || targets[0] === '') {
35
- console.error('error: `lat check --` expects exactly one directory after `--`');
59
+ console.error(`error: \`${name} check --\` expects exactly one directory after \`--\``);
36
60
  process.exit(1);
37
61
  }
38
62
  return {
@@ -40,45 +64,27 @@ function splitCheckTarget(args) {
40
64
  target: targets[0],
41
65
  };
42
66
  }
43
- const checkTargetArgs = splitCheckTarget(process.argv.slice(2));
44
- function findPackageJson() {
45
- let dir = dirname(fileURLToPath(import.meta.url));
46
- while (true) {
47
- const candidate = join(dir, 'package.json');
48
- try {
49
- return JSON.parse(readFileSync(candidate, 'utf-8')).version;
50
- }
51
- catch { }
52
- const parent = dirname(dir);
53
- if (parent === dir)
54
- return '0.0.0';
55
- dir = parent;
56
- }
57
- }
58
- function handleResult(result) {
59
- if (result.isError) {
60
- console.error(result.output);
61
- process.exit(1);
62
- }
63
- if (result.output)
64
- console.log(result.output);
65
- }
66
- const version = findPackageJson();
67
+ const checkTargetArgs = splitCheckTarget(process.argv.slice(2), 'lat');
67
68
  const program = new Command();
68
69
  program
69
70
  .name('lat')
71
+ .version(packageVersion(import.meta.url))
70
72
  .description('Anchor source code to high-level concepts defined in markdown')
71
- .version(version)
72
73
  .option('--dir <path>', 'project root to look for lat.md in (default: cwd)')
73
74
  .option('--no-color', 'disable color output')
74
75
  .option('--verbose', 'show deprecation warnings and extra diagnostics');
76
+ if (checkTargetArgs.args.includes('--verbose'))
77
+ process.noDeprecation = false;
78
+ else
79
+ process.noDeprecation = true;
80
+ const args = checkTargetArgs.args;
75
81
  program
76
82
  .command('locate')
77
- .description('Find sections by id')
78
- .argument('<query>', 'section id to search for')
83
+ .description('Find section(s) by name or text')
84
+ .argument('<query>', 'name or text to search for')
79
85
  .action(async (query) => {
80
86
  const ctx = resolveContext(program.opts());
81
- const { locateCommand } = await import('./locate.js');
87
+ const { locateCommand } = await import('@plebeiantech/lat.md-core/cli/locate');
82
88
  handleResult(await locateCommand(ctx, query));
83
89
  });
84
90
  program
@@ -87,16 +93,64 @@ program
87
93
  .argument('<query>', 'section id to look up')
88
94
  .action(async (query) => {
89
95
  const ctx = resolveContext(program.opts());
90
- const { sectionCommand } = await import('./section.js');
96
+ const { sectionCommand } = await import('@plebeiantech/lat.md-core/cli/section');
91
97
  handleResult(await sectionCommand(ctx, query));
92
98
  });
93
99
  program
94
- .command('ui')
95
- .description('Open lat.md in a local browser')
96
- .action(async () => {
100
+ .command('paths')
101
+ .description('Show configuration, cache, and temporary file locations')
102
+ .option('--config', 'show only the user configuration file path')
103
+ .action(async (options) => {
104
+ const { pathsCommand } = await import('@plebeiantech/lat.md-core/cli/paths');
105
+ console.log(pathsCommand({ ...program.opts(), ...options, search: true }));
106
+ });
107
+ async function runUi(opts) {
97
108
  const ctx = resolveContext(program.opts());
98
109
  const { uiCommand } = await import('./ui.js');
99
- handleResult(await uiCommand(ctx));
110
+ handleResult(await uiCommand(ctx, {
111
+ git: opts.git,
112
+ logoText: opts.logoText,
113
+ port: opts.port,
114
+ }));
115
+ }
116
+ const ui = configureUiRun(program.command('ui').description('Run or build the Lat UI')).action(runUi);
117
+ configureUiRun(ui.command('run').description('Run the local Lat UI server')).action(async (opts) => {
118
+ await runUi(opts);
119
+ });
120
+ const uiBuild = ui.command('build').description('Build a deployable Lat UI');
121
+ uiBuild
122
+ .command('static')
123
+ .description('Build a fully static, read-only Lat UI')
124
+ .argument('[output]', 'output directory relative to the project (default: .lat-build/static)', '.lat-build/static')
125
+ .option('--base <path>', 'deployment base path', '/')
126
+ .option('--force', 'replace an existing output path')
127
+ .option('--logo-text <text>', 'top-left logo text')
128
+ .action(async (output, opts) => {
129
+ const ctx = resolveContext(program.opts());
130
+ const { uiBuildCommand } = await import('./ui-build.js');
131
+ handleResult(await uiBuildCommand(ctx, output, {
132
+ basePath: opts.base,
133
+ force: opts.force,
134
+ logoText: opts.logoText ?? ui.opts().logoText,
135
+ }));
136
+ });
137
+ uiBuild
138
+ .command('server')
139
+ .description('Build a static Lat UI with a portable search server')
140
+ .argument('[output]', 'output directory (default: .lat-build/server for node, .vercel/output for vercel)')
141
+ .option('--base <path>', 'deployment base path', '/')
142
+ .option('--force', 'replace an existing output path')
143
+ .option('--logo-text <text>', 'top-left logo text')
144
+ .option('--target <target>', 'deployment target: node or vercel', parseUiServerBuildTarget, 'node')
145
+ .action(async (output, opts) => {
146
+ const ctx = resolveContext(program.opts());
147
+ const { uiBuildServerCommand } = await import('./ui-build-server.js');
148
+ handleResult(await uiBuildServerCommand(ctx, output, {
149
+ basePath: opts.base,
150
+ force: opts.force,
151
+ logoText: opts.logoText ?? ui.opts().logoText,
152
+ target: opts.target,
153
+ }));
100
154
  });
101
155
  program
102
156
  .command('refs')
@@ -110,18 +164,56 @@ program
110
164
  process.exit(1);
111
165
  }
112
166
  const ctx = resolveContext(program.opts());
113
- const { refsCommand } = await import('./refs.js');
167
+ const { refsCommand } = await import('@plebeiantech/lat.md-core/cli/refs');
114
168
  handleResult(await refsCommand(ctx, query, scope));
115
169
  });
170
+ const external = program
171
+ .command('external')
172
+ .description('Manage pinned external source repositories');
173
+ external
174
+ .command('add')
175
+ .argument('[handle]', 'stable external source handle')
176
+ .argument('[repo]', 'canonical HTTPS Git repository')
177
+ .option('--commit <commit-or-ref>', 'commit, branch, or tag to pin')
178
+ .option('--prefix <path>', 'repository path prefix')
179
+ .option('--default-file-extension <extension>', 'extension for external paths that omit one')
180
+ .option('--strategy <strategy>', 'retrieval strategy: fetch or checkout')
181
+ .option('--fetch-url <template>', 'raw-file URL template')
182
+ .action(async (handle, repo, opts) => {
183
+ const ctx = resolveContext(program.opts());
184
+ const { externalAddCommand } = await import('@plebeiantech/lat.md-core/cli/external');
185
+ handleResult(await externalAddCommand(ctx, handle, repo, opts));
186
+ });
187
+ external
188
+ .command('show')
189
+ .argument('<source>', 'handle or exact external target')
190
+ .option('--json', 'emit structured JSON')
191
+ .action(async (source, opts) => {
192
+ const ctx = resolveContext(program.opts());
193
+ const { externalShowCommand } = await import('@plebeiantech/lat.md-core/cli/external');
194
+ handleResult(await externalShowCommand(ctx, source, !!opts.json));
195
+ });
196
+ external
197
+ .command('list')
198
+ .option('--json', 'emit structured JSON')
199
+ .action(async (opts) => {
200
+ const ctx = resolveContext(program.opts());
201
+ const { externalListCommand } = await import('@plebeiantech/lat.md-core/cli/external');
202
+ handleResult(await externalListCommand(ctx, !!opts.json));
203
+ });
116
204
  const check = program
117
205
  .command('check')
118
206
  .usage('[subcommand] [-- <directory>]')
119
207
  .description('Validate markdown, links, code references, and structure')
120
208
  .option('--fix', 'generate/update directory index files from frontmatter')
209
+ .option('--profile', 'show detailed validation timing')
121
210
  .action(async (opts) => {
122
211
  const ctx = resolveCheckContext(program.opts(), checkTargetArgs.target);
123
- const { checkAllCommand } = await import('./check.js');
124
- handleResult(await checkAllCommand(ctx, { fix: opts.fix }));
212
+ const { checkAllCommand } = await import('@plebeiantech/lat.md-core/cli/check');
213
+ handleResult(await checkAllCommand(ctx, {
214
+ fix: opts.fix,
215
+ profile: !!opts.profile,
216
+ }));
125
217
  });
126
218
  check
127
219
  .command('md')
@@ -129,7 +221,7 @@ check
129
221
  .description('Validate wiki links in markdown files')
130
222
  .action(async () => {
131
223
  const ctx = resolveCheckContext(program.opts(), checkTargetArgs.target);
132
- const { checkMdCommand } = await import('./check.js');
224
+ const { checkMdCommand } = await import('@plebeiantech/lat.md-core/cli/check');
133
225
  handleResult(await checkMdCommand(ctx));
134
226
  });
135
227
  check
@@ -138,7 +230,7 @@ check
138
230
  .description('Validate relative markdown links')
139
231
  .action(async () => {
140
232
  const ctx = resolveCheckContext(program.opts(), checkTargetArgs.target);
141
- const { checkLinksCommand } = await import('./check.js');
233
+ const { checkLinksCommand } = await import('@plebeiantech/lat.md-core/cli/check');
142
234
  handleResult(await checkLinksCommand(ctx));
143
235
  });
144
236
  check
@@ -147,7 +239,7 @@ check
147
239
  .description('Validate @lat code references and coverage')
148
240
  .action(async () => {
149
241
  const ctx = resolveCheckContext(program.opts(), checkTargetArgs.target);
150
- const { checkCodeRefsCommand } = await import('./check.js');
242
+ const { checkCodeRefsCommand } = await import('@plebeiantech/lat.md-core/cli/check');
151
243
  handleResult(await checkCodeRefsCommand(ctx));
152
244
  });
153
245
  check
@@ -162,7 +254,7 @@ check
162
254
  // read it off `check.opts()` instead.
163
255
  .action(async () => {
164
256
  const ctx = resolveCheckContext(program.opts(), checkTargetArgs.target);
165
- const { checkIndexCommand } = await import('./check.js');
257
+ const { checkIndexCommand } = await import('@plebeiantech/lat.md-core/cli/check');
166
258
  handleResult(await checkIndexCommand(ctx, { fix: check.opts().fix }));
167
259
  });
168
260
  check
@@ -171,7 +263,7 @@ check
171
263
  .description('Validate section leading paragraphs')
172
264
  .action(async () => {
173
265
  const ctx = resolveCheckContext(program.opts(), checkTargetArgs.target);
174
- const { checkSectionsCommand } = await import('./check.js');
266
+ const { checkSectionsCommand } = await import('@plebeiantech/lat.md-core/cli/check');
175
267
  handleResult(await checkSectionsCommand(ctx));
176
268
  });
177
269
  check
@@ -180,7 +272,7 @@ check
180
272
  .description('Validate Diátaxis modes and document shape')
181
273
  .action(async () => {
182
274
  const ctx = resolveCheckContext(program.opts(), checkTargetArgs.target);
183
- const { checkModeCommand } = await import('./check.js');
275
+ const { checkModeCommand } = await import('@plebeiantech/lat.md-core/cli/check');
184
276
  handleResult(await checkModeCommand(ctx));
185
277
  });
186
278
  check
@@ -189,7 +281,7 @@ check
189
281
  .description('Validate provenance status and detect stale reviews')
190
282
  .action(async () => {
191
283
  const ctx = resolveCheckContext(program.opts(), checkTargetArgs.target);
192
- const { checkStatusCommand } = await import('./check.js');
284
+ const { checkStatusCommand } = await import('@plebeiantech/lat.md-core/cli/check');
193
285
  handleResult(await checkStatusCommand(ctx));
194
286
  });
195
287
  async function runExpand(text, opts) {
@@ -205,7 +297,7 @@ async function runExpand(text, opts) {
205
297
  process.exit(1);
206
298
  }
207
299
  const ctx = resolveContext(program.opts());
208
- const { expandCommand } = await import('./expand.js');
300
+ const { expandCommand } = await import('@plebeiantech/lat.md-core/cli/expand');
209
301
  const result = await expandCommand(ctx, text);
210
302
  if (result.isError) {
211
303
  console.error(result.output);
@@ -231,14 +323,26 @@ program
231
323
  });
232
324
  program
233
325
  .command('search')
234
- .description('Semantic search across lat.md sections')
326
+ .description('Hybrid search across lat.md sections')
235
327
  .argument('[query]', 'search query in plain English')
236
- .option('--limit <n>', 'max results', '5')
328
+ .option('--limit <n>', `max results (default: ${DEFAULT_SEARCH_LIMIT})`, String(DEFAULT_SEARCH_LIMIT))
329
+ .option('--preview <variant>', 'preview passage, intro, or both', (value) => {
330
+ if (!['passage', 'intro', 'both'].includes(value))
331
+ throw new InvalidArgumentError('preview must be passage, intro, or both');
332
+ return value;
333
+ }, 'passage')
334
+ .option('--debug', 'show retrieval scores and candidate diagnostics')
335
+ .option('--min-similarity <score>', `minimum cosine similarity score (default: ${DEFAULT_MIN_SIMILARITY})`, parseSimilarityThreshold)
237
336
  .action(async (query, opts) => {
238
337
  const ctx = resolveContext(program.opts());
239
338
  const { searchCommand, cliProgress } = await import('./search.js');
240
339
  const progress = cliProgress(ctx.styler);
241
- const result = await searchCommand(ctx, query, { limit: parseInt(opts.limit) }, progress);
340
+ const result = await searchCommand(ctx, query, {
341
+ limit: parseInt(opts.limit),
342
+ debug: opts.debug,
343
+ minSimilarity: opts.minSimilarity,
344
+ preview: opts.preview,
345
+ }, progress);
242
346
  handleResult(result);
243
347
  });
244
348
  program
@@ -285,13 +389,11 @@ program
285
389
  await startMcpServer();
286
390
  });
287
391
  program
288
- .command('config')
289
- .description('Show configuration file path')
392
+ .command('config', { hidden: true })
393
+ .description('Alias for paths --config')
290
394
  .action(async () => {
291
- const { getConfigPath } = await import('../config.js');
292
- const configPath = getConfigPath();
293
- const exists = existsSync(configPath);
294
- console.log(`Config file: ${configPath}${exists ? '' : ' (not found)'}`);
395
+ const { pathsCommand } = await import('@plebeiantech/lat.md-core/cli/paths');
396
+ console.log(pathsCommand({ config: true }));
295
397
  });
296
398
  program
297
399
  .command('graph')
@@ -0,0 +1,4 @@
1
+ /** Read machine-local checklist defaults without inferring installed agents. */
2
+ export declare function readInitAgents(latDir: string): string[];
3
+ /** Update just the confirmed selection, preserving other YAML and comments. */
4
+ export declare function writeInitAgents(latDir: string, agents: string[]): void;
@@ -0,0 +1,36 @@
1
+ import { projectWritePath, writeProjectFile, } from '@plebeiantech/lat.md-core/project-write';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { isMap, parseDocument } from 'yaml';
5
+ function readPreferences(latDir) {
6
+ const path = projectWritePath(dirname(latDir), join(latDir, 'config.local.yaml'));
7
+ const document = parseDocument(existsSync(path) ? readFileSync(path, 'utf8') : '');
8
+ if (document.errors.length > 0) {
9
+ throw new Error(`Cannot parse ${path}: ${document.errors[0].message}`);
10
+ }
11
+ if (document.contents !== null && !isMap(document.contents)) {
12
+ throw new Error(`${path} must be a mapping`);
13
+ }
14
+ if (document.has('init') && !isMap(document.get('init', true))) {
15
+ throw new Error(`${path}: init must be a mapping`);
16
+ }
17
+ return { path, document };
18
+ }
19
+ /** Read machine-local checklist defaults without inferring installed agents. */
20
+ export function readInitAgents(latDir) {
21
+ const { path, document } = readPreferences(latDir);
22
+ const agents = document.toJS()?.init?.agents;
23
+ if (agents === undefined)
24
+ return [];
25
+ if (!Array.isArray(agents) ||
26
+ agents.some((agent) => typeof agent !== 'string')) {
27
+ throw new Error(`${path}: init.agents must be a list of strings`);
28
+ }
29
+ return agents;
30
+ }
31
+ /** Update just the confirmed selection, preserving other YAML and comments. */
32
+ export function writeInitAgents(latDir, agents) {
33
+ const { path, document } = readPreferences(latDir);
34
+ document.setIn(['init', 'agents'], agents);
35
+ writeProjectFile(dirname(latDir), path, document.toString());
36
+ }