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,178 @@
1
+ import { dirname, join, resolve } from "node:path";
2
+ import { Branch } from "./Branch.js";
3
+ import { DatabaseLocation } from "./DatabaseLocation.js";
4
+ import { Project } from "./Project.js";
5
+ import { ProjectId } from "./ProjectId.js";
6
+ /**
7
+ * Translates a working directory into a project identity and a database
8
+ * location.
9
+ *
10
+ * This is the only place that knows the rules, and there are three:
11
+ *
12
+ * **A repository's index lives inside it**, at `<git-common-dir>/lmgrep/`.
13
+ * Git resolves that to the main checkout's `.git` even from a linked worktree,
14
+ * so every worktree of a repository agrees on one index by construction rather
15
+ * than by a shared registry that could disagree with reality. It also means
16
+ * the index is found by `du`, deleted by `rm -rf`, and gone when the clone is
17
+ * — which is what stops orphaned databases from accumulating somewhere the
18
+ * user never looks. Git never walks its own directory, so nothing here is ever
19
+ * committed or indexed.
20
+ *
21
+ * **Each embedding model gets its own database.** Vectors from different
22
+ * models are not comparable, so pointing lmgrep at a new model used to mean
23
+ * discarding the index or searching it with embeddings that quietly meant
24
+ * nothing. Keyed by model, switching is just a different subdirectory, and
25
+ * switching back finds the old index intact.
26
+ *
27
+ * **Everything else falls back to the state directory**: projects outside git
28
+ * have no repository to live in, and `--database <name>` is by definition not
29
+ * tied to one.
30
+ */
31
+ export class ProjectLocator {
32
+ git;
33
+ state;
34
+ model;
35
+ dimensions;
36
+ /** Subdirectory of the git common directory holding every model's index. */
37
+ static REPOSITORY_SUBDIRECTORY = "lmgrep";
38
+ constructor(git, state,
39
+ /** The configured embedding model, which partitions the databases. */
40
+ model,
41
+ /** Configured output width, when the model has a configurable one. */
42
+ dimensions) {
43
+ this.git = git;
44
+ this.state = state;
45
+ this.model = model;
46
+ this.dimensions = dimensions;
47
+ }
48
+ /**
49
+ * Identify the project containing `cwd`.
50
+ *
51
+ * A git repo is identified by its origin URL when it has one, so every
52
+ * worktree and clone maps to a single identity; a remoteless repo falls
53
+ * back to its root path, and a plain directory to its own absolute path.
54
+ */
55
+ resolveProject(cwd) {
56
+ const absolute = resolve(cwd);
57
+ const gitRoot = this.git.toplevel(absolute);
58
+ if (gitRoot) {
59
+ const branch = Branch.of(this.git.currentBranch(gitRoot) ?? "HEAD");
60
+ const remoteUrl = this.git.originUrl(gitRoot);
61
+ return new Project(ProjectId.of(remoteUrl ?? gitRoot), gitRoot, branch, remoteUrl);
62
+ }
63
+ return new Project(ProjectId.of(absolute), absolute, Branch.default());
64
+ }
65
+ /** The directory holding every model's index for the project at `cwd`. */
66
+ indexHomeFor(cwd) {
67
+ const commonDir = this.git.commonDir(resolve(cwd));
68
+ if (commonDir) {
69
+ return join(commonDir, ProjectLocator.REPOSITORY_SUBDIRECTORY);
70
+ }
71
+ return join(this.state.databasesDirectory(), this.resolveProject(cwd).id.toSlug());
72
+ }
73
+ /** Database directory for the project containing `cwd`. */
74
+ databasePathFor(cwd) {
75
+ return join(this.indexHomeFor(cwd), this.modelSlug());
76
+ }
77
+ /**
78
+ * The working tree a repository index belongs to, for display and for the
79
+ * registry.
80
+ *
81
+ * Worktrees share one database, so the toplevel of whichever worktree
82
+ * happened to run the index would name an arbitrary one of them. The main
83
+ * checkout — the parent of the common directory — is the stable answer.
84
+ */
85
+ projectRootFor(cwd) {
86
+ const commonDir = this.git.commonDir(resolve(cwd));
87
+ return commonDir ? dirname(commonDir) : this.resolveProject(cwd).root;
88
+ }
89
+ /** Directory name the configured model's embeddings are stored under. */
90
+ modelSlug() {
91
+ return this.model.toSlug(this.dimensions);
92
+ }
93
+ /**
94
+ * Where an index built with `model` belongs.
95
+ *
96
+ * Needed when adopting a database written by an older layout, which knows
97
+ * which model built it but not which slot the current rules would put it
98
+ * in. It must go through here rather than deriving a slug independently:
99
+ * the width only counts when it was *configured*, since an index records
100
+ * the width it observed and that is the model's native size whenever
101
+ * nothing was requested. Computing the slug from the recorded width
102
+ * instead produced a directory the locator would never look in — an
103
+ * adopted index that was silently invisible.
104
+ */
105
+ databasePathForModel(cwd, model) {
106
+ const dimensions = model.isSameFamilyAs(this.model)
107
+ ? this.dimensions
108
+ : undefined;
109
+ return join(this.indexHomeFor(cwd), model.toSlug(dimensions));
110
+ }
111
+ /**
112
+ * Decide which database a command targets.
113
+ *
114
+ * With no override this is the repository's index for the configured
115
+ * model. An override containing a separator is taken literally — it is an
116
+ * exact address, and appending anything to it would make it impossible to
117
+ * point at a database that already exists. A bare name is an identity
118
+ * instead, so it is model-scoped like any other.
119
+ *
120
+ * Either way the result is flat and branch-agnostic: indexing and search
121
+ * both use the default branch, so switching git branches never hides
122
+ * results in a database the user asked for explicitly. `cwd` still drives
123
+ * file scanning; only the database identity changes.
124
+ */
125
+ resolveDatabase(cwd, database) {
126
+ if (database && database.length > 0) {
127
+ const path = this.isPathLike(database)
128
+ ? resolve(cwd, database)
129
+ : join(this.state.databasesDirectory(), database.replace(/[^a-zA-Z0-9_.-]/g, "_"), this.modelSlug());
130
+ return new DatabaseLocation(path, Branch.default(), resolve(cwd), true);
131
+ }
132
+ const project = this.resolveProject(cwd);
133
+ return new DatabaseLocation(this.databasePathFor(cwd), project.branch, project.root, false);
134
+ }
135
+ /**
136
+ * Find the indexed project root covering `cwd` and the prefix from it.
137
+ *
138
+ * For a git repo the root is the toplevel. Outside git, walks up looking
139
+ * for an ancestor that already has an index, so running from a
140
+ * subdirectory of an indexed tree still finds it.
141
+ */
142
+ findIndexedAncestor(cwd) {
143
+ const absolute = resolve(cwd);
144
+ const root = this.resolveProject(cwd).root;
145
+ if (this.state.isDirectory(this.databasePathFor(root))) {
146
+ return {
147
+ root,
148
+ prefix: root === absolute ? "" : absolute.slice(root.length + 1),
149
+ };
150
+ }
151
+ // Only plain directories climb: inside a git repo the toplevel is
152
+ // definitive, so a miss there means there is genuinely no index.
153
+ if (root === absolute) {
154
+ let current = resolve(absolute, "..");
155
+ for (;;) {
156
+ if (this.state.isDirectory(this.databasePathFor(current))) {
157
+ return {
158
+ root: current,
159
+ prefix: absolute.slice(current.length + 1),
160
+ };
161
+ }
162
+ const parent = resolve(current, "..");
163
+ if (parent === current)
164
+ break;
165
+ current = parent;
166
+ }
167
+ }
168
+ return undefined;
169
+ }
170
+ /** A `--database` override is a path when it carries a separator. */
171
+ isPathLike(value) {
172
+ return (value.includes("/") ||
173
+ value.includes("\\") ||
174
+ value === "." ||
175
+ value === "..");
176
+ }
177
+ }
178
+ //# sourceMappingURL=ProjectLocator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectLocator.js","sourceRoot":"","sources":["../../../src/domain/project/ProjectLocator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /** A source an answer can cite: a numbered code location. */
2
+ export interface Source {
3
+ n: number;
4
+ path: string;
5
+ startLine: number;
6
+ endLine: number;
7
+ }
8
+ /**
9
+ * Reads `[n]` citation markers out of an answer.
10
+ *
11
+ * Both the single `[3]` and the grouped `[3, 5]` forms must parse — small
12
+ * models reach for the grouped form when one claim has several sources, and a
13
+ * marker we cannot read is a source silently missing from the answer's list,
14
+ * which is exactly the grounding the answer exists to provide.
15
+ */
16
+ export declare class CitationMarkers {
17
+ private static readonly PATTERN;
18
+ /** Every cited id in first-appearance order, groups expanded; may repeat. */
19
+ static idsIn(text: string): number[];
20
+ static present(text: string): boolean;
21
+ /**
22
+ * Resolve cited ids against the sources actually surfaced, in citation
23
+ * order. Hallucinated ids are dropped: the marker stays in the prose, but
24
+ * no invented source is listed under it.
25
+ */
26
+ static resolve(answer: string, sources: readonly Source[]): Source[];
27
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Reads `[n]` citation markers out of an answer.
3
+ *
4
+ * Both the single `[3]` and the grouped `[3, 5]` forms must parse — small
5
+ * models reach for the grouped form when one claim has several sources, and a
6
+ * marker we cannot read is a source silently missing from the answer's list,
7
+ * which is exactly the grounding the answer exists to provide.
8
+ */
9
+ export class CitationMarkers {
10
+ static PATTERN = /\[(\d+(?:\s*,\s*\d+)*)\]/g;
11
+ /** Every cited id in first-appearance order, groups expanded; may repeat. */
12
+ static idsIn(text) {
13
+ const out = [];
14
+ for (const match of text.matchAll(CitationMarkers.PATTERN)) {
15
+ for (const part of match[1].split(","))
16
+ out.push(Number(part.trim()));
17
+ }
18
+ return out;
19
+ }
20
+ static present(text) {
21
+ return CitationMarkers.idsIn(text).length > 0;
22
+ }
23
+ /**
24
+ * Resolve cited ids against the sources actually surfaced, in citation
25
+ * order. Hallucinated ids are dropped: the marker stays in the prose, but
26
+ * no invented source is listed under it.
27
+ */
28
+ static resolve(answer, sources) {
29
+ const byNumber = new Map(sources.map((s) => [s.n, s]));
30
+ const seen = new Set();
31
+ const out = [];
32
+ for (const n of CitationMarkers.idsIn(answer)) {
33
+ if (seen.has(n))
34
+ continue;
35
+ seen.add(n);
36
+ const source = byNumber.get(n);
37
+ if (source)
38
+ out.push(source);
39
+ }
40
+ return out;
41
+ }
42
+ }
43
+ //# sourceMappingURL=Citation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Citation.js","sourceRoot":"","sources":["../../../src/domain/research/Citation.ts"],"names":[],"mappings":"AAQA;;;;;;;GAOG;AACH,MAAM,OAAO,eAAe;IACnB,MAAM,CAAU,OAAO,GAAG,2BAA2B,CAAC;IAE9D,6EAA6E;IAC7E,MAAM,CAAC,KAAK,CAAC,IAAY;QACxB,MAAM,GAAG,GAAa,EAAE,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5D,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,IAAY;QAC1B,OAAO,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,MAAc,EAAE,OAA0B;QACxD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,GAAG,GAAa,EAAE,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/C,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,SAAS;YAC1B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACZ,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAI,MAAM;gBAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,GAAG,CAAC;IACZ,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { Hit } from "../retrieval/Hit.js";
2
+ import type { Source } from "./Citation.js";
3
+ /**
4
+ * Accumulates what the research loop has seen, and numbers it.
5
+ *
6
+ * Numbering is stable and deduplicated by location, so the same chunk surfaced
7
+ * by two different searches keeps one id — otherwise the model would cite the
8
+ * same code under several numbers and the source list would triple.
9
+ */
10
+ export declare class EvidenceLedger {
11
+ /**
12
+ * Cap on one hit's source. AST chunks are usually small; a large one is
13
+ * truncated to its head so a single search cannot swamp the context.
14
+ */
15
+ private static readonly MAX_CONTENT_CHARS;
16
+ /**
17
+ * Char budget for the digest fed to fallback synthesis. ~9k chars is
18
+ * roughly 2.5k tokens, which fits even an 8k window alongside the prompt
19
+ * and the answer.
20
+ */
21
+ private static readonly DIGEST_CHAR_BUDGET;
22
+ /** How many sources to offer when asking a model to add citations. */
23
+ private static readonly MENU_SIZE;
24
+ private readonly sourceList;
25
+ private readonly byLocation;
26
+ private readonly evidence;
27
+ private readonly recorded;
28
+ get sources(): Source[];
29
+ get isEmpty(): boolean;
30
+ /** Register hits, returning each one's id and the body shown to the model. */
31
+ ingest(hits: readonly Hit[]): Array<{
32
+ id: number;
33
+ hit: Hit;
34
+ body: string;
35
+ }>;
36
+ /**
37
+ * A budgeted digest of everything gathered, for one-shot synthesis in a
38
+ * fresh context. Blocks are truncated rather than dropped so the earliest
39
+ * (highest-ranked) evidence always appears.
40
+ */
41
+ digest(): string;
42
+ /** A compact source list, for asking a model to insert missing citations. */
43
+ menu(): string;
44
+ private register;
45
+ private clamp;
46
+ private firstLine;
47
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Accumulates what the research loop has seen, and numbers it.
3
+ *
4
+ * Numbering is stable and deduplicated by location, so the same chunk surfaced
5
+ * by two different searches keeps one id — otherwise the model would cite the
6
+ * same code under several numbers and the source list would triple.
7
+ */
8
+ export class EvidenceLedger {
9
+ /**
10
+ * Cap on one hit's source. AST chunks are usually small; a large one is
11
+ * truncated to its head so a single search cannot swamp the context.
12
+ */
13
+ static MAX_CONTENT_CHARS = 1400;
14
+ /**
15
+ * Char budget for the digest fed to fallback synthesis. ~9k chars is
16
+ * roughly 2.5k tokens, which fits even an 8k window alongside the prompt
17
+ * and the answer.
18
+ */
19
+ static DIGEST_CHAR_BUDGET = 9000;
20
+ /** How many sources to offer when asking a model to add citations. */
21
+ static MENU_SIZE = 12;
22
+ sourceList = [];
23
+ byLocation = new Map();
24
+ evidence = [];
25
+ recorded = new Set();
26
+ get sources() {
27
+ return this.sourceList;
28
+ }
29
+ get isEmpty() {
30
+ return this.evidence.length === 0;
31
+ }
32
+ /** Register hits, returning each one's id and the body shown to the model. */
33
+ ingest(hits) {
34
+ return hits.map((hit) => {
35
+ const id = this.register(hit);
36
+ const body = this.clamp(hit.content);
37
+ if (!this.recorded.has(id)) {
38
+ this.recorded.add(id);
39
+ this.evidence.push({
40
+ n: id,
41
+ path: hit.location.filePath,
42
+ startLine: hit.location.startLine,
43
+ endLine: hit.location.endLine,
44
+ text: body,
45
+ });
46
+ }
47
+ return { id, hit, body };
48
+ });
49
+ }
50
+ /**
51
+ * A budgeted digest of everything gathered, for one-shot synthesis in a
52
+ * fresh context. Blocks are truncated rather than dropped so the earliest
53
+ * (highest-ranked) evidence always appears.
54
+ */
55
+ digest() {
56
+ let budget = EvidenceLedger.DIGEST_CHAR_BUDGET;
57
+ const blocks = [];
58
+ for (const ev of this.evidence) {
59
+ if (budget <= 0)
60
+ break;
61
+ const header = `[${ev.n}] ${ev.path}:${ev.startLine}-${ev.endLine}`;
62
+ const overhead = header.length + 2;
63
+ let text = ev.text;
64
+ if (text.length + overhead > budget) {
65
+ text = `${text.slice(0, Math.max(0, budget - overhead))}\n… (truncated)`;
66
+ }
67
+ blocks.push(`${header}\n${text}`);
68
+ budget -= text.length + overhead;
69
+ }
70
+ return blocks.join("\n\n");
71
+ }
72
+ /** A compact source list, for asking a model to insert missing citations. */
73
+ menu() {
74
+ return this.evidence
75
+ .slice(0, EvidenceLedger.MENU_SIZE)
76
+ .map((ev) => `[${ev.n}] ${ev.path}:${ev.startLine}-${ev.endLine} — ${this.firstLine(ev.text)}`)
77
+ .join("\n");
78
+ }
79
+ register(hit) {
80
+ const key = hit.location.toString();
81
+ const existing = this.byLocation.get(key);
82
+ if (existing != null)
83
+ return existing;
84
+ const n = this.sourceList.length + 1;
85
+ this.sourceList.push({
86
+ n,
87
+ path: hit.location.filePath,
88
+ startLine: hit.location.startLine,
89
+ endLine: hit.location.endLine,
90
+ });
91
+ this.byLocation.set(key, n);
92
+ return n;
93
+ }
94
+ clamp(content) {
95
+ if (content.length <= EvidenceLedger.MAX_CONTENT_CHARS)
96
+ return content;
97
+ const head = content.slice(0, EvidenceLedger.MAX_CONTENT_CHARS);
98
+ const omitted = content
99
+ .slice(EvidenceLedger.MAX_CONTENT_CHARS)
100
+ .split("\n").length;
101
+ return `${head}\n… (${omitted} more lines — search a narrower query if you need them)`;
102
+ }
103
+ firstLine(text) {
104
+ const line = text
105
+ .split("\n")
106
+ .find((l) => l.trim().length > 0)
107
+ ?.trim() ?? "";
108
+ return line.length > 100 ? `${line.slice(0, 100)}…` : line;
109
+ }
110
+ }
111
+ //# sourceMappingURL=EvidenceLedger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvidenceLedger.js","sourceRoot":"","sources":["../../../src/domain/research/EvidenceLedger.ts"],"names":[],"mappings":"AAYA;;;;;;GAMG;AACH,MAAM,OAAO,cAAc;IAC1B;;;OAGG;IACK,MAAM,CAAU,iBAAiB,GAAG,IAAI,CAAC;IAEjD;;;;OAIG;IACK,MAAM,CAAU,kBAAkB,GAAG,IAAI,CAAC;IAElD,sEAAsE;IAC9D,MAAM,CAAU,SAAS,GAAG,EAAE,CAAC;IAEtB,UAAU,GAAa,EAAE,CAAC;IAC1B,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,QAAQ,GAAe,EAAE,CAAC;IAC1B,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IAE9C,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;IAED,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,8EAA8E;IAC9E,MAAM,CAAC,IAAoB;QAC1B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACvB,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAClB,CAAC,EAAE,EAAE;oBACL,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ;oBAC3B,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS;oBACjC,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO;oBAC7B,IAAI,EAAE,IAAI;iBACV,CAAC,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,MAAM;QACL,IAAI,MAAM,GAAG,cAAc,CAAC,kBAAkB,CAAC;QAC/C,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,MAAM,IAAI,CAAC;gBAAE,MAAM;YACvB,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YACpE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YACnC,IAAI,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC;YACnB,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,GAAG,MAAM,EAAE,CAAC;gBACrC,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,iBAAiB,CAAC;YAC1E,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;YAClC,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;QAClC,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,6EAA6E;IAC7E,IAAI;QACH,OAAO,IAAI,CAAC,QAAQ;aAClB,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC;aAClC,GAAG,CACH,CAAC,EAAE,EAAE,EAAE,CACN,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAClF;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAEO,QAAQ,CAAC,GAAQ;QACxB,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,QAAQ,IAAI,IAAI;YAAE,OAAO,QAAQ,CAAC;QAEtC,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACpB,CAAC;YACD,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ;YAC3B,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS;YACjC,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO;SAC7B,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,CAAC,CAAC;IACV,CAAC;IAEO,KAAK,CAAC,OAAe;QAC5B,IAAI,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,iBAAiB;YAAE,OAAO,OAAO,CAAC;QACvE,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,OAAO;aACrB,KAAK,CAAC,cAAc,CAAC,iBAAiB,CAAC;aACvC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACrB,OAAO,GAAG,IAAI,QAAQ,OAAO,yDAAyD,CAAC;IACxF,CAAC;IAEO,SAAS,CAAC,IAAY;QAC7B,MAAM,IAAI,GACT,IAAI;aACF,KAAK,CAAC,IAAI,CAAC;aACX,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;YACjC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,CAAC"}
@@ -0,0 +1,19 @@
1
+ /** One step of a research run, for the caller to display live. */
2
+ export type TraceEntry = {
3
+ kind: "search";
4
+ query: string;
5
+ hits: number;
6
+ } | {
7
+ kind: "note";
8
+ message: string;
9
+ };
10
+ /** Records what a research run did, and streams it to an optional observer. */
11
+ export declare class ResearchTrace {
12
+ private readonly observer?;
13
+ private readonly entries;
14
+ constructor(observer?: ((entry: TraceEntry) => void) | undefined);
15
+ record(entry: TraceEntry): void;
16
+ searched(query: string, hits: number): void;
17
+ noted(message: string): void;
18
+ toArray(): TraceEntry[];
19
+ }
@@ -0,0 +1,22 @@
1
+ /** Records what a research run did, and streams it to an optional observer. */
2
+ export class ResearchTrace {
3
+ observer;
4
+ entries = [];
5
+ constructor(observer) {
6
+ this.observer = observer;
7
+ }
8
+ record(entry) {
9
+ this.entries.push(entry);
10
+ this.observer?.(entry);
11
+ }
12
+ searched(query, hits) {
13
+ this.record({ kind: "search", query, hits });
14
+ }
15
+ noted(message) {
16
+ this.record({ kind: "note", message });
17
+ }
18
+ toArray() {
19
+ return [...this.entries];
20
+ }
21
+ }
22
+ //# sourceMappingURL=ResearchTrace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResearchTrace.js","sourceRoot":"","sources":["../../../src/domain/research/ResearchTrace.ts"],"names":[],"mappings":"AAKA,+EAA+E;AAC/E,MAAM,OAAO,aAAa;IAGI;IAFZ,OAAO,GAAiB,EAAE,CAAC;IAE5C,YAA6B,QAAsC;QAAtC,aAAQ,GAAR,QAAQ,CAA8B;IAAG,CAAC;IAEvE,MAAM,CAAC,KAAiB;QACvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAED,QAAQ,CAAC,KAAa,EAAE,IAAY;QACnC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,OAAe;QACpB,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,OAAO;QACN,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;CACD"}
@@ -0,0 +1,19 @@
1
+ import type { CodeLocation } from "../corpus/CodeLocation.js";
2
+ import type { FileVersion } from "../corpus/FileVersion.js";
3
+ /** A retrieved chunk together with its similarity score. */
4
+ export declare class Hit {
5
+ /** Chunk identity, used to deduplicate a result page. */
6
+ readonly id: string;
7
+ readonly location: CodeLocation;
8
+ readonly type: string;
9
+ readonly name: string;
10
+ readonly content: string;
11
+ readonly context: string;
12
+ readonly score: number;
13
+ readonly fileVersion: FileVersion;
14
+ constructor(
15
+ /** Chunk identity, used to deduplicate a result page. */
16
+ id: string, location: CodeLocation, type: string, name: string, content: string, context: string, score: number, fileVersion: FileVersion);
17
+ /** The same hit with its path rooted under another project's directory. */
18
+ relocatedUnder(root: string): Hit;
19
+ }
@@ -0,0 +1,28 @@
1
+ /** A retrieved chunk together with its similarity score. */
2
+ export class Hit {
3
+ id;
4
+ location;
5
+ type;
6
+ name;
7
+ content;
8
+ context;
9
+ score;
10
+ fileVersion;
11
+ constructor(
12
+ /** Chunk identity, used to deduplicate a result page. */
13
+ id, location, type, name, content, context, score, fileVersion) {
14
+ this.id = id;
15
+ this.location = location;
16
+ this.type = type;
17
+ this.name = name;
18
+ this.content = content;
19
+ this.context = context;
20
+ this.score = score;
21
+ this.fileVersion = fileVersion;
22
+ }
23
+ /** The same hit with its path rooted under another project's directory. */
24
+ relocatedUnder(root) {
25
+ return new Hit(this.id, this.location.relocatedUnder(root), this.type, this.name, this.content, this.context, this.score, this.fileVersion);
26
+ }
27
+ }
28
+ //# sourceMappingURL=Hit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Hit.js","sourceRoot":"","sources":["../../../src/domain/retrieval/Hit.ts"],"names":[],"mappings":"AAGA,4DAA4D;AAC5D,MAAM,OAAO,GAAG;IAGL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IATV;IACC,yDAAyD;IAChD,EAAU,EACV,QAAsB,EACtB,IAAY,EACZ,IAAY,EACZ,OAAe,EACf,OAAe,EACf,KAAa,EACb,WAAwB;QAPxB,OAAE,GAAF,EAAE,CAAQ;QACV,aAAQ,GAAR,QAAQ,CAAc;QACtB,SAAI,GAAJ,IAAI,CAAQ;QACZ,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAQ;QACf,YAAO,GAAP,OAAO,CAAQ;QACf,UAAK,GAAL,KAAK,CAAQ;QACb,gBAAW,GAAX,WAAW,CAAa;IAC/B,CAAC;IAEJ,2EAA2E;IAC3E,cAAc,CAAC,IAAY;QAC1B,OAAO,IAAI,GAAG,CACb,IAAI,CAAC,EAAE,EACP,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,EAClC,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,WAAW,CAChB,CAAC;IACH,CAAC;CACD"}
@@ -0,0 +1,35 @@
1
+ import type { Hit } from "./Hit.js";
2
+ /**
3
+ * An ordered result page, with the reductions that always follow retrieval.
4
+ *
5
+ * These used to be loose steps repeated at each call site; collecting them
6
+ * here means "what search returns" has one definition, and the ordering of the
7
+ * reductions (dedup before trim, always) cannot drift between callers.
8
+ */
9
+ export declare class HitList {
10
+ private readonly hits;
11
+ private constructor();
12
+ static of(hits: readonly Hit[]): HitList;
13
+ static empty(): HitList;
14
+ get length(): number;
15
+ get isEmpty(): boolean;
16
+ toArray(): Hit[];
17
+ [Symbol.iterator](): Iterator<Hit>;
18
+ /**
19
+ * Drop redundant rows, keeping the first (highest-scoring) of each group:
20
+ *
21
+ * 1. Exact duplicates by chunk id — identical rows produced by concurrent
22
+ * unlocked indexing.
23
+ * 2. Overlapping line ranges within a file — the fallback chunker's
24
+ * sliding-window overlap, plus any parent/child or near-duplicate span.
25
+ * Tree-sitter chunks are node-bounded and never overlap, so this only
26
+ * ever removes genuine near-duplicates.
27
+ */
28
+ deduplicated(): HitList;
29
+ takeAtMost(limit: number): HitList;
30
+ filtered(predicate: (hit: Hit) => boolean): HitList;
31
+ mapped(transform: (hit: Hit) => Hit): HitList;
32
+ /** Highest score first — used when merging pages from several projects. */
33
+ sortedByScoreDescending(): HitList;
34
+ concat(other: HitList): HitList;
35
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * An ordered result page, with the reductions that always follow retrieval.
3
+ *
4
+ * These used to be loose steps repeated at each call site; collecting them
5
+ * here means "what search returns" has one definition, and the ordering of the
6
+ * reductions (dedup before trim, always) cannot drift between callers.
7
+ */
8
+ export class HitList {
9
+ hits;
10
+ constructor(hits) {
11
+ this.hits = hits;
12
+ }
13
+ static of(hits) {
14
+ return new HitList(hits);
15
+ }
16
+ static empty() {
17
+ return new HitList([]);
18
+ }
19
+ get length() {
20
+ return this.hits.length;
21
+ }
22
+ get isEmpty() {
23
+ return this.hits.length === 0;
24
+ }
25
+ toArray() {
26
+ return [...this.hits];
27
+ }
28
+ [Symbol.iterator]() {
29
+ return this.hits[Symbol.iterator]();
30
+ }
31
+ /**
32
+ * Drop redundant rows, keeping the first (highest-scoring) of each group:
33
+ *
34
+ * 1. Exact duplicates by chunk id — identical rows produced by concurrent
35
+ * unlocked indexing.
36
+ * 2. Overlapping line ranges within a file — the fallback chunker's
37
+ * sliding-window overlap, plus any parent/child or near-duplicate span.
38
+ * Tree-sitter chunks are node-bounded and never overlap, so this only
39
+ * ever removes genuine near-duplicates.
40
+ */
41
+ deduplicated() {
42
+ const seenIds = new Set();
43
+ const keptRanges = new Map();
44
+ const out = [];
45
+ for (const hit of this.hits) {
46
+ if (seenIds.has(hit.id))
47
+ continue;
48
+ seenIds.add(hit.id);
49
+ const { filePath, startLine, endLine } = hit.location;
50
+ const ranges = keptRanges.get(filePath);
51
+ if (ranges) {
52
+ const overlaps = ranges.some(([s, e]) => startLine <= e && s <= endLine);
53
+ if (overlaps)
54
+ continue;
55
+ ranges.push([startLine, endLine]);
56
+ }
57
+ else {
58
+ keptRanges.set(filePath, [[startLine, endLine]]);
59
+ }
60
+ out.push(hit);
61
+ }
62
+ return new HitList(out);
63
+ }
64
+ takeAtMost(limit) {
65
+ return new HitList(this.hits.slice(0, limit));
66
+ }
67
+ filtered(predicate) {
68
+ return new HitList(this.hits.filter(predicate));
69
+ }
70
+ mapped(transform) {
71
+ return new HitList(this.hits.map(transform));
72
+ }
73
+ /** Highest score first — used when merging pages from several projects. */
74
+ sortedByScoreDescending() {
75
+ return new HitList([...this.hits].sort((a, b) => b.score - a.score));
76
+ }
77
+ concat(other) {
78
+ return new HitList([...this.hits, ...other.hits]);
79
+ }
80
+ }
81
+ //# sourceMappingURL=HitList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HitList.js","sourceRoot":"","sources":["../../../src/domain/retrieval/HitList.ts"],"names":[],"mappings":"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"}