@plebeiantech/lat.md 0.12.3-fork.8 → 0.13.4-fork.1
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 +147 -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/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 -53
- 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/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-VZwPPiFE.js +0 -334
- package/dist/src/view/client/assets/index-W8ktvNj9.css +0 -1
- 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
package/README.md
CHANGED
|
@@ -77,9 +77,33 @@ The hooks are also packaged as a plugin, installable straight from this reposito
|
|
|
77
77
|
|
|
78
78
|
The plugin ships hooks only and finds `lat` on your `PATH`, accepting a build only if its version carries a `-fork` suffix.
|
|
79
79
|
|
|
80
|
+
### As an Antigravity / Gemini CLI plugin
|
|
81
|
+
|
|
82
|
+
The hooks, rules, and skills are packaged as an Antigravity plugin under `plugins/lat-md/`.
|
|
83
|
+
|
|
84
|
+
You can install it directly without cloning the repository:
|
|
85
|
+
|
|
86
|
+
**Global installation (all local projects):**
|
|
87
|
+
```bash
|
|
88
|
+
mkdir -p ~/.gemini/config/plugins/lat-md && \
|
|
89
|
+
curl -sL https://github.com/PlebeianTech/lat.md/archive/refs/heads/main.tar.gz | \
|
|
90
|
+
tar -xz -C ~/.gemini/config/plugins/lat-md --strip-components=2 lat.md-main/plugins/lat-md
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Workspace installation (single repository):**
|
|
94
|
+
```bash
|
|
95
|
+
mkdir -p .agents/plugins/lat-md && \
|
|
96
|
+
curl -sL https://github.com/PlebeianTech/lat.md/archive/refs/heads/main.tar.gz | \
|
|
97
|
+
tar -xz -C .agents/plugins/lat-md --strip-components=2 lat.md-main/plugins/lat-md
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Alternatively, install `@plebeiantech/lat.md` via npm/mise, run `lat init` in your project, and select **Antigravity / Gemini** from the agent checklist.
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
80
104
|
## How it works
|
|
81
105
|
|
|
82
|
-
Run `lat init` to scaffold a `lat.md/` directory, then write markdown files describing your architecture, business logic, test specs — whatever matters. Link between sections using `[[file#Section#Subsection]]` syntax. Link to source code symbols with `[[src/auth.ts#validateToken]]`. Annotate source code with `// @lat: [[section-id]]` (or `# @lat: [[section-id]]` in Python) comments to tie implementation back to concepts.
|
|
106
|
+
Run `lat init` to scaffold a `lat.md/` directory, then write markdown files describing your architecture, business logic, test specs — whatever matters. Link between sections using `[[file#Section#Subsection]]` syntax. Link to source code symbols with `[[src/auth.ts#validateToken]]`. Annotate source code with `// @lat: [[section-id]]` (or `# @lat: [[section-id]]` in Python and PHP) comments to tie implementation back to concepts.
|
|
83
107
|
|
|
84
108
|
```
|
|
85
109
|
my-project/
|
|
@@ -115,7 +139,7 @@ To use higher-quality hosted embeddings instead, provide an OpenAI (`sk-...`) or
|
|
|
115
139
|
1. `LAT_LLM_KEY` env var — direct value
|
|
116
140
|
2. `LAT_LLM_KEY_FILE` env var — path to a file containing the key
|
|
117
141
|
3. `LAT_LLM_KEY_HELPER` env var — shell command that prints the key (10s timeout)
|
|
118
|
-
4. Config file — power users can set `llm_key` manually. Run `lat config` to print its location.
|
|
142
|
+
4. Config file — power users can set `llm_key` manually. Run `lat paths --config` to print its location. Run `lat paths` to see cache and other storage paths with their purposes.
|
|
119
143
|
|
|
120
144
|
Switch backends any time with `lat reindex` (`--local` to force the offline model, `--remote` to use your key).
|
|
121
145
|
|
|
@@ -123,7 +147,7 @@ Switch backends any time with `lat reindex` (`--local` to force the offline mode
|
|
|
123
147
|
|
|
124
148
|
Development requires Node.js 22, pnpm, and Rust installed through rustup. The
|
|
125
149
|
pnpm setup installs the matching WASM target and build tools project-locally.
|
|
126
|
-
See the [development process](lat.md/dev-process.md) for complete setup and
|
|
150
|
+
See the [development process](lat.md/knowledge/dev-process.md) for complete setup and
|
|
127
151
|
contribution guidance.
|
|
128
152
|
|
|
129
153
|
```bash
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface AgentInvocation {
|
|
2
|
+
command: string;
|
|
3
|
+
args: string[];
|
|
4
|
+
}
|
|
5
|
+
/** Generated tools pass user input as argv, never as shell program text. */
|
|
6
|
+
export declare function agentInvocation(style: 'local' | 'global' | 'npx', local: AgentInvocation, platform?: NodeJS.Platform): AgentInvocation;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { delimiter, dirname, join } from 'node:path';
|
|
3
|
+
/** Generated tools pass user input as argv, never as shell program text. */
|
|
4
|
+
export function agentInvocation(style, local, platform = process.platform) {
|
|
5
|
+
if (style === 'local')
|
|
6
|
+
return local;
|
|
7
|
+
// Windows npm command shims require cmd.exe. Use the installed entry point
|
|
8
|
+
// directly instead, retaining the Node launcher and its loader arguments.
|
|
9
|
+
if (style === 'global')
|
|
10
|
+
return platform === 'win32' ? local : { command: 'lat', args: [] };
|
|
11
|
+
if (platform !== 'win32')
|
|
12
|
+
return { command: 'npx', args: ['lat.md@latest'] };
|
|
13
|
+
const directories = [
|
|
14
|
+
dirname(process.execPath),
|
|
15
|
+
...(process.env.PATH ?? '').split(delimiter),
|
|
16
|
+
];
|
|
17
|
+
for (const directory of directories) {
|
|
18
|
+
const cli = join(directory, 'node_modules', 'npm', 'bin', 'npx-cli.js');
|
|
19
|
+
if (existsSync(cli))
|
|
20
|
+
return { command: process.execPath, args: [cli, 'lat.md@latest'] };
|
|
21
|
+
}
|
|
22
|
+
throw new Error('Cannot find the npm npx entry point. Choose the local command style or install npm.');
|
|
23
|
+
}
|
|
@@ -5,8 +5,9 @@ export interface ChecklistOption {
|
|
|
5
5
|
/**
|
|
6
6
|
* Display an interactive multi-select checklist with arrow-key navigation.
|
|
7
7
|
* Returns an array of checked values.
|
|
8
|
+
* Known initial values start checked; unknown values are ignored.
|
|
8
9
|
*
|
|
9
10
|
* Keys: Up/Down (j/k) to move, Space to toggle, Enter to confirm, Ctrl+C to exit.
|
|
10
11
|
* Non-TTY fallback: returns [].
|
|
11
12
|
*/
|
|
12
|
-
export declare function checklistMenu(options: ChecklistOption[], prompt?: string): Promise<string[]>;
|
|
13
|
+
export declare function checklistMenu(options: ChecklistOption[], prompt?: string, initialValues?: readonly string[]): Promise<string[]>;
|
|
@@ -2,18 +2,19 @@ import { styleText } from 'node:util';
|
|
|
2
2
|
/**
|
|
3
3
|
* Display an interactive multi-select checklist with arrow-key navigation.
|
|
4
4
|
* Returns an array of checked values.
|
|
5
|
+
* Known initial values start checked; unknown values are ignored.
|
|
5
6
|
*
|
|
6
7
|
* Keys: Up/Down (j/k) to move, Space to toggle, Enter to confirm, Ctrl+C to exit.
|
|
7
8
|
* Non-TTY fallback: returns [].
|
|
8
9
|
*/
|
|
9
|
-
export async function checklistMenu(options, prompt) {
|
|
10
|
+
export async function checklistMenu(options, prompt, initialValues = []) {
|
|
10
11
|
if (options.length === 0)
|
|
11
12
|
return [];
|
|
12
13
|
if (!process.stdin.isTTY)
|
|
13
14
|
return [];
|
|
14
15
|
return new Promise((resolve) => {
|
|
15
16
|
let cursor = 0;
|
|
16
|
-
const checked = new Set();
|
|
17
|
+
const checked = new Set(options.flatMap((option, index) => initialValues.includes(option.value) ? [index] : []));
|
|
17
18
|
const stdin = process.stdin;
|
|
18
19
|
const wasRaw = stdin.isRaw;
|
|
19
20
|
stdin.setRawMode(true);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const SKILL_FRONTMATTER = "---\nname: lat-md-conventions\ndescription: >-\n Rules and writing conventions for this project: Di\u00E1taxis mode placement for\n every lat.md/ document, Strunk & White prose style, mandatory @lat: code refs\n starting at the application entrypoint, and test specs wired to their tests.\n Load alongside lat-md whenever creating or editing files under lat.md/.\n---\n\n";
|
|
1
2
|
export declare function readForkConventions(): string;
|
|
2
3
|
/**
|
|
3
4
|
* Replace the fork block in `content`, or append one when absent.
|
|
@@ -1,33 +1,9 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { styleText } from 'node:util';
|
|
4
|
-
import { contentHash, readFileHash } from '
|
|
4
|
+
import { contentHash, readFileHash, } from '@plebeiantech/lat.md-core/init-version';
|
|
5
5
|
import { findTemplatesDir } from './templates.js';
|
|
6
|
-
|
|
7
|
-
* The fork's own instruction channel into a consumer project.
|
|
8
|
-
*
|
|
9
|
-
* Upstream teaches a consumer's agent through `templates/AGENTS.md` and
|
|
10
|
-
* `templates/skill/SKILL.md`. Both are upstream files, and both are the ones
|
|
11
|
-
* upstream is most likely to rewrite, so every sentence this fork adds to them
|
|
12
|
-
* is a merge conflict bought on credit. The fork's Diátaxis block cost 13
|
|
13
|
-
* lines in one and 14 in the other before this module existed.
|
|
14
|
-
*
|
|
15
|
-
* Everything here writes into fork-owned paths instead. The entire upstream
|
|
16
|
-
* footprint is one import and one call in `initCmd`.
|
|
17
|
-
*
|
|
18
|
-
* Two shapes, because the destinations behave differently:
|
|
19
|
-
*
|
|
20
|
-
* - Always-loaded instruction files (`CLAUDE.md`, `AGENTS.md`,
|
|
21
|
-
* `.github/copilot-instructions.md`) already carry upstream's
|
|
22
|
-
* `%% lat:begin %%` block, so this appends a *second* block under its own
|
|
23
|
-
* `%% lat-fork:begin %%` markers. Upstream's `appendTemplateSection` slices
|
|
24
|
-
* between its own markers and leaves anything after them intact, so the two
|
|
25
|
-
* blocks do not fight on re-run.
|
|
26
|
-
* - Skill directories get a separate `lat-md-conventions/SKILL.md`. Upstream
|
|
27
|
-
* writes its `lat-md` skill with a whole-file hash comparison, so appending
|
|
28
|
-
* to that file would make every later `lat init` report it as
|
|
29
|
-
* user-modified and prompt.
|
|
30
|
-
*/
|
|
6
|
+
// @lat: [[fork#Fork#The instruction channel]]
|
|
31
7
|
const FORK_BEGIN = '%% lat-fork:begin %%';
|
|
32
8
|
const FORK_END = '%% lat-fork:end %%';
|
|
33
9
|
/**
|
|
@@ -40,8 +16,8 @@ function forkHashKey(relPath) {
|
|
|
40
16
|
}
|
|
41
17
|
/** Instruction files that use upstream's marker-append shape. */
|
|
42
18
|
const BLOCK_TARGETS = [
|
|
43
|
-
'CLAUDE.md',
|
|
44
19
|
'AGENTS.md',
|
|
20
|
+
'GEMINI.md',
|
|
45
21
|
'.github/copilot-instructions.md',
|
|
46
22
|
];
|
|
47
23
|
/**
|
|
@@ -56,13 +32,13 @@ const SKILL_ROOTS = [
|
|
|
56
32
|
'.codex/skills',
|
|
57
33
|
];
|
|
58
34
|
const SKILL_NAME = 'lat-md-conventions';
|
|
59
|
-
const SKILL_FRONTMATTER = `---
|
|
35
|
+
export const SKILL_FRONTMATTER = `---
|
|
60
36
|
name: ${SKILL_NAME}
|
|
61
37
|
description: >-
|
|
62
|
-
Rules
|
|
63
|
-
lat.md/ document, mandatory @lat: code refs
|
|
64
|
-
entrypoint, and test specs wired to their tests.
|
|
65
|
-
whenever creating or editing files under lat.md/.
|
|
38
|
+
Rules and writing conventions for this project: Diátaxis mode placement for
|
|
39
|
+
every lat.md/ document, Strunk & White prose style, mandatory @lat: code refs
|
|
40
|
+
starting at the application entrypoint, and test specs wired to their tests.
|
|
41
|
+
Load alongside lat-md whenever creating or editing files under lat.md/.
|
|
66
42
|
---
|
|
67
43
|
|
|
68
44
|
`;
|
|
@@ -2,8 +2,8 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
|
2
2
|
import { basename, dirname, join } from 'node:path';
|
|
3
3
|
import { styleText } from 'node:util';
|
|
4
4
|
import { isMap, isScalar, isSeq, parseDocument } from 'yaml';
|
|
5
|
-
import { parseFrontmatter } from '
|
|
6
|
-
import { DIATAXIS_MODES, MODE_DIRS, checkMode, indexNameFor, } from '
|
|
5
|
+
import { parseFrontmatter } from '@plebeiantech/lat.md-core/lattice';
|
|
6
|
+
import { DIATAXIS_MODES, MODE_DIRS, checkMode, indexNameFor, } from '@plebeiantech/lat.md-core/cli/check-mode';
|
|
7
7
|
/**
|
|
8
8
|
* Give a freshly created `lat.md/` the Diátaxis shape, and turn the gate on.
|
|
9
9
|
*
|
package/dist/src/cli/graph.d.ts
CHANGED
package/dist/src/cli/hook.d.ts
CHANGED
|
@@ -1 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Measure code vs `lat.md/` churn since HEAD, in lines. Combines tracked
|
|
3
|
+
* changes (`git diff HEAD --numstat`) with untracked files
|
|
4
|
+
* (`git ls-files --others --exclude-standard -z`). Counting untracked files is
|
|
5
|
+
* what makes a freshly scaffolded, never-committed `lat.md/` register as
|
|
6
|
+
* updated — otherwise its edits are invisible to `git diff HEAD` and the sync
|
|
7
|
+
* reminder fires on every turn until `lat.md/` is committed (issue #61).
|
|
8
|
+
* Both scans are scoped and made relative to `projectRoot`, so a Lat project
|
|
9
|
+
* nested in a larger worktree neither misses its own `lat.md/` paths nor counts
|
|
10
|
+
* changes from sibling projects.
|
|
11
|
+
* Outside a Git worktree both scans contribute zero churn by design: Git is
|
|
12
|
+
* optional, so the hook still validates the project but skips the sync ratio.
|
|
13
|
+
*/
|
|
14
|
+
export declare function analyzeDiff(projectRoot: string): {
|
|
15
|
+
codeLines: number;
|
|
16
|
+
latMdLines: number;
|
|
17
|
+
};
|
|
18
|
+
export type StopStatus = {
|
|
19
|
+
checkFailed: boolean;
|
|
20
|
+
totalErrors: number;
|
|
21
|
+
needsSync: boolean;
|
|
22
|
+
codeLines: number;
|
|
23
|
+
latMdLines: number;
|
|
24
|
+
};
|
|
25
|
+
export declare function getStopStatus(latDir: string): Promise<StopStatus>;
|
|
26
|
+
export declare function formatStopReason({ checkFailed, totalErrors, needsSync, codeLines, latMdLines, }: StopStatus): string | null;
|
|
1
27
|
export declare function hookCmd(agent: string, event: string): Promise<void>;
|
package/dist/src/cli/hook.js
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { lstatSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, extname, join } from 'node:path';
|
|
4
|
+
import { findLatticeDir } from '@plebeiantech/lat.md-core/project-discovery';
|
|
5
|
+
import { findSections } from '@plebeiantech/lat.md-core/lattice-model';
|
|
6
|
+
import { plainStyler, } from '@plebeiantech/lat.md-core/context';
|
|
6
7
|
import { runSearch } from './search.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { DEFAULT_SEARCH_LIMIT } from '../search/search.js';
|
|
9
|
+
import { getSection, formatSectionOutput, } from '@plebeiantech/lat.md-core/cli/section';
|
|
10
|
+
import { checkMd, checkCodeRefs, checkIndex, checkSections, } from '@plebeiantech/lat.md-core/cli/check';
|
|
11
|
+
import { CheckRunContext } from '@plebeiantech/lat.md-core/cli/check-context';
|
|
12
|
+
import { isSourceFileExtension } from '@plebeiantech/lat.md-core/source-formats';
|
|
13
|
+
import { commandProjectAnalysis } from '@plebeiantech/lat.md-core/project-analysis';
|
|
14
|
+
import { checkMode } from '@plebeiantech/lat.md-core/cli/check-mode';
|
|
11
15
|
import { federateTags, taggedDocsForFiles } from '../knowledge/index.js';
|
|
12
16
|
import { loadSessionMarkers, saveSessionMarkers, } from '../knowledge/session.js';
|
|
13
17
|
import { computeCommentReminder, } from './comment-reminder.js';
|
|
14
18
|
import { handlePreToolUse } from './comment-guard.js';
|
|
19
|
+
import { handleAntigravityHook } from '../fork/antigravity-hook.js';
|
|
15
20
|
function outputPromptSubmit(context) {
|
|
16
21
|
process.stdout.write(JSON.stringify({
|
|
17
22
|
hookSpecificOutput: {
|
|
@@ -53,9 +58,6 @@ async function readStdin() {
|
|
|
53
58
|
}
|
|
54
59
|
return Buffer.concat(chunks).toString('utf-8');
|
|
55
60
|
}
|
|
56
|
-
function hasWikiLinks(text) {
|
|
57
|
-
return /\[\[[^\]]+\]\]/.test(text);
|
|
58
|
-
}
|
|
59
61
|
function makeHookCtx(latDir) {
|
|
60
62
|
return {
|
|
61
63
|
latDir,
|
|
@@ -64,15 +66,15 @@ function makeHookCtx(latDir) {
|
|
|
64
66
|
mode: 'cli',
|
|
65
67
|
};
|
|
66
68
|
}
|
|
67
|
-
async function
|
|
69
|
+
async function searchContextForPrompt(ctx, userPrompt) {
|
|
68
70
|
let result;
|
|
69
71
|
try {
|
|
70
72
|
// Read-only: search an existing index but never build/update it here. A fresh
|
|
71
73
|
// repo's first prompt must not trigger a full local embed pass — that's what
|
|
72
74
|
// `lat search` / `lat reindex` are for. Returns no matches until then.
|
|
73
|
-
result = await runSearch(ctx.latDir, userPrompt,
|
|
75
|
+
result = await runSearch(ctx.latDir, userPrompt, DEFAULT_SEARCH_LIMIT, undefined, {
|
|
74
76
|
buildIndex: false,
|
|
75
|
-
|
|
77
|
+
project: await commandProjectAnalysis(ctx),
|
|
76
78
|
});
|
|
77
79
|
}
|
|
78
80
|
catch {
|
|
@@ -109,32 +111,16 @@ async function handleUserPromptSubmit() {
|
|
|
109
111
|
// If we can't parse stdin, still emit the reminder
|
|
110
112
|
}
|
|
111
113
|
const parts = [];
|
|
112
|
-
parts.push("Before starting work, run `lat search` with one or more queries describing the user's intent.", 'ALWAYS do this, even when the task seems straightforward — search results may reveal critical design details, protocols, or constraints.', 'Use `lat section` to read the full content of relevant matches.', 'Do not read files, write code, or run commands until you have searched.', '', 'Remember: `lat.md/` must stay in sync with meaningful codebase state. If you change behavior, architecture,
|
|
114
|
+
parts.push("Before starting work, run `lat search` with one or more queries describing the user's intent.", 'ALWAYS do this, even when the task seems straightforward — search results may reveal critical design details, protocols, or constraints.', 'Use `lat section` to read the full content of relevant matches.', 'Do not read files, write code, or run commands until you have searched.', '', 'Remember: `lat.md/` must stay in sync with meaningful codebase state. If you change implemented behavior, architecture, or tests, update the relevant current-state sections and run `lat check` before finishing. Plans may be drafted in `lat.md/` alongside implementation, with the intent that by commit time they describe what was implemented. Otherwise, keep proposals, hypothetical designs, and future work outside `lat.md/` unless the user explicitly requests them there. Do not use `lat.md/` as a journal/changelog or add notes for insignificant details.');
|
|
113
115
|
const latDir = findLatticeDir();
|
|
114
116
|
if (latDir && userPrompt) {
|
|
115
117
|
const ctx = makeHookCtx(latDir);
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
const allSections = await loadAllSections(latDir);
|
|
119
|
-
// If the user prompt contains [[refs]], resolve them inline
|
|
120
|
-
if (hasWikiLinks(userPrompt)) {
|
|
121
|
-
try {
|
|
122
|
-
const expanded = await expandPrompt(ctx, userPrompt, allSections);
|
|
123
|
-
if (expanded) {
|
|
124
|
-
parts.push('', 'Expanded user prompt with resolved [[refs]]:', expanded);
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
parts.push('', 'NOTE: The user prompt contains [[refs]] but they could not be resolved. Ask the user to correct them.');
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
parts.push('', 'NOTE: The user prompt contains [[refs]] but resolution failed. Run `lat expand` on the prompt text manually.');
|
|
132
|
-
}
|
|
133
|
-
}
|
|
118
|
+
// Search and federation share the analysis memoised on `ctx`.
|
|
119
|
+
const { allSections } = await commandProjectAnalysis(ctx);
|
|
134
120
|
// Search for relevant sections and include their full content
|
|
135
121
|
let searchFilePaths = [];
|
|
136
122
|
try {
|
|
137
|
-
const searchContext = await
|
|
123
|
+
const searchContext = await searchContextForPrompt(ctx, userPrompt);
|
|
138
124
|
searchFilePaths = searchContext.filePaths;
|
|
139
125
|
if (searchContext.text) {
|
|
140
126
|
parts.push('', searchContext.text);
|
|
@@ -161,7 +147,7 @@ async function handleUserPromptSubmit() {
|
|
|
161
147
|
}
|
|
162
148
|
}
|
|
163
149
|
}
|
|
164
|
-
// Reuses what
|
|
150
|
+
// Reuses what searchContextForPrompt already matched. Searching again here
|
|
165
151
|
// would double the cost of every prompt, and an unusable index makes
|
|
166
152
|
// runSearch throw — which abandoned the [[ref]] paths collected above,
|
|
167
153
|
// even though resolving those never touches the index at all.
|
|
@@ -252,55 +238,116 @@ const DIFF_THRESHOLD = 5;
|
|
|
252
238
|
const LATMD_RATIO = 0.05;
|
|
253
239
|
/** If lat.md/ changes exceed this many lines, skip the ratio check entirely. */
|
|
254
240
|
const LATMD_UPPER_THRESHOLD = 50;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
241
|
+
function diffFileKind(file) {
|
|
242
|
+
if (file.startsWith('lat.md/'))
|
|
243
|
+
return 'latMd';
|
|
244
|
+
if (isSourceFileExtension(extname(file)))
|
|
245
|
+
return 'code';
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
/** Count a regular text file's lines as additions, matching Git numstat. */
|
|
249
|
+
function countUntrackedFileLines(projectRoot, file) {
|
|
258
250
|
try {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
251
|
+
const path = join(projectRoot, file);
|
|
252
|
+
if (!lstatSync(path).isFile())
|
|
253
|
+
return 0;
|
|
254
|
+
const text = readFileSync(path, 'utf-8');
|
|
255
|
+
if (text.length === 0)
|
|
256
|
+
return 0;
|
|
257
|
+
return text.split('\n').length - (text.endsWith('\n') ? 1 : 0);
|
|
264
258
|
}
|
|
265
259
|
catch {
|
|
266
|
-
return
|
|
260
|
+
return 0;
|
|
267
261
|
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Measure code vs `lat.md/` churn since HEAD, in lines. Combines tracked
|
|
265
|
+
* changes (`git diff HEAD --numstat`) with untracked files
|
|
266
|
+
* (`git ls-files --others --exclude-standard -z`). Counting untracked files is
|
|
267
|
+
* what makes a freshly scaffolded, never-committed `lat.md/` register as
|
|
268
|
+
* updated — otherwise its edits are invisible to `git diff HEAD` and the sync
|
|
269
|
+
* reminder fires on every turn until `lat.md/` is committed (issue #61).
|
|
270
|
+
* Both scans are scoped and made relative to `projectRoot`, so a Lat project
|
|
271
|
+
* nested in a larger worktree neither misses its own `lat.md/` paths nor counts
|
|
272
|
+
* changes from sibling projects.
|
|
273
|
+
* Outside a Git worktree both scans contribute zero churn by design: Git is
|
|
274
|
+
* optional, so the hook still validates the project but skips the sync ratio.
|
|
275
|
+
*/
|
|
276
|
+
export function analyzeDiff(projectRoot) {
|
|
268
277
|
let codeLines = 0;
|
|
269
278
|
let latMdLines = 0;
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
const parts = line.split('\t');
|
|
273
|
-
if (parts.length < 3)
|
|
274
|
-
continue;
|
|
275
|
-
const added = parseInt(parts[0], 10) || 0;
|
|
276
|
-
const removed = parseInt(parts[1], 10) || 0;
|
|
277
|
-
const file = parts[2];
|
|
278
|
-
const changed = added + removed;
|
|
279
|
-
if (file.startsWith('lat.md/')) {
|
|
279
|
+
const tally = (kind, changed) => {
|
|
280
|
+
if (kind === 'latMd') {
|
|
280
281
|
latMdLines += changed;
|
|
281
282
|
}
|
|
282
|
-
else
|
|
283
|
+
else {
|
|
283
284
|
codeLines += changed;
|
|
284
285
|
}
|
|
286
|
+
};
|
|
287
|
+
// Tracked changes vs HEAD. Throws when there is no HEAD yet (a repo with no
|
|
288
|
+
// commits) or no repo at all; the untracked scan below still runs.
|
|
289
|
+
try {
|
|
290
|
+
const output = execSync('git diff HEAD --numstat --relative -- .', {
|
|
291
|
+
cwd: projectRoot,
|
|
292
|
+
encoding: 'utf-8',
|
|
293
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
294
|
+
});
|
|
295
|
+
// Each line: "added\tremoved\tfile" (e.g. "42\t11\tsrc/cli/hook.ts")
|
|
296
|
+
for (const line of output.split('\n')) {
|
|
297
|
+
const parts = line.split('\t');
|
|
298
|
+
if (parts.length < 3)
|
|
299
|
+
continue;
|
|
300
|
+
const added = parseInt(parts[0], 10) || 0;
|
|
301
|
+
const removed = parseInt(parts[1], 10) || 0;
|
|
302
|
+
const kind = diffFileKind(parts[2]);
|
|
303
|
+
if (kind)
|
|
304
|
+
tally(kind, added + removed);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
// Not a git repo, or no HEAD — fall through to the untracked scan.
|
|
309
|
+
}
|
|
310
|
+
// NUL-delimited output preserves spaces, non-ASCII names, and newlines.
|
|
311
|
+
// Classify paths before reading so unrelated untracked files are never read.
|
|
312
|
+
try {
|
|
313
|
+
const output = execSync('git ls-files --others --exclude-standard -z -- .', {
|
|
314
|
+
cwd: projectRoot,
|
|
315
|
+
encoding: 'utf-8',
|
|
316
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
317
|
+
});
|
|
318
|
+
for (const file of output.split('\0')) {
|
|
319
|
+
if (!file)
|
|
320
|
+
continue;
|
|
321
|
+
const kind = diffFileKind(file);
|
|
322
|
+
if (!kind)
|
|
323
|
+
continue;
|
|
324
|
+
tally(kind, countUntrackedFileLines(projectRoot, file));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
// Not a Git repo — diff-based sync analysis is intentionally disabled.
|
|
285
329
|
}
|
|
286
330
|
return { codeLines, latMdLines };
|
|
287
331
|
}
|
|
288
|
-
async function getStopStatus(latDir) {
|
|
289
|
-
const
|
|
290
|
-
const
|
|
291
|
-
const indexErrors = await checkIndex(latDir);
|
|
292
|
-
const sectionErrors = await checkSections(latDir);
|
|
332
|
+
export async function getStopStatus(latDir) {
|
|
333
|
+
const projectRoot = dirname(latDir);
|
|
334
|
+
const run = new CheckRunContext(latDir, projectRoot);
|
|
293
335
|
// Must stay in step with `checkAllCommand` in check.ts. A check counted
|
|
294
336
|
// there but not here lets the Stop hook call a failing tree clean, which
|
|
295
337
|
// silently disables the very enforcement the check was added for.
|
|
296
|
-
const modeErrors = await
|
|
338
|
+
const [md, code, indexErrors, sectionErrors, modeErrors] = await Promise.all([
|
|
339
|
+
checkMd(latDir, projectRoot, run),
|
|
340
|
+
checkCodeRefs(latDir, projectRoot, run),
|
|
341
|
+
checkIndex(latDir, run),
|
|
342
|
+
checkSections(latDir, projectRoot, run),
|
|
343
|
+
checkMode(latDir, projectRoot),
|
|
344
|
+
]);
|
|
297
345
|
const totalErrors = md.errors.length +
|
|
298
346
|
code.errors.length +
|
|
299
347
|
indexErrors.length +
|
|
300
348
|
sectionErrors.length +
|
|
301
349
|
modeErrors.length;
|
|
302
350
|
const checkFailed = totalErrors > 0;
|
|
303
|
-
const projectRoot = dirname(latDir);
|
|
304
351
|
const { codeLines, latMdLines } = analyzeDiff(projectRoot);
|
|
305
352
|
let needsSync = false;
|
|
306
353
|
if (codeLines >= DIFF_THRESHOLD && latMdLines < LATMD_UPPER_THRESHOLD) {
|
|
@@ -315,7 +362,7 @@ async function getStopStatus(latDir) {
|
|
|
315
362
|
latMdLines,
|
|
316
363
|
};
|
|
317
364
|
}
|
|
318
|
-
function formatStopReason({ checkFailed, totalErrors, needsSync, codeLines, latMdLines, }) {
|
|
365
|
+
export function formatStopReason({ checkFailed, totalErrors, needsSync, codeLines, latMdLines, }) {
|
|
319
366
|
if (!checkFailed && !needsSync)
|
|
320
367
|
return null;
|
|
321
368
|
const parts = [];
|
|
@@ -425,8 +472,12 @@ export async function hookCmd(agent, event) {
|
|
|
425
472
|
console.error(`Unknown hook event for cursor: ${event}. Supported: stop, postToolUse`);
|
|
426
473
|
process.exit(1);
|
|
427
474
|
}
|
|
475
|
+
case 'antigravity':
|
|
476
|
+
case 'gemini':
|
|
477
|
+
await handleAntigravityHook(event);
|
|
478
|
+
return;
|
|
428
479
|
default:
|
|
429
|
-
console.error(`Unknown agent: ${agent}. Supported: claude, codex, cursor`);
|
|
480
|
+
console.error(`Unknown agent: ${agent}. Supported: claude, codex, cursor, antigravity, gemini`);
|
|
430
481
|
process.exit(1);
|
|
431
482
|
}
|
|
432
483
|
}
|