@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.
- package/README.md +27 -3
- package/dist/src/cli/agent-invocation.d.ts +6 -0
- package/dist/src/cli/agent-invocation.js +23 -0
- package/dist/src/cli/checklist-menu.d.ts +2 -1
- package/dist/src/cli/checklist-menu.js +3 -2
- package/dist/src/cli/fork-instructions.d.ts +1 -0
- package/dist/src/cli/fork-instructions.js +8 -32
- package/dist/src/cli/fork-scaffold.js +2 -2
- package/dist/src/cli/graph.d.ts +1 -1
- package/dist/src/cli/hook.d.ts +26 -0
- package/dist/src/cli/hook.js +115 -64
- package/dist/src/cli/index.js +178 -70
- package/dist/src/cli/init-preferences.d.ts +4 -0
- package/dist/src/cli/init-preferences.js +36 -0
- package/dist/src/cli/init.d.ts +2 -1
- package/dist/src/cli/init.js +100 -60
- package/dist/src/cli/reindex.d.ts +1 -1
- package/dist/src/cli/reindex.js +7 -10
- package/dist/src/cli/search.d.ts +14 -4
- package/dist/src/cli/search.js +115 -101
- package/dist/src/cli/ui-build-server.d.ts +12 -0
- package/dist/src/cli/ui-build-server.js +26 -0
- package/dist/src/cli/ui-build.d.ts +1 -1
- package/dist/src/cli/ui-build.js +1 -1
- package/dist/src/cli/ui.d.ts +1 -1
- package/dist/src/cli/ui.js +1 -1
- package/dist/src/cli/wiki.d.ts +12 -0
- package/dist/src/cli/wiki.js +85 -0
- package/dist/src/fork/antigravity-hook.d.ts +47 -0
- package/dist/src/fork/antigravity-hook.js +424 -0
- package/dist/src/fork/antigravity-init.d.ts +17 -0
- package/dist/src/fork/antigravity-init.js +124 -0
- package/dist/src/fork/upstream-drift.js +1 -1
- package/dist/src/fork/upstream-guard.d.ts +1 -1
- package/dist/src/fork/upstream-guard.js +8 -7
- package/dist/src/graph-export.js +7 -7
- package/dist/src/knowledge/index.js +2 -2
- package/dist/src/mcp/server.js +34 -18
- package/dist/src/search/cache.d.ts +3 -0
- package/dist/src/search/cache.js +104 -0
- package/dist/src/search/chunks.d.ts +23 -0
- package/dist/src/search/chunks.js +200 -0
- package/dist/src/search/db.d.ts +28 -16
- package/dist/src/search/db.js +100 -40
- package/dist/src/search/embedder.d.ts +2 -1
- package/dist/src/search/embedder.js +7 -6
- package/dist/src/search/index.d.ts +6 -2
- package/dist/src/search/index.js +176 -70
- package/dist/src/search/lexical.d.ts +6 -0
- package/dist/src/search/lexical.js +36 -0
- package/dist/src/search/lock.d.ts +5 -0
- package/dist/src/search/lock.js +45 -0
- package/dist/src/search/query.d.ts +26 -0
- package/dist/src/search/query.js +103 -0
- package/dist/src/search/search.d.ts +16 -7
- package/dist/src/search/search.js +165 -21
- package/dist/src/search/types.d.ts +15 -0
- package/dist/src/view/client/assets/GraphView-D_xnk0bP.js +456 -0
- package/dist/src/view/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/src/view/client/assets/MarkdownEditor-bjqt_FoF.js +28 -0
- package/dist/src/view/client/assets/OrbitControls-DwcpQNja.js +1 -0
- package/dist/src/view/client/assets/STLLoader-CLWTKt5i.js +1 -0
- package/dist/src/view/client/assets/_commonjsHelpers-CqkleIqs.js +1 -0
- package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-kWGvtRnL.js +1 -0
- package/dist/src/view/client/assets/arc-BPAFd7cP.js +1 -0
- package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-CsY39oIR.js +36 -0
- package/dist/src/view/client/assets/blockDiagram-I7D4REHJ-DHGBG7BJ.js +129 -0
- package/dist/src/view/client/assets/c4Diagram-7LVT6UL2-vywK4eb7.js +38 -0
- package/dist/src/view/client/assets/channel-CX71L_qV.js +1 -0
- package/dist/src/view/client/assets/chunk-2Q5K7J3B-Do3Hz_ci.js +1 -0
- package/dist/src/view/client/assets/chunk-5VM5RSS4-B5R1lSeY.js +15 -0
- package/dist/src/view/client/assets/chunk-F27PBJKO-Dm55FM_W.js +1 -0
- package/dist/src/view/client/assets/chunk-IMKFNOWR-ChptrvvM.js +231 -0
- package/dist/src/view/client/assets/chunk-JWPE2WC7-BRQBjrKS.js +1 -0
- package/dist/src/view/client/assets/chunk-POPQ4Y6H-CainVZIL.js +1 -0
- package/dist/src/view/client/assets/chunk-SVP7TREG-DsKsNGmM.js +88 -0
- package/dist/src/view/client/assets/chunk-TICWLB2K-BctkMcJc.js +206 -0
- package/dist/src/view/client/assets/chunk-XXDRQBXY-BN7SgOUT.js +1 -0
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-B1VyU6zO.js +1 -0
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-B1VyU6zO.js +1 -0
- package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-BszzwrMe.js +1 -0
- package/dist/src/view/client/assets/cynefin-OW5HDTMX-CdRyAkPs.js +166 -0
- package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-BLvKPZ1u.js +62 -0
- package/dist/src/view/client/assets/cytoscape.esm-DzSz-X2X.js +321 -0
- package/dist/src/view/client/assets/dagre-GXQ25YYZ-V68w_l65.js +4 -0
- package/dist/src/view/client/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/src/view/client/assets/diagram-S7CK7UJ4-C2i4eEMg.js +30 -0
- package/dist/src/view/client/assets/diagram-UQ7AKVKN-BiwWh5jC.js +41 -0
- package/dist/src/view/client/assets/diagram-VSXAHHWV-hkKR_vyS.js +3 -0
- package/dist/src/view/client/assets/diagram-VX7I27RA-DzRCSMAc.js +24 -0
- package/dist/src/view/client/assets/diagram-Z3DM3KII-fhSFPxyK.js +24 -0
- package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-CCEUDKSA.js +1 -0
- package/dist/src/view/client/assets/erDiagram-RLTQ6QDP-FJ2IMyTi.js +99 -0
- package/dist/src/view/client/assets/flowDiagram-HODETNUW-BvasdLeK.js +168 -0
- package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-CiwkBZvY.js +292 -0
- package/dist/src/view/client/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/src/view/client/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/src/view/client/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/src/view/client/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/dist/src/view/client/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-DYlP2_js.js +106 -0
- package/dist/src/view/client/assets/index-BnENo9bV.js +1 -0
- package/dist/src/view/client/assets/index-CQ7EOox7.css +1 -0
- package/dist/src/view/client/assets/index-CynNDkxt.js +13 -0
- package/dist/src/view/client/assets/infoDiagram-27XIBGKW-DRPB2c48.js +2 -0
- package/dist/src/view/client/assets/init-Gi6I4Gst.js +1 -0
- package/dist/src/view/client/assets/ishikawaDiagram-5VMMS53U-8VV429Cv.js +70 -0
- package/dist/src/view/client/assets/journeyDiagram-3NMN7TZE-Dzmwnf83.js +139 -0
- package/dist/src/view/client/assets/kanban-definition-UXKFOSKX-pYyZZ1i-.js +89 -0
- package/dist/src/view/client/assets/katex-HP8lGamR.js +257 -0
- package/dist/src/view/client/assets/layout-GF9k6yGo.js +1 -0
- package/dist/src/view/client/assets/linear-Yt2sSOYV.js +1 -0
- package/dist/src/view/client/assets/logo-RR_KBOAT.svg +149 -0
- package/dist/src/view/client/assets/maplibre-gl-CDX6Zuow.js +800 -0
- package/dist/src/view/client/assets/mermaid.core-ChWYCHN0.js +310 -0
- package/dist/src/view/client/assets/mindmap-definition-YA3MSWOX-Cc4fQvf1.js +96 -0
- package/dist/src/view/client/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-C0SsB8bZ.js +1 -0
- package/dist/src/view/client/assets/pieDiagram-E7YTZNPT-DIJpqERZ.js +39 -0
- package/dist/src/view/client/assets/quadrantDiagram-AXDQQJYC--d-gl6j-.js +7 -0
- package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-BQxwTt7z.js +1 -0
- package/dist/src/view/client/assets/requirementDiagram-BXWQKSXE-B_oTeD2A.js +84 -0
- package/dist/src/view/client/assets/sankeyDiagram-P5KCCOFB-DLukmE8X.js +40 -0
- package/dist/src/view/client/assets/sequenceDiagram-WJ2MYXX4-BNjVB2sc.js +162 -0
- package/dist/src/view/client/assets/sizeCapture-INFHLROL-BZecQTOw.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-D77RDMKH-Bu1urvXC.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-5pc_697G.js +1 -0
- package/dist/src/view/client/assets/swimlanes-42K2YHIH-bLAlcepB.js +1 -0
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-BbOpZjpp.js +8 -0
- package/dist/src/view/client/assets/three.module-PDSP0dbZ.js +4108 -0
- package/dist/src/view/client/assets/timeline-definition-24CTP7MA-tbwCNvcA.js +120 -0
- package/dist/src/view/client/assets/vennDiagram-4TSXK5OY-D8U8Fk0N.js +34 -0
- package/dist/src/view/client/assets/wardleyDiagram-VM6X3IG4-LHBVIeNb.js +78 -0
- package/dist/src/view/client/assets/xychartDiagram-S5SC5T6Z-CN4tfaFV.js +7 -0
- package/dist/src/view/client/index.html +2 -2
- package/dist/src/view/client-shell.d.ts +2 -0
- package/dist/src/view/client-shell.js +5 -0
- package/dist/src/view/diagnostics.d.ts +3 -2
- package/dist/src/view/diagnostics.js +49 -58
- package/dist/src/view/document-edit.d.ts +8 -0
- package/dist/src/view/document-edit.js +25 -0
- package/dist/src/view/document-route.d.ts +14 -0
- package/dist/src/view/document-route.js +137 -0
- package/dist/src/view/document-tree.d.ts +18 -0
- package/dist/src/view/document-tree.js +139 -0
- package/dist/src/view/external-document-tree.d.ts +3 -0
- package/dist/src/view/external-document-tree.js +674 -0
- package/dist/src/view/git-diff.js +202 -2
- package/dist/src/view/git.js +1 -1
- package/dist/src/view/graph.d.ts +4 -3
- package/dist/src/view/graph.js +100 -9
- package/dist/src/view/highlight.d.ts +10 -2
- package/dist/src/view/highlight.js +50648 -3166
- package/dist/src/view/markdown.d.ts +3 -2
- package/dist/src/view/markdown.js +256 -54
- package/dist/src/view/preindexed-search.d.ts +15 -0
- package/dist/src/view/preindexed-search.js +25 -0
- package/dist/src/view/protocol.d.ts +53 -7
- package/dist/src/view/publication.d.ts +2 -0
- package/dist/src/view/publication.js +78 -0
- package/dist/src/view/references.d.ts +11 -26
- package/dist/src/view/references.js +121 -112
- package/dist/src/view/repository.d.ts +14 -4
- package/dist/src/view/repository.js +260 -19
- package/dist/src/view/request-security.d.ts +5 -0
- package/dist/src/view/request-security.js +46 -0
- package/dist/src/view/search-result.d.ts +4 -0
- package/dist/src/view/search-result.js +25 -0
- package/dist/src/view/search.d.ts +7 -2
- package/dist/src/view/search.js +23 -34
- package/dist/src/view/server-build.d.ts +21 -0
- package/dist/src/view/server-build.js +145 -0
- package/dist/src/view/server-deployment.d.ts +31 -0
- package/dist/src/view/server-deployment.js +123 -0
- package/dist/src/view/server-index-worker.d.ts +6 -0
- package/dist/src/view/server-index-worker.js +14 -0
- package/dist/src/view/server.d.ts +11 -2
- package/dist/src/view/server.js +245 -73
- package/dist/src/view/source-target.d.ts +2 -0
- package/dist/src/view/source-target.js +49 -8
- package/dist/src/view/static-build.d.ts +18 -2
- package/dist/src/view/static-build.js +449 -110
- package/dist/src/view/static-protocol.d.ts +26 -2
- package/dist/src/view/static-protocol.js +5 -0
- package/dist/src/view/store.d.ts +20 -3
- package/dist/src/view/store.js +304 -48
- package/dist/src/view/table-of-contents.d.ts +2 -2
- package/dist/src/view/table-of-contents.js +2 -22
- package/dist/src/view/vercel-build.d.ts +24 -0
- package/dist/src/view/vercel-build.js +152 -0
- package/dist/src/view/vercel-server-build.d.ts +10 -0
- package/dist/src/view/vercel-server-build.js +61 -0
- package/dist/src/wiki/catalog.d.ts +21 -0
- package/dist/src/wiki/catalog.js +256 -0
- package/dist/src/wiki/publish.d.ts +27 -0
- package/dist/src/wiki/publish.js +265 -0
- package/dist/src/wiki/render.d.ts +20 -0
- package/dist/src/wiki/render.js +163 -0
- package/dist/src/wiki/transform.d.ts +7 -0
- package/dist/src/wiki/transform.js +264 -0
- package/dist/vendor/lat.md-server/cli.d.ts +2 -0
- package/dist/vendor/lat.md-server/cli.js +12 -0
- package/dist/vendor/lat.md-server/index.d.ts +38 -0
- package/dist/vendor/lat.md-server/index.js +128 -0
- package/package.json +68 -22
- package/plugins/lat-md/README.md +61 -0
- package/plugins/lat-md/hooks.json +38 -0
- package/plugins/lat-md/plugin.json +9 -0
- package/plugins/lat-md/rules/AGENTS.md +344 -0
- package/plugins/lat-md/skills/lat-md/SKILL.md +210 -0
- package/plugins/lat-md/skills/lat-md-conventions/SKILL.md +226 -0
- package/templates/AGENTS.md +26 -7
- package/templates/cursor-rules.md +23 -7
- package/templates/fork/conventions.md +133 -11
- package/templates/opencode-plugin.ts +9 -9
- package/templates/pi-extension.ts +11 -11
- package/templates/skill/SKILL.md +35 -3
- package/dist/src/cli/check-coverage.d.ts +0 -2
- package/dist/src/cli/check-coverage.js +0 -71
- package/dist/src/cli/check-frontmatter.d.ts +0 -12
- package/dist/src/cli/check-frontmatter.js +0 -44
- package/dist/src/cli/check-mode.d.ts +0 -21
- package/dist/src/cli/check-mode.js +0 -364
- package/dist/src/cli/check-status.d.ts +0 -74
- package/dist/src/cli/check-status.js +0 -217
- package/dist/src/cli/check.d.ts +0 -45
- package/dist/src/cli/check.js +0 -781
- package/dist/src/cli/context.d.ts +0 -11
- package/dist/src/cli/context.js +0 -58
- package/dist/src/cli/expand.d.ts +0 -8
- package/dist/src/cli/expand.js +0 -94
- package/dist/src/cli/gen-index.d.ts +0 -45
- package/dist/src/cli/gen-index.js +0 -235
- package/dist/src/cli/link-scheme.d.ts +0 -54
- package/dist/src/cli/link-scheme.js +0 -101
- package/dist/src/cli/locate.d.ts +0 -2
- package/dist/src/cli/locate.js +0 -17
- package/dist/src/cli/refs.d.ts +0 -22
- package/dist/src/cli/refs.js +0 -229
- package/dist/src/cli/section.d.ts +0 -43
- package/dist/src/cli/section.js +0 -252
- package/dist/src/cli/select-menu.d.ts +0 -13
- package/dist/src/cli/select-menu.js +0 -100
- package/dist/src/code-refs.d.ts +0 -17
- package/dist/src/code-refs.js +0 -298
- package/dist/src/config.d.ts +0 -29
- package/dist/src/config.js +0 -83
- package/dist/src/context.d.ts +0 -23
- package/dist/src/context.js +0 -11
- package/dist/src/extensions/wiki-link/from-markdown.d.ts +0 -5
- package/dist/src/extensions/wiki-link/from-markdown.js +0 -34
- package/dist/src/extensions/wiki-link/index.d.ts +0 -4
- package/dist/src/extensions/wiki-link/index.js +0 -3
- package/dist/src/extensions/wiki-link/syntax.d.ts +0 -14
- package/dist/src/extensions/wiki-link/syntax.js +0 -121
- package/dist/src/extensions/wiki-link/to-markdown.d.ts +0 -5
- package/dist/src/extensions/wiki-link/to-markdown.js +0 -28
- package/dist/src/extensions/wiki-link/types.d.ts +0 -34
- package/dist/src/format.d.ts +0 -8
- package/dist/src/format.js +0 -43
- package/dist/src/init-version.d.ts +0 -10
- package/dist/src/init-version.js +0 -49
- package/dist/src/lattice.d.ts +0 -109
- package/dist/src/lattice.js +0 -817
- package/dist/src/parser.d.ts +0 -3
- package/dist/src/parser.js +0 -18
- package/dist/src/source-parser.d.ts +0 -27
- package/dist/src/source-parser.js +0 -916
- package/dist/src/untrusted.d.ts +0 -18
- package/dist/src/untrusted.js +0 -93
- package/dist/src/view/client/assets/index-C3iaZyYT.css +0 -1
- package/dist/src/view/client/assets/index-KWi67IMz.js +0 -334
- package/dist/src/view/client/assets/logo-CNF8zs47.svg +0 -182
- package/dist/src/walk.d.ts +0 -18
- package/dist/src/walk.js +0 -27
- /package/dist/src/{extensions/wiki-link → search}/types.js +0 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { existsSync, statSync } from 'node:fs';
|
|
2
|
+
import { dirname, isAbsolute, relative, resolve } from 'node:path';
|
|
3
|
+
import { buildFileIndex, buildSectionSlugIndex, flattenSections, resolveRef, } from '@plebeiantech/lat.md-core/lattice';
|
|
4
|
+
import { inspectRepositoryPath, normalizeRepositoryPath, } from '@plebeiantech/lat.md-core/repository-path';
|
|
5
|
+
import { resolveSourceSymbol, } from '@plebeiantech/lat.md-core/source-parser';
|
|
6
|
+
import { isSourceFilePath } from '@plebeiantech/lat.md-core/source-formats';
|
|
7
|
+
import { parse } from '@plebeiantech/lat.md-core/parser';
|
|
8
|
+
import { toPosix } from '@plebeiantech/lat.md-core/path';
|
|
9
|
+
function collectTargetNodes(node, list) {
|
|
10
|
+
if ((node.type === 'wikiLink' || node.type === 'link') &&
|
|
11
|
+
node.position?.start?.offset != null &&
|
|
12
|
+
node.position?.end?.offset != null) {
|
|
13
|
+
list.push(node);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if ('children' in node &&
|
|
17
|
+
Array.isArray(node.children)) {
|
|
18
|
+
for (const child of node.children) {
|
|
19
|
+
collectTargetNodes(child, list);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async function rewriteText(text, baseDir, ctx) {
|
|
24
|
+
if (!text)
|
|
25
|
+
return text;
|
|
26
|
+
const tree = parse(text);
|
|
27
|
+
const nodes = [];
|
|
28
|
+
collectTargetNodes(tree, nodes);
|
|
29
|
+
if (nodes.length === 0)
|
|
30
|
+
return text;
|
|
31
|
+
const repoUrl = ctx.options?.repoUrl?.replace(/\/+$/, '');
|
|
32
|
+
const ref = ctx.options?.ref ?? 'HEAD';
|
|
33
|
+
const replacements = [];
|
|
34
|
+
for (const node of nodes) {
|
|
35
|
+
const start = node.position.start.offset;
|
|
36
|
+
const end = node.position.end.offset;
|
|
37
|
+
if (node.type === 'wikiLink') {
|
|
38
|
+
const target = (node.value ?? '').trim();
|
|
39
|
+
const alias = node.data?.alias ? node.data.alias.trim() : undefined;
|
|
40
|
+
// 1. Try to resolve as Markdown section
|
|
41
|
+
const refResult = resolveRef(target, ctx.sectionIds, ctx.fileIndex, ctx.slugIndex);
|
|
42
|
+
const section = refResult?.resolved
|
|
43
|
+
? ctx.sectionByLowerId.get(refResult.resolved.toLowerCase())
|
|
44
|
+
: undefined;
|
|
45
|
+
if (section) {
|
|
46
|
+
const doc = ctx.docByFilePath.get(section.filePath);
|
|
47
|
+
const label = alias ?? section.heading;
|
|
48
|
+
if (doc) {
|
|
49
|
+
// Exported Diataxis section link
|
|
50
|
+
const dest = section.depth === 1
|
|
51
|
+
? doc.slug
|
|
52
|
+
: `${doc.slug}#${section.githubSlug}`;
|
|
53
|
+
replacements.push({ start, end, replacement: `[${label}](${dest})` });
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// Non-exported lat.md section link
|
|
57
|
+
if (repoUrl) {
|
|
58
|
+
const frag = section.githubSlug ? `#${section.githubSlug}` : '';
|
|
59
|
+
replacements.push({
|
|
60
|
+
start,
|
|
61
|
+
end,
|
|
62
|
+
replacement: `[${label}](${repoUrl}/blob/${ref}/${section.filePath}${frag})`,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
replacements.push({ start, end, replacement: label });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
// 2. Source code and repository path link
|
|
72
|
+
const hashIdx = target.indexOf('#');
|
|
73
|
+
const filePart = hashIdx >= 0 ? target.slice(0, hashIdx) : target;
|
|
74
|
+
const symbolPath = hashIdx >= 0 ? target.slice(hashIdx + 1) : undefined;
|
|
75
|
+
const normalizedPath = normalizeRepositoryPath(filePart);
|
|
76
|
+
if (!normalizedPath) {
|
|
77
|
+
replacements.push({ start, end, replacement: alias ?? target });
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const inspected = await inspectRepositoryPath(ctx.catalog.projectRoot, normalizedPath);
|
|
81
|
+
if (inspected.kind !== 'file' && inspected.kind !== 'directory') {
|
|
82
|
+
replacements.push({ start, end, replacement: alias ?? target });
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const label = alias ?? (symbolPath || normalizedPath);
|
|
86
|
+
if (symbolPath && isSourceFilePath(normalizedPath)) {
|
|
87
|
+
const symbolResult = await resolveSourceSymbol(normalizedPath, symbolPath, ctx.catalog.projectRoot, { latDir: ctx.catalog.latDir });
|
|
88
|
+
const parts = symbolPath.split('#');
|
|
89
|
+
let symbol;
|
|
90
|
+
if (parts.length === 1) {
|
|
91
|
+
symbol = symbolResult.symbols.find((s) => s.name === parts[0] && !s.parent);
|
|
92
|
+
}
|
|
93
|
+
else if (parts.length === 2) {
|
|
94
|
+
symbol = symbolResult.symbols.find((s) => s.name === parts[1] && s.parent === parts[0]);
|
|
95
|
+
}
|
|
96
|
+
if (symbol) {
|
|
97
|
+
const lineFrag = symbol.startLine === symbol.endLine
|
|
98
|
+
? `#L${symbol.startLine}`
|
|
99
|
+
: `#L${symbol.startLine}-L${symbol.endLine}`;
|
|
100
|
+
if (repoUrl) {
|
|
101
|
+
replacements.push({
|
|
102
|
+
start,
|
|
103
|
+
end,
|
|
104
|
+
replacement: `[${label}](${repoUrl}/blob/${ref}/${normalizedPath}${lineFrag})`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
replacements.push({ start, end, replacement: label });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
if (repoUrl) {
|
|
113
|
+
replacements.push({
|
|
114
|
+
start,
|
|
115
|
+
end,
|
|
116
|
+
replacement: `[${label}](${repoUrl}/blob/${ref}/${normalizedPath})`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
replacements.push({ start, end, replacement: label });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const action = inspected.kind === 'directory' ? 'tree' : 'blob';
|
|
126
|
+
if (repoUrl) {
|
|
127
|
+
replacements.push({
|
|
128
|
+
start,
|
|
129
|
+
end,
|
|
130
|
+
replacement: `[${label}](${repoUrl}/${action}/${ref}/${normalizedPath})`,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
replacements.push({ start, end, replacement: label });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else if (node.type === 'link') {
|
|
139
|
+
const url = node.url ?? '';
|
|
140
|
+
// Skip same-page anchors and external URLs
|
|
141
|
+
if (url.startsWith('#') ||
|
|
142
|
+
url.startsWith('http://') ||
|
|
143
|
+
url.startsWith('https://') ||
|
|
144
|
+
url.startsWith('mailto:') ||
|
|
145
|
+
url.startsWith('tel:')) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
// Extract inner label text
|
|
149
|
+
let label = '';
|
|
150
|
+
if (node.children && node.children.length > 0) {
|
|
151
|
+
const first = node.children[0];
|
|
152
|
+
const last = node.children[node.children.length - 1];
|
|
153
|
+
if (first.position?.start?.offset != null &&
|
|
154
|
+
last.position?.end?.offset != null) {
|
|
155
|
+
label = text.slice(first.position.start.offset, last.position.end.offset);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const hashIdx = url.indexOf('#');
|
|
159
|
+
const pathPart = hashIdx >= 0 ? url.slice(0, hashIdx) : url;
|
|
160
|
+
const frag = hashIdx >= 0 ? url.slice(hashIdx) : '';
|
|
161
|
+
const resolvedPath = resolve(baseDir, pathPart);
|
|
162
|
+
const relToRoot = relative(ctx.catalog.projectRoot, resolvedPath);
|
|
163
|
+
const isInsideRoot = !relToRoot.startsWith('..') && !isAbsolute(relToRoot);
|
|
164
|
+
if (!isInsideRoot) {
|
|
165
|
+
// Prevent path traversal escape: do not rewrite links escaping project root
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const repoRelPath = toPosix(relToRoot);
|
|
169
|
+
const doc = ctx.docByFilePath.get(repoRelPath) ??
|
|
170
|
+
ctx.docByFilePath.get(repoRelPath + '.md');
|
|
171
|
+
if (doc) {
|
|
172
|
+
replacements.push({
|
|
173
|
+
start,
|
|
174
|
+
end,
|
|
175
|
+
replacement: `[${label}](${doc.slug}${frag})`,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
else if (existsSync(resolvedPath)) {
|
|
179
|
+
let isDir = false;
|
|
180
|
+
try {
|
|
181
|
+
isDir = statSync(resolvedPath).isDirectory();
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// ignore
|
|
185
|
+
}
|
|
186
|
+
const action = isDir ? 'tree' : 'blob';
|
|
187
|
+
if (repoUrl) {
|
|
188
|
+
replacements.push({
|
|
189
|
+
start,
|
|
190
|
+
end,
|
|
191
|
+
replacement: `[${label}](${repoUrl}/${action}/${ref}/${repoRelPath}${frag})`,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
replacements.push({ start, end, replacement: label });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Apply replacements in reverse order of appearance
|
|
201
|
+
replacements.sort((a, b) => b.start - a.start);
|
|
202
|
+
let result = text;
|
|
203
|
+
for (const rep of replacements) {
|
|
204
|
+
result =
|
|
205
|
+
result.slice(0, rep.start) + rep.replacement + result.slice(rep.end);
|
|
206
|
+
}
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
function createTransformContext(catalog, options) {
|
|
210
|
+
const flat = flattenSections(catalog.allSections);
|
|
211
|
+
const sectionIds = new Set(flat.map((s) => s.id.toLowerCase()));
|
|
212
|
+
const sectionByLowerId = new Map(flat.map((s) => [s.id.toLowerCase(), s]));
|
|
213
|
+
const fileIndex = buildFileIndex(catalog.allSections);
|
|
214
|
+
const slugIndex = buildSectionSlugIndex(catalog.allSections);
|
|
215
|
+
const docByFilePath = new Map(catalog.docs.map((d) => [d.filePath, d]));
|
|
216
|
+
const docByRelPath = new Map(catalog.docs.map((d) => [d.relPath, d]));
|
|
217
|
+
return {
|
|
218
|
+
catalog,
|
|
219
|
+
options,
|
|
220
|
+
sectionIds,
|
|
221
|
+
sectionByLowerId,
|
|
222
|
+
fileIndex,
|
|
223
|
+
slugIndex,
|
|
224
|
+
docByFilePath,
|
|
225
|
+
docByRelPath,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
export async function transformWikiDocument(doc, catalog, options) {
|
|
229
|
+
const ctx = createTransformContext(catalog, options);
|
|
230
|
+
const baseDir = resolve(catalog.projectRoot, dirname(doc.filePath));
|
|
231
|
+
const [body, firstParagraph] = await Promise.all([
|
|
232
|
+
rewriteText(doc.body, baseDir, ctx),
|
|
233
|
+
rewriteText(doc.firstParagraph, baseDir, ctx),
|
|
234
|
+
]);
|
|
235
|
+
return {
|
|
236
|
+
...doc,
|
|
237
|
+
body,
|
|
238
|
+
firstParagraph,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
export async function transformWikiCatalog(catalog, options) {
|
|
242
|
+
const ctx = createTransformContext(catalog, options);
|
|
243
|
+
const transformedDocs = await Promise.all(catalog.docs.map(async (doc) => {
|
|
244
|
+
const baseDir = resolve(catalog.projectRoot, dirname(doc.filePath));
|
|
245
|
+
const [body, firstParagraph] = await Promise.all([
|
|
246
|
+
rewriteText(doc.body, baseDir, ctx),
|
|
247
|
+
rewriteText(doc.firstParagraph, baseDir, ctx),
|
|
248
|
+
]);
|
|
249
|
+
return {
|
|
250
|
+
...doc,
|
|
251
|
+
body,
|
|
252
|
+
firstParagraph,
|
|
253
|
+
};
|
|
254
|
+
}));
|
|
255
|
+
let rootOverview = catalog.rootOverview;
|
|
256
|
+
if (rootOverview) {
|
|
257
|
+
rootOverview = await rewriteText(rootOverview, catalog.latDir, ctx);
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
...catalog,
|
|
261
|
+
rootOverview,
|
|
262
|
+
docs: transformedDocs,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { runLatServer } from './index.js';
|
|
5
|
+
const entry = process.argv[2];
|
|
6
|
+
if (!entry)
|
|
7
|
+
throw new Error('Usage: lat-ui-server <app-module>');
|
|
8
|
+
const module = (await import(pathToFileURL(resolve(entry)).href));
|
|
9
|
+
if (typeof module.default !== 'function') {
|
|
10
|
+
throw new Error(`${entry} must default-export an Express app`);
|
|
11
|
+
}
|
|
12
|
+
await runLatServer(module.default, { close: module.close });
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type IncomingMessage, type RequestListener, type Server, type ServerResponse } from 'node:http';
|
|
2
|
+
import { type Express } from 'express';
|
|
3
|
+
export declare const LAT_UI_CONTENT_SECURITY_POLICY = "default-src 'self'; connect-src 'self' https://tiles.openfreemap.org; font-src 'self' data:; img-src 'self' data: https://github.com https://github.githubassets.com https://img.shields.io; style-src 'self' 'unsafe-inline'; worker-src 'self' blob:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'";
|
|
4
|
+
export type LatServerAppOptions = {
|
|
5
|
+
/** Handle dynamic routes before immutable files and fallback handlers. */
|
|
6
|
+
handle?: LatServerRequestHandler;
|
|
7
|
+
/** Serve a completed Lat UI export after dynamic routes. */
|
|
8
|
+
publicDir?: string;
|
|
9
|
+
};
|
|
10
|
+
export type LatServerApp = RequestListener;
|
|
11
|
+
export type LatServerRequestHandler = (req: IncomingMessage, res: ServerResponse, next: (error?: unknown) => void) => void | Promise<void>;
|
|
12
|
+
export type ListenLatServerOptions = {
|
|
13
|
+
host: string;
|
|
14
|
+
port: number;
|
|
15
|
+
/** Advance through occupied ports. Explicit user ports should leave this off. */
|
|
16
|
+
findAvailablePort?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type RunningLatServer = {
|
|
19
|
+
server: Server;
|
|
20
|
+
host: string;
|
|
21
|
+
port: number;
|
|
22
|
+
url: string;
|
|
23
|
+
close: () => Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
/** Create the common Express stack used by live and exported Lat UI servers. */
|
|
26
|
+
export declare function createLatServerApp(options?: LatServerAppOptions, app?: Express): LatServerApp;
|
|
27
|
+
/** Listen with the same strict-or-next-port behavior in every Lat UI host. */
|
|
28
|
+
export declare function listenLatServer(app: LatServerApp, options: ListenLatServerOptions): Promise<RunningLatServer>;
|
|
29
|
+
export type RunLatServerOptions = {
|
|
30
|
+
host?: string;
|
|
31
|
+
port?: number;
|
|
32
|
+
close?: () => void | Promise<void>;
|
|
33
|
+
log?: (message: string) => void;
|
|
34
|
+
};
|
|
35
|
+
/** Run an exported Express app until the standalone process is terminated. */
|
|
36
|
+
export declare function runLatServer(app: LatServerApp, options?: RunLatServerOptions): Promise<RunningLatServer>;
|
|
37
|
+
/** Read this published package's exact version for generated artifacts. */
|
|
38
|
+
export declare function getLatServerVersion(): string;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { createServer, } from 'node:http';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import express from 'express';
|
|
4
|
+
export const LAT_UI_CONTENT_SECURITY_POLICY = "default-src 'self'; connect-src 'self' https://tiles.openfreemap.org; font-src 'self' data:; img-src 'self' data: https://github.com https://github.githubassets.com https://img.shields.io; style-src 'self' 'unsafe-inline'; worker-src 'self' blob:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'";
|
|
5
|
+
function setSecurityHeaders(res) {
|
|
6
|
+
res.setHeader('Content-Security-Policy', LAT_UI_CONTENT_SECURITY_POLICY);
|
|
7
|
+
res.setHeader('Referrer-Policy', 'no-referrer');
|
|
8
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
9
|
+
}
|
|
10
|
+
function isImmutablePublicFile(path) {
|
|
11
|
+
const parts = path.split(/[/\\]/);
|
|
12
|
+
if (parts.includes('assets'))
|
|
13
|
+
return true;
|
|
14
|
+
return /[/\\]data[/\\][^/\\]+[/\\][a-f0-9]{20}\.json$/.test(path);
|
|
15
|
+
}
|
|
16
|
+
/** Create the common Express stack used by live and exported Lat UI servers. */
|
|
17
|
+
export function createLatServerApp(options = {}, app = express()) {
|
|
18
|
+
app.disable('x-powered-by');
|
|
19
|
+
app.use((_req, res, next) => {
|
|
20
|
+
setSecurityHeaders(res);
|
|
21
|
+
next();
|
|
22
|
+
});
|
|
23
|
+
if (options.handle) {
|
|
24
|
+
app.use((req, res, next) => {
|
|
25
|
+
try {
|
|
26
|
+
void Promise.resolve(options.handle(req, res, next)).catch(next);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
next(error);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (options.publicDir) {
|
|
34
|
+
app.use(express.static(options.publicDir, {
|
|
35
|
+
setHeaders(res, path) {
|
|
36
|
+
res.setHeader('Cache-Control', isImmutablePublicFile(path)
|
|
37
|
+
? 'public, max-age=31536000, immutable'
|
|
38
|
+
: 'no-cache');
|
|
39
|
+
},
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
app.use((_req, res) => {
|
|
43
|
+
res.status(404).type('text/plain').send('Not found');
|
|
44
|
+
});
|
|
45
|
+
app.use((error, _req, res, _next) => {
|
|
46
|
+
console.error(error);
|
|
47
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
48
|
+
});
|
|
49
|
+
return app;
|
|
50
|
+
}
|
|
51
|
+
function listen(server, host, port) {
|
|
52
|
+
return new Promise((resolveListen, reject) => {
|
|
53
|
+
const onError = (error) => {
|
|
54
|
+
server.off('listening', onListening);
|
|
55
|
+
reject(error);
|
|
56
|
+
};
|
|
57
|
+
const onListening = () => {
|
|
58
|
+
server.off('error', onError);
|
|
59
|
+
resolveListen();
|
|
60
|
+
};
|
|
61
|
+
server.once('error', onError);
|
|
62
|
+
server.once('listening', onListening);
|
|
63
|
+
server.listen(port, host);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function closeServer(server) {
|
|
67
|
+
return new Promise((resolveClose, reject) => {
|
|
68
|
+
server.close((error) => (error ? reject(error) : resolveClose()));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/** Listen with the same strict-or-next-port behavior in every Lat UI host. */
|
|
72
|
+
export async function listenLatServer(app, options) {
|
|
73
|
+
const server = createServer(app);
|
|
74
|
+
let port = options.port;
|
|
75
|
+
while (true) {
|
|
76
|
+
try {
|
|
77
|
+
await listen(server, options.host, port);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
if (!options.findAvailablePort ||
|
|
82
|
+
error.code !== 'EADDRINUSE' ||
|
|
83
|
+
port === 65_535) {
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
port++;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const address = server.address();
|
|
90
|
+
if (!address) {
|
|
91
|
+
await closeServer(server);
|
|
92
|
+
throw new Error('Could not determine Lat UI server address');
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
server,
|
|
96
|
+
host: options.host,
|
|
97
|
+
port: address.port,
|
|
98
|
+
url: `http://${options.host}:${address.port}/`,
|
|
99
|
+
close: () => closeServer(server),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** Run an exported Express app until the standalone process is terminated. */
|
|
103
|
+
export async function runLatServer(app, options = {}) {
|
|
104
|
+
const host = options.host ?? process.env.HOST ?? '0.0.0.0';
|
|
105
|
+
const rawPort = options.port ?? Number(process.env.PORT ?? 3000);
|
|
106
|
+
if (!Number.isInteger(rawPort) || rawPort < 1 || rawPort > 65_535) {
|
|
107
|
+
throw new Error('PORT must be an integer from 1 to 65535');
|
|
108
|
+
}
|
|
109
|
+
const running = await listenLatServer(app, { host, port: rawPort });
|
|
110
|
+
(options.log ?? console.log)(`Lat UI listening on ${running.url}`);
|
|
111
|
+
let closing = false;
|
|
112
|
+
const shutdown = () => {
|
|
113
|
+
if (closing)
|
|
114
|
+
return;
|
|
115
|
+
closing = true;
|
|
116
|
+
void Promise.all([running.close(), options.close?.()]).catch((error) => {
|
|
117
|
+
console.error(error);
|
|
118
|
+
process.exitCode = 1;
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
process.once('SIGINT', shutdown);
|
|
122
|
+
process.once('SIGTERM', shutdown);
|
|
123
|
+
return running;
|
|
124
|
+
}
|
|
125
|
+
/** Read this published package's exact version for generated artifacts. */
|
|
126
|
+
export function getLatServerVersion() {
|
|
127
|
+
return JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
|
|
128
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plebeiantech/lat.md",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.4-fork.2",
|
|
4
4
|
"description": "A knowledge graph for your codebase, written in markdown",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,66 +22,112 @@
|
|
|
22
22
|
"bin": {
|
|
23
23
|
"lat": "./dist/src/cli/index.js"
|
|
24
24
|
},
|
|
25
|
+
"exports": {
|
|
26
|
+
"./server": {
|
|
27
|
+
"types": "./dist/src/view/server-deployment.d.ts",
|
|
28
|
+
"import": "./dist/src/view/server-deployment.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
25
31
|
"files": [
|
|
26
32
|
"dist/src",
|
|
27
|
-
"
|
|
33
|
+
"dist/vendor",
|
|
34
|
+
"templates",
|
|
35
|
+
"plugins"
|
|
28
36
|
],
|
|
29
37
|
"devDependencies": {
|
|
38
|
+
"@codemirror/commands": "^6.11.0",
|
|
39
|
+
"@codemirror/lang-markdown": "^6.5.2",
|
|
40
|
+
"@codemirror/language": "^6.12.4",
|
|
41
|
+
"@codemirror/merge": "^6.12.2",
|
|
42
|
+
"@codemirror/state": "^6.7.1",
|
|
43
|
+
"@codemirror/view": "^6.43.9",
|
|
44
|
+
"@fontsource-variable/geist": "^5.3.0",
|
|
45
|
+
"@fontsource-variable/geist-mono": "^5.3.0",
|
|
46
|
+
"@lezer/highlight": "^1.2.3",
|
|
47
|
+
"@types/express": "^5.0.6",
|
|
48
|
+
"@types/geojson": "^7946.0.16",
|
|
49
|
+
"@types/hast": "^3.0.5",
|
|
30
50
|
"@types/mdast": "^4.0.4",
|
|
31
51
|
"@types/node": "^25.3.0",
|
|
32
52
|
"@types/react": "^19.0.0",
|
|
33
53
|
"@types/react-dom": "^19.0.0",
|
|
54
|
+
"@types/three": "^0.185.4",
|
|
55
|
+
"@types/topojson-client": "^3.1.5",
|
|
34
56
|
"@vitejs/plugin-react": "^5.0.0",
|
|
35
57
|
"graphology": "^0.26.0",
|
|
36
58
|
"highlight.js": "^11.12.0",
|
|
59
|
+
"jsdom": "^30.0.1",
|
|
60
|
+
"katex": "^0.18.4",
|
|
61
|
+
"lowlight": "^3.3.0",
|
|
62
|
+
"maplibre-gl": "^5.24.0",
|
|
37
63
|
"mdast-util-from-markdown": "^2.0.3",
|
|
64
|
+
"mermaid": "^11.17.2",
|
|
38
65
|
"micromark-util-types": "^2.0.2",
|
|
39
66
|
"prettier": "^3.8.1",
|
|
40
67
|
"react": "^19.0.0",
|
|
41
68
|
"react-dom": "^19.0.0",
|
|
69
|
+
"rehype-stringify": "^10.0.1",
|
|
42
70
|
"sigma": "^3.0.3",
|
|
71
|
+
"three": "^0.185.1",
|
|
72
|
+
"topojson-client": "^3.1.0",
|
|
43
73
|
"tsx": "^4.21.0",
|
|
44
|
-
"typescript": "
|
|
74
|
+
"typescript": "7.0.2",
|
|
45
75
|
"vite": "^7.0.0",
|
|
46
|
-
"vitest": "^3.0.0"
|
|
76
|
+
"vitest": "^3.0.0",
|
|
77
|
+
"web-tree-sitter": "^0.26.6",
|
|
78
|
+
"micromark-extension-gfm-table": "^2.1.1",
|
|
79
|
+
"mdast-util-gfm-table": "^2.0.0",
|
|
80
|
+
"remark-math": "^6.0.0",
|
|
81
|
+
"@folder/xdg": "^4.0.1",
|
|
82
|
+
"@lat.md/server": "0.1.0"
|
|
47
83
|
},
|
|
48
84
|
"dependencies": {
|
|
49
|
-
"@
|
|
85
|
+
"@asciidoctor/core": "4.0.6",
|
|
50
86
|
"@libsql/client": "^0.17.0",
|
|
51
87
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
52
|
-
"@
|
|
88
|
+
"@tursodatabase/database": "0.8.2",
|
|
89
|
+
"@vercel/nft": "^1.10.0",
|
|
53
90
|
"commander": "^14.0.3",
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
91
|
+
"diff": "^8.0.4",
|
|
92
|
+
"express": "^5.2.1",
|
|
93
|
+
"fs-native-extensions": "1.5.1",
|
|
94
|
+
"rehype-katex": "^7.0.1",
|
|
95
|
+
"rehype-raw": "^7.0.0",
|
|
57
96
|
"rehype-sanitize": "^6.0.0",
|
|
58
97
|
"rehype-slug": "^6.0.0",
|
|
59
|
-
"
|
|
60
|
-
"remark-frontmatter": "^5.0.0",
|
|
61
|
-
"remark-parse": "^11.0.0",
|
|
98
|
+
"remark-emoji": "^5.0.2",
|
|
62
99
|
"remark-rehype": "^11.1.2",
|
|
63
|
-
"
|
|
100
|
+
"rst-compiler": "0.5.9",
|
|
64
101
|
"unified": "^11.0.0",
|
|
65
102
|
"unist-util-visit": "^5.0.0",
|
|
66
|
-
"web-tree-sitter": "^0.26.6",
|
|
67
103
|
"yaml": "^2.8.2",
|
|
68
104
|
"zod": "^4.3.6",
|
|
69
|
-
"@lat.md/embed": "0.2.
|
|
70
|
-
"@lat.md/embed-minilm-fp16": "0.1.
|
|
105
|
+
"@lat.md/embed": "0.2.2",
|
|
106
|
+
"@lat.md/embed-minilm-fp16": "0.1.1",
|
|
107
|
+
"@lat.md/stemmer": "0.1.0",
|
|
108
|
+
"@plebeiantech/lat.md-core": "0.13.4-fork.2"
|
|
71
109
|
},
|
|
72
110
|
"scripts": {
|
|
73
|
-
"build": "tsc && pnpm build:view",
|
|
111
|
+
"build": "tsc && tsx scripts/fork-vendor-ui-server.ts && pnpm build:view",
|
|
74
112
|
"build:view": "vite build --config view/vite.config.ts && vite build --config view/highlight.vite.config.ts",
|
|
113
|
+
"build:site": "pnpm --filter @lat.md/server build && node scripts/prepare-site-packages.mjs && pnpm build && node dist/src/cli/index.js ui build server --force",
|
|
114
|
+
"build:site:vercel": "pnpm build:site && node scripts/vendor-site-packages.mjs && npm install --prefix .lat-build/server --ignore-scripts --no-package-lock && node scripts/build-vercel-output.mjs",
|
|
115
|
+
"build:site:source": "pnpm buildall && node dist/src/cli/index.js ui build server --force",
|
|
75
116
|
"buildall": "pnpm build:packages && pnpm build",
|
|
76
117
|
"setup:rust": "pnpm --filter @lat.md/embed setup:rust",
|
|
77
118
|
"build:wasm": "pnpm --filter @lat.md/embed build:wasm",
|
|
78
119
|
"build:weights": "pnpm --filter @lat.md/embed-minilm-fp16 build:weights",
|
|
79
|
-
"build:packages": "pnpm --filter @lat.md/embed build && pnpm --filter @lat.md/embed-minilm-fp16 build",
|
|
120
|
+
"build:packages": "pnpm build:core && pnpm --filter @lat.md/server build && pnpm --filter @lat.md/stemmer build && pnpm --filter @lat.md/embed build && pnpm --filter @lat.md/embed-minilm-fp16 build",
|
|
80
121
|
"test": "vitest run",
|
|
81
122
|
"test:watch": "vitest",
|
|
82
|
-
"typecheck": "
|
|
83
|
-
"
|
|
84
|
-
"format
|
|
85
|
-
"
|
|
123
|
+
"typecheck": "pnpm build:core && pnpm --filter @lat.md/server build && pnpm typecheck:no-build",
|
|
124
|
+
"typecheck:no-build": "pnpm --filter @plebeiantech/lat.md-core typecheck && pnpm --filter @lat.md/server typecheck && tsc --noEmit && tsc --noEmit -p view/tsconfig.json",
|
|
125
|
+
"format": "prettier --write \"src/**/*.ts\" \"packages/core/src/**/*.ts\" \"packages/server/src/**/*.ts\" \"view/**/*.{ts,tsx,css,html}\"",
|
|
126
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"packages/core/src/**/*.ts\" \"packages/server/src/**/*.ts\" \"view/**/*.{ts,tsx,css,html}\"",
|
|
127
|
+
"cook-test-rag": "tsx scripts/cook-test-rag.ts",
|
|
128
|
+
"build:core": "pnpm --filter @plebeiantech/lat.md-core build",
|
|
129
|
+
"build:action-test": "pnpm build:core && node scripts/build-action-test.mjs",
|
|
130
|
+
"test:core": "node --test scripts/test-core-distribution.js",
|
|
131
|
+
"test:action": "node --test scripts/test-check-action.js"
|
|
86
132
|
}
|
|
87
133
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Antigravity & Gemini CLI Plugin for lat.md
|
|
2
|
+
|
|
3
|
+
This plugin integrates [lat.md](https://github.com/PlebeianTech/lat.md) with Google Antigravity and Gemini CLI. It grounds the agent in your codebase knowledge graph, prevents multi-line rationale comments in source code, maintains directory indexes, and blocks finishing work on check failures.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **PreInvocation Hook**: Automatically expands wiki links (`[[section]]`) in user prompts, retrieves relevant sections using semantic search, and reminds the agent to maintain the knowledge graph.
|
|
8
|
+
- **PreToolUse Hook**: Intercepts file edits (`replace_file_content` and `write_to_file`) and blocks multi-line rationale comments, prompting the agent to document the reasoning in `lat.md/` with a `@lat:` pointer instead.
|
|
9
|
+
- **PostToolUse Hook**: Runs index synchronization after file modifications.
|
|
10
|
+
- **Stop Hook**: Enforces `lat check` (including Diátaxis mode validation) before the agent completes its work, refusing stop if errors remain.
|
|
11
|
+
- **Bundled Skills**: Provides `lat-md` (syntax & structure authoring guide) and `lat-md-conventions` (fork conventions & rules).
|
|
12
|
+
- **Rules**: Injects core `lat.md` workflow directives via `rules/AGENTS.md`.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Option 1: Via `lat init` (Zero Clone, Recommended)
|
|
17
|
+
|
|
18
|
+
You do not need to clone the repository to use lat.md with Antigravity. Install the CLI and initialize your repository directly:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -g @plebeiantech/lat.md
|
|
22
|
+
# or: mise use -g npm:@plebeiantech/lat.md@latest
|
|
23
|
+
|
|
24
|
+
lat init
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Select **Antigravity / Gemini** from the agent checklist menu. This automatically writes `.agents/hooks.json`, `GEMINI.md`, and `.agents/skills/`.
|
|
28
|
+
|
|
29
|
+
### Option 2: Global User Plugin (Without Cloning)
|
|
30
|
+
|
|
31
|
+
To install the plugin bundle globally across all repositories without cloning:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
mkdir -p ~/.gemini/config/plugins/lat-md && \
|
|
35
|
+
curl -sL https://github.com/PlebeianTech/lat.md/archive/refs/heads/main.tar.gz | \
|
|
36
|
+
tar -xz -C ~/.gemini/config/plugins/lat-md --strip-components=2 lat.md-main/plugins/lat-md
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Option 3: Workspace Plugin (Without Cloning)
|
|
40
|
+
|
|
41
|
+
To install the plugin bundle into a specific repository without cloning:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
mkdir -p .agents/plugins/lat-md && \
|
|
45
|
+
curl -sL https://github.com/PlebeianTech/lat.md/archive/refs/heads/main.tar.gz | \
|
|
46
|
+
tar -xz -C .agents/plugins/lat-md --strip-components=2 lat.md-main/plugins/lat-md
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Requirements
|
|
50
|
+
|
|
51
|
+
The plugin requires the `@plebeiantech/lat.md` CLI on your `PATH`:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install -g @plebeiantech/lat.md
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or using [mise](https://mise.jdx.dev/):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
mise use -g npm:@plebeiantech/lat.md@latest
|
|
61
|
+
```
|