@plebeiantech/lat.md 0.12.3-fork.9 → 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 -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/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
package/dist/src/view/store.js
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
|
+
import { repositoryFilePath } from '@plebeiantech/lat.md-core/repository-path';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
1
3
|
import { watch as watchFiles } from 'node:fs';
|
|
2
|
-
import { readFile, realpath } from 'node:fs/promises';
|
|
4
|
+
import { readFile, realpath, rename, rm, stat, writeFile, } from 'node:fs/promises';
|
|
3
5
|
import { basename, extname, isAbsolute, relative, resolve, sep, } from 'node:path';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { createCodeReferenceDiscovery, extractCodeRefTargets, } from '@plebeiantech/lat.md-core/code-refs';
|
|
7
|
+
import { createExternalResolver, } from '@plebeiantech/lat.md-core/external-sources';
|
|
8
|
+
import { listLatticeFiles } from '@plebeiantech/lat.md-core/project-discovery';
|
|
9
|
+
import { analyzeMarkdownPath } from '@plebeiantech/lat.md-core/markdown-analysis-cache';
|
|
10
|
+
import { isSourceFileExtension } from '@plebeiantech/lat.md-core/source-formats';
|
|
11
|
+
import { toPosix } from '@plebeiantech/lat.md-core/path';
|
|
8
12
|
import { renderMarkdown } from './markdown.js';
|
|
9
13
|
import { buildViewDiagnostics } from './diagnostics.js';
|
|
14
|
+
import { applyDocumentEdit, ViewDocumentConflictError, } from './document-edit.js';
|
|
10
15
|
import { buildGitDiffTree } from './git-diff.js';
|
|
11
16
|
import { buildViewGraph } from './graph.js';
|
|
12
17
|
import { buildViewTableOfContents } from './table-of-contents.js';
|
|
13
18
|
import { emptyViewGitSnapshot, findViewGitRepository, readViewGitSnapshot, sameViewGitSnapshot, } from './git.js';
|
|
14
19
|
import { DEFAULT_VIEW_LOGO_TEXT } from './protocol.js';
|
|
15
|
-
import { createMarkdownWikiLinkResolver, getViewSource, ViewDocumentNotFoundError, } from './repository.js';
|
|
16
|
-
import { buildViewReferenceIndex,
|
|
20
|
+
import { createMarkdownWikiLinkResolver, getViewExternal, getViewSource, ViewDocumentNotFoundError, ViewSourceNotFoundError, } from './repository.js';
|
|
21
|
+
import { buildViewReferenceIndex, renderSectionBackReferences, } from './references.js';
|
|
22
|
+
import { rewriteLocalFileLink } from './source-target.js';
|
|
17
23
|
const DEFAULT_DEBOUNCE_MS = 75;
|
|
18
24
|
const DEFAULT_GIT_POLL_MS = 2_000;
|
|
25
|
+
const EXTERNAL_REFRESH_PATH = '@lat-external-refresh';
|
|
26
|
+
const DOCUMENT_EDIT_WRITE_ATTEMPTS = 3;
|
|
27
|
+
const DOCUMENT_EDIT_TEMP_PREFIX = '.lat-edit-';
|
|
19
28
|
function isInside(root, candidate) {
|
|
20
29
|
const rel = relative(root, candidate);
|
|
21
30
|
return (rel === '' ||
|
|
@@ -25,12 +34,16 @@ function projectPath(projectRoot, path) {
|
|
|
25
34
|
const normalized = isAbsolute(path) ? relative(projectRoot, path) : path;
|
|
26
35
|
return toPosix(normalized).replace(/^\.\//, '');
|
|
27
36
|
}
|
|
37
|
+
function isInternalLatCachePath(path, latPath) {
|
|
38
|
+
const cachePath = latPath ? `${latPath}/.cache` : '.cache';
|
|
39
|
+
return path === cachePath || path.startsWith(`${cachePath}/`);
|
|
40
|
+
}
|
|
28
41
|
function excludedCodePath(projectRoot, path, excludedPaths) {
|
|
29
42
|
const absolutePath = resolve(projectRoot, path);
|
|
30
43
|
return excludedPaths.some((root) => isInside(resolve(root), absolutePath));
|
|
31
44
|
}
|
|
32
45
|
function sourcePath(path) {
|
|
33
|
-
return
|
|
46
|
+
return isSourceFileExtension(extname(path).toLowerCase());
|
|
34
47
|
}
|
|
35
48
|
function obviouslyIgnoredCodePath(path, latPath) {
|
|
36
49
|
const parts = path.split('/');
|
|
@@ -44,10 +57,8 @@ function codeRefsFromContent(path, content) {
|
|
|
44
57
|
const refs = [];
|
|
45
58
|
const lines = content.split('\n');
|
|
46
59
|
for (let index = 0; index < lines.length; index++) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
while ((match = LAT_REF_RE.exec(lines[index])) !== null) {
|
|
50
|
-
refs.push({ target: match[1], file: path, line: index + 1 });
|
|
60
|
+
for (const target of extractCodeRefTargets(lines[index])) {
|
|
61
|
+
refs.push({ target, file: path, line: index + 1 });
|
|
51
62
|
}
|
|
52
63
|
}
|
|
53
64
|
return refs;
|
|
@@ -63,7 +74,10 @@ async function loadCodeReferenceFiles(projectRoot, refs) {
|
|
|
63
74
|
const files = new Map();
|
|
64
75
|
await Promise.all([...refsByFile].map(async ([path, fileRefs]) => {
|
|
65
76
|
try {
|
|
66
|
-
const
|
|
77
|
+
const safePath = await repositoryFilePath(projectRoot, path);
|
|
78
|
+
if (!safePath)
|
|
79
|
+
return;
|
|
80
|
+
const content = await readFile(safePath, 'utf8');
|
|
67
81
|
files.set(path, { path, lines: content.split('\n'), refs: fileRefs });
|
|
68
82
|
}
|
|
69
83
|
catch {
|
|
@@ -72,25 +86,61 @@ async function loadCodeReferenceFiles(projectRoot, refs) {
|
|
|
72
86
|
}));
|
|
73
87
|
return files;
|
|
74
88
|
}
|
|
75
|
-
async function scanCodeState(projectRoot, excludedPaths = []) {
|
|
76
|
-
const
|
|
89
|
+
async function scanCodeState(projectRoot, excludedPaths = [], publishable) {
|
|
90
|
+
const discovery = createCodeReferenceDiscovery(projectRoot);
|
|
91
|
+
const [scan, sourceFiles] = await Promise.all([
|
|
92
|
+
discovery.scan(),
|
|
93
|
+
discovery.listSourceFiles(),
|
|
94
|
+
]);
|
|
77
95
|
const allowed = (path) => !excludedCodePath(projectRoot, path, excludedPaths);
|
|
78
|
-
const
|
|
79
|
-
const
|
|
96
|
+
const candidates = sourceFiles.filter(allowed);
|
|
97
|
+
const decisions = await Promise.all(candidates.map((path) => publishable?.(projectPath(projectRoot, path)) ?? true));
|
|
98
|
+
const files = candidates.filter((_, index) => decisions[index]);
|
|
80
99
|
const scope = new Set(files.map((path) => projectPath(projectRoot, path)));
|
|
100
|
+
const refs = scan.refs.filter((ref) => allowed(ref.file) && scope.has(ref.file));
|
|
81
101
|
return {
|
|
82
102
|
files: await loadCodeReferenceFiles(projectRoot, refs),
|
|
83
103
|
scope,
|
|
84
104
|
};
|
|
85
105
|
}
|
|
86
|
-
function viewIndex(latDir,
|
|
87
|
-
const files = [...
|
|
106
|
+
function viewIndex(latDir, markdownFiles, diagnostics, git, references, external) {
|
|
107
|
+
const files = [...markdownFiles.keys()].sort();
|
|
108
|
+
const externalFiles = new Map();
|
|
109
|
+
for (const target of references.externalByTarget.keys()) {
|
|
110
|
+
try {
|
|
111
|
+
const parsed = external.parse(target);
|
|
112
|
+
if (!parsed)
|
|
113
|
+
continue;
|
|
114
|
+
const hash = parsed.identity.indexOf('#');
|
|
115
|
+
const baseTarget = hash === -1 ? parsed.identity : parsed.identity.slice(0, hash);
|
|
116
|
+
externalFiles.set(baseTarget, {
|
|
117
|
+
handle: parsed.handle,
|
|
118
|
+
path: parsed.resolvedPath,
|
|
119
|
+
target: baseTarget,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// Invalid external targets remain diagnostics, not sidebar entries.
|
|
124
|
+
}
|
|
125
|
+
}
|
|
88
126
|
const directoryName = basename(latDir);
|
|
89
127
|
const indexName = directoryName.endsWith('.md')
|
|
90
128
|
? directoryName
|
|
91
129
|
: `${directoryName}.md`;
|
|
130
|
+
const directoryOrder = Object.fromEntries([...markdownFiles].flatMap(([path, file]) => {
|
|
131
|
+
const separator = path.lastIndexOf('/');
|
|
132
|
+
const directory = separator === -1 ? '' : path.slice(0, separator);
|
|
133
|
+
const name = directory ? basename(directory) : directoryName;
|
|
134
|
+
const filename = name.endsWith('.md') ? name : `${name}.md`;
|
|
135
|
+
if (path.slice(separator + 1) !== filename)
|
|
136
|
+
return [];
|
|
137
|
+
return [[directory, file.indexEntries]];
|
|
138
|
+
}));
|
|
92
139
|
return {
|
|
93
140
|
files,
|
|
141
|
+
directoryOrder,
|
|
142
|
+
externalFiles: [...externalFiles.values()].sort((left, right) => left.handle.localeCompare(right.handle) ||
|
|
143
|
+
left.path.localeCompare(right.path)),
|
|
94
144
|
entry: files.includes(indexName) ? indexName : (files[0] ?? ''),
|
|
95
145
|
errorCounts: Object.fromEntries([...diagnostics]
|
|
96
146
|
.filter(([, errors]) => errors.length > 0)
|
|
@@ -103,21 +153,34 @@ function viewIndex(latDir, paths, diagnostics, git) {
|
|
|
103
153
|
logoText: DEFAULT_VIEW_LOGO_TEXT,
|
|
104
154
|
};
|
|
105
155
|
}
|
|
106
|
-
async function buildSnapshot(latDir, projectRoot, markdownFiles, codeFiles, git, generation, markdownGeneration) {
|
|
156
|
+
async function buildSnapshot(latDir, projectRoot, markdownFiles, codeFiles, git, generation, markdownGeneration, options) {
|
|
107
157
|
const files = new Map([...markdownFiles].sort(([left], [right]) => left.localeCompare(right)));
|
|
108
158
|
const allSections = [...files.values()].flatMap((file) => file.sections);
|
|
109
|
-
const
|
|
110
|
-
|
|
159
|
+
const external = await createExternalResolver(latDir, projectRoot, {
|
|
160
|
+
ignoreLocal: options.externalIgnoreLocal,
|
|
161
|
+
ca: options.externalCa,
|
|
162
|
+
});
|
|
163
|
+
await external.reconcile();
|
|
164
|
+
const diagnostics = await buildViewDiagnostics(files.values(), codeFiles.values(), allSections, projectRoot, external, latDir);
|
|
165
|
+
const references = buildViewReferenceIndex(files.values(), codeFiles.values(), allSections, (target) => {
|
|
166
|
+
try {
|
|
167
|
+
return external.parse(target)?.identity ?? null;
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return target;
|
|
171
|
+
}
|
|
172
|
+
});
|
|
111
173
|
return {
|
|
112
174
|
generation,
|
|
113
175
|
markdownGeneration,
|
|
114
176
|
files,
|
|
115
177
|
allSections,
|
|
116
178
|
references,
|
|
117
|
-
graph: buildViewGraph(files.values(), codeFiles.values(), allSections, diagnostics, git, generation),
|
|
179
|
+
graph: buildViewGraph(files.values(), codeFiles.values(), allSections, diagnostics, git, generation, references, external),
|
|
118
180
|
diagnostics,
|
|
119
181
|
git,
|
|
120
|
-
index: viewIndex(latDir,
|
|
182
|
+
index: viewIndex(latDir, files, diagnostics, git, references, external),
|
|
183
|
+
external,
|
|
121
184
|
};
|
|
122
185
|
}
|
|
123
186
|
/** Own the immutable, incrementally refreshed project snapshot for `lat ui`. */
|
|
@@ -133,11 +196,13 @@ export class ViewStore {
|
|
|
133
196
|
ignoredCodePaths = new Set();
|
|
134
197
|
listeners = new Set();
|
|
135
198
|
watcher = null;
|
|
199
|
+
externalWatchers = [];
|
|
136
200
|
pendingPaths = new Set();
|
|
137
201
|
debounceTimer = null;
|
|
138
202
|
gitPollTimer = null;
|
|
139
203
|
gitPollQueued = false;
|
|
140
204
|
refreshTail = Promise.resolve();
|
|
205
|
+
editTail = Promise.resolve();
|
|
141
206
|
closed = false;
|
|
142
207
|
constructor(latDir, projectRoot, realLatDir, snapshot, codeFiles, codeScope, gitRepository, options) {
|
|
143
208
|
this.latDir = latDir;
|
|
@@ -168,6 +233,29 @@ export class ViewStore {
|
|
|
168
233
|
catch (error) {
|
|
169
234
|
process.stderr.write(`lat ui watcher: ${error.message}\n`);
|
|
170
235
|
}
|
|
236
|
+
this.refreshExternalWatchers();
|
|
237
|
+
}
|
|
238
|
+
refreshExternalWatchers() {
|
|
239
|
+
for (const watcher of this.externalWatchers)
|
|
240
|
+
watcher.close();
|
|
241
|
+
this.externalWatchers = [];
|
|
242
|
+
if (this.options.watch === false)
|
|
243
|
+
return;
|
|
244
|
+
const paths = new Set([...this.snapshotValue.external.snapshot.sources.values()]
|
|
245
|
+
.map((source) => source.localPath)
|
|
246
|
+
.filter((path) => Boolean(path)));
|
|
247
|
+
for (const path of paths) {
|
|
248
|
+
try {
|
|
249
|
+
const watcher = watchFiles(path, { recursive: true }, () => this.scheduleRefresh(EXTERNAL_REFRESH_PATH));
|
|
250
|
+
watcher.on('error', (error) => {
|
|
251
|
+
process.stderr.write(`lat ui external watcher: ${error.message}\n`);
|
|
252
|
+
});
|
|
253
|
+
this.externalWatchers.push(watcher);
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
process.stderr.write(`lat ui external watcher: ${error.message}\n`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
171
259
|
}
|
|
172
260
|
subscribe(listener) {
|
|
173
261
|
this.listeners.add(listener);
|
|
@@ -179,7 +267,54 @@ export class ViewStore {
|
|
|
179
267
|
getGraph() {
|
|
180
268
|
return this.snapshotValue.graph;
|
|
181
269
|
}
|
|
270
|
+
async renderSectionOutput(markdown, sectionId) {
|
|
271
|
+
const snapshot = this.snapshotValue;
|
|
272
|
+
const section = snapshot.allSections.find((candidate) => candidate.id.toLowerCase() === sectionId.toLowerCase());
|
|
273
|
+
const requestedPath = section
|
|
274
|
+
? toPosix(relative(this.latDir, resolve(this.projectRoot, section.filePath)))
|
|
275
|
+
: 'section-output.md';
|
|
276
|
+
const resolver = await createMarkdownWikiLinkResolver(this.latDir, requestedPath, snapshot.allSections, snapshot.references, snapshot.external, this.options.publishable);
|
|
277
|
+
return (await renderMarkdown(markdown, requestedPath, resolver)).tree;
|
|
278
|
+
}
|
|
279
|
+
async projectPreviewFile(path) {
|
|
280
|
+
if (!path ||
|
|
281
|
+
path.includes('@') ||
|
|
282
|
+
path.includes('\\') ||
|
|
283
|
+
path.split('/').some((part) => !part || part === '.' || part === '..')) {
|
|
284
|
+
throw new ViewDocumentNotFoundError('Project file not found');
|
|
285
|
+
}
|
|
286
|
+
if (this.options.publishable && !(await this.options.publishable(path))) {
|
|
287
|
+
throw new ViewDocumentNotFoundError('Project file is excluded from publication');
|
|
288
|
+
}
|
|
289
|
+
const file = await repositoryFilePath(this.projectRoot, path);
|
|
290
|
+
if (!file)
|
|
291
|
+
throw new ViewDocumentNotFoundError('Project file not found');
|
|
292
|
+
return file;
|
|
293
|
+
}
|
|
294
|
+
async getProjectDocument(path) {
|
|
295
|
+
const file = await this.projectPreviewFile(path);
|
|
296
|
+
if (!path.toLowerCase().endsWith('.md'))
|
|
297
|
+
throw new ViewDocumentNotFoundError('Markdown document not found');
|
|
298
|
+
const analysis = await analyzeMarkdownPath(file, this.latDir, this.projectRoot);
|
|
299
|
+
const requestedPath = '@/' + path;
|
|
300
|
+
const resolver = await createMarkdownWikiLinkResolver(this.latDir, toPosix(relative(this.latDir, file)), this.snapshotValue.allSections, this.snapshotValue.references, this.snapshotValue.external, this.options.publishable);
|
|
301
|
+
const rendered = await renderMarkdown(analysis.content, requestedPath, resolver, {
|
|
302
|
+
rewriteMarkdownLink: (url) => rewriteLocalFileLink(url, requestedPath),
|
|
303
|
+
});
|
|
304
|
+
return {
|
|
305
|
+
...rendered,
|
|
306
|
+
path: requestedPath,
|
|
307
|
+
gitTree: null,
|
|
308
|
+
tableOfContents: buildViewTableOfContents(analysis.sections, analysis.headingTitles, { errors: [], gitTree: null }),
|
|
309
|
+
graphNodeIds: {},
|
|
310
|
+
errors: [],
|
|
311
|
+
backReferences: [],
|
|
312
|
+
frontmatter: { requireCodeMention: false },
|
|
313
|
+
};
|
|
314
|
+
}
|
|
182
315
|
async getDocument(requestedPath) {
|
|
316
|
+
if (requestedPath.startsWith('@/'))
|
|
317
|
+
return this.getProjectDocument(requestedPath.slice(2));
|
|
183
318
|
if (!requestedPath ||
|
|
184
319
|
requestedPath.includes('\\') ||
|
|
185
320
|
isAbsolute(requestedPath) ||
|
|
@@ -191,24 +326,27 @@ export class ViewStore {
|
|
|
191
326
|
if (!file) {
|
|
192
327
|
throw new ViewDocumentNotFoundError('Markdown document not found');
|
|
193
328
|
}
|
|
194
|
-
const resolver = await createMarkdownWikiLinkResolver(this.latDir, requestedPath, snapshot.allSections, snapshot.references);
|
|
195
|
-
const rendered = await renderMarkdown(file.content, requestedPath, resolver, {
|
|
329
|
+
const resolver = await createMarkdownWikiLinkResolver(this.latDir, requestedPath, snapshot.allSections, snapshot.references, snapshot.external, this.options.publishable);
|
|
330
|
+
const rendered = await renderMarkdown(file.content, requestedPath, resolver, {
|
|
331
|
+
errors: [...(snapshot.diagnostics.get(requestedPath) ?? [])],
|
|
332
|
+
rewriteMarkdownLink: (url) => rewriteLocalFileLink(url, requestedPath),
|
|
333
|
+
});
|
|
196
334
|
const errors = [...(snapshot.diagnostics.get(requestedPath) ?? [])];
|
|
197
335
|
const gitFile = snapshot.git.files.get(requestedPath);
|
|
198
336
|
const gitTree = gitFile
|
|
199
|
-
? buildGitDiffTree(gitFile.baseContent, file.content
|
|
337
|
+
? buildGitDiffTree(gitFile.baseContent, file.content)
|
|
200
338
|
: null;
|
|
201
339
|
const gitRendered = gitTree
|
|
202
|
-
? await renderMarkdown(file.content, requestedPath, resolver, {
|
|
340
|
+
? await renderMarkdown(file.content, requestedPath, resolver, {
|
|
341
|
+
errors,
|
|
342
|
+
rewriteMarkdownLink: (url) => rewriteLocalFileLink(url, requestedPath),
|
|
343
|
+
}, gitTree)
|
|
203
344
|
: null;
|
|
204
345
|
return {
|
|
205
346
|
path: requestedPath,
|
|
206
347
|
...rendered,
|
|
207
|
-
|
|
208
|
-
tableOfContents: buildViewTableOfContents(file.sections, file.
|
|
209
|
-
errors,
|
|
210
|
-
gitTree,
|
|
211
|
-
}),
|
|
348
|
+
gitTree: gitRendered?.tree ?? null,
|
|
349
|
+
tableOfContents: buildViewTableOfContents(file.sections, file.headingTitles, { errors, gitTree }),
|
|
212
350
|
graphNodeIds: Object.fromEntries(snapshot.graph.nodes
|
|
213
351
|
.filter((node) => node.documentPath === requestedPath && node.kind === 'document')
|
|
214
352
|
.map((node) => {
|
|
@@ -223,20 +361,119 @@ export class ViewStore {
|
|
|
223
361
|
return [headingId, node.id];
|
|
224
362
|
})),
|
|
225
363
|
errors,
|
|
226
|
-
backReferences: await renderSectionBackReferences(snapshot.references, file.sections, this.latDir, this.projectRoot, (path) => createMarkdownWikiLinkResolver(this.latDir, path, snapshot.allSections, snapshot.references)),
|
|
364
|
+
backReferences: await renderSectionBackReferences(snapshot.references, file.sections, this.latDir, this.projectRoot, (path) => createMarkdownWikiLinkResolver(this.latDir, path, snapshot.allSections, snapshot.references, snapshot.external, this.options.publishable)),
|
|
227
365
|
frontmatter: {
|
|
228
|
-
requireCodeMention:
|
|
366
|
+
requireCodeMention: file.frontmatter.requireCodeMention === true,
|
|
229
367
|
},
|
|
230
368
|
};
|
|
231
369
|
}
|
|
232
|
-
|
|
370
|
+
async editableDocumentPath(requestedPath) {
|
|
371
|
+
if (!requestedPath ||
|
|
372
|
+
requestedPath.includes('\\') ||
|
|
373
|
+
isAbsolute(requestedPath) ||
|
|
374
|
+
!requestedPath.toLowerCase().endsWith('.md') ||
|
|
375
|
+
!this.snapshotValue.files.has(requestedPath)) {
|
|
376
|
+
throw new ViewDocumentNotFoundError('Markdown document not found');
|
|
377
|
+
}
|
|
378
|
+
let realFile;
|
|
379
|
+
try {
|
|
380
|
+
realFile = await realpath(resolve(this.latDir, requestedPath));
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
throw new ViewDocumentNotFoundError('Markdown document not found');
|
|
384
|
+
}
|
|
385
|
+
if (!isInside(this.realLatDir, realFile)) {
|
|
386
|
+
throw new ViewDocumentNotFoundError('Markdown document not found');
|
|
387
|
+
}
|
|
388
|
+
return realFile;
|
|
389
|
+
}
|
|
390
|
+
async getDocumentSource(requestedPath) {
|
|
391
|
+
const path = await this.editableDocumentPath(requestedPath);
|
|
392
|
+
return { path: requestedPath, content: await readFile(path, 'utf8') };
|
|
393
|
+
}
|
|
394
|
+
async getDocumentResource(requestedPath) {
|
|
395
|
+
if (requestedPath.startsWith('@/')) {
|
|
396
|
+
const path = requestedPath.slice(2);
|
|
397
|
+
if (path.toLowerCase().endsWith('.md'))
|
|
398
|
+
throw new ViewDocumentNotFoundError('Document resource not found');
|
|
399
|
+
return readFile(await this.projectPreviewFile(path));
|
|
400
|
+
}
|
|
401
|
+
if (this.options.publishable &&
|
|
402
|
+
!(await this.options.publishable(projectPath(this.projectRoot, resolve(this.latDir, requestedPath)))))
|
|
403
|
+
throw new ViewDocumentNotFoundError(`Resource is excluded from publication: ${requestedPath}`);
|
|
404
|
+
if (!requestedPath ||
|
|
405
|
+
requestedPath.includes('\\') ||
|
|
406
|
+
isAbsolute(requestedPath) ||
|
|
407
|
+
requestedPath.toLowerCase().endsWith('.md')) {
|
|
408
|
+
throw new ViewDocumentNotFoundError('Document resource not found');
|
|
409
|
+
}
|
|
410
|
+
let path;
|
|
411
|
+
try {
|
|
412
|
+
path = await realpath(resolve(this.latDir, requestedPath));
|
|
413
|
+
if (!isInside(this.realLatDir, path) || !(await stat(path)).isFile()) {
|
|
414
|
+
throw new ViewDocumentNotFoundError('Document resource not found');
|
|
415
|
+
}
|
|
416
|
+
return await readFile(path);
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
if (error instanceof ViewDocumentNotFoundError)
|
|
420
|
+
throw error;
|
|
421
|
+
throw new ViewDocumentNotFoundError('Document resource not found');
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
editDocument(requestedPath, baseContent, editedContent) {
|
|
425
|
+
const operation = this.editTail.then(async () => {
|
|
426
|
+
const path = await this.editableDocumentPath(requestedPath);
|
|
427
|
+
for (let attempt = 0; attempt < DOCUMENT_EDIT_WRITE_ATTEMPTS; attempt++) {
|
|
428
|
+
const currentContent = await readFile(path, 'utf8');
|
|
429
|
+
const edit = applyDocumentEdit(baseContent, editedContent, currentContent);
|
|
430
|
+
if (edit.content === currentContent) {
|
|
431
|
+
return { path: requestedPath, ...edit };
|
|
432
|
+
}
|
|
433
|
+
const currentStat = await stat(path);
|
|
434
|
+
const temporaryPath = resolve(this.latDir, `${DOCUMENT_EDIT_TEMP_PREFIX}${process.pid}-${randomUUID()}.tmp`);
|
|
435
|
+
try {
|
|
436
|
+
await writeFile(temporaryPath, edit.content, {
|
|
437
|
+
encoding: 'utf8',
|
|
438
|
+
flag: 'wx',
|
|
439
|
+
mode: currentStat.mode,
|
|
440
|
+
});
|
|
441
|
+
if ((await readFile(path, 'utf8')) !== currentContent)
|
|
442
|
+
continue;
|
|
443
|
+
await rename(temporaryPath, path);
|
|
444
|
+
}
|
|
445
|
+
finally {
|
|
446
|
+
await rm(temporaryPath, { force: true });
|
|
447
|
+
}
|
|
448
|
+
await this.refresh([resolve(this.latDir, requestedPath)]);
|
|
449
|
+
return { path: requestedPath, ...edit };
|
|
450
|
+
}
|
|
451
|
+
throw new ViewDocumentConflictError('Could not save because this file kept changing. Your edits are still in the editor.');
|
|
452
|
+
});
|
|
453
|
+
this.editTail = operation.then(() => undefined, () => undefined);
|
|
454
|
+
return operation;
|
|
455
|
+
}
|
|
456
|
+
async getSource(requestedPath, requestedSymbol = '', origin, requestedLine = 0) {
|
|
457
|
+
if (this.options.publishable &&
|
|
458
|
+
!(await this.options.publishable(requestedPath)))
|
|
459
|
+
throw new ViewSourceNotFoundError(`Source is excluded from publication: ${requestedPath}`);
|
|
233
460
|
const snapshot = this.snapshotValue;
|
|
234
|
-
return getViewSource(this.latDir, this.projectRoot, requestedPath, requestedSymbol, origin, requestedLine, snapshot.allSections, snapshot.references);
|
|
461
|
+
return getViewSource(this.latDir, this.projectRoot, requestedPath, requestedSymbol, origin, requestedLine, snapshot.allSections, snapshot.references, this.options.publishable);
|
|
462
|
+
}
|
|
463
|
+
getExternal(target) {
|
|
464
|
+
const snapshot = this.snapshotValue;
|
|
465
|
+
return getViewExternal(this.latDir, this.projectRoot, target, snapshot.external, snapshot.allSections, snapshot.references, this.options.publishable);
|
|
235
466
|
}
|
|
236
467
|
refresh(paths) {
|
|
237
468
|
if (this.closed)
|
|
238
469
|
return Promise.resolve();
|
|
239
|
-
const
|
|
470
|
+
const latPath = projectPath(this.projectRoot, this.latDir);
|
|
471
|
+
const normalized = paths
|
|
472
|
+
.map((path) => (path ? projectPath(this.projectRoot, path) : ''))
|
|
473
|
+
.filter((path) => !isInternalLatCachePath(path, latPath));
|
|
474
|
+
if (paths.length > 0 && normalized.length === 0) {
|
|
475
|
+
return Promise.resolve();
|
|
476
|
+
}
|
|
240
477
|
return this.queueRefresh(normalized, false);
|
|
241
478
|
}
|
|
242
479
|
queueRefresh(paths, pollGit) {
|
|
@@ -254,13 +491,30 @@ export class ViewStore {
|
|
|
254
491
|
this.gitPollTimer = null;
|
|
255
492
|
this.watcher?.close();
|
|
256
493
|
this.watcher = null;
|
|
494
|
+
for (const watcher of this.externalWatchers)
|
|
495
|
+
watcher.close();
|
|
496
|
+
this.externalWatchers = [];
|
|
497
|
+
await this.editTail;
|
|
257
498
|
await this.refreshTail;
|
|
258
499
|
this.listeners.clear();
|
|
259
500
|
}
|
|
260
501
|
scheduleRefresh(path) {
|
|
261
502
|
if (this.closed)
|
|
262
503
|
return;
|
|
263
|
-
|
|
504
|
+
if (path !== EXTERNAL_REFRESH_PATH &&
|
|
505
|
+
basename(path).startsWith(DOCUMENT_EDIT_TEMP_PREFIX) &&
|
|
506
|
+
path.endsWith('.tmp')) {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
const normalizedPath = path === EXTERNAL_REFRESH_PATH
|
|
510
|
+
? path
|
|
511
|
+
: path
|
|
512
|
+
? projectPath(this.projectRoot, path)
|
|
513
|
+
: '';
|
|
514
|
+
const latPath = projectPath(this.projectRoot, this.latDir);
|
|
515
|
+
if (isInternalLatCachePath(normalizedPath, latPath))
|
|
516
|
+
return;
|
|
517
|
+
this.pendingPaths.add(normalizedPath);
|
|
264
518
|
if (this.debounceTimer)
|
|
265
519
|
clearTimeout(this.debounceTimer);
|
|
266
520
|
this.debounceTimer = setTimeout(() => {
|
|
@@ -300,12 +554,13 @@ export class ViewStore {
|
|
|
300
554
|
}
|
|
301
555
|
if (!isInside(this.realLatDir, realFile))
|
|
302
556
|
return null;
|
|
303
|
-
|
|
304
|
-
return parseViewMarkdownFile(absolutePath, content, this.latDir, this.projectRoot);
|
|
557
|
+
return analyzeMarkdownPath(absolutePath, this.latDir, this.projectRoot);
|
|
305
558
|
}
|
|
306
559
|
async applyRefresh(paths, pollGit) {
|
|
307
560
|
const fullRefresh = paths.includes('');
|
|
308
561
|
const latPath = projectPath(this.projectRoot, this.latDir);
|
|
562
|
+
const externalChanged = paths.includes(EXTERNAL_REFRESH_PATH) ||
|
|
563
|
+
paths.includes(`${latPath}/config.local.yaml`);
|
|
309
564
|
const touchesMarkdown = fullRefresh ||
|
|
310
565
|
paths.some((path) => path === latPath || path.startsWith(`${latPath}/`));
|
|
311
566
|
let markdownFiles = new Map(this.snapshotValue.files);
|
|
@@ -380,7 +635,7 @@ export class ViewStore {
|
|
|
380
635
|
paths.some((path) => path === '.gitignore' || path.endsWith('/.gitignore')) ||
|
|
381
636
|
codePaths.some((path) => !this.codeScope.has(path) && !this.ignoredCodePaths.has(path));
|
|
382
637
|
if (refreshCodeScope) {
|
|
383
|
-
const nextCode = await scanCodeState(this.projectRoot, this.options.codeExcludePaths);
|
|
638
|
+
const nextCode = await scanCodeState(this.projectRoot, this.options.codeExcludePaths, this.options.publishable);
|
|
384
639
|
codeFiles = nextCode.files;
|
|
385
640
|
this.codeScope = nextCode.scope;
|
|
386
641
|
this.ignoredCodePaths.clear();
|
|
@@ -419,10 +674,12 @@ export class ViewStore {
|
|
|
419
674
|
if (!markdownChanged &&
|
|
420
675
|
!codeChanged &&
|
|
421
676
|
!gitChanged &&
|
|
422
|
-
!linkedResourceChanged
|
|
677
|
+
!linkedResourceChanged &&
|
|
678
|
+
!externalChanged)
|
|
423
679
|
return;
|
|
424
680
|
this.codeFiles = codeFiles;
|
|
425
|
-
this.snapshotValue = await buildSnapshot(this.latDir, this.projectRoot, markdownFiles, codeFiles, git, this.snapshotValue.generation + 1, this.snapshotValue.markdownGeneration + (markdownChanged ? 1 : 0));
|
|
681
|
+
this.snapshotValue = await buildSnapshot(this.latDir, this.projectRoot, markdownFiles, codeFiles, git, this.snapshotValue.generation + 1, this.snapshotValue.markdownGeneration + (markdownChanged ? 1 : 0), this.options);
|
|
682
|
+
this.refreshExternalWatchers();
|
|
426
683
|
const change = {
|
|
427
684
|
generation: this.snapshotValue.generation,
|
|
428
685
|
markdownGeneration: this.snapshotValue.markdownGeneration,
|
|
@@ -436,7 +693,7 @@ export async function createViewStore(latDir, projectRoot, options = {}) {
|
|
|
436
693
|
const [realLatDir, markdownPaths, codeState, gitRepository] = await Promise.all([
|
|
437
694
|
realpath(latDir),
|
|
438
695
|
listLatticeFiles(latDir),
|
|
439
|
-
scanCodeState(projectRoot, options.codeExcludePaths),
|
|
696
|
+
scanCodeState(projectRoot, options.codeExcludePaths, options.publishable),
|
|
440
697
|
options.git === false
|
|
441
698
|
? Promise.resolve(null)
|
|
442
699
|
: findViewGitRepository(projectRoot, latDir),
|
|
@@ -449,8 +706,7 @@ export async function createViewStore(latDir, projectRoot, options = {}) {
|
|
|
449
706
|
const realFile = await realpath(absolutePath);
|
|
450
707
|
if (!isInside(realLatDir, realFile))
|
|
451
708
|
return;
|
|
452
|
-
const
|
|
453
|
-
const parsed = parseViewMarkdownFile(absolutePath, content, latDir, projectRoot);
|
|
709
|
+
const parsed = await analyzeMarkdownPath(absolutePath, latDir, projectRoot);
|
|
454
710
|
markdownFiles.set(parsed.path, parsed);
|
|
455
711
|
}));
|
|
456
712
|
if (markdownFiles.size === 0) {
|
|
@@ -465,7 +721,7 @@ export async function createViewStore(latDir, projectRoot, options = {}) {
|
|
|
465
721
|
process.stderr.write(`lat ui git: ${error.message}\n`);
|
|
466
722
|
}
|
|
467
723
|
}
|
|
468
|
-
const store = new ViewStore(latDir, projectRoot, realLatDir, await buildSnapshot(latDir, projectRoot, markdownFiles, codeState.files, git, 0, 0), codeState.files, codeState.scope, gitRepository, options);
|
|
724
|
+
const store = new ViewStore(latDir, projectRoot, realLatDir, await buildSnapshot(latDir, projectRoot, markdownFiles, codeState.files, git, 0, 0, options), codeState.files, codeState.scope, gitRepository, options);
|
|
469
725
|
store.startWatching();
|
|
470
726
|
return store;
|
|
471
727
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Root } from 'mdast';
|
|
2
|
-
import { type Section } from '
|
|
2
|
+
import { type Section } from '@plebeiantech/lat.md-core/lattice-model';
|
|
3
3
|
import type { ViewDocumentError, ViewDocumentTocItem } from './protocol.js';
|
|
4
4
|
export type ViewTableOfContentsOptions = {
|
|
5
5
|
errors?: readonly ViewDocumentError[];
|
|
6
6
|
gitTree?: Root | null;
|
|
7
7
|
};
|
|
8
8
|
/** Project rendered headings into the document's local navigation. */
|
|
9
|
-
export declare function buildViewTableOfContents(sections: Section[],
|
|
9
|
+
export declare function buildViewTableOfContents(sections: Section[], titles: readonly string[], options?: ViewTableOfContentsOptions): ViewDocumentTocItem[];
|
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { flattenSections } from '../lattice.js';
|
|
3
|
-
function headingText(node) {
|
|
4
|
-
if (!node || typeof node !== 'object')
|
|
5
|
-
return '';
|
|
6
|
-
const value = node;
|
|
7
|
-
if (value.type === 'text' || value.type === 'inlineCode') {
|
|
8
|
-
return value.value ?? '';
|
|
9
|
-
}
|
|
10
|
-
if (value.type === 'image' || value.type === 'imageReference') {
|
|
11
|
-
return value.alt ?? '';
|
|
12
|
-
}
|
|
13
|
-
if (value.type === 'wikiLink') {
|
|
14
|
-
return value.data?.alias ?? value.value ?? '';
|
|
15
|
-
}
|
|
16
|
-
return value.children?.map(headingText).join('') ?? '';
|
|
17
|
-
}
|
|
1
|
+
import { flattenSections, } from '@plebeiantech/lat.md-core/lattice-model';
|
|
18
2
|
function sectionAtLine(sections, line) {
|
|
19
3
|
let owner = null;
|
|
20
4
|
for (const section of sections) {
|
|
@@ -76,12 +60,8 @@ function gitChangedSections(sections, tree) {
|
|
|
76
60
|
return changed;
|
|
77
61
|
}
|
|
78
62
|
/** Project rendered headings into the document's local navigation. */
|
|
79
|
-
export function buildViewTableOfContents(sections,
|
|
63
|
+
export function buildViewTableOfContents(sections, titles, options = {}) {
|
|
80
64
|
const flatSections = flattenSections(sections);
|
|
81
|
-
const titles = [];
|
|
82
|
-
visit(tree, 'heading', (node) => {
|
|
83
|
-
titles.push(headingText(node));
|
|
84
|
-
});
|
|
85
65
|
const errorCounts = new Map();
|
|
86
66
|
for (const error of options.errors ?? []) {
|
|
87
67
|
const owner = sectionAtLine(flatSections, error.line);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
type FileTraceResult = {
|
|
2
|
+
fileList: Set<string>;
|
|
3
|
+
warnings: Set<Error>;
|
|
4
|
+
};
|
|
5
|
+
export type VercelBuildDependencies = {
|
|
6
|
+
traceFiles: (files: string[], options: {
|
|
7
|
+
base: string;
|
|
8
|
+
conditions: string[];
|
|
9
|
+
exportsOnly: boolean;
|
|
10
|
+
processCwd: string;
|
|
11
|
+
}) => Promise<FileTraceResult>;
|
|
12
|
+
};
|
|
13
|
+
export type VercelBuildOptions = {
|
|
14
|
+
force?: boolean;
|
|
15
|
+
warn?: (message: string) => void;
|
|
16
|
+
};
|
|
17
|
+
export type VercelBuildResult = {
|
|
18
|
+
files: number;
|
|
19
|
+
functionPath: string;
|
|
20
|
+
outputDir: string;
|
|
21
|
+
};
|
|
22
|
+
/** Convert an installed portable Lat UI server into Vercel Build Output API v3. */
|
|
23
|
+
export declare function buildVercelOutput(requestedArtifact: string, requestedOutput?: string, options?: VercelBuildOptions, dependencies?: VercelBuildDependencies): Promise<VercelBuildResult>;
|
|
24
|
+
export {};
|