@plebeiantech/lat.md 0.12.3-fork.13 → 0.12.3-fork.15
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 +24 -0
- package/dist/src/cli/check-context.d.ts +56 -0
- package/dist/src/cli/check-context.js +215 -0
- package/dist/src/cli/check-coverage.js +9 -5
- package/dist/src/cli/check-frontmatter.js +1 -1
- package/dist/src/cli/check-mode.js +1 -1
- package/dist/src/cli/check-status.js +1 -1
- package/dist/src/cli/check.d.ts +19 -12
- package/dist/src/cli/check.js +259 -206
- package/dist/src/cli/context.js +1 -1
- package/dist/src/cli/expand.d.ts +1 -2
- package/dist/src/cli/expand.js +52 -5
- package/dist/src/cli/external.d.ts +11 -0
- package/dist/src/cli/external.js +185 -0
- package/dist/src/cli/fork-instructions.d.ts +1 -0
- package/dist/src/cli/fork-instructions.js +3 -2
- package/dist/src/cli/hook.d.ts +26 -0
- package/dist/src/cli/hook.js +112 -40
- package/dist/src/cli/index.js +55 -3
- package/dist/src/cli/init.d.ts +1 -0
- package/dist/src/cli/init.js +40 -2
- package/dist/src/cli/locate.js +4 -3
- package/dist/src/cli/refs.d.ts +2 -1
- package/dist/src/cli/refs.js +88 -43
- package/dist/src/cli/reindex.js +2 -1
- package/dist/src/cli/search.d.ts +12 -3
- package/dist/src/cli/search.js +45 -49
- package/dist/src/cli/section.d.ts +3 -1
- package/dist/src/cli/section.js +114 -38
- package/dist/src/code-refs.d.ts +17 -5
- package/dist/src/code-refs.js +246 -65
- package/dist/src/context.d.ts +3 -0
- package/dist/src/document-formats.d.ts +7 -0
- package/dist/src/document-formats.js +39 -0
- package/dist/src/extensions/alert-marker.d.ts +25 -0
- package/dist/src/extensions/alert-marker.js +55 -0
- package/dist/src/external-documents.d.ts +56 -0
- package/dist/src/external-documents.js +404 -0
- package/dist/src/external-sources.d.ts +136 -0
- package/dist/src/external-sources.js +1098 -0
- package/dist/src/fork/antigravity-hook.d.ts +47 -0
- package/dist/src/fork/antigravity-hook.js +424 -0
- package/dist/src/fork/antigravity-init.d.ts +17 -0
- package/dist/src/fork/antigravity-init.js +124 -0
- package/dist/src/fork/frontmatter-fields.d.ts +36 -0
- package/dist/src/fork/frontmatter-fields.js +23 -0
- package/dist/src/format.d.ts +5 -2
- package/dist/src/format.js +8 -3
- package/dist/src/graph-export.js +1 -1
- package/dist/src/lattice-model.d.ts +77 -0
- package/dist/src/lattice-model.js +464 -0
- package/dist/src/lattice.d.ts +9 -104
- package/dist/src/lattice.js +69 -516
- package/dist/src/markdown-analysis-cache.d.ts +20 -0
- package/dist/src/markdown-analysis-cache.js +139 -0
- package/dist/src/markdown-analysis-worker.d.ts +16 -0
- package/dist/src/markdown-analysis-worker.js +33 -0
- package/dist/src/markdown-analysis.d.ts +50 -0
- package/dist/src/markdown-analysis.js +139 -0
- package/dist/src/markdown-analyzer-loader.d.ts +4 -0
- package/dist/src/markdown-analyzer-loader.js +13 -0
- package/dist/src/markdown-validation.d.ts +25 -0
- package/dist/src/markdown-validation.js +104 -0
- package/dist/src/mcp/server.js +27 -11
- package/dist/src/parser-cache.d.ts +17 -0
- package/dist/src/parser-cache.js +65 -0
- package/dist/src/parser-import.d.ts +8 -0
- package/dist/src/parser-import.js +1 -0
- package/dist/src/parser.js +80 -5
- package/dist/src/path.d.ts +2 -0
- package/dist/src/path.js +4 -0
- package/dist/src/profiler.d.ts +16 -0
- package/dist/src/profiler.js +81 -0
- package/dist/src/project-analysis.d.ts +59 -0
- package/dist/src/project-analysis.js +233 -0
- package/dist/src/project-discovery.d.ts +6 -0
- package/dist/src/project-discovery.js +30 -0
- package/dist/src/repository-path.d.ts +11 -0
- package/dist/src/repository-path.js +52 -0
- package/dist/src/search/db.d.ts +1 -1
- package/dist/src/search/db.js +2 -2
- package/dist/src/search/embedder.d.ts +2 -1
- package/dist/src/search/embedder.js +6 -5
- package/dist/src/search/index.d.ts +2 -1
- package/dist/src/search/index.js +10 -8
- package/dist/src/search/query.d.ts +20 -0
- package/dist/src/search/query.js +67 -0
- package/dist/src/search/search.d.ts +3 -1
- package/dist/src/search/search.js +5 -2
- package/dist/src/source-formats.d.ts +7 -0
- package/dist/src/source-formats.js +26 -0
- package/dist/src/source-parser.d.ts +44 -4
- package/dist/src/source-parser.js +494 -57
- 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-B7quqPb8.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/abnfDiagram-VCTEODGH-V7-T6qsl.js +1 -0
- package/dist/src/view/client/assets/arc-BnwR8Bu7.js +1 -0
- package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-u97vDna9.js +36 -0
- package/dist/src/view/client/assets/blockDiagram-I7D4REHJ-DETl8e_H.js +129 -0
- package/dist/src/view/client/assets/c4Diagram-7LVT6UL2-DJRAT1Ve.js +38 -0
- package/dist/src/view/client/assets/channel-BwQbnWCN.js +1 -0
- package/dist/src/view/client/assets/chunk-2Q5K7J3B-C0TmOC1Q.js +1 -0
- package/dist/src/view/client/assets/chunk-5VM5RSS4-dfBOrYE6.js +15 -0
- package/dist/src/view/client/assets/chunk-F27PBJKO-DAnks99K.js +1 -0
- package/dist/src/view/client/assets/chunk-IMKFNOWR-CPjB07if.js +231 -0
- package/dist/src/view/client/assets/chunk-JWPE2WC7-VvU_gZI6.js +1 -0
- package/dist/src/view/client/assets/chunk-POPQ4Y6H-DDUbVF55.js +1 -0
- package/dist/src/view/client/assets/chunk-SVP7TREG-BHROkr6D.js +88 -0
- package/dist/src/view/client/assets/chunk-TICWLB2K-95PzGIOg.js +206 -0
- package/dist/src/view/client/assets/chunk-XXDRQBXY-MdmuLhIs.js +1 -0
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-HvQKkIS-.js +1 -0
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-HvQKkIS-.js +1 -0
- package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-CauUf_rN.js +1 -0
- package/dist/src/view/client/assets/cynefin-OW5HDTMX-CeA8IKWo.js +166 -0
- package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-L1rtcT8l.js +62 -0
- package/dist/src/view/client/assets/cytoscape.esm-DzSz-X2X.js +321 -0
- package/dist/src/view/client/assets/dagre-GXQ25YYZ-DLQwTa3H.js +4 -0
- package/dist/src/view/client/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/src/view/client/assets/diagram-S7CK7UJ4-kbKdIyXG.js +30 -0
- package/dist/src/view/client/assets/diagram-UQ7AKVKN-kmzp92RC.js +41 -0
- package/dist/src/view/client/assets/diagram-VSXAHHWV-EXJTU8qq.js +3 -0
- package/dist/src/view/client/assets/diagram-VX7I27RA-DAiIyMCG.js +24 -0
- package/dist/src/view/client/assets/diagram-Z3DM3KII-G9wz50ZV.js +24 -0
- package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-D2tVRCNA.js +1 -0
- package/dist/src/view/client/assets/erDiagram-RLTQ6QDP-C925J5A3.js +99 -0
- package/dist/src/view/client/assets/flowDiagram-HODETNUW-DzoCa-Nq.js +168 -0
- package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-D2ebbg4p.js +292 -0
- package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-B4QratYy.js +106 -0
- package/dist/src/view/client/assets/index-BnENo9bV.js +1 -0
- package/dist/src/view/client/assets/index-D0ajr_Ja.css +1 -0
- package/dist/src/view/client/assets/index-KZcnpXJH.js +321 -0
- package/dist/src/view/client/assets/infoDiagram-27XIBGKW-DL4mtHkt.js +2 -0
- package/dist/src/view/client/assets/init-Gi6I4Gst.js +1 -0
- package/dist/src/view/client/assets/ishikawaDiagram-5VMMS53U-CW4mto2d.js +70 -0
- package/dist/src/view/client/assets/journeyDiagram-3NMN7TZE-8R4eacFW.js +139 -0
- package/dist/src/view/client/assets/kanban-definition-UXKFOSKX-Cy9ioXEJ.js +89 -0
- package/dist/src/view/client/assets/katex-HP8lGamR.js +257 -0
- package/dist/src/view/client/assets/layout-C0MFuhth.js +1 -0
- package/dist/src/view/client/assets/linear-Dv3N4dQR.js +1 -0
- package/dist/src/view/client/assets/logo-small-RR_KBOAT.svg +149 -0
- package/dist/src/view/client/assets/maplibre-gl-DnqZgfUS.js +800 -0
- package/dist/src/view/client/assets/mermaid.core-bds9A7e2.js +310 -0
- package/dist/src/view/client/assets/mindmap-definition-YA3MSWOX-DjmGW355.js +96 -0
- package/dist/src/view/client/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-BWsZp0ab.js +1 -0
- package/dist/src/view/client/assets/pieDiagram-E7YTZNPT-CCH2gGR-.js +39 -0
- package/dist/src/view/client/assets/quadrantDiagram-AXDQQJYC-CjocPJFz.js +7 -0
- package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-BjLeb2KF.js +1 -0
- package/dist/src/view/client/assets/requirementDiagram-BXWQKSXE-Ct6AoXRr.js +84 -0
- package/dist/src/view/client/assets/sankeyDiagram-P5KCCOFB-CIpgGN_w.js +40 -0
- package/dist/src/view/client/assets/sequenceDiagram-WJ2MYXX4-DrmLFj6w.js +162 -0
- package/dist/src/view/client/assets/sizeCapture-INFHLROL-BdFMe2Lr.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-D77RDMKH-Zd9F1goW.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-ByIKCftl.js +1 -0
- package/dist/src/view/client/assets/swimlanes-42K2YHIH-a7VFwi00.js +1 -0
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-CzxaUHB-.js +8 -0
- package/dist/src/view/client/assets/three.module-PDSP0dbZ.js +4108 -0
- package/dist/src/view/client/assets/timeline-definition-24CTP7MA-BExPu6X5.js +120 -0
- package/dist/src/view/client/assets/vennDiagram-4TSXK5OY-PC1MU3si.js +34 -0
- package/dist/src/view/client/assets/wardleyDiagram-VM6X3IG4-DNWqU3fa.js +78 -0
- package/dist/src/view/client/assets/xychartDiagram-S5SC5T6Z-E1uA28_D.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 +12 -0
- package/dist/src/view/document-route.js +93 -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 +187 -0
- package/dist/src/view/git.js +1 -1
- package/dist/src/view/graph.d.ts +3 -2
- package/dist/src/view/graph.js +94 -7
- package/dist/src/view/highlight.d.ts +10 -2
- package/dist/src/view/highlight.js +4540 -1360
- package/dist/src/view/markdown.d.ts +3 -2
- package/dist/src/view/markdown.js +214 -53
- package/dist/src/view/protocol.d.ts +59 -6
- package/dist/src/view/references.d.ts +10 -25
- package/dist/src/view/references.js +117 -107
- package/dist/src/view/repository.d.ts +13 -3
- package/dist/src/view/repository.js +234 -15
- package/dist/src/view/search.d.ts +1 -1
- package/dist/src/view/search.js +3 -7
- package/dist/src/view/server.d.ts +11 -2
- package/dist/src/view/server.js +212 -70
- package/dist/src/view/source-target.js +5 -8
- package/dist/src/view/static-build.d.ts +1 -0
- package/dist/src/view/static-build.js +245 -42
- package/dist/src/view/static-protocol.d.ts +19 -2
- package/dist/src/view/store.d.ts +16 -3
- package/dist/src/view/store.js +228 -36
- package/dist/src/view/table-of-contents.d.ts +2 -2
- package/dist/src/view/table-of-contents.js +2 -22
- package/dist/src/walk.d.ts +5 -3
- package/dist/src/walk.js +102 -8
- 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 +52 -12
- 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 +118 -0
- package/plugins/lat-md/skills/lat-md/SKILL.md +178 -0
- package/plugins/lat-md/skills/lat-md-conventions/SKILL.md +182 -0
- package/templates/AGENTS.md +15 -3
- package/templates/cursor-rules.md +12 -3
- package/templates/skill/SKILL.md +22 -1
- 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
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lat-md
|
|
3
|
+
description: >-
|
|
4
|
+
Writing and maintaining lat.md documentation files — structured markdown that
|
|
5
|
+
describes a project's architecture, design decisions, and test specs. Use when
|
|
6
|
+
creating, editing, or reviewing files in the lat.md/ directory.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# lat.md Authoring Guide
|
|
10
|
+
|
|
11
|
+
This skill covers the syntax, structure rules, and conventions for writing `lat.md/` files. Load it whenever you need to create or edit sections in the `lat.md/` directory.
|
|
12
|
+
|
|
13
|
+
Project-specific lat documentation belongs in `lat.md/`. Do not modify this generated skill or a generated `AGENTS.md` to record project guidance: both are owned by lat tooling and may be replaced by a later `lat init`.
|
|
14
|
+
|
|
15
|
+
## What belongs in lat.md
|
|
16
|
+
|
|
17
|
+
`lat.md/` files describe **what** the project does and **why** — domain concepts, key design decisions, business logic, and test specifications. They do NOT duplicate source code. Think of each section as an anchor that source code references back to.
|
|
18
|
+
|
|
19
|
+
Treat `lat.md/` as a focused snapshot of the current state of affairs or planned features. Do not use it as a journal or changelog, and do not grow it just to record insignificant implementation details.
|
|
20
|
+
|
|
21
|
+
Good candidates for sections:
|
|
22
|
+
- Architecture decisions and their rationale
|
|
23
|
+
- Domain concepts and business rules
|
|
24
|
+
- API contracts and protocols
|
|
25
|
+
- Test specifications (what is tested and why)
|
|
26
|
+
- Non-obvious constraints or invariants
|
|
27
|
+
|
|
28
|
+
Bad candidates:
|
|
29
|
+
- Step-by-step code walkthroughs (the code itself is the walkthrough)
|
|
30
|
+
- Auto-generated API docs (use tools for that)
|
|
31
|
+
- Journal/changelog entries for each change
|
|
32
|
+
- Temporary notes or TODOs
|
|
33
|
+
- Insignificant implementation details that do not change the current-state model
|
|
34
|
+
|
|
35
|
+
## Section structure
|
|
36
|
+
|
|
37
|
+
Every section **must** have a leading paragraph — at least one sentence immediately after the heading, before any child headings or other block content.
|
|
38
|
+
|
|
39
|
+
The first paragraph must be ≤250 characters (excluding `[[wiki link]]` content). This paragraph is the section's identity — it appears in search results, command output, and RAG context.
|
|
40
|
+
|
|
41
|
+
```markdown
|
|
42
|
+
# Good Section
|
|
43
|
+
|
|
44
|
+
Brief overview of what this section documents and why it matters.
|
|
45
|
+
|
|
46
|
+
More detail can go in subsequent paragraphs, code blocks, or lists.
|
|
47
|
+
|
|
48
|
+
## Child heading
|
|
49
|
+
|
|
50
|
+
Details about this child topic.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
# Bad Section
|
|
55
|
+
|
|
56
|
+
## Child heading
|
|
57
|
+
|
|
58
|
+
This is invalid — "Bad Section" has no leading paragraph.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`lat check` enforces this rule.
|
|
62
|
+
|
|
63
|
+
## Section IDs
|
|
64
|
+
|
|
65
|
+
Sections are addressed by file path and heading chain:
|
|
66
|
+
|
|
67
|
+
- **Full form**: `lat.md/path/to/file#Heading#SubHeading`
|
|
68
|
+
- **Short form**: `file#Heading#SubHeading` (when the file stem is unique)
|
|
69
|
+
|
|
70
|
+
Examples: `lat.md/tests/search#RAG Replay Tests`, `cli#init`, `parser#Wiki Links`.
|
|
71
|
+
|
|
72
|
+
## Wiki links
|
|
73
|
+
|
|
74
|
+
Cross-reference other sections or source code with `[[target]]` or `[[target|alias]]`.
|
|
75
|
+
|
|
76
|
+
### Section links
|
|
77
|
+
|
|
78
|
+
```markdown
|
|
79
|
+
See [[cli#init]] for setup details.
|
|
80
|
+
The parser validates [[parser#Wiki Links|wiki link syntax]].
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Source code links
|
|
84
|
+
|
|
85
|
+
Reference functions, classes, constants, and methods in source files:
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
[[src/config.ts#getConfigDir]] — function
|
|
89
|
+
[[src/server.ts#App#listen]] — class method
|
|
90
|
+
[[lib/utils.py#parse_args]] — Python function
|
|
91
|
+
[[src/lib.rs#Greeter#greet]] — Rust impl method
|
|
92
|
+
[[src/app.go#Greeter#Greet]] — Go method
|
|
93
|
+
[[src/app.h#Greeter]] — C struct
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`lat check` validates that all targets exist.
|
|
97
|
+
|
|
98
|
+
## Code refs
|
|
99
|
+
|
|
100
|
+
Tie source code back to `lat.md/` sections with `@lat:` comments:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// @lat: [[cli#init]]
|
|
104
|
+
export function init() { ... }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
# @lat: [[cli#init]]
|
|
109
|
+
def init():
|
|
110
|
+
...
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Supported comment styles: `//` (JS/TS/Rust/Go/C) and `#` (Python).
|
|
114
|
+
|
|
115
|
+
Place one `@lat:` comment per section, at the relevant code — not at the top of the file.
|
|
116
|
+
|
|
117
|
+
## Test specs
|
|
118
|
+
|
|
119
|
+
Describe tests as sections in `lat.md/` files. Add frontmatter to require that every leaf section has a matching `@lat:` comment in test code:
|
|
120
|
+
|
|
121
|
+
```markdown
|
|
122
|
+
---
|
|
123
|
+
lat:
|
|
124
|
+
require-code-mention: true
|
|
125
|
+
---
|
|
126
|
+
# Tests
|
|
127
|
+
|
|
128
|
+
Authentication test specifications.
|
|
129
|
+
|
|
130
|
+
## User login
|
|
131
|
+
|
|
132
|
+
Verify credential validation and error handling.
|
|
133
|
+
|
|
134
|
+
### Rejects expired tokens
|
|
135
|
+
|
|
136
|
+
Tokens past their expiry timestamp are rejected with 401, even if otherwise valid.
|
|
137
|
+
|
|
138
|
+
### Handles missing password
|
|
139
|
+
|
|
140
|
+
Login request without a password field returns 400 with a descriptive error.
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Each test references its spec:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
# @lat: [[tests#User login#Rejects expired tokens]]
|
|
147
|
+
def test_rejects_expired_tokens():
|
|
148
|
+
...
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Rules:
|
|
152
|
+
- Every leaf section under `require-code-mention: true` must be referenced by exactly one `@lat:` comment
|
|
153
|
+
- Every section MUST have a description — at least one sentence explaining what the test verifies and why
|
|
154
|
+
- `lat check` flags unreferenced specs and dangling code refs
|
|
155
|
+
|
|
156
|
+
## Frontmatter
|
|
157
|
+
|
|
158
|
+
Optional YAML frontmatter at the top of `lat.md/` files:
|
|
159
|
+
|
|
160
|
+
```yaml
|
|
161
|
+
---
|
|
162
|
+
lat:
|
|
163
|
+
require-code-mention: true
|
|
164
|
+
---
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Currently the only supported field is `require-code-mention` for test spec enforcement.
|
|
168
|
+
|
|
169
|
+
## Validation
|
|
170
|
+
|
|
171
|
+
Always run `lat check` after editing `lat.md/` files. It validates:
|
|
172
|
+
- All wiki links point to existing sections or source code symbols
|
|
173
|
+
- All relative markdown links point to existing files
|
|
174
|
+
- Full and collapsed reference-style links have definitions
|
|
175
|
+
- All `@lat:` code refs point to existing sections
|
|
176
|
+
- Every section has a leading paragraph (≤250 chars)
|
|
177
|
+
- All `require-code-mention` leaf sections are referenced in code
|
|
178
|
+
- Every `lat.md/` directory has an accurate index
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lat-md-conventions
|
|
3
|
+
description: >-
|
|
4
|
+
Rules lat check enforces in this project: Diátaxis mode placement for every
|
|
5
|
+
lat.md/ document, mandatory @lat: code refs starting at the application
|
|
6
|
+
entrypoint, and test specs wired to their tests. Load alongside lat-md
|
|
7
|
+
whenever creating or editing files under lat.md/.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# lat.md conventions this project enforces
|
|
11
|
+
|
|
12
|
+
`lat check` fails on the first three rules below. The last two it cannot see,
|
|
13
|
+
and they matter as much. None of the five are style preferences. This block is
|
|
14
|
+
generated and a later `lat init` replaces it — record project guidance in
|
|
15
|
+
`lat.md/`, never here.
|
|
16
|
+
|
|
17
|
+
## Every document goes in a Diátaxis mode directory
|
|
18
|
+
|
|
19
|
+
A document belongs in exactly one of four subdirectories, and `lat check mode`
|
|
20
|
+
enforces one shape rule for each:
|
|
21
|
+
|
|
22
|
+
| Directory | Holds | Shape rule |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| `lat.md/tutorials/` | a guided first pass for someone new | an ordered list of steps, and a stated outcome |
|
|
25
|
+
| `lat.md/how-to/` | a recipe for a task that recurs | an ordered list of steps |
|
|
26
|
+
| `lat.md/reference/` | lookup facts: fields, states, limits, names | no narrative prose — no second paragraph under a heading |
|
|
27
|
+
| `lat.md/explanation/` | why the design is what it is | no imperative commands |
|
|
28
|
+
|
|
29
|
+
A document is classified either by the directory it sits in, or by declaring
|
|
30
|
+
the mode in its own frontmatter:
|
|
31
|
+
|
|
32
|
+
```markdown
|
|
33
|
+
---
|
|
34
|
+
lat:
|
|
35
|
+
mode: explanation
|
|
36
|
+
---
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Both are enforced identically — `lat check mode` applies the shape rule to any
|
|
40
|
+
document that declares a mode, whether or not the root index carries
|
|
41
|
+
`require-mode: true`. That flag adds a separate rule: a document declaring *no*
|
|
42
|
+
mode, in no mode directory, becomes an error too.
|
|
43
|
+
|
|
44
|
+
Prefer the directory in a tree you own outright. Prefer the declaration when
|
|
45
|
+
the file cannot move — a document another project maintains, or a tree other
|
|
46
|
+
agents are writing to while you work. Moving costs every reference to the file;
|
|
47
|
+
declaring costs nothing at read time, because frontmatter sits above the first
|
|
48
|
+
heading and outside every section.
|
|
49
|
+
|
|
50
|
+
**A document that fails its mode is usually two documents.** A file that lists
|
|
51
|
+
the states *and* argues for the design is mixed: the lookup half goes in
|
|
52
|
+
`reference/`, the reasoning half in `explanation/`, and each links the other.
|
|
53
|
+
Filing it under one mode and softening the prose until the check passes is the
|
|
54
|
+
wrong repair.
|
|
55
|
+
|
|
56
|
+
Classifying a mixed document does not make it pass. Narrative prose put under
|
|
57
|
+
`reference/` fails on contact, because a reference may not carry a second
|
|
58
|
+
paragraph under a heading — so a move is not a way to adopt the rule cheaply.
|
|
59
|
+
Split first, then place. And `explanation` is not the safe default: it bans
|
|
60
|
+
only imperative commands, so nearly any prose passes it. Declaring it is a
|
|
61
|
+
claim about the document, not somewhere to put whatever is left over. A
|
|
62
|
+
document you cannot honestly classify is better left undeclared than
|
|
63
|
+
mislabelled.
|
|
64
|
+
|
|
65
|
+
Classify before writing, not after. If a `diataxis` skill is available, use it.
|
|
66
|
+
|
|
67
|
+
## Every project has at least one `@lat:` code ref
|
|
68
|
+
|
|
69
|
+
`lat check` fails a tree that has documents and no `@lat:` ref anywhere in the
|
|
70
|
+
codebase. A graph nothing points at cannot be reached from the code, which is
|
|
71
|
+
the only reason it exists.
|
|
72
|
+
|
|
73
|
+
Start at the application entrypoint — `config/application.rb`, `src/index.ts`,
|
|
74
|
+
`main.go`, `manage.py`, whatever a new reader opens first — and point it at the
|
|
75
|
+
root index:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
# @lat: [[lat#Acme]]
|
|
79
|
+
module Acme
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Then one ref per section that source code actually implements, placed at that
|
|
83
|
+
code. Never in a block at the top of a file.
|
|
84
|
+
|
|
85
|
+
### An `@lat:` pointer is exempt from this project's comment conventions
|
|
86
|
+
|
|
87
|
+
A repository that minimises, budgets, or forbids comments is right about prose
|
|
88
|
+
comments and does not reach this one. An `@lat:` line is a machine directive,
|
|
89
|
+
in the same class as `# frozen_string_literal:` or `// eslint-disable`. It
|
|
90
|
+
carries no rationale, asserts nothing a reader could dispute, and cannot rot
|
|
91
|
+
quietly — `lat check` fails the moment its target moves or disappears.
|
|
92
|
+
|
|
93
|
+
Add the ref. Then, if the reasoning that would have been a comment is worth
|
|
94
|
+
keeping, put it in a `lat.md/explanation/` section and let the pointer reach it.
|
|
95
|
+
|
|
96
|
+
### The marker is a comment syntax, not a language allowlist
|
|
97
|
+
|
|
98
|
+
`//` for C-family languages; `#` for Ruby, Python, shell, Elixir, YAML, Make,
|
|
99
|
+
and everything else that comments with `#`. The scan is textual and walks every
|
|
100
|
+
non-markdown file in the project, so every language works.
|
|
101
|
+
|
|
102
|
+
Any list of example languages you find is a list of examples. Never conclude a
|
|
103
|
+
language is unsupported because it is absent from one. `lat check` prints what
|
|
104
|
+
it scanned:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
Scanned 41 .md, 622 .rb, 118 .tsx in 1.2s
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Read that line rather than guessing, and if you are still unsure, add one ref
|
|
111
|
+
and run the check. It costs one command.
|
|
112
|
+
|
|
113
|
+
(The tree-sitter grammars limit only `[[src/file.ts#symbol]]` wiki links, which
|
|
114
|
+
resolve a symbol inside source. `@lat:` refs point the other way and have no
|
|
115
|
+
such limit.)
|
|
116
|
+
|
|
117
|
+
## Test specs are wired to their tests
|
|
118
|
+
|
|
119
|
+
A document describing tests declares it in frontmatter:
|
|
120
|
+
|
|
121
|
+
```markdown
|
|
122
|
+
---
|
|
123
|
+
lat:
|
|
124
|
+
require-code-mention: true
|
|
125
|
+
---
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Every leaf section then needs exactly one `@lat:` comment at the test that
|
|
129
|
+
covers it, and every section needs at least one sentence saying what it
|
|
130
|
+
verifies and why. `lat check` reports any spec section no test claims, and any
|
|
131
|
+
ref pointing at no section.
|
|
132
|
+
|
|
133
|
+
## One specialty per document
|
|
134
|
+
|
|
135
|
+
A document is **small**, **discrete**, and does **not conflict** with any
|
|
136
|
+
other. Those are three demands on the same thing: a reader must be able to
|
|
137
|
+
find the one place a fact is written down, and trust it.
|
|
138
|
+
|
|
139
|
+
**Small — a document covers one specialty.** Not one topic area; one
|
|
140
|
+
specialty. When a document covers two, it is two documents. Past roughly forty
|
|
141
|
+
sections it has almost certainly become several, and an agent then loads all of
|
|
142
|
+
it to reach one part.
|
|
143
|
+
|
|
144
|
+
**Discrete — each document covers its own specialty.** Before writing a new
|
|
145
|
+
document, search for the specialty first:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
lat search "the thing you are about to document"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
An overlap has two honest repairs, and picking neither is what produces the
|
|
152
|
+
third copy. Either the two are one document and belong merged, or the part they
|
|
153
|
+
share is its own document that both link. Deciding they are "mostly different"
|
|
154
|
+
and writing anyway is how the set rots.
|
|
155
|
+
|
|
156
|
+
**Does not conflict — two documents never say different things about the same
|
|
157
|
+
specialty.** Never restate a fact another document owns. Link to it with
|
|
158
|
+
`[[section]]`. A restatement is a second copy, a second copy drifts, and drift
|
|
159
|
+
is how document B ends up contradicting document A while both look maintained.
|
|
160
|
+
|
|
161
|
+
The mode rule above is the sharpest available test of "one specialty": a
|
|
162
|
+
document that fails its mode is usually two documents. Split it. Do not soften
|
|
163
|
+
the prose until the check passes.
|
|
164
|
+
|
|
165
|
+
## Read sections, not files
|
|
166
|
+
|
|
167
|
+
`lat search` prints a section id and the exact lines that section occupies.
|
|
168
|
+
Resolve it with `lat section`, or read only that line range. Opening the whole
|
|
169
|
+
file is the reflex to break, and it is the expensive one:
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
lat search "how does backend selection work"
|
|
173
|
+
lat section "cli#CLI#search#Backend selection"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
not a `read` of `lat.md/cli.md`. Measured on lat.md's own graph, the section
|
|
177
|
+
costs 4 KB against the file's 44 KB — eleven times the context for the same
|
|
178
|
+
answer, and the answer arrives buried in forty-one sections that were not
|
|
179
|
+
asked about.
|
|
180
|
+
|
|
181
|
+
Use `lat expand` on a prompt carrying `[[refs]]` for the same reason: it
|
|
182
|
+
resolves each ref to a location and a preview rather than to a file.
|
package/templates/AGENTS.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Before starting work
|
|
2
2
|
|
|
3
|
+
Use Lat's knowledge graph to ground each task before changing code.
|
|
4
|
+
|
|
3
5
|
- Run `lat search` to find sections relevant to your task. Read them to understand the design intent before writing code.
|
|
4
6
|
- Run `lat expand` on user prompts to expand any `[[refs]]` — this resolves section names to file locations and provides context.
|
|
5
7
|
|
|
@@ -15,17 +17,22 @@ After EVERY task, before responding to the user:
|
|
|
15
17
|
|
|
16
18
|
# What is lat.md?
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
Lat.md is the project's structured knowledge graph for architecture, design decisions, behavior, and tests.
|
|
21
|
+
|
|
22
|
+
The graph lives in `lat.md/` as cross-linked Markdown describing **what** the project does and **why**. Use it to ground work in actual architecture, and keep it a focused current/planned snapshot rather than a journal or changelog.
|
|
19
23
|
|
|
20
24
|
Project-specific lat documentation belongs in `lat.md/`. Do not modify this generated instruction file or a generated `lat-md` `SKILL.md` to record project guidance: both are owned by lat tooling and may be replaced by a later `lat init`.
|
|
21
25
|
|
|
22
26
|
# Commands
|
|
23
27
|
|
|
28
|
+
Use these commands to navigate, expand, and validate the project knowledge graph.
|
|
29
|
+
|
|
24
30
|
```bash
|
|
25
31
|
lat locate "Section Name" # find a section by name (exact, fuzzy)
|
|
26
32
|
lat refs "file#Section" # find what references a section
|
|
27
33
|
lat search "natural language" # semantic search across all sections
|
|
28
34
|
lat expand "user prompt text" # expand [[refs]] to resolved locations
|
|
35
|
+
lat external show <handle> # inspect a pinned external source before cloning it
|
|
29
36
|
lat check # run full graph and documentation validation
|
|
30
37
|
```
|
|
31
38
|
|
|
@@ -35,9 +42,12 @@ If `lat search` fails because no API key is configured, explain to the user that
|
|
|
35
42
|
|
|
36
43
|
# Syntax primer
|
|
37
44
|
|
|
45
|
+
Lat uses stable section ids, wiki links, source links, and code references to connect documentation with implementation.
|
|
46
|
+
|
|
38
47
|
- **Section ids**: `lat.md/path/to/file#Heading#SubHeading` — full form uses project-root-relative path (e.g. `lat.md/tests/search#RAG Replay Tests`). Short form uses bare file name when unique (e.g. `search#RAG Replay Tests`, `cli#search#Indexing`).
|
|
39
|
-
- **Wiki links**: `[[target]]` or `[[target|alias]]` — cross-references between sections. Can also reference source code: `[[src/foo.ts#myFunction]]`.
|
|
40
|
-
- **
|
|
48
|
+
- **Wiki links**: `[[target]]` or `[[target|alias]]` — cross-references between sections. Can also reference repository paths or source code: `[[schema.sql]]`, `[[src/components]]`, `[[src/foo.ts#myFunction]]`.
|
|
49
|
+
- **Repository path links**: Wiki links without a `#` fragment may target any existing file or directory inside the project. Unsupported formats validate but cannot be opened by Lat; fragments require a `lat.md/` section or supported source file.
|
|
50
|
+
- **Source code links**: Wiki links in `lat.md/` files can reference functions, classes, constants, and methods in supported source files. Use the full path: `[[src/config.ts#getConfigDir]]`, `[[src/server.ts#App#listen]]` (class method), `[[lib/utils.py#parse_args]]`, `[[src/lib.rs#Greeter#greet]]` (Rust impl method), `[[src/app.go#Greeter#Greet]]` (Go method), `[[src/app.h#Greeter]]` (C struct). When prose names an implementation symbol or a behavior governed by one, link the symbol instead of using a bare code span or copying its literal value. Prefer `[[src/config.ts#DEFAULT_TIMEOUT]]` (or an aliased form) over a bare identifier or copied value. `lat check` validates these exist.
|
|
41
51
|
- **Code refs**: `// @lat: [[section-id]]` (JS/TS/Rust/Go/C) or `# @lat: [[section-id]]` (Python) — ties source code to concepts
|
|
42
52
|
|
|
43
53
|
# Test specs
|
|
@@ -82,6 +92,8 @@ Do not duplicate refs. One `@lat:` comment per spec section, placed at the test
|
|
|
82
92
|
|
|
83
93
|
# Section structure
|
|
84
94
|
|
|
95
|
+
Concise opening paragraphs give every section a stable overview for validation and discovery.
|
|
96
|
+
|
|
85
97
|
Every section in `lat.md/` **must** have a leading paragraph — at least one sentence immediately after the heading, before any child headings or other block content. The first paragraph must be ≤250 characters (excluding `[[wiki link]]` content). This paragraph serves as the section's overview and is used in search results, command output, and RAG context — keeping it concise guarantees the section's essence is always captured.
|
|
86
98
|
|
|
87
99
|
```markdown
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Before starting work
|
|
2
2
|
|
|
3
|
+
Use Lat's knowledge graph to ground each task before changing code.
|
|
4
|
+
|
|
3
5
|
- Use the `lat_search` tool to find sections relevant to your task. Read them to understand the design intent before writing code.
|
|
4
6
|
- Use the `lat_expand` tool on user prompts to expand any `[[refs]]` — this resolves section names to file locations and provides context.
|
|
5
7
|
|
|
@@ -15,10 +17,14 @@ After EVERY task, before responding to the user:
|
|
|
15
17
|
|
|
16
18
|
# What is lat.md?
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
Lat.md is the project's structured knowledge graph for architecture, design decisions, behavior, and tests.
|
|
21
|
+
|
|
22
|
+
The graph lives in `lat.md/` as cross-linked Markdown describing **what** the project does and **why**. Use it to ground work in actual architecture, and keep it a focused current/planned snapshot rather than a journal or changelog.
|
|
19
23
|
|
|
20
24
|
# Tools
|
|
21
25
|
|
|
26
|
+
Use the Lat MCP tools to navigate, expand, and validate the project knowledge graph.
|
|
27
|
+
|
|
22
28
|
You have access to the following MCP tools from the `lat` server:
|
|
23
29
|
|
|
24
30
|
- **lat_locate** — find a section by name (exact, fuzzy)
|
|
@@ -31,9 +37,12 @@ If `lat_search` fails because `LAT_LLM_KEY` is not set, explain to the user that
|
|
|
31
37
|
|
|
32
38
|
# Syntax primer
|
|
33
39
|
|
|
40
|
+
Lat uses stable section ids, wiki links, source links, and code references to connect documentation with implementation.
|
|
41
|
+
|
|
34
42
|
- **Section ids**: `lat.md/path/to/file#Heading#SubHeading` — full form uses project-root-relative path (e.g. `lat.md/tests/search#RAG Replay Tests`). Short form uses bare file name when unique (e.g. `search#RAG Replay Tests`, `cli#search#Indexing`).
|
|
35
|
-
- **Wiki links**: `[[target]]` or `[[target|alias]]` — cross-references between sections. Can also reference source code: `[[src/foo.ts#myFunction]]`.
|
|
36
|
-
- **
|
|
43
|
+
- **Wiki links**: `[[target]]` or `[[target|alias]]` — cross-references between sections. Can also reference repository paths or source code: `[[schema.sql]]`, `[[src/components]]`, `[[src/foo.ts#myFunction]]`.
|
|
44
|
+
- **Repository path links**: Wiki links without a `#` fragment may target any existing file or directory inside the project. Unsupported formats validate but cannot be opened by Lat; fragments require a `lat.md/` section or supported source file.
|
|
45
|
+
- **Source code links**: Wiki links in `lat.md/` files can reference functions, classes, constants, and methods in supported source files. Use the full path: `[[src/config.ts#getConfigDir]]`, `[[src/server.ts#App#listen]]` (class method), `[[lib/utils.py#parse_args]]`, `[[src/lib.rs#Greeter#greet]]` (Rust impl method), `[[src/app.go#Greeter#Greet]]` (Go method), `[[src/app.h#Greeter]]` (C struct). When prose names an implementation symbol or a behavior governed by one, link the symbol instead of using a bare code span or copying its literal value. Prefer `[[src/config.ts#DEFAULT_TIMEOUT]]` (or an aliased form) over a bare identifier or copied value. `lat check` validates these exist.
|
|
37
46
|
- **Code refs**: `// @lat: [[section-id]]` (JS/TS/Rust/Go/C) or `# @lat: [[section-id]]` (Python) — ties source code to concepts
|
|
38
47
|
|
|
39
48
|
# Test specs
|
package/templates/skill/SKILL.md
CHANGED
|
@@ -69,17 +69,36 @@ Sections are addressed by file path and heading chain:
|
|
|
69
69
|
|
|
70
70
|
Examples: `lat.md/tests/search#RAG Replay Tests`, `cli#init`, `parser#Wiki Links`.
|
|
71
71
|
|
|
72
|
+
Configured external sources use `[[handle:path/to/file.md#Heading]]` for
|
|
73
|
+
Markdown headings and `[[handle:path/to/file.ts#symbol]]` for supported code
|
|
74
|
+
symbols. Run `lat external show <handle>` before cloning an external source;
|
|
75
|
+
its output includes the pinned commit and safe checkout suggestions.
|
|
76
|
+
|
|
72
77
|
## Wiki links
|
|
73
78
|
|
|
74
79
|
Cross-reference other sections or source code with `[[target]]` or `[[target|alias]]`.
|
|
75
80
|
|
|
76
81
|
### Section links
|
|
77
82
|
|
|
83
|
+
Section links connect related concepts while keeping their stable graph identities explicit.
|
|
84
|
+
|
|
78
85
|
```markdown
|
|
79
86
|
See [[cli#init]] for setup details.
|
|
80
87
|
The parser validates [[parser#Wiki Links|wiki link syntax]].
|
|
81
88
|
```
|
|
82
89
|
|
|
90
|
+
### Repository path links
|
|
91
|
+
|
|
92
|
+
Reference any existing file or directory beneath the project root without a fragment:
|
|
93
|
+
|
|
94
|
+
```markdown
|
|
95
|
+
[[schema.sql]]
|
|
96
|
+
[[CHANGELOG]]
|
|
97
|
+
[[src/components]]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Unsupported formats validate as references but cannot be opened by Lat. A `#fragment` requires a `lat.md/` section or a supported source file.
|
|
101
|
+
|
|
83
102
|
### Source code links
|
|
84
103
|
|
|
85
104
|
Reference functions, classes, constants, and methods in source files:
|
|
@@ -93,6 +112,8 @@ Reference functions, classes, constants, and methods in source files:
|
|
|
93
112
|
[[src/app.h#Greeter]] — C struct
|
|
94
113
|
```
|
|
95
114
|
|
|
115
|
+
When prose names an implementation symbol or a behavior governed by one, link the symbol instead of using a bare code span or copying its literal value. Prefer `[[src/config.ts#DEFAULT_TIMEOUT]]` (or `[[src/config.ts#DEFAULT_TIMEOUT|the default timeout]]`) over a bare identifier or copied value. Keep the behavioral explanation in prose; the link makes its implementation binding navigable and validated.
|
|
116
|
+
|
|
96
117
|
`lat check` validates that all targets exist.
|
|
97
118
|
|
|
98
119
|
## Code refs
|
|
@@ -169,7 +190,7 @@ Currently the only supported field is `require-code-mention` for test spec enfor
|
|
|
169
190
|
## Validation
|
|
170
191
|
|
|
171
192
|
Always run `lat check` after editing `lat.md/` files. It validates:
|
|
172
|
-
- All wiki links point to existing sections or source code symbols
|
|
193
|
+
- All wiki links point to existing sections, repository paths, or source code symbols
|
|
173
194
|
- All relative markdown links point to existing files
|
|
174
195
|
- Full and collapsed reference-style links have definitions
|
|
175
196
|
- All `@lat:` code refs point to existing sections
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
:root{color:#171717;background:#fff;font-family:Geist,Geist Sans,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-synthesis:none;text-rendering:optimizeLegibility;color-scheme:light dark;--background: #fff;--panel: #fafafa;--sidebar: #fafafa;--sidebar-selection: #eaeaea;--panel-border: #eaeaea;--text: #171717;--muted: #666;--accent: #171717;--accent-soft: #ededed;--link: #0070f3;--danger: #e5484d;--danger-soft: #ffebe9;--danger-border: #f3b8b8;--warning: #b7791f;--warning-soft: #fff4ce;--success: #2e7d46;--success-soft: #e9f9ee;--git-notification: #e47f19;--code: #f5f5f5;--context-surface: #f7f7f7;--inline-code: #ededed;--reference-control: #e5e5e5;--graph-document: #0070f3;--graph-code: #d97706;--syntax-built-in: #9a3f75;--syntax-comment: #737373;--syntax-keyword: #6c4bc2;--syntax-number: #a85414;--syntax-string: #397348;--syntax-title: #26649a}@media(prefers-color-scheme:dark){:root{color:#ededed;background:#000;--background: #000;--panel: #0a0a0a;--sidebar: #000;--sidebar-selection: #242424;--panel-border: #262626;--text: #ededed;--muted: #888;--accent: #fff;--accent-soft: #1f1f1f;--link: rgb(82, 168, 255);--danger: #ff6166;--danger-soft: #2a1314;--danger-border: #5c2628;--warning: #f5a623;--warning-soft: #2a210f;--success: #62c073;--success-soft: #12261a;--git-notification: #f0a044;--code: #111;--context-surface: #111;--inline-code: #1f1f1f;--reference-control: #262626;--graph-document: rgb(82, 168, 255);--graph-code: #f5a623;--syntax-built-in: #e6a2cc;--syntax-comment: #888;--syntax-keyword: #c2adff;--syntax-number: #efb271;--syntax-string: #9fd0a5;--syntax-title: #8fc6ef}}*{box-sizing:border-box}body{margin:0;min-width:320px;min-height:100vh;color:var(--text);background:var(--background);-webkit-font-smoothing:antialiased}::selection{color:var(--background);background:var(--text)}a{color:var(--link)}.app-shell{display:grid;grid-template-columns:260px minmax(0,1fr);min-height:100vh}.sidebar{position:sticky;top:0;height:100vh;padding:28px 18px;overflow-y:auto;background:var(--sidebar);border-right:0}.sidebar-header{display:flex;margin:0 2px 34px 10px;align-items:center;justify-content:space-between}.mobile-navigation-trigger{display:none}.brand{display:inline-flex;min-width:0;align-items:center;overflow:hidden;color:var(--text);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:21px;font-weight:750;letter-spacing:-.04em;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.brand-logo{display:block;width:auto;height:21px;flex:none}.brand span{color:inherit}.sidebar-actions{display:flex;flex:none;align-items:center;gap:3px}.sidebar-search,.sidebar-graph,.sidebar-git{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;color:var(--muted);cursor:pointer;background:transparent;border:0;border-radius:6px}.sidebar-search:hover,.sidebar-search[aria-current=page],.sidebar-graph:hover,.sidebar-graph[aria-current=page],.sidebar-git:hover{color:var(--accent);background:var(--sidebar-selection)}.sidebar-git[aria-pressed=true]{color:var(--warning);background:var(--warning-soft)}.sidebar-git{position:relative}.sidebar-git[data-has-changes=true]:after{position:absolute;top:3px;right:3px;width:6px;height:6px;content:"";background:var(--git-notification);border-radius:50%;box-shadow:0 0 0 1.5px var(--sidebar)}.sidebar-search svg,.sidebar-graph svg,.sidebar-git svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-linecap:round;stroke-width:1.8}.file-tree{display:grid;min-width:0;gap:2px}.tree-directory>summary{display:flex;padding:7px 10px;align-items:center;gap:7px;color:var(--muted);font-size:12px;font-weight:650;cursor:pointer;list-style:none;border-radius:7px}.tree-directory>summary::-webkit-details-marker{display:none}.tree-directory>summary>a,.tree-directory>summary>span{min-width:0;flex:1;color:inherit;text-decoration:none}.tree-directory>summary>a,.tree-directory>summary>span{display:flex;align-items:center;gap:8px}.tree-directory>summary:before{content:"›";display:inline-block;width:10px;font-size:15px;line-height:1;transform-origin:center;transition:transform .12s ease}.tree-directory[open]>summary:before{transform:rotate(90deg)}.tree-directory>summary:hover{color:var(--text);background:var(--sidebar-selection)}.tree-children{display:grid;margin-left:15px;padding-left:7px;gap:2px;border-left:1px solid var(--panel-border)}.tree-directory[open]>.tree-children{margin-top:2px}.document-link{display:flex;padding:7px 10px;align-items:center;gap:8px;overflow:hidden;color:var(--muted);font-size:13px;line-height:1.35;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;border-radius:7px}.document-link-name{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.document-state-disc{width:7px;height:7px;flex:0 0 auto;border-radius:50%}.document-state-disc.has-errors{background:var(--danger);box-shadow:0 0 0 2px color-mix(in srgb,var(--danger) 12%,transparent)}.document-state-disc.git-modified{background:var(--warning);box-shadow:0 0 0 2px color-mix(in srgb,var(--warning) 12%,transparent)}.document-state-disc.git-new{background:var(--success);box-shadow:0 0 0 2px color-mix(in srgb,var(--success) 12%,transparent)}.document-state-disc.has-errors.git-modified{background:linear-gradient(90deg,var(--danger) 0 50%,var(--warning) 50% 100%)}.document-state-disc.has-errors.git-new{background:linear-gradient(90deg,var(--danger) 0 50%,var(--success) 50% 100%)}.document-link:hover,.document-link.active{color:var(--text);background:var(--sidebar-selection)}.document-link.active{font-weight:650}.main{--document-gutter: clamp(28px, 3vw, 48px);--document-toc-gutter: calc(var(--document-gutter) + 16px);width:100%;max-width:1280px;min-width:0;padding:28px var(--document-gutter) 100px}.main.restoring-history-scroll{visibility:hidden}.document-header{max-width:760px;margin-bottom:34px}.document-layout{display:grid;grid-template-columns:minmax(0,760px) 286px;grid-template-areas:"document toc";gap:var(--document-toc-gutter);align-items:start}.document-column{grid-area:document;min-width:0}.document-toc{grid-area:toc;position:sticky;top:28px;height:calc(100vh - 56px);box-sizing:border-box;padding-right:16px;overflow:hidden}.document-toc-title{display:flex;width:100%;min-height:24px;padding:0;align-items:center;gap:9px;color:var(--muted);font-family:inherit;font-size:13px;font-weight:650;text-align:left;background:transparent;border:0}.document-toc-toggle{display:none}.document-toc-title svg{width:17px;height:17px;flex:0 0 auto;fill:none;stroke:currentColor;stroke-linecap:round;stroke-width:2}.document-toc-list{display:block;max-height:calc(100% - 38px);margin-top:14px;overflow-y:auto;overscroll-behavior:contain;border-left:1px solid var(--panel-border);scrollbar-width:none}.document-toc-list::-webkit-scrollbar{display:none}.document-toc-link{position:relative;display:flex;padding:7px 0 7px calc(14px + var(--toc-depth) * 13px);align-items:center;gap:7px;color:var(--muted);font-size:12.5px;font-weight:520;line-height:17px;text-decoration:none;transition:color .14s ease;overflow-wrap:anywhere}.document-toc-link-label{min-width:0;flex:1}.document-toc-states{display:inline-flex;padding-right:2px;flex:0 0 auto;align-items:center;gap:4px}.document-toc-state{width:6px;height:6px;border-radius:50%;box-shadow:0 0 0 2px color-mix(in srgb,currentColor 12%,transparent)}.document-toc-state.git{color:var(--git-notification);background:currentColor}.document-toc-state.error{color:var(--danger);background:currentColor}.document-toc-link:before{position:absolute;top:4px;bottom:4px;left:-1px;width:2px;content:"";background:transparent;border-radius:2px}.document-toc-link:hover{color:var(--text)}.document-toc-link[data-depth="1"]{font-weight:650}.document-toc-link[aria-current=location]{color:var(--link)}.document-toc-link[aria-current=location]:before{background:var(--link)}.document-metadata{display:flex;min-height:28px;align-items:center;gap:10px;flex-wrap:wrap}.document-path{min-width:0;overflow-wrap:anywhere;color:var(--muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px}.document-flag{padding:3px 8px;color:var(--accent);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:10px;font-weight:700;letter-spacing:.025em;background:var(--accent-soft);border:1px solid color-mix(in srgb,var(--accent) 25%,transparent);border-radius:999px}.document-error-toggle{display:inline-flex;padding:3px 8px;align-items:center;color:var(--danger);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:10px;font-weight:700;letter-spacing:.025em;cursor:pointer;background:var(--danger-soft);border:1px solid var(--danger-border);border-radius:999px}.document-error-toggle:hover,.document-error-toggle[aria-expanded=true]{color:var(--text)}.document-error-panel{margin-top:12px;overflow:hidden;font-family:Geist,Geist Sans,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;background:color-mix(in srgb,var(--danger-soft) 55%,var(--background));border:1px solid var(--danger-border);border-radius:8px}.document-error-header{padding:9px 13px 7px;color:var(--danger);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:10px;font-weight:750;letter-spacing:.08em;text-transform:uppercase}.document-error-item{display:grid;padding:10px 13px 11px;gap:5px;color:inherit;text-decoration:none}.document-error-item+.document-error-item{border-top:1px solid var(--danger-border)}.document-error-item:hover{background:color-mix(in srgb,var(--danger-soft) 75%,transparent)}.document-error-location{color:var(--danger);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:11px;font-weight:700}.document-error-message{color:var(--muted);font-size:12px;line-height:1.45;white-space:pre-wrap}.source-context{position:relative;z-index:1;width:calc(100% - 5.25rem);max-width:760px;margin:12px 16px 12px 4.25rem;overflow:visible;font-family:Geist,Geist Sans,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;background:var(--context-surface);border:1px solid var(--panel-border);border-radius:8px}.source-context.has-references:not(.references-open){margin-bottom:24px}.source-context-header{display:flex;min-height:36px;padding:7px 10px 7px 13px;align-items:center;gap:12px;color:var(--muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.source-reference-toggle{position:relative;z-index:1;display:flex;height:0;align-items:center;gap:10px}.source-reference-toggle:before,.source-reference-toggle:after{height:1px;flex:1;content:"";background:var(--panel-border);visibility:hidden}.source-context.references-open .source-reference-toggle:before,.source-context.references-open .source-reference-toggle:after{visibility:visible}.source-reference-toggle button{display:inline-flex;padding:4px 7px;align-items:center;gap:6px;color:var(--accent);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:10px;font-weight:650;line-height:1.3;letter-spacing:.02em;text-transform:none;cursor:pointer;background:var(--reference-control);border:0;border-radius:5px}.source-reference-toggle button:hover{color:var(--text)}.source-reference-toggle button>span{min-width:16px;padding:1px 4px;color:var(--muted);text-align:center;background:color-mix(in srgb,var(--background) 65%,transparent);border-radius:999px}.source-context-current{padding:0 13px 13px}.source-context-current>a,.source-reference-item>a{color:var(--text);text-decoration:none}.source-breadcrumbs{display:flex;align-items:center;gap:5px;overflow:hidden;color:var(--link);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px;font-weight:650;white-space:nowrap}.source-breadcrumbs>span{display:inline-flex;min-width:0;align-items:center;gap:5px}.source-breadcrumbs>span>span{color:var(--muted)}.source-context-current>a:hover .source-breadcrumbs,.source-reference-item>a:hover .source-breadcrumbs{text-decoration:underline;text-underline-offset:3px}.source-context-paragraph p{margin:8px 0 0;color:var(--text);font-size:13px;line-height:1.5}.source-context-paragraph a,.source-reference-paragraph a{text-underline-offset:2px}.source-reference-list{padding:17px 0 3px}.source-reference-item{padding:10px 13px}.source-reference-item+.source-reference-item{border-top:1px solid var(--panel-border)}.source-reference-paragraph p{margin:5px 0 0;color:var(--muted);font-size:12px;line-height:1.4}.source-code{max-width:100%;padding:10px 0;overflow-x:auto;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:13px;line-height:1.55;background:var(--code);border:1px solid var(--panel-border);border-radius:10px;overflow-anchor:none}.document-metadata+.source-code{margin-top:14px}.source-collapse{display:flex;min-width:max-content;min-height:34px;align-items:center;color:var(--muted);background:color-mix(in srgb,var(--panel) 52%,transparent);border-top:1px solid color-mix(in srgb,var(--panel-border) 72%,transparent);border-bottom:1px solid color-mix(in srgb,var(--panel-border) 72%,transparent)}.source-collapse:first-child{margin-top:-10px;border-top:0;border-radius:10px 10px 0 0}.source-collapse:last-child{margin-bottom:-10px;border-bottom:0;border-radius:0 0 10px 10px}.source-collapse>span{flex:0 0 4.25rem;padding-right:14px;text-align:right;-webkit-user-select:none;user-select:none}.source-collapse button{padding:6px 20px 6px 0;color:var(--muted);font:inherit;font-size:11px;cursor:pointer;background:transparent;border:0}.source-collapse button:hover{color:var(--accent)}.source-line{display:flex;min-width:max-content}.source-line.focused{background:color-mix(in srgb,var(--accent-soft) 72%,transparent)}.source-line-number{flex:0 0 4.25rem;padding-right:14px;color:var(--muted);text-align:right;-webkit-user-select:none;user-select:none}.source-line.focused .source-line-number{color:var(--accent)}.source-line-content{flex:1 0 auto;padding-right:20px;color:var(--text);white-space:pre}.source-code .hljs-comment,.source-code .hljs-quote{color:var(--syntax-comment);font-style:italic}.source-code .hljs-keyword,.source-code .hljs-literal,.source-code .hljs-selector-tag,.source-code .hljs-section{color:var(--syntax-keyword)}.source-code .hljs-string,.source-code .hljs-regexp,.source-code .hljs-addition,.source-code .hljs-attribute{color:var(--syntax-string)}.source-code .hljs-number,.source-code .hljs-symbol,.source-code .hljs-bullet{color:var(--syntax-number)}.source-code .hljs-title,.source-code .hljs-function,.source-code .hljs-class,.source-code .hljs-type{color:var(--syntax-title)}.source-code .hljs-built_in,.source-code .hljs-variable.language_,.source-code .hljs-meta{color:var(--syntax-built-in)}.source-code .hljs-deletion{color:#bd3d3d}.source-code .hljs-emphasis{font-style:italic}.source-code .hljs-strong{font-weight:700}.markdown{max-width:760px;font-size:16px;line-height:1.72}.markdown h1,.markdown h2,.markdown h3,.markdown h4{margin:2em 0 .65em;line-height:1.2;letter-spacing:-.025em;scroll-margin-top:24px}.section-back-reference-toggle{display:inline-flex;padding:3px 5px 3px 7px;margin-left:10px;align-items:center;gap:5px;color:var(--accent);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:10px;font-weight:650;line-height:1.3;letter-spacing:.01em;vertical-align:middle;cursor:pointer;background:var(--reference-control);border:0;border-radius:5px}.section-back-reference-toggle:hover,.section-back-reference-toggle[aria-expanded=true]{color:var(--text)}.section-back-reference-count{min-width:16px;padding:1px 4px;color:var(--muted);text-align:center;background:color-mix(in srgb,var(--background) 65%,transparent);border-radius:999px}.section-back-reference-panel{margin:-.15em 0 1.5em;overflow:hidden;font-family:Geist,Geist Sans,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;background:var(--context-surface);border:1px solid var(--panel-border);border-radius:8px}.section-back-reference-panel[hidden]{display:none}.section-back-reference-header{padding:9px 13px 7px;color:var(--muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.section-back-reference-item{padding:10px 13px 11px}.section-back-reference-item+.section-back-reference-item{border-top:1px solid var(--panel-border)}.section-back-reference-location{display:inline-flex;align-items:center;gap:5px;color:var(--link);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px;font-weight:650;line-height:1.35;text-decoration:none}.section-back-reference-location:hover{text-decoration:underline;text-underline-offset:3px}.section-back-reference-location>span[aria-hidden=true]{color:var(--muted)}.section-back-reference-paragraph p{margin:5px 0 0;color:var(--muted);font-size:12px;line-height:1.45}.section-back-reference-paragraph a{text-underline-offset:2px}.section-back-reference-code .code-link-language{margin-right:0;font-size:7px}.markdown .section-back-reference-code>code{display:block;padding:7px 9px;margin-top:7px;overflow-x:auto;color:var(--muted);font-size:11px;line-height:1.4;white-space:pre;border:1px solid color-mix(in srgb,var(--panel-border) 75%,transparent)}.markdown h1{margin-top:0;font-size:clamp(32px,5vw,46px)}.markdown h2{font-size:26px}.markdown h3{font-size:20px}.markdown p,.markdown ul,.markdown ol,.markdown blockquote,.markdown pre{margin:0 0 1.25em}.markdown li+li{margin-top:.35em}.markdown a{overflow-wrap:anywhere;text-decoration-line:underline;text-decoration-thickness:1px;text-underline-offset:3px}.markdown .markdown-error{color:var(--danger);scroll-margin-top:24px;text-decoration-color:currentColor}.markdown p.markdown-error,.markdown li.markdown-error,.markdown blockquote.markdown-error,.markdown pre.markdown-error,.markdown h1.markdown-error,.markdown h2.markdown-error,.markdown h3.markdown-error,.markdown h4.markdown-error,.markdown h5.markdown-error,.markdown h6.markdown-error{padding-left:10px;background:color-mix(in srgb,var(--danger-soft) 42%,transparent);box-shadow:inset 3px 0 0 var(--danger)}.markdown a.markdown-error,.markdown span.markdown-error{padding:.08em .2em;margin:-.08em -.2em;background:var(--danger-soft);border-radius:3px;box-decoration-break:clone;-webkit-box-decoration-break:clone}.markdown ins.git-added,.markdown del.git-removed{padding:.08em .12em;margin:-.08em -.04em;border-radius:3px;box-decoration-break:clone;-webkit-box-decoration-break:clone}.markdown ins.git-added{color:var(--success);text-decoration:none;background:var(--success-soft)}.markdown del.git-removed{color:var(--danger);background:var(--danger-soft);text-decoration-thickness:1px}.markdown p.git-added,.markdown blockquote.git-added,.markdown pre.git-added,.markdown h1.git-added,.markdown h2.git-added,.markdown h3.git-added,.markdown h4.git-added,.markdown h5.git-added,.markdown h6.git-added,.markdown ul.git-added,.markdown ol.git-added,.markdown li.git-added{padding-left:10px;color:var(--success);background:color-mix(in srgb,var(--success-soft) 55%,transparent);box-shadow:inset 3px 0 0 var(--success)}.markdown pre:has(>code.git-added){color:var(--success);background:color-mix(in srgb,var(--success-soft) 55%,var(--code));box-shadow:inset 3px 0 0 var(--success)}.markdown p.git-removed,.markdown div.git-removed,.markdown blockquote.git-removed,.markdown pre.git-removed,.markdown ul.git-removed,.markdown ol.git-removed,.markdown li.git-removed{padding-left:10px;color:var(--danger);text-decoration:line-through;background:color-mix(in srgb,var(--danger-soft) 55%,transparent);box-shadow:inset 3px 0 0 var(--danger)}.markdown pre:has(>code.git-removed){color:var(--danger);text-decoration:line-through;background:color-mix(in srgb,var(--danger-soft) 55%,var(--code));box-shadow:inset 3px 0 0 var(--danger)}.wiki-link-context{color:var(--muted)}a.wiki-link-segmented{text-decoration:none}a.wiki-link-segmented .wiki-link-context,a.wiki-link-segmented .wiki-link-leaf,a.wiki-link-code:not(.wiki-link-segmented) .code-link-leading{text-decoration-line:underline;text-decoration-color:currentColor;text-decoration-thickness:1px;text-underline-offset:3px}.wiki-link-ref-count{display:inline-flex;min-width:1.45em;height:1.45em;padding:0 .34em;margin-left:.4em;align-items:center;justify-content:center;color:var(--muted);font-size:.66em;font-style:normal;font-weight:750;line-height:1;text-decoration:none;vertical-align:.15em;background:color-mix(in srgb,var(--muted) 14%,transparent);border-radius:999px}.markdown a:hover .wiki-link-ref-count{color:var(--text)}.external-link-icon{display:inline-block;width:.78em;height:.78em;margin-left:.28em;vertical-align:.02em;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M15 3h6v6M10 14 21 3M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M15 3h6v6M10 14 21 3M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat}.code-link-language{display:inline-flex;width:1.55em;height:1.55em;margin-right:.38em;align-items:center;justify-content:center;color:var(--background);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.62em;font-style:normal;font-weight:800;line-height:1;text-decoration:none;vertical-align:.12em;background:var(--text);border-radius:3px}.code-link-leading{display:inline-flex;align-items:baseline;white-space:nowrap}a.wiki-link-active{padding:.12em .28em;margin:-.12em -.28em;background:var(--accent-soft);border-radius:4px;box-decoration-break:clone;-webkit-box-decoration-break:clone}.markdown blockquote{margin-left:0;padding-left:18px;color:var(--muted);border-left:3px solid var(--panel-border)}.markdown code{padding:.16em .36em;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.9em;background:var(--inline-code);border-radius:5px}.markdown pre{padding:18px 20px;overflow-x:auto;background:var(--code);border:1px solid var(--panel-border);border-radius:10px}.markdown pre code{padding:0;background:transparent}.markdown img{max-width:100%}.markdown hr{margin:2.5em 0;border:0;border-top:1px solid var(--panel-border)}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;white-space:nowrap;border:0;clip:rect(0,0,0,0)}.search-page{width:100%;max-width:760px}.search-input-shell{display:flex;height:52px;padding:0 16px;align-items:center;gap:11px;color:var(--muted);background:var(--panel);border:1px solid var(--panel-border);border-radius:6px;box-shadow:0 1px 1px color-mix(in srgb,var(--text) 5%,transparent)}.search-input-shell:focus-within{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 55%,var(--panel-border));box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 12%,transparent)}.search-input-shell svg{width:20px;height:20px;flex:0 0 auto;fill:none;stroke:currentColor;stroke-linecap:round;stroke-width:1.8}.search-input-shell input{width:100%;min-width:0;padding:0;color:var(--text);font:inherit;font-size:17px;line-height:1;background:transparent;border:0;outline:0}.search-input-shell input::placeholder{color:var(--muted)}.search-input-shell input::-webkit-search-cancel-button{cursor:pointer}.search-status{min-height:42px;padding:12px 2px 8px;color:var(--muted);font-size:12px}.search-results{display:grid;gap:10px}.search-result{display:block;padding:16px 18px;color:var(--text);text-decoration:none;background:color-mix(in srgb,var(--panel) 72%,transparent);border:1px solid var(--panel-border);border-radius:6px;transition:border-color .12s ease,background .12s ease,transform .12s ease}.search-result:hover{background:var(--panel);border-color:color-mix(in srgb,var(--accent) 38%,var(--panel-border));transform:translateY(-1px)}.search-result-breadcrumbs{display:flex;align-items:center;gap:5px;overflow:hidden;color:var(--link);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:11px;font-weight:650;white-space:nowrap}.search-result-breadcrumbs>span{display:inline-flex;min-width:0;align-items:center;gap:5px}.search-result-breadcrumbs>span>span{color:var(--muted)}.search-result h2{margin:7px 0 0;font-size:18px;line-height:1.3;letter-spacing:-.015em}.search-result p{margin:6px 0 0;color:var(--muted);font-size:13px;line-height:1.5}.state{display:flex;min-height:50vh;align-items:center;justify-content:center;color:var(--muted)}.state.error{flex-direction:column;gap:8px;text-align:center}.state.error strong{color:var(--text)}.graph-shell{position:relative;height:100vh;overflow:hidden;background:var(--panel)}.graph-topbar{position:absolute;z-index:8;inset:0 auto auto 0;width:50%;height:84px;pointer-events:none}.graph-topbar-graph{display:flex;min-width:0;padding:0 28px;align-items:center;gap:14px;height:100%;pointer-events:auto}.graph-topbar-graph .graph-header{display:flex;min-width:0;flex:0 0 212px;align-items:center;justify-content:space-between}.graph-topbar-graph .graph-tools{min-width:0}.graph-workspace{display:grid;height:100vh;min-height:0;grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.graph-pane,.graph-inspector{position:relative;min-width:0;min-height:0}.graph-pane{overflow:hidden;border-right:1px solid var(--panel-border)}.graph-canvas-shell,.graph-canvas{position:absolute;inset:0}.graph-canvas-shell{background:radial-gradient(circle at center,color-mix(in srgb,var(--accent-soft) 22%,transparent),transparent 58%),var(--panel)}.graph-tools{display:flex;min-width:0;flex:1 1 auto;align-items:center;gap:8px}.graph-filter{display:flex;min-width:100px;height:36px;flex:1 1 220px;align-items:center;background:color-mix(in srgb,var(--background) 72%,transparent);border:1px solid var(--panel-border);border-radius:8px}.graph-filter:focus-within{border-color:color-mix(in srgb,var(--accent) 55%,var(--panel-border));box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 12%,transparent)}.graph-filter input{width:auto;min-width:0;flex:1 1 auto;padding:0 12px;color:var(--text);font:inherit;font-size:13px;background:transparent;border:0;outline:0}.graph-filter input::placeholder{color:var(--muted)}.graph-kind-filters{display:flex;flex:0 0 auto;align-items:center;gap:5px}.graph-kind-filters label{position:relative;display:inline-flex;cursor:pointer}.graph-kind-filters input{position:absolute;opacity:0;pointer-events:none}.graph-kind-filters label span{padding:4px 7px;color:var(--muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:9px;font-weight:700;text-transform:capitalize;background:color-mix(in srgb,var(--background) 82%,transparent);border:1px solid var(--panel-border);border-radius:999px;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.graph-kind-filters input:checked+span{color:var(--accent);background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 30%,var(--panel-border))}.graph-kind-filters input:focus-visible+span{outline:2px solid var(--accent);outline-offset:2px}.graph-node-count{flex:0 0 auto;padding-right:10px;color:var(--muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:9px;font-weight:650;white-space:nowrap}.graph-fit{position:absolute;z-index:4;right:18px;bottom:18px;padding:5px 8px;color:var(--muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:9px;font-weight:700;cursor:pointer;background:color-mix(in srgb,var(--background) 84%,transparent);border:1px solid var(--panel-border);border-radius:6px;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.graph-fit:hover{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 35%,var(--panel-border))}.graph-legend{position:absolute;z-index:4;bottom:20px;left:18px;display:flex;gap:12px;color:var(--muted);font-size:9px;font-weight:650}.graph-legend span{display:inline-flex;align-items:center;gap:5px}.graph-legend span:before{width:6px;height:6px;content:"";background:currentColor;border-radius:50%}.graph-legend .document{color:var(--graph-document)}.graph-legend .code{color:var(--graph-code)}.graph-legend .document input:checked+span{color:var(--graph-document)}.graph-legend .code input:checked+span{color:var(--graph-code)}.graph-legend input:not(:checked)+span{opacity:.42}.graph-no-results{position:absolute;z-index:3;inset:0;display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:12px;pointer-events:none}.graph-inspector{background:var(--panel)}.graph-inspector-scroll{height:100%;overflow-y:auto;overscroll-behavior:contain}.graph-inspector-empty{display:flex;height:100%;padding:40px;align-items:center;justify-content:center;color:var(--muted);font-size:12px;line-height:1.5;text-align:center}.graph-inspector-document,.graph-inspector-source{padding:28px 28px 80px}.graph-inspector-document .markdown{max-width:none}.graph-inspector-document>.document-metadata{margin-bottom:28px}.graph-inspector-source .source-context{width:calc(100% - 5.25rem)}.graph-state{height:calc(100vh - 84px);min-height:0}@media(prefers-reduced-motion:reduce){.document-toc-link,.document-toc-chevron{transition:none}}@media(max-width:1100px)and (min-width:64rem){.graph-topbar-graph{padding:0 18px 0 28px;gap:8px}.graph-node-count{display:none}}@media(max-width:1340px){.document-layout{display:flex;flex-direction:column;gap:0;align-items:stretch}.document-toc{position:static;width:100%;max-width:760px;height:auto;padding:0;margin-bottom:28px;overflow:visible}.document-toc-heading{display:none}.document-toc-toggle{display:flex;min-height:52px;padding:0 16px;cursor:pointer;background:var(--panel);border:1px solid var(--panel-border);border-radius:7px}.document-toc-toggle:hover,.document-toc-toggle[aria-expanded=true]{color:var(--text)}.document-toc-chevron{margin-left:auto;color:var(--muted);font-size:18px;line-height:1;transform:rotate(90deg);transition:transform .12s ease}.document-toc[data-expanded=true] .document-toc-chevron{transform:rotate(-90deg)}.document-toc-list{display:none;max-height:min(52vh,420px);padding:8px 0;margin-top:0;background:var(--panel);border:1px solid var(--panel-border);border-top:0;border-radius:0 0 7px 7px}.document-toc[data-expanded=true] .document-toc-toggle{border-radius:7px 7px 0 0}.document-toc[data-expanded=true] .document-toc-list{display:block}}@media(min-width:64rem)and (max-width:1340px){.sidebar-header{min-height:42px}.document-layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,286px);grid-template-areas:"metadata toc" "document document";column-gap:var(--document-toc-gutter);row-gap:34px;align-items:start}.document-column{display:contents}.document-header{grid-area:metadata;min-width:0;margin:0}.document-metadata,.document-toc-toggle{min-height:42px}.document-toc{grid-area:toc;position:relative;z-index:1;top:0;max-width:286px;margin:0}.document-toc-list{position:absolute;top:100%;right:0;left:0}.document-toc-states{padding-right:14px}.markdown{grid-area:document;min-width:0}}@media not (min-width:64rem){body.mobile-navigation-open{overflow:hidden}.app-shell{display:block}.sidebar{position:sticky;z-index:20;top:0;width:100%;height:104px;padding:0;overflow:visible;border-right:0;border-bottom:1px solid var(--panel-border)}.sidebar-header{height:48px;padding:0 16px;margin:0}.sidebar-header .brand{font-size:18px}.sidebar-header .brand-logo{height:18px}.sidebar-actions{gap:5px}.sidebar-search,.sidebar-graph,.sidebar-git{width:36px;height:36px}.mobile-navigation-trigger{display:flex;width:100%;height:56px;padding:0 18px;align-items:center;gap:13px;overflow:hidden;color:var(--muted);font:inherit;font-size:13px;text-align:left;cursor:pointer;background:transparent;border:0;border-top:1px solid var(--panel-border)}.mobile-navigation-trigger:hover,.mobile-navigation-trigger[aria-expanded=true]{color:var(--text)}.mobile-navigation-trigger svg{width:18px;height:18px;flex:0 0 auto;fill:none;stroke:currentColor;stroke-linecap:round;stroke-width:1.8}.mobile-navigation-context{display:flex;min-width:0;align-items:center;gap:9px}.mobile-navigation-context>span:first-child{color:var(--text);font-weight:600}.mobile-navigation-context>span[aria-hidden=true]{color:var(--muted)}.mobile-navigation-current{min-width:0;overflow:hidden;color:var(--muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}.sidebar nav{display:none}.sidebar[data-mobile-navigation-open=true] nav{position:fixed;z-index:19;inset:104px 0 0;display:block;padding:16px 16px max(28px,env(safe-area-inset-bottom));overflow-y:auto;overscroll-behavior:contain;background:var(--sidebar);outline:0}.sidebar[data-mobile-navigation-open=true] .file-tree{max-width:560px;margin:0 auto}.sidebar[data-mobile-navigation-open=true] .tree-directory>summary,.sidebar[data-mobile-navigation-open=true] .document-link{min-height:44px;padding-top:10px;padding-bottom:10px}.main{--mobile-gutter: clamp(20px, 5vw, 48px);padding:28px clamp(20px,5vw,48px) 80px}.document-toc{position:sticky;z-index:10;top:104px;width:calc(100% + var(--mobile-gutter) * 2);max-width:none;margin:-28px calc(var(--mobile-gutter) * -1) 28px;background:var(--background)}.document-toc-toggle{min-height:56px;padding:0 var(--mobile-gutter);background:color-mix(in srgb,var(--background) 94%,transparent);border-top:0;border-right:0;border-left:0;border-radius:0;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}.document-toc[data-expanded=true] .document-toc-toggle{border-radius:0}.document-toc-list{max-height:calc(100vh - 160px);max-height:calc(100dvh - 160px);padding-right:var(--mobile-gutter);padding-left:var(--mobile-gutter);background:var(--background);border-right:0;border-left:0;border-radius:0}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown .markdown-error{scroll-margin-top:180px}.source-context{width:calc(100% - 24px);margin-right:12px;margin-left:12px}.graph-shell{height:auto;min-height:100vh;min-height:100dvh;overflow:visible}.graph-topbar{position:sticky;top:0;width:100%;height:auto;background:color-mix(in srgb,var(--panel) 92%,transparent);border-bottom:1px solid var(--panel-border);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);pointer-events:auto}.graph-topbar-graph{min-height:64px;padding:10px 16px;border-right:0}.graph-topbar-graph .graph-header{flex-basis:190px}.graph-header .brand{font-size:18px}.graph-header .brand-logo{height:18px}.graph-header .sidebar-search,.graph-header .sidebar-graph,.graph-header .sidebar-git{width:36px;height:36px}.graph-workspace{display:block;height:auto}.graph-pane{height:min(58vh,520px);height:min(58svh,520px);min-height:320px;border-right:0;border-bottom:1px solid var(--panel-border)}.graph-canvas{touch-action:none}.graph-filter input{font-size:16px}.graph-kind-filters label span{min-height:32px;padding:7px 10px}.graph-fit{min-width:44px;min-height:32px}.graph-inspector{min-height:55vh;min-height:55svh}.graph-inspector-scroll{height:auto;overflow:visible}.graph-inspector-empty{min-height:45vh}.graph-inspector-document,.graph-inspector-source{padding-right:20px;padding-left:20px}.graph-inspector-source .source-context{width:calc(100% - 24px)}.graph-state{height:auto;min-height:50vh}}@media(max-width:600px){.main{--mobile-gutter: 18px;padding-right:18px;padding-left:18px}.markdown{font-size:15.5px}.markdown h1{font-size:32px}.markdown h2{font-size:24px}.graph-topbar-graph{flex-wrap:wrap}.graph-topbar-graph .graph-header,.graph-topbar-graph .graph-tools,.graph-filter{flex-basis:100%}.graph-pane{height:52vh;height:52svh;min-height:300px}}
|