@plebeiantech/lat.md 0.12.3-fork.17 → 0.12.3-fork.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/README.md +1 -1
  2. package/dist/src/cli/agent-invocation.d.ts +6 -0
  3. package/dist/src/cli/agent-invocation.js +23 -0
  4. package/dist/src/cli/fork-instructions.js +1 -1
  5. package/dist/src/cli/fork-scaffold.js +2 -2
  6. package/dist/src/cli/graph.d.ts +1 -1
  7. package/dist/src/cli/hook.js +11 -11
  8. package/dist/src/cli/index.js +41 -59
  9. package/dist/src/cli/init-preferences.js +5 -4
  10. package/dist/src/cli/init.d.ts +1 -1
  11. package/dist/src/cli/init.js +54 -45
  12. package/dist/src/cli/reindex.d.ts +1 -1
  13. package/dist/src/cli/reindex.js +2 -2
  14. package/dist/src/cli/search.d.ts +4 -4
  15. package/dist/src/cli/search.js +41 -28
  16. package/dist/src/cli/ui-build-server.d.ts +1 -1
  17. package/dist/src/cli/ui-build.d.ts +1 -1
  18. package/dist/src/cli/ui.d.ts +1 -1
  19. package/dist/src/fork/antigravity-hook.js +6 -6
  20. package/dist/src/fork/antigravity-init.d.ts +2 -2
  21. package/dist/src/fork/antigravity-init.js +2 -2
  22. package/dist/src/graph-export.js +7 -7
  23. package/dist/src/knowledge/index.js +2 -2
  24. package/dist/src/mcp/server.js +8 -8
  25. package/dist/src/search/cache.d.ts +1 -1
  26. package/dist/src/search/cache.js +40 -7
  27. package/dist/src/search/chunks.d.ts +2 -2
  28. package/dist/src/search/db.d.ts +5 -4
  29. package/dist/src/search/db.js +36 -40
  30. package/dist/src/search/embedder.js +1 -1
  31. package/dist/src/search/index.d.ts +1 -1
  32. package/dist/src/search/index.js +2 -2
  33. package/dist/src/search/lock.d.ts +4 -1
  34. package/dist/src/search/lock.js +30 -8
  35. package/dist/src/search/query.d.ts +5 -2
  36. package/dist/src/search/query.js +55 -38
  37. package/dist/src/search/search.d.ts +3 -1
  38. package/dist/src/search/search.js +21 -12
  39. package/dist/src/search/types.d.ts +2 -18
  40. package/dist/src/view/client/assets/{GraphView-BWlRdQM4.js → GraphView-Dij8mAA_.js} +1 -1
  41. package/dist/src/view/client/assets/{MarkdownEditor-MW-Ck1O0.js → MarkdownEditor-88Wbt0M1.js} +1 -1
  42. package/dist/src/view/client/assets/{abnfDiagram-VCTEODGH-Bn3RshMV.js → abnfDiagram-VCTEODGH-y0DlYa8E.js} +1 -1
  43. package/dist/src/view/client/assets/{arc-En9tdFQF.js → arc-FlMu8dnO.js} +1 -1
  44. package/dist/src/view/client/assets/{architectureDiagram-5GKGNRK7-B-9J1VAM.js → architectureDiagram-5GKGNRK7-DA_uWZW1.js} +1 -1
  45. package/dist/src/view/client/assets/{blockDiagram-I7D4REHJ-QlznwalP.js → blockDiagram-I7D4REHJ-BHQ5LU85.js} +1 -1
  46. package/dist/src/view/client/assets/{c4Diagram-7LVT6UL2-Bp2y8B4_.js → c4Diagram-7LVT6UL2-BRucKCt2.js} +1 -1
  47. package/dist/src/view/client/assets/channel-BgDNA_Ay.js +1 -0
  48. package/dist/src/view/client/assets/{chunk-2Q5K7J3B-CnBKL-lm.js → chunk-2Q5K7J3B-BJPcFivt.js} +1 -1
  49. package/dist/src/view/client/assets/{chunk-5VM5RSS4-LLYMi_n6.js → chunk-5VM5RSS4-v2q99bGz.js} +1 -1
  50. package/dist/src/view/client/assets/{chunk-F27PBJKO-VIeO7VF0.js → chunk-F27PBJKO-CcHOuJCs.js} +1 -1
  51. package/dist/src/view/client/assets/{chunk-IMKFNOWR-D5i67DVD.js → chunk-IMKFNOWR-DNxYuJNq.js} +1 -1
  52. package/dist/src/view/client/assets/{chunk-JWPE2WC7-D4qAtoL3.js → chunk-JWPE2WC7-C0eHKvLW.js} +1 -1
  53. package/dist/src/view/client/assets/{chunk-POPQ4Y6H-BMzOyiW_.js → chunk-POPQ4Y6H-57CWp2Ve.js} +1 -1
  54. package/dist/src/view/client/assets/{chunk-SVP7TREG-DWy5nbfp.js → chunk-SVP7TREG-BqcoxIJw.js} +1 -1
  55. package/dist/src/view/client/assets/{chunk-TICWLB2K-CVqCANFB.js → chunk-TICWLB2K-DRUJR5zH.js} +1 -1
  56. package/dist/src/view/client/assets/{chunk-XXDRQBXY-Bp23h6Tf.js → chunk-XXDRQBXY-Dez0oRoM.js} +1 -1
  57. package/dist/src/view/client/assets/classDiagram-ZZMXUADV-CFZ_Sgh5.js +1 -0
  58. package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-CFZ_Sgh5.js +1 -0
  59. package/dist/src/view/client/assets/{cose-bilkent-JH36ORCC-BCw7fCC2.js → cose-bilkent-JH36ORCC-BHtud6Hg.js} +1 -1
  60. package/dist/src/view/client/assets/{cynefin-OW5HDTMX--lYN4N9m.js → cynefin-OW5HDTMX-BjBW8VGk.js} +1 -1
  61. package/dist/src/view/client/assets/{cynefinDiagram-5FMLGOSQ-9sK5EV7v.js → cynefinDiagram-5FMLGOSQ-DwGuD7oF.js} +1 -1
  62. package/dist/src/view/client/assets/{dagre-GXQ25YYZ-CoMdEFCq.js → dagre-GXQ25YYZ-C5zSlGK9.js} +1 -1
  63. package/dist/src/view/client/assets/{diagram-S7CK7UJ4-D13dyWdd.js → diagram-S7CK7UJ4-C_NhA3bj.js} +1 -1
  64. package/dist/src/view/client/assets/{diagram-UQ7AKVKN-PdwLPPPA.js → diagram-UQ7AKVKN-az7QPYNb.js} +1 -1
  65. package/dist/src/view/client/assets/{diagram-VSXAHHWV-CtWWa_A7.js → diagram-VSXAHHWV-BRvDuM8_.js} +1 -1
  66. package/dist/src/view/client/assets/{diagram-VX7I27RA-BeCYcSU-.js → diagram-VX7I27RA-BWLgF6S-.js} +1 -1
  67. package/dist/src/view/client/assets/{diagram-Z3DM3KII-DiWabOBM.js → diagram-Z3DM3KII-DV3d6mL5.js} +1 -1
  68. package/dist/src/view/client/assets/{ebnfDiagram-PWID7BFC-CZQ3MD_K.js → ebnfDiagram-PWID7BFC-yUXrEAvK.js} +1 -1
  69. package/dist/src/view/client/assets/{erDiagram-RLTQ6QDP-B1AhXIrP.js → erDiagram-RLTQ6QDP-D35FN1Pt.js} +1 -1
  70. package/dist/src/view/client/assets/{flowDiagram-HODETNUW-Bhr0JM6P.js → flowDiagram-HODETNUW-BciZqsjT.js} +1 -1
  71. package/dist/src/view/client/assets/{ganttDiagram-EL5Y4UJY-CbP8iAkg.js → ganttDiagram-EL5Y4UJY-BysPGgXS.js} +1 -1
  72. package/dist/src/view/client/assets/{gitGraphDiagram-WWUBYQGX-B9uuGdLF.js → gitGraphDiagram-WWUBYQGX-C3DdJ5xG.js} +1 -1
  73. package/dist/src/view/client/assets/index-CJokoRSp.js +13 -0
  74. package/dist/src/view/client/assets/{infoDiagram-27XIBGKW-BrfwQ_Cq.js → infoDiagram-27XIBGKW-D3HZrDRb.js} +1 -1
  75. package/dist/src/view/client/assets/{ishikawaDiagram-5VMMS53U-CHtJ36re.js → ishikawaDiagram-5VMMS53U-BXyVIXTU.js} +1 -1
  76. package/dist/src/view/client/assets/{journeyDiagram-3NMN7TZE-BChcgX1s.js → journeyDiagram-3NMN7TZE-D4-1NxVU.js} +1 -1
  77. package/dist/src/view/client/assets/{kanban-definition-UXKFOSKX-BnwFsKiB.js → kanban-definition-UXKFOSKX-4Gu_5yBA.js} +1 -1
  78. package/dist/src/view/client/assets/{layout-Dnd0pLdb.js → layout-Jf1K3TMM.js} +1 -1
  79. package/dist/src/view/client/assets/{linear-CFhW2ozn.js → linear-DWfwzUT_.js} +1 -1
  80. package/dist/src/view/client/assets/{mermaid.core--OP6lXtW.js → mermaid.core-DMx_DAl8.js} +5 -5
  81. package/dist/src/view/client/assets/{mindmap-definition-YA3MSWOX-D51y2zbm.js → mindmap-definition-YA3MSWOX-8pxY_RWi.js} +1 -1
  82. package/dist/src/view/client/assets/{pegDiagram-XKGWAZYB--zyQJDvI.js → pegDiagram-XKGWAZYB-DNAw_O5t.js} +1 -1
  83. package/dist/src/view/client/assets/{pieDiagram-E7YTZNPT-Cj8mvpJy.js → pieDiagram-E7YTZNPT-uuvRCDkC.js} +1 -1
  84. package/dist/src/view/client/assets/{quadrantDiagram-AXDQQJYC-qvhJrnBf.js → quadrantDiagram-AXDQQJYC-BER2O4Aq.js} +1 -1
  85. package/dist/src/view/client/assets/{railroadDiagram-O6MQD6OU-CtWvxpSo.js → railroadDiagram-O6MQD6OU-CxEsJ_0n.js} +1 -1
  86. package/dist/src/view/client/assets/{requirementDiagram-BXWQKSXE-CBxen_KG.js → requirementDiagram-BXWQKSXE-yS9rspca.js} +1 -1
  87. package/dist/src/view/client/assets/{sankeyDiagram-P5KCCOFB-B_fUkmfc.js → sankeyDiagram-P5KCCOFB-Bqt70a2j.js} +1 -1
  88. package/dist/src/view/client/assets/{sequenceDiagram-WJ2MYXX4-Dclv4p68.js → sequenceDiagram-WJ2MYXX4-BvOOEJNr.js} +1 -1
  89. package/dist/src/view/client/assets/{sizeCapture-INFHLROL-GfG0sMTZ.js → sizeCapture-INFHLROL-CvO_Pjjo.js} +1 -1
  90. package/dist/src/view/client/assets/{stateDiagram-D77RDMKH-YQWPnzxU.js → stateDiagram-D77RDMKH-KLmVOZkq.js} +1 -1
  91. package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-KCS8Mdzu.js +1 -0
  92. package/dist/src/view/client/assets/{swimlanes-42K2YHIH-5yiCveVS.js → swimlanes-42K2YHIH-DC1r4_sq.js} +1 -1
  93. package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-B2TcAwis.js +8 -0
  94. package/dist/src/view/client/assets/{timeline-definition-24CTP7MA-BvAbB5Zs.js → timeline-definition-24CTP7MA-ChXLOuBL.js} +1 -1
  95. package/dist/src/view/client/assets/{vennDiagram-4TSXK5OY-guC-r60n.js → vennDiagram-4TSXK5OY-D9_h25-Y.js} +1 -1
  96. package/dist/src/view/client/assets/{wardleyDiagram-VM6X3IG4-C0yXcU2x.js → wardleyDiagram-VM6X3IG4-CsQJGGW0.js} +1 -1
  97. package/dist/src/view/client/assets/{xychartDiagram-S5SC5T6Z-RPmkPNfK.js → xychartDiagram-S5SC5T6Z-DGMuPMlm.js} +1 -1
  98. package/dist/src/view/client/index.html +1 -1
  99. package/dist/src/view/diagnostics.d.ts +2 -2
  100. package/dist/src/view/diagnostics.js +5 -5
  101. package/dist/src/view/external-document-tree.js +1 -1
  102. package/dist/src/view/git-diff.js +1 -1
  103. package/dist/src/view/git.js +1 -1
  104. package/dist/src/view/graph.d.ts +2 -2
  105. package/dist/src/view/graph.js +2 -2
  106. package/dist/src/view/markdown.js +1 -1
  107. package/dist/src/view/preindexed-search.d.ts +1 -1
  108. package/dist/src/view/protocol.d.ts +2 -18
  109. package/dist/src/view/publication.d.ts +2 -0
  110. package/dist/src/view/publication.js +78 -0
  111. package/dist/src/view/references.d.ts +3 -3
  112. package/dist/src/view/references.js +3 -3
  113. package/dist/src/view/repository.d.ts +6 -6
  114. package/dist/src/view/repository.js +28 -14
  115. package/dist/src/view/request-security.d.ts +5 -0
  116. package/dist/src/view/request-security.js +46 -0
  117. package/dist/src/view/search-result.d.ts +1 -1
  118. package/dist/src/view/search-result.js +1 -1
  119. package/dist/src/view/search.d.ts +1 -1
  120. package/dist/src/view/server-build.d.ts +2 -2
  121. package/dist/src/view/server-build.js +2 -2
  122. package/dist/src/view/server-deployment.d.ts +1 -2
  123. package/dist/src/view/server-deployment.js +6 -46
  124. package/dist/src/view/server-index-worker.d.ts +1 -1
  125. package/dist/src/view/server.d.ts +1 -1
  126. package/dist/src/view/server.js +13 -3
  127. package/dist/src/view/source-target.js +2 -2
  128. package/dist/src/view/static-build.d.ts +1 -1
  129. package/dist/src/view/static-build.js +49 -17
  130. package/dist/src/view/store.d.ts +4 -2
  131. package/dist/src/view/store.js +31 -19
  132. package/dist/src/view/table-of-contents.d.ts +1 -1
  133. package/dist/src/view/table-of-contents.js +1 -1
  134. package/dist/src/view/vercel-server-build.d.ts +1 -1
  135. package/package.json +19 -29
  136. package/templates/AGENTS.md +2 -2
  137. package/templates/cursor-rules.md +2 -2
  138. package/templates/opencode-plugin.ts +9 -9
  139. package/templates/pi-extension.ts +11 -11
  140. package/templates/skill/SKILL.md +2 -1
  141. package/dist/src/cli/check-context.d.ts +0 -56
  142. package/dist/src/cli/check-context.js +0 -215
  143. package/dist/src/cli/check-coverage.d.ts +0 -2
  144. package/dist/src/cli/check-coverage.js +0 -75
  145. package/dist/src/cli/check-frontmatter.d.ts +0 -12
  146. package/dist/src/cli/check-frontmatter.js +0 -44
  147. package/dist/src/cli/check-mode.d.ts +0 -21
  148. package/dist/src/cli/check-mode.js +0 -394
  149. package/dist/src/cli/check-status.d.ts +0 -74
  150. package/dist/src/cli/check-status.js +0 -217
  151. package/dist/src/cli/check.d.ts +0 -52
  152. package/dist/src/cli/check.js +0 -834
  153. package/dist/src/cli/context.d.ts +0 -11
  154. package/dist/src/cli/context.js +0 -58
  155. package/dist/src/cli/expand.d.ts +0 -7
  156. package/dist/src/cli/expand.js +0 -141
  157. package/dist/src/cli/external.d.ts +0 -11
  158. package/dist/src/cli/external.js +0 -185
  159. package/dist/src/cli/gen-index.d.ts +0 -45
  160. package/dist/src/cli/gen-index.js +0 -235
  161. package/dist/src/cli/link-scheme.d.ts +0 -54
  162. package/dist/src/cli/link-scheme.js +0 -101
  163. package/dist/src/cli/locate.d.ts +0 -2
  164. package/dist/src/cli/locate.js +0 -18
  165. package/dist/src/cli/refs.d.ts +0 -23
  166. package/dist/src/cli/refs.js +0 -274
  167. package/dist/src/cli/section.d.ts +0 -45
  168. package/dist/src/cli/section.js +0 -328
  169. package/dist/src/cli/select-menu.d.ts +0 -13
  170. package/dist/src/cli/select-menu.js +0 -100
  171. package/dist/src/code-refs.d.ts +0 -29
  172. package/dist/src/code-refs.js +0 -479
  173. package/dist/src/config.d.ts +0 -29
  174. package/dist/src/config.js +0 -83
  175. package/dist/src/context.d.ts +0 -26
  176. package/dist/src/context.js +0 -11
  177. package/dist/src/document-formats.d.ts +0 -7
  178. package/dist/src/document-formats.js +0 -39
  179. package/dist/src/extensions/alert-marker.d.ts +0 -25
  180. package/dist/src/extensions/alert-marker.js +0 -55
  181. package/dist/src/extensions/wiki-link/from-markdown.d.ts +0 -5
  182. package/dist/src/extensions/wiki-link/from-markdown.js +0 -34
  183. package/dist/src/extensions/wiki-link/index.d.ts +0 -4
  184. package/dist/src/extensions/wiki-link/index.js +0 -3
  185. package/dist/src/extensions/wiki-link/syntax.d.ts +0 -14
  186. package/dist/src/extensions/wiki-link/syntax.js +0 -121
  187. package/dist/src/extensions/wiki-link/to-markdown.d.ts +0 -5
  188. package/dist/src/extensions/wiki-link/to-markdown.js +0 -28
  189. package/dist/src/extensions/wiki-link/types.d.ts +0 -34
  190. package/dist/src/extensions/wiki-link/types.js +0 -1
  191. package/dist/src/external-documents.d.ts +0 -56
  192. package/dist/src/external-documents.js +0 -404
  193. package/dist/src/external-sources.d.ts +0 -136
  194. package/dist/src/external-sources.js +0 -1098
  195. package/dist/src/fork/frontmatter-fields.d.ts +0 -36
  196. package/dist/src/fork/frontmatter-fields.js +0 -23
  197. package/dist/src/format.d.ts +0 -16
  198. package/dist/src/format.js +0 -76
  199. package/dist/src/init-version.d.ts +0 -10
  200. package/dist/src/init-version.js +0 -49
  201. package/dist/src/lattice-model.d.ts +0 -84
  202. package/dist/src/lattice-model.js +0 -467
  203. package/dist/src/lattice.d.ts +0 -14
  204. package/dist/src/lattice.js +0 -353
  205. package/dist/src/markdown-analysis-cache.d.ts +0 -20
  206. package/dist/src/markdown-analysis-cache.js +0 -139
  207. package/dist/src/markdown-analysis-worker.d.ts +0 -16
  208. package/dist/src/markdown-analysis-worker.js +0 -33
  209. package/dist/src/markdown-analysis.d.ts +0 -61
  210. package/dist/src/markdown-analysis.js +0 -169
  211. package/dist/src/markdown-analyzer-loader.d.ts +0 -4
  212. package/dist/src/markdown-analyzer-loader.js +0 -13
  213. package/dist/src/markdown-validation.d.ts +0 -25
  214. package/dist/src/markdown-validation.js +0 -104
  215. package/dist/src/parser-cache.d.ts +0 -17
  216. package/dist/src/parser-cache.js +0 -65
  217. package/dist/src/parser-import.d.ts +0 -8
  218. package/dist/src/parser-import.js +0 -1
  219. package/dist/src/parser.d.ts +0 -3
  220. package/dist/src/parser.js +0 -93
  221. package/dist/src/path.d.ts +0 -2
  222. package/dist/src/path.js +0 -4
  223. package/dist/src/profiler.d.ts +0 -16
  224. package/dist/src/profiler.js +0 -81
  225. package/dist/src/project-analysis.d.ts +0 -59
  226. package/dist/src/project-analysis.js +0 -233
  227. package/dist/src/project-discovery.d.ts +0 -6
  228. package/dist/src/project-discovery.js +0 -30
  229. package/dist/src/repository-path.d.ts +0 -11
  230. package/dist/src/repository-path.js +0 -52
  231. package/dist/src/source-formats.d.ts +0 -7
  232. package/dist/src/source-formats.js +0 -30
  233. package/dist/src/source-parser.d.ts +0 -67
  234. package/dist/src/source-parser.js +0 -1749
  235. package/dist/src/untrusted.d.ts +0 -18
  236. package/dist/src/untrusted.js +0 -93
  237. package/dist/src/view/client/assets/channel-uy0fFvcW.js +0 -1
  238. package/dist/src/view/client/assets/classDiagram-ZZMXUADV-DbSEqjA5.js +0 -1
  239. package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-DbSEqjA5.js +0 -1
  240. package/dist/src/view/client/assets/index-nBmbYfun.js +0 -13
  241. package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-gUj6Hzgl.js +0 -1
  242. package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-DR7JhrxL.js +0 -8
  243. package/dist/src/walk.d.ts +0 -20
  244. package/dist/src/walk.js +0 -121
@@ -1,19 +1,21 @@
1
- import { existsSync, cpSync, mkdirSync, writeFileSync, readFileSync, } from 'node:fs';
2
- import { join, resolve } from 'node:path';
1
+ import { agentInvocation } from './agent-invocation.js';
2
+ import { projectWritePath, writeProjectFile, } from '@plebeiantech/lat.md-core/project-write';
3
+ import { existsSync, cpSync, mkdirSync, readFileSync } from 'node:fs';
4
+ import { dirname, join, resolve } from 'node:path';
3
5
  import { execSync } from 'node:child_process';
4
6
  import { createInterface } from 'node:readline/promises';
5
7
  import { styleText } from 'node:util';
6
8
  import { createEmbedder } from '@lat.md/embed';
7
9
  import { findTemplatesDir } from './templates.js';
8
10
  import { readAgentsTemplate, readCursorRulesTemplate, readPiExtensionTemplate, readOpenCodePluginTemplate, readSkillTemplate, } from './gen.js';
9
- import { getLlmKey, getRepoEmbedding, setRepoEmbedding } from '../config.js';
10
- import { makeStyler } from './context.js';
11
+ import { getLlmKey, getRepoEmbedding, setRepoEmbedding, } from '@plebeiantech/lat.md-core/config';
12
+ import { makeStyler } from '@plebeiantech/lat.md-core/cli/context';
11
13
  import { closeDb, getStoredModel, openDb } from '../search/db.js';
12
14
  import { modelKey } from '../search/embedder.js';
13
15
  import { reindexCommand } from './reindex.js';
14
- import { INIT_VERSION, writeInitMeta, readInitVersion, readFileHash, contentHash, } from '../init-version.js';
16
+ import { INIT_VERSION, writeInitMeta, readInitVersion, readFileHash, contentHash, } from '@plebeiantech/lat.md-core/init-version';
15
17
  import { getLocalVersion, fetchLatestVersion } from '../version.js';
16
- import { selectMenu } from './select-menu.js';
18
+ import { selectMenu, } from '@plebeiantech/lat.md-core/cli/select-menu';
17
19
  import { checklistMenu } from './checklist-menu.js';
18
20
  import { writeForkInstructions } from './fork-instructions.js';
19
21
  import { offerRequireMode, writeForkScaffold } from './fork-scaffold.js';
@@ -124,7 +126,8 @@ function isLatHookEntry(entry) {
124
126
  * Remove all lat-owned hook entries from settings, then add fresh ones.
125
127
  * Preserves any non-lat hooks the user may have configured.
126
128
  */
127
- export function syncLatHooks(settingsPath, style, agent = 'claude') {
129
+ export function syncLatHooks(settingsPath, style, agent = 'claude', root = dirname(dirname(settingsPath))) {
130
+ projectWritePath(root, settingsPath);
128
131
  let settings = {};
129
132
  if (existsSync(settingsPath)) {
130
133
  const raw = readFileSync(settingsPath, 'utf-8');
@@ -176,7 +179,7 @@ export function syncLatHooks(settingsPath, style, agent = 'claude') {
176
179
  },
177
180
  ],
178
181
  });
179
- writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
182
+ writeProjectFile(root, settingsPath, JSON.stringify(settings, null, 2) + '\n');
180
183
  }
181
184
  function cursorHooksTemplate(style) {
182
185
  return (JSON.stringify({
@@ -197,7 +200,7 @@ function cursorHooksTemplate(style) {
197
200
  }
198
201
  // ── Gitignore helper ─────────────────────────────────────────────────
199
202
  function ensureGitignored(root, entry) {
200
- const gitignorePath = join(root, '.gitignore');
203
+ const gitignorePath = projectWritePath(root, join(root, '.gitignore'));
201
204
  const gitDir = join(root, '.git');
202
205
  // Check if already ignored
203
206
  if (existsSync(gitignorePath)) {
@@ -233,12 +236,12 @@ function ensureGitignored(root, entry) {
233
236
  let content = readFileSync(gitignorePath, 'utf-8');
234
237
  if (!content.endsWith('\n'))
235
238
  content += '\n';
236
- writeFileSync(gitignorePath, content + entry + '\n');
239
+ writeProjectFile(root, gitignorePath, content + entry + '\n');
237
240
  console.log(styleText('green', ` Added ${entry}`) + ' to .gitignore');
238
241
  }
239
242
  else if (existsSync(gitDir)) {
240
243
  // Create .gitignore with the entry
241
- writeFileSync(gitignorePath, entry + '\n');
244
+ writeProjectFile(root, gitignorePath, entry + '\n');
242
245
  console.log(styleText('green', ` Created .gitignore`) + ` with ${entry}`);
243
246
  }
244
247
  else {
@@ -261,7 +264,8 @@ function mcpCommand() {
261
264
  args: [...args, 'mcp'],
262
265
  };
263
266
  }
264
- function hasMcpServer(configPath, key) {
267
+ function hasMcpServer(root, configPath, key) {
268
+ projectWritePath(root, configPath);
265
269
  if (!existsSync(configPath))
266
270
  return false;
267
271
  try {
@@ -273,7 +277,8 @@ function hasMcpServer(configPath, key) {
273
277
  return false;
274
278
  }
275
279
  }
276
- function addMcpServer(configPath, key, style) {
280
+ function addMcpServer(root, configPath, key, style) {
281
+ projectWritePath(root, configPath);
277
282
  let cfg = { [key]: {} };
278
283
  if (existsSync(configPath)) {
279
284
  const raw = readFileSync(configPath, 'utf-8');
@@ -288,14 +293,15 @@ function addMcpServer(configPath, key, style) {
288
293
  }
289
294
  cfg[key].lat = styledMcpCommand(style);
290
295
  mkdirSync(join(configPath, '..'), { recursive: true });
291
- writeFileSync(configPath, JSON.stringify(cfg, null, 2) + '\n');
296
+ writeProjectFile(root, configPath, JSON.stringify(cfg, null, 2) + '\n');
292
297
  }
293
298
  // ── Codex TOML MCP helpers ────────────────────────────────────────────
294
299
  /**
295
300
  * Check whether `.codex/config.toml` already contains an `[mcp_servers.lat]`
296
301
  * table. We use a simple regex match — no TOML parser needed.
297
302
  */
298
- function hasCodexMcpServer(configPath) {
303
+ function hasCodexMcpServer(root, configPath) {
304
+ projectWritePath(root, configPath);
299
305
  if (!existsSync(configPath))
300
306
  return false;
301
307
  try {
@@ -320,7 +326,8 @@ function hasCodexMcpServer(configPath) {
320
326
  * args = ["mcp"]
321
327
  * ```
322
328
  */
323
- function addCodexMcpServer(configPath, style) {
329
+ function addCodexMcpServer(root, configPath, style) {
330
+ projectWritePath(root, configPath);
324
331
  const cmd = styledMcpCommand(style);
325
332
  // Format args as a TOML inline array of quoted strings
326
333
  const argsToml = '[' + cmd.args.map((a) => `"${a}"`).join(', ') + ']';
@@ -331,10 +338,10 @@ function addCodexMcpServer(configPath, style) {
331
338
  if (!content.endsWith('\n'))
332
339
  content += '\n';
333
340
  content += '\n' + block;
334
- writeFileSync(configPath, content);
341
+ writeProjectFile(root, configPath, content);
335
342
  }
336
343
  else {
337
- writeFileSync(configPath, block);
344
+ writeProjectFile(root, configPath, block);
338
345
  }
339
346
  }
340
347
  // ── Template file helpers ─────────────────────────────────────────────
@@ -345,11 +352,11 @@ function addCodexMcpServer(configPath, style) {
345
352
  * Returns the hash of the written content, or null if the file was skipped.
346
353
  */
347
354
  async function writeTemplateFile(root, latDir, relPath, template, genTarget, label, indent, ask) {
348
- const absPath = join(root, relPath);
355
+ const absPath = projectWritePath(root, join(root, relPath));
349
356
  const templateHash = contentHash(template);
350
357
  if (!existsSync(absPath)) {
351
358
  mkdirSync(join(absPath, '..'), { recursive: true });
352
- writeFileSync(absPath, template);
359
+ writeProjectFile(root, absPath, template);
353
360
  console.log(styleText('green', `${indent}Created ${label}`));
354
361
  return templateHash;
355
362
  }
@@ -364,7 +371,7 @@ async function writeTemplateFile(root, latDir, relPath, template, genTarget, lab
364
371
  }
365
372
  if (storedHash && currentHash === storedHash) {
366
373
  // Unmodified by user — safe to overwrite with new template
367
- writeFileSync(absPath, template);
374
+ writeProjectFile(root, absPath, template);
368
375
  console.log(styleText('green', `${indent}Updated ${label}`));
369
376
  return templateHash;
370
377
  }
@@ -372,7 +379,7 @@ async function writeTemplateFile(root, latDir, relPath, template, genTarget, lab
372
379
  console.log(styleText('yellow', `${indent}${label}`) +
373
380
  ' exists and may contain your own content.');
374
381
  if (await ask(`${indent}Overwrite with latest lat template?`)) {
375
- writeFileSync(absPath, template);
382
+ writeProjectFile(root, absPath, template);
376
383
  console.log(styleText('green', `${indent}Updated ${label}`));
377
384
  return templateHash;
378
385
  }
@@ -414,12 +421,12 @@ function wrapWithMarkers(template) {
414
421
  * Returns the hash of the written template content, or null if skipped.
415
422
  */
416
423
  async function appendTemplateSection(root, latDir, relPath, template, label, indent, ask) {
417
- const absPath = join(root, relPath);
424
+ const absPath = projectWritePath(root, join(root, relPath));
418
425
  const templateHash = contentHash(template);
419
426
  const wrapped = wrapWithMarkers(template);
420
427
  if (!existsSync(absPath)) {
421
428
  mkdirSync(join(absPath, '..'), { recursive: true });
422
- writeFileSync(absPath, wrapped);
429
+ writeProjectFile(root, absPath, wrapped);
423
430
  console.log(styleText('green', `${indent}Created ${label}`));
424
431
  return templateHash;
425
432
  }
@@ -443,7 +450,7 @@ async function appendTemplateSection(root, latDir, relPath, template, label, ind
443
450
  const updated = currentContent.slice(0, beginIdx) +
444
451
  wrapped +
445
452
  currentContent.slice(endWithNl);
446
- writeFileSync(absPath, updated);
453
+ writeProjectFile(root, absPath, updated);
447
454
  console.log(styleText('green', `${indent}Updated ${label}`));
448
455
  return templateHash;
449
456
  }
@@ -457,7 +464,7 @@ async function appendTemplateSection(root, latDir, relPath, template, label, ind
457
464
  const updated = currentContent.slice(0, beginIdx) +
458
465
  wrapped +
459
466
  currentContent.slice(endWithNl);
460
- writeFileSync(absPath, updated);
467
+ writeProjectFile(root, absPath, updated);
461
468
  console.log(styleText('green', `${indent}Updated ${label}`));
462
469
  return templateHash;
463
470
  }
@@ -470,7 +477,7 @@ async function appendTemplateSection(root, latDir, relPath, template, label, ind
470
477
  const storedHash = readFileHash(latDir, relPath);
471
478
  if (storedHash && currentHash === storedHash) {
472
479
  // Unmodified old-style file — migrate: wrap existing content with markers
473
- writeFileSync(absPath, wrapWithMarkers(currentContent));
480
+ writeProjectFile(root, absPath, wrapWithMarkers(currentContent));
474
481
  console.log(styleText('green', `${indent}Migrated ${label}`) + ' to marker format');
475
482
  // Return hash of what's now in the section (the old content)
476
483
  return currentHash;
@@ -480,7 +487,7 @@ async function appendTemplateSection(root, latDir, relPath, template, label, ind
480
487
  if (!content.endsWith('\n'))
481
488
  content += '\n';
482
489
  content += '\n' + wrapped;
483
- writeFileSync(absPath, content);
490
+ writeProjectFile(root, absPath, content);
484
491
  console.log(styleText('green', `${indent}Appended lat section to ${label}`));
485
492
  return templateHash;
486
493
  }
@@ -508,10 +515,10 @@ async function setupClaudeCode(root, latDir, template, hashes, ask, style) {
508
515
  console.log('');
509
516
  console.log(styleText('dim', ' Hooks inject lat.md workflow reminders into every prompt and remind'));
510
517
  console.log(styleText('dim', ' the agent to update lat.md/ before finishing.'));
511
- const claudeDir = join(root, '.claude');
518
+ const claudeDir = projectWritePath(root, join(root, '.claude'));
512
519
  const settingsPath = join(claudeDir, 'settings.json');
513
520
  mkdirSync(claudeDir, { recursive: true });
514
- syncLatHooks(settingsPath, style);
521
+ syncLatHooks(settingsPath, style, 'claude', root);
515
522
  console.log(styleText('green', ' Hooks') +
516
523
  ' synced (UserPromptSubmit + Stop + PostToolUse)');
517
524
  // .claude/skills/lat-md/SKILL.md — skill for authoring lat.md files
@@ -528,11 +535,11 @@ async function setupClaudeCode(root, latDir, template, hashes, ask, style) {
528
535
  console.log(styleText('dim', ' Agents can call `lat` from the command line, but an MCP server gives lat'));
529
536
  console.log(styleText('dim', ' more visibility and makes agents more likely to use it proactively.'));
530
537
  const mcpPath = join(root, '.mcp.json');
531
- if (hasMcpServer(mcpPath, 'mcpServers')) {
538
+ if (hasMcpServer(root, mcpPath, 'mcpServers')) {
532
539
  console.log(styleText('green', ' MCP server') + ' already configured');
533
540
  }
534
541
  else {
535
- addMcpServer(mcpPath, 'mcpServers', style);
542
+ addMcpServer(root, mcpPath, 'mcpServers', style);
536
543
  console.log(styleText('green', ' MCP server') + ' registered in .mcp.json');
537
544
  }
538
545
  // Ensure .mcp.json is gitignored (it contains local absolute paths)
@@ -555,11 +562,11 @@ async function setupCursor(root, latDir, hashes, ask, style) {
555
562
  console.log(styleText('dim', ' Agents can call `lat` from the command line, but an MCP server gives lat'));
556
563
  console.log(styleText('dim', ' more visibility and makes agents more likely to use it proactively.'));
557
564
  const mcpPath = join(root, '.cursor', 'mcp.json');
558
- if (hasMcpServer(mcpPath, 'mcpServers')) {
565
+ if (hasMcpServer(root, mcpPath, 'mcpServers')) {
559
566
  console.log(styleText('green', ' MCP server') + ' already configured');
560
567
  }
561
568
  else {
562
- addMcpServer(mcpPath, 'mcpServers', style);
569
+ addMcpServer(root, mcpPath, 'mcpServers', style);
563
570
  console.log(styleText('green', ' MCP server') + ' registered in .cursor/mcp.json');
564
571
  }
565
572
  // Ensure .cursor is gitignored (hooks and MCP config may contain local paths)
@@ -580,11 +587,11 @@ async function setupCopilot(root, latDir, hashes, ask, style) {
580
587
  console.log(styleText('dim', ' Agents can call `lat` from the command line, but an MCP server gives lat'));
581
588
  console.log(styleText('dim', ' more visibility and makes agents more likely to use it proactively.'));
582
589
  const mcpPath = join(root, '.vscode', 'mcp.json');
583
- if (hasMcpServer(mcpPath, 'servers')) {
590
+ if (hasMcpServer(root, mcpPath, 'servers')) {
584
591
  console.log(styleText('green', ' MCP server') + ' already configured');
585
592
  }
586
593
  else {
587
- addMcpServer(mcpPath, 'servers', style);
594
+ addMcpServer(root, mcpPath, 'servers', style);
588
595
  console.log(styleText('green', ' MCP server') + ' registered in .vscode/mcp.json');
589
596
  }
590
597
  // .agents/skills/lat-md/SKILL.md — skill for authoring lat.md files
@@ -597,7 +604,7 @@ async function setupPi(root, latDir, hashes, ask, style) {
597
604
  console.log('');
598
605
  console.log(styleText('dim', ' The Pi extension registers lat tools and hooks into the agent lifecycle'));
599
606
  console.log(styleText('dim', ' to inject search context and validate lat.md/ before finishing.'));
600
- const template = readPiExtensionTemplate().replace('__LAT_BIN__', latBinString(style));
607
+ const template = readPiExtensionTemplate().replace('__LAT_INVOCATION__', () => JSON.stringify(agentInvocation(style, resolveLatInvocation())));
601
608
  const hash = await writeTemplateFile(root, latDir, '.pi/extensions/lat.ts', template, 'pi-extension.ts', 'Extension (.pi/extensions/lat.ts)', ' ', ask);
602
609
  if (hash)
603
610
  hashes['.pi/extensions/lat.ts'] = hash;
@@ -618,7 +625,7 @@ async function setupOpenCode(root, latDir, hashes, ask, style) {
618
625
  console.log('');
619
626
  console.log(styleText('dim', ' The OpenCode plugin registers lat tools and hooks into the session'));
620
627
  console.log(styleText('dim', ' lifecycle to validate lat.md/ when the agent finishes.'));
621
- const template = readOpenCodePluginTemplate().replace('__LAT_BIN__', latBinString(style));
628
+ const template = readOpenCodePluginTemplate().replace('__LAT_INVOCATION__', () => JSON.stringify(agentInvocation(style, resolveLatInvocation())));
622
629
  const hash = await writeTemplateFile(root, latDir, '.opencode/plugins/lat.ts', template, 'opencode-plugin.ts', 'Plugin (.opencode/plugins/lat.ts)', ' ', ask);
623
630
  if (hash)
624
631
  hashes['.opencode/plugins/lat.ts'] = hash;
@@ -634,10 +641,10 @@ async function setupCodex(root, latDir, hashes, ask, style) {
634
641
  console.log('');
635
642
  console.log(styleText('dim', ' Hooks inject lat.md workflow reminders into every prompt and remind'));
636
643
  console.log(styleText('dim', ' the agent to update lat.md/ before finishing.'));
637
- const codexDir = join(root, '.codex');
644
+ const codexDir = projectWritePath(root, join(root, '.codex'));
638
645
  const hooksPath = join(codexDir, 'hooks.json');
639
646
  mkdirSync(codexDir, { recursive: true });
640
- syncLatHooks(hooksPath, style, 'codex');
647
+ syncLatHooks(hooksPath, style, 'codex', root);
641
648
  console.log(styleText('green', ' Hooks') +
642
649
  ' synced (UserPromptSubmit + Stop + PostToolUse)');
643
650
  // .codex/config.toml — MCP server registration
@@ -645,11 +652,11 @@ async function setupCodex(root, latDir, hashes, ask, style) {
645
652
  console.log(styleText('dim', ' Agents can call `lat` from the command line, but an MCP server gives lat'));
646
653
  console.log(styleText('dim', ' more visibility and makes agents more likely to use it proactively.'));
647
654
  const mcpPath = join(root, '.codex', 'config.toml');
648
- if (hasCodexMcpServer(mcpPath)) {
655
+ if (hasCodexMcpServer(root, mcpPath)) {
649
656
  console.log(styleText('green', ' MCP server') + ' already configured');
650
657
  }
651
658
  else {
652
- addCodexMcpServer(mcpPath, style);
659
+ addCodexMcpServer(root, mcpPath, style);
653
660
  console.log(styleText('green', ' MCP server') + ' registered in .codex/config.toml');
654
661
  }
655
662
  // Ensure .codex is gitignored (config contains local absolute paths)
@@ -844,13 +851,14 @@ export function readLogo() {
844
851
  return readFileSync(join(findTemplatesDir(), 'logo.txt'), 'utf-8');
845
852
  }
846
853
  export function ensureLatLocalConfigIgnored(latDir) {
847
- const path = join(latDir, '.gitignore');
854
+ const root = dirname(latDir);
855
+ const path = projectWritePath(root, join(latDir, '.gitignore'));
848
856
  const entry = 'config.local.yaml';
849
857
  const current = existsSync(path) ? readFileSync(path, 'utf8') : '';
850
858
  if (current.split(/\r?\n/).includes(entry))
851
859
  return;
852
860
  const prefix = current && !current.endsWith('\n') ? `${current}\n` : current;
853
- writeFileSync(path, `${prefix}${entry}\n`);
861
+ writeProjectFile(root, path, `${prefix}${entry}\n`);
854
862
  }
855
863
  export async function initCmd(targetDir) {
856
864
  console.log(styleText('cyan', readLogo()));
@@ -875,6 +883,7 @@ export async function initCmd(targetDir) {
875
883
  }
876
884
  const root = resolve(targetDir ?? process.cwd());
877
885
  const latDir = join(root, 'lat.md');
886
+ projectWritePath(root, latDir);
878
887
  const storedInitVersion = readInitVersion(latDir);
879
888
  const interactive = process.stdin.isTTY ?? false;
880
889
  // Readline is created AFTER the selectMenu loop below.
@@ -1060,7 +1069,7 @@ export async function initCmd(targetDir) {
1060
1069
  styleText('cyan', 'lat check') +
1061
1070
  ' to validate your setup.');
1062
1071
  // Suggest ripgrep if not available
1063
- const { hasRipgrep } = await import('../code-refs.js');
1072
+ const { hasRipgrep } = await import('@plebeiantech/lat.md-core/code-refs');
1064
1073
  if (!(await hasRipgrep())) {
1065
1074
  console.log('');
1066
1075
  console.log(styleText('yellow', 'Tip:') +
@@ -1,4 +1,4 @@
1
- import type { CmdContext, CmdResult } from '../context.js';
1
+ import type { CmdContext, CmdResult } from '@plebeiantech/lat.md-core/context';
2
2
  /**
3
3
  * Rebuild the embedding index. Honors the durable per-repo backend preference:
4
4
  * a repo pinned to local rebuilds local and ignores the key. `--local` forces
@@ -2,9 +2,9 @@ import { writeIndex } from '../search/cache.js';
2
2
  import readline from 'node:readline/promises';
3
3
  import { ensureMeta, setStoredModel, ensureSectionsSchema, dropSections, } from '../search/db.js';
4
4
  import { embedderFromEnv, localEmbedder, modelKey, EmbeddingAuthError, } from '../search/embedder.js';
5
- import { getLlmKey, getRepoEmbedding, setRepoEmbedding } from '../config.js';
5
+ import { getLlmKey, getRepoEmbedding, setRepoEmbedding, } from '@plebeiantech/lat.md-core/config';
6
6
  import { indexSections } from '../search/index.js';
7
- import { commandProjectAnalysis } from '../project-analysis.js';
7
+ import { commandProjectAnalysis } from '@plebeiantech/lat.md-core/project-analysis';
8
8
  const SPINNER = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
9
9
  async function confirmUseLocal(ctx, status, assumeYes) {
10
10
  const s = ctx.styler;
@@ -1,8 +1,8 @@
1
- import type { CmdContext, CmdResult, Styler } from '../context.js';
1
+ import type { CmdContext, CmdResult, Styler } from '@plebeiantech/lat.md-core/context';
2
2
  import { type IndexStats } from '../search/index.js';
3
- import type { SectionMatch } from '../lattice-model.js';
4
- import type { Section } from '../lattice-model.js';
5
- import { type MarkdownProjectAnalysis } from '../project-analysis.js';
3
+ import type { SectionMatch } from '@plebeiantech/lat.md-core/lattice-model';
4
+ import type { Section } from '@plebeiantech/lat.md-core/lattice-model';
5
+ import { type MarkdownProjectAnalysis } from '@plebeiantech/lat.md-core/project-analysis';
6
6
  export type SearchResult = {
7
7
  query: string;
8
8
  matches: SectionMatch[];
@@ -4,37 +4,46 @@ import { hasIndex } from '../search/db.js';
4
4
  import { embeddingFingerprint } from '../search/chunks.js';
5
5
  import { writeIndex } from '../search/cache.js';
6
6
  import { dirname, join } from 'node:path';
7
- import { openDb, getStoredModel, setStoredModel, ensureSectionsSchema, closeDb, } from '../search/db.js';
7
+ import { openDb, setStoredModel, ensureSectionsSchema, closeDb, } from '../search/db.js';
8
8
  import { embedderForIndex, modelKey, ReindexRequiredError, EmbeddingAuthError, } from '../search/embedder.js';
9
9
  import { indexSections, projectFingerprint, } from '../search/index.js';
10
- import { searchSections } from '../search/search.js';
11
- import { resolveSearchMatches, searchIndexedSections, } from '../search/query.js';
12
- import { analyzeMarkdownProject, commandProjectAnalysis, } from '../project-analysis.js';
13
- import { formatSectionPreview, formatNavHints } from '../format.js';
14
- import { provenanceNote, formatProvenanceNote } from './check-status.js';
15
- async function withDb(latDir, progress, project, cacheDir, fn) {
16
- if (hasIndex(cacheDir ?? join(latDir, '.cache'))) {
10
+ import { searchSections, prepareSearchQuery } from '../search/search.js';
11
+ import { indexMetadata, sameIndexMetadata, resolveSearchMatches, searchIndexedSections, } from '../search/query.js';
12
+ import { analyzeMarkdownProject, commandProjectAnalysis, } from '@plebeiantech/lat.md-core/project-analysis';
13
+ import { formatSectionPreview, formatNavHints, } from '@plebeiantech/lat.md-core/format';
14
+ import { provenanceNote, formatProvenanceNote, } from '@plebeiantech/lat.md-core/cli/check-status';
15
+ async function withDb(latDir, progress, project, cacheDir, fn, prepare) {
16
+ for (let attempt = 0; hasIndex(cacheDir ?? join(latDir, '.cache')); attempt++) {
17
+ if (attempt >= 3)
18
+ throw new Error('Search index keeps changing; retry shortly.');
19
+ const metadataDb = openDb(latDir, cacheDir, true);
20
+ let metadata;
21
+ try {
22
+ metadata = await indexMetadata(metadataDb);
23
+ }
24
+ finally {
25
+ await closeDb(metadataDb);
26
+ }
27
+ const stored = metadata.get('embedding_model') ?? null;
28
+ const embedder = await embedderForIndex(stored, latDir);
29
+ if (metadata.get('fingerprint') !== embeddingFingerprint(embedder))
30
+ throw new ReindexRequiredError('Search chunking or embedding model changed; run lat reindex.');
31
+ if (!stored ||
32
+ metadata.get('lexical_version') !== LEXICAL_VERSION ||
33
+ metadata.get('project_hash') !== projectFingerprint(project))
34
+ break;
35
+ await prepare?.(embedder);
17
36
  const db = openDb(latDir, cacheDir, true);
18
37
  try {
19
- const stored = await getStoredModel(db);
20
- const embedder = await embedderForIndex(stored, latDir);
21
- const metadata = new Map((await db.execute('SELECT key,value FROM meta')).rows.map((row) => [
22
- row.key,
23
- row.value,
24
- ]));
25
- if (metadata.get('fingerprint') !== embeddingFingerprint(embedder))
26
- throw new ReindexRequiredError('Search chunking or embedding model changed; run lat reindex.');
27
- if (stored &&
28
- metadata.get('lexical_version') === LEXICAL_VERSION &&
29
- metadata.get('project_hash') === projectFingerprint(project)) {
30
- progress?.afterIndex?.({
31
- added: 0,
32
- updated: 0,
33
- removed: 0,
34
- unchanged: project.sections.length,
35
- }, false);
36
- return await fn(db, embedder, project);
37
- }
38
+ if (!sameIndexMetadata(metadata, await indexMetadata(db)))
39
+ continue;
40
+ progress?.afterIndex?.({
41
+ added: 0,
42
+ updated: 0,
43
+ removed: 0,
44
+ unchanged: project.sections.length,
45
+ }, false);
46
+ return await fn(db, embedder, project);
38
47
  }
39
48
  finally {
40
49
  await closeDb(db);
@@ -48,6 +57,7 @@ async function withDb(latDir, progress, project, cacheDir, fn) {
48
57
  const stats = await indexSections(latDir, db, embedder, undefined, project);
49
58
  await setStoredModel(db, modelKey(embedder));
50
59
  progress?.afterIndex?.(stats, isEmpty);
60
+ await prepare?.(embedder);
51
61
  return fn(db, embedder, project);
52
62
  });
53
63
  }
@@ -77,12 +87,15 @@ export async function runSearch(latDir, query, limit, progress, opts) {
77
87
  (await analyzeMarkdownProject(latDir, dirname(latDir), {
78
88
  executor: 'auto',
79
89
  }));
90
+ let vector;
80
91
  return withDb(latDir, progress, project, opts?.cacheDir, async (db, embedder, analyzed) => {
81
- const results = await searchSections(db, query, embedder, limit, opts?.minSimilarity);
92
+ const results = await searchSections(db, query, embedder, limit, opts?.minSimilarity, vector);
82
93
  return {
83
94
  query,
84
95
  matches: resolveSearchMatches(results, analyzed.sectionById),
85
96
  };
97
+ }, async (embedder) => {
98
+ vector = await prepareSearchQuery(query, embedder, limit, opts?.minSimilarity);
86
99
  });
87
100
  }
88
101
  /**
@@ -1,4 +1,4 @@
1
- import type { CmdContext, CmdResult } from '../context.js';
1
+ import type { CmdContext, CmdResult } from '@plebeiantech/lat.md-core/context';
2
2
  import { buildServerView, type ServerViewBuildOptions, type ServerViewBuildResult } from '../view/server-build.js';
3
3
  export type ServerViewBuildTarget = 'node' | 'vercel';
4
4
  export type UiBuildServerOptions = ServerViewBuildOptions & {
@@ -1,4 +1,4 @@
1
- import type { CmdContext, CmdResult } from '../context.js';
1
+ import type { CmdContext, CmdResult } from '@plebeiantech/lat.md-core/context';
2
2
  import { type StaticViewBuildOptions } from '../view/static-build.js';
3
3
  /** Export the current vault as a serverless, read-only Lat UI. */
4
4
  export declare function uiBuildCommand(ctx: CmdContext, output?: string, options?: StaticViewBuildOptions): Promise<CmdResult>;
@@ -1,4 +1,4 @@
1
- import type { CmdContext, CmdResult } from '../context.js';
1
+ import type { CmdContext, CmdResult } from '@plebeiantech/lat.md-core/context';
2
2
  import { type ViewServer, type ViewServerOptions } from '../view/server.js';
3
3
  type UiCommandOptions = ViewServerOptions & {
4
4
  openBrowser?: (url: string) => Promise<void>;
@@ -1,11 +1,11 @@
1
1
  import { existsSync, openSync, readSync, closeSync, statSync } from 'node:fs';
2
2
  import { dirname, isAbsolute, resolve } from 'node:path';
3
- import { findLatticeDir, findSections } from '../lattice.js';
4
- import { commandProjectAnalysis } from '../project-analysis.js';
5
- import { plainStyler } from '../context.js';
6
- import { expandPrompt } from '../cli/expand.js';
3
+ import { findLatticeDir, findSections, } from '@plebeiantech/lat.md-core/lattice';
4
+ import { commandProjectAnalysis } from '@plebeiantech/lat.md-core/project-analysis';
5
+ import { plainStyler, } from '@plebeiantech/lat.md-core/context';
6
+ import { expandPrompt } from '@plebeiantech/lat.md-core/cli/expand';
7
7
  import { runSearch } from '../cli/search.js';
8
- import { getSection, formatSectionOutput } from '../cli/section.js';
8
+ import { getSection, formatSectionOutput, } from '@plebeiantech/lat.md-core/cli/section';
9
9
  import { getStopStatus, formatStopReason, } from '../cli/hook.js';
10
10
  import { computeCommentBlock } from '../cli/comment-guard.js';
11
11
  import { taggedDocsForFiles, federateTags } from '../knowledge/index.js';
@@ -328,7 +328,7 @@ export async function handleAntigravityPostToolUse(rawInput, writeOutput = true)
328
328
  const latDir = findLatticeDir(workspacePath) ?? findLatticeDir();
329
329
  if (latDir) {
330
330
  try {
331
- const { checkIndex } = await import('../cli/check.js');
331
+ const { checkIndex } = await import('@plebeiantech/lat.md-core/cli/check');
332
332
  await checkIndex(latDir, undefined, { fix: true });
333
333
  }
334
334
  catch { }
@@ -11,7 +11,7 @@ export type SetupAntigravityOptions = {
11
11
  appendTemplateSection: (root: string, latDir: string, relPath: string, template: string, label: string, indent: string, ask: (message: string) => Promise<boolean>) => Promise<string | null>;
12
12
  writeTemplateFile: (root: string, latDir: string, relPath: string, template: string, genTarget: string | null, label: string, indent: string, ask: (message: string) => Promise<boolean>) => Promise<string | null>;
13
13
  ensureGitignored: (root: string, entry: string) => void;
14
- hasMcpServer: (configPath: string, key: string) => boolean;
15
- addMcpServer: (configPath: string, key: string, style: 'global' | 'local' | 'npx') => void;
14
+ hasMcpServer: (root: string, configPath: string, key: string) => boolean;
15
+ addMcpServer: (root: string, configPath: string, key: string, style: 'global' | 'local' | 'npx') => void;
16
16
  };
17
17
  export declare function setupAntigravity(opts: SetupAntigravityOptions): Promise<void>;
@@ -113,11 +113,11 @@ export async function setupAntigravity(opts) {
113
113
  catch { }
114
114
  ensureGitignored(root, '.gemini');
115
115
  const mcpPath = join(root, '.mcp.json');
116
- if (hasMcpServer(mcpPath, 'mcpServers')) {
116
+ if (hasMcpServer(root, mcpPath, 'mcpServers')) {
117
117
  console.log(styleText('green', ' MCP server') + ' already configured');
118
118
  }
119
119
  else {
120
- addMcpServer(mcpPath, 'mcpServers', style);
120
+ addMcpServer(root, mcpPath, 'mcpServers', style);
121
121
  console.log(styleText('green', ' MCP server') + ' registered in .mcp.json');
122
122
  }
123
123
  ensureGitignored(root, '.mcp.json');
@@ -11,12 +11,12 @@ import { execFile } from 'node:child_process';
11
11
  import { createHash } from 'node:crypto';
12
12
  import { join, relative } from 'node:path';
13
13
  import { promisify } from 'node:util';
14
- import { extractRefs, buildFileIndex, buildSectionSlugIndex, parseSections, parseFrontmatter, resolveRef, } from './lattice.js';
15
- import { scanCodeRefs } from './code-refs.js';
16
- import { DIATAXIS_MODES, MODE_DIRS } from './cli/check-mode.js';
17
- import { readProvenance } from './cli/check-status.js';
18
- import { cleanUntrustedId } from './untrusted.js';
19
- import { toPosix } from './path.js';
14
+ import { extractRefs, buildFileIndex, buildSectionSlugIndex, parseSections, parseFrontmatter, resolveRef, } from '@plebeiantech/lat.md-core/lattice';
15
+ import { scanCodeRefs } from '@plebeiantech/lat.md-core/code-refs';
16
+ import { DIATAXIS_MODES, MODE_DIRS, } from '@plebeiantech/lat.md-core/cli/check-mode';
17
+ import { readProvenance } from '@plebeiantech/lat.md-core/cli/check-status';
18
+ import { cleanUntrustedId } from '@plebeiantech/lat.md-core/untrusted';
19
+ import { toPosix } from '@plebeiantech/lat.md-core/path';
20
20
  const execFileAsync = promisify(execFile);
21
21
  /** Bytes. Node's `execFile` default is 1 MB, which a large document exceeds. */
22
22
  const GIT_MAX_BUFFER = 256 * 1024 * 1024;
@@ -192,7 +192,7 @@ export async function buildGraph(files, projectRoot, includeCode) {
192
192
  }
193
193
  /** Read the working tree's lat.md files straight off disk. */
194
194
  export async function loadWorkingTreeFiles(latticeDir, projectRoot) {
195
- const { listLatticeFiles } = await import('./lattice.js');
195
+ const { listLatticeFiles } = await import('@plebeiantech/lat.md-core/lattice');
196
196
  const { readFile } = await import('node:fs/promises');
197
197
  const paths = await listLatticeFiles(latticeDir);
198
198
  const files = [];
@@ -1,7 +1,7 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
- import { parseFrontmatter } from '../lattice.js';
4
- import { UNTRUSTED_NOTICE, quoteUntrusted, cleanUntrustedId, } from '../untrusted.js';
3
+ import { parseFrontmatter } from '@plebeiantech/lat.md-core/lattice';
4
+ import { UNTRUSTED_NOTICE, quoteUntrusted, cleanUntrustedId, } from '@plebeiantech/lat.md-core/untrusted';
5
5
  import { tagsToTerms, capHits } from './ranking.js';
6
6
  const STORE_GROUP_LABELS = {
7
7
  cq: 'cq:',
@@ -2,16 +2,16 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
3
  import { z } from 'zod';
4
4
  import { dirname } from 'node:path';
5
- import { findLatticeDir } from '../project-discovery.js';
6
- import { plainStyler } from '../context.js';
7
- import { locateCommand } from '../cli/locate.js';
8
- import { sectionCommand } from '../cli/section.js';
5
+ import { findLatticeDir } from '@plebeiantech/lat.md-core/project-discovery';
6
+ import { plainStyler, } from '@plebeiantech/lat.md-core/context';
7
+ import { locateCommand } from '@plebeiantech/lat.md-core/cli/locate';
8
+ import { sectionCommand } from '@plebeiantech/lat.md-core/cli/section';
9
9
  import { searchCommand } from '../cli/search.js';
10
10
  import { DEFAULT_SEARCH_LIMIT, DEFAULT_MIN_SIMILARITY, } from '../search/search.js';
11
- import { expandCommand } from '../cli/expand.js';
12
- import { checkAllCommand } from '../cli/check.js';
13
- import { refsCommand } from '../cli/refs.js';
14
- import { externalListCommand, externalShowCommand } from '../cli/external.js';
11
+ import { expandCommand } from '@plebeiantech/lat.md-core/cli/expand';
12
+ import { checkAllCommand } from '@plebeiantech/lat.md-core/cli/check';
13
+ import { refsCommand } from '@plebeiantech/lat.md-core/cli/refs';
14
+ import { externalListCommand, externalShowCommand, } from '@plebeiantech/lat.md-core/cli/external';
15
15
  function toMcp(result) {
16
16
  const content = [{ type: 'text', text: result.output }];
17
17
  return result.isError ? { content, isError: true } : { content };
@@ -1,3 +1,3 @@
1
1
  import { SearchDb } from './db.js';
2
- /** Build a private staging database; readers only open snapshots of search.db. */
2
+ /** Build a private staging database; access locks protect copies and publication of search.db. */
3
3
  export declare function writeIndex<T>(latDir: string, cacheDir: string | undefined, rebuild: boolean, work: (db: SearchDb, storedModel: string | null) => Promise<T>): Promise<T>;