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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/README.md +27 -3
  2. package/dist/src/cli/agent-invocation.d.ts +6 -0
  3. package/dist/src/cli/agent-invocation.js +23 -0
  4. package/dist/src/cli/checklist-menu.d.ts +2 -1
  5. package/dist/src/cli/checklist-menu.js +3 -2
  6. package/dist/src/cli/fork-instructions.d.ts +1 -0
  7. package/dist/src/cli/fork-instructions.js +8 -32
  8. package/dist/src/cli/fork-scaffold.js +2 -2
  9. package/dist/src/cli/graph.d.ts +1 -1
  10. package/dist/src/cli/hook.d.ts +26 -0
  11. package/dist/src/cli/hook.js +115 -64
  12. package/dist/src/cli/index.js +178 -70
  13. package/dist/src/cli/init-preferences.d.ts +4 -0
  14. package/dist/src/cli/init-preferences.js +36 -0
  15. package/dist/src/cli/init.d.ts +2 -1
  16. package/dist/src/cli/init.js +100 -60
  17. package/dist/src/cli/reindex.d.ts +1 -1
  18. package/dist/src/cli/reindex.js +7 -10
  19. package/dist/src/cli/search.d.ts +14 -4
  20. package/dist/src/cli/search.js +115 -101
  21. package/dist/src/cli/ui-build-server.d.ts +12 -0
  22. package/dist/src/cli/ui-build-server.js +26 -0
  23. package/dist/src/cli/ui-build.d.ts +1 -1
  24. package/dist/src/cli/ui-build.js +1 -1
  25. package/dist/src/cli/ui.d.ts +1 -1
  26. package/dist/src/cli/ui.js +1 -1
  27. package/dist/src/cli/wiki.d.ts +12 -0
  28. package/dist/src/cli/wiki.js +85 -0
  29. package/dist/src/fork/antigravity-hook.d.ts +47 -0
  30. package/dist/src/fork/antigravity-hook.js +424 -0
  31. package/dist/src/fork/antigravity-init.d.ts +17 -0
  32. package/dist/src/fork/antigravity-init.js +124 -0
  33. package/dist/src/fork/upstream-drift.js +1 -1
  34. package/dist/src/fork/upstream-guard.d.ts +1 -1
  35. package/dist/src/fork/upstream-guard.js +8 -7
  36. package/dist/src/graph-export.js +7 -7
  37. package/dist/src/knowledge/index.js +2 -2
  38. package/dist/src/mcp/server.js +34 -18
  39. package/dist/src/search/cache.d.ts +3 -0
  40. package/dist/src/search/cache.js +104 -0
  41. package/dist/src/search/chunks.d.ts +23 -0
  42. package/dist/src/search/chunks.js +200 -0
  43. package/dist/src/search/db.d.ts +28 -16
  44. package/dist/src/search/db.js +100 -40
  45. package/dist/src/search/embedder.d.ts +2 -1
  46. package/dist/src/search/embedder.js +7 -6
  47. package/dist/src/search/index.d.ts +6 -2
  48. package/dist/src/search/index.js +176 -70
  49. package/dist/src/search/lexical.d.ts +6 -0
  50. package/dist/src/search/lexical.js +36 -0
  51. package/dist/src/search/lock.d.ts +5 -0
  52. package/dist/src/search/lock.js +45 -0
  53. package/dist/src/search/query.d.ts +26 -0
  54. package/dist/src/search/query.js +103 -0
  55. package/dist/src/search/search.d.ts +16 -7
  56. package/dist/src/search/search.js +165 -21
  57. package/dist/src/search/types.d.ts +15 -0
  58. package/dist/src/view/client/assets/GraphView-D_xnk0bP.js +456 -0
  59. package/dist/src/view/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  60. package/dist/src/view/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  61. package/dist/src/view/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  62. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  63. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  64. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  65. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  66. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  67. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  68. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  69. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  70. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  71. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  72. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  73. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  74. package/dist/src/view/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  75. package/dist/src/view/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  76. package/dist/src/view/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  77. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  78. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  79. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  80. package/dist/src/view/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  81. package/dist/src/view/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  82. package/dist/src/view/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  83. package/dist/src/view/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  84. package/dist/src/view/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  85. package/dist/src/view/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  86. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  87. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  88. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  89. package/dist/src/view/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  90. package/dist/src/view/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  91. package/dist/src/view/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  92. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  93. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  94. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  95. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  96. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  97. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  98. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  99. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  100. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  101. package/dist/src/view/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  102. package/dist/src/view/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  103. package/dist/src/view/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  104. package/dist/src/view/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  105. package/dist/src/view/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  106. package/dist/src/view/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  107. package/dist/src/view/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  108. package/dist/src/view/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  109. package/dist/src/view/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  110. package/dist/src/view/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  111. package/dist/src/view/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  112. package/dist/src/view/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  113. package/dist/src/view/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  114. package/dist/src/view/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  115. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  116. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  117. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  118. package/dist/src/view/client/assets/MarkdownEditor-bjqt_FoF.js +28 -0
  119. package/dist/src/view/client/assets/OrbitControls-DwcpQNja.js +1 -0
  120. package/dist/src/view/client/assets/STLLoader-CLWTKt5i.js +1 -0
  121. package/dist/src/view/client/assets/_commonjsHelpers-CqkleIqs.js +1 -0
  122. package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-kWGvtRnL.js +1 -0
  123. package/dist/src/view/client/assets/arc-BPAFd7cP.js +1 -0
  124. package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-CsY39oIR.js +36 -0
  125. package/dist/src/view/client/assets/blockDiagram-I7D4REHJ-DHGBG7BJ.js +129 -0
  126. package/dist/src/view/client/assets/c4Diagram-7LVT6UL2-vywK4eb7.js +38 -0
  127. package/dist/src/view/client/assets/channel-CX71L_qV.js +1 -0
  128. package/dist/src/view/client/assets/chunk-2Q5K7J3B-Do3Hz_ci.js +1 -0
  129. package/dist/src/view/client/assets/chunk-5VM5RSS4-B5R1lSeY.js +15 -0
  130. package/dist/src/view/client/assets/chunk-F27PBJKO-Dm55FM_W.js +1 -0
  131. package/dist/src/view/client/assets/chunk-IMKFNOWR-ChptrvvM.js +231 -0
  132. package/dist/src/view/client/assets/chunk-JWPE2WC7-BRQBjrKS.js +1 -0
  133. package/dist/src/view/client/assets/chunk-POPQ4Y6H-CainVZIL.js +1 -0
  134. package/dist/src/view/client/assets/chunk-SVP7TREG-DsKsNGmM.js +88 -0
  135. package/dist/src/view/client/assets/chunk-TICWLB2K-BctkMcJc.js +206 -0
  136. package/dist/src/view/client/assets/chunk-XXDRQBXY-BN7SgOUT.js +1 -0
  137. package/dist/src/view/client/assets/classDiagram-ZZMXUADV-B1VyU6zO.js +1 -0
  138. package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-B1VyU6zO.js +1 -0
  139. package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-BszzwrMe.js +1 -0
  140. package/dist/src/view/client/assets/cynefin-OW5HDTMX-CdRyAkPs.js +166 -0
  141. package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-BLvKPZ1u.js +62 -0
  142. package/dist/src/view/client/assets/cytoscape.esm-DzSz-X2X.js +321 -0
  143. package/dist/src/view/client/assets/dagre-GXQ25YYZ-V68w_l65.js +4 -0
  144. package/dist/src/view/client/assets/defaultLocale-DX6XiGOO.js +1 -0
  145. package/dist/src/view/client/assets/diagram-S7CK7UJ4-C2i4eEMg.js +30 -0
  146. package/dist/src/view/client/assets/diagram-UQ7AKVKN-BiwWh5jC.js +41 -0
  147. package/dist/src/view/client/assets/diagram-VSXAHHWV-hkKR_vyS.js +3 -0
  148. package/dist/src/view/client/assets/diagram-VX7I27RA-DzRCSMAc.js +24 -0
  149. package/dist/src/view/client/assets/diagram-Z3DM3KII-fhSFPxyK.js +24 -0
  150. package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-CCEUDKSA.js +1 -0
  151. package/dist/src/view/client/assets/erDiagram-RLTQ6QDP-FJ2IMyTi.js +99 -0
  152. package/dist/src/view/client/assets/flowDiagram-HODETNUW-BvasdLeK.js +168 -0
  153. package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-CiwkBZvY.js +292 -0
  154. package/dist/src/view/client/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  155. package/dist/src/view/client/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  156. package/dist/src/view/client/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  157. package/dist/src/view/client/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  158. package/dist/src/view/client/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
  159. package/dist/src/view/client/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
  160. package/dist/src/view/client/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
  161. package/dist/src/view/client/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
  162. package/dist/src/view/client/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
  163. package/dist/src/view/client/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
  164. package/dist/src/view/client/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  165. package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-DYlP2_js.js +106 -0
  166. package/dist/src/view/client/assets/index-BnENo9bV.js +1 -0
  167. package/dist/src/view/client/assets/index-CQ7EOox7.css +1 -0
  168. package/dist/src/view/client/assets/index-CynNDkxt.js +13 -0
  169. package/dist/src/view/client/assets/infoDiagram-27XIBGKW-DRPB2c48.js +2 -0
  170. package/dist/src/view/client/assets/init-Gi6I4Gst.js +1 -0
  171. package/dist/src/view/client/assets/ishikawaDiagram-5VMMS53U-8VV429Cv.js +70 -0
  172. package/dist/src/view/client/assets/journeyDiagram-3NMN7TZE-Dzmwnf83.js +139 -0
  173. package/dist/src/view/client/assets/kanban-definition-UXKFOSKX-pYyZZ1i-.js +89 -0
  174. package/dist/src/view/client/assets/katex-HP8lGamR.js +257 -0
  175. package/dist/src/view/client/assets/layout-GF9k6yGo.js +1 -0
  176. package/dist/src/view/client/assets/linear-Yt2sSOYV.js +1 -0
  177. package/dist/src/view/client/assets/logo-RR_KBOAT.svg +149 -0
  178. package/dist/src/view/client/assets/maplibre-gl-CDX6Zuow.js +800 -0
  179. package/dist/src/view/client/assets/mermaid.core-ChWYCHN0.js +310 -0
  180. package/dist/src/view/client/assets/mindmap-definition-YA3MSWOX-Cc4fQvf1.js +96 -0
  181. package/dist/src/view/client/assets/ordinal-Cboi1Yqb.js +1 -0
  182. package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-C0SsB8bZ.js +1 -0
  183. package/dist/src/view/client/assets/pieDiagram-E7YTZNPT-DIJpqERZ.js +39 -0
  184. package/dist/src/view/client/assets/quadrantDiagram-AXDQQJYC--d-gl6j-.js +7 -0
  185. package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-BQxwTt7z.js +1 -0
  186. package/dist/src/view/client/assets/requirementDiagram-BXWQKSXE-B_oTeD2A.js +84 -0
  187. package/dist/src/view/client/assets/sankeyDiagram-P5KCCOFB-DLukmE8X.js +40 -0
  188. package/dist/src/view/client/assets/sequenceDiagram-WJ2MYXX4-BNjVB2sc.js +162 -0
  189. package/dist/src/view/client/assets/sizeCapture-INFHLROL-BZecQTOw.js +1 -0
  190. package/dist/src/view/client/assets/stateDiagram-D77RDMKH-Bu1urvXC.js +1 -0
  191. package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-5pc_697G.js +1 -0
  192. package/dist/src/view/client/assets/swimlanes-42K2YHIH-bLAlcepB.js +1 -0
  193. package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-BbOpZjpp.js +8 -0
  194. package/dist/src/view/client/assets/three.module-PDSP0dbZ.js +4108 -0
  195. package/dist/src/view/client/assets/timeline-definition-24CTP7MA-tbwCNvcA.js +120 -0
  196. package/dist/src/view/client/assets/vennDiagram-4TSXK5OY-D8U8Fk0N.js +34 -0
  197. package/dist/src/view/client/assets/wardleyDiagram-VM6X3IG4-LHBVIeNb.js +78 -0
  198. package/dist/src/view/client/assets/xychartDiagram-S5SC5T6Z-CN4tfaFV.js +7 -0
  199. package/dist/src/view/client/index.html +2 -2
  200. package/dist/src/view/client-shell.d.ts +2 -0
  201. package/dist/src/view/client-shell.js +5 -0
  202. package/dist/src/view/diagnostics.d.ts +3 -2
  203. package/dist/src/view/diagnostics.js +49 -58
  204. package/dist/src/view/document-edit.d.ts +8 -0
  205. package/dist/src/view/document-edit.js +25 -0
  206. package/dist/src/view/document-route.d.ts +14 -0
  207. package/dist/src/view/document-route.js +137 -0
  208. package/dist/src/view/document-tree.d.ts +18 -0
  209. package/dist/src/view/document-tree.js +139 -0
  210. package/dist/src/view/external-document-tree.d.ts +3 -0
  211. package/dist/src/view/external-document-tree.js +674 -0
  212. package/dist/src/view/git-diff.js +202 -2
  213. package/dist/src/view/git.js +1 -1
  214. package/dist/src/view/graph.d.ts +4 -3
  215. package/dist/src/view/graph.js +100 -9
  216. package/dist/src/view/highlight.d.ts +10 -2
  217. package/dist/src/view/highlight.js +50648 -3166
  218. package/dist/src/view/markdown.d.ts +3 -2
  219. package/dist/src/view/markdown.js +256 -54
  220. package/dist/src/view/preindexed-search.d.ts +15 -0
  221. package/dist/src/view/preindexed-search.js +25 -0
  222. package/dist/src/view/protocol.d.ts +53 -7
  223. package/dist/src/view/publication.d.ts +2 -0
  224. package/dist/src/view/publication.js +78 -0
  225. package/dist/src/view/references.d.ts +11 -26
  226. package/dist/src/view/references.js +121 -112
  227. package/dist/src/view/repository.d.ts +14 -4
  228. package/dist/src/view/repository.js +260 -19
  229. package/dist/src/view/request-security.d.ts +5 -0
  230. package/dist/src/view/request-security.js +46 -0
  231. package/dist/src/view/search-result.d.ts +4 -0
  232. package/dist/src/view/search-result.js +25 -0
  233. package/dist/src/view/search.d.ts +7 -2
  234. package/dist/src/view/search.js +23 -34
  235. package/dist/src/view/server-build.d.ts +21 -0
  236. package/dist/src/view/server-build.js +145 -0
  237. package/dist/src/view/server-deployment.d.ts +31 -0
  238. package/dist/src/view/server-deployment.js +123 -0
  239. package/dist/src/view/server-index-worker.d.ts +6 -0
  240. package/dist/src/view/server-index-worker.js +14 -0
  241. package/dist/src/view/server.d.ts +11 -2
  242. package/dist/src/view/server.js +245 -73
  243. package/dist/src/view/source-target.d.ts +2 -0
  244. package/dist/src/view/source-target.js +49 -8
  245. package/dist/src/view/static-build.d.ts +18 -2
  246. package/dist/src/view/static-build.js +449 -110
  247. package/dist/src/view/static-protocol.d.ts +26 -2
  248. package/dist/src/view/static-protocol.js +5 -0
  249. package/dist/src/view/store.d.ts +20 -3
  250. package/dist/src/view/store.js +304 -48
  251. package/dist/src/view/table-of-contents.d.ts +2 -2
  252. package/dist/src/view/table-of-contents.js +2 -22
  253. package/dist/src/view/vercel-build.d.ts +24 -0
  254. package/dist/src/view/vercel-build.js +152 -0
  255. package/dist/src/view/vercel-server-build.d.ts +10 -0
  256. package/dist/src/view/vercel-server-build.js +61 -0
  257. package/dist/src/wiki/catalog.d.ts +21 -0
  258. package/dist/src/wiki/catalog.js +256 -0
  259. package/dist/src/wiki/publish.d.ts +27 -0
  260. package/dist/src/wiki/publish.js +265 -0
  261. package/dist/src/wiki/render.d.ts +20 -0
  262. package/dist/src/wiki/render.js +163 -0
  263. package/dist/src/wiki/transform.d.ts +7 -0
  264. package/dist/src/wiki/transform.js +264 -0
  265. package/dist/vendor/lat.md-server/cli.d.ts +2 -0
  266. package/dist/vendor/lat.md-server/cli.js +12 -0
  267. package/dist/vendor/lat.md-server/index.d.ts +38 -0
  268. package/dist/vendor/lat.md-server/index.js +128 -0
  269. package/package.json +68 -22
  270. package/plugins/lat-md/README.md +61 -0
  271. package/plugins/lat-md/hooks.json +38 -0
  272. package/plugins/lat-md/plugin.json +9 -0
  273. package/plugins/lat-md/rules/AGENTS.md +344 -0
  274. package/plugins/lat-md/skills/lat-md/SKILL.md +210 -0
  275. package/plugins/lat-md/skills/lat-md-conventions/SKILL.md +226 -0
  276. package/templates/AGENTS.md +26 -7
  277. package/templates/cursor-rules.md +23 -7
  278. package/templates/fork/conventions.md +133 -11
  279. package/templates/opencode-plugin.ts +9 -9
  280. package/templates/pi-extension.ts +11 -11
  281. package/templates/skill/SKILL.md +35 -3
  282. package/dist/src/cli/check-coverage.d.ts +0 -2
  283. package/dist/src/cli/check-coverage.js +0 -71
  284. package/dist/src/cli/check-frontmatter.d.ts +0 -12
  285. package/dist/src/cli/check-frontmatter.js +0 -44
  286. package/dist/src/cli/check-mode.d.ts +0 -21
  287. package/dist/src/cli/check-mode.js +0 -364
  288. package/dist/src/cli/check-status.d.ts +0 -74
  289. package/dist/src/cli/check-status.js +0 -217
  290. package/dist/src/cli/check.d.ts +0 -45
  291. package/dist/src/cli/check.js +0 -781
  292. package/dist/src/cli/context.d.ts +0 -11
  293. package/dist/src/cli/context.js +0 -58
  294. package/dist/src/cli/expand.d.ts +0 -8
  295. package/dist/src/cli/expand.js +0 -94
  296. package/dist/src/cli/gen-index.d.ts +0 -45
  297. package/dist/src/cli/gen-index.js +0 -235
  298. package/dist/src/cli/link-scheme.d.ts +0 -54
  299. package/dist/src/cli/link-scheme.js +0 -101
  300. package/dist/src/cli/locate.d.ts +0 -2
  301. package/dist/src/cli/locate.js +0 -17
  302. package/dist/src/cli/refs.d.ts +0 -22
  303. package/dist/src/cli/refs.js +0 -229
  304. package/dist/src/cli/section.d.ts +0 -43
  305. package/dist/src/cli/section.js +0 -252
  306. package/dist/src/cli/select-menu.d.ts +0 -13
  307. package/dist/src/cli/select-menu.js +0 -100
  308. package/dist/src/code-refs.d.ts +0 -17
  309. package/dist/src/code-refs.js +0 -298
  310. package/dist/src/config.d.ts +0 -29
  311. package/dist/src/config.js +0 -83
  312. package/dist/src/context.d.ts +0 -23
  313. package/dist/src/context.js +0 -11
  314. package/dist/src/extensions/wiki-link/from-markdown.d.ts +0 -5
  315. package/dist/src/extensions/wiki-link/from-markdown.js +0 -34
  316. package/dist/src/extensions/wiki-link/index.d.ts +0 -4
  317. package/dist/src/extensions/wiki-link/index.js +0 -3
  318. package/dist/src/extensions/wiki-link/syntax.d.ts +0 -14
  319. package/dist/src/extensions/wiki-link/syntax.js +0 -121
  320. package/dist/src/extensions/wiki-link/to-markdown.d.ts +0 -5
  321. package/dist/src/extensions/wiki-link/to-markdown.js +0 -28
  322. package/dist/src/extensions/wiki-link/types.d.ts +0 -34
  323. package/dist/src/format.d.ts +0 -8
  324. package/dist/src/format.js +0 -43
  325. package/dist/src/init-version.d.ts +0 -10
  326. package/dist/src/init-version.js +0 -49
  327. package/dist/src/lattice.d.ts +0 -109
  328. package/dist/src/lattice.js +0 -817
  329. package/dist/src/parser.d.ts +0 -3
  330. package/dist/src/parser.js +0 -18
  331. package/dist/src/source-parser.d.ts +0 -27
  332. package/dist/src/source-parser.js +0 -916
  333. package/dist/src/untrusted.d.ts +0 -18
  334. package/dist/src/untrusted.js +0 -93
  335. package/dist/src/view/client/assets/index-C3iaZyYT.css +0 -1
  336. package/dist/src/view/client/assets/index-KWi67IMz.js +0 -334
  337. package/dist/src/view/client/assets/logo-CNF8zs47.svg +0 -182
  338. package/dist/src/walk.d.ts +0 -18
  339. package/dist/src/walk.js +0 -27
  340. /package/dist/src/{extensions/wiki-link → search}/types.js +0 -0
@@ -1,11 +0,0 @@
1
- import type { CmdContext, Styler } from '../context.js';
2
- export type { CmdContext };
3
- export declare function makeStyler(): Styler;
4
- export declare function resolveContext(opts: {
5
- dir?: string;
6
- color?: boolean;
7
- }): CmdContext;
8
- export declare function resolveCheckContext(opts: {
9
- dir?: string;
10
- color?: boolean;
11
- }, target?: string): CmdContext;
@@ -1,58 +0,0 @@
1
- import { statSync } from 'node:fs';
2
- import { dirname, resolve } from 'node:path';
3
- import { styleText } from 'node:util';
4
- import { findLatticeDir } from '../lattice.js';
5
- export function makeStyler() {
6
- return {
7
- bold: (s) => styleText('bold', s),
8
- dim: (s) => styleText('dim', s),
9
- red: (s) => styleText('red', s),
10
- cyan: (s) => styleText('cyan', s),
11
- white: (s) => styleText('white', s),
12
- green: (s) => styleText('green', s),
13
- yellow: (s) => styleText('yellow', s),
14
- boldWhite: (s) => styleText(['bold', 'white'], s),
15
- };
16
- }
17
- export function resolveContext(opts) {
18
- const color = opts.color !== false;
19
- if (!color) {
20
- process.env.NO_COLOR = '1';
21
- }
22
- const latDir = findLatticeDir(opts.dir) ?? '';
23
- if (!latDir) {
24
- console.error(styleText('red', 'No lat.md directory found'));
25
- console.error(styleText('dim', 'Run `lat init` to create one.'));
26
- process.exit(1);
27
- }
28
- const projectRoot = dirname(latDir);
29
- return { latDir, projectRoot, styler: makeStyler(), mode: 'cli' };
30
- }
31
- export function resolveCheckContext(opts, target) {
32
- if (target === undefined)
33
- return resolveContext(opts);
34
- if (opts.color === false) {
35
- process.env.NO_COLOR = '1';
36
- }
37
- const projectRoot = resolve(opts.dir ?? process.cwd());
38
- const latDir = resolve(projectRoot, target);
39
- try {
40
- if (!statSync(latDir).isDirectory()) {
41
- console.error(styleText('red', `Check target is not a directory: ${target}`));
42
- process.exit(1);
43
- }
44
- }
45
- catch (error) {
46
- if (error.code !== 'ENOENT')
47
- throw error;
48
- console.error(styleText('red', `Check directory not found: ${target}`));
49
- process.exit(1);
50
- }
51
- return {
52
- latDir,
53
- projectRoot,
54
- styler: makeStyler(),
55
- mode: 'cli',
56
- headless: true,
57
- };
58
- }
@@ -1,8 +0,0 @@
1
- import { type Section } from '../lattice.js';
2
- import type { CmdContext, CmdResult } from '../context.js';
3
- /**
4
- * Resolve [[refs]] in text and return the expanded output.
5
- * Returns null if there are no wiki links, or if resolution fails.
6
- */
7
- export declare function expandPrompt(ctx: CmdContext, text: string, preloadedSections?: Section[]): Promise<string | null>;
8
- export declare function expandCommand(ctx: CmdContext, text: string): Promise<CmdResult>;
@@ -1,94 +0,0 @@
1
- import { join, relative } from 'node:path';
2
- import { loadAllSections, findSections, } from '../lattice.js';
3
- import { UNTRUSTED_NOTICE, quoteUntrusted, cleanUntrustedId, } from '../untrusted.js';
4
- const WIKI_LINK_RE = /\[\[([^\]]+)\]\]/g;
5
- function formatLocation(section, projectRoot) {
6
- const relPath = relative(process.cwd(), join(projectRoot, section.filePath));
7
- return `${cleanUntrustedId(relPath)}:${section.startLine}-${section.endLine}`;
8
- }
9
- /**
10
- * Resolve [[refs]] in text and return the expanded output.
11
- * Returns null if there are no wiki links, or if resolution fails.
12
- */
13
- export async function expandPrompt(ctx, text, preloadedSections) {
14
- const refs = [...text.matchAll(WIKI_LINK_RE)];
15
- if (refs.length === 0)
16
- return null;
17
- const allSections = preloadedSections ?? (await loadAllSections(ctx.latDir));
18
- const resolved = new Map();
19
- const errors = [];
20
- for (const match of refs) {
21
- const target = match[1];
22
- if (resolved.has(target))
23
- continue;
24
- const matches = findSections(allSections, target);
25
- if (matches.length >= 1) {
26
- resolved.set(target, {
27
- target,
28
- best: matches[0],
29
- alternatives: matches.slice(1),
30
- });
31
- }
32
- else {
33
- errors.push(`No section found for [[${target}]]`);
34
- }
35
- }
36
- if (errors.length > 0)
37
- return null;
38
- // Replace [[refs]] inline
39
- let output = text.replace(WIKI_LINK_RE, (_match, target) => {
40
- const ref = resolved.get(target);
41
- return `[[${cleanUntrustedId(ref.best.section.id)}]]`;
42
- });
43
- // Append context block as nested outliner
44
- output += '\n\n<lat-context>\n';
45
- output += UNTRUSTED_NOTICE + '\n';
46
- for (const ref of resolved.values()) {
47
- const isExact = ref.best.reason === 'exact match' ||
48
- ref.best.reason.startsWith('file stem expanded');
49
- const all = isExact ? [ref.best] : [ref.best, ...ref.alternatives];
50
- if (isExact) {
51
- output += `* \`[[${ref.target}]]\` is referring to:\n`;
52
- }
53
- else {
54
- output += `* \`[[${ref.target}]]\` might be referring to either of the following:\n`;
55
- }
56
- for (const m of all) {
57
- const reason = isExact ? '' : ` (${cleanUntrustedId(m.reason)})`;
58
- output += ` * [[${cleanUntrustedId(m.section.id)}]]${reason}\n`;
59
- output += ` * ${formatLocation(m.section, ctx.projectRoot)}\n`;
60
- if (m.section.firstParagraph) {
61
- output += ` * ${quoteUntrusted(m.section.firstParagraph)}\n`;
62
- }
63
- }
64
- }
65
- output += '</lat-context>\n';
66
- return output;
67
- }
68
- export async function expandCommand(ctx, text) {
69
- const result = await expandPrompt(ctx, text);
70
- if (result === null) {
71
- const refs = [...text.matchAll(WIKI_LINK_RE)];
72
- if (refs.length === 0) {
73
- return { output: text };
74
- }
75
- // Resolution failed — find which ref is broken
76
- const allSections = await loadAllSections(ctx.latDir);
77
- for (const match of refs) {
78
- const target = match[1];
79
- const matches = findSections(allSections, target);
80
- if (matches.length === 0) {
81
- const s = ctx.styler;
82
- return {
83
- output: s.red(`No section found for [[${target}]]`) +
84
- ' (no exact, substring, or fuzzy matches).\n' +
85
- s.dim('Ask the user to correct the reference.'),
86
- isError: true,
87
- };
88
- }
89
- }
90
- // All refs matched individually but expansion still failed — shouldn't happen
91
- return { output: text };
92
- }
93
- return { output: result };
94
- }
@@ -1,45 +0,0 @@
1
- export declare function mdEscapeLabel(value: string): string;
2
- export declare function mdEscapeDest(value: string): string;
3
- export type IndexEntrySource = {
4
- /** Filesystem entry name: "notes.md" for a file, "guides" for a directory. */
5
- name: string;
6
- /**
7
- * Link destination relative to the index file being written: the child's
8
- * own filename ("notes.md"), or its own index file for a directory
9
- * ("guides/guides.md"). This is what actually resolves on disk — unlike
10
- * the wiki-link stem, it keeps the .md extension.
11
- */
12
- dest: string;
13
- /** Absolute path to read the title/summary from (the file itself, or a directory's own index file). */
14
- readFrom: string;
15
- };
16
- /**
17
- * Render the generated bullet list for a directory index, one entry per
18
- * child, sorted by title. Each entry links through the wiki-link stem
19
- * (`entryToStem`-compatible) using a real Markdown link so the title can
20
- * carry a human-written summary — which is exactly why it must be escaped:
21
- * the title is repository text landing inside `[...]`.
22
- */
23
- export declare function renderIndexEntries(entries: IndexEntrySource[]): Promise<string>;
24
- /**
25
- * Compute, for each line, whether it lies inside a fenced code block.
26
- * Marker and bullet-run detection must skip fenced lines — otherwise a
27
- * documentation example that shows the marker syntax (or a sample bullet
28
- * list) inside a ``` block gets mistaken for the real thing and rewritten.
29
- */
30
- export declare function fencedLineMask(lines: string[]): boolean[];
31
- export type SpliceResult = {
32
- ok: true;
33
- content: string;
34
- } | {
35
- ok: false;
36
- message: string;
37
- };
38
- /**
39
- * Splice a freshly rendered entry list into an index file's content inside
40
- * `<!-- lat:index:begin -->` / `<!-- lat:index:end -->` markers, preserving
41
- * everything outside that region byte for byte. An unmarked file is
42
- * migrated by wrapping the first contiguous run of local index entry
43
- * bullets; a malformed marker pair is refused rather than guessed at.
44
- */
45
- export declare function spliceIndexContent(existingContent: string | null, dirLabel: string, renderedList: string): SpliceResult;
@@ -1,235 +0,0 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { cleanUntrusted } from '../untrusted.js';
3
- import { isLatticeLocalDest } from './link-scheme.js';
4
- // Mirrors the two escaping rules in hooks/generate_docs_index.rb (see
5
- // lat-t1y.5). Both were found by a working exploit against that generator,
6
- // and the same exploit applies here: an index entry's title is repository
7
- // text (an H1 heading or a leading paragraph) placed into a generated
8
- // Markdown link, so it must be treated as untrusted the moment it is quoted.
9
- /**
10
- * Escape a link LABEL. Without this, a title of `Real](https://evil/)
11
- * [ignore` closes the generated link early and reopens it against an
12
- * attacker's URL, leaving the real target as the label of a second,
13
- * harmless-looking link. Backslash-escaping is CommonMark's own answer: each
14
- * of these renders as the literal character.
15
- */
16
- const MD_LABEL_SPECIALS = /([\\[\]()`])/g;
17
- export function mdEscapeLabel(value) {
18
- return value.replace(MD_LABEL_SPECIALS, '\\$1');
19
- }
20
- /**
21
- * Escape a link DESTINATION. A destination does not escape the same way a
22
- * label does: a `)` anywhere ends the destination there, and CommonMark reads
23
- * a bare `\` in a destination as an escape for the punctuation after it.
24
- * Percent-encoding survives the round trip; backslash-escaping does not,
25
- * because a renderer that decodes `%5C` back to `\` does not then treat it as
26
- * an escape character again.
27
- *
28
- * `%` itself must be in the class too, or the encoding is not injective: a
29
- * file genuinely named `a%28b.md` would be emitted verbatim and then decoded
30
- * by the renderer to `a(b.md` — a link to a path that does not exist.
31
- */
32
- const MD_DEST_SPECIALS = /[()<>\s%\\]/g;
33
- export function mdEscapeDest(value) {
34
- return value.replace(MD_DEST_SPECIALS, (c) => '%' + c.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0'));
35
- }
36
- function fallbackTitle(name) {
37
- const stem = name.endsWith('.md') ? name.slice(0, -3) : name;
38
- return stem.replace(/[-_]/g, ' ');
39
- }
40
- /**
41
- * Pull a title (first `# ` heading) and a summary (the paragraph that
42
- * follows it, or the document's own leading paragraph when it has no
43
- * heading) out of a document's raw text. Deliberately simple line scanning
44
- * rather than a full parse — good enough for index generation, and it avoids
45
- * depending on parseSections' heading-to-id machinery here.
46
- */
47
- async function titleAndSummary(readFrom, fallback) {
48
- let content;
49
- try {
50
- content = await readFile(readFrom, 'utf-8');
51
- }
52
- catch {
53
- return { title: fallback, summary: '(no summary yet)' };
54
- }
55
- const stripped = content.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, '');
56
- const lines = stripped.split(/\r?\n/);
57
- let idx = 0;
58
- while (idx < lines.length && lines[idx].trim() === '')
59
- idx++;
60
- let title = fallback;
61
- if (idx < lines.length && /^#\s+\S/.test(lines[idx])) {
62
- title = lines[idx].replace(/^#\s+/, '').trim();
63
- idx++;
64
- }
65
- while (idx < lines.length && lines[idx].trim() === '')
66
- idx++;
67
- const paraLines = [];
68
- while (idx < lines.length &&
69
- lines[idx].trim() !== '' &&
70
- !/^#{1,6}\s/.test(lines[idx]) &&
71
- !/^- /.test(lines[idx])) {
72
- paraLines.push(lines[idx]);
73
- idx++;
74
- }
75
- const summary = paraLines.join(' ').trim();
76
- return {
77
- title: cleanUntrusted(title || fallback, 120),
78
- summary: summary ? cleanUntrusted(summary, 300) : '(no summary yet)',
79
- };
80
- }
81
- /**
82
- * Render the generated bullet list for a directory index, one entry per
83
- * child, sorted by title. Each entry links through the wiki-link stem
84
- * (`entryToStem`-compatible) using a real Markdown link so the title can
85
- * carry a human-written summary — which is exactly why it must be escaped:
86
- * the title is repository text landing inside `[...]`.
87
- */
88
- export async function renderIndexEntries(entries) {
89
- const rendered = await Promise.all(entries.map(async (entry) => {
90
- const { title, summary } = await titleAndSummary(entry.readFrom, fallbackTitle(entry.name));
91
- return {
92
- title,
93
- line: `- [${mdEscapeLabel(title)}](${mdEscapeDest(entry.dest)}) — ${mdEscapeLabel(summary)}`,
94
- };
95
- }));
96
- rendered.sort((a, b) => a.title.toLowerCase().localeCompare(b.title.toLowerCase()));
97
- return rendered.map((r) => r.line).join('\n');
98
- }
99
- /** HTML comment markers delimiting the region `--fix` is allowed to rewrite. */
100
- const BEGIN_MARKER = '<!-- lat:index:begin -->';
101
- const END_MARKER = '<!-- lat:index:end -->';
102
- // Tolerant of a trailing \r so a CRLF file's marker lines still match —
103
- // `existingContent` is otherwise split on plain '\n' (see the module doc).
104
- const BEGIN_RE = /^<!-- lat:index:begin -->\r?$/;
105
- const END_RE = /^<!-- lat:index:end -->\r?$/;
106
- /**
107
- * True when `line` is a "local index entry bullet" per the shared predicate
108
- * documented in link-scheme.ts: the legacy wiki form, or a Markdown link
109
- * bullet whose destination names a child of this directory. This MUST agree
110
- * with `parseIndexEntries` in check.ts — both read the same bullets, and a
111
- * second, differently-behaved copy of the rule is exactly how they drift.
112
- */
113
- function isIndexEntryBulletLine(line) {
114
- const trimmed = line.replace(/\r$/, '');
115
- if (/^- \[\[/.test(trimmed))
116
- return true;
117
- const m = /^- \[(?:\\.|[^\]])*\]\(([^)]*)\)/.exec(trimmed);
118
- if (!m)
119
- return false;
120
- return isLatticeLocalDest(m[1]);
121
- }
122
- /** A fenced code block delimiter line (opening or closing ``` or ~~~). */
123
- const FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
124
- /**
125
- * Compute, for each line, whether it lies inside a fenced code block.
126
- * Marker and bullet-run detection must skip fenced lines — otherwise a
127
- * documentation example that shows the marker syntax (or a sample bullet
128
- * list) inside a ``` block gets mistaken for the real thing and rewritten.
129
- */
130
- export function fencedLineMask(lines) {
131
- const mask = new Array(lines.length).fill(false);
132
- let inFence = false;
133
- for (let i = 0; i < lines.length; i++) {
134
- const isFenceDelim = FENCE_RE.test(lines[i].replace(/\r$/, ''));
135
- if (isFenceDelim) {
136
- // The delimiter line itself counts as "inside" so it can never be
137
- // mistaken for a marker or entry bullet either.
138
- mask[i] = true;
139
- inFence = !inFence;
140
- }
141
- else {
142
- mask[i] = inFence;
143
- }
144
- }
145
- return mask;
146
- }
147
- /**
148
- * Splice a freshly rendered entry list into an index file's content inside
149
- * `<!-- lat:index:begin -->` / `<!-- lat:index:end -->` markers, preserving
150
- * everything outside that region byte for byte. An unmarked file is
151
- * migrated by wrapping the first contiguous run of local index entry
152
- * bullets; a malformed marker pair is refused rather than guessed at.
153
- */
154
- export function spliceIndexContent(existingContent, dirLabel, renderedList) {
155
- const block = `${BEGIN_MARKER}\n${renderedList}\n${END_MARKER}`;
156
- if (existingContent === null) {
157
- return { ok: true, content: `${dirLabel} directory index.\n\n${block}\n` };
158
- }
159
- const lines = existingContent.replace(/\n$/, '').split('\n');
160
- const fenced = fencedLineMask(lines);
161
- const beginIdx = lines.findIndex((l, i) => !fenced[i] && BEGIN_RE.test(l));
162
- // The end marker that matters is the first one AFTER begin (per the
163
- // design contract). Fall back to the first end anywhere so an end marker
164
- // with no begin at all is still detected and reported.
165
- let endIdx = -1;
166
- if (beginIdx !== -1) {
167
- for (let i = beginIdx + 1; i < lines.length; i++) {
168
- if (!fenced[i] && END_RE.test(lines[i])) {
169
- endIdx = i;
170
- break;
171
- }
172
- }
173
- }
174
- else {
175
- endIdx = lines.findIndex((l, i) => !fenced[i] && END_RE.test(l));
176
- }
177
- if (beginIdx !== -1 || endIdx !== -1) {
178
- if (beginIdx === -1) {
179
- return {
180
- ok: false,
181
- message: 'found a "lat:index:end" marker with no matching "lat:index:begin" marker — fix the markers by hand before running --fix again',
182
- };
183
- }
184
- if (endIdx === -1) {
185
- return {
186
- ok: false,
187
- message: 'found a "lat:index:begin" marker with no matching "lat:index:end" marker — fix the markers by hand before running --fix again',
188
- };
189
- }
190
- if (endIdx < beginIdx) {
191
- return {
192
- ok: false,
193
- message: 'found a "lat:index:end" marker before the "lat:index:begin" marker — fix the markers by hand before running --fix again',
194
- };
195
- }
196
- const before = lines.slice(0, beginIdx);
197
- const after = lines.slice(endIdx + 1);
198
- const rebuilt = [...before, block, ...after].join('\n');
199
- return { ok: true, content: `${rebuilt}\n` };
200
- }
201
- // No markers at all: migrate. Find the first contiguous run of local index
202
- // entry bullets and replace exactly that run with the marked block.
203
- let runStart = -1;
204
- let runEnd = -1;
205
- for (let i = 0; i < lines.length; i++) {
206
- if (!fenced[i] && isIndexEntryBulletLine(lines[i])) {
207
- if (runStart === -1)
208
- runStart = i;
209
- runEnd = i;
210
- }
211
- else if (runStart !== -1) {
212
- break;
213
- }
214
- }
215
- if (runStart !== -1) {
216
- const before = lines.slice(0, runStart);
217
- const after = lines.slice(runEnd + 1);
218
- const rebuilt = [...before, block, ...after].join('\n');
219
- return { ok: true, content: `${rebuilt}\n` };
220
- }
221
- // No entry-bullet run: insert before the first heading, or append at the end.
222
- const headingIdx = lines.findIndex((l, i) => !fenced[i] && /^#{2,6}\s/.test(l));
223
- if (headingIdx !== -1) {
224
- const before = lines.slice(0, headingIdx);
225
- while (before.length > 0 && before[before.length - 1].trim() === '') {
226
- before.pop();
227
- }
228
- const after = lines.slice(headingIdx);
229
- const rebuilt = [...before, '', block, '', ...after].join('\n');
230
- return { ok: true, content: `${rebuilt}\n` };
231
- }
232
- const trimmedExisting = lines.join('\n').replace(/\s+$/, '');
233
- const rebuilt = trimmedExisting.length > 0 ? `${trimmedExisting}\n\n${block}` : block;
234
- return { ok: true, content: `${rebuilt}\n` };
235
- }
@@ -1,54 +0,0 @@
1
- /**
2
- * Decide whether a Markdown link destination points inside the lattice or
3
- * out at the wider world.
4
- *
5
- * This exists as its own module because two callers need the same answer and
6
- * a second, differently-behaved copy of the rule is exactly how the two
7
- * drift: `parseIndexEntries` in check.ts decides which index bullets are
8
- * generated entries, and `spliceIndexContent` in gen-index.ts decides which
9
- * bullets belong to the region `--fix` is allowed to rewrite. If those two
10
- * ever disagree about a line, `--fix` rewrites a bullet the checker does not
11
- * track, or leaves one it does.
12
- *
13
- * `localLinkTarget` in check.ts applies the same rule inline for
14
- * relative-link validation. It is upstream code and is deliberately left
15
- * alone here; if this ever moves upstream, that is the call site to fold in.
16
- */
17
- /**
18
- * True when `url` carries a URL scheme (`https:`, `mailto:`, `file:`) and is
19
- * therefore not a path inside the lattice.
20
- *
21
- * A Windows drive letter is the one case that looks like a scheme and is not
22
- * — `C:\docs\a.md` matches the scheme grammar because a drive letter is a
23
- * single ASCII letter followed by a colon. Treat it as a path, the same way
24
- * `localLinkTarget` does, so the two agree.
25
- */
26
- export declare function hasUrlScheme(url: string): boolean;
27
- /**
28
- * True when `url` is a destination the lattice can own: no scheme, and not
29
- * rooted at the filesystem root. A root-absolute path is excluded for the
30
- * same reason `localLinkTarget` excludes it — it names a location outside
31
- * the lattice tree, so it is never a child entry of a directory index.
32
- */
33
- export declare function isLatticeLocalDest(url: string): boolean;
34
- /**
35
- * Reduce a Markdown link destination to the name of the directory child it
36
- * refers to, or null when it refers to no child of this directory at all.
37
- *
38
- * The naive reading — take the first `/`-separated segment — is wrong in
39
- * four distinct ways, and each one was observed producing a bogus entry
40
- * name that `lat check` then reported as a stale entry that "does not
41
- * exist":
42
- *
43
- * https://example.com/docs -> "https:" a scheme is not a path segment
44
- * ./notes.md -> "." a no-op prefix is not a child
45
- * ../siblings/x.md -> ".." this escapes the directory
46
- * notes.md#intro -> "notes.md#intro" fragments are not names
47
- *
48
- * Order is load-bearing. The fragment and query are split off BEFORE
49
- * percent-decoding, and the path is split on `/` BEFORE decoding too, for
50
- * the same reason `localLinkTarget` does it: `%23` and `%2F` decode to `#`
51
- * and `/`, and decoding first would let a filename that legitimately
52
- * contains either one truncate or split itself.
53
- */
54
- export declare function indexEntryNameFromDest(dest: string): string | null;
@@ -1,101 +0,0 @@
1
- /**
2
- * Decide whether a Markdown link destination points inside the lattice or
3
- * out at the wider world.
4
- *
5
- * This exists as its own module because two callers need the same answer and
6
- * a second, differently-behaved copy of the rule is exactly how the two
7
- * drift: `parseIndexEntries` in check.ts decides which index bullets are
8
- * generated entries, and `spliceIndexContent` in gen-index.ts decides which
9
- * bullets belong to the region `--fix` is allowed to rewrite. If those two
10
- * ever disagree about a line, `--fix` rewrites a bullet the checker does not
11
- * track, or leaves one it does.
12
- *
13
- * `localLinkTarget` in check.ts applies the same rule inline for
14
- * relative-link validation. It is upstream code and is deliberately left
15
- * alone here; if this ever moves upstream, that is the call site to fold in.
16
- */
17
- /**
18
- * True when `url` carries a URL scheme (`https:`, `mailto:`, `file:`) and is
19
- * therefore not a path inside the lattice.
20
- *
21
- * A Windows drive letter is the one case that looks like a scheme and is not
22
- * — `C:\docs\a.md` matches the scheme grammar because a drive letter is a
23
- * single ASCII letter followed by a colon. Treat it as a path, the same way
24
- * `localLinkTarget` does, so the two agree.
25
- */
26
- export function hasUrlScheme(url) {
27
- const u = url.trim();
28
- if (/^[a-zA-Z]:\\/.test(u))
29
- return false;
30
- return /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(u);
31
- }
32
- /**
33
- * True when `url` is a destination the lattice can own: no scheme, and not
34
- * rooted at the filesystem root. A root-absolute path is excluded for the
35
- * same reason `localLinkTarget` excludes it — it names a location outside
36
- * the lattice tree, so it is never a child entry of a directory index.
37
- */
38
- export function isLatticeLocalDest(url) {
39
- const u = url.trim();
40
- if (u === '')
41
- return false;
42
- if (u.startsWith('/'))
43
- return false;
44
- return !hasUrlScheme(u);
45
- }
46
- /**
47
- * Reduce a Markdown link destination to the name of the directory child it
48
- * refers to, or null when it refers to no child of this directory at all.
49
- *
50
- * The naive reading — take the first `/`-separated segment — is wrong in
51
- * four distinct ways, and each one was observed producing a bogus entry
52
- * name that `lat check` then reported as a stale entry that "does not
53
- * exist":
54
- *
55
- * https://example.com/docs -> "https:" a scheme is not a path segment
56
- * ./notes.md -> "." a no-op prefix is not a child
57
- * ../siblings/x.md -> ".." this escapes the directory
58
- * notes.md#intro -> "notes.md#intro" fragments are not names
59
- *
60
- * Order is load-bearing. The fragment and query are split off BEFORE
61
- * percent-decoding, and the path is split on `/` BEFORE decoding too, for
62
- * the same reason `localLinkTarget` does it: `%23` and `%2F` decode to `#`
63
- * and `/`, and decoding first would let a filename that legitimately
64
- * contains either one truncate or split itself.
65
- */
66
- export function indexEntryNameFromDest(dest) {
67
- if (!isLatticeLocalDest(dest))
68
- return null;
69
- const u = dest.trim();
70
- const queryAt = u.indexOf('?');
71
- const fragmentAt = u.indexOf('#');
72
- const pathEnd = Math.min(queryAt === -1 ? u.length : queryAt, fragmentAt === -1 ? u.length : fragmentAt);
73
- let path = u.slice(0, pathEnd);
74
- // `./` contributes nothing to the path, and may be repeated.
75
- while (path.startsWith('./'))
76
- path = path.slice(2);
77
- // `..` leaves the directory whose index this is, so whatever it names is
78
- // by definition not a child of it.
79
- if (path === '..' || path.startsWith('../'))
80
- return null;
81
- if (path === '' || path === '.')
82
- return null;
83
- const segment = path.split('/')[0];
84
- if (segment === '')
85
- return null;
86
- let decoded;
87
- try {
88
- decoded = decodeURIComponent(segment);
89
- }
90
- catch {
91
- decoded = segment;
92
- }
93
- // A percent-encoded `.` or `..` (e.g. `%2e%2e`) decodes to the same
94
- // traversal segment the raw check above already rejects. Re-check after
95
- // decoding so both spellings agree — this is a consistency fix, not a
96
- // security one: parseIndexEntries only compares names, it never builds a
97
- // filesystem path from one.
98
- if (decoded === '.' || decoded === '..')
99
- return null;
100
- return decoded;
101
- }
@@ -1,2 +0,0 @@
1
- import type { CmdContext, CmdResult } from '../context.js';
2
- export declare function locateCommand(ctx: CmdContext, query: string): Promise<CmdResult>;
@@ -1,17 +0,0 @@
1
- import { loadAllSections, findSections } from '../lattice.js';
2
- import { formatResultList } from '../format.js';
3
- export async function locateCommand(ctx, query) {
4
- const stripped = query.replace(/^\[\[|\]\]$/g, '');
5
- const sections = await loadAllSections(ctx.latDir);
6
- const matches = findSections(sections, stripped);
7
- if (matches.length === 0) {
8
- const s = ctx.styler;
9
- return {
10
- output: s.red(`No sections matching "${stripped}" (no exact, substring, or fuzzy matches)`),
11
- isError: true,
12
- };
13
- }
14
- return {
15
- output: formatResultList(ctx, `Sections matching "${stripped}":`, matches),
16
- };
17
- }
@@ -1,22 +0,0 @@
1
- import { type Section, type SectionMatch } from '../lattice.js';
2
- import type { CmdContext, CmdResult } from '../context.js';
3
- export type Scope = 'md' | 'code' | 'md+code';
4
- export type RefsFound = {
5
- kind: 'found';
6
- target: Section;
7
- mdRefs: SectionMatch[];
8
- codeRefs: string[];
9
- };
10
- export type RefsError = {
11
- kind: 'no-match';
12
- suggestions: SectionMatch[];
13
- };
14
- export type RefsResult = RefsFound | RefsError;
15
- /**
16
- * Find all sections and code locations that reference a given section or
17
- * source file. Accepts section ids (full-path, short-form) and source file
18
- * paths (e.g. src/app.rs#foo). Source file queries match wiki links directly
19
- * without section resolution.
20
- */
21
- export declare function findRefs(ctx: CmdContext, query: string, scope: Scope): Promise<RefsResult>;
22
- export declare function refsCommand(ctx: CmdContext, query: string, scope: Scope): Promise<CmdResult>;