lmgrep 0.1.18 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (414) hide show
  1. package/README.md +253 -62
  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 +4 -953
  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 +94 -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 -45
  178. package/dist/index.js +30 -567
  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/DockerModelRunnerProbe.d.ts +16 -0
  187. package/dist/infrastructure/ai/DockerModelRunnerProbe.js +52 -0
  188. package/dist/infrastructure/ai/DockerModelRunnerProbe.js.map +1 -0
  189. package/dist/infrastructure/ai/EmbeddingPrefixes.d.ts +21 -0
  190. package/dist/infrastructure/ai/EmbeddingPrefixes.js +40 -0
  191. package/dist/infrastructure/ai/EmbeddingPrefixes.js.map +1 -0
  192. package/dist/infrastructure/ai/LmStudioProbe.d.ts +18 -0
  193. package/dist/infrastructure/ai/LmStudioProbe.js +49 -0
  194. package/dist/infrastructure/ai/LmStudioProbe.js.map +1 -0
  195. package/dist/infrastructure/ai/LocalModelReloader.d.ts +21 -0
  196. package/dist/infrastructure/ai/LocalModelReloader.js +61 -0
  197. package/dist/infrastructure/ai/LocalModelReloader.js.map +1 -0
  198. package/dist/infrastructure/ai/LocalRuntimeDetector.d.ts +36 -0
  199. package/dist/infrastructure/ai/LocalRuntimeDetector.js +63 -0
  200. package/dist/infrastructure/ai/LocalRuntimeDetector.js.map +1 -0
  201. package/dist/infrastructure/ai/ModelRuntime.d.ts +32 -0
  202. package/dist/infrastructure/ai/ModelRuntime.js +2 -0
  203. package/dist/infrastructure/ai/ModelRuntime.js.map +1 -0
  204. package/dist/infrastructure/ai/OllamaProbe.d.ts +22 -0
  205. package/dist/infrastructure/ai/OllamaProbe.js +71 -0
  206. package/dist/infrastructure/ai/OllamaProbe.js.map +1 -0
  207. package/dist/infrastructure/ai/ProviderFailure.d.ts +16 -0
  208. package/dist/infrastructure/ai/ProviderFailure.js +35 -0
  209. package/dist/infrastructure/ai/ProviderFailure.js.map +1 -0
  210. package/dist/infrastructure/ai/ProviderModuleLoader.d.ts +14 -0
  211. package/dist/infrastructure/ai/ProviderModuleLoader.js +56 -0
  212. package/dist/infrastructure/ai/ProviderModuleLoader.js.map +1 -0
  213. package/dist/infrastructure/ai/ProviderRegistry.d.ts +38 -0
  214. package/dist/infrastructure/ai/ProviderRegistry.js +63 -0
  215. package/dist/infrastructure/ai/ProviderRegistry.js.map +1 -0
  216. package/dist/infrastructure/fs/ConfigLoader.d.ts +59 -0
  217. package/dist/infrastructure/fs/ConfigLoader.js +194 -0
  218. package/dist/infrastructure/fs/ConfigLoader.js.map +1 -0
  219. package/dist/infrastructure/fs/DatabaseLocks.d.ts +52 -0
  220. package/dist/infrastructure/fs/DatabaseLocks.js +92 -0
  221. package/dist/infrastructure/fs/DatabaseLocks.js.map +1 -0
  222. package/dist/infrastructure/fs/DiskUsage.d.ts +6 -0
  223. package/dist/infrastructure/fs/DiskUsage.js +41 -0
  224. package/dist/infrastructure/fs/DiskUsage.js.map +1 -0
  225. package/dist/infrastructure/fs/IndexableFileRules.d.ts +33 -0
  226. package/dist/infrastructure/fs/IndexableFileRules.js +177 -0
  227. package/dist/infrastructure/fs/IndexableFileRules.js.map +1 -0
  228. package/dist/infrastructure/fs/Loggers.d.ts +14 -0
  229. package/dist/infrastructure/fs/Loggers.js +18 -0
  230. package/dist/infrastructure/fs/Loggers.js.map +1 -0
  231. package/dist/infrastructure/fs/PidFileLock.d.ts +40 -0
  232. package/dist/infrastructure/fs/PidFileLock.js +97 -0
  233. package/dist/infrastructure/fs/PidFileLock.js.map +1 -0
  234. package/dist/infrastructure/fs/ProjectIndexes.d.ts +8 -0
  235. package/dist/infrastructure/fs/ProjectIndexes.js +35 -0
  236. package/dist/infrastructure/fs/ProjectIndexes.js.map +1 -0
  237. package/dist/infrastructure/fs/ProjectMetadataStore.d.ts +42 -0
  238. package/dist/infrastructure/fs/ProjectMetadataStore.js +86 -0
  239. package/dist/infrastructure/fs/ProjectMetadataStore.js.map +1 -0
  240. package/dist/infrastructure/fs/ProjectRegistry.d.ts +25 -0
  241. package/dist/infrastructure/fs/ProjectRegistry.js +83 -0
  242. package/dist/infrastructure/fs/ProjectRegistry.js.map +1 -0
  243. package/dist/infrastructure/fs/StateDirectory.d.ts +28 -0
  244. package/dist/infrastructure/fs/StateDirectory.js +71 -0
  245. package/dist/infrastructure/fs/StateDirectory.js.map +1 -0
  246. package/dist/infrastructure/fs/Workspace.d.ts +25 -0
  247. package/dist/infrastructure/fs/Workspace.js +90 -0
  248. package/dist/infrastructure/fs/Workspace.js.map +1 -0
  249. package/dist/infrastructure/git/GitClient.d.ts +34 -0
  250. package/dist/infrastructure/git/GitClient.js +74 -0
  251. package/dist/infrastructure/git/GitClient.js.map +1 -0
  252. package/dist/infrastructure/lancedb/ChunkRepository.d.ts +38 -0
  253. package/dist/infrastructure/lancedb/ChunkRepository.js +166 -0
  254. package/dist/infrastructure/lancedb/ChunkRepository.js.map +1 -0
  255. package/dist/infrastructure/lancedb/DatabaseImporter.d.ts +22 -0
  256. package/dist/infrastructure/lancedb/DatabaseImporter.js +74 -0
  257. package/dist/infrastructure/lancedb/DatabaseImporter.js.map +1 -0
  258. package/dist/infrastructure/lancedb/FileManifestRepository.d.ts +34 -0
  259. package/dist/infrastructure/lancedb/FileManifestRepository.js +137 -0
  260. package/dist/infrastructure/lancedb/FileManifestRepository.js.map +1 -0
  261. package/dist/infrastructure/lancedb/IndexMaintenance.d.ts +53 -0
  262. package/dist/infrastructure/lancedb/IndexMaintenance.js +227 -0
  263. package/dist/infrastructure/lancedb/IndexMaintenance.js.map +1 -0
  264. package/dist/infrastructure/lancedb/LanceTables.d.ts +67 -0
  265. package/dist/infrastructure/lancedb/LanceTables.js +159 -0
  266. package/dist/infrastructure/lancedb/LanceTables.js.map +1 -0
  267. package/dist/{lib/native-tuning.js → infrastructure/lancedb/NativeTuning.js} +1 -1
  268. package/dist/infrastructure/lancedb/NativeTuning.js.map +1 -0
  269. package/dist/infrastructure/lancedb/RowReplication.d.ts +27 -0
  270. package/dist/infrastructure/lancedb/RowReplication.js +82 -0
  271. package/dist/infrastructure/lancedb/RowReplication.js.map +1 -0
  272. package/dist/infrastructure/lancedb/VectorIndexPolicy.d.ts +60 -0
  273. package/dist/infrastructure/lancedb/VectorIndexPolicy.js +72 -0
  274. package/dist/infrastructure/lancedb/VectorIndexPolicy.js.map +1 -0
  275. package/dist/infrastructure/p2p/IndexShare.d.ts +45 -0
  276. package/dist/infrastructure/p2p/IndexShare.js +160 -0
  277. package/dist/infrastructure/p2p/IndexShare.js.map +1 -0
  278. package/dist/infrastructure/p2p/PeerSwarm.d.ts +16 -0
  279. package/dist/infrastructure/p2p/PeerSwarm.js +41 -0
  280. package/dist/infrastructure/p2p/PeerSwarm.js.map +1 -0
  281. package/dist/infrastructure/p2p/SecureChannel.d.ts +60 -0
  282. package/dist/infrastructure/p2p/SecureChannel.js +71 -0
  283. package/dist/infrastructure/p2p/SecureChannel.js.map +1 -0
  284. package/dist/infrastructure/p2p/ShareCode.d.ts +25 -0
  285. package/dist/infrastructure/p2p/ShareCode.js +304 -0
  286. package/dist/infrastructure/p2p/ShareCode.js.map +1 -0
  287. package/dist/infrastructure/process/ProcessRegistry.d.ts +50 -0
  288. package/dist/infrastructure/process/ProcessRegistry.js +109 -0
  289. package/dist/infrastructure/process/ProcessRegistry.js.map +1 -0
  290. package/dist/infrastructure/treesitter/ChunkContextBuilder.d.ts +45 -0
  291. package/dist/infrastructure/treesitter/ChunkContextBuilder.js +159 -0
  292. package/dist/infrastructure/treesitter/ChunkContextBuilder.js.map +1 -0
  293. package/dist/infrastructure/treesitter/EmbeddedTreeSitterAssets.d.ts +8 -0
  294. package/dist/infrastructure/treesitter/EmbeddedTreeSitterAssets.js +12 -0
  295. package/dist/infrastructure/treesitter/EmbeddedTreeSitterAssets.js.map +1 -0
  296. package/dist/infrastructure/treesitter/LanguageCatalog.d.ts +30 -0
  297. package/dist/{lib/chunker/languages.js → infrastructure/treesitter/LanguageCatalog.js} +38 -29
  298. package/dist/infrastructure/treesitter/LanguageCatalog.js.map +1 -0
  299. package/dist/infrastructure/treesitter/SlidingWindowChunker.d.ts +15 -0
  300. package/dist/infrastructure/treesitter/SlidingWindowChunker.js +42 -0
  301. package/dist/infrastructure/treesitter/SlidingWindowChunker.js.map +1 -0
  302. package/dist/infrastructure/treesitter/TreeSitterChunker.d.ts +42 -0
  303. package/dist/infrastructure/treesitter/TreeSitterChunker.js +165 -0
  304. package/dist/infrastructure/treesitter/TreeSitterChunker.js.map +1 -0
  305. package/dist/mcp.d.ts +1 -1
  306. package/dist/mcp.js +14 -72
  307. package/dist/mcp.js.map +1 -1
  308. package/dist/presentation/cli/Cli.d.ts +31 -0
  309. package/dist/presentation/cli/Cli.js +120 -0
  310. package/dist/presentation/cli/Cli.js.map +1 -0
  311. package/dist/presentation/cli/CliOptions.d.ts +18 -0
  312. package/dist/presentation/cli/CliOptions.js +25 -0
  313. package/dist/presentation/cli/CliOptions.js.map +1 -0
  314. package/dist/presentation/cli/CommandContext.d.ts +50 -0
  315. package/dist/presentation/cli/CommandContext.js +88 -0
  316. package/dist/presentation/cli/CommandContext.js.map +1 -0
  317. package/dist/presentation/cli/ConfigTemplate.d.ts +31 -0
  318. package/dist/presentation/cli/ConfigTemplate.js +83 -0
  319. package/dist/presentation/cli/ConfigTemplate.js.map +1 -0
  320. package/dist/presentation/cli/Renderer.d.ts +90 -0
  321. package/dist/presentation/cli/Renderer.js +290 -0
  322. package/dist/presentation/cli/Renderer.js.map +1 -0
  323. package/dist/presentation/cli/commands/AskCommand.d.ts +14 -0
  324. package/dist/presentation/cli/commands/AskCommand.js +48 -0
  325. package/dist/presentation/cli/commands/AskCommand.js.map +1 -0
  326. package/dist/presentation/cli/commands/CompletionsCommand.d.ts +18 -0
  327. package/dist/presentation/cli/commands/CompletionsCommand.js +96 -0
  328. package/dist/presentation/cli/commands/CompletionsCommand.js.map +1 -0
  329. package/dist/presentation/cli/commands/ConfigCommands.d.ts +56 -0
  330. package/dist/presentation/cli/commands/ConfigCommands.js +220 -0
  331. package/dist/presentation/cli/commands/ConfigCommands.js.map +1 -0
  332. package/dist/presentation/cli/commands/IndexCommand.d.ts +18 -0
  333. package/dist/presentation/cli/commands/IndexCommand.js +54 -0
  334. package/dist/presentation/cli/commands/IndexCommand.js.map +1 -0
  335. package/dist/presentation/cli/commands/ProjectsCommand.d.ts +48 -0
  336. package/dist/presentation/cli/commands/ProjectsCommand.js +240 -0
  337. package/dist/presentation/cli/commands/ProjectsCommand.js.map +1 -0
  338. package/dist/presentation/cli/commands/SearchCommand.d.ts +19 -0
  339. package/dist/presentation/cli/commands/SearchCommand.js +55 -0
  340. package/dist/presentation/cli/commands/SearchCommand.js.map +1 -0
  341. package/dist/presentation/cli/commands/ServerCommands.d.ts +13 -0
  342. package/dist/presentation/cli/commands/ServerCommands.js +40 -0
  343. package/dist/presentation/cli/commands/ServerCommands.js.map +1 -0
  344. package/dist/presentation/cli/commands/ShareCommands.d.ts +22 -0
  345. package/dist/presentation/cli/commands/ShareCommands.js +134 -0
  346. package/dist/presentation/cli/commands/ShareCommands.js.map +1 -0
  347. package/dist/presentation/cli/commands/StatusCommand.d.ts +15 -0
  348. package/dist/presentation/cli/commands/StatusCommand.js +53 -0
  349. package/dist/presentation/cli/commands/StatusCommand.js.map +1 -0
  350. package/dist/presentation/mcp/HitFormatter.d.ts +17 -0
  351. package/dist/presentation/mcp/HitFormatter.js +42 -0
  352. package/dist/presentation/mcp/HitFormatter.js.map +1 -0
  353. package/dist/presentation/mcp/IndexWatchController.d.ts +17 -0
  354. package/dist/presentation/mcp/IndexWatchController.js +31 -0
  355. package/dist/presentation/mcp/IndexWatchController.js.map +1 -0
  356. package/dist/presentation/mcp/LmgrepCore.d.ts +66 -0
  357. package/dist/presentation/mcp/LmgrepCore.js +178 -0
  358. package/dist/presentation/mcp/LmgrepCore.js.map +1 -0
  359. package/dist/presentation/mcp/McpServer.d.ts +18 -0
  360. package/dist/presentation/mcp/McpServer.js +63 -0
  361. package/dist/presentation/mcp/McpServer.js.map +1 -0
  362. package/dist/presentation/mcp/ToolDescriptions.d.ts +40 -0
  363. package/dist/presentation/mcp/ToolDescriptions.js +85 -0
  364. package/dist/presentation/mcp/ToolDescriptions.js.map +1 -0
  365. package/package.json +93 -89
  366. package/dist/lib/build.d.ts +0 -21
  367. package/dist/lib/build.js +0 -374
  368. package/dist/lib/build.js.map +0 -1
  369. package/dist/lib/chunker/context.d.ts +0 -21
  370. package/dist/lib/chunker/context.js +0 -131
  371. package/dist/lib/chunker/context.js.map +0 -1
  372. package/dist/lib/chunker/index.d.ts +0 -7
  373. package/dist/lib/chunker/index.js +0 -209
  374. package/dist/lib/chunker/index.js.map +0 -1
  375. package/dist/lib/chunker/languages.d.ts +0 -15
  376. package/dist/lib/chunker/languages.js.map +0 -1
  377. package/dist/lib/config.d.ts +0 -12
  378. package/dist/lib/config.js +0 -83
  379. package/dist/lib/config.js.map +0 -1
  380. package/dist/lib/embedder.d.ts +0 -65
  381. package/dist/lib/embedder.js +0 -236
  382. package/dist/lib/embedder.js.map +0 -1
  383. package/dist/lib/facet-session.d.ts +0 -44
  384. package/dist/lib/facet-session.js +0 -125
  385. package/dist/lib/facet-session.js.map +0 -1
  386. package/dist/lib/native-tuning.js.map +0 -1
  387. package/dist/lib/p2p.d.ts +0 -32
  388. package/dist/lib/p2p.js +0 -281
  389. package/dist/lib/p2p.js.map +0 -1
  390. package/dist/lib/providers.d.ts +0 -1
  391. package/dist/lib/providers.js +0 -41
  392. package/dist/lib/providers.js.map +0 -1
  393. package/dist/lib/repair.d.ts +0 -10
  394. package/dist/lib/repair.js +0 -57
  395. package/dist/lib/repair.js.map +0 -1
  396. package/dist/lib/scanner.d.ts +0 -34
  397. package/dist/lib/scanner.js +0 -242
  398. package/dist/lib/scanner.js.map +0 -1
  399. package/dist/lib/search-tool.d.ts +0 -55
  400. package/dist/lib/search-tool.js +0 -319
  401. package/dist/lib/search-tool.js.map +0 -1
  402. package/dist/lib/serve.d.ts +0 -11
  403. package/dist/lib/serve.js +0 -144
  404. package/dist/lib/serve.js.map +0 -1
  405. package/dist/lib/store.d.ts +0 -252
  406. package/dist/lib/store.js +0 -1216
  407. package/dist/lib/store.js.map +0 -1
  408. package/dist/lib/types.d.ts +0 -194
  409. package/dist/lib/types.js +0 -13
  410. package/dist/lib/types.js.map +0 -1
  411. package/dist/lib/vocab.d.ts +0 -20
  412. package/dist/lib/vocab.js +0 -275
  413. package/dist/lib/vocab.js.map +0 -1
  414. /package/dist/{lib/native-tuning.d.ts → infrastructure/lancedb/NativeTuning.d.ts} +0 -0
@@ -0,0 +1,171 @@
1
+ import { Deadline } from "./Deadline.js";
2
+ /**
3
+ * Reports what the index holds and whether it actually works.
4
+ *
5
+ * The two liveness checks are deliberately shallow and time-boxed: `status`
6
+ * must stay responsive even when the embedder is wedged, since diagnosing that
7
+ * is exactly why someone runs it.
8
+ */
9
+ export class StatusService {
10
+ chunks;
11
+ maintenance;
12
+ embedder;
13
+ locator;
14
+ metadata;
15
+ location;
16
+ config;
17
+ cwd;
18
+ configSources;
19
+ alternatives;
20
+ static PROBE_TIMEOUT_MS = 3000;
21
+ /** A word generic enough to match something in any codebase. */
22
+ static SMOKE_QUERY = "code";
23
+ constructor(chunks, maintenance, embedder, locator, metadata, location, config, cwd, configSources, alternatives) {
24
+ this.chunks = chunks;
25
+ this.maintenance = maintenance;
26
+ this.embedder = embedder;
27
+ this.locator = locator;
28
+ this.metadata = metadata;
29
+ this.location = location;
30
+ this.config = config;
31
+ this.cwd = cwd;
32
+ this.configSources = configSources;
33
+ this.alternatives = alternatives;
34
+ }
35
+ async status() {
36
+ // A manually targeted database is flat — no ancestor or prefix walking.
37
+ const ancestor = this.location.isGitAware
38
+ ? this.locator.findIndexedAncestor(this.cwd)
39
+ : undefined;
40
+ const projectRoot = this.location.manual
41
+ ? this.location.root
42
+ : (ancestor?.root ?? this.cwd);
43
+ const filesByPath = await this.chunks.hashesByFile();
44
+ const hashes = await this.chunks.allHashes();
45
+ let chunkCount = 0;
46
+ for (const [, list] of filesByPath)
47
+ chunkCount += list.length;
48
+ const probe = await this.probe(filesByPath.size > 0);
49
+ const meta = this.metadata.read(this.location.manual
50
+ ? this.location.path
51
+ : this.locator.databasePathFor(projectRoot));
52
+ const vectorIndex = await this.maintenance.vectorIndexState();
53
+ const info = {
54
+ projectRoot,
55
+ prefix: ancestor?.prefix ?? "",
56
+ databasePath: this.location.path,
57
+ config: this.config,
58
+ configSources: this.configSources,
59
+ fileCount: filesByPath.size,
60
+ chunkCount,
61
+ uniqueHashes: hashes.size,
62
+ ...probe,
63
+ vectorIndex,
64
+ indexModel: meta?.model,
65
+ indexDimensions: meta?.dimensions,
66
+ };
67
+ return { ...info, verdict: this.judge(info) };
68
+ }
69
+ /**
70
+ * Reduce the probes to one answer, in the order a user would care.
71
+ *
72
+ * A missing vector index is a note rather than a failure: search works, it
73
+ * is just answering by reading every embedding, which nothing else would
74
+ * tell you.
75
+ */
76
+ judge(info) {
77
+ if (info.fileCount === 0) {
78
+ // An empty database for the configured model usually means the
79
+ // model changed, not that the project was never indexed.
80
+ const absence = this.alternatives.explainAbsence();
81
+ return absence
82
+ ? { searchable: false, reason: absence.reason, fix: absence.fix }
83
+ : {
84
+ searchable: false,
85
+ reason: "This project is not indexed.",
86
+ fix: "lmgrep index",
87
+ };
88
+ }
89
+ if (!info.embeddingOk) {
90
+ return {
91
+ searchable: false,
92
+ reason: `The embedding provider is unreachable — ${info.embeddingError ?? "no response"}`,
93
+ fix: `Start the server at ${this.config.baseURL ?? "your configured baseURL"}, then retry.`,
94
+ };
95
+ }
96
+ if (!info.searchOk) {
97
+ // Manifests are per branch while chunks are shared by content, so
98
+ // a checkout that has never been indexed searches an empty scope
99
+ // over a full database. That is an ordinary state on a new
100
+ // worktree or branch, and telling someone to `--reset` over it
101
+ // would throw away a working index for no reason.
102
+ return info.anyBranchOk
103
+ ? {
104
+ searchable: false,
105
+ reason: "This branch has not been indexed yet.",
106
+ fix: "lmgrep index",
107
+ }
108
+ : {
109
+ searchable: false,
110
+ reason: "The index holds files but answered a test query with nothing — it is likely stale or was built with a different model.",
111
+ fix: "lmgrep index --reset",
112
+ };
113
+ }
114
+ if (!info.vectorIndex.built && info.vectorIndex.worthBuilding) {
115
+ return {
116
+ searchable: true,
117
+ note: `Every search reads all ${info.vectorIndex.rows} embeddings — slow, and roughly the ` +
118
+ "index's size in memory per query. `lmgrep index` builds the vector index.",
119
+ };
120
+ }
121
+ return { searchable: true };
122
+ }
123
+ /**
124
+ * Embed once and reuse the vector for the search check — one roundtrip
125
+ * covers both, which keeps `status` cheap against a billed provider.
126
+ */
127
+ async probe(hasFiles) {
128
+ const deadline = Deadline.after(StatusService.PROBE_TIMEOUT_MS);
129
+ let vector;
130
+ let embeddingLatencyMs;
131
+ try {
132
+ const started = Date.now();
133
+ vector = await deadline.enforce(this.embedder.embedQuery(StatusService.SMOKE_QUERY));
134
+ embeddingLatencyMs = Date.now() - started;
135
+ }
136
+ catch (err) {
137
+ return {
138
+ embeddingOk: false,
139
+ searchOk: false,
140
+ embeddingError: err instanceof Error ? err.message : String(err),
141
+ };
142
+ }
143
+ if (!hasFiles) {
144
+ return { embeddingOk: true, embeddingLatencyMs, searchOk: false };
145
+ }
146
+ try {
147
+ const started = Date.now();
148
+ const hits = await deadline.enforce(this.chunks.search({ vector, limit: 1, scopeToBranch: true }));
149
+ // Only when the scoped query found nothing: the unscoped one is a
150
+ // second query, and it is worth running solely to tell an
151
+ // unindexed branch apart from a broken index.
152
+ const anyBranchOk = hits.length > 0
153
+ ? true
154
+ : (await deadline.enforce(this.chunks.search({ vector, limit: 1, scopeToBranch: false }))).length > 0;
155
+ return {
156
+ embeddingOk: true,
157
+ embeddingLatencyMs,
158
+ searchOk: hits.length > 0,
159
+ searchResultCount: hits.length,
160
+ searchLatencyMs: Date.now() - started,
161
+ anyBranchOk,
162
+ };
163
+ }
164
+ catch {
165
+ // The embedder works; the index does not answer. That is a
166
+ // meaningful distinction the caller reports differently.
167
+ return { embeddingOk: true, embeddingLatencyMs, searchOk: false };
168
+ }
169
+ }
170
+ }
171
+ //# sourceMappingURL=StatusService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusService.js","sourceRoot":"","sources":["../../../src/application/operations/StatusService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { LmgrepConfig } from "../../domain/config/LmgrepConfig.js";
2
+ import type { LockPort } from "../../domain/ports/LockPort.js";
3
+ import type { LoggerPort } from "../../domain/ports/LoggerPort.js";
4
+ import type { WorkspacePort } from "../../domain/ports/WorkspacePort.js";
5
+ import type { IndexBuilder } from "../indexing/IndexBuilder.js";
6
+ /**
7
+ * Keeps an index current while the process runs.
8
+ *
9
+ * Two mechanisms, because neither suffices alone: filesystem events give a
10
+ * fast path for ordinary edits, and a periodic full reconcile is the backstop
11
+ * for what recursive `fs.watch` misses on Linux — new subdirectories, editor
12
+ * atomic saves, event bursts. The reconcile also retries files that failed
13
+ * while the embedder was down, which is what removes the need to re-run
14
+ * `lmgrep index` by hand.
15
+ */
16
+ export declare class WatchService {
17
+ private readonly builder;
18
+ private readonly workspace;
19
+ private readonly config;
20
+ private readonly cwd;
21
+ private readonly logger;
22
+ private readonly locks;
23
+ /** How often the backstop reconcile runs. */
24
+ private static readonly RECONCILE_MS;
25
+ /** Window for coalescing a burst of filesystem events. */
26
+ private static readonly DEBOUNCE_MS;
27
+ private indexing;
28
+ /** Whether anything arrived while a run was in flight. */
29
+ private queuedWork;
30
+ /**
31
+ * Paths queued mid-run, or undefined when the queued work is a full
32
+ * rebuild. A full rebuild is a superset, so once one is queued no file list
33
+ * may narrow it back down.
34
+ */
35
+ private queuedFiles;
36
+ private timer;
37
+ private watcher;
38
+ private holdsLock;
39
+ /** The catch-up build is the one allowed to train a vector index. */
40
+ private caughtUp;
41
+ constructor(builder: IndexBuilder, workspace: WorkspacePort, config: LmgrepConfig, cwd: string, logger: LoggerPort, locks: LockPort);
42
+ /**
43
+ * Begin watching. Returns a function that stops it.
44
+ *
45
+ * Acquiring the maintainer lock is what makes exactly one process
46
+ * responsible for a database; it also registers this process so
47
+ * `lmgrep status` can report who is watching. Losing the race is normal —
48
+ * another server already has it — and simply means not watching.
49
+ */
50
+ start(): () => void;
51
+ private beginWatching;
52
+ stop(): void;
53
+ /**
54
+ * Run an index pass, coalescing anything that arrives while one is in
55
+ * flight. A queued full rebuild wins over queued file lists: it is the
56
+ * superset, and narrowing it would skip work.
57
+ */
58
+ private reindex;
59
+ /**
60
+ * Merge incoming work into whatever is already queued.
61
+ *
62
+ * The previous implementation used `undefined` both for "nothing queued"
63
+ * and for "a full rebuild is queued", so a reconcile that landed mid-run
64
+ * was silently dropped. The two states are now distinct.
65
+ */
66
+ private enqueue;
67
+ }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Keeps an index current while the process runs.
3
+ *
4
+ * Two mechanisms, because neither suffices alone: filesystem events give a
5
+ * fast path for ordinary edits, and a periodic full reconcile is the backstop
6
+ * for what recursive `fs.watch` misses on Linux — new subdirectories, editor
7
+ * atomic saves, event bursts. The reconcile also retries files that failed
8
+ * while the embedder was down, which is what removes the need to re-run
9
+ * `lmgrep index` by hand.
10
+ */
11
+ export class WatchService {
12
+ builder;
13
+ workspace;
14
+ config;
15
+ cwd;
16
+ logger;
17
+ locks;
18
+ /** How often the backstop reconcile runs. */
19
+ static RECONCILE_MS = 30_000;
20
+ /** Window for coalescing a burst of filesystem events. */
21
+ static DEBOUNCE_MS = 2000;
22
+ indexing = false;
23
+ /** Whether anything arrived while a run was in flight. */
24
+ queuedWork = false;
25
+ /**
26
+ * Paths queued mid-run, or undefined when the queued work is a full
27
+ * rebuild. A full rebuild is a superset, so once one is queued no file list
28
+ * may narrow it back down.
29
+ */
30
+ queuedFiles;
31
+ timer;
32
+ watcher;
33
+ holdsLock = false;
34
+ /** The catch-up build is the one allowed to train a vector index. */
35
+ caughtUp = false;
36
+ constructor(builder, workspace, config, cwd, logger, locks) {
37
+ this.builder = builder;
38
+ this.workspace = workspace;
39
+ this.config = config;
40
+ this.cwd = cwd;
41
+ this.logger = logger;
42
+ this.locks = locks;
43
+ }
44
+ /**
45
+ * Begin watching. Returns a function that stops it.
46
+ *
47
+ * Acquiring the maintainer lock is what makes exactly one process
48
+ * responsible for a database; it also registers this process so
49
+ * `lmgrep status` can report who is watching. Losing the race is normal —
50
+ * another server already has it — and simply means not watching.
51
+ */
52
+ start() {
53
+ if (!this.locks.acquireMaintainer()) {
54
+ this.logger.info("Another process is already watching this index.");
55
+ return () => { };
56
+ }
57
+ this.holdsLock = true;
58
+ return this.beginWatching();
59
+ }
60
+ beginWatching() {
61
+ // Catch up first, so a branch checked out while this was not running
62
+ // gets its manifest bootstrapped before any event arrives.
63
+ void this.reindex();
64
+ this.watcher = this.workspace.watch(this.cwd, this.config.ignore, (changed) => void this.reindex(changed), WatchService.DEBOUNCE_MS, this.config.extensions);
65
+ this.timer = setInterval(() => void this.reindex(), WatchService.RECONCILE_MS);
66
+ // Never keep the host process alive on the timer alone.
67
+ this.timer.unref?.();
68
+ this.logger.info("Watching for changes...");
69
+ return () => this.stop();
70
+ }
71
+ stop() {
72
+ if (this.timer)
73
+ clearInterval(this.timer);
74
+ this.timer = undefined;
75
+ this.watcher?.close();
76
+ this.watcher = undefined;
77
+ if (this.holdsLock) {
78
+ this.locks.releaseMaintainer();
79
+ this.holdsLock = false;
80
+ }
81
+ }
82
+ /**
83
+ * Run an index pass, coalescing anything that arrives while one is in
84
+ * flight. A queued full rebuild wins over queued file lists: it is the
85
+ * superset, and narrowing it would skip work.
86
+ */
87
+ async reindex(changedFiles) {
88
+ if (this.indexing) {
89
+ this.enqueue(changedFiles);
90
+ return;
91
+ }
92
+ this.indexing = true;
93
+ try {
94
+ this.logger.info(changedFiles?.length
95
+ ? `Changes detected in ${changedFiles.length} file(s), re-indexing...`
96
+ : "Changes detected, re-indexing...");
97
+ // Train the vector index on the catch-up build only.
98
+ //
99
+ // Without an index every search brute-force scans the table, which
100
+ // costs roughly the index's own size in peak memory *per query* —
101
+ // measured at ~1GB a search against a 759MB index, versus ~200MB
102
+ // once indexed. Training spikes higher (~2.5GB) but does so once,
103
+ // so for a process that will serve many queries it is the cheaper
104
+ // option as well as the faster one. Incremental ticks stay off it
105
+ // and only absorb the tail.
106
+ await this.builder.build({
107
+ files: changedFiles,
108
+ createIndex: !this.caughtUp,
109
+ });
110
+ this.caughtUp = true;
111
+ }
112
+ catch (err) {
113
+ this.logger.error(`Index error: ${err instanceof Error ? err.message : err}`);
114
+ }
115
+ finally {
116
+ this.indexing = false;
117
+ if (this.queuedWork) {
118
+ const next = this.queuedFiles;
119
+ this.queuedWork = false;
120
+ this.queuedFiles = undefined;
121
+ void this.reindex(next);
122
+ }
123
+ }
124
+ }
125
+ /**
126
+ * Merge incoming work into whatever is already queued.
127
+ *
128
+ * The previous implementation used `undefined` both for "nothing queued"
129
+ * and for "a full rebuild is queued", so a reconcile that landed mid-run
130
+ * was silently dropped. The two states are now distinct.
131
+ */
132
+ enqueue(changedFiles) {
133
+ if (!changedFiles) {
134
+ this.queuedWork = true;
135
+ this.queuedFiles = undefined;
136
+ return;
137
+ }
138
+ // A queued full rebuild already covers these paths.
139
+ if (this.queuedWork && this.queuedFiles === undefined)
140
+ return;
141
+ this.queuedWork = true;
142
+ this.queuedFiles = [...(this.queuedFiles ?? []), ...changedFiles];
143
+ }
144
+ }
145
+ //# sourceMappingURL=WatchService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WatchService.js","sourceRoot":"","sources":["../../../src/application/operations/WatchService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { FileManifest } from "../../domain/corpus/SourceFile.js";
2
+ import type { WorkspacePort } from "../../domain/ports/WorkspacePort.js";
3
+ /** How the working tree differs from what the manifest recorded. */
4
+ export interface TreeChanges {
5
+ added: string[];
6
+ modified: string[];
7
+ deleted: string[];
8
+ }
9
+ /**
10
+ * Compares the working tree against the manifest, without changing anything.
11
+ *
12
+ * This is what `lmgrep status --changes` reports: a read-only preview of what
13
+ * the next index run would do, so a user can see whether it is worth running.
14
+ */
15
+ export declare class WorkingTreeDiff {
16
+ private readonly workspace;
17
+ constructor(workspace: WorkspacePort);
18
+ compute(projectRoot: string, manifest: FileManifest): TreeChanges;
19
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Compares the working tree against the manifest, without changing anything.
3
+ *
4
+ * This is what `lmgrep status --changes` reports: a read-only preview of what
5
+ * the next index run would do, so a user can see whether it is worth running.
6
+ */
7
+ export class WorkingTreeDiff {
8
+ workspace;
9
+ constructor(workspace) {
10
+ this.workspace = workspace;
11
+ }
12
+ compute(projectRoot, manifest) {
13
+ const added = [];
14
+ const modified = [];
15
+ const deleted = [];
16
+ const seen = new Set();
17
+ for (const file of this.workspace.listFiles(projectRoot)) {
18
+ seen.add(file);
19
+ const hash = this.workspace.hashOf(projectRoot, file);
20
+ // Unreadable right now: not a reportable change either way.
21
+ if (!hash)
22
+ continue;
23
+ const stored = manifest.versionOf(file);
24
+ if (!stored)
25
+ added.push(file);
26
+ else if (!stored.equals(hash))
27
+ modified.push(file);
28
+ }
29
+ for (const path of manifest.paths()) {
30
+ if (!seen.has(path))
31
+ deleted.push(path);
32
+ }
33
+ return { added, modified, deleted };
34
+ }
35
+ }
36
+ //# sourceMappingURL=WorkingTreeDiff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkingTreeDiff.js","sourceRoot":"","sources":["../../../src/application/operations/WorkingTreeDiff.ts"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IACE;IAA7B,YAA6B,SAAwB;QAAxB,cAAS,GAAT,SAAS,CAAe;IAAG,CAAC;IAEzD,OAAO,CAAC,WAAmB,EAAE,QAAsB;QAClD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAE/B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACf,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YACtD,4DAA4D;YAC5D,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,CAAC,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;iBACzB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IACrC,CAAC;CACD"}
@@ -0,0 +1,68 @@
1
+ import type { LmgrepConfig } from "../../domain/config/LmgrepConfig.js";
2
+ import type { ChatModelPort } from "../../domain/ports/ChatModelPort.js";
3
+ import { type Source } from "../../domain/research/Citation.js";
4
+ import { type TraceEntry } from "../../domain/research/ResearchTrace.js";
5
+ import type { HitList } from "../../domain/retrieval/HitList.js";
6
+ import { SearchCriteria } from "../search/SearchCriteria.js";
7
+ export interface ResearchResult {
8
+ question: string;
9
+ answer: string;
10
+ /** Sources the answer actually cited, in citation order. */
11
+ sources: Source[];
12
+ trace: TraceEntry[];
13
+ steps: number;
14
+ elapsedMs: number;
15
+ /**
16
+ * True when synthesis was unavailable and the result fell back to raw
17
+ * search hits, so the caller knows not to over-trust the answer.
18
+ */
19
+ degraded: boolean;
20
+ }
21
+ /** How the agent reaches the index. */
22
+ export interface ResearchSearcher {
23
+ search(query: string, criteria: SearchCriteria): Promise<HitList>;
24
+ }
25
+ /**
26
+ * Answers a question by searching the codebase and synthesizing a cited answer.
27
+ *
28
+ * Robustness is layered, because a local model fails in several distinct ways
29
+ * and none of them should hard-fail the caller:
30
+ *
31
+ * 1. Happy path — the model self-terminates with a cited answer.
32
+ * 2. It cannot self-terminate (step cap, timeout, or the transcript overflows
33
+ * its context) — synthesize from a budgeted digest in a fresh context.
34
+ * 3. It answered without ever searching — discard that, since it is ungrounded
35
+ * by construction, search directly and synthesize.
36
+ * 4. The model is unreachable — degrade to raw search hits.
37
+ */
38
+ export declare class ResearchAgent {
39
+ private readonly searcher;
40
+ private readonly chat;
41
+ private readonly config;
42
+ private static readonly DEFAULT_MAX_STEPS;
43
+ /**
44
+ * Wall clock is only a backstop against a wedged run; the search and step
45
+ * budgets bound the real work. A local model doing a few steps plus a cold
46
+ * load can need minutes, so this stays generous.
47
+ */
48
+ private static readonly DEFAULT_TIMEOUT_MS;
49
+ private static readonly MAX_SEARCHES;
50
+ private static readonly DEFAULT_SEARCH_LIMIT;
51
+ /** The model tends to ask for 10+, which bloats the transcript. */
52
+ private static readonly MAX_SEARCH_LIMIT;
53
+ /** After this many searches, nudge it to wrap up. */
54
+ private static readonly NUDGE_AFTER;
55
+ constructor(searcher: ResearchSearcher, chat: ChatModelPort, config: LmgrepConfig);
56
+ research(question: string, onTrace?: (entry: TraceEntry) => void): Promise<ResearchResult>;
57
+ private runSearch;
58
+ /**
59
+ * One-shot synthesis over a budgeted digest, in a fresh context with no
60
+ * tool transcript to replay — which is what makes it work even when the
61
+ * agentic loop overflowed the window.
62
+ */
63
+ private synthesize;
64
+ /** Ask the model to insert markers into its own answer, wording unchanged. */
65
+ private addCitations;
66
+ /** Last resort: return the raw hits, clearly marked as un-synthesized. */
67
+ private degrade;
68
+ }