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.
- package/README.md +253 -62
- package/completions/_lmgrep +49 -40
- package/dist/application/Lmgrep.d.ts +107 -0
- package/dist/application/Lmgrep.js +99 -0
- package/dist/application/Lmgrep.js.map +1 -0
- package/dist/application/LmgrepFactory.d.ts +40 -0
- package/dist/application/LmgrepFactory.js +155 -0
- package/dist/application/LmgrepFactory.js.map +1 -0
- package/dist/application/indexing/BranchBootstrapper.d.ts +21 -0
- package/dist/application/indexing/BranchBootstrapper.js +52 -0
- package/dist/application/indexing/BranchBootstrapper.js.map +1 -0
- package/dist/application/indexing/BranchManifestSweeper.d.ts +17 -0
- package/dist/application/indexing/BranchManifestSweeper.js +35 -0
- package/dist/application/indexing/BranchManifestSweeper.js.map +1 -0
- package/dist/application/indexing/Duration.d.ts +9 -0
- package/dist/application/indexing/Duration.js +25 -0
- package/dist/application/indexing/Duration.js.map +1 -0
- package/dist/application/indexing/EmbeddingAbortError.d.ts +11 -0
- package/dist/application/indexing/EmbeddingAbortError.js +20 -0
- package/dist/application/indexing/EmbeddingAbortError.js.map +1 -0
- package/dist/application/indexing/EmbeddingPipeline.d.ts +59 -0
- package/dist/application/indexing/EmbeddingPipeline.js +140 -0
- package/dist/application/indexing/EmbeddingPipeline.js.map +1 -0
- package/dist/application/indexing/IndexBuilder.d.ts +112 -0
- package/dist/application/indexing/IndexBuilder.js +370 -0
- package/dist/application/indexing/IndexBuilder.js.map +1 -0
- package/dist/application/indexing/IndexingProgress.d.ts +34 -0
- package/dist/application/indexing/IndexingProgress.js +2 -0
- package/dist/application/indexing/IndexingProgress.js.map +1 -0
- package/dist/application/operations/Deadline.d.ts +13 -0
- package/dist/application/operations/Deadline.js +29 -0
- package/dist/application/operations/Deadline.js.map +1 -0
- package/dist/application/operations/HealthMonitor.d.ts +58 -0
- package/dist/application/operations/HealthMonitor.js +128 -0
- package/dist/application/operations/HealthMonitor.js.map +1 -0
- package/dist/application/operations/IndexAlternatives.d.ts +35 -0
- package/dist/application/operations/IndexAlternatives.js +61 -0
- package/dist/application/operations/IndexAlternatives.js.map +1 -0
- package/dist/application/operations/IndexInventory.d.ts +69 -0
- package/dist/application/operations/IndexInventory.js +99 -0
- package/dist/application/operations/IndexInventory.js.map +1 -0
- package/dist/application/operations/StatusService.d.ts +90 -0
- package/dist/application/operations/StatusService.js +171 -0
- package/dist/application/operations/StatusService.js.map +1 -0
- package/dist/application/operations/WatchService.d.ts +67 -0
- package/dist/application/operations/WatchService.js +145 -0
- package/dist/application/operations/WatchService.js.map +1 -0
- package/dist/application/operations/WorkingTreeDiff.d.ts +19 -0
- package/dist/application/operations/WorkingTreeDiff.js +36 -0
- package/dist/application/operations/WorkingTreeDiff.js.map +1 -0
- package/dist/application/research/ResearchAgent.d.ts +68 -0
- package/dist/application/research/ResearchAgent.js +201 -0
- package/dist/application/research/ResearchAgent.js.map +1 -0
- package/dist/application/research/ResearchPrompts.d.ts +16 -0
- package/dist/application/research/ResearchPrompts.js +34 -0
- package/dist/application/research/ResearchPrompts.js.map +1 -0
- package/dist/application/search/SearchCriteria.d.ts +37 -0
- package/dist/application/search/SearchCriteria.js +48 -0
- package/dist/application/search/SearchCriteria.js.map +1 -0
- package/dist/application/search/SearchService.d.ts +36 -0
- package/dist/application/search/SearchService.js +108 -0
- package/dist/application/search/SearchService.js.map +1 -0
- package/dist/application/search/SearchTargetResolver.d.ts +56 -0
- package/dist/application/search/SearchTargetResolver.js +104 -0
- package/dist/application/search/SearchTargetResolver.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +4 -953
- package/dist/cli.js.map +1 -1
- package/dist/domain/config/ConfigSource.d.ts +16 -0
- package/dist/domain/config/ConfigSource.js +2 -0
- package/dist/domain/config/ConfigSource.js.map +1 -0
- package/dist/domain/config/LmgrepConfig.d.ts +53 -0
- package/dist/domain/config/LmgrepConfig.js +2 -0
- package/dist/domain/config/LmgrepConfig.js.map +1 -0
- package/dist/domain/corpus/Chunk.d.ts +49 -0
- package/dist/domain/corpus/Chunk.js +60 -0
- package/dist/domain/corpus/Chunk.js.map +1 -0
- package/dist/domain/corpus/CodeLocation.d.ts +18 -0
- package/dist/domain/corpus/CodeLocation.js +34 -0
- package/dist/domain/corpus/CodeLocation.js.map +1 -0
- package/dist/domain/corpus/ContentHash.d.ts +15 -0
- package/dist/domain/corpus/ContentHash.js +30 -0
- package/dist/domain/corpus/ContentHash.js.map +1 -0
- package/dist/domain/corpus/FileVersion.d.ts +31 -0
- package/dist/domain/corpus/FileVersion.js +47 -0
- package/dist/domain/corpus/FileVersion.js.map +1 -0
- package/dist/domain/corpus/SourceFile.d.ts +26 -0
- package/dist/domain/corpus/SourceFile.js +47 -0
- package/dist/domain/corpus/SourceFile.js.map +1 -0
- package/dist/domain/corpus/Vector.d.ts +37 -0
- package/dist/domain/corpus/Vector.js +96 -0
- package/dist/domain/corpus/Vector.js.map +1 -0
- package/dist/domain/ports/ChatModelPort.d.ts +57 -0
- package/dist/domain/ports/ChatModelPort.js +2 -0
- package/dist/domain/ports/ChatModelPort.js.map +1 -0
- package/dist/domain/ports/ChunkRepositoryPort.d.ts +42 -0
- package/dist/domain/ports/ChunkRepositoryPort.js +2 -0
- package/dist/domain/ports/ChunkRepositoryPort.js.map +1 -0
- package/dist/domain/ports/ChunkerPort.d.ts +5 -0
- package/dist/domain/ports/ChunkerPort.js +2 -0
- package/dist/domain/ports/ChunkerPort.js.map +1 -0
- package/dist/domain/ports/DatabaseSessionPort.d.ts +10 -0
- package/dist/domain/ports/DatabaseSessionPort.js +2 -0
- package/dist/domain/ports/DatabaseSessionPort.js.map +1 -0
- package/dist/domain/ports/EmbedderPort.d.ts +14 -0
- package/dist/domain/ports/EmbedderPort.js +2 -0
- package/dist/domain/ports/EmbedderPort.js.map +1 -0
- package/dist/domain/ports/FileManifestRepositoryPort.d.ts +32 -0
- package/dist/domain/ports/FileManifestRepositoryPort.js +2 -0
- package/dist/domain/ports/FileManifestRepositoryPort.js.map +1 -0
- package/dist/domain/ports/GitPort.d.ts +24 -0
- package/dist/domain/ports/GitPort.js +2 -0
- package/dist/domain/ports/GitPort.js.map +1 -0
- package/dist/domain/ports/IndexMaintenancePort.d.ts +58 -0
- package/dist/domain/ports/IndexMaintenancePort.js +2 -0
- package/dist/domain/ports/IndexMaintenancePort.js.map +1 -0
- package/dist/domain/ports/IndexMetadataPort.d.ts +23 -0
- package/dist/domain/ports/IndexMetadataPort.js +2 -0
- package/dist/domain/ports/IndexMetadataPort.js.map +1 -0
- package/dist/domain/ports/LockPort.d.ts +17 -0
- package/dist/domain/ports/LockPort.js +2 -0
- package/dist/domain/ports/LockPort.js.map +1 -0
- package/dist/domain/ports/LoggerPort.d.ts +5 -0
- package/dist/domain/ports/LoggerPort.js +2 -0
- package/dist/domain/ports/LoggerPort.js.map +1 -0
- package/dist/domain/ports/ProjectIndexesPort.d.ts +20 -0
- package/dist/domain/ports/ProjectIndexesPort.js +2 -0
- package/dist/domain/ports/ProjectIndexesPort.js.map +1 -0
- package/dist/domain/ports/ProjectRegistryPort.d.ts +42 -0
- package/dist/domain/ports/ProjectRegistryPort.js +2 -0
- package/dist/domain/ports/ProjectRegistryPort.js.map +1 -0
- package/dist/domain/ports/StateDirectoryPort.d.ts +29 -0
- package/dist/domain/ports/StateDirectoryPort.js +2 -0
- package/dist/domain/ports/StateDirectoryPort.js.map +1 -0
- package/dist/domain/ports/WorkspacePort.d.ts +38 -0
- package/dist/domain/ports/WorkspacePort.js +2 -0
- package/dist/domain/ports/WorkspacePort.js.map +1 -0
- package/dist/domain/project/Branch.d.ts +20 -0
- package/dist/domain/project/Branch.js +33 -0
- package/dist/domain/project/Branch.js.map +1 -0
- package/dist/domain/project/DatabaseLocation.d.ts +32 -0
- package/dist/domain/project/DatabaseLocation.js +35 -0
- package/dist/domain/project/DatabaseLocation.js.map +1 -0
- package/dist/domain/project/IndexMetadata.d.ts +17 -0
- package/dist/domain/project/IndexMetadata.js +2 -0
- package/dist/domain/project/IndexMetadata.js.map +1 -0
- package/dist/domain/project/ModelIdentity.d.ts +58 -0
- package/dist/domain/project/ModelIdentity.js +94 -0
- package/dist/domain/project/ModelIdentity.js.map +1 -0
- package/dist/domain/project/Project.d.ts +17 -0
- package/dist/domain/project/Project.js +21 -0
- package/dist/domain/project/Project.js.map +1 -0
- package/dist/domain/project/ProjectId.d.ts +28 -0
- package/dist/domain/project/ProjectId.js +58 -0
- package/dist/domain/project/ProjectId.js.map +1 -0
- package/dist/domain/project/ProjectLocator.d.ts +112 -0
- package/dist/domain/project/ProjectLocator.js +178 -0
- package/dist/domain/project/ProjectLocator.js.map +1 -0
- package/dist/domain/research/Citation.d.ts +27 -0
- package/dist/domain/research/Citation.js +43 -0
- package/dist/domain/research/Citation.js.map +1 -0
- package/dist/domain/research/EvidenceLedger.d.ts +47 -0
- package/dist/domain/research/EvidenceLedger.js +111 -0
- package/dist/domain/research/EvidenceLedger.js.map +1 -0
- package/dist/domain/research/ResearchTrace.d.ts +19 -0
- package/dist/domain/research/ResearchTrace.js +22 -0
- package/dist/domain/research/ResearchTrace.js.map +1 -0
- package/dist/domain/retrieval/Hit.d.ts +19 -0
- package/dist/domain/retrieval/Hit.js +28 -0
- package/dist/domain/retrieval/Hit.js.map +1 -0
- package/dist/domain/retrieval/HitList.d.ts +35 -0
- package/dist/domain/retrieval/HitList.js +81 -0
- package/dist/domain/retrieval/HitList.js.map +1 -0
- package/dist/domain/retrieval/MissingIndexError.d.ts +11 -0
- package/dist/domain/retrieval/MissingIndexError.js +15 -0
- package/dist/domain/retrieval/MissingIndexError.js.map +1 -0
- package/dist/index.d.ts +43 -45
- package/dist/index.js +30 -567
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/ai/AiSdkChatModel.d.ts +31 -0
- package/dist/infrastructure/ai/AiSdkChatModel.js +137 -0
- package/dist/infrastructure/ai/AiSdkChatModel.js.map +1 -0
- package/dist/infrastructure/ai/AiSdkEmbedder.d.ts +28 -0
- package/dist/infrastructure/ai/AiSdkEmbedder.js +79 -0
- package/dist/infrastructure/ai/AiSdkEmbedder.js.map +1 -0
- package/dist/infrastructure/ai/DockerModelRunnerProbe.d.ts +16 -0
- package/dist/infrastructure/ai/DockerModelRunnerProbe.js +52 -0
- package/dist/infrastructure/ai/DockerModelRunnerProbe.js.map +1 -0
- package/dist/infrastructure/ai/EmbeddingPrefixes.d.ts +21 -0
- package/dist/infrastructure/ai/EmbeddingPrefixes.js +40 -0
- package/dist/infrastructure/ai/EmbeddingPrefixes.js.map +1 -0
- package/dist/infrastructure/ai/LmStudioProbe.d.ts +18 -0
- package/dist/infrastructure/ai/LmStudioProbe.js +49 -0
- package/dist/infrastructure/ai/LmStudioProbe.js.map +1 -0
- package/dist/infrastructure/ai/LocalModelReloader.d.ts +21 -0
- package/dist/infrastructure/ai/LocalModelReloader.js +61 -0
- package/dist/infrastructure/ai/LocalModelReloader.js.map +1 -0
- package/dist/infrastructure/ai/LocalRuntimeDetector.d.ts +36 -0
- package/dist/infrastructure/ai/LocalRuntimeDetector.js +63 -0
- package/dist/infrastructure/ai/LocalRuntimeDetector.js.map +1 -0
- package/dist/infrastructure/ai/ModelRuntime.d.ts +32 -0
- package/dist/infrastructure/ai/ModelRuntime.js +2 -0
- package/dist/infrastructure/ai/ModelRuntime.js.map +1 -0
- package/dist/infrastructure/ai/OllamaProbe.d.ts +22 -0
- package/dist/infrastructure/ai/OllamaProbe.js +71 -0
- package/dist/infrastructure/ai/OllamaProbe.js.map +1 -0
- package/dist/infrastructure/ai/ProviderFailure.d.ts +16 -0
- package/dist/infrastructure/ai/ProviderFailure.js +35 -0
- package/dist/infrastructure/ai/ProviderFailure.js.map +1 -0
- package/dist/infrastructure/ai/ProviderModuleLoader.d.ts +14 -0
- package/dist/infrastructure/ai/ProviderModuleLoader.js +56 -0
- package/dist/infrastructure/ai/ProviderModuleLoader.js.map +1 -0
- package/dist/infrastructure/ai/ProviderRegistry.d.ts +38 -0
- package/dist/infrastructure/ai/ProviderRegistry.js +63 -0
- package/dist/infrastructure/ai/ProviderRegistry.js.map +1 -0
- package/dist/infrastructure/fs/ConfigLoader.d.ts +59 -0
- package/dist/infrastructure/fs/ConfigLoader.js +194 -0
- package/dist/infrastructure/fs/ConfigLoader.js.map +1 -0
- package/dist/infrastructure/fs/DatabaseLocks.d.ts +52 -0
- package/dist/infrastructure/fs/DatabaseLocks.js +92 -0
- package/dist/infrastructure/fs/DatabaseLocks.js.map +1 -0
- package/dist/infrastructure/fs/DiskUsage.d.ts +6 -0
- package/dist/infrastructure/fs/DiskUsage.js +41 -0
- package/dist/infrastructure/fs/DiskUsage.js.map +1 -0
- package/dist/infrastructure/fs/IndexableFileRules.d.ts +33 -0
- package/dist/infrastructure/fs/IndexableFileRules.js +177 -0
- package/dist/infrastructure/fs/IndexableFileRules.js.map +1 -0
- package/dist/infrastructure/fs/Loggers.d.ts +14 -0
- package/dist/infrastructure/fs/Loggers.js +18 -0
- package/dist/infrastructure/fs/Loggers.js.map +1 -0
- package/dist/infrastructure/fs/PidFileLock.d.ts +40 -0
- package/dist/infrastructure/fs/PidFileLock.js +97 -0
- package/dist/infrastructure/fs/PidFileLock.js.map +1 -0
- package/dist/infrastructure/fs/ProjectIndexes.d.ts +8 -0
- package/dist/infrastructure/fs/ProjectIndexes.js +35 -0
- package/dist/infrastructure/fs/ProjectIndexes.js.map +1 -0
- package/dist/infrastructure/fs/ProjectMetadataStore.d.ts +42 -0
- package/dist/infrastructure/fs/ProjectMetadataStore.js +86 -0
- package/dist/infrastructure/fs/ProjectMetadataStore.js.map +1 -0
- package/dist/infrastructure/fs/ProjectRegistry.d.ts +25 -0
- package/dist/infrastructure/fs/ProjectRegistry.js +83 -0
- package/dist/infrastructure/fs/ProjectRegistry.js.map +1 -0
- package/dist/infrastructure/fs/StateDirectory.d.ts +28 -0
- package/dist/infrastructure/fs/StateDirectory.js +71 -0
- package/dist/infrastructure/fs/StateDirectory.js.map +1 -0
- package/dist/infrastructure/fs/Workspace.d.ts +25 -0
- package/dist/infrastructure/fs/Workspace.js +90 -0
- package/dist/infrastructure/fs/Workspace.js.map +1 -0
- package/dist/infrastructure/git/GitClient.d.ts +34 -0
- package/dist/infrastructure/git/GitClient.js +74 -0
- package/dist/infrastructure/git/GitClient.js.map +1 -0
- package/dist/infrastructure/lancedb/ChunkRepository.d.ts +38 -0
- package/dist/infrastructure/lancedb/ChunkRepository.js +166 -0
- package/dist/infrastructure/lancedb/ChunkRepository.js.map +1 -0
- package/dist/infrastructure/lancedb/DatabaseImporter.d.ts +22 -0
- package/dist/infrastructure/lancedb/DatabaseImporter.js +74 -0
- package/dist/infrastructure/lancedb/DatabaseImporter.js.map +1 -0
- package/dist/infrastructure/lancedb/FileManifestRepository.d.ts +34 -0
- package/dist/infrastructure/lancedb/FileManifestRepository.js +137 -0
- package/dist/infrastructure/lancedb/FileManifestRepository.js.map +1 -0
- package/dist/infrastructure/lancedb/IndexMaintenance.d.ts +53 -0
- package/dist/infrastructure/lancedb/IndexMaintenance.js +227 -0
- package/dist/infrastructure/lancedb/IndexMaintenance.js.map +1 -0
- package/dist/infrastructure/lancedb/LanceTables.d.ts +67 -0
- package/dist/infrastructure/lancedb/LanceTables.js +159 -0
- package/dist/infrastructure/lancedb/LanceTables.js.map +1 -0
- package/dist/{lib/native-tuning.js → infrastructure/lancedb/NativeTuning.js} +1 -1
- package/dist/infrastructure/lancedb/NativeTuning.js.map +1 -0
- package/dist/infrastructure/lancedb/RowReplication.d.ts +27 -0
- package/dist/infrastructure/lancedb/RowReplication.js +82 -0
- package/dist/infrastructure/lancedb/RowReplication.js.map +1 -0
- package/dist/infrastructure/lancedb/VectorIndexPolicy.d.ts +60 -0
- package/dist/infrastructure/lancedb/VectorIndexPolicy.js +72 -0
- package/dist/infrastructure/lancedb/VectorIndexPolicy.js.map +1 -0
- package/dist/infrastructure/p2p/IndexShare.d.ts +45 -0
- package/dist/infrastructure/p2p/IndexShare.js +160 -0
- package/dist/infrastructure/p2p/IndexShare.js.map +1 -0
- package/dist/infrastructure/p2p/PeerSwarm.d.ts +16 -0
- package/dist/infrastructure/p2p/PeerSwarm.js +41 -0
- package/dist/infrastructure/p2p/PeerSwarm.js.map +1 -0
- package/dist/infrastructure/p2p/SecureChannel.d.ts +60 -0
- package/dist/infrastructure/p2p/SecureChannel.js +71 -0
- package/dist/infrastructure/p2p/SecureChannel.js.map +1 -0
- package/dist/infrastructure/p2p/ShareCode.d.ts +25 -0
- package/dist/infrastructure/p2p/ShareCode.js +304 -0
- package/dist/infrastructure/p2p/ShareCode.js.map +1 -0
- package/dist/infrastructure/process/ProcessRegistry.d.ts +50 -0
- package/dist/infrastructure/process/ProcessRegistry.js +109 -0
- package/dist/infrastructure/process/ProcessRegistry.js.map +1 -0
- package/dist/infrastructure/treesitter/ChunkContextBuilder.d.ts +45 -0
- package/dist/infrastructure/treesitter/ChunkContextBuilder.js +159 -0
- package/dist/infrastructure/treesitter/ChunkContextBuilder.js.map +1 -0
- package/dist/infrastructure/treesitter/EmbeddedTreeSitterAssets.d.ts +8 -0
- package/dist/infrastructure/treesitter/EmbeddedTreeSitterAssets.js +12 -0
- package/dist/infrastructure/treesitter/EmbeddedTreeSitterAssets.js.map +1 -0
- package/dist/infrastructure/treesitter/LanguageCatalog.d.ts +30 -0
- package/dist/{lib/chunker/languages.js → infrastructure/treesitter/LanguageCatalog.js} +38 -29
- package/dist/infrastructure/treesitter/LanguageCatalog.js.map +1 -0
- package/dist/infrastructure/treesitter/SlidingWindowChunker.d.ts +15 -0
- package/dist/infrastructure/treesitter/SlidingWindowChunker.js +42 -0
- package/dist/infrastructure/treesitter/SlidingWindowChunker.js.map +1 -0
- package/dist/infrastructure/treesitter/TreeSitterChunker.d.ts +42 -0
- package/dist/infrastructure/treesitter/TreeSitterChunker.js +165 -0
- package/dist/infrastructure/treesitter/TreeSitterChunker.js.map +1 -0
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +14 -72
- package/dist/mcp.js.map +1 -1
- package/dist/presentation/cli/Cli.d.ts +31 -0
- package/dist/presentation/cli/Cli.js +120 -0
- package/dist/presentation/cli/Cli.js.map +1 -0
- package/dist/presentation/cli/CliOptions.d.ts +18 -0
- package/dist/presentation/cli/CliOptions.js +25 -0
- package/dist/presentation/cli/CliOptions.js.map +1 -0
- package/dist/presentation/cli/CommandContext.d.ts +50 -0
- package/dist/presentation/cli/CommandContext.js +88 -0
- package/dist/presentation/cli/CommandContext.js.map +1 -0
- package/dist/presentation/cli/ConfigTemplate.d.ts +31 -0
- package/dist/presentation/cli/ConfigTemplate.js +83 -0
- package/dist/presentation/cli/ConfigTemplate.js.map +1 -0
- package/dist/presentation/cli/Renderer.d.ts +90 -0
- package/dist/presentation/cli/Renderer.js +290 -0
- package/dist/presentation/cli/Renderer.js.map +1 -0
- package/dist/presentation/cli/commands/AskCommand.d.ts +14 -0
- package/dist/presentation/cli/commands/AskCommand.js +48 -0
- package/dist/presentation/cli/commands/AskCommand.js.map +1 -0
- package/dist/presentation/cli/commands/CompletionsCommand.d.ts +18 -0
- package/dist/presentation/cli/commands/CompletionsCommand.js +96 -0
- package/dist/presentation/cli/commands/CompletionsCommand.js.map +1 -0
- package/dist/presentation/cli/commands/ConfigCommands.d.ts +56 -0
- package/dist/presentation/cli/commands/ConfigCommands.js +220 -0
- package/dist/presentation/cli/commands/ConfigCommands.js.map +1 -0
- package/dist/presentation/cli/commands/IndexCommand.d.ts +18 -0
- package/dist/presentation/cli/commands/IndexCommand.js +54 -0
- package/dist/presentation/cli/commands/IndexCommand.js.map +1 -0
- package/dist/presentation/cli/commands/ProjectsCommand.d.ts +48 -0
- package/dist/presentation/cli/commands/ProjectsCommand.js +240 -0
- package/dist/presentation/cli/commands/ProjectsCommand.js.map +1 -0
- package/dist/presentation/cli/commands/SearchCommand.d.ts +19 -0
- package/dist/presentation/cli/commands/SearchCommand.js +55 -0
- package/dist/presentation/cli/commands/SearchCommand.js.map +1 -0
- package/dist/presentation/cli/commands/ServerCommands.d.ts +13 -0
- package/dist/presentation/cli/commands/ServerCommands.js +40 -0
- package/dist/presentation/cli/commands/ServerCommands.js.map +1 -0
- package/dist/presentation/cli/commands/ShareCommands.d.ts +22 -0
- package/dist/presentation/cli/commands/ShareCommands.js +134 -0
- package/dist/presentation/cli/commands/ShareCommands.js.map +1 -0
- package/dist/presentation/cli/commands/StatusCommand.d.ts +15 -0
- package/dist/presentation/cli/commands/StatusCommand.js +53 -0
- package/dist/presentation/cli/commands/StatusCommand.js.map +1 -0
- package/dist/presentation/mcp/HitFormatter.d.ts +17 -0
- package/dist/presentation/mcp/HitFormatter.js +42 -0
- package/dist/presentation/mcp/HitFormatter.js.map +1 -0
- package/dist/presentation/mcp/IndexWatchController.d.ts +17 -0
- package/dist/presentation/mcp/IndexWatchController.js +31 -0
- package/dist/presentation/mcp/IndexWatchController.js.map +1 -0
- package/dist/presentation/mcp/LmgrepCore.d.ts +66 -0
- package/dist/presentation/mcp/LmgrepCore.js +178 -0
- package/dist/presentation/mcp/LmgrepCore.js.map +1 -0
- package/dist/presentation/mcp/McpServer.d.ts +18 -0
- package/dist/presentation/mcp/McpServer.js +63 -0
- package/dist/presentation/mcp/McpServer.js.map +1 -0
- package/dist/presentation/mcp/ToolDescriptions.d.ts +40 -0
- package/dist/presentation/mcp/ToolDescriptions.js +85 -0
- package/dist/presentation/mcp/ToolDescriptions.js.map +1 -0
- package/package.json +93 -89
- package/dist/lib/build.d.ts +0 -21
- package/dist/lib/build.js +0 -374
- package/dist/lib/build.js.map +0 -1
- package/dist/lib/chunker/context.d.ts +0 -21
- package/dist/lib/chunker/context.js +0 -131
- package/dist/lib/chunker/context.js.map +0 -1
- package/dist/lib/chunker/index.d.ts +0 -7
- package/dist/lib/chunker/index.js +0 -209
- package/dist/lib/chunker/index.js.map +0 -1
- package/dist/lib/chunker/languages.d.ts +0 -15
- package/dist/lib/chunker/languages.js.map +0 -1
- package/dist/lib/config.d.ts +0 -12
- package/dist/lib/config.js +0 -83
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/embedder.d.ts +0 -65
- package/dist/lib/embedder.js +0 -236
- package/dist/lib/embedder.js.map +0 -1
- package/dist/lib/facet-session.d.ts +0 -44
- package/dist/lib/facet-session.js +0 -125
- package/dist/lib/facet-session.js.map +0 -1
- package/dist/lib/native-tuning.js.map +0 -1
- package/dist/lib/p2p.d.ts +0 -32
- package/dist/lib/p2p.js +0 -281
- package/dist/lib/p2p.js.map +0 -1
- package/dist/lib/providers.d.ts +0 -1
- package/dist/lib/providers.js +0 -41
- package/dist/lib/providers.js.map +0 -1
- package/dist/lib/repair.d.ts +0 -10
- package/dist/lib/repair.js +0 -57
- package/dist/lib/repair.js.map +0 -1
- package/dist/lib/scanner.d.ts +0 -34
- package/dist/lib/scanner.js +0 -242
- package/dist/lib/scanner.js.map +0 -1
- package/dist/lib/search-tool.d.ts +0 -55
- package/dist/lib/search-tool.js +0 -319
- package/dist/lib/search-tool.js.map +0 -1
- package/dist/lib/serve.d.ts +0 -11
- package/dist/lib/serve.js +0 -144
- package/dist/lib/serve.js.map +0 -1
- package/dist/lib/store.d.ts +0 -252
- package/dist/lib/store.js +0 -1216
- package/dist/lib/store.js.map +0 -1
- package/dist/lib/types.d.ts +0 -194
- package/dist/lib/types.js +0 -13
- package/dist/lib/types.js.map +0 -1
- package/dist/lib/vocab.d.ts +0 -20
- package/dist/lib/vocab.js +0 -275
- package/dist/lib/vocab.js.map +0 -1
- /package/dist/{lib/native-tuning.d.ts → infrastructure/lancedb/NativeTuning.d.ts} +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { EmbeddingAbortError } from "./EmbeddingAbortError.js";
|
|
2
|
+
/**
|
|
3
|
+
* Embeds a list of texts batch by batch, surviving a flaky provider.
|
|
4
|
+
*
|
|
5
|
+
* Three behaviours matter here and are easy to lose:
|
|
6
|
+
*
|
|
7
|
+
* - **Incremental persistence.** Each batch is handed to `persist` before the
|
|
8
|
+
* next starts, so a crash leaves completed work in the index and a resume
|
|
9
|
+
* skips it. Nothing is buffered for the caller to write at the end.
|
|
10
|
+
* - **Per-item retry.** A failed batch is retried one item at a time, so a
|
|
11
|
+
* single oversized chunk cannot cost the other 99 in its batch.
|
|
12
|
+
* - **Model reload.** A local provider that has fallen over is given a chance
|
|
13
|
+
* to reload, and the failed span is replayed rather than abandoned.
|
|
14
|
+
*/
|
|
15
|
+
export class EmbeddingPipeline {
|
|
16
|
+
embedder;
|
|
17
|
+
config;
|
|
18
|
+
progress;
|
|
19
|
+
reloadModel;
|
|
20
|
+
isLocal;
|
|
21
|
+
static BATCH_DELAY_MS = 200;
|
|
22
|
+
static MAX_CONSECUTIVE_FAILURES = 3;
|
|
23
|
+
static MAX_RELOADS = 3;
|
|
24
|
+
consecutiveFailures = 0;
|
|
25
|
+
reloads = 0;
|
|
26
|
+
constructor(embedder, config, progress = {},
|
|
27
|
+
/** Reloads a local model; returns false when it cannot be done. */
|
|
28
|
+
reloadModel = async () => false,
|
|
29
|
+
/** Whether the provider is local, and therefore reloadable. */
|
|
30
|
+
isLocal = false) {
|
|
31
|
+
this.embedder = embedder;
|
|
32
|
+
this.config = config;
|
|
33
|
+
this.progress = progress;
|
|
34
|
+
this.reloadModel = reloadModel;
|
|
35
|
+
this.isLocal = isLocal;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns the positions that could not be embedded. Successes are reported
|
|
39
|
+
* through `persist` exactly once each, never returned in bulk.
|
|
40
|
+
*/
|
|
41
|
+
async run(texts, persist) {
|
|
42
|
+
const batchSize = this.config.batchSize;
|
|
43
|
+
const failedIndices = new Set();
|
|
44
|
+
const totalBatches = Math.ceil(texts.length / batchSize);
|
|
45
|
+
// One byte per text to remember which positions have embedded, rather
|
|
46
|
+
// than retaining the embeddings: `persist` already stored them and no
|
|
47
|
+
// caller reads them back. At high dimensions a retained vector is tens
|
|
48
|
+
// of KB, so a large repo would buffer gigabytes for a progress count.
|
|
49
|
+
//
|
|
50
|
+
// A flag array rather than a counter because the reload path below
|
|
51
|
+
// rewinds and replays batches; flags keep the count idempotent.
|
|
52
|
+
const succeededFlags = new Uint8Array(texts.length);
|
|
53
|
+
let succeededCount = 0;
|
|
54
|
+
const markSucceeded = (index) => {
|
|
55
|
+
if (succeededFlags[index])
|
|
56
|
+
return;
|
|
57
|
+
succeededFlags[index] = 1;
|
|
58
|
+
succeededCount++;
|
|
59
|
+
};
|
|
60
|
+
for (let i = 0; i < texts.length; i += batchSize) {
|
|
61
|
+
const batchNumber = Math.floor(i / batchSize) + 1;
|
|
62
|
+
const end = Math.min(i + batchSize, texts.length);
|
|
63
|
+
const batch = texts.slice(i, end);
|
|
64
|
+
this.progress.onBatchStart?.(batchNumber, totalBatches);
|
|
65
|
+
const embedded = [];
|
|
66
|
+
try {
|
|
67
|
+
const vectors = await this.embedder.embedDocuments(batch);
|
|
68
|
+
for (let j = 0; j < batch.length; j++) {
|
|
69
|
+
markSucceeded(i + j);
|
|
70
|
+
embedded.push({ index: i + j, vector: vectors[j] });
|
|
71
|
+
}
|
|
72
|
+
this.consecutiveFailures = 0;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
const batchFailures = await this.retryIndividually(batch, i, embedded, failedIndices, markSucceeded);
|
|
76
|
+
this.consecutiveFailures =
|
|
77
|
+
batchFailures === batch.length ? this.consecutiveFailures + 1 : 0;
|
|
78
|
+
}
|
|
79
|
+
// Persist before any abort below, so partial progress is durable
|
|
80
|
+
// even when the next batches force one.
|
|
81
|
+
if (embedded.length > 0)
|
|
82
|
+
await persist(embedded);
|
|
83
|
+
this.progress.onBatchDone?.(batchNumber, succeededCount, failedIndices.size);
|
|
84
|
+
if (this.consecutiveFailures >= EmbeddingPipeline.MAX_CONSECUTIVE_FAILURES) {
|
|
85
|
+
const rewound = await this.tryReload(i, batchSize);
|
|
86
|
+
if (rewound !== undefined) {
|
|
87
|
+
i = rewound;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
for (let k = end; k < texts.length; k++)
|
|
91
|
+
failedIndices.add(k);
|
|
92
|
+
throw new EmbeddingAbortError(succeededCount, failedIndices, texts.length);
|
|
93
|
+
}
|
|
94
|
+
// Brief cooldown so a local server is not hammered back over.
|
|
95
|
+
if (end < texts.length) {
|
|
96
|
+
await new Promise((r) => setTimeout(r, EmbeddingPipeline.BATCH_DELAY_MS));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { failedIndices };
|
|
100
|
+
}
|
|
101
|
+
/** Retry a failed batch item by item; returns how many still failed. */
|
|
102
|
+
async retryIndividually(batch, offset, embedded, failedIndices, markSucceeded) {
|
|
103
|
+
let failures = 0;
|
|
104
|
+
for (let j = 0; j < batch.length; j++) {
|
|
105
|
+
try {
|
|
106
|
+
const [vector] = await this.embedder.embedDocuments([batch[j]]);
|
|
107
|
+
markSucceeded(offset + j);
|
|
108
|
+
embedded.push({ index: offset + j, vector });
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
failedIndices.add(offset + j);
|
|
112
|
+
failures++;
|
|
113
|
+
console.error(` ! Failed (~${Math.ceil(batch[j].length / 4)} tok): ` +
|
|
114
|
+
`${err instanceof Error ? err.message : err}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return failures;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Give a local model a chance to come back, and return the loop position to
|
|
121
|
+
* rewind to. Undefined means give up.
|
|
122
|
+
*/
|
|
123
|
+
async tryReload(current, batchSize) {
|
|
124
|
+
if (!this.isLocal)
|
|
125
|
+
return undefined;
|
|
126
|
+
if (this.reloads >= EmbeddingPipeline.MAX_RELOADS)
|
|
127
|
+
return undefined;
|
|
128
|
+
this.reloads++;
|
|
129
|
+
this.progress.onReload?.(this.reloads, EmbeddingPipeline.MAX_RELOADS);
|
|
130
|
+
if (!(await this.reloadModel()))
|
|
131
|
+
return undefined;
|
|
132
|
+
this.consecutiveFailures = 0;
|
|
133
|
+
// Replay the span that failed. Already-persisted positions are marked,
|
|
134
|
+
// so re-embedding them cannot double-count. Clamped at zero: rewinding
|
|
135
|
+
// past the start would hand `slice` a negative index, which counts from
|
|
136
|
+
// the end and would replay the wrong texts.
|
|
137
|
+
return Math.max(0, current - EmbeddingPipeline.MAX_CONSECUTIVE_FAILURES * batchSize);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=EmbeddingPipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmbeddingPipeline.js","sourceRoot":"","sources":["../../../src/application/indexing/EmbeddingPipeline.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAc/D;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,iBAAiB;IASX;IACA;IACA;IAEA;IAEA;IAdV,MAAM,CAAU,cAAc,GAAG,GAAG,CAAC;IACrC,MAAM,CAAU,wBAAwB,GAAG,CAAC,CAAC;IAC7C,MAAM,CAAU,WAAW,GAAG,CAAC,CAAC;IAEhC,mBAAmB,GAAG,CAAC,CAAC;IACxB,OAAO,GAAG,CAAC,CAAC;IAEpB,YACkB,QAAsB,EACtB,MAAoB,EACpB,WAA8B,EAAE;IACjD,mEAAmE;IAClD,cAAsC,KAAK,IAAI,EAAE,CAAC,KAAK;IACxE,+DAA+D;IAC9C,UAAU,KAAK;QANf,aAAQ,GAAR,QAAQ,CAAc;QACtB,WAAM,GAAN,MAAM,CAAc;QACpB,aAAQ,GAAR,QAAQ,CAAwB;QAEhC,gBAAW,GAAX,WAAW,CAA4C;QAEvD,YAAO,GAAP,OAAO,CAAQ;IAC9B,CAAC;IAEJ;;;OAGG;IACH,KAAK,CAAC,GAAG,CACR,KAAe,EACf,OAAiD;QAEjD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QACxC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QACxC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;QAEzD,sEAAsE;QACtE,sEAAsE;QACtE,uEAAuE;QACvE,sEAAsE;QACtE,EAAE;QACF,mEAAmE;QACnE,gEAAgE;QAChE,MAAM,cAAc,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,MAAM,aAAa,GAAG,CAAC,KAAa,EAAQ,EAAE;YAC7C,IAAI,cAAc,CAAC,KAAK,CAAC;gBAAE,OAAO;YAClC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC1B,cAAc,EAAE,CAAC;QAClB,CAAC,CAAC;QAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YAClD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAElC,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAExD,MAAM,QAAQ,GAAmB,EAAE,CAAC;YACpC,IAAI,CAAC;gBACJ,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;gBAC1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACvC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;oBACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACrD,CAAC;gBACD,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACR,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,iBAAiB,CACjD,KAAK,EACL,CAAC,EACD,QAAQ,EACR,aAAa,EACb,aAAa,CACb,CAAC;gBACF,IAAI,CAAC,mBAAmB;oBACvB,aAAa,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,CAAC;YAED,iEAAiE;YACjE,wCAAwC;YACxC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;YAEjD,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAC1B,WAAW,EACX,cAAc,EACd,aAAa,CAAC,IAAI,CAClB,CAAC;YAEF,IACC,IAAI,CAAC,mBAAmB,IAAI,iBAAiB,CAAC,wBAAwB,EACrE,CAAC;gBACF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;gBACnD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC3B,CAAC,GAAG,OAAO,CAAC;oBACZ,SAAS;gBACV,CAAC;gBAED,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE;oBAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC9D,MAAM,IAAI,mBAAmB,CAC5B,cAAc,EACd,aAAa,EACb,KAAK,CAAC,MAAM,CACZ,CAAC;YACH,CAAC;YAED,8DAA8D;YAC9D,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBACxB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACvB,UAAU,CAAC,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAC/C,CAAC;YACH,CAAC;QACF,CAAC;QAED,OAAO,EAAE,aAAa,EAAE,CAAC;IAC1B,CAAC;IAED,wEAAwE;IAChE,KAAK,CAAC,iBAAiB,CAC9B,KAAe,EACf,MAAc,EACd,QAAwB,EACxB,aAA0B,EAC1B,aAAsC;QAEtC,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC;gBACJ,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChE,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,aAAa,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC9B,QAAQ,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CACZ,gBAAgB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,SAAS;oBACtD,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAC9C,CAAC;YACH,CAAC;QACF,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,SAAS,CACtB,OAAe,EACf,SAAiB;QAEjB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QACpC,IAAI,IAAI,CAAC,OAAO,IAAI,iBAAiB,CAAC,WAAW;YAAE,OAAO,SAAS,CAAC;QAEpE,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;QACtE,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YAAE,OAAO,SAAS,CAAC;QAElD,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,uEAAuE;QACvE,uEAAuE;QACvE,wEAAwE;QACxE,4CAA4C;QAC5C,OAAO,IAAI,CAAC,GAAG,CACd,CAAC,EACD,OAAO,GAAG,iBAAiB,CAAC,wBAAwB,GAAG,SAAS,CAChE,CAAC;IACH,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { LmgrepConfig } from "../../domain/config/LmgrepConfig.js";
|
|
2
|
+
import type { ChunkerPort } from "../../domain/ports/ChunkerPort.js";
|
|
3
|
+
import type { ChunkRepositoryPort } from "../../domain/ports/ChunkRepositoryPort.js";
|
|
4
|
+
import type { EmbedderPort } from "../../domain/ports/EmbedderPort.js";
|
|
5
|
+
import type { FileManifestRepositoryPort } from "../../domain/ports/FileManifestRepositoryPort.js";
|
|
6
|
+
import type { IndexMaintenancePort } from "../../domain/ports/IndexMaintenancePort.js";
|
|
7
|
+
import type { LockPort } from "../../domain/ports/LockPort.js";
|
|
8
|
+
import type { LoggerPort } from "../../domain/ports/LoggerPort.js";
|
|
9
|
+
import type { WorkspacePort } from "../../domain/ports/WorkspacePort.js";
|
|
10
|
+
import type { DatabaseLocation } from "../../domain/project/DatabaseLocation.js";
|
|
11
|
+
import type { BranchBootstrapper } from "./BranchBootstrapper.js";
|
|
12
|
+
import type { BranchManifestSweeper } from "./BranchManifestSweeper.js";
|
|
13
|
+
import type { IndexBuildOptions, IndexBuildResult } from "./IndexingProgress.js";
|
|
14
|
+
/** Everything the builder collaborates with, named so wiring stays readable. */
|
|
15
|
+
export interface IndexBuilderDependencies {
|
|
16
|
+
workspace: WorkspacePort;
|
|
17
|
+
chunker: ChunkerPort;
|
|
18
|
+
embedder: EmbedderPort;
|
|
19
|
+
chunks: ChunkRepositoryPort;
|
|
20
|
+
manifest: FileManifestRepositoryPort;
|
|
21
|
+
maintenance: IndexMaintenancePort;
|
|
22
|
+
bootstrapper: BranchBootstrapper;
|
|
23
|
+
sweeper: BranchManifestSweeper;
|
|
24
|
+
logger: LoggerPort;
|
|
25
|
+
config: LmgrepConfig;
|
|
26
|
+
location: DatabaseLocation;
|
|
27
|
+
/** Serializes writes against any other indexer on this database. */
|
|
28
|
+
locks: LockPort;
|
|
29
|
+
/** Records the model and dimensions this run indexed with. */
|
|
30
|
+
recordMetadata: (dimensions: number | undefined) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Announces that this database exists, so it can be listed and searched
|
|
33
|
+
* from elsewhere. Separate from {@link recordMetadata} because that one
|
|
34
|
+
* needs a vector width and therefore only runs when something was actually
|
|
35
|
+
* embedded — a repository indexed once and never changed again would
|
|
36
|
+
* otherwise never appear anywhere.
|
|
37
|
+
*/
|
|
38
|
+
registerIndex: () => void;
|
|
39
|
+
/** Reloads a wedged local model mid-run; false when not possible. */
|
|
40
|
+
reloadModel: () => Promise<boolean>;
|
|
41
|
+
isLocalProvider: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Turns a working tree into an index.
|
|
45
|
+
*
|
|
46
|
+
* The order of operations is what makes a run resumable after a crash: a
|
|
47
|
+
* file's manifest entry is written only once every one of its chunks is
|
|
48
|
+
* embedded *and* persisted. A hard stop therefore leaves completed files
|
|
49
|
+
* marked done (a resume skips them) and in-flight files unmarked (a resume
|
|
50
|
+
* re-embeds them cleanly, after dropping their partial chunks).
|
|
51
|
+
*/
|
|
52
|
+
export declare class IndexBuilder {
|
|
53
|
+
private readonly deps;
|
|
54
|
+
constructor(deps: IndexBuilderDependencies);
|
|
55
|
+
/**
|
|
56
|
+
* Held for the whole run: a watcher and an ad-hoc `lmgrep index` must not
|
|
57
|
+
* write concurrently, or they race into duplicate chunk rows.
|
|
58
|
+
*/
|
|
59
|
+
build(options?: IndexBuildOptions): Promise<IndexBuildResult>;
|
|
60
|
+
private buildLocked;
|
|
61
|
+
/**
|
|
62
|
+
* The files this run will look at, and whether that is the whole tree.
|
|
63
|
+
*
|
|
64
|
+
* `complete` matters for deletion detection: only a full scan can prove a
|
|
65
|
+
* path is gone. A targeted or `--since` run sees a subset, where "absent
|
|
66
|
+
* from the scan" means nothing.
|
|
67
|
+
*/
|
|
68
|
+
private selectFiles;
|
|
69
|
+
/**
|
|
70
|
+
* Drop files the index still lists but the working tree no longer has.
|
|
71
|
+
*
|
|
72
|
+
* Without this a deleted file answers searches forever: change detection
|
|
73
|
+
* only walks what exists on disk, so a removal is invisible to it — not
|
|
74
|
+
* even a targeted re-index of the deleted path notices, because that path
|
|
75
|
+
* simply fails to hash and is skipped.
|
|
76
|
+
*
|
|
77
|
+
* Two independent signals, because a run may not have seen the whole tree:
|
|
78
|
+
* - any scanned path that the manifest knows but cannot be read now;
|
|
79
|
+
* - on a complete scan only, any manifest path the scan never saw.
|
|
80
|
+
*/
|
|
81
|
+
private pruneDeletedFiles;
|
|
82
|
+
/**
|
|
83
|
+
* Register files whose content another branch already embedded, and return
|
|
84
|
+
* only those genuinely needing work.
|
|
85
|
+
*
|
|
86
|
+
* This is what makes branch switching cheap: chunks are content-addressed,
|
|
87
|
+
* so an identical file on another branch needs a manifest row, not a
|
|
88
|
+
* re-embed.
|
|
89
|
+
*/
|
|
90
|
+
private registerAlreadyKnownContent;
|
|
91
|
+
private chunkAll;
|
|
92
|
+
/** Drop chunks already embedded, then any the provider would reject. */
|
|
93
|
+
private selectChunksToEmbed;
|
|
94
|
+
private embedAndStore;
|
|
95
|
+
/** Commit files whose every chunk is now embedded and persisted. */
|
|
96
|
+
private commitCompletedFiles;
|
|
97
|
+
/**
|
|
98
|
+
* Commit files that produced no new chunks at all — everything they held
|
|
99
|
+
* was already indexed, oversized, or unparseable — provided none of their
|
|
100
|
+
* chunks failed to embed.
|
|
101
|
+
*/
|
|
102
|
+
private commitUntouchedFiles;
|
|
103
|
+
private commitFiles;
|
|
104
|
+
private report;
|
|
105
|
+
/**
|
|
106
|
+
* Fold new rows into the ANN index and compact the fragments they landed
|
|
107
|
+
* in. No-ops while the unindexed tail is small, so a watcher's periodic
|
|
108
|
+
* reconcile does not churn. Never fatal: an unoptimized index is slow and
|
|
109
|
+
* memory-hungry, not wrong.
|
|
110
|
+
*/
|
|
111
|
+
private runMaintenance;
|
|
112
|
+
}
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import { FileVersion } from "../../domain/corpus/FileVersion.js";
|
|
2
|
+
import { Duration } from "./Duration.js";
|
|
3
|
+
import { EmbeddingAbortError } from "./EmbeddingAbortError.js";
|
|
4
|
+
import { EmbeddingPipeline } from "./EmbeddingPipeline.js";
|
|
5
|
+
/**
|
|
6
|
+
* Turns a working tree into an index.
|
|
7
|
+
*
|
|
8
|
+
* The order of operations is what makes a run resumable after a crash: a
|
|
9
|
+
* file's manifest entry is written only once every one of its chunks is
|
|
10
|
+
* embedded *and* persisted. A hard stop therefore leaves completed files
|
|
11
|
+
* marked done (a resume skips them) and in-flight files unmarked (a resume
|
|
12
|
+
* re-embeds them cleanly, after dropping their partial chunks).
|
|
13
|
+
*/
|
|
14
|
+
export class IndexBuilder {
|
|
15
|
+
deps;
|
|
16
|
+
constructor(deps) {
|
|
17
|
+
this.deps = deps;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Held for the whole run: a watcher and an ad-hoc `lmgrep index` must not
|
|
21
|
+
* write concurrently, or they race into duplicate chunk rows.
|
|
22
|
+
*/
|
|
23
|
+
async build(options = {}) {
|
|
24
|
+
return this.deps.locks.withWriteLock(async () => {
|
|
25
|
+
const result = await this.buildLocked(options);
|
|
26
|
+
// Outside buildLocked on purpose. Sweeping is about branches that
|
|
27
|
+
// vanished from git, which has nothing to do with whether this run
|
|
28
|
+
// found anything to embed — and buildLocked returns early in five
|
|
29
|
+
// places, all of them reachable on a repo that never changes.
|
|
30
|
+
if (!options.dry) {
|
|
31
|
+
await this.deps.sweeper.sweep(this.deps.location.root);
|
|
32
|
+
this.deps.registerIndex();
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async buildLocked(options) {
|
|
38
|
+
const { logger } = this.deps;
|
|
39
|
+
if (options.reset) {
|
|
40
|
+
logger.info("Resetting index...");
|
|
41
|
+
await this.deps.maintenance.reset();
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
await this.deps.bootstrapper.bootstrap(this.deps.location.root);
|
|
45
|
+
}
|
|
46
|
+
const { files, complete } = this.selectFiles(options);
|
|
47
|
+
options.onProgress?.({
|
|
48
|
+
phase: "scan",
|
|
49
|
+
current: files.length,
|
|
50
|
+
total: files.length,
|
|
51
|
+
});
|
|
52
|
+
const manifest = await this.deps.manifest.current();
|
|
53
|
+
const { changed, current } = this.deps.workspace.detectChanges(files, manifest, this.deps.location.root);
|
|
54
|
+
// Deletions are handled before the early returns below: a run where
|
|
55
|
+
// nothing changed can still be a run where something was removed.
|
|
56
|
+
const removed = options.dry
|
|
57
|
+
? 0
|
|
58
|
+
: await this.pruneDeletedFiles(files, current, manifest, complete);
|
|
59
|
+
logger.info(`${changed.length} files changed out of ${files.length}`);
|
|
60
|
+
if (changed.length === 0) {
|
|
61
|
+
logger.info(removed > 0
|
|
62
|
+
? "No changes to index."
|
|
63
|
+
: "No changes detected. Index is up to date.");
|
|
64
|
+
return { succeeded: 0, failed: 0, removed };
|
|
65
|
+
}
|
|
66
|
+
const fresh = await this.registerAlreadyKnownContent(changed);
|
|
67
|
+
if (fresh.length === 0) {
|
|
68
|
+
logger.info("No new content to index.");
|
|
69
|
+
return { succeeded: 0, failed: 0, removed };
|
|
70
|
+
}
|
|
71
|
+
const chunks = await this.chunkAll(fresh, options);
|
|
72
|
+
if (chunks.length === 0) {
|
|
73
|
+
logger.info("No chunks produced. Index is up to date.");
|
|
74
|
+
return { succeeded: 0, failed: 0, removed };
|
|
75
|
+
}
|
|
76
|
+
const changedPaths = fresh.map((f) => f.path);
|
|
77
|
+
if (options.dry) {
|
|
78
|
+
for (const path of changedPaths)
|
|
79
|
+
logger.info(` ${path}`);
|
|
80
|
+
return { succeeded: 0, failed: 0, removed };
|
|
81
|
+
}
|
|
82
|
+
// Drop the previous version's chunks before writing the new ones, or
|
|
83
|
+
// both versions would answer searches.
|
|
84
|
+
await this.deps.chunks.deleteByFiles(changedPaths);
|
|
85
|
+
const toEmbed = await this.selectChunksToEmbed(chunks, changedPaths);
|
|
86
|
+
if (toEmbed.length === 0) {
|
|
87
|
+
await this.commitFiles(changedPaths, current);
|
|
88
|
+
logger.info("All chunks already indexed.");
|
|
89
|
+
return { succeeded: 0, failed: 0, removed };
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
...(await this.embedAndStore(toEmbed, changedPaths, current, options)),
|
|
93
|
+
removed,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The files this run will look at, and whether that is the whole tree.
|
|
98
|
+
*
|
|
99
|
+
* `complete` matters for deletion detection: only a full scan can prove a
|
|
100
|
+
* path is gone. A targeted or `--since` run sees a subset, where "absent
|
|
101
|
+
* from the scan" means nothing.
|
|
102
|
+
*/
|
|
103
|
+
selectFiles(options) {
|
|
104
|
+
const { logger, workspace, config, location } = this.deps;
|
|
105
|
+
if (options.files && options.files.length > 0) {
|
|
106
|
+
logger.info(`Processing ${options.files.length} targeted files`);
|
|
107
|
+
return { files: options.files, complete: false };
|
|
108
|
+
}
|
|
109
|
+
let files = workspace.listFiles(location.root, config.ignore, config.extensions);
|
|
110
|
+
if (options.since) {
|
|
111
|
+
const cutoff = Duration.parse(options.since).agoFrom(Date.now());
|
|
112
|
+
const before = files.length;
|
|
113
|
+
files = workspace.modifiedSince(files, location.root, cutoff);
|
|
114
|
+
logger.info(`Found ${files.length} files modified in the last ${options.since} (out of ${before})`);
|
|
115
|
+
return { files, complete: false };
|
|
116
|
+
}
|
|
117
|
+
logger.info(`Found ${files.length} files`);
|
|
118
|
+
return { files, complete: true };
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Drop files the index still lists but the working tree no longer has.
|
|
122
|
+
*
|
|
123
|
+
* Without this a deleted file answers searches forever: change detection
|
|
124
|
+
* only walks what exists on disk, so a removal is invisible to it — not
|
|
125
|
+
* even a targeted re-index of the deleted path notices, because that path
|
|
126
|
+
* simply fails to hash and is skipped.
|
|
127
|
+
*
|
|
128
|
+
* Two independent signals, because a run may not have seen the whole tree:
|
|
129
|
+
* - any scanned path that the manifest knows but cannot be read now;
|
|
130
|
+
* - on a complete scan only, any manifest path the scan never saw.
|
|
131
|
+
*/
|
|
132
|
+
async pruneDeletedFiles(scanned, readable, manifest, completeScan) {
|
|
133
|
+
const gone = new Set();
|
|
134
|
+
for (const path of scanned) {
|
|
135
|
+
if (!readable.has(path) && manifest.has(path))
|
|
136
|
+
gone.add(path);
|
|
137
|
+
}
|
|
138
|
+
// A complete scan that found nothing has not proven the repository is
|
|
139
|
+
// empty — far more likely the walk failed, or the tree is mid-checkout.
|
|
140
|
+
// Wiping the manifest on that evidence would force a full re-embed, so
|
|
141
|
+
// treat it the same way as a partial scan and prune nothing.
|
|
142
|
+
if (completeScan && scanned.length > 0) {
|
|
143
|
+
const seen = new Set(scanned);
|
|
144
|
+
for (const path of manifest.paths()) {
|
|
145
|
+
if (!seen.has(path))
|
|
146
|
+
gone.add(path);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else if (completeScan && !manifest.isEmpty) {
|
|
150
|
+
this.deps.logger.info("Scan found no files; skipping deletion check. " +
|
|
151
|
+
"Run `lmgrep index --reset` if the working tree really is empty.");
|
|
152
|
+
}
|
|
153
|
+
if (gone.size === 0)
|
|
154
|
+
return 0;
|
|
155
|
+
const paths = [...gone];
|
|
156
|
+
// Chunks first: the repository decides whether another branch still
|
|
157
|
+
// references the path and keeps them if so. Our manifest row goes
|
|
158
|
+
// either way.
|
|
159
|
+
await this.deps.chunks.deleteByFiles(paths);
|
|
160
|
+
await this.deps.manifest.deleteFiles(paths);
|
|
161
|
+
this.deps.logger.info(`Removed ${paths.length} file(s) deleted from the working tree`);
|
|
162
|
+
return paths.length;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Register files whose content another branch already embedded, and return
|
|
166
|
+
* only those genuinely needing work.
|
|
167
|
+
*
|
|
168
|
+
* This is what makes branch switching cheap: chunks are content-addressed,
|
|
169
|
+
* so an identical file on another branch needs a manifest row, not a
|
|
170
|
+
* re-embed.
|
|
171
|
+
*/
|
|
172
|
+
async registerAlreadyKnownContent(changed) {
|
|
173
|
+
const known = await this.deps.manifest.knownHashes(changed.map((f) => f.hash));
|
|
174
|
+
const alreadyIndexed = changed.filter((f) => known.has(f.hash.toString()));
|
|
175
|
+
const fresh = changed.filter((f) => !known.has(f.hash.toString()));
|
|
176
|
+
if (alreadyIndexed.length > 0) {
|
|
177
|
+
await this.deps.manifest.upsert(alreadyIndexed);
|
|
178
|
+
this.deps.logger.info(`${alreadyIndexed.length} files already indexed (content known from other branches)`);
|
|
179
|
+
}
|
|
180
|
+
return fresh;
|
|
181
|
+
}
|
|
182
|
+
async chunkAll(files, options) {
|
|
183
|
+
const all = [];
|
|
184
|
+
for (let i = 0; i < files.length; i++) {
|
|
185
|
+
const file = files[i];
|
|
186
|
+
try {
|
|
187
|
+
const produced = await this.deps.chunker.chunk(file.path, this.deps.location.root);
|
|
188
|
+
// Stamp each chunk with its file's version so search can scope
|
|
189
|
+
// to exactly the versions this branch references.
|
|
190
|
+
const version = FileVersion.of(file.hash);
|
|
191
|
+
for (const chunk of produced)
|
|
192
|
+
all.push(chunk.stampedWith(version));
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// A file that fails to parse is skipped, not fatal — one bad
|
|
196
|
+
// file must not abort a whole index run.
|
|
197
|
+
}
|
|
198
|
+
if ((i + 1) % 1000 === 0 || i === files.length - 1) {
|
|
199
|
+
options.onProgress?.({
|
|
200
|
+
phase: "chunk",
|
|
201
|
+
current: i + 1,
|
|
202
|
+
total: files.length,
|
|
203
|
+
message: `${all.length} chunks`,
|
|
204
|
+
});
|
|
205
|
+
this.deps.logger.info(`Chunking: ${i + 1}/${files.length} files, ${all.length} chunks so far`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return all;
|
|
209
|
+
}
|
|
210
|
+
/** Drop chunks already embedded, then any the provider would reject. */
|
|
211
|
+
async selectChunksToEmbed(chunks, changedPaths) {
|
|
212
|
+
const existing = await this.deps.chunks.existingHashes(chunks.map((c) => c.hash));
|
|
213
|
+
let candidates = chunks.filter((c) => !existing.has(c.hash.toString()));
|
|
214
|
+
const alreadyIndexed = chunks.length - candidates.length;
|
|
215
|
+
let oversized = 0;
|
|
216
|
+
const maxTokens = this.deps.config.maxTokens;
|
|
217
|
+
if (maxTokens) {
|
|
218
|
+
const before = candidates.length;
|
|
219
|
+
candidates = candidates.filter((c) => c.estimatedTokens() <= maxTokens);
|
|
220
|
+
oversized = before - candidates.length;
|
|
221
|
+
}
|
|
222
|
+
this.deps.logger.info(`${changedPaths.length} files changed, ${chunks.length} chunks total, ` +
|
|
223
|
+
`${candidates.length} to embed (${alreadyIndexed} already indexed` +
|
|
224
|
+
`${oversized > 0 ? `, ${oversized} oversized` : ""})`);
|
|
225
|
+
return candidates;
|
|
226
|
+
}
|
|
227
|
+
async embedAndStore(chunks, changedPaths, current, options) {
|
|
228
|
+
const { logger } = this.deps;
|
|
229
|
+
// Chunks still owed per file. A file commits only when this hits zero.
|
|
230
|
+
const outstanding = new Map();
|
|
231
|
+
for (const c of chunks) {
|
|
232
|
+
const path = c.location.filePath;
|
|
233
|
+
outstanding.set(path, (outstanding.get(path) ?? 0) + 1);
|
|
234
|
+
}
|
|
235
|
+
let succeeded = 0;
|
|
236
|
+
let stored = 0;
|
|
237
|
+
let dimensions;
|
|
238
|
+
const persist = async (items) => {
|
|
239
|
+
const embedded = items.map((it) => ({
|
|
240
|
+
chunk: chunks[it.index],
|
|
241
|
+
vector: it.vector,
|
|
242
|
+
}));
|
|
243
|
+
await this.deps.chunks.add(embedded);
|
|
244
|
+
succeeded += embedded.length;
|
|
245
|
+
stored += embedded.length;
|
|
246
|
+
dimensions ??= embedded[0]?.vector.dimensions;
|
|
247
|
+
options.onProgress?.({
|
|
248
|
+
phase: "store",
|
|
249
|
+
current: stored,
|
|
250
|
+
total: chunks.length,
|
|
251
|
+
});
|
|
252
|
+
await this.commitCompletedFiles(embedded, outstanding, current);
|
|
253
|
+
};
|
|
254
|
+
const pipeline = new EmbeddingPipeline(this.deps.embedder, this.deps.config, {
|
|
255
|
+
onBatchStart: (n, total) => options.onProgress?.({ phase: "embed", current: n, total }),
|
|
256
|
+
onBatchDone: (n, ok, failed) => logger.info(`Batch ${n}: ${ok} ok / ${failed} err / ${chunks.length} total`),
|
|
257
|
+
onReload: (attempt, max) => logger.info(`Consecutive failures — reloading model (attempt ${attempt}/${max})...`),
|
|
258
|
+
}, this.deps.reloadModel, this.deps.isLocalProvider);
|
|
259
|
+
let failedIndices;
|
|
260
|
+
let aborted = false;
|
|
261
|
+
try {
|
|
262
|
+
({ failedIndices } = await pipeline.run(chunks.map((c) => c.embeddingText()), persist));
|
|
263
|
+
}
|
|
264
|
+
catch (err) {
|
|
265
|
+
if (!(err instanceof EmbeddingAbortError))
|
|
266
|
+
throw err;
|
|
267
|
+
aborted = true;
|
|
268
|
+
failedIndices = err.failedIndices;
|
|
269
|
+
logger.error(err.message);
|
|
270
|
+
}
|
|
271
|
+
await this.commitUntouchedFiles(changedPaths, current, chunks, failedIndices, outstanding);
|
|
272
|
+
this.report(aborted, succeeded, failedIndices.size, changedPaths.length);
|
|
273
|
+
this.deps.recordMetadata(dimensions);
|
|
274
|
+
await this.runMaintenance(succeeded, options);
|
|
275
|
+
return { succeeded, failed: failedIndices.size, removed: 0 };
|
|
276
|
+
}
|
|
277
|
+
/** Commit files whose every chunk is now embedded and persisted. */
|
|
278
|
+
async commitCompletedFiles(embedded, outstanding, current) {
|
|
279
|
+
const completed = [];
|
|
280
|
+
for (const { chunk } of embedded) {
|
|
281
|
+
const path = chunk.location.filePath;
|
|
282
|
+
const left = (outstanding.get(path) ?? 0) - 1;
|
|
283
|
+
outstanding.set(path, left);
|
|
284
|
+
const hash = current.get(path);
|
|
285
|
+
if (left === 0 && hash) {
|
|
286
|
+
completed.push({ path, hash });
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (completed.length > 0)
|
|
290
|
+
await this.deps.manifest.upsert(completed);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Commit files that produced no new chunks at all — everything they held
|
|
294
|
+
* was already indexed, oversized, or unparseable — provided none of their
|
|
295
|
+
* chunks failed to embed.
|
|
296
|
+
*/
|
|
297
|
+
async commitUntouchedFiles(changedPaths, current, chunks, failedIndices, outstanding) {
|
|
298
|
+
const failedFiles = new Set();
|
|
299
|
+
for (const index of failedIndices) {
|
|
300
|
+
failedFiles.add(chunks[index].location.filePath);
|
|
301
|
+
}
|
|
302
|
+
const remaining = [];
|
|
303
|
+
for (const path of changedPaths) {
|
|
304
|
+
const hash = current.get(path);
|
|
305
|
+
if (!hash)
|
|
306
|
+
continue;
|
|
307
|
+
if (failedFiles.has(path))
|
|
308
|
+
continue;
|
|
309
|
+
if ((outstanding.get(path) ?? 0) !== 0)
|
|
310
|
+
continue;
|
|
311
|
+
remaining.push({ path, hash });
|
|
312
|
+
}
|
|
313
|
+
if (remaining.length > 0)
|
|
314
|
+
await this.deps.manifest.upsert(remaining);
|
|
315
|
+
}
|
|
316
|
+
async commitFiles(paths, current) {
|
|
317
|
+
const entries = [];
|
|
318
|
+
for (const path of paths) {
|
|
319
|
+
const hash = current.get(path);
|
|
320
|
+
if (hash)
|
|
321
|
+
entries.push({ path, hash });
|
|
322
|
+
}
|
|
323
|
+
if (entries.length > 0)
|
|
324
|
+
await this.deps.manifest.upsert(entries);
|
|
325
|
+
}
|
|
326
|
+
report(aborted, succeeded, failed, fileCount) {
|
|
327
|
+
const { logger } = this.deps;
|
|
328
|
+
if (aborted) {
|
|
329
|
+
if (succeeded > 0) {
|
|
330
|
+
logger.info(`Saved ${succeeded} chunks before aborting.`);
|
|
331
|
+
}
|
|
332
|
+
logger.info(`Embedding failed. ${failed} chunks could not be embedded. ` +
|
|
333
|
+
"Fix your embedding provider and run `lmgrep index` to resume.");
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
logger.info(`Done: ${succeeded} chunks indexed from ${fileCount} files` +
|
|
337
|
+
(failed > 0 ? ` (${failed} failed)` : ""));
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Fold new rows into the ANN index and compact the fragments they landed
|
|
341
|
+
* in. No-ops while the unindexed tail is small, so a watcher's periodic
|
|
342
|
+
* reconcile does not churn. Never fatal: an unoptimized index is slow and
|
|
343
|
+
* memory-hungry, not wrong.
|
|
344
|
+
*/
|
|
345
|
+
async runMaintenance(succeeded, options) {
|
|
346
|
+
if (succeeded === 0)
|
|
347
|
+
return;
|
|
348
|
+
try {
|
|
349
|
+
const report = await this.deps.maintenance.optimize({
|
|
350
|
+
create: options.createIndex ?? false,
|
|
351
|
+
});
|
|
352
|
+
for (const table of report.tables) {
|
|
353
|
+
if (table.action === "created") {
|
|
354
|
+
this.deps.logger.info(`Built vector index on ${table.table} (${table.rows} rows)`);
|
|
355
|
+
}
|
|
356
|
+
else if (table.action === "optimized") {
|
|
357
|
+
this.deps.logger.info(`Optimized ${table.table}: absorbed ${table.unindexed} unindexed rows`);
|
|
358
|
+
}
|
|
359
|
+
else if (table.action === "needs-index") {
|
|
360
|
+
this.deps.logger.info(`${table.table} has ${table.rows} rows and no vector index — ` +
|
|
361
|
+
"searches scan every embedding. Run `lmgrep compact` to build one.");
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch (err) {
|
|
366
|
+
this.deps.logger.error(`Index optimization skipped: ${err instanceof Error ? err.message : err}`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
//# sourceMappingURL=IndexBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IndexBuilder.js","sourceRoot":"","sources":["../../../src/application/indexing/IndexBuilder.ts"],"names":[],"mappings":"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"}
|