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

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 +115 -64
  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 +200 -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-0bPe_Q5I.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-1_8mI7lO.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-BLIuikwY.js +1 -0
  134. package/dist/src/view/client/assets/arc-D4PzdKSA.js +1 -0
  135. package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-35Egww62.js +36 -0
  136. package/dist/src/view/client/assets/blockDiagram-I7D4REHJ-tqNy53-W.js +129 -0
  137. package/dist/src/view/client/assets/c4Diagram-7LVT6UL2-DZ_GcD9K.js +38 -0
  138. package/dist/src/view/client/assets/channel-DensupHE.js +1 -0
  139. package/dist/src/view/client/assets/chunk-2Q5K7J3B-BUjq4Q7b.js +1 -0
  140. package/dist/src/view/client/assets/chunk-5VM5RSS4-BsIix6I5.js +15 -0
  141. package/dist/src/view/client/assets/chunk-F27PBJKO-Dxo7UheG.js +1 -0
  142. package/dist/src/view/client/assets/chunk-IMKFNOWR-C5lzUDK5.js +231 -0
  143. package/dist/src/view/client/assets/chunk-JWPE2WC7-qCHQlKfY.js +1 -0
  144. package/dist/src/view/client/assets/chunk-POPQ4Y6H-CDPKw21I.js +1 -0
  145. package/dist/src/view/client/assets/chunk-SVP7TREG-CD_C-9M-.js +88 -0
  146. package/dist/src/view/client/assets/chunk-TICWLB2K-ZMatRvad.js +206 -0
  147. package/dist/src/view/client/assets/chunk-XXDRQBXY-dDs4quwg.js +1 -0
  148. package/dist/src/view/client/assets/classDiagram-ZZMXUADV-CV7ArHLW.js +1 -0
  149. package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-CV7ArHLW.js +1 -0
  150. package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-CwH3-T1N.js +1 -0
  151. package/dist/src/view/client/assets/cynefin-OW5HDTMX-DodS6r00.js +166 -0
  152. package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-D7WDoy0K.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-yc2GTi5h.js +4 -0
  155. package/dist/src/view/client/assets/defaultLocale-DX6XiGOO.js +1 -0
  156. package/dist/src/view/client/assets/diagram-S7CK7UJ4-CEP0FGL8.js +30 -0
  157. package/dist/src/view/client/assets/diagram-UQ7AKVKN-BZIEojBf.js +41 -0
  158. package/dist/src/view/client/assets/diagram-VSXAHHWV-BSB6COmM.js +3 -0
  159. package/dist/src/view/client/assets/diagram-VX7I27RA-DqfR3psV.js +24 -0
  160. package/dist/src/view/client/assets/diagram-Z3DM3KII-B79t0s5P.js +24 -0
  161. package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-CqbCQhE1.js +1 -0
  162. package/dist/src/view/client/assets/erDiagram-RLTQ6QDP-BVfoYIhJ.js +99 -0
  163. package/dist/src/view/client/assets/flowDiagram-HODETNUW-Dfyjm6ib.js +168 -0
  164. package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-Da9ta_k3.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-BDqlQ6LG.js +106 -0
  177. package/dist/src/view/client/assets/index-BnENo9bV.js +1 -0
  178. package/dist/src/view/client/assets/index-DG0Ez15D.css +1 -0
  179. package/dist/src/view/client/assets/index-heNSjszK.js +13 -0
  180. package/dist/src/view/client/assets/infoDiagram-27XIBGKW-CozIUYm1.js +2 -0
  181. package/dist/src/view/client/assets/init-Gi6I4Gst.js +1 -0
  182. package/dist/src/view/client/assets/ishikawaDiagram-5VMMS53U-tkBLr-Tn.js +70 -0
  183. package/dist/src/view/client/assets/journeyDiagram-3NMN7TZE-Dcd_Ofwc.js +139 -0
  184. package/dist/src/view/client/assets/kanban-definition-UXKFOSKX-CQvZmdAf.js +89 -0
  185. package/dist/src/view/client/assets/katex-HP8lGamR.js +257 -0
  186. package/dist/src/view/client/assets/layout-BxuGL0Ip.js +1 -0
  187. package/dist/src/view/client/assets/linear-D8tR6G5K.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-BlHZooLK.js +310 -0
  191. package/dist/src/view/client/assets/mindmap-definition-YA3MSWOX-BqvVz5lC.js +96 -0
  192. package/dist/src/view/client/assets/ordinal-Cboi1Yqb.js +1 -0
  193. package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-BkbOOTxX.js +1 -0
  194. package/dist/src/view/client/assets/pieDiagram-E7YTZNPT-BToTpG0m.js +39 -0
  195. package/dist/src/view/client/assets/quadrantDiagram-AXDQQJYC-CerD2TfT.js +7 -0
  196. package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-B2oElPYD.js +1 -0
  197. package/dist/src/view/client/assets/requirementDiagram-BXWQKSXE-BCL8RGFd.js +84 -0
  198. package/dist/src/view/client/assets/sankeyDiagram-P5KCCOFB-BqnkNRPm.js +40 -0
  199. package/dist/src/view/client/assets/sequenceDiagram-WJ2MYXX4-DKSKYknp.js +162 -0
  200. package/dist/src/view/client/assets/sizeCapture-INFHLROL-D8reQ7IM.js +1 -0
  201. package/dist/src/view/client/assets/stateDiagram-D77RDMKH-B-Eme-BN.js +1 -0
  202. package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-yXL-Y-Ym.js +1 -0
  203. package/dist/src/view/client/assets/swimlanes-42K2YHIH-lK0158X4.js +1 -0
  204. package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-CGn5WOGw.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-imh-edhJ.js +120 -0
  207. package/dist/src/view/client/assets/vennDiagram-4TSXK5OY-Ixwhcd6r.js +34 -0
  208. package/dist/src/view/client/assets/wardleyDiagram-VM6X3IG4-Cvr_zzKI.js +78 -0
  209. package/dist/src/view/client/assets/xychartDiagram-S5SC5T6Z-BvcmHKlQ.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 +50648 -3166
  229. package/dist/src/view/markdown.d.ts +8 -3
  230. package/dist/src/view/markdown.js +311 -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 -20
  281. package/templates/cursor-rules.md +14 -7
  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
@@ -0,0 +1,490 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { basename, dirname, join } from 'node:path';
3
+ import { styleText } from 'node:util';
4
+ import { isMap, isScalar, isSeq, parseDocument } from 'yaml';
5
+ import { parseFrontmatter } from '@plebeiantech/lat.md-core/lattice';
6
+ import { DIATAXIS_MODES, MODE_DIRS, checkMode, indexNameFor, } from '@plebeiantech/lat.md-core/cli/check-mode';
7
+ /**
8
+ * Give a freshly created `lat.md/` the Diátaxis shape, and turn the gate on.
9
+ *
10
+ * Upstream's `templates/init/` holds two files and is copied wholesale, so a
11
+ * new tree is one flat root index. An agent asked to document a codebase then
12
+ * writes flat files beside it — which is not merely untidy: `checkMode` binds
13
+ * only inside the four mode directories, so flat placement puts every document
14
+ * out of reach of every shape rule. A bella-derms session did exactly that and
15
+ * confirmed afterwards that its largest document produced 64 errors the moment
16
+ * it was moved into `reference/`.
17
+ *
18
+ * Structure is the cheaper half of the fix. Four directories that already
19
+ * exist, each with a passing index, make placement the path of least
20
+ * resistance; `require-mode: true` in the root index makes flat placement an
21
+ * error rather than an option.
22
+ *
23
+ * Written from here rather than added to `templates/init/` because the flag
24
+ * has to land inside `lat.md/lat.md`, which upstream's template owns.
25
+ */
26
+ /** One-line summary and body for each mode's index, keyed by directory. */
27
+ const MODE_INDEX = {
28
+ tutorials: {
29
+ title: 'Tutorials',
30
+ lead: 'Guided first passes through this system, each ending somewhere the reader can see.',
31
+ },
32
+ 'how-to': {
33
+ title: 'How-to',
34
+ lead: 'Recipes for tasks that recur, written for someone who already knows what they want.',
35
+ },
36
+ reference: {
37
+ title: 'Reference',
38
+ lead: 'Lookup facts about this system: fields, states, limits, names and defaults.',
39
+ },
40
+ explanation: {
41
+ title: 'Explanation',
42
+ lead: 'Why this system is shaped the way it is, and what the alternatives cost.',
43
+ },
44
+ };
45
+ /**
46
+ * A mode index has to satisfy its own mode. A tutorial index needs ordered
47
+ * steps and a stated outcome, a how-to index needs ordered steps, and a
48
+ * reference index must not carry a second paragraph — so each stub is written
49
+ * to the rule it will be checked against rather than to one house style.
50
+ */
51
+ function indexBody(dir) {
52
+ const { title, lead } = MODE_INDEX[dir];
53
+ const header = `# ${title}\n\n${lead}\n`;
54
+ if (dir === 'tutorials') {
55
+ return (header +
56
+ '\nBy the end of any document here the reader will have run something and seen it work.\n' +
57
+ '\n1. Pick the tutorial closest to what you are trying to learn.\n' +
58
+ '2. Follow it top to bottom without skipping.\n' +
59
+ '3. Come back to `reference/` for the details it left out.\n');
60
+ }
61
+ if (dir === 'how-to') {
62
+ return (header +
63
+ '\n1. Find the recipe for the task in front of you.\n' +
64
+ '2. Follow its steps.\n' +
65
+ '3. If no recipe fits, write one here once the task is done.\n');
66
+ }
67
+ if (dir === 'reference') {
68
+ return header;
69
+ }
70
+ return (header +
71
+ '\nEach document here answers a "why", not a "how". The steps that follow ' +
72
+ 'from a decision belong in `how-to/`, and the facts it fixes belong in ' +
73
+ '`reference/`.\n');
74
+ }
75
+ // ── Turning the gate on in a root index ──────────────────────────────
76
+ /**
77
+ * The frontmatter fence, copied from `parseFrontmatter` rather than written
78
+ * afresh.
79
+ *
80
+ * The two readers have to agree on what counts as frontmatter. When they did
81
+ * not — this pattern once required the closing fence to end its line, which
82
+ * upstream's does not — a root index closed with `----` was frontmatter to the
83
+ * parser and no frontmatter here, so a whole second block was prepended above
84
+ * the real one. The original block still sat in the file, still looked live,
85
+ * and every field it declared was silently no longer read.
86
+ */
87
+ const FENCE = /^---\n([\s\S]*?)\n---/;
88
+ /**
89
+ * `lineWidth: 0` stops long values being wrapped onto continuation lines, and
90
+ * `flowCollectionPadding: false` keeps `[a, b]` from becoming `[ a, b ]`. Both
91
+ * exist to keep the diff to the line that changed.
92
+ */
93
+ const STRINGIFY = { flowCollectionPadding: false, lineWidth: 0 };
94
+ /**
95
+ * Read the gate straight from a root index's frontmatter.
96
+ *
97
+ * Four states rather than a boolean, because `checkMode` enforces on `=== true`
98
+ * and anything looser here disagrees with it. A root index reading
99
+ * `require-mode: yes` is a string to this parser: treating that as "set" left
100
+ * the user believing the gate was on, `checkMode` enforcing nothing, and the
101
+ * one prompt that would have said so permanently silenced by the same value.
102
+ * `invalid` is reported rather than assumed either way.
103
+ */
104
+ export function requireModeState(content) {
105
+ const value = parseFrontmatter(content).raw['require-mode'];
106
+ if (value === undefined)
107
+ return 'unset';
108
+ if (value === true)
109
+ return 'on';
110
+ if (value === false)
111
+ return 'off';
112
+ return 'invalid';
113
+ }
114
+ function shapeOf(node) {
115
+ if (isSeq(node))
116
+ return 'a list';
117
+ if (isScalar(node))
118
+ return `the value ${JSON.stringify(node.value)}`;
119
+ return 'something other than a mapping';
120
+ }
121
+ /**
122
+ * Decide what turning the gate on in this document would do, without doing it.
123
+ *
124
+ * Parsed and re-emitted through the YAML document API rather than edited line
125
+ * by line. Line surgery looked cheaper — it preserves the file byte for byte
126
+ * except where it inserts — but it has to answer, from raw text, every question
127
+ * the parser already answers: which line opens the block, which lines are the
128
+ * `lat:` mapping's own children rather than a later key's, how far they are
129
+ * indented, and whether the value on the `lat:` line is a flow mapping, an
130
+ * anchor or a block scalar. Each wrong answer was its own defect: a flow
131
+ * mapping and an anchor were refused although both merge cleanly, an empty
132
+ * `lat:` beside a sibling list was refused because the scan walked past the end
133
+ * of the block, and one shape produced frontmatter that no longer parsed at
134
+ * all. `parseDocument` answers all of it, and round-trips comments and blank
135
+ * lines while doing so.
136
+ *
137
+ * The one thing the document API does not give for free is that the fields
138
+ * already there survive, so that is asserted below rather than assumed.
139
+ */
140
+ export function planRequireMode(content) {
141
+ const state = requireModeState(content);
142
+ if (state === 'on')
143
+ return { kind: 'on' };
144
+ if (state === 'off')
145
+ return { kind: 'off' };
146
+ if (state === 'invalid') {
147
+ const value = parseFrontmatter(content).raw['require-mode'];
148
+ return {
149
+ kind: 'invalid',
150
+ detail: `require-mode is ${JSON.stringify(value)}; it must be true or false`,
151
+ };
152
+ }
153
+ const fence = content.match(FENCE);
154
+ // Every branch below produces `stamped` and then falls through to the same
155
+ // gate. Returning early from any of them is how the last version let the
156
+ // "no frontmatter here" branch write a second block above frontmatter the
157
+ // parser was reading perfectly well.
158
+ let stamped;
159
+ let movedRootKey = false;
160
+ if (!fence) {
161
+ stamped = `---\nlat:\n require-mode: true\n---\n\n${content.replace(/^\n+/, '')}`;
162
+ }
163
+ else {
164
+ const doc = parseDocument(fence[1]);
165
+ if (doc.errors.length > 0) {
166
+ return {
167
+ kind: 'unparseable',
168
+ detail: doc.errors[0].message.split('\n')[0],
169
+ };
170
+ }
171
+ const node = doc.get('lat', true);
172
+ if (node === undefined || node === null) {
173
+ doc.set('lat', doc.createNode({ 'require-mode': true }));
174
+ }
175
+ else if (isScalar(node) && node.value === null) {
176
+ // `lat:` with nothing under it. Replacing the key in place keeps its
177
+ // position and any comment attached to it.
178
+ doc.set('lat', doc.createNode({ 'require-mode': true }));
179
+ }
180
+ else if (isMap(node)) {
181
+ doc.setIn(['lat', 'require-mode'], true);
182
+ }
183
+ else {
184
+ return {
185
+ kind: 'unsupported',
186
+ detail: `\`lat:\` holds ${shapeOf(node)}, which cannot take \`require-mode\``,
187
+ };
188
+ }
189
+ // A root-level `require-mode` is dead — upstream reads fields only under
190
+ // `lat:` — and `checkFrontmatter` reports it as misplaced. Once the nested
191
+ // key exists that report stops firing, because the diagnostic asks whether
192
+ // the field is missing from `lat:`. Leaving the dead key behind would mean
193
+ // silently ending the one message that would ever have mentioned it, so it
194
+ // is moved rather than shadowed.
195
+ movedRootKey = doc.has('require-mode');
196
+ if (movedRootKey)
197
+ doc.delete('require-mode');
198
+ stamped = `---\n${doc.toString(STRINGIFY)}---${content.slice(fence[0].length)}`;
199
+ }
200
+ // The invariant, asserted rather than argued.
201
+ //
202
+ // Setting the flag is worth nothing if the merge quietly drops a field that
203
+ // was already there: an edit that lands `require-mode: true` and loses
204
+ // `require-code-mention: true` turns one check on and another off, and `lat
205
+ // check` then passes on a document that used to be enforced. Checking that
206
+ // the output parses is not enough to catch it — the losing edit parses fine.
207
+ // So every key read before must read back the same afterwards.
208
+ const before = parseFrontmatter(content);
209
+ const after = parseFrontmatter(stamped);
210
+ if ((after.problems ?? []).some((problem) => problem.kind === 'parse-error')) {
211
+ return {
212
+ kind: 'unsupported',
213
+ detail: 'the merged frontmatter did not parse',
214
+ };
215
+ }
216
+ if (after.raw['require-mode'] !== true) {
217
+ return {
218
+ kind: 'unsupported',
219
+ detail: 'the flag did not land where it is read',
220
+ };
221
+ }
222
+ for (const [key, value] of Object.entries(before.raw)) {
223
+ if (JSON.stringify(after.raw[key]) !== JSON.stringify(value)) {
224
+ return {
225
+ kind: 'unsupported',
226
+ detail: `the merge would change \`${key}\``,
227
+ };
228
+ }
229
+ }
230
+ return { kind: 'stamped', content: stamped, movedRootKey };
231
+ }
232
+ /** The edited document when the gate can be turned on, the input when not. */
233
+ export function stampRequireMode(content) {
234
+ const plan = planRequireMode(content);
235
+ return plan.kind === 'stamped' ? plan.content : content;
236
+ }
237
+ /**
238
+ * Append the four mode directories to the root index.
239
+ *
240
+ * Without this a fresh `lat init` leaves `lat check index` reporting four
241
+ * missing entries, which is a poor first impression of a tool whose whole
242
+ * pitch is that the check passes. Each directory is tested for separately: an
243
+ * index that already links `reference/` used to suppress the other three, so
244
+ * the three unlinked directories this had just created turned a passing
245
+ * `lat check index` into a failing one.
246
+ */
247
+ export function listModeDirs(content) {
248
+ const missing = DIATAXIS_MODES.map((mode) => MODE_DIRS[mode]).filter((dir) => !content.includes(`(${dir}/`));
249
+ if (missing.length === 0)
250
+ return content;
251
+ const entries = missing
252
+ .map((dir) => {
253
+ const { title, lead } = MODE_INDEX[dir];
254
+ return `- [${title}](${dir}/${dir}.md) — ${lead}`;
255
+ })
256
+ .join('\n');
257
+ let base = content;
258
+ if (!base.endsWith('\n'))
259
+ base += '\n';
260
+ const intro = missing.length === DIATAXIS_MODES.length
261
+ ? '\nEvery document belongs in exactly one of these.\n\n'
262
+ : '\n';
263
+ return `${base}${intro}${entries}\n`;
264
+ }
265
+ /**
266
+ * Scaffold the four mode directories and turn the gate on.
267
+ *
268
+ * Nothing at all happens when the gate cannot land in the root index. A tree
269
+ * left with four new directories and the gate still off is worse than one left
270
+ * alone: `checkMode` passes on it, so nothing ever says the adoption stopped
271
+ * half way — and if the index was not rewritten to list them, `lat check index`
272
+ * fails instead, on four directories the user never asked for.
273
+ */
274
+ export function writeForkScaffold(latDir) {
275
+ const rootIndex = join(latDir, indexNameFor(basename(latDir)));
276
+ const current = existsSync(rootIndex)
277
+ ? readFileSync(rootIndex, 'utf-8')
278
+ : null;
279
+ const stamped = current === null ? null : stampRequireMode(current);
280
+ if (stamped !== null && requireModeState(stamped) !== 'on')
281
+ return;
282
+ const created = [];
283
+ for (const mode of DIATAXIS_MODES) {
284
+ const dir = MODE_DIRS[mode];
285
+ const dirPath = join(latDir, dir);
286
+ const indexPath = join(dirPath, `${dir}.md`);
287
+ if (existsSync(indexPath))
288
+ continue;
289
+ mkdirSync(dirPath, { recursive: true });
290
+ writeFileSync(indexPath, indexBody(dir));
291
+ created.push(`${dir}/`);
292
+ }
293
+ if (current !== null && stamped !== null) {
294
+ const listed = listModeDirs(stamped);
295
+ if (listed !== current)
296
+ writeFileSync(rootIndex, listed);
297
+ }
298
+ if (created.length > 0) {
299
+ console.log(styleText('green', 'Scaffolded Diátaxis modes') +
300
+ ' — ' +
301
+ created.join(' ') +
302
+ styleText('dim', ' (every document belongs in one of these)'));
303
+ }
304
+ }
305
+ // ── Adopting the gate in a tree that already exists ──────────────────
306
+ /**
307
+ * Where a declined offer is remembered.
308
+ *
309
+ * Fork-owned rather than a field on upstream's `lat_init.json`, so recording
310
+ * it costs no edit to `src/init-version.ts`.
311
+ */
312
+ function markerPath(latDir) {
313
+ return join(latDir, '.cache', 'lat_fork.json');
314
+ }
315
+ function readForkMeta(latDir) {
316
+ try {
317
+ const raw = JSON.parse(readFileSync(markerPath(latDir), 'utf-8'));
318
+ // An array is an object too, and spreading one produces `{"0": ...}` —
319
+ // which then overwrites the file with something no reader understands.
320
+ if (typeof raw === 'object' && raw !== null && !Array.isArray(raw)) {
321
+ return raw;
322
+ }
323
+ }
324
+ catch {
325
+ // Absent or unreadable — nothing has been settled yet.
326
+ }
327
+ return {};
328
+ }
329
+ function declined(latDir) {
330
+ return readForkMeta(latDir).require_mode_declined === true;
331
+ }
332
+ /**
333
+ * Remember a no.
334
+ *
335
+ * The marker is a local answer, not a project fact: committed, it would tell
336
+ * every other clone that this project had already declined. `lat.md/.gitignore`
337
+ * covers `.cache/`, but that file is written only by the run that *creates*
338
+ * `lat.md/` — and this path exists for trees `lat init` did not create — so the
339
+ * cache is made to ignore itself rather than trusting a file that may not be
340
+ * there.
341
+ *
342
+ * Failure to record is reported and survived. This runs after the tree has
343
+ * already been restructured, and an unwritable cache directory is not a reason
344
+ * to abort `lat init` with a stack trace at that point.
345
+ */
346
+ function recordDeclined(latDir) {
347
+ try {
348
+ const cacheDir = join(latDir, '.cache');
349
+ mkdirSync(cacheDir, { recursive: true });
350
+ const selfIgnore = join(cacheDir, '.gitignore');
351
+ if (!existsSync(selfIgnore))
352
+ writeFileSync(selfIgnore, '*\n');
353
+ writeFileSync(markerPath(latDir), JSON.stringify({ ...readForkMeta(latDir), require_mode_declined: true }, null, 2) + '\n');
354
+ }
355
+ catch (err) {
356
+ console.log(' ' +
357
+ styleText('dim', `Could not record the answer (${err.message}) — the offer will repeat.`));
358
+ }
359
+ }
360
+ /**
361
+ * What adopting the gate would newly cost, measured with the gate itself.
362
+ *
363
+ * Counted by running `checkMode` twice and taking the difference rather than
364
+ * by re-implementing its classification here. The hand-written version drifted
365
+ * immediately: it skipped every document inside a mode directory before
366
+ * reading what that document declared, so two files with byte-identical
367
+ * frontmatter were counted or not according to where they sat, and it reported
368
+ * one offender against two errors. Advertising a document as settled and then
369
+ * failing it is the failure worth avoiding, and only the checker knows.
370
+ */
371
+ async function adoptionCost(latDir) {
372
+ const projectRoot = dirname(latDir);
373
+ const key = (error) => `${error.file}:${error.line}:${error.message}`;
374
+ const [gated, ungated] = await Promise.all([
375
+ checkMode(latDir, projectRoot, { requireMode: true }),
376
+ checkMode(latDir, projectRoot, { requireMode: false }),
377
+ ]);
378
+ const already = new Set(ungated.map(key));
379
+ return [
380
+ ...new Set(gated.filter((e) => !already.has(key(e))).map((e) => e.target)),
381
+ ];
382
+ }
383
+ /** Say what is wrong with a root index the gate cannot be written into. */
384
+ function reportUnstampable(latDir, plan) {
385
+ const where = `${basename(latDir)}/${indexNameFor(basename(latDir))}`;
386
+ console.log('');
387
+ console.log(styleText('bold', 'Diátaxis modes'));
388
+ console.log(' ' +
389
+ styleText('dim', `require-mode cannot be set in ${where}: `) +
390
+ ('detail' in plan ? plan.detail : ''));
391
+ if (plan.kind === 'unparseable') {
392
+ // Worth more than the offer that prompted it. Every `lat:` field on a
393
+ // document whose frontmatter does not parse is silently ignored, so this
394
+ // root index is already not being read.
395
+ console.log(' ' +
396
+ styleText('dim', 'Until that parses, no `lat:` field on this document is read at all.'));
397
+ }
398
+ }
399
+ /**
400
+ * Offer the gate to a tree `lat init` did not create.
401
+ *
402
+ * `writeForkScaffold` runs only on the branch that creates `lat.md/`, which
403
+ * left the flag unreachable for every project that already had one — that is,
404
+ * for every project that needs it. Restructuring someone's tree without asking
405
+ * is still wrong, so this asks.
406
+ *
407
+ * Whether the flag *can* be written is decided before anything is asked and
408
+ * before anything is written. Asking first cost a tree four directories and a
409
+ * rewritten index in exchange for a gate that never landed, and the user was
410
+ * told in the same breath that nothing could be edited.
411
+ *
412
+ * Silent when the flag is already set either way, when a previous run was told
413
+ * no, and when there is no TTY to ask — the non-interactive path prints the
414
+ * count and the manual edit instead, and records nothing, so a later
415
+ * interactive run still offers.
416
+ */
417
+ export async function offerRequireMode(latDir, interactive, ask) {
418
+ const rootIndex = join(latDir, indexNameFor(basename(latDir)));
419
+ if (!existsSync(rootIndex))
420
+ return;
421
+ let current;
422
+ try {
423
+ current = readFileSync(rootIndex, 'utf-8');
424
+ }
425
+ catch {
426
+ return;
427
+ }
428
+ const plan = planRequireMode(current);
429
+ if (plan.kind === 'on' || plan.kind === 'off')
430
+ return;
431
+ if (plan.kind !== 'stamped') {
432
+ // Not recorded and not silenced: this is a defect in the document with a
433
+ // fix the user can apply, and it stops being printed the moment they do.
434
+ reportUnstampable(latDir, plan);
435
+ return;
436
+ }
437
+ if (declined(latDir))
438
+ return;
439
+ const offenders = await adoptionCost(latDir);
440
+ console.log('');
441
+ console.log(styleText('bold', 'Diátaxis modes'));
442
+ console.log(' ' +
443
+ styleText('dim', 'Every document belongs in one of four modes. Without') +
444
+ ' require-mode ' +
445
+ styleText('dim', 'a document'));
446
+ console.log(' ' +
447
+ styleText('dim', 'placed outside a mode directory is checked against no shape rule at all.'));
448
+ if (offenders.length > 0) {
449
+ console.log('');
450
+ console.log(` ${styleText('yellow', String(offenders.length))} document(s) would need a mode:`);
451
+ for (const name of offenders.slice(0, 5)) {
452
+ console.log(' ' + styleText('dim', name));
453
+ }
454
+ if (offenders.length > 5) {
455
+ console.log(' ' + styleText('dim', `... and ${offenders.length - 5} more`));
456
+ }
457
+ }
458
+ if (!interactive) {
459
+ console.log('');
460
+ console.log(' ' +
461
+ styleText('dim', 'To turn it on, add this to the top of') +
462
+ ` ${basename(latDir)}/${indexNameFor(basename(latDir))}:`);
463
+ console.log('');
464
+ for (const line of ['---', 'lat:', ' require-mode: true', '---']) {
465
+ console.log(' ' + styleText('cyan', line));
466
+ }
467
+ return;
468
+ }
469
+ console.log('');
470
+ if (!(await ask(' Turn require-mode on for this project?'))) {
471
+ recordDeclined(latDir);
472
+ console.log(' ' +
473
+ styleText('dim', 'Skipped. Add') +
474
+ ' require-mode: true ' +
475
+ styleText('dim', 'to the root index whenever you want it.'));
476
+ return;
477
+ }
478
+ writeFileSync(rootIndex, plan.content);
479
+ if (plan.movedRootKey) {
480
+ console.log(' ' +
481
+ styleText('dim', 'Moved the stray root-level require-mode under `lat:`, where it is read.'));
482
+ }
483
+ writeForkScaffold(latDir);
484
+ if (offenders.length > 0) {
485
+ console.log(' ' +
486
+ styleText('dim', 'Run') +
487
+ ' lat check ' +
488
+ styleText('dim', 'to see which documents need placing.'));
489
+ }
490
+ }
@@ -1,4 +1,4 @@
1
- import type { CmdContext, CmdResult } from '../context.js';
1
+ import type { CmdContext, CmdResult } from '@plebeiantech/lat.md-core/context';
2
2
  export type GraphOptions = {
3
3
  format?: string;
4
4
  at?: string;
@@ -1 +1,27 @@
1
+ /**
2
+ * Measure code vs `lat.md/` churn since HEAD, in lines. Combines tracked
3
+ * changes (`git diff HEAD --numstat`) with untracked files
4
+ * (`git ls-files --others --exclude-standard -z`). Counting untracked files is
5
+ * what makes a freshly scaffolded, never-committed `lat.md/` register as
6
+ * updated — otherwise its edits are invisible to `git diff HEAD` and the sync
7
+ * reminder fires on every turn until `lat.md/` is committed (issue #61).
8
+ * Both scans are scoped and made relative to `projectRoot`, so a Lat project
9
+ * nested in a larger worktree neither misses its own `lat.md/` paths nor counts
10
+ * changes from sibling projects.
11
+ * Outside a Git worktree both scans contribute zero churn by design: Git is
12
+ * optional, so the hook still validates the project but skips the sync ratio.
13
+ */
14
+ export declare function analyzeDiff(projectRoot: string): {
15
+ codeLines: number;
16
+ latMdLines: number;
17
+ };
18
+ export type StopStatus = {
19
+ checkFailed: boolean;
20
+ totalErrors: number;
21
+ needsSync: boolean;
22
+ codeLines: number;
23
+ latMdLines: number;
24
+ };
25
+ export declare function getStopStatus(latDir: string): Promise<StopStatus>;
26
+ export declare function formatStopReason({ checkFailed, totalErrors, needsSync, codeLines, latMdLines, }: StopStatus): string | null;
1
27
  export declare function hookCmd(agent: string, event: string): Promise<void>;