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,52 @@
|
|
|
1
|
+
import type { LockPort } from "../../domain/ports/LockPort.js";
|
|
2
|
+
/**
|
|
3
|
+
* The two locks a database has, which exist for different reasons and are
|
|
4
|
+
* therefore scoped differently.
|
|
5
|
+
*
|
|
6
|
+
* The **write mutex** (`.writelock`) is per *database*, because that is what
|
|
7
|
+
* concurrent writers actually contend for: two indexers writing the same
|
|
8
|
+
* tables race into duplicate rows. It is held only around a build.
|
|
9
|
+
*
|
|
10
|
+
* The **maintainer** lock is per *worktree*. Watching is inherently per
|
|
11
|
+
* working tree — a watcher scans its own root and maintains its own branch's
|
|
12
|
+
* manifest — but worktrees of one repository share a single database. Keying
|
|
13
|
+
* this lock by database, as it once was, meant the first worktree to start
|
|
14
|
+
* silently prevented every sibling from ever watching, leaving their branches
|
|
15
|
+
* to go stale with no indication. It also doubles as the liveness registry
|
|
16
|
+
* `lmgrep status` reads, which is why the owning worktree is recorded in it.
|
|
17
|
+
*
|
|
18
|
+
* Both live in the state directory rather than beside the database. Locks
|
|
19
|
+
* coordinate processes on *this machine*; a database now lives inside a
|
|
20
|
+
* repository, which may be on a network filesystem, may be read-only, and is
|
|
21
|
+
* the wrong place to record which local pid is busy with it. Keeping them
|
|
22
|
+
* together in one directory is also what lets `status` find every running
|
|
23
|
+
* lmgrep by reading a single directory.
|
|
24
|
+
*/
|
|
25
|
+
export declare class DatabaseLocks implements LockPort {
|
|
26
|
+
private readonly databasePath;
|
|
27
|
+
/** Working tree this process would be responsible for. */
|
|
28
|
+
private readonly workspaceRoot;
|
|
29
|
+
private static readonly DEFAULT_WAIT_MS;
|
|
30
|
+
private static readonly DEFAULT_POLL_MS;
|
|
31
|
+
/** Enough to separate worktrees without making the filename unreadable. */
|
|
32
|
+
private static readonly ROOT_DIGEST_LENGTH;
|
|
33
|
+
private readonly maintainer;
|
|
34
|
+
private readonly writer;
|
|
35
|
+
constructor(locksDirectory: string, databasePath: string,
|
|
36
|
+
/** Working tree this process would be responsible for. */
|
|
37
|
+
workspaceRoot: string);
|
|
38
|
+
acquireMaintainer(): boolean;
|
|
39
|
+
releaseMaintainer(): void;
|
|
40
|
+
isMaintained(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Run `fn` holding the write mutex. Waits for a busy lock, taking over one
|
|
43
|
+
* whose owner has died. Throws if it cannot be acquired in time — better to
|
|
44
|
+
* fail than to write concurrently and duplicate rows.
|
|
45
|
+
*/
|
|
46
|
+
withWriteLock<T>(fn: () => Promise<T>, options?: {
|
|
47
|
+
waitMs?: number;
|
|
48
|
+
pollMs?: number;
|
|
49
|
+
}): Promise<T>;
|
|
50
|
+
/** Short stable name for a path, used to key lock files. */
|
|
51
|
+
private static digestOf;
|
|
52
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { PidFileLock } from "./PidFileLock.js";
|
|
4
|
+
/**
|
|
5
|
+
* The two locks a database has, which exist for different reasons and are
|
|
6
|
+
* therefore scoped differently.
|
|
7
|
+
*
|
|
8
|
+
* The **write mutex** (`.writelock`) is per *database*, because that is what
|
|
9
|
+
* concurrent writers actually contend for: two indexers writing the same
|
|
10
|
+
* tables race into duplicate rows. It is held only around a build.
|
|
11
|
+
*
|
|
12
|
+
* The **maintainer** lock is per *worktree*. Watching is inherently per
|
|
13
|
+
* working tree — a watcher scans its own root and maintains its own branch's
|
|
14
|
+
* manifest — but worktrees of one repository share a single database. Keying
|
|
15
|
+
* this lock by database, as it once was, meant the first worktree to start
|
|
16
|
+
* silently prevented every sibling from ever watching, leaving their branches
|
|
17
|
+
* to go stale with no indication. It also doubles as the liveness registry
|
|
18
|
+
* `lmgrep status` reads, which is why the owning worktree is recorded in it.
|
|
19
|
+
*
|
|
20
|
+
* Both live in the state directory rather than beside the database. Locks
|
|
21
|
+
* coordinate processes on *this machine*; a database now lives inside a
|
|
22
|
+
* repository, which may be on a network filesystem, may be read-only, and is
|
|
23
|
+
* the wrong place to record which local pid is busy with it. Keeping them
|
|
24
|
+
* together in one directory is also what lets `status` find every running
|
|
25
|
+
* lmgrep by reading a single directory.
|
|
26
|
+
*/
|
|
27
|
+
export class DatabaseLocks {
|
|
28
|
+
databasePath;
|
|
29
|
+
workspaceRoot;
|
|
30
|
+
static DEFAULT_WAIT_MS = 120_000;
|
|
31
|
+
static DEFAULT_POLL_MS = 200;
|
|
32
|
+
/** Enough to separate worktrees without making the filename unreadable. */
|
|
33
|
+
static ROOT_DIGEST_LENGTH = 12;
|
|
34
|
+
maintainer;
|
|
35
|
+
writer;
|
|
36
|
+
constructor(locksDirectory, databasePath,
|
|
37
|
+
/** Working tree this process would be responsible for. */
|
|
38
|
+
workspaceRoot) {
|
|
39
|
+
this.databasePath = databasePath;
|
|
40
|
+
this.workspaceRoot = workspaceRoot;
|
|
41
|
+
const database = DatabaseLocks.digestOf(databasePath);
|
|
42
|
+
this.maintainer = new PidFileLock(join(locksDirectory, `${database}@${DatabaseLocks.digestOf(workspaceRoot)}.lock`));
|
|
43
|
+
this.writer = new PidFileLock(join(locksDirectory, `${database}.writelock`));
|
|
44
|
+
}
|
|
45
|
+
acquireMaintainer() {
|
|
46
|
+
// The database path goes in the payload because it is no longer in the
|
|
47
|
+
// filename: a digest cannot be reversed, and `status` needs to name the
|
|
48
|
+
// index a process is holding.
|
|
49
|
+
return this.maintainer.tryAcquire({
|
|
50
|
+
root: this.workspaceRoot,
|
|
51
|
+
database: this.databasePath,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
releaseMaintainer() {
|
|
55
|
+
this.maintainer.release();
|
|
56
|
+
}
|
|
57
|
+
isMaintained() {
|
|
58
|
+
return this.maintainer.isHeldByLiveProcess();
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Run `fn` holding the write mutex. Waits for a busy lock, taking over one
|
|
62
|
+
* whose owner has died. Throws if it cannot be acquired in time — better to
|
|
63
|
+
* fail than to write concurrently and duplicate rows.
|
|
64
|
+
*/
|
|
65
|
+
async withWriteLock(fn, options = {}) {
|
|
66
|
+
const waitMs = options.waitMs ?? DatabaseLocks.DEFAULT_WAIT_MS;
|
|
67
|
+
const pollMs = options.pollMs ?? DatabaseLocks.DEFAULT_POLL_MS;
|
|
68
|
+
let waited = 0;
|
|
69
|
+
while (!this.writer.tryAcquire()) {
|
|
70
|
+
if (waited >= waitMs) {
|
|
71
|
+
throw new Error("Could not acquire the index write lock — another indexer is busy. " +
|
|
72
|
+
"Try again once it finishes.");
|
|
73
|
+
}
|
|
74
|
+
await new Promise((r) => setTimeout(r, pollMs));
|
|
75
|
+
waited += pollMs;
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
return await fn();
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
this.writer.releaseIfOwned();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Short stable name for a path, used to key lock files. */
|
|
85
|
+
static digestOf(path) {
|
|
86
|
+
return createHash("sha256")
|
|
87
|
+
.update(path)
|
|
88
|
+
.digest("hex")
|
|
89
|
+
.slice(0, DatabaseLocks.ROOT_DIGEST_LENGTH);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=DatabaseLocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatabaseLocks.js","sourceRoot":"","sources":["../../../src/infrastructure/fs/DatabaseLocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,aAAa;IAWP;IAEA;IAZV,MAAM,CAAU,eAAe,GAAG,OAAO,CAAC;IAC1C,MAAM,CAAU,eAAe,GAAG,GAAG,CAAC;IAC9C,2EAA2E;IACnE,MAAM,CAAU,kBAAkB,GAAG,EAAE,CAAC;IAE/B,UAAU,CAAc;IACxB,MAAM,CAAc;IAErC,YACC,cAAsB,EACL,YAAoB;IACrC,0DAA0D;IACzC,aAAqB;QAFrB,iBAAY,GAAZ,YAAY,CAAQ;QAEpB,kBAAa,GAAb,aAAa,CAAQ;QAEtC,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,GAAG,IAAI,WAAW,CAChC,IAAI,CACH,cAAc,EACd,GAAG,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,CAC3D,CACD,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAC5B,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,YAAY,CAAC,CAC7C,CAAC;IACH,CAAC;IAED,iBAAiB;QAChB,uEAAuE;QACvE,wEAAwE;QACxE,8BAA8B;QAC9B,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YACjC,IAAI,EAAE,IAAI,CAAC,aAAa;YACxB,QAAQ,EAAE,IAAI,CAAC,YAAY;SAC3B,CAAC,CAAC;IACJ,CAAC;IAED,iBAAiB;QAChB,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,YAAY;QACX,OAAO,IAAI,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,aAAa,CAClB,EAAoB,EACpB,UAAgD,EAAE;QAElD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC,eAAe,CAAC;QAC/D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC,eAAe,CAAC;QAE/D,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;YAClC,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CACd,oEAAoE;oBACnE,6BAA6B,CAC9B,CAAC;YACH,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YAChD,MAAM,IAAI,MAAM,CAAC;QAClB,CAAC;QAED,IAAI,CAAC;YACJ,OAAO,MAAM,EAAE,EAAE,CAAC;QACnB,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAC9B,CAAC;IACF,CAAC;IAED,4DAA4D;IACpD,MAAM,CAAC,QAAQ,CAAC,IAAY;QACnC,OAAO,UAAU,CAAC,QAAQ,CAAC;aACzB,MAAM,CAAC,IAAI,CAAC;aACZ,MAAM,CAAC,KAAK,CAAC;aACb,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAC9C,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { readdirSync, statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/** Recursive on-disk size, for reporting what an index actually costs. */
|
|
4
|
+
export class DiskUsage {
|
|
5
|
+
/** Bytes used by `path` and everything under it; 0 when unreadable. */
|
|
6
|
+
static of(path) {
|
|
7
|
+
let total = 0;
|
|
8
|
+
let entries;
|
|
9
|
+
try {
|
|
10
|
+
entries = readdirSync(path, { withFileTypes: true });
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
const child = join(path, entry.name);
|
|
17
|
+
if (entry.isDirectory()) {
|
|
18
|
+
total += DiskUsage.of(child);
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
total += statSync(child).size;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// Vanished mid-walk; the number is a report, not an invariant.
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return total;
|
|
29
|
+
}
|
|
30
|
+
static format(bytes) {
|
|
31
|
+
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
32
|
+
let value = bytes;
|
|
33
|
+
let unit = 0;
|
|
34
|
+
while (value >= 1024 && unit < units.length - 1) {
|
|
35
|
+
value /= 1024;
|
|
36
|
+
unit++;
|
|
37
|
+
}
|
|
38
|
+
return `${value < 10 && unit > 0 ? value.toFixed(1) : Math.round(value)}${units[unit]}`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=DiskUsage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiskUsage.js","sourceRoot":"","sources":["../../../src/infrastructure/fs/DiskUsage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,0EAA0E;AAC1E,MAAM,OAAO,SAAS;IACrB,uEAAuE;IACvE,MAAM,CAAC,EAAE,CAAC,IAAY;QACrB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,OAAmC,CAAC;QACxC,IAAI,CAAC;YACJ,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,CAAC,CAAC;QACV,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACzB,KAAK,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;gBAC7B,SAAS;YACV,CAAC;YACD,IAAI,CAAC;gBACJ,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACR,+DAA+D;YAChE,CAAC;QACF,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,KAAa;QAC1B,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5C,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,OAAO,KAAK,IAAI,IAAI,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjD,KAAK,IAAI,IAAI,CAAC;YACd,IAAI,EAAE,CAAC;QACR,CAAC;QACD,OAAO,GAAG,KAAK,GAAG,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;IACzF,CAAC;CACD"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ExtensionRules } from "../../domain/ports/WorkspacePort.js";
|
|
2
|
+
/**
|
|
3
|
+
* Decides which files are worth indexing.
|
|
4
|
+
*
|
|
5
|
+
* Two independent filters: an extension allow-list (is this even source?) and
|
|
6
|
+
* ignore patterns (should this source be skipped?). Ignore rules come from the
|
|
7
|
+
* built-in list, the user's config, `.gitignore` and `.lmgrepignore`, plus
|
|
8
|
+
* nested `.gitignore` files further down the tree.
|
|
9
|
+
*/
|
|
10
|
+
export declare class IndexableFileRules {
|
|
11
|
+
private readonly cwd;
|
|
12
|
+
static readonly DEFAULT_IGNORE: string[];
|
|
13
|
+
static readonly CODE_EXTENSIONS: Set<string>;
|
|
14
|
+
private readonly root;
|
|
15
|
+
private readonly extensions;
|
|
16
|
+
private readonly nested;
|
|
17
|
+
constructor(cwd: string, extraIgnore?: string[], extensionRules?: ExtensionRules);
|
|
18
|
+
/** Whether the path's extension is one we index at all. */
|
|
19
|
+
hasIndexableExtension(filePath: string): boolean;
|
|
20
|
+
/** Whether the root-level ignore rules exclude this path. */
|
|
21
|
+
isIgnored(filePath: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Load `.gitignore` files sitting in subdirectories, so a nested ignore
|
|
24
|
+
* applies to its own subtree the way git applies it.
|
|
25
|
+
*/
|
|
26
|
+
loadNestedIgnores(relativePaths: readonly string[]): void;
|
|
27
|
+
/** Whether any nested `.gitignore` excludes this path. */
|
|
28
|
+
isIgnoredByNested(filePath: string): boolean;
|
|
29
|
+
/** Full decision for a scanned path. */
|
|
30
|
+
admits(filePath: string): boolean;
|
|
31
|
+
private static buildIgnore;
|
|
32
|
+
private static buildExtensions;
|
|
33
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, extname, join } from "node:path";
|
|
3
|
+
import ignore from "ignore";
|
|
4
|
+
/**
|
|
5
|
+
* Decides which files are worth indexing.
|
|
6
|
+
*
|
|
7
|
+
* Two independent filters: an extension allow-list (is this even source?) and
|
|
8
|
+
* ignore patterns (should this source be skipped?). Ignore rules come from the
|
|
9
|
+
* built-in list, the user's config, `.gitignore` and `.lmgrepignore`, plus
|
|
10
|
+
* nested `.gitignore` files further down the tree.
|
|
11
|
+
*/
|
|
12
|
+
export class IndexableFileRules {
|
|
13
|
+
cwd;
|
|
14
|
+
static DEFAULT_IGNORE = [
|
|
15
|
+
"node_modules",
|
|
16
|
+
".git",
|
|
17
|
+
"dist",
|
|
18
|
+
"build",
|
|
19
|
+
".next",
|
|
20
|
+
"__pycache__",
|
|
21
|
+
".venv",
|
|
22
|
+
"vendor",
|
|
23
|
+
"target",
|
|
24
|
+
".lmgrep",
|
|
25
|
+
"*.min.js",
|
|
26
|
+
"*.min.css",
|
|
27
|
+
"*.map",
|
|
28
|
+
"*.lock",
|
|
29
|
+
"pnpm-lock.yaml",
|
|
30
|
+
"package-lock.json",
|
|
31
|
+
"yarn.lock",
|
|
32
|
+
"*.png",
|
|
33
|
+
"*.jpg",
|
|
34
|
+
"*.jpeg",
|
|
35
|
+
"*.gif",
|
|
36
|
+
"*.ico",
|
|
37
|
+
"*.woff",
|
|
38
|
+
"*.woff2",
|
|
39
|
+
"*.ttf",
|
|
40
|
+
"*.eot",
|
|
41
|
+
"*.svg",
|
|
42
|
+
"*.zip",
|
|
43
|
+
"*.tar",
|
|
44
|
+
"*.gz",
|
|
45
|
+
"*.bin",
|
|
46
|
+
"*.exe",
|
|
47
|
+
"*.dll",
|
|
48
|
+
"*.so",
|
|
49
|
+
"*.dylib",
|
|
50
|
+
"*.wasm",
|
|
51
|
+
];
|
|
52
|
+
static CODE_EXTENSIONS = new Set([
|
|
53
|
+
".js",
|
|
54
|
+
".ts",
|
|
55
|
+
".jsx",
|
|
56
|
+
".tsx",
|
|
57
|
+
".py",
|
|
58
|
+
".rs",
|
|
59
|
+
".go",
|
|
60
|
+
".rb",
|
|
61
|
+
".c",
|
|
62
|
+
".h",
|
|
63
|
+
".cpp",
|
|
64
|
+
".hpp",
|
|
65
|
+
".cc",
|
|
66
|
+
".swift",
|
|
67
|
+
".json",
|
|
68
|
+
".yaml",
|
|
69
|
+
".yml",
|
|
70
|
+
".toml",
|
|
71
|
+
".lua",
|
|
72
|
+
".scala",
|
|
73
|
+
".zig",
|
|
74
|
+
".md",
|
|
75
|
+
".markdown",
|
|
76
|
+
".mdx",
|
|
77
|
+
".sh",
|
|
78
|
+
".bash",
|
|
79
|
+
".sql",
|
|
80
|
+
".graphql",
|
|
81
|
+
".gql",
|
|
82
|
+
".proto",
|
|
83
|
+
".html",
|
|
84
|
+
".css",
|
|
85
|
+
".scss",
|
|
86
|
+
".vue",
|
|
87
|
+
".svelte",
|
|
88
|
+
".nix",
|
|
89
|
+
".tf",
|
|
90
|
+
".hcl",
|
|
91
|
+
".kt",
|
|
92
|
+
".java",
|
|
93
|
+
".php",
|
|
94
|
+
".cs",
|
|
95
|
+
".rst",
|
|
96
|
+
".adoc",
|
|
97
|
+
]);
|
|
98
|
+
root;
|
|
99
|
+
extensions;
|
|
100
|
+
nested = new Map();
|
|
101
|
+
constructor(cwd, extraIgnore, extensionRules) {
|
|
102
|
+
this.cwd = cwd;
|
|
103
|
+
this.root = IndexableFileRules.buildIgnore(cwd, extraIgnore);
|
|
104
|
+
this.extensions = IndexableFileRules.buildExtensions(extensionRules);
|
|
105
|
+
}
|
|
106
|
+
/** Whether the path's extension is one we index at all. */
|
|
107
|
+
hasIndexableExtension(filePath) {
|
|
108
|
+
return this.extensions.has(extname(filePath));
|
|
109
|
+
}
|
|
110
|
+
/** Whether the root-level ignore rules exclude this path. */
|
|
111
|
+
isIgnored(filePath) {
|
|
112
|
+
try {
|
|
113
|
+
return this.root.ignores(filePath);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// `ignore` rejects paths it considers malformed; treat those as
|
|
117
|
+
// ignorable rather than letting one bad name abort a whole scan.
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Load `.gitignore` files sitting in subdirectories, so a nested ignore
|
|
123
|
+
* applies to its own subtree the way git applies it.
|
|
124
|
+
*/
|
|
125
|
+
loadNestedIgnores(relativePaths) {
|
|
126
|
+
for (const f of relativePaths) {
|
|
127
|
+
if (f.endsWith("/.gitignore") || f === ".gitignore")
|
|
128
|
+
continue;
|
|
129
|
+
const dir = dirname(f);
|
|
130
|
+
if (dir === "." || this.nested.has(dir))
|
|
131
|
+
continue;
|
|
132
|
+
const nestedPath = join(this.cwd, dir, ".gitignore");
|
|
133
|
+
if (!existsSync(nestedPath))
|
|
134
|
+
continue;
|
|
135
|
+
const rules = ignore();
|
|
136
|
+
rules.add(readFileSync(nestedPath, "utf-8"));
|
|
137
|
+
this.nested.set(dir, rules);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/** Whether any nested `.gitignore` excludes this path. */
|
|
141
|
+
isIgnoredByNested(filePath) {
|
|
142
|
+
for (const [dir, rules] of this.nested) {
|
|
143
|
+
if (!filePath.startsWith(`${dir}/`))
|
|
144
|
+
continue;
|
|
145
|
+
if (rules.ignores(filePath.slice(dir.length + 1)))
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
/** Full decision for a scanned path. */
|
|
151
|
+
admits(filePath) {
|
|
152
|
+
return (this.hasIndexableExtension(filePath) &&
|
|
153
|
+
!this.isIgnored(filePath) &&
|
|
154
|
+
!this.isIgnoredByNested(filePath));
|
|
155
|
+
}
|
|
156
|
+
static buildIgnore(cwd, extra) {
|
|
157
|
+
const rules = ignore();
|
|
158
|
+
rules.add([...IndexableFileRules.DEFAULT_IGNORE]);
|
|
159
|
+
if (extra)
|
|
160
|
+
rules.add(extra);
|
|
161
|
+
for (const name of [".gitignore", ".lmgrepignore"]) {
|
|
162
|
+
const path = join(cwd, name);
|
|
163
|
+
if (existsSync(path))
|
|
164
|
+
rules.add(readFileSync(path, "utf-8"));
|
|
165
|
+
}
|
|
166
|
+
return rules;
|
|
167
|
+
}
|
|
168
|
+
static buildExtensions(rules) {
|
|
169
|
+
const exts = new Set(IndexableFileRules.CODE_EXTENSIONS);
|
|
170
|
+
for (const e of rules?.include ?? [])
|
|
171
|
+
exts.add(e);
|
|
172
|
+
for (const e of rules?.exclude ?? [])
|
|
173
|
+
exts.delete(e);
|
|
174
|
+
return exts;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=IndexableFileRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IndexableFileRules.js","sourceRoot":"","sources":["../../../src/infrastructure/fs/IndexableFileRules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LoggerPort } from "../../domain/ports/LoggerPort.js";
|
|
2
|
+
/** Timestamped output on stdout/stderr, for foreground commands. */
|
|
3
|
+
export declare class ConsoleLogger implements LoggerPort {
|
|
4
|
+
info(message: string): void;
|
|
5
|
+
error(message: string): void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Discards everything. Used by the MCP server, whose stdout is a protocol
|
|
9
|
+
* stream — a stray log line there corrupts the transport.
|
|
10
|
+
*/
|
|
11
|
+
export declare class SilentLogger implements LoggerPort {
|
|
12
|
+
info(): void;
|
|
13
|
+
error(): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Timestamped output on stdout/stderr, for foreground commands. */
|
|
2
|
+
export class ConsoleLogger {
|
|
3
|
+
info(message) {
|
|
4
|
+
console.log(`[${new Date().toISOString()}] ${message}`);
|
|
5
|
+
}
|
|
6
|
+
error(message) {
|
|
7
|
+
console.error(`[${new Date().toISOString()}] ${message}`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Discards everything. Used by the MCP server, whose stdout is a protocol
|
|
12
|
+
* stream — a stray log line there corrupts the transport.
|
|
13
|
+
*/
|
|
14
|
+
export class SilentLogger {
|
|
15
|
+
info() { }
|
|
16
|
+
error() { }
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=Loggers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Loggers.js","sourceRoot":"","sources":["../../../src/infrastructure/fs/Loggers.ts"],"names":[],"mappings":"AAEA,oEAAoE;AACpE,MAAM,OAAO,aAAa;IACzB,IAAI,CAAC,OAAe;QACnB,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,OAAe;QACpB,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC;CACD;AAED;;;GAGG;AACH,MAAM,OAAO,YAAY;IACxB,IAAI,KAAU,CAAC;IACf,KAAK,KAAU,CAAC;CAChB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** What a lock records about its owner. */
|
|
2
|
+
export interface LockOwner {
|
|
3
|
+
pid: number;
|
|
4
|
+
/** Working tree the owner is responsible for, when it has one. */
|
|
5
|
+
root?: string;
|
|
6
|
+
/** Database the owner holds. Lock files no longer sit beside it. */
|
|
7
|
+
database?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A lock file recording its owning process.
|
|
11
|
+
*
|
|
12
|
+
* The pid is what makes the lock recoverable: a process that dies without
|
|
13
|
+
* cleaning up leaves the file behind, and the next contender takes it over
|
|
14
|
+
* once it sees the owner is gone. Without that, one crash would wedge a
|
|
15
|
+
* database until someone deleted the file by hand.
|
|
16
|
+
*/
|
|
17
|
+
export declare class PidFileLock {
|
|
18
|
+
readonly path: string;
|
|
19
|
+
constructor(path: string);
|
|
20
|
+
/** True when acquired; false when a live process already holds it. */
|
|
21
|
+
tryAcquire(owner?: Omit<LockOwner, "pid">): boolean;
|
|
22
|
+
/** Release unconditionally — used by the long-lived maintainer lock. */
|
|
23
|
+
release(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Release only if this process still owns it, so a lock already lost to a
|
|
26
|
+
* takeover is not deleted out from under its new owner.
|
|
27
|
+
*/
|
|
28
|
+
releaseIfOwned(): void;
|
|
29
|
+
isHeldByLiveProcess(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Parse the lock body.
|
|
32
|
+
*
|
|
33
|
+
* Locks written before this carried a bare pid, and a stale one of those
|
|
34
|
+
* must still be recognised — otherwise an upgrade would treat a live
|
|
35
|
+
* watcher's lock as free and start a second one.
|
|
36
|
+
*/
|
|
37
|
+
read(): LockOwner | undefined;
|
|
38
|
+
/** Signal 0 tests for existence without delivering anything. */
|
|
39
|
+
static isAlive(pid: number): boolean;
|
|
40
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* A lock file recording its owning process.
|
|
5
|
+
*
|
|
6
|
+
* The pid is what makes the lock recoverable: a process that dies without
|
|
7
|
+
* cleaning up leaves the file behind, and the next contender takes it over
|
|
8
|
+
* once it sees the owner is gone. Without that, one crash would wedge a
|
|
9
|
+
* database until someone deleted the file by hand.
|
|
10
|
+
*/
|
|
11
|
+
export class PidFileLock {
|
|
12
|
+
path;
|
|
13
|
+
constructor(path) {
|
|
14
|
+
this.path = path;
|
|
15
|
+
}
|
|
16
|
+
/** True when acquired; false when a live process already holds it. */
|
|
17
|
+
tryAcquire(owner = {}) {
|
|
18
|
+
if (this.isHeldByLiveProcess())
|
|
19
|
+
return false;
|
|
20
|
+
mkdirSync(dirname(this.path), { recursive: true });
|
|
21
|
+
writeFileSync(this.path, `${JSON.stringify({ pid: process.pid, ...owner })}\n`);
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
/** Release unconditionally — used by the long-lived maintainer lock. */
|
|
25
|
+
release() {
|
|
26
|
+
try {
|
|
27
|
+
unlinkSync(this.path);
|
|
28
|
+
}
|
|
29
|
+
catch { }
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Release only if this process still owns it, so a lock already lost to a
|
|
33
|
+
* takeover is not deleted out from under its new owner.
|
|
34
|
+
*/
|
|
35
|
+
releaseIfOwned() {
|
|
36
|
+
try {
|
|
37
|
+
if (this.read()?.pid === process.pid)
|
|
38
|
+
unlinkSync(this.path);
|
|
39
|
+
}
|
|
40
|
+
catch { }
|
|
41
|
+
}
|
|
42
|
+
isHeldByLiveProcess() {
|
|
43
|
+
if (!existsSync(this.path))
|
|
44
|
+
return false;
|
|
45
|
+
const owner = this.read();
|
|
46
|
+
// An unreadable or corrupt lock is stale, and safe to take over.
|
|
47
|
+
if (owner === undefined)
|
|
48
|
+
return false;
|
|
49
|
+
return PidFileLock.isAlive(owner.pid);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Parse the lock body.
|
|
53
|
+
*
|
|
54
|
+
* Locks written before this carried a bare pid, and a stale one of those
|
|
55
|
+
* must still be recognised — otherwise an upgrade would treat a live
|
|
56
|
+
* watcher's lock as free and start a second one.
|
|
57
|
+
*/
|
|
58
|
+
read() {
|
|
59
|
+
let raw;
|
|
60
|
+
try {
|
|
61
|
+
raw = readFileSync(this.path, "utf-8").trim();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
if (raw.length === 0)
|
|
67
|
+
return undefined;
|
|
68
|
+
if (raw.startsWith("{")) {
|
|
69
|
+
try {
|
|
70
|
+
const parsed = JSON.parse(raw);
|
|
71
|
+
return typeof parsed.pid === "number"
|
|
72
|
+
? {
|
|
73
|
+
pid: parsed.pid,
|
|
74
|
+
root: parsed.root,
|
|
75
|
+
database: parsed.database,
|
|
76
|
+
}
|
|
77
|
+
: undefined;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const pid = Number.parseInt(raw, 10);
|
|
84
|
+
return Number.isNaN(pid) ? undefined : { pid };
|
|
85
|
+
}
|
|
86
|
+
/** Signal 0 tests for existence without delivering anything. */
|
|
87
|
+
static isAlive(pid) {
|
|
88
|
+
try {
|
|
89
|
+
process.kill(pid, 0);
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=PidFileLock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PidFileLock.js","sourceRoot":"","sources":["../../../src/infrastructure/fs/PidFileLock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IndexMetadataPort } from "../../domain/ports/IndexMetadataPort.js";
|
|
2
|
+
import type { ProjectIndex, ProjectIndexesPort } from "../../domain/ports/ProjectIndexesPort.js";
|
|
3
|
+
/** ProjectIndexesPort over the index home directory. */
|
|
4
|
+
export declare class ProjectIndexes implements ProjectIndexesPort {
|
|
5
|
+
private readonly metadata;
|
|
6
|
+
constructor(metadata: IndexMetadataPort);
|
|
7
|
+
list(indexHome: string): ProjectIndex[];
|
|
8
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { readdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { DiskUsage } from "./DiskUsage.js";
|
|
4
|
+
/** ProjectIndexesPort over the index home directory. */
|
|
5
|
+
export class ProjectIndexes {
|
|
6
|
+
metadata;
|
|
7
|
+
constructor(metadata) {
|
|
8
|
+
this.metadata = metadata;
|
|
9
|
+
}
|
|
10
|
+
list(indexHome) {
|
|
11
|
+
let entries;
|
|
12
|
+
try {
|
|
13
|
+
entries = readdirSync(indexHome, { withFileTypes: true });
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
const out = [];
|
|
19
|
+
for (const entry of entries) {
|
|
20
|
+
if (!entry.isDirectory())
|
|
21
|
+
continue;
|
|
22
|
+
const databasePath = join(indexHome, entry.name);
|
|
23
|
+
const meta = this.metadata.read(databasePath);
|
|
24
|
+
out.push({
|
|
25
|
+
databasePath,
|
|
26
|
+
model: meta?.model,
|
|
27
|
+
dimensions: meta?.dimensions,
|
|
28
|
+
indexedAt: meta?.indexedAt,
|
|
29
|
+
bytes: DiskUsage.of(databasePath),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return out.sort((a, b) => b.bytes - a.bytes);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=ProjectIndexes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectIndexes.js","sourceRoot":"","sources":["../../../src/infrastructure/fs/ProjectIndexes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAMjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,wDAAwD;AACxD,MAAM,OAAO,cAAc;IACG;IAA7B,YAA6B,QAA2B;QAA3B,aAAQ,GAAR,QAAQ,CAAmB;IAAG,CAAC;IAE5D,IAAI,CAAC,SAAiB;QACrB,IAAI,OAAmC,CAAC;QACxC,IAAI,CAAC;YACJ,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,EAAE,CAAC;QACX,CAAC;QAED,MAAM,GAAG,GAAmB,EAAE,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBAAE,SAAS;YACnC,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACjD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC9C,GAAG,CAAC,IAAI,CAAC;gBACR,YAAY;gBACZ,KAAK,EAAE,IAAI,EAAE,KAAK;gBAClB,UAAU,EAAE,IAAI,EAAE,UAAU;gBAC5B,SAAS,EAAE,IAAI,EAAE,SAAS;gBAC1B,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC,YAAY,CAAC;aACjC,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;CACD"}
|