lmgrep 0.1.18 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -63
- 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 +97 -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/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 +61 -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 +21 -0
- package/dist/infrastructure/ai/OllamaProbe.js +69 -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 +13 -0
- package/dist/infrastructure/ai/ProviderModuleLoader.js +49 -0
- package/dist/infrastructure/ai/ProviderModuleLoader.js.map +1 -0
- package/dist/infrastructure/ai/ProviderRegistry.d.ts +37 -0
- package/dist/infrastructure/ai/ProviderRegistry.js +55 -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/LanguageCatalog.d.ts +30 -0
- package/dist/{lib/chunker/languages.js → infrastructure/treesitter/LanguageCatalog.js} +34 -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 +163 -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 +55 -0
- package/dist/presentation/cli/commands/ConfigCommands.js +204 -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 +84 -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,42 @@
|
|
|
1
|
+
import type { IndexMetadataPort } from "../../domain/ports/IndexMetadataPort.js";
|
|
2
|
+
import type { IndexMetadata } from "../../domain/project/IndexMetadata.js";
|
|
3
|
+
/**
|
|
4
|
+
* The `lmgrep.json` sidecar written beside each database.
|
|
5
|
+
*
|
|
6
|
+
* It records the model and dimensions the index was built with, which is what
|
|
7
|
+
* lets a later search refuse to run against incompatible embeddings instead of
|
|
8
|
+
* silently returning nonsense.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ProjectMetadataStore implements IndexMetadataPort {
|
|
11
|
+
private static readonly FILE;
|
|
12
|
+
/** What an lmgrep database looks like from the outside. */
|
|
13
|
+
private static readonly MARKERS;
|
|
14
|
+
read(databasePath: string): IndexMetadata | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Write the sidecar, preserving the model and dimensions already recorded.
|
|
17
|
+
*
|
|
18
|
+
* The first index establishes the baseline; later writes must not overwrite
|
|
19
|
+
* it, or a search with a different model would stop being detectable as a
|
|
20
|
+
* mismatch.
|
|
21
|
+
*/
|
|
22
|
+
write(databasePath: string, metadata: Omit<IndexMetadata, "indexedAt">): void;
|
|
23
|
+
/**
|
|
24
|
+
* Whether a directory holds an lmgrep database, or is an empty directory
|
|
25
|
+
* safe to treat as one.
|
|
26
|
+
*
|
|
27
|
+
* `--database <path>` lets a caller aim any directory at any command, so a
|
|
28
|
+
* destructive operation must confirm the target is ours before touching it
|
|
29
|
+
* — without this, `lmgrep prune --database .` would delete a working tree.
|
|
30
|
+
* An empty directory passes because that is what an interrupted index
|
|
31
|
+
* leaves behind, and removing it cannot lose data.
|
|
32
|
+
*/
|
|
33
|
+
isDatabaseDirectory(databasePath: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Whether a directory actually holds an index.
|
|
36
|
+
*
|
|
37
|
+
* Same markers as {@link isDatabaseDirectory}, without its allowance for
|
|
38
|
+
* an empty directory — the two are kept on one marker set so that what
|
|
39
|
+
* counts as a database is defined in exactly one place.
|
|
40
|
+
*/
|
|
41
|
+
holdsIndex(databasePath: string): boolean;
|
|
42
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { TableName } from "../lancedb/LanceTables.js";
|
|
4
|
+
/**
|
|
5
|
+
* The `lmgrep.json` sidecar written beside each database.
|
|
6
|
+
*
|
|
7
|
+
* It records the model and dimensions the index was built with, which is what
|
|
8
|
+
* lets a later search refuse to run against incompatible embeddings instead of
|
|
9
|
+
* silently returning nonsense.
|
|
10
|
+
*/
|
|
11
|
+
export class ProjectMetadataStore {
|
|
12
|
+
static FILE = "lmgrep.json";
|
|
13
|
+
/** What an lmgrep database looks like from the outside. */
|
|
14
|
+
static MARKERS = new Set([
|
|
15
|
+
ProjectMetadataStore.FILE,
|
|
16
|
+
`${TableName.Chunks}.lance`,
|
|
17
|
+
`${TableName.Files}.lance`,
|
|
18
|
+
`${TableName.LegacyVocab}.lance`,
|
|
19
|
+
]);
|
|
20
|
+
read(databasePath) {
|
|
21
|
+
try {
|
|
22
|
+
return JSON.parse(readFileSync(join(databasePath, ProjectMetadataStore.FILE), "utf-8"));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Write the sidecar, preserving the model and dimensions already recorded.
|
|
30
|
+
*
|
|
31
|
+
* The first index establishes the baseline; later writes must not overwrite
|
|
32
|
+
* it, or a search with a different model would stop being detectable as a
|
|
33
|
+
* mismatch.
|
|
34
|
+
*/
|
|
35
|
+
write(databasePath, metadata) {
|
|
36
|
+
mkdirSync(databasePath, { recursive: true });
|
|
37
|
+
const existing = this.read(databasePath);
|
|
38
|
+
const merged = {
|
|
39
|
+
root: metadata.root,
|
|
40
|
+
remote: metadata.remote,
|
|
41
|
+
branch: metadata.branch,
|
|
42
|
+
indexedAt: new Date().toISOString(),
|
|
43
|
+
model: existing?.model ?? metadata.model,
|
|
44
|
+
dimensions: existing?.dimensions ?? metadata.dimensions,
|
|
45
|
+
};
|
|
46
|
+
writeFileSync(join(databasePath, ProjectMetadataStore.FILE), JSON.stringify(merged, null, 2));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Whether a directory holds an lmgrep database, or is an empty directory
|
|
50
|
+
* safe to treat as one.
|
|
51
|
+
*
|
|
52
|
+
* `--database <path>` lets a caller aim any directory at any command, so a
|
|
53
|
+
* destructive operation must confirm the target is ours before touching it
|
|
54
|
+
* — without this, `lmgrep prune --database .` would delete a working tree.
|
|
55
|
+
* An empty directory passes because that is what an interrupted index
|
|
56
|
+
* leaves behind, and removing it cannot lose data.
|
|
57
|
+
*/
|
|
58
|
+
isDatabaseDirectory(databasePath) {
|
|
59
|
+
let entries;
|
|
60
|
+
try {
|
|
61
|
+
entries = readdirSync(databasePath);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (entries.length === 0)
|
|
67
|
+
return true;
|
|
68
|
+
return entries.some((e) => ProjectMetadataStore.MARKERS.has(e));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Whether a directory actually holds an index.
|
|
72
|
+
*
|
|
73
|
+
* Same markers as {@link isDatabaseDirectory}, without its allowance for
|
|
74
|
+
* an empty directory — the two are kept on one marker set so that what
|
|
75
|
+
* counts as a database is defined in exactly one place.
|
|
76
|
+
*/
|
|
77
|
+
holdsIndex(databasePath) {
|
|
78
|
+
try {
|
|
79
|
+
return readdirSync(databasePath).some((e) => ProjectMetadataStore.MARKERS.has(e));
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=ProjectMetadataStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectMetadataStore.js","sourceRoot":"","sources":["../../../src/infrastructure/fs/ProjectMetadataStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,OAAO,oBAAoB;IACxB,MAAM,CAAU,IAAI,GAAG,aAAa,CAAC;IAC7C,2DAA2D;IACnD,MAAM,CAAU,OAAO,GAAG,IAAI,GAAG,CAAS;QACjD,oBAAoB,CAAC,IAAI;QACzB,GAAG,SAAS,CAAC,MAAM,QAAQ;QAC3B,GAAG,SAAS,CAAC,KAAK,QAAQ;QAC1B,GAAG,SAAS,CAAC,WAAW,QAAQ;KAChC,CAAC,CAAC;IAEH,IAAI,CAAC,YAAoB;QACxB,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,KAAK,CAChB,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,oBAAoB,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CACnD,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CACJ,YAAoB,EACpB,QAA0C;QAE1C,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzC,MAAM,MAAM,GAAkB;YAC7B,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,QAAQ,CAAC,KAAK;YACxC,UAAU,EAAE,QAAQ,EAAE,UAAU,IAAI,QAAQ,CAAC,UAAU;SACvD,CAAC;QACF,aAAa,CACZ,IAAI,CAAC,YAAY,EAAE,oBAAoB,CAAC,IAAI,CAAC,EAC7C,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAC/B,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,mBAAmB,CAAC,YAAoB;QACvC,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACJ,OAAO,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,YAAoB;QAC9B,IAAI,CAAC;YACJ,OAAO,WAAW,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3C,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CACnC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ProjectRegistryPort, RegisteredIndex } from "../../domain/ports/ProjectRegistryPort.js";
|
|
2
|
+
import type { StateDirectoryPort } from "../../domain/ports/StateDirectoryPort.js";
|
|
3
|
+
/**
|
|
4
|
+
* ProjectRegistryPort as one small JSON file per database.
|
|
5
|
+
*
|
|
6
|
+
* One file per entry rather than one file listing all of them, because several
|
|
7
|
+
* lmgrep processes index different projects at the same time — a shared list
|
|
8
|
+
* would need a lock and would still lose writes if one crashed mid-rewrite.
|
|
9
|
+
* Separate files make every write independent and every partial write
|
|
10
|
+
* survivable: a corrupt entry is skipped, not fatal to the listing.
|
|
11
|
+
*/
|
|
12
|
+
export declare class ProjectRegistry implements ProjectRegistryPort {
|
|
13
|
+
private readonly state;
|
|
14
|
+
private static readonly SUFFIX;
|
|
15
|
+
private static readonly KEY_LENGTH;
|
|
16
|
+
constructor(state: StateDirectoryPort);
|
|
17
|
+
record(entry: Omit<RegisteredIndex, "indexedAt">): void;
|
|
18
|
+
list(): RegisteredIndex[];
|
|
19
|
+
dangling(): RegisteredIndex[];
|
|
20
|
+
forget(databasePath: string): void;
|
|
21
|
+
private all;
|
|
22
|
+
private exists;
|
|
23
|
+
/** Keyed by database path, so re-indexing refreshes rather than duplicates. */
|
|
24
|
+
private pathFor;
|
|
25
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { mkdirSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* ProjectRegistryPort as one small JSON file per database.
|
|
6
|
+
*
|
|
7
|
+
* One file per entry rather than one file listing all of them, because several
|
|
8
|
+
* lmgrep processes index different projects at the same time — a shared list
|
|
9
|
+
* would need a lock and would still lose writes if one crashed mid-rewrite.
|
|
10
|
+
* Separate files make every write independent and every partial write
|
|
11
|
+
* survivable: a corrupt entry is skipped, not fatal to the listing.
|
|
12
|
+
*/
|
|
13
|
+
export class ProjectRegistry {
|
|
14
|
+
state;
|
|
15
|
+
static SUFFIX = ".json";
|
|
16
|
+
static KEY_LENGTH = 16;
|
|
17
|
+
constructor(state) {
|
|
18
|
+
this.state = state;
|
|
19
|
+
}
|
|
20
|
+
record(entry) {
|
|
21
|
+
const directory = this.state.registryDirectory();
|
|
22
|
+
mkdirSync(directory, { recursive: true });
|
|
23
|
+
const full = {
|
|
24
|
+
...entry,
|
|
25
|
+
indexedAt: new Date().toISOString(),
|
|
26
|
+
};
|
|
27
|
+
writeFileSync(this.pathFor(entry.databasePath), JSON.stringify(full, null, 2));
|
|
28
|
+
}
|
|
29
|
+
list() {
|
|
30
|
+
return this.all().filter((e) => this.exists(e.databasePath));
|
|
31
|
+
}
|
|
32
|
+
dangling() {
|
|
33
|
+
return this.all().filter((e) => !this.exists(e.databasePath));
|
|
34
|
+
}
|
|
35
|
+
forget(databasePath) {
|
|
36
|
+
try {
|
|
37
|
+
unlinkSync(this.pathFor(databasePath));
|
|
38
|
+
}
|
|
39
|
+
catch { }
|
|
40
|
+
}
|
|
41
|
+
all() {
|
|
42
|
+
let names;
|
|
43
|
+
try {
|
|
44
|
+
names = readdirSync(this.state.registryDirectory());
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
const out = [];
|
|
50
|
+
for (const name of names) {
|
|
51
|
+
if (!name.endsWith(ProjectRegistry.SUFFIX))
|
|
52
|
+
continue;
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(readFileSync(join(this.state.registryDirectory(), name), "utf-8"));
|
|
55
|
+
if (typeof parsed.databasePath === "string" && parsed.databasePath) {
|
|
56
|
+
out.push(parsed);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// A truncated or hand-edited entry is a lost pointer, never a
|
|
61
|
+
// reason to fail the listing that would have shown the rest.
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
exists(databasePath) {
|
|
67
|
+
try {
|
|
68
|
+
return statSync(databasePath).isDirectory();
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** Keyed by database path, so re-indexing refreshes rather than duplicates. */
|
|
75
|
+
pathFor(databasePath) {
|
|
76
|
+
const key = createHash("sha256")
|
|
77
|
+
.update(databasePath)
|
|
78
|
+
.digest("hex")
|
|
79
|
+
.slice(0, ProjectRegistry.KEY_LENGTH);
|
|
80
|
+
return join(this.state.registryDirectory(), `${key}${ProjectRegistry.SUFFIX}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=ProjectRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectRegistry.js","sourceRoot":"","sources":["../../../src/infrastructure/fs/ProjectRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { StateDirectoryPort } from "../../domain/ports/StateDirectoryPort.js";
|
|
2
|
+
/**
|
|
3
|
+
* StateDirectoryPort over the real filesystem, rooted at the XDG state
|
|
4
|
+
* location.
|
|
5
|
+
*
|
|
6
|
+
* The subdirectories are new; earlier versions wrote databases and their lock
|
|
7
|
+
* files as immediate children of the root, interleaved. {@link RESERVED} is
|
|
8
|
+
* what keeps the two schemes apart, so a legacy scan never mistakes the
|
|
9
|
+
* registry for a database.
|
|
10
|
+
*
|
|
11
|
+
* Existence probes swallow their errors: an unreadable or missing path is
|
|
12
|
+
* simply "not a database", never a failure.
|
|
13
|
+
*/
|
|
14
|
+
export declare class StateDirectory implements StateDirectoryPort {
|
|
15
|
+
private static readonly LOCKS;
|
|
16
|
+
private static readonly REGISTRY;
|
|
17
|
+
private static readonly DATABASES;
|
|
18
|
+
/** Subdirectories of the state root that are not legacy databases. */
|
|
19
|
+
private static readonly RESERVED;
|
|
20
|
+
private readonly base;
|
|
21
|
+
constructor(base?: string);
|
|
22
|
+
root(): string;
|
|
23
|
+
isDirectory(path: string): boolean;
|
|
24
|
+
locksDirectory(): string;
|
|
25
|
+
registryDirectory(): string;
|
|
26
|
+
databasesDirectory(): string;
|
|
27
|
+
legacyDatabaseDirectories(): string[];
|
|
28
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { readdirSync, statSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* StateDirectoryPort over the real filesystem, rooted at the XDG state
|
|
6
|
+
* location.
|
|
7
|
+
*
|
|
8
|
+
* The subdirectories are new; earlier versions wrote databases and their lock
|
|
9
|
+
* files as immediate children of the root, interleaved. {@link RESERVED} is
|
|
10
|
+
* what keeps the two schemes apart, so a legacy scan never mistakes the
|
|
11
|
+
* registry for a database.
|
|
12
|
+
*
|
|
13
|
+
* Existence probes swallow their errors: an unreadable or missing path is
|
|
14
|
+
* simply "not a database", never a failure.
|
|
15
|
+
*/
|
|
16
|
+
export class StateDirectory {
|
|
17
|
+
static LOCKS = "locks";
|
|
18
|
+
static REGISTRY = "registry";
|
|
19
|
+
static DATABASES = "db";
|
|
20
|
+
/** Subdirectories of the state root that are not legacy databases. */
|
|
21
|
+
static RESERVED = new Set([
|
|
22
|
+
StateDirectory.LOCKS,
|
|
23
|
+
StateDirectory.REGISTRY,
|
|
24
|
+
StateDirectory.DATABASES,
|
|
25
|
+
]);
|
|
26
|
+
base;
|
|
27
|
+
constructor(base) {
|
|
28
|
+
// LMGREP_STATE_DIR relocates everything machine-global in one step,
|
|
29
|
+
// which is what makes an isolated run possible without also moving
|
|
30
|
+
// HOME — moving HOME breaks provider resolution, since AI SDK packages
|
|
31
|
+
// are found through the user's global node_modules.
|
|
32
|
+
this.base =
|
|
33
|
+
base ??
|
|
34
|
+
process.env.LMGREP_STATE_DIR ??
|
|
35
|
+
join(homedir(), ".local", "state", "lmgrep");
|
|
36
|
+
}
|
|
37
|
+
root() {
|
|
38
|
+
return this.base;
|
|
39
|
+
}
|
|
40
|
+
isDirectory(path) {
|
|
41
|
+
try {
|
|
42
|
+
return statSync(path).isDirectory();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
locksDirectory() {
|
|
49
|
+
return join(this.base, StateDirectory.LOCKS);
|
|
50
|
+
}
|
|
51
|
+
registryDirectory() {
|
|
52
|
+
return join(this.base, StateDirectory.REGISTRY);
|
|
53
|
+
}
|
|
54
|
+
databasesDirectory() {
|
|
55
|
+
return join(this.base, StateDirectory.DATABASES);
|
|
56
|
+
}
|
|
57
|
+
legacyDatabaseDirectories() {
|
|
58
|
+
let entries;
|
|
59
|
+
try {
|
|
60
|
+
entries = readdirSync(this.base);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
return entries
|
|
66
|
+
.filter((name) => !StateDirectory.RESERVED.has(name))
|
|
67
|
+
.map((name) => join(this.base, name))
|
|
68
|
+
.filter((p) => this.isDirectory(p));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=StateDirectory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StateDirectory.js","sourceRoot":"","sources":["../../../src/infrastructure/fs/StateDirectory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,cAAc;IAClB,MAAM,CAAU,KAAK,GAAG,OAAO,CAAC;IAChC,MAAM,CAAU,QAAQ,GAAG,UAAU,CAAC;IACtC,MAAM,CAAU,SAAS,GAAG,IAAI,CAAC;IACzC,sEAAsE;IAC9D,MAAM,CAAU,QAAQ,GAAG,IAAI,GAAG,CAAS;QAClD,cAAc,CAAC,KAAK;QACpB,cAAc,CAAC,QAAQ;QACvB,cAAc,CAAC,SAAS;KACxB,CAAC,CAAC;IAEc,IAAI,CAAS;IAE9B,YAAY,IAAa;QACxB,oEAAoE;QACpE,mEAAmE;QACnE,uEAAuE;QACvE,oDAAoD;QACpD,IAAI,CAAC,IAAI;YACR,IAAI;gBACJ,OAAO,CAAC,GAAG,CAAC,gBAAgB;gBAC5B,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI;QACH,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,WAAW,CAAC,IAAY;QACvB,IAAI,CAAC;YACJ,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAED,cAAc;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED,iBAAiB;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC;IAED,kBAAkB;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;IAED,yBAAyB;QACxB,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACJ,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,EAAE,CAAC;QACX,CAAC;QACD,OAAO,OAAO;aACZ,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;aACpD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;aACpC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ContentHash } from "../../domain/corpus/ContentHash.js";
|
|
2
|
+
import type { ChangeSet, ExtensionRules, WatchHandle, WorkspacePort } from "../../domain/ports/WorkspacePort.js";
|
|
3
|
+
/** The working tree on the real filesystem. */
|
|
4
|
+
export declare class Workspace implements WorkspacePort {
|
|
5
|
+
listFiles(cwd: string, extraIgnore?: string[], extensions?: ExtensionRules): string[];
|
|
6
|
+
hashOf(cwd: string, filePath: string): ContentHash | undefined;
|
|
7
|
+
modifiedSince(files: string[], cwd: string, cutoffMs: number): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Compare on-disk hashes against what the manifest recorded.
|
|
10
|
+
*
|
|
11
|
+
* Unreadable files are skipped rather than reported as changed — a
|
|
12
|
+
* transient read error should not evict a file from the index.
|
|
13
|
+
*/
|
|
14
|
+
detectChanges(files: string[], manifest: {
|
|
15
|
+
versionOf(path: string): ContentHash | undefined;
|
|
16
|
+
}, cwd: string, force?: boolean): ChangeSet;
|
|
17
|
+
/**
|
|
18
|
+
* Watch for changes, coalescing a burst into one callback.
|
|
19
|
+
*
|
|
20
|
+
* fs.watch's recursive mode misses events on Linux (new subdirectories,
|
|
21
|
+
* editor atomic saves); callers pair this with a periodic reconcile rather
|
|
22
|
+
* than trusting it alone.
|
|
23
|
+
*/
|
|
24
|
+
watch(cwd: string, extraIgnore: string[] | undefined, onChanges: (changedFiles: string[]) => void, debounceMs: number, extensions?: ExtensionRules): WatchHandle;
|
|
25
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { readFileSync, statSync, watch } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { globSync } from "glob";
|
|
4
|
+
import { ContentHash } from "../../domain/corpus/ContentHash.js";
|
|
5
|
+
import { SourceFile } from "../../domain/corpus/SourceFile.js";
|
|
6
|
+
import { IndexableFileRules } from "./IndexableFileRules.js";
|
|
7
|
+
/** The working tree on the real filesystem. */
|
|
8
|
+
export class Workspace {
|
|
9
|
+
listFiles(cwd, extraIgnore, extensions) {
|
|
10
|
+
const rules = new IndexableFileRules(cwd, extraIgnore, extensions);
|
|
11
|
+
const all = globSync("**/*", { cwd, nodir: true, dot: false });
|
|
12
|
+
rules.loadNestedIgnores(all);
|
|
13
|
+
return all.filter((f) => rules.admits(f));
|
|
14
|
+
}
|
|
15
|
+
hashOf(cwd, filePath) {
|
|
16
|
+
try {
|
|
17
|
+
return ContentHash.of(readFileSync(join(cwd, filePath)));
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
modifiedSince(files, cwd, cutoffMs) {
|
|
24
|
+
return files.filter((f) => {
|
|
25
|
+
try {
|
|
26
|
+
return statSync(join(cwd, f)).mtimeMs >= cutoffMs;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Compare on-disk hashes against what the manifest recorded.
|
|
35
|
+
*
|
|
36
|
+
* Unreadable files are skipped rather than reported as changed — a
|
|
37
|
+
* transient read error should not evict a file from the index.
|
|
38
|
+
*/
|
|
39
|
+
detectChanges(files, manifest, cwd, force = false) {
|
|
40
|
+
const changed = [];
|
|
41
|
+
const current = new Map();
|
|
42
|
+
for (const file of files) {
|
|
43
|
+
const hash = this.hashOf(cwd, file);
|
|
44
|
+
if (!hash)
|
|
45
|
+
continue;
|
|
46
|
+
current.set(file, hash);
|
|
47
|
+
const stored = manifest.versionOf(file);
|
|
48
|
+
if (force || stored === undefined || !stored.equals(hash)) {
|
|
49
|
+
changed.push(new SourceFile(file, hash));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { changed, current };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Watch for changes, coalescing a burst into one callback.
|
|
56
|
+
*
|
|
57
|
+
* fs.watch's recursive mode misses events on Linux (new subdirectories,
|
|
58
|
+
* editor atomic saves); callers pair this with a periodic reconcile rather
|
|
59
|
+
* than trusting it alone.
|
|
60
|
+
*/
|
|
61
|
+
watch(cwd, extraIgnore, onChanges, debounceMs, extensions) {
|
|
62
|
+
const rules = new IndexableFileRules(cwd, extraIgnore, extensions);
|
|
63
|
+
let timer;
|
|
64
|
+
let pending = new Set();
|
|
65
|
+
const watcher = watch(cwd, { recursive: true }, (_event, filename) => {
|
|
66
|
+
if (!filename)
|
|
67
|
+
return;
|
|
68
|
+
if (!rules.hasIndexableExtension(filename))
|
|
69
|
+
return;
|
|
70
|
+
if (rules.isIgnored(filename))
|
|
71
|
+
return;
|
|
72
|
+
pending.add(filename);
|
|
73
|
+
if (timer)
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
timer = setTimeout(() => {
|
|
76
|
+
const files = [...pending];
|
|
77
|
+
pending = new Set();
|
|
78
|
+
onChanges(files);
|
|
79
|
+
}, debounceMs);
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
close() {
|
|
83
|
+
if (timer)
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
watcher.close();
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=Workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Workspace.js","sourceRoot":"","sources":["../../../src/infrastructure/fs/Workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { GitPort } from "../../domain/ports/GitPort.js";
|
|
2
|
+
/**
|
|
3
|
+
* GitPort over the `git` binary.
|
|
4
|
+
*
|
|
5
|
+
* Every call is best-effort: a missing binary, a non-repo directory, or a
|
|
6
|
+
* detached/oprhaned state all surface as `undefined` rather than throwing,
|
|
7
|
+
* because every caller treats "not a git repo" as an ordinary case.
|
|
8
|
+
*/
|
|
9
|
+
export declare class GitClient implements GitPort {
|
|
10
|
+
private static readonly TIMEOUT_MS;
|
|
11
|
+
toplevel(cwd: string): string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* `--git-common-dir` reports a path *relative to the invocation directory*
|
|
14
|
+
* (`../../.git` from a subdirectory), so it is resolved against that
|
|
15
|
+
* directory rather than used as given. `--path-format=absolute` would do
|
|
16
|
+
* the same but only on git 2.31 and later.
|
|
17
|
+
*/
|
|
18
|
+
commonDir(cwd: string): string | undefined;
|
|
19
|
+
currentBranch(repoRoot: string): string | undefined;
|
|
20
|
+
originUrl(repoRoot: string): string | undefined;
|
|
21
|
+
mergeBase(repoRoot: string, ref: string): string | undefined;
|
|
22
|
+
commitDistance(repoRoot: string, from: string, to: string): number | undefined;
|
|
23
|
+
localBranches(repoRoot: string): string[];
|
|
24
|
+
/**
|
|
25
|
+
* Run git with an argv array rather than a command string.
|
|
26
|
+
*
|
|
27
|
+
* This must not go through a shell. Git's own format specifiers contain
|
|
28
|
+
* parentheses (`--format=%(refname:short)`), and branch names may legally
|
|
29
|
+
* contain `(`, `)`, `&`, `;`, `$` and quotes — all of which a shell would
|
|
30
|
+
* interpret. Passing a string here silently broke branch listing entirely
|
|
31
|
+
* and made any branch name with a metacharacter unusable.
|
|
32
|
+
*/
|
|
33
|
+
private run;
|
|
34
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* GitPort over the `git` binary.
|
|
5
|
+
*
|
|
6
|
+
* Every call is best-effort: a missing binary, a non-repo directory, or a
|
|
7
|
+
* detached/oprhaned state all surface as `undefined` rather than throwing,
|
|
8
|
+
* because every caller treats "not a git repo" as an ordinary case.
|
|
9
|
+
*/
|
|
10
|
+
export class GitClient {
|
|
11
|
+
static TIMEOUT_MS = 5000;
|
|
12
|
+
toplevel(cwd) {
|
|
13
|
+
return this.run(cwd, "rev-parse", "--show-toplevel");
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* `--git-common-dir` reports a path *relative to the invocation directory*
|
|
17
|
+
* (`../../.git` from a subdirectory), so it is resolved against that
|
|
18
|
+
* directory rather than used as given. `--path-format=absolute` would do
|
|
19
|
+
* the same but only on git 2.31 and later.
|
|
20
|
+
*/
|
|
21
|
+
commonDir(cwd) {
|
|
22
|
+
const out = this.run(cwd, "rev-parse", "--git-common-dir");
|
|
23
|
+
return out === undefined ? undefined : resolve(cwd, out);
|
|
24
|
+
}
|
|
25
|
+
currentBranch(repoRoot) {
|
|
26
|
+
return this.run(repoRoot, "rev-parse", "--abbrev-ref", "HEAD");
|
|
27
|
+
}
|
|
28
|
+
originUrl(repoRoot) {
|
|
29
|
+
return this.run(repoRoot, "remote", "get-url", "origin");
|
|
30
|
+
}
|
|
31
|
+
mergeBase(repoRoot, ref) {
|
|
32
|
+
return this.run(repoRoot, "merge-base", "HEAD", ref);
|
|
33
|
+
}
|
|
34
|
+
commitDistance(repoRoot, from, to) {
|
|
35
|
+
const out = this.run(repoRoot, "rev-list", "--count", `${from}..${to}`);
|
|
36
|
+
if (out === undefined)
|
|
37
|
+
return undefined;
|
|
38
|
+
const n = Number.parseInt(out, 10);
|
|
39
|
+
return Number.isNaN(n) ? undefined : n;
|
|
40
|
+
}
|
|
41
|
+
localBranches(repoRoot) {
|
|
42
|
+
const out = this.run(repoRoot, "for-each-ref", "--format=%(refname:short)", "refs/heads");
|
|
43
|
+
if (!out)
|
|
44
|
+
return [];
|
|
45
|
+
return out
|
|
46
|
+
.split("\n")
|
|
47
|
+
.map((l) => l.trim())
|
|
48
|
+
.filter(Boolean);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Run git with an argv array rather than a command string.
|
|
52
|
+
*
|
|
53
|
+
* This must not go through a shell. Git's own format specifiers contain
|
|
54
|
+
* parentheses (`--format=%(refname:short)`), and branch names may legally
|
|
55
|
+
* contain `(`, `)`, `&`, `;`, `$` and quotes — all of which a shell would
|
|
56
|
+
* interpret. Passing a string here silently broke branch listing entirely
|
|
57
|
+
* and made any branch name with a metacharacter unusable.
|
|
58
|
+
*/
|
|
59
|
+
run(cwd, ...args) {
|
|
60
|
+
try {
|
|
61
|
+
return execFileSync("git", args, {
|
|
62
|
+
cwd,
|
|
63
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
64
|
+
timeout: GitClient.TIMEOUT_MS,
|
|
65
|
+
})
|
|
66
|
+
.toString()
|
|
67
|
+
.trim();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=GitClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitClient.js","sourceRoot":"","sources":["../../../src/infrastructure/git/GitClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;;;GAMG;AACH,MAAM,OAAO,SAAS;IACb,MAAM,CAAU,UAAU,GAAG,IAAI,CAAC;IAE1C,QAAQ,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;IACtD,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,GAAW;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAC;QAC3D,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,aAAa,CAAC,QAAgB;QAC7B,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC;IAED,SAAS,CAAC,QAAgB;QACzB,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC1D,CAAC;IAED,SAAS,CAAC,QAAgB,EAAE,GAAW;QACtC,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IACtD,CAAC;IAED,cAAc,CACb,QAAgB,EAChB,IAAY,EACZ,EAAU;QAEV,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;QACxE,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACxC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,aAAa,CAAC,QAAgB;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CACnB,QAAQ,EACR,cAAc,EACd,2BAA2B,EAC3B,YAAY,CACZ,CAAC;QACF,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,OAAO,GAAG;aACR,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;IAED;;;;;;;;OAQG;IACK,GAAG,CAAC,GAAW,EAAE,GAAG,IAAc;QACzC,IAAI,CAAC;YACJ,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE;gBAChC,GAAG;gBACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;gBACnC,OAAO,EAAE,SAAS,CAAC,UAAU;aAC7B,CAAC;iBACA,QAAQ,EAAE;iBACV,IAAI,EAAE,CAAC;QACV,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Chunk } from "../../domain/corpus/Chunk.js";
|
|
2
|
+
import { ContentHash } from "../../domain/corpus/ContentHash.js";
|
|
3
|
+
import type { ChunkQuery, ChunkRepositoryPort, ChunkText, EmbeddedChunk } from "../../domain/ports/ChunkRepositoryPort.js";
|
|
4
|
+
import type { FileManifestRepositoryPort } from "../../domain/ports/FileManifestRepositoryPort.js";
|
|
5
|
+
import type { Branch } from "../../domain/project/Branch.js";
|
|
6
|
+
import { HitList } from "../../domain/retrieval/HitList.js";
|
|
7
|
+
import { LanceTables } from "./LanceTables.js";
|
|
8
|
+
/**
|
|
9
|
+
* Embedded chunks in LanceDB.
|
|
10
|
+
*
|
|
11
|
+
* Branch scoping lives here because it is a property of how chunks are stored:
|
|
12
|
+
* they are shared across branches by content hash, so a query must intersect
|
|
13
|
+
* them with the manifest of file versions the branch actually references.
|
|
14
|
+
*/
|
|
15
|
+
export declare class ChunkRepository implements ChunkRepositoryPort {
|
|
16
|
+
private readonly tables;
|
|
17
|
+
private readonly manifest;
|
|
18
|
+
private readonly branch;
|
|
19
|
+
constructor(tables: LanceTables, manifest: FileManifestRepositoryPort, branch: Branch);
|
|
20
|
+
add(chunks: EmbeddedChunk[]): Promise<void>;
|
|
21
|
+
search(query: ChunkQuery): Promise<HitList>;
|
|
22
|
+
/**
|
|
23
|
+
* Delete chunks for files no longer referenced by ANY branch. A path still
|
|
24
|
+
* present in another branch's manifest keeps its chunks — they are shared
|
|
25
|
+
* by content, so deleting them would blank that branch's results.
|
|
26
|
+
*/
|
|
27
|
+
deleteByFiles(filePaths: string[]): Promise<void>;
|
|
28
|
+
existingHashes(hashes: ContentHash[]): Promise<Set<string>>;
|
|
29
|
+
count(): Promise<number>;
|
|
30
|
+
hashesByFile(): Promise<Map<string, string[]>>;
|
|
31
|
+
allHashes(): Promise<Set<string>>;
|
|
32
|
+
streamTexts(batchSize?: number): AsyncGenerator<ChunkText[]>;
|
|
33
|
+
private buildPredicate;
|
|
34
|
+
private toRow;
|
|
35
|
+
private toHit;
|
|
36
|
+
/** Rebuild a domain Chunk from a stored row — used by import and dedup. */
|
|
37
|
+
static rowToChunk(row: Record<string, unknown>): Chunk;
|
|
38
|
+
}
|