lmgrep 0.1.17 → 0.2.0

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 (401) hide show
  1. package/README.md +226 -63
  2. package/completions/_lmgrep +49 -40
  3. package/dist/application/Lmgrep.d.ts +107 -0
  4. package/dist/application/Lmgrep.js +99 -0
  5. package/dist/application/Lmgrep.js.map +1 -0
  6. package/dist/application/LmgrepFactory.d.ts +40 -0
  7. package/dist/application/LmgrepFactory.js +155 -0
  8. package/dist/application/LmgrepFactory.js.map +1 -0
  9. package/dist/application/indexing/BranchBootstrapper.d.ts +21 -0
  10. package/dist/application/indexing/BranchBootstrapper.js +52 -0
  11. package/dist/application/indexing/BranchBootstrapper.js.map +1 -0
  12. package/dist/application/indexing/BranchManifestSweeper.d.ts +17 -0
  13. package/dist/application/indexing/BranchManifestSweeper.js +35 -0
  14. package/dist/application/indexing/BranchManifestSweeper.js.map +1 -0
  15. package/dist/application/indexing/Duration.d.ts +9 -0
  16. package/dist/application/indexing/Duration.js +25 -0
  17. package/dist/application/indexing/Duration.js.map +1 -0
  18. package/dist/application/indexing/EmbeddingAbortError.d.ts +11 -0
  19. package/dist/application/indexing/EmbeddingAbortError.js +20 -0
  20. package/dist/application/indexing/EmbeddingAbortError.js.map +1 -0
  21. package/dist/application/indexing/EmbeddingPipeline.d.ts +59 -0
  22. package/dist/application/indexing/EmbeddingPipeline.js +140 -0
  23. package/dist/application/indexing/EmbeddingPipeline.js.map +1 -0
  24. package/dist/application/indexing/IndexBuilder.d.ts +112 -0
  25. package/dist/application/indexing/IndexBuilder.js +370 -0
  26. package/dist/application/indexing/IndexBuilder.js.map +1 -0
  27. package/dist/application/indexing/IndexingProgress.d.ts +34 -0
  28. package/dist/application/indexing/IndexingProgress.js +2 -0
  29. package/dist/application/indexing/IndexingProgress.js.map +1 -0
  30. package/dist/application/operations/Deadline.d.ts +13 -0
  31. package/dist/application/operations/Deadline.js +29 -0
  32. package/dist/application/operations/Deadline.js.map +1 -0
  33. package/dist/application/operations/HealthMonitor.d.ts +58 -0
  34. package/dist/application/operations/HealthMonitor.js +128 -0
  35. package/dist/application/operations/HealthMonitor.js.map +1 -0
  36. package/dist/application/operations/IndexAlternatives.d.ts +35 -0
  37. package/dist/application/operations/IndexAlternatives.js +61 -0
  38. package/dist/application/operations/IndexAlternatives.js.map +1 -0
  39. package/dist/application/operations/IndexInventory.d.ts +69 -0
  40. package/dist/application/operations/IndexInventory.js +99 -0
  41. package/dist/application/operations/IndexInventory.js.map +1 -0
  42. package/dist/application/operations/StatusService.d.ts +90 -0
  43. package/dist/application/operations/StatusService.js +171 -0
  44. package/dist/application/operations/StatusService.js.map +1 -0
  45. package/dist/application/operations/WatchService.d.ts +67 -0
  46. package/dist/application/operations/WatchService.js +145 -0
  47. package/dist/application/operations/WatchService.js.map +1 -0
  48. package/dist/application/operations/WorkingTreeDiff.d.ts +19 -0
  49. package/dist/application/operations/WorkingTreeDiff.js +36 -0
  50. package/dist/application/operations/WorkingTreeDiff.js.map +1 -0
  51. package/dist/application/research/ResearchAgent.d.ts +68 -0
  52. package/dist/application/research/ResearchAgent.js +201 -0
  53. package/dist/application/research/ResearchAgent.js.map +1 -0
  54. package/dist/application/research/ResearchPrompts.d.ts +16 -0
  55. package/dist/application/research/ResearchPrompts.js +34 -0
  56. package/dist/application/research/ResearchPrompts.js.map +1 -0
  57. package/dist/application/search/SearchCriteria.d.ts +37 -0
  58. package/dist/application/search/SearchCriteria.js +48 -0
  59. package/dist/application/search/SearchCriteria.js.map +1 -0
  60. package/dist/application/search/SearchService.d.ts +36 -0
  61. package/dist/application/search/SearchService.js +108 -0
  62. package/dist/application/search/SearchService.js.map +1 -0
  63. package/dist/application/search/SearchTargetResolver.d.ts +56 -0
  64. package/dist/application/search/SearchTargetResolver.js +104 -0
  65. package/dist/application/search/SearchTargetResolver.js.map +1 -0
  66. package/dist/cli.d.ts +1 -1
  67. package/dist/cli.js +5 -754
  68. package/dist/cli.js.map +1 -1
  69. package/dist/domain/config/ConfigSource.d.ts +16 -0
  70. package/dist/domain/config/ConfigSource.js +2 -0
  71. package/dist/domain/config/ConfigSource.js.map +1 -0
  72. package/dist/domain/config/LmgrepConfig.d.ts +53 -0
  73. package/dist/domain/config/LmgrepConfig.js +2 -0
  74. package/dist/domain/config/LmgrepConfig.js.map +1 -0
  75. package/dist/domain/corpus/Chunk.d.ts +49 -0
  76. package/dist/domain/corpus/Chunk.js +60 -0
  77. package/dist/domain/corpus/Chunk.js.map +1 -0
  78. package/dist/domain/corpus/CodeLocation.d.ts +18 -0
  79. package/dist/domain/corpus/CodeLocation.js +34 -0
  80. package/dist/domain/corpus/CodeLocation.js.map +1 -0
  81. package/dist/domain/corpus/ContentHash.d.ts +15 -0
  82. package/dist/domain/corpus/ContentHash.js +30 -0
  83. package/dist/domain/corpus/ContentHash.js.map +1 -0
  84. package/dist/domain/corpus/FileVersion.d.ts +31 -0
  85. package/dist/domain/corpus/FileVersion.js +47 -0
  86. package/dist/domain/corpus/FileVersion.js.map +1 -0
  87. package/dist/domain/corpus/SourceFile.d.ts +26 -0
  88. package/dist/domain/corpus/SourceFile.js +47 -0
  89. package/dist/domain/corpus/SourceFile.js.map +1 -0
  90. package/dist/domain/corpus/Vector.d.ts +37 -0
  91. package/dist/domain/corpus/Vector.js +96 -0
  92. package/dist/domain/corpus/Vector.js.map +1 -0
  93. package/dist/domain/ports/ChatModelPort.d.ts +57 -0
  94. package/dist/domain/ports/ChatModelPort.js +2 -0
  95. package/dist/domain/ports/ChatModelPort.js.map +1 -0
  96. package/dist/domain/ports/ChunkRepositoryPort.d.ts +42 -0
  97. package/dist/domain/ports/ChunkRepositoryPort.js +2 -0
  98. package/dist/domain/ports/ChunkRepositoryPort.js.map +1 -0
  99. package/dist/domain/ports/ChunkerPort.d.ts +5 -0
  100. package/dist/domain/ports/ChunkerPort.js +2 -0
  101. package/dist/domain/ports/ChunkerPort.js.map +1 -0
  102. package/dist/domain/ports/DatabaseSessionPort.d.ts +10 -0
  103. package/dist/domain/ports/DatabaseSessionPort.js +2 -0
  104. package/dist/domain/ports/DatabaseSessionPort.js.map +1 -0
  105. package/dist/domain/ports/EmbedderPort.d.ts +14 -0
  106. package/dist/domain/ports/EmbedderPort.js +2 -0
  107. package/dist/domain/ports/EmbedderPort.js.map +1 -0
  108. package/dist/domain/ports/FileManifestRepositoryPort.d.ts +32 -0
  109. package/dist/domain/ports/FileManifestRepositoryPort.js +2 -0
  110. package/dist/domain/ports/FileManifestRepositoryPort.js.map +1 -0
  111. package/dist/domain/ports/GitPort.d.ts +24 -0
  112. package/dist/domain/ports/GitPort.js +2 -0
  113. package/dist/domain/ports/GitPort.js.map +1 -0
  114. package/dist/domain/ports/IndexMaintenancePort.d.ts +58 -0
  115. package/dist/domain/ports/IndexMaintenancePort.js +2 -0
  116. package/dist/domain/ports/IndexMaintenancePort.js.map +1 -0
  117. package/dist/domain/ports/IndexMetadataPort.d.ts +23 -0
  118. package/dist/domain/ports/IndexMetadataPort.js +2 -0
  119. package/dist/domain/ports/IndexMetadataPort.js.map +1 -0
  120. package/dist/domain/ports/LockPort.d.ts +17 -0
  121. package/dist/domain/ports/LockPort.js +2 -0
  122. package/dist/domain/ports/LockPort.js.map +1 -0
  123. package/dist/domain/ports/LoggerPort.d.ts +5 -0
  124. package/dist/domain/ports/LoggerPort.js +2 -0
  125. package/dist/domain/ports/LoggerPort.js.map +1 -0
  126. package/dist/domain/ports/ProjectIndexesPort.d.ts +20 -0
  127. package/dist/domain/ports/ProjectIndexesPort.js +2 -0
  128. package/dist/domain/ports/ProjectIndexesPort.js.map +1 -0
  129. package/dist/domain/ports/ProjectRegistryPort.d.ts +42 -0
  130. package/dist/domain/ports/ProjectRegistryPort.js +2 -0
  131. package/dist/domain/ports/ProjectRegistryPort.js.map +1 -0
  132. package/dist/domain/ports/StateDirectoryPort.d.ts +29 -0
  133. package/dist/domain/ports/StateDirectoryPort.js +2 -0
  134. package/dist/domain/ports/StateDirectoryPort.js.map +1 -0
  135. package/dist/domain/ports/WorkspacePort.d.ts +38 -0
  136. package/dist/domain/ports/WorkspacePort.js +2 -0
  137. package/dist/domain/ports/WorkspacePort.js.map +1 -0
  138. package/dist/domain/project/Branch.d.ts +20 -0
  139. package/dist/domain/project/Branch.js +33 -0
  140. package/dist/domain/project/Branch.js.map +1 -0
  141. package/dist/domain/project/DatabaseLocation.d.ts +32 -0
  142. package/dist/domain/project/DatabaseLocation.js +35 -0
  143. package/dist/domain/project/DatabaseLocation.js.map +1 -0
  144. package/dist/domain/project/IndexMetadata.d.ts +17 -0
  145. package/dist/domain/project/IndexMetadata.js +2 -0
  146. package/dist/domain/project/IndexMetadata.js.map +1 -0
  147. package/dist/domain/project/ModelIdentity.d.ts +58 -0
  148. package/dist/domain/project/ModelIdentity.js +97 -0
  149. package/dist/domain/project/ModelIdentity.js.map +1 -0
  150. package/dist/domain/project/Project.d.ts +17 -0
  151. package/dist/domain/project/Project.js +21 -0
  152. package/dist/domain/project/Project.js.map +1 -0
  153. package/dist/domain/project/ProjectId.d.ts +28 -0
  154. package/dist/domain/project/ProjectId.js +58 -0
  155. package/dist/domain/project/ProjectId.js.map +1 -0
  156. package/dist/domain/project/ProjectLocator.d.ts +112 -0
  157. package/dist/domain/project/ProjectLocator.js +178 -0
  158. package/dist/domain/project/ProjectLocator.js.map +1 -0
  159. package/dist/domain/research/Citation.d.ts +27 -0
  160. package/dist/domain/research/Citation.js +43 -0
  161. package/dist/domain/research/Citation.js.map +1 -0
  162. package/dist/domain/research/EvidenceLedger.d.ts +47 -0
  163. package/dist/domain/research/EvidenceLedger.js +111 -0
  164. package/dist/domain/research/EvidenceLedger.js.map +1 -0
  165. package/dist/domain/research/ResearchTrace.d.ts +19 -0
  166. package/dist/domain/research/ResearchTrace.js +22 -0
  167. package/dist/domain/research/ResearchTrace.js.map +1 -0
  168. package/dist/domain/retrieval/Hit.d.ts +19 -0
  169. package/dist/domain/retrieval/Hit.js +28 -0
  170. package/dist/domain/retrieval/Hit.js.map +1 -0
  171. package/dist/domain/retrieval/HitList.d.ts +35 -0
  172. package/dist/domain/retrieval/HitList.js +81 -0
  173. package/dist/domain/retrieval/HitList.js.map +1 -0
  174. package/dist/domain/retrieval/MissingIndexError.d.ts +11 -0
  175. package/dist/domain/retrieval/MissingIndexError.js +15 -0
  176. package/dist/domain/retrieval/MissingIndexError.js.map +1 -0
  177. package/dist/index.d.ts +43 -33
  178. package/dist/index.js +32 -215
  179. package/dist/index.js.map +1 -1
  180. package/dist/infrastructure/ai/AiSdkChatModel.d.ts +31 -0
  181. package/dist/infrastructure/ai/AiSdkChatModel.js +137 -0
  182. package/dist/infrastructure/ai/AiSdkChatModel.js.map +1 -0
  183. package/dist/infrastructure/ai/AiSdkEmbedder.d.ts +28 -0
  184. package/dist/infrastructure/ai/AiSdkEmbedder.js +79 -0
  185. package/dist/infrastructure/ai/AiSdkEmbedder.js.map +1 -0
  186. package/dist/infrastructure/ai/EmbeddingPrefixes.d.ts +21 -0
  187. package/dist/infrastructure/ai/EmbeddingPrefixes.js +40 -0
  188. package/dist/infrastructure/ai/EmbeddingPrefixes.js.map +1 -0
  189. package/dist/infrastructure/ai/LmStudioProbe.d.ts +18 -0
  190. package/dist/infrastructure/ai/LmStudioProbe.js +49 -0
  191. package/dist/infrastructure/ai/LmStudioProbe.js.map +1 -0
  192. package/dist/infrastructure/ai/LocalModelReloader.d.ts +21 -0
  193. package/dist/infrastructure/ai/LocalModelReloader.js +61 -0
  194. package/dist/infrastructure/ai/LocalModelReloader.js.map +1 -0
  195. package/dist/infrastructure/ai/LocalRuntimeDetector.d.ts +36 -0
  196. package/dist/infrastructure/ai/LocalRuntimeDetector.js +61 -0
  197. package/dist/infrastructure/ai/LocalRuntimeDetector.js.map +1 -0
  198. package/dist/infrastructure/ai/ModelRuntime.d.ts +32 -0
  199. package/dist/infrastructure/ai/ModelRuntime.js +2 -0
  200. package/dist/infrastructure/ai/ModelRuntime.js.map +1 -0
  201. package/dist/infrastructure/ai/OllamaProbe.d.ts +21 -0
  202. package/dist/infrastructure/ai/OllamaProbe.js +69 -0
  203. package/dist/infrastructure/ai/OllamaProbe.js.map +1 -0
  204. package/dist/infrastructure/ai/ProviderFailure.d.ts +16 -0
  205. package/dist/infrastructure/ai/ProviderFailure.js +35 -0
  206. package/dist/infrastructure/ai/ProviderFailure.js.map +1 -0
  207. package/dist/infrastructure/ai/ProviderModuleLoader.d.ts +13 -0
  208. package/dist/infrastructure/ai/ProviderModuleLoader.js +49 -0
  209. package/dist/infrastructure/ai/ProviderModuleLoader.js.map +1 -0
  210. package/dist/infrastructure/ai/ProviderRegistry.d.ts +37 -0
  211. package/dist/infrastructure/ai/ProviderRegistry.js +55 -0
  212. package/dist/infrastructure/ai/ProviderRegistry.js.map +1 -0
  213. package/dist/infrastructure/fs/ConfigLoader.d.ts +59 -0
  214. package/dist/infrastructure/fs/ConfigLoader.js +194 -0
  215. package/dist/infrastructure/fs/ConfigLoader.js.map +1 -0
  216. package/dist/infrastructure/fs/DatabaseLocks.d.ts +52 -0
  217. package/dist/infrastructure/fs/DatabaseLocks.js +92 -0
  218. package/dist/infrastructure/fs/DatabaseLocks.js.map +1 -0
  219. package/dist/infrastructure/fs/DiskUsage.d.ts +6 -0
  220. package/dist/infrastructure/fs/DiskUsage.js +41 -0
  221. package/dist/infrastructure/fs/DiskUsage.js.map +1 -0
  222. package/dist/infrastructure/fs/IndexableFileRules.d.ts +33 -0
  223. package/dist/infrastructure/fs/IndexableFileRules.js +177 -0
  224. package/dist/infrastructure/fs/IndexableFileRules.js.map +1 -0
  225. package/dist/infrastructure/fs/Loggers.d.ts +14 -0
  226. package/dist/infrastructure/fs/Loggers.js +18 -0
  227. package/dist/infrastructure/fs/Loggers.js.map +1 -0
  228. package/dist/infrastructure/fs/PidFileLock.d.ts +40 -0
  229. package/dist/infrastructure/fs/PidFileLock.js +97 -0
  230. package/dist/infrastructure/fs/PidFileLock.js.map +1 -0
  231. package/dist/infrastructure/fs/ProjectIndexes.d.ts +8 -0
  232. package/dist/infrastructure/fs/ProjectIndexes.js +35 -0
  233. package/dist/infrastructure/fs/ProjectIndexes.js.map +1 -0
  234. package/dist/infrastructure/fs/ProjectMetadataStore.d.ts +42 -0
  235. package/dist/infrastructure/fs/ProjectMetadataStore.js +86 -0
  236. package/dist/infrastructure/fs/ProjectMetadataStore.js.map +1 -0
  237. package/dist/infrastructure/fs/ProjectRegistry.d.ts +25 -0
  238. package/dist/infrastructure/fs/ProjectRegistry.js +83 -0
  239. package/dist/infrastructure/fs/ProjectRegistry.js.map +1 -0
  240. package/dist/infrastructure/fs/StateDirectory.d.ts +28 -0
  241. package/dist/infrastructure/fs/StateDirectory.js +71 -0
  242. package/dist/infrastructure/fs/StateDirectory.js.map +1 -0
  243. package/dist/infrastructure/fs/Workspace.d.ts +25 -0
  244. package/dist/infrastructure/fs/Workspace.js +90 -0
  245. package/dist/infrastructure/fs/Workspace.js.map +1 -0
  246. package/dist/infrastructure/git/GitClient.d.ts +34 -0
  247. package/dist/infrastructure/git/GitClient.js +74 -0
  248. package/dist/infrastructure/git/GitClient.js.map +1 -0
  249. package/dist/infrastructure/lancedb/ChunkRepository.d.ts +38 -0
  250. package/dist/infrastructure/lancedb/ChunkRepository.js +166 -0
  251. package/dist/infrastructure/lancedb/ChunkRepository.js.map +1 -0
  252. package/dist/infrastructure/lancedb/DatabaseImporter.d.ts +22 -0
  253. package/dist/infrastructure/lancedb/DatabaseImporter.js +74 -0
  254. package/dist/infrastructure/lancedb/DatabaseImporter.js.map +1 -0
  255. package/dist/infrastructure/lancedb/FileManifestRepository.d.ts +34 -0
  256. package/dist/infrastructure/lancedb/FileManifestRepository.js +137 -0
  257. package/dist/infrastructure/lancedb/FileManifestRepository.js.map +1 -0
  258. package/dist/infrastructure/lancedb/IndexMaintenance.d.ts +53 -0
  259. package/dist/infrastructure/lancedb/IndexMaintenance.js +227 -0
  260. package/dist/infrastructure/lancedb/IndexMaintenance.js.map +1 -0
  261. package/dist/infrastructure/lancedb/LanceTables.d.ts +67 -0
  262. package/dist/infrastructure/lancedb/LanceTables.js +159 -0
  263. package/dist/infrastructure/lancedb/LanceTables.js.map +1 -0
  264. package/dist/infrastructure/lancedb/NativeTuning.d.ts +1 -0
  265. package/dist/infrastructure/lancedb/NativeTuning.js +9 -0
  266. package/dist/infrastructure/lancedb/NativeTuning.js.map +1 -0
  267. package/dist/infrastructure/lancedb/RowReplication.d.ts +27 -0
  268. package/dist/infrastructure/lancedb/RowReplication.js +82 -0
  269. package/dist/infrastructure/lancedb/RowReplication.js.map +1 -0
  270. package/dist/infrastructure/lancedb/VectorIndexPolicy.d.ts +60 -0
  271. package/dist/infrastructure/lancedb/VectorIndexPolicy.js +72 -0
  272. package/dist/infrastructure/lancedb/VectorIndexPolicy.js.map +1 -0
  273. package/dist/infrastructure/p2p/IndexShare.d.ts +45 -0
  274. package/dist/infrastructure/p2p/IndexShare.js +160 -0
  275. package/dist/infrastructure/p2p/IndexShare.js.map +1 -0
  276. package/dist/infrastructure/p2p/PeerSwarm.d.ts +16 -0
  277. package/dist/infrastructure/p2p/PeerSwarm.js +41 -0
  278. package/dist/infrastructure/p2p/PeerSwarm.js.map +1 -0
  279. package/dist/infrastructure/p2p/SecureChannel.d.ts +60 -0
  280. package/dist/infrastructure/p2p/SecureChannel.js +71 -0
  281. package/dist/infrastructure/p2p/SecureChannel.js.map +1 -0
  282. package/dist/infrastructure/p2p/ShareCode.d.ts +25 -0
  283. package/dist/infrastructure/p2p/ShareCode.js +304 -0
  284. package/dist/infrastructure/p2p/ShareCode.js.map +1 -0
  285. package/dist/infrastructure/process/ProcessRegistry.d.ts +50 -0
  286. package/dist/infrastructure/process/ProcessRegistry.js +109 -0
  287. package/dist/infrastructure/process/ProcessRegistry.js.map +1 -0
  288. package/dist/infrastructure/treesitter/ChunkContextBuilder.d.ts +45 -0
  289. package/dist/infrastructure/treesitter/ChunkContextBuilder.js +159 -0
  290. package/dist/infrastructure/treesitter/ChunkContextBuilder.js.map +1 -0
  291. package/dist/infrastructure/treesitter/LanguageCatalog.d.ts +30 -0
  292. package/dist/{lib/chunker/languages.js → infrastructure/treesitter/LanguageCatalog.js} +65 -41
  293. package/dist/infrastructure/treesitter/LanguageCatalog.js.map +1 -0
  294. package/dist/infrastructure/treesitter/SlidingWindowChunker.d.ts +15 -0
  295. package/dist/infrastructure/treesitter/SlidingWindowChunker.js +42 -0
  296. package/dist/infrastructure/treesitter/SlidingWindowChunker.js.map +1 -0
  297. package/dist/infrastructure/treesitter/TreeSitterChunker.d.ts +42 -0
  298. package/dist/infrastructure/treesitter/TreeSitterChunker.js +163 -0
  299. package/dist/infrastructure/treesitter/TreeSitterChunker.js.map +1 -0
  300. package/dist/mcp.d.ts +1 -1
  301. package/dist/mcp.js +15 -61
  302. package/dist/mcp.js.map +1 -1
  303. package/dist/presentation/cli/Cli.d.ts +31 -0
  304. package/dist/presentation/cli/Cli.js +120 -0
  305. package/dist/presentation/cli/Cli.js.map +1 -0
  306. package/dist/presentation/cli/CliOptions.d.ts +18 -0
  307. package/dist/presentation/cli/CliOptions.js +25 -0
  308. package/dist/presentation/cli/CliOptions.js.map +1 -0
  309. package/dist/presentation/cli/CommandContext.d.ts +50 -0
  310. package/dist/presentation/cli/CommandContext.js +88 -0
  311. package/dist/presentation/cli/CommandContext.js.map +1 -0
  312. package/dist/presentation/cli/ConfigTemplate.d.ts +31 -0
  313. package/dist/presentation/cli/ConfigTemplate.js +83 -0
  314. package/dist/presentation/cli/ConfigTemplate.js.map +1 -0
  315. package/dist/presentation/cli/Renderer.d.ts +90 -0
  316. package/dist/presentation/cli/Renderer.js +290 -0
  317. package/dist/presentation/cli/Renderer.js.map +1 -0
  318. package/dist/presentation/cli/commands/AskCommand.d.ts +14 -0
  319. package/dist/presentation/cli/commands/AskCommand.js +48 -0
  320. package/dist/presentation/cli/commands/AskCommand.js.map +1 -0
  321. package/dist/presentation/cli/commands/CompletionsCommand.d.ts +18 -0
  322. package/dist/presentation/cli/commands/CompletionsCommand.js +96 -0
  323. package/dist/presentation/cli/commands/CompletionsCommand.js.map +1 -0
  324. package/dist/presentation/cli/commands/ConfigCommands.d.ts +55 -0
  325. package/dist/presentation/cli/commands/ConfigCommands.js +204 -0
  326. package/dist/presentation/cli/commands/ConfigCommands.js.map +1 -0
  327. package/dist/presentation/cli/commands/IndexCommand.d.ts +18 -0
  328. package/dist/presentation/cli/commands/IndexCommand.js +54 -0
  329. package/dist/presentation/cli/commands/IndexCommand.js.map +1 -0
  330. package/dist/presentation/cli/commands/ProjectsCommand.d.ts +48 -0
  331. package/dist/presentation/cli/commands/ProjectsCommand.js +240 -0
  332. package/dist/presentation/cli/commands/ProjectsCommand.js.map +1 -0
  333. package/dist/presentation/cli/commands/SearchCommand.d.ts +19 -0
  334. package/dist/presentation/cli/commands/SearchCommand.js +55 -0
  335. package/dist/presentation/cli/commands/SearchCommand.js.map +1 -0
  336. package/dist/presentation/cli/commands/ServerCommands.d.ts +13 -0
  337. package/dist/presentation/cli/commands/ServerCommands.js +40 -0
  338. package/dist/presentation/cli/commands/ServerCommands.js.map +1 -0
  339. package/dist/presentation/cli/commands/ShareCommands.d.ts +22 -0
  340. package/dist/presentation/cli/commands/ShareCommands.js +134 -0
  341. package/dist/presentation/cli/commands/ShareCommands.js.map +1 -0
  342. package/dist/presentation/cli/commands/StatusCommand.d.ts +15 -0
  343. package/dist/presentation/cli/commands/StatusCommand.js +53 -0
  344. package/dist/presentation/cli/commands/StatusCommand.js.map +1 -0
  345. package/dist/presentation/mcp/HitFormatter.d.ts +17 -0
  346. package/dist/presentation/mcp/HitFormatter.js +42 -0
  347. package/dist/presentation/mcp/HitFormatter.js.map +1 -0
  348. package/dist/presentation/mcp/IndexWatchController.d.ts +17 -0
  349. package/dist/presentation/mcp/IndexWatchController.js +31 -0
  350. package/dist/presentation/mcp/IndexWatchController.js.map +1 -0
  351. package/dist/presentation/mcp/LmgrepCore.d.ts +66 -0
  352. package/dist/presentation/mcp/LmgrepCore.js +178 -0
  353. package/dist/presentation/mcp/LmgrepCore.js.map +1 -0
  354. package/dist/presentation/mcp/McpServer.d.ts +18 -0
  355. package/dist/presentation/mcp/McpServer.js +63 -0
  356. package/dist/presentation/mcp/McpServer.js.map +1 -0
  357. package/dist/presentation/mcp/ToolDescriptions.d.ts +40 -0
  358. package/dist/presentation/mcp/ToolDescriptions.js +85 -0
  359. package/dist/presentation/mcp/ToolDescriptions.js.map +1 -0
  360. package/package.json +84 -63
  361. package/dist/lib/build.d.ts +0 -7
  362. package/dist/lib/build.js +0 -284
  363. package/dist/lib/build.js.map +0 -1
  364. package/dist/lib/chunker/context.d.ts +0 -21
  365. package/dist/lib/chunker/context.js +0 -131
  366. package/dist/lib/chunker/context.js.map +0 -1
  367. package/dist/lib/chunker/index.d.ts +0 -7
  368. package/dist/lib/chunker/index.js +0 -150
  369. package/dist/lib/chunker/index.js.map +0 -1
  370. package/dist/lib/chunker/languages.d.ts +0 -15
  371. package/dist/lib/chunker/languages.js.map +0 -1
  372. package/dist/lib/config.d.ts +0 -12
  373. package/dist/lib/config.js +0 -83
  374. package/dist/lib/config.js.map +0 -1
  375. package/dist/lib/embedder.d.ts +0 -55
  376. package/dist/lib/embedder.js +0 -221
  377. package/dist/lib/embedder.js.map +0 -1
  378. package/dist/lib/p2p.d.ts +0 -32
  379. package/dist/lib/p2p.js +0 -281
  380. package/dist/lib/p2p.js.map +0 -1
  381. package/dist/lib/providers.d.ts +0 -1
  382. package/dist/lib/providers.js +0 -41
  383. package/dist/lib/providers.js.map +0 -1
  384. package/dist/lib/repair.d.ts +0 -10
  385. package/dist/lib/repair.js +0 -57
  386. package/dist/lib/repair.js.map +0 -1
  387. package/dist/lib/scanner.d.ts +0 -34
  388. package/dist/lib/scanner.js +0 -242
  389. package/dist/lib/scanner.js.map +0 -1
  390. package/dist/lib/search-tool.d.ts +0 -47
  391. package/dist/lib/search-tool.js +0 -239
  392. package/dist/lib/search-tool.js.map +0 -1
  393. package/dist/lib/serve.d.ts +0 -11
  394. package/dist/lib/serve.js +0 -127
  395. package/dist/lib/serve.js.map +0 -1
  396. package/dist/lib/store.d.ts +0 -177
  397. package/dist/lib/store.js +0 -825
  398. package/dist/lib/store.js.map +0 -1
  399. package/dist/lib/types.d.ts +0 -129
  400. package/dist/lib/types.js +0 -13
  401. package/dist/lib/types.js.map +0 -1
package/README.md CHANGED
@@ -8,12 +8,14 @@ lmgrep uses [Tree-sitter](https://tree-sitter.github.io/tree-sitter/) to parse s
8
8
 
9
9
  - **Any embedding provider** — works with Ollama, OpenAI, Google, or any provider supported by the [Vercel AI SDK](https://sdk.vercel.ai/)
10
10
  - **Tree-sitter chunking** — splits code at AST boundaries so search results are complete, meaningful units
11
+ - **The index lives in the repo** — under `.git/lmgrep/`, so `du` finds it, `rm -rf` removes it, and deleting a clone deletes its index
12
+ - **One index per model** — switching embedding models selects a different database instead of invalidating the one you have; switching back is instant
13
+ - **Ask (research mode)** — `lmgrep ask` runs a local model that searches, reads, and synthesizes a cited answer, so agents spend one call instead of many searches
11
14
  - **MCP server** — built-in MCP server (`lmgrep mcp`) for integration with Claude Code, Cursor, and other AI tools
12
15
  - **File watching** — `lmgrep serve` watches for changes and incrementally re-indexes
13
16
  - **P2P sharing** — share your index with teammates via direct peer-to-peer transfer
14
17
  - **Cross-project search** — search across multiple indexed projects
15
- - **Git-aware** — respects `.gitignore`, deduplicates across worktrees sharing the same remote
16
- - **Configurable** — global or per-project config, custom ignore patterns, extension filtering
18
+ - **Git-aware** — respects `.gitignore`, and every worktree of a repository shares one index
17
19
 
18
20
  ## Quick start
19
21
 
@@ -25,19 +27,24 @@ pnpm install -g lmgrep
25
27
 
26
28
  ### 2. Set up an embedding model
27
29
 
28
- The fastest way to get started is with [Ollama](https://ollama.com/):
30
+ Start a local inference server, then let lmgrep configure itself.
31
+
32
+ With [Ollama](https://ollama.com/):
29
33
 
30
34
  ```sh
31
- # Install Ollama
32
35
  curl -fsSL https://ollama.com/install.sh | sh
33
-
34
- # Pull an embedding model
35
36
  ollama pull nomic-embed-text
36
-
37
- # Auto-detect and write config
38
37
  lmgrep init
39
38
  ```
40
39
 
40
+ Or with [LM Studio](https://lmstudio.ai): install an embedding model, enable
41
+ the local server, and run `lmgrep init`.
42
+
43
+ `init` detects whichever server is running, picks an embedding model, and
44
+ writes the provider, base URL and any prefixes that model requires. Where the
45
+ server also reports a chat model it configures `chatModel` too, which is what
46
+ enables `lmgrep ask`.
47
+
41
48
  This creates a config file at `~/.config/lmgrep/config.yml` (Linux) or `~/Library/Application Support/lmgrep/config.yml` (macOS).
42
49
 
43
50
  ### 3. Index your project
@@ -49,55 +56,178 @@ lmgrep index
49
56
 
50
57
  ### 4. Search
51
58
 
59
+ A bare query searches — `search` is the default command:
60
+
52
61
  ```sh
53
- lmgrep search "how are users authenticated"
62
+ lmgrep how are users authenticated
54
63
  lmgrep search "database connection pooling" --limit 5
55
- lmgrep search "error handling" --file-prefix src/lib --language .ts
64
+ lmgrep search "error handling" --under src/lib --language .ts
56
65
  ```
57
66
 
58
67
  ## CLI commands
59
68
 
69
+ Two of these are the product; the rest you run once.
70
+
60
71
  | Command | Description |
61
72
  |---|---|
62
- | `lmgrep index` | Index the current directory |
63
- | `lmgrep search <query>` | Search using natural language |
64
- | `lmgrep status` | Show index stats, embedding connectivity, and running processes |
65
- | `lmgrep serve` | Watch for changes and re-index automatically |
73
+ | `lmgrep <query>` | Search using natural language (`search` is the default command) |
74
+ | `lmgrep ask <question>` | Answer a question with a local research loop (search → read → cited answer) |
75
+ | `lmgrep index` | Index this project, and keep it current |
76
+ | `lmgrep status` | Report whether search works, and why not |
77
+ | `lmgrep projects` | List every index on this machine, and reclaim their space |
78
+ | `lmgrep init` | Detect your local models and write the machine config |
79
+ | `lmgrep config` | Open the machine config in your editor |
66
80
  | `lmgrep mcp` | Start the MCP server (stdio transport) |
67
- | `lmgrep init` | Detect embedding setup and create config |
68
- | `lmgrep config` | Open the global config in your editor |
69
- | `lmgrep repair` | Detect and fix index inconsistencies |
70
- | `lmgrep migrate` | Rename existing index directories to match the current slug scheme |
71
- | `lmgrep compact` | Compact the index to reclaim disk space |
72
- | `lmgrep export` | Share this project's index with a peer via P2P |
73
- | `lmgrep import [source]` | Import from a peer (share code) or local database |
74
- | `lmgrep prune` | Delete the index for the current directory |
81
+ | `lmgrep serve` | Watch this project and re-index as files change |
82
+ | `lmgrep share` | Offer this project's index to a peer over P2P |
83
+ | `lmgrep import <source>` | Import from a peer (share code) or another database (path) |
75
84
  | `lmgrep completions zsh` | Output or install zsh completions |
76
85
 
86
+ There is no `repair`, `compact`, or `migrate`. Reconciling the manifest,
87
+ dropping duplicate rows, compacting fragments and training the vector index all
88
+ happen inside `lmgrep index`, which is the one moment you are already waiting.
89
+ `prune` became `lmgrep projects rm`, which can see what it is deleting.
90
+
77
91
  ### Search options
78
92
 
79
93
  ```
80
- --limit <n> Max results (default: 25)
81
- --file-prefix <path> Only search files under this path
82
- --language <exts> Filter by file extension (e.g. .ts,.py)
83
- --type <types> Filter by AST node type (e.g. function_declaration)
84
- --not <query> Exclude results similar to this query
85
- --scores Show relevance scores
86
- --compact Show file paths only
87
- --json Output as JSON
88
- --project <path> Search a different project's index
89
- --across <paths> Search multiple projects (comma-separated)
94
+ --limit <n> Max results (default: 25)
95
+ --under <path> Only search files under this path
96
+ --language <exts> Only search these extensions (e.g. .ts,.py)
97
+ --compact Print matching file paths only
98
+ --json Print results as JSON
99
+ --in <target> Repeatable: a project directory, or a standalone index name
90
100
  ```
91
101
 
92
102
  ### Index options
93
103
 
94
104
  ```
95
- --reset Rebuild the entire index from scratch
96
- --since <dur> Only re-index files modified within duration (e.g. 10m, 2h, 1d)
97
- --force Force re-embed even if file hash is unchanged
98
- --dry Show what would be indexed without doing it
105
+ --reset Discard the index and rebuild from scratch
106
+ --since <dur> Only consider files modified within duration (e.g. 10m, 2h, 1d)
107
+ --dry Report what would be indexed, and stop
99
108
  --verbose Show file-by-file progress
109
+ --in <target> A project directory, or a standalone index name
110
+ ```
111
+
112
+ ## Ask (research mode)
113
+
114
+ `lmgrep ask` answers a question *about the codebase* instead of returning raw chunks. A local chat model runs a short agentic loop — it searches the index, reads the matching code, and writes a concise answer where every claim is cited as `[n] → file:line`. This is aimed at AI agents: one `ask` call replaces several searches and pages of chunks, so it's far cheaper on the agent's context.
115
+
116
+ It requires a generative `chatModel` in addition to your embedding `model`. On a local runtime (LM Studio, Ollama) it reuses the same provider and `baseURL`, so one extra config line is enough:
117
+
118
+ ```yaml
119
+ # ~/.config/lmgrep/config.yml
120
+ model: lmstudio:text-embedding-nomic-embed-code # embeddings (retrieval)
121
+ chatModel: lmstudio:google/gemma-4-e2b # generation (the research loop)
122
+ ```
123
+
124
+ ```sh
125
+ lmgrep ask "how does the file watcher trigger reindexing"
126
+ lmgrep ask "where are webhooks authenticated and what token format" --json
127
+ ```
128
+
129
+ The answer, its `Sources:` list, and a one-line trace (queries run, steps, time) are printed; the live search trace streams to stderr (silence it with `--quiet`). When configured, `ask` is also exposed as an MCP tool alongside `search`.
130
+
131
+ ```
132
+ --json Print the full result (answer, sources, trace) as JSON
133
+ --quiet Suppress the live research trace on stderr
134
+ --in A project directory, or a standalone index name
135
+ ```
136
+
137
+ Config keys: `chatModel` (required for `ask`), `chatProvider` / `chatBaseURL` (default to the embedding `provider` / `baseURL`), `chatMaxSteps` (default 8), `chatTimeoutMs` (per model call, default 240000).
138
+
139
+ ## The vector index
140
+
141
+ Above a few thousand chunks lmgrep trains an ANN index over the embeddings.
142
+ Without one, every search brute-force scans the whole table: roughly the
143
+ index's own size in peak memory per query, and an order of magnitude more
144
+ latency. `lmgrep status` reports which mode you are in.
145
+
146
+ It is built automatically by `lmgrep index`, and by `lmgrep serve` / the MCP
147
+ server on their first catch-up pass. Training briefly needs several GB, so it
148
+ happens once rather than on every incremental update — and never behind a
149
+ background watcher that has not caught up yet. If `status` reports it missing,
150
+ `lmgrep index` builds it.
151
+
152
+ ## Where the index lives
153
+
154
+ Inside the repository it indexes:
155
+
100
156
  ```
157
+ <repo>/.git/lmgrep/<model>/
158
+ ```
159
+
160
+ Git resolves `.git` to the main checkout even from a linked worktree, so every
161
+ worktree of a repository shares one index automatically — no registry, nothing
162
+ to keep in sync. Git never walks its own directory, so the index is never
163
+ committed and never indexed. And because it is *there*, `du -sh` finds it,
164
+ `rm -rf` removes it, and deleting a clone deletes its index with it.
165
+
166
+ Each embedding model gets its own subdirectory. Changing `model` in your config
167
+ selects a different database rather than invalidating the one you have, so
168
+ trying another model costs one re-index and switching back costs nothing.
169
+
170
+ ### Changing your embedding model
171
+
172
+ The new model has no index yet, so lmgrep says so and names what you already
173
+ have:
174
+
175
+ ```
176
+ $ lmgrep how are webhooks authenticated
177
+ This project has no index for "qwen3-embedding-4b" — but it is indexed with
178
+ "nomic-embed-code".
179
+ Set `model` back to lmstudio:nomic-embed-code to use that index immediately, or
180
+ run `lmgrep index` to embed this project with the new model (the other index is
181
+ kept).
182
+ ```
183
+
184
+ `status` gives the same answer, and `lmgrep index` says what it is about to do
185
+ before it starts — embedding a large repository takes a while, and trying a
186
+ model out should not commit you to it by accident. Both indexes then coexist,
187
+ and `model` decides which one answers.
188
+
189
+ Note that `serve` and the MCP server read configuration once, at startup. A
190
+ server already running keeps using the model it started with — self-consistent,
191
+ but it will disagree with the CLI until you restart it. `lmgrep status
192
+ --verbose` prints the database each running process is holding.
193
+
194
+ Projects outside a git repository, and indexes you name yourself, live under
195
+ `~/.local/state/lmgrep/db/`. Lock files and a small pointer registry live
196
+ beside it — that registry is what `lmgrep projects` and cross-project search
197
+ read, since an index inside a repository cannot be found by listing a
198
+ directory.
199
+
200
+ ### Targeting another index
201
+
202
+ `--in` takes a project directory or the name of a standalone index, and repeats:
203
+
204
+ ```sh
205
+ # A standalone index, for a corpus that is not a repository
206
+ lmgrep index --in notes
207
+ lmgrep search "retry policy" --in notes
208
+
209
+ # Another project
210
+ lmgrep search "retry policy" --in ../other-repo
211
+
212
+ # Several at once; `.` includes the current project
213
+ lmgrep search "retry policy" --in . --in ../other-repo
214
+ ```
215
+
216
+ For write commands the files indexed still come from the current directory;
217
+ only the database identity changes. A standalone index is flat — branch-agnostic,
218
+ so switching git branches never hides results.
219
+
220
+ ### Seeing and reclaiming
221
+
222
+ ```sh
223
+ lmgrep projects # every index, largest first, with its model and size
224
+ lmgrep projects adopt # move a pre-0.2 index into this repository, no re-embed
225
+ lmgrep projects rm # delete this project's index
226
+ lmgrep projects gc # delete indexes whose project no longer exists
227
+ ```
228
+
229
+ `rm` and `gc` refuse to recurse into anything that is not recognizably an
230
+ lmgrep database.
101
231
 
102
232
  ## P2P index sharing
103
233
 
@@ -105,7 +235,7 @@ Share your index with a teammate without any server or infrastructure. Uses [Hyp
105
235
 
106
236
  ```sh
107
237
  # On your machine — start sharing
108
- lmgrep export
238
+ lmgrep share
109
239
  # → Share code: lmgrepoceantiger7f3a
110
240
  # → Waiting for peer...
111
241
 
@@ -164,18 +294,6 @@ gemini mcp add lmgrep -- lmgrep mcp
164
294
  gemini mcp add lmgrep -- npx -y lmgrep mcp
165
295
  ```
166
296
 
167
- ### Pi coding agent
168
-
169
- Pi doesn't speak MCP — it uses TypeScript extensions instead. lmgrep ships one at [`pi-extension/`](./pi-extension) that registers two tools: `lmgrep_search` and `lmgrep_list_other_indexed_projects`. It imports lmgrep directly, runs an in-process file watcher to keep the index fresh, and gates tool visibility on embedder health — if lmgrep isn't configured, or the embedding provider is unreachable, the tools stay hidden so you get a clean tool surface instead of a broken one. Configure lmgrep first (`lmgrep init`) before relying on it inside Pi.
170
-
171
- Install via Pi's package manager:
172
-
173
- ```sh
174
- pi install git:github.com/Aetherall/lmgrep
175
- ```
176
-
177
- Update with `pi update`, remove with `pi remove git:github.com/Aetherall/lmgrep`, and list installed extensions with `pi list`.
178
-
179
297
  ### OpenCode
180
298
 
181
299
  OpenCode has no one-shot install flag — add an entry to `~/.config/opencode/opencode.json` (or project-level `opencode.json`):
@@ -200,13 +318,27 @@ The MCP server exposes a `search` tool and a `list_other_indexed_projects` tool.
200
318
 
201
319
  ## Configuration
202
320
 
203
- lmgrep looks for configuration in this order:
321
+ There are two kinds of setting, split by what they describe.
322
+
323
+ **Machine settings** — which model to embed with, which to answer with, where
324
+ those servers listen — describe this computer. They live in one file:
325
+
326
+ - `~/.config/lmgrep/config.yml` (Linux) or `~/Library/Application Support/lmgrep/config.yml` (macOS)
327
+ - `~/.lmgrep.yml` still works, as a deprecated location
204
328
 
205
- 1. `.lmgrep.yml` in the project root (per-project)
206
- 2. `~/.config/lmgrep/config.yml` (global, Linux) or `~/Library/Application Support/lmgrep/config.yml` (macOS)
207
- 3. `~/.lmgrep.yml` (legacy fallback)
329
+ **Project settings** what to ignore, which extensions to index — describe a
330
+ repository, are worth committing, and go in a `.lmgrep.yml` inside it.
208
331
 
209
- ### Example config
332
+ A machine setting written in a project file is reported and ignored. The model
333
+ decides what a stored vector *means*, so a project file able to change it was
334
+ the single most confusing thing about lmgrep: two files could set `model`, and
335
+ `status` would print the winner without saying which file it came from. If you
336
+ want a different model for one corpus, index it under `--in <name>` — the model
337
+ is a property of an index, not of a directory.
338
+
339
+ `lmgrep status` prints exactly which file supplied which keys.
340
+
341
+ ### Machine config
210
342
 
211
343
  ```yaml
212
344
  # Embedding model in "provider:model" format
@@ -218,7 +350,10 @@ baseURL: http://localhost:11434/v1
218
350
  # Batch size for embedding API calls
219
351
  batchSize: 100
220
352
 
221
- # Optional: embedding dimensions (if model supports it)
353
+ # Generative model for `lmgrep ask`. Optional without it, `ask` is hidden.
354
+ # chatModel: lmstudio:qwen/qwen3.5-9b
355
+
356
+ # Optional: embedding dimensions (if the model supports it)
222
357
  # dimensions: 384
223
358
 
224
359
  # Optional: max tokens per chunk (estimated at 4 chars/token)
@@ -227,16 +362,20 @@ batchSize: 100
227
362
  # Optional: prefixes for asymmetric embedding models
228
363
  # queryPrefix: "search_query: "
229
364
  # documentPrefix: "search_document: "
365
+ ```
230
366
 
231
- # Optional: additional ignore patterns (merged with .gitignore)
232
- # ignore:
233
- # - "*.generated.ts"
234
- # - "fixtures/"
367
+ ### Project config `.lmgrep.yml`
235
368
 
236
- # Optional: file extension control
237
- # extensions:
238
- # include: [".sql", ".graphql", ".proto"]
239
- # exclude: [".json"]
369
+ ```yaml
370
+ # Additional ignore patterns (merged with .gitignore)
371
+ ignore:
372
+ - "*.generated.ts"
373
+ - "fixtures/"
374
+
375
+ # File extension control
376
+ extensions:
377
+ include: [".sql", ".graphql", ".proto"]
378
+ exclude: [".json"]
240
379
  ```
241
380
 
242
381
  ### Using other providers
@@ -262,6 +401,30 @@ pnpm dev # watch mode
262
401
  pnpm check # format and lint (Biome)
263
402
  ```
264
403
 
404
+ ### Architecture
405
+
406
+ The source is layered, with dependencies pointing inward only:
407
+
408
+ ```
409
+ src/
410
+ domain/ entities, value objects, and the port interfaces
411
+ application/ use cases that orchestrate the domain
412
+ infrastructure/ adapters: LanceDB, filesystem, git, AI SDK, tree-sitter, p2p
413
+ presentation/ the CLI and the MCP server
414
+ ```
415
+
416
+ `domain/` knows nothing outside itself. `application/` depends on domain ports,
417
+ never on a concrete adapter. `LmgrepFactory` is the single place that wires the
418
+ graph together, so no entry point needs to know the assembly order.
419
+
420
+ ### Conventions
421
+
422
+ - **No free functions.** Behaviour lives on the type that owns it. Constant
423
+ tables and pure helpers land as static-only classes, which is why Biome's
424
+ `noStaticOnlyClass` rule is disabled — the shape is intended here.
425
+ - **Comments explain why, not what.** A measured constant records what the
426
+ measurement was; a non-obvious ordering records what breaks if it changes.
427
+
265
428
  ## License
266
429
 
267
430
  GPL-3.0
@@ -1,19 +1,23 @@
1
1
  #compdef lmgrep
2
2
 
3
+ # Regenerate by hand when commands change; `lmgrep completions zsh` prints this
4
+ # file verbatim.
5
+
3
6
  _lmgrep() {
4
7
  local -a commands
5
8
  commands=(
6
- 'index:Index the current directory for semantic search'
7
9
  'search:Search the codebase using natural language'
8
- 'status:Show index stats and check embedding connectivity'
9
- 'repair:Detect and fix index inconsistencies'
10
- 'serve:Watch the current directory and re-index on changes'
11
- 'init:Detect your embedding setup and create config'
12
- 'config:Open the global config file in your editor'
13
- 'compact:Compact the index to reclaim disk space'
14
- 'prune:Delete the index database for the current directory'
15
- 'import:Import chunks and file hashes from another lmgrep database'
10
+ 'ask:Answer a question with a local research loop'
11
+ 'index:Index this project for semantic search'
12
+ 'status:Report whether search works, and why not'
13
+ 'projects:List indexes on this machine, and reclaim their space'
14
+ 'init:Detect your local models and write the machine config'
15
+ 'config:Open the machine config in your editor'
16
+ 'mcp:Start the MCP server (stdio transport)'
16
17
  'completions:Output shell completions'
18
+ 'serve:Watch this project and re-index as files change'
19
+ 'share:Offer this project index to a peer over P2P'
20
+ 'import:Import chunks from a peer or another lmgrep database'
17
21
  )
18
22
 
19
23
  _arguments -C \
@@ -30,55 +34,60 @@ _lmgrep() {
30
34
  case "$words[1]" in
31
35
  index)
32
36
  _arguments \
33
- '(-r --reset)'{-r,--reset}'[Reset and rebuild the entire index]' \
37
+ '(-r --reset)'{-r,--reset}'[Discard the index and rebuild from scratch]' \
34
38
  '(-v --verbose)'{-v,--verbose}'[Show file-by-file progress]' \
35
39
  '(-s --since)'{-s,--since}'[Only consider files modified within duration]:duration' \
36
- '(-f --force)'{-f,--force}'[Force re-embed even if file hash unchanged]' \
37
- '(-d --dry)'{-d,--dry}'[Show what would be indexed without actually doing it]'
40
+ '(-d --dry)'{-d,--dry}'[Report what would be indexed, and stop]' \
41
+ '*--in[Project directory, or the name of a standalone index]:project or name:_files -/'
38
42
  ;;
39
43
  search)
40
44
  _arguments \
41
- '1:query' \
42
- '(-m --limit)'{-m,--limit}'[Max results]:number' \
43
- '--scores[Show relevance scores]' \
44
- '--compact[Show file paths only]' \
45
- '--json[Output results as JSON]' \
46
- '--min-score[Minimum score threshold]:score' \
47
- '--file-prefix[Only search files matching this path prefix]:prefix:_files -/' \
48
- '--not[Exclude results similar to this query]:query' \
49
- '--type[Only return chunks of these AST types]:types' \
50
- '--language[Only return chunks from files with these extensions]:extensions' \
51
- '--project[Search a different project index]:path:_files -/' \
52
- '--across[Search multiple project indexes]:paths'
45
+ '(-m --limit)'{-m,--limit}'[Max results]:count' \
46
+ '--under[Only search files under this path]:path:_files -/' \
47
+ '--language[Only search these file extensions]:extensions' \
48
+ '--compact[Print matching file paths only]' \
49
+ '--json[Print results as JSON]' \
50
+ '*--in[Project directory, or the name of a standalone index]:project or name:_files -/'
53
51
  ;;
54
- status)
52
+ ask)
55
53
  _arguments \
56
- '(-c --changes)'{-c,--changes}'[Scan for changed files since last index]' \
57
- '--json[Output status as JSON]'
54
+ '--json[Print the full result as JSON]' \
55
+ '--quiet[Suppress the live research trace on stderr]' \
56
+ '*--in[Project directory, or the name of a standalone index]:project or name:_files -/'
58
57
  ;;
59
- repair)
58
+ status)
60
59
  _arguments \
61
- '(-d --dry)'{-d,--dry}'[Show what would be repaired without making changes]' \
62
- '--json[Output repair results as JSON]'
60
+ '(-v --verbose)'{-v,--verbose}'[Also show index statistics and probes]' \
61
+ '(-c --changes)'{-c,--changes}'[Scan for files changed since the last index]' \
62
+ '--json[Print status as JSON]' \
63
+ '*--in[Project directory, or the name of a standalone index]:project or name:_files -/'
64
+ ;;
65
+ projects)
66
+ local -a subcommands
67
+ subcommands=(
68
+ 'list:Show every index, largest first'
69
+ 'adopt:Move this project index from the state directory into the repository'
70
+ 'rm:Delete an index'
71
+ 'gc:Delete indexes whose project no longer exists'
72
+ )
73
+ _describe 'subcommand' subcommands
63
74
  ;;
64
75
  init)
65
- _arguments \
66
- '--force[Overwrite existing config]' \
67
- '--local[Write a project-local .lmgrep.yml instead of the global config]'
76
+ _arguments '--force[Overwrite the existing config]'
68
77
  ;;
69
- prune)
78
+ serve|mcp)
70
79
  _arguments \
71
- '--force[Skip confirmation]'
80
+ '*--in[Project directory, or the name of a standalone index]:project or name:_files -/'
72
81
  ;;
73
82
  import)
74
83
  _arguments \
75
- '1:database path:_files' \
76
- '--reset[Reset the current index before importing]'
84
+ '--reset[Reset the current index before importing]' \
85
+ '1:share code or database path:_files -/'
77
86
  ;;
78
87
  completions)
79
- _arguments \
80
- '1:shell:(zsh)' \
81
- '--install[Install to site-functions]'
88
+ local -a shells
89
+ shells=('zsh:Output zsh completions')
90
+ _describe 'shell' shells
82
91
  ;;
83
92
  esac
84
93
  ;;
@@ -0,0 +1,107 @@
1
+ import type { LmgrepConfig } from "../domain/config/LmgrepConfig.js";
2
+ import type { FileManifest } from "../domain/corpus/SourceFile.js";
3
+ import type { ChunkerPort } from "../domain/ports/ChunkerPort.js";
4
+ import type { ChunkRepositoryPort } from "../domain/ports/ChunkRepositoryPort.js";
5
+ import type { DatabaseSessionPort } from "../domain/ports/DatabaseSessionPort.js";
6
+ import type { EmbedderPort } from "../domain/ports/EmbedderPort.js";
7
+ import type { FileManifestRepositoryPort } from "../domain/ports/FileManifestRepositoryPort.js";
8
+ import type { DedupeReport, IndexMaintenancePort, OptimizeReport } from "../domain/ports/IndexMaintenancePort.js";
9
+ import type { IndexMetadataPort } from "../domain/ports/IndexMetadataPort.js";
10
+ import type { LoggerPort } from "../domain/ports/LoggerPort.js";
11
+ import type { ProjectRegistryPort } from "../domain/ports/ProjectRegistryPort.js";
12
+ import type { DatabaseLocation } from "../domain/project/DatabaseLocation.js";
13
+ import type { ProjectId } from "../domain/project/ProjectId.js";
14
+ import type { ProjectLocator } from "../domain/project/ProjectLocator.js";
15
+ import type { TraceEntry } from "../domain/research/ResearchTrace.js";
16
+ import type { HitList } from "../domain/retrieval/HitList.js";
17
+ import type { BranchManifestSweeper } from "./indexing/BranchManifestSweeper.js";
18
+ import type { IndexBuilder } from "./indexing/IndexBuilder.js";
19
+ import type { IndexBuildOptions, IndexBuildResult } from "./indexing/IndexingProgress.js";
20
+ import type { IndexAlternatives } from "./operations/IndexAlternatives.js";
21
+ import type { StatusInfo, StatusService } from "./operations/StatusService.js";
22
+ import type { WatchService } from "./operations/WatchService.js";
23
+ import type { ResearchAgent, ResearchResult } from "./research/ResearchAgent.js";
24
+ import { type SearchOptions } from "./search/SearchCriteria.js";
25
+ import type { SearchService } from "./search/SearchService.js";
26
+ /** What a maintenance pass changed. */
27
+ export interface TidyReport {
28
+ deduped: DedupeReport;
29
+ optimized: OptimizeReport;
30
+ }
31
+ /** Everything an Lmgrep instance owns, assembled by the composition root. */
32
+ export interface LmgrepServices {
33
+ cwd: string;
34
+ config: LmgrepConfig;
35
+ location: DatabaseLocation;
36
+ locator: ProjectLocator;
37
+ logger: LoggerPort;
38
+ tables: DatabaseSessionPort;
39
+ chunks: ChunkRepositoryPort;
40
+ manifest: FileManifestRepositoryPort;
41
+ maintenance: IndexMaintenancePort;
42
+ metadata: IndexMetadataPort;
43
+ registry: ProjectRegistryPort;
44
+ alternatives: IndexAlternatives;
45
+ embedder: EmbedderPort;
46
+ chunker: ChunkerPort;
47
+ builder: IndexBuilder;
48
+ sweeper: BranchManifestSweeper;
49
+ searcher: SearchService;
50
+ statusReporter: StatusService;
51
+ watcher: WatchService;
52
+ researcher: ResearchAgent;
53
+ projectId: () => ProjectId;
54
+ }
55
+ /**
56
+ * The application façade: one object exposing every operation the CLI, the MCP
57
+ * server and the Pi extension need.
58
+ *
59
+ * It holds no logic of its own — each method delegates to the service that
60
+ * owns that behaviour. Its job is to be the single place where a caller
61
+ * acquires a working, wired-up lmgrep, so no entry point has to know the
62
+ * assembly order.
63
+ */
64
+ export declare class Lmgrep {
65
+ private readonly services;
66
+ constructor(services: LmgrepServices);
67
+ get cwd(): string;
68
+ get config(): LmgrepConfig;
69
+ get location(): DatabaseLocation;
70
+ build(options?: IndexBuildOptions): Promise<IndexBuildResult>;
71
+ search(query: string, options?: SearchOptions): Promise<HitList>;
72
+ ask(question: string, onTrace?: (entry: TraceEntry) => void): Promise<ResearchResult>;
73
+ status(): Promise<StatusInfo>;
74
+ /** Start watching; returns a function that stops it. */
75
+ watch(): () => void;
76
+ /** The current branch's file manifest, for change previews. */
77
+ currentManifest(): Promise<FileManifest>;
78
+ /**
79
+ * Everything the index needs done to it that is not indexing: drop dead
80
+ * branches' manifests, remove duplicate and superseded rows, compact the
81
+ * fragments, and train the vector index if the table has grown into
82
+ * wanting one.
83
+ *
84
+ * These were three separate commands. They are one call because they are
85
+ * one intent and because the order between them is not optional: `dedupe`
86
+ * keeps any chunk version some manifest still references, so sweeping dead
87
+ * branches has to happen first or their leftover rows shield their own
88
+ * orphaned chunks from collection.
89
+ */
90
+ tidy(): Promise<TidyReport>;
91
+ get maintenance(): IndexMaintenancePort;
92
+ /** Every index this machine knows about. */
93
+ get registry(): ProjectRegistryPort;
94
+ /** This project's indexes under other embedding models. */
95
+ get alternatives(): IndexAlternatives;
96
+ get projectId(): ProjectId;
97
+ /**
98
+ * Whether this working directory has a usable index.
99
+ *
100
+ * An indexed ancestor counts: running from a subdirectory of an indexed
101
+ * tree is ordinary, and reporting it as unindexed would disable search for
102
+ * no reason. A manually targeted database is flat, so only its own path
103
+ * matters.
104
+ */
105
+ isIndexed(): boolean;
106
+ close(): Promise<void>;
107
+ }