codesearch-mcp 0.2.3-alpha → 0.4.0-alpha
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/CHANGELOG.md +88 -5
- package/LICENSE +661 -21
- package/README.md +76 -40
- package/dist/app.js +17 -38
- package/dist/src/ast/CallExtractor.d.ts +8 -0
- package/dist/src/ast/CallExtractor.js +68 -0
- package/dist/src/ast/GraphqlNameExtractor.d.ts +22 -0
- package/dist/src/ast/GraphqlNameExtractor.js +240 -0
- package/dist/src/ast/ImportEdgeExtractor.d.ts +11 -0
- package/dist/src/ast/ImportEdgeExtractor.js +129 -0
- package/dist/src/ast/IndexedNodeResolver.d.ts +14 -0
- package/dist/src/ast/IndexedNodeResolver.js +217 -0
- package/dist/src/ast/MemberExtractor.d.ts +8 -0
- package/dist/src/ast/MemberExtractor.js +129 -0
- package/dist/src/ast/TopLevelSymbolExtractor.d.ts +5 -0
- package/dist/src/ast/TopLevelSymbolExtractor.js +86 -0
- package/dist/src/ast/graphql-grammar.d.ts +24 -0
- package/dist/src/ast/graphql-grammar.js +93 -0
- package/dist/src/ast/node-helpers.d.ts +11 -0
- package/dist/src/ast/node-helpers.js +55 -0
- package/dist/src/chunking/AstChunker.d.ts +12 -0
- package/dist/src/chunking/AstChunker.js +30 -0
- package/dist/src/chunking/CharacterChunkStrategy.d.ts +8 -0
- package/dist/src/chunking/CharacterChunkStrategy.js +15 -0
- package/dist/src/chunking/DeclarationChunkStrategy.d.ts +15 -0
- package/dist/src/chunking/DeclarationChunkStrategy.js +87 -0
- package/dist/src/chunking/FragmentMerger.d.ts +11 -0
- package/dist/src/chunking/FragmentMerger.js +61 -0
- package/dist/src/chunking/ImportOnlyFilter.d.ts +5 -0
- package/dist/src/chunking/ImportOnlyFilter.js +14 -0
- package/dist/src/chunking/LangchainTextSplitter.d.ts +21 -0
- package/dist/src/chunking/LangchainTextSplitter.js +133 -0
- package/dist/src/chunking/MinSizeSplitPolicy.d.ts +9 -0
- package/dist/src/chunking/MinSizeSplitPolicy.js +18 -0
- package/dist/src/chunking/RunPacker.d.ts +12 -0
- package/dist/src/chunking/RunPacker.js +84 -0
- package/dist/src/chunking/create-chunker.d.ts +3 -0
- package/dist/src/chunking/create-chunker.js +15 -0
- package/dist/src/chunking/interfaces.d.ts +27 -0
- package/dist/src/commands/ConfigCommand.js +1 -9
- package/dist/src/commands/EvalCommand.d.ts +10 -5
- package/dist/src/commands/EvalCommand.js +60 -149
- package/dist/src/commands/IndexCommand.d.ts +10 -4
- package/dist/src/commands/IndexCommand.js +52 -146
- package/dist/src/commands/McpCommand.d.ts +6 -3
- package/dist/src/commands/McpCommand.js +19 -20
- package/dist/src/commands/WebCommand.d.ts +9 -3
- package/dist/src/commands/WebCommand.js +17 -11
- package/dist/src/commands/eval/baseline-comparison.d.ts +6 -0
- package/dist/src/commands/eval/baseline-comparison.js +54 -0
- package/dist/src/commands/eval/eval-args.d.ts +6 -0
- package/dist/src/commands/eval/eval-args.js +71 -0
- package/dist/src/commands/eval/eval-corpora.d.ts +6 -0
- package/dist/src/commands/eval/eval-corpora.js +76 -0
- package/dist/src/commands/eval/eval-metadata.d.ts +17 -0
- package/dist/src/commands/eval/eval-metadata.js +75 -0
- package/dist/src/commands/eval/index-inspector.d.ts +3 -0
- package/dist/src/commands/eval/index-inspector.js +21 -0
- package/dist/src/commands/eval/staged-search.d.ts +3 -0
- package/dist/src/commands/eval/staged-search.js +20 -0
- package/dist/src/commands/eval/suite-loader.d.ts +8 -0
- package/dist/src/commands/eval/suite-loader.js +52 -0
- package/dist/src/commands/index/backend-probe.d.ts +2 -0
- package/dist/src/commands/index/backend-probe.js +15 -0
- package/dist/src/commands/index/embedding-setup.d.ts +3 -0
- package/dist/src/commands/index/embedding-setup.js +16 -0
- package/dist/src/commands/index/index-summary.d.ts +2 -0
- package/dist/src/commands/index/index-summary.js +22 -0
- package/dist/src/commands/index/legacy-ollama-guard.d.ts +3 -0
- package/dist/src/commands/index/legacy-ollama-guard.js +23 -0
- package/dist/src/commands/index/prune-step.d.ts +3 -0
- package/dist/src/commands/index/prune-step.js +22 -0
- package/dist/src/commands/index/scan-targets.d.ts +8 -0
- package/dist/src/commands/index/scan-targets.js +107 -0
- package/dist/src/config-error.d.ts +0 -4
- package/dist/src/config-error.js +0 -4
- package/dist/src/config-store.d.ts +1 -55
- package/dist/src/config-store.js +11 -73
- package/dist/src/config.d.ts +9 -18
- package/dist/src/config.js +36 -35
- package/dist/src/constants.d.ts +17 -28
- package/dist/src/constants.js +35 -29
- package/dist/src/container.d.ts +10 -2
- package/dist/src/container.js +19 -8
- package/dist/src/db/drizzle-types.d.ts +7 -0
- package/dist/src/db/drizzle-types.js +2 -0
- package/dist/src/db/index.d.ts +1 -0
- package/dist/src/db/schema-steps.d.ts +8 -0
- package/dist/src/db/schema-steps.js +105 -0
- package/dist/src/db/schema.d.ts +17 -0
- package/dist/src/db/schema.js +1 -6
- package/dist/src/declarations/DeclarationTree.d.ts +19 -0
- package/dist/src/declarations/DeclarationTree.js +66 -0
- package/dist/src/declarations/DeclarationTreeBuilder.d.ts +22 -0
- package/dist/src/declarations/DeclarationTreeBuilder.js +179 -0
- package/dist/src/declarations/SourceLines.d.ts +37 -0
- package/dist/src/declarations/SourceLines.js +415 -0
- package/dist/src/dependency-traversal.d.ts +0 -6
- package/dist/src/dependency-traversal.js +0 -6
- package/dist/src/enriched-prompt.d.ts +0 -6
- package/dist/src/enriched-prompt.js +0 -6
- package/dist/src/error-record.d.ts +12 -0
- package/dist/src/error-record.js +248 -0
- package/dist/src/eval-corpus.d.ts +16 -0
- package/dist/src/eval-corpus.js +169 -0
- package/dist/src/eval-results.d.ts +6 -3
- package/dist/src/eval-results.js +323 -26
- package/dist/src/eval-vector-index.d.ts +5 -0
- package/dist/src/eval-vector-index.js +60 -0
- package/dist/src/file-utils.d.ts +0 -5
- package/dist/src/file-utils.js +0 -5
- package/dist/src/graph.d.ts +0 -25
- package/dist/src/graph.js +0 -28
- package/dist/src/help.js +9 -1
- package/dist/src/hnsw-settings.d.ts +3 -0
- package/dist/src/hnsw-settings.js +24 -0
- package/dist/src/index-args.d.ts +13 -0
- package/dist/src/index-args.js +48 -0
- package/dist/src/indexing/AnalysisBatcher.d.ts +12 -0
- package/dist/src/indexing/AnalysisBatcher.js +28 -0
- package/dist/src/indexing/ChunkEmbedder.d.ts +24 -0
- package/dist/src/indexing/ChunkEmbedder.js +37 -0
- package/dist/src/indexing/ConsoleScanReporter.d.ts +10 -0
- package/dist/src/indexing/ConsoleScanReporter.js +73 -0
- package/dist/src/indexing/EmbeddingSchemaPreparer.d.ts +14 -0
- package/dist/src/indexing/EmbeddingSchemaPreparer.js +66 -0
- package/dist/src/indexing/FileIngestor.d.ts +22 -0
- package/dist/src/indexing/FileIngestor.js +116 -0
- package/dist/src/indexing/IndexStore.d.ts +24 -0
- package/dist/src/indexing/IndexStore.js +69 -0
- package/dist/src/indexing/StaleFilePruner.d.ts +8 -0
- package/dist/src/indexing/StaleFilePruner.js +55 -0
- package/dist/src/indexing/analysis-rows.d.ts +4 -0
- package/dist/src/indexing/analysis-rows.js +65 -0
- package/dist/src/indexing/project-notices.d.ts +2 -0
- package/dist/src/indexing/project-notices.js +63 -0
- package/dist/src/interfaces/IAstParser.d.ts +4 -40
- package/dist/src/interfaces/ICallGraph.d.ts +28 -0
- package/dist/src/interfaces/ICallGraph.js +2 -0
- package/dist/src/interfaces/IChunkSearch.d.ts +42 -0
- package/dist/src/interfaces/IChunkSearch.js +2 -0
- package/dist/src/interfaces/IChunker.d.ts +3 -12
- package/dist/src/interfaces/ICorpusInspector.d.ts +7 -0
- package/dist/src/interfaces/ICorpusInspector.js +2 -0
- package/dist/src/interfaces/IDatabase.d.ts +8 -24
- package/dist/src/interfaces/IDependencyGraph.d.ts +24 -0
- package/dist/src/interfaces/IDependencyGraph.js +2 -0
- package/dist/src/interfaces/IEmbedder.d.ts +0 -9
- package/dist/src/interfaces/IIndexIdentityGuard.d.ts +3 -0
- package/dist/src/interfaces/IIndexIdentityGuard.js +2 -0
- package/dist/src/interfaces/IIndexedNodeResolver.d.ts +10 -0
- package/dist/src/interfaces/IIndexedNodeResolver.js +2 -0
- package/dist/src/interfaces/ILogger.d.ts +1 -11
- package/dist/src/interfaces/IMcpReadiness.d.ts +12 -0
- package/dist/src/interfaces/IMcpReadiness.js +2 -0
- package/dist/src/interfaces/IMcpToolHandler.d.ts +0 -5
- package/dist/src/interfaces/IMonorepoResolver.d.ts +0 -22
- package/dist/src/interfaces/IProjectCatalog.d.ts +13 -0
- package/dist/src/interfaces/IProjectCatalog.js +2 -0
- package/dist/src/interfaces/IProjectDiscovery.d.ts +0 -17
- package/dist/src/interfaces/IProjectRoots.d.ts +3 -0
- package/dist/src/interfaces/IProjectRoots.js +2 -0
- package/dist/src/interfaces/IRetrievalEvaluator.d.ts +153 -12
- package/dist/src/interfaces/IScanReporter.d.ts +13 -0
- package/dist/src/interfaces/IScanReporter.js +2 -0
- package/dist/src/interfaces/ISymbolLookup.d.ts +49 -0
- package/dist/src/interfaces/ISymbolLookup.js +2 -0
- package/dist/src/interfaces/IToolPaths.d.ts +62 -0
- package/dist/src/interfaces/IToolPaths.js +2 -0
- package/dist/src/interfaces/IWorkspaceFiles.d.ts +28 -0
- package/dist/src/interfaces/IWorkspaceFiles.js +2 -0
- package/dist/src/interfaces/SymbolKind.d.ts +1 -0
- package/dist/src/interfaces/SymbolKind.js +2 -0
- package/dist/src/interfaces/index.d.ts +12 -1
- package/dist/src/interrupt.js +0 -2
- package/dist/src/owner-path.d.ts +9 -10
- package/dist/src/owner-path.js +11 -23
- package/dist/src/project-scope.d.ts +1 -12
- package/dist/src/project-scope.js +5 -12
- package/dist/src/project-selector.d.ts +0 -5
- package/dist/src/project-selector.js +0 -11
- package/dist/src/retrieval-eval.d.ts +15 -6
- package/dist/src/retrieval-eval.js +388 -59
- package/dist/src/search/CallGraph.d.ts +9 -0
- package/dist/src/search/CallGraph.js +84 -0
- package/dist/src/search/ChunkSearch.d.ts +23 -0
- package/dist/src/search/ChunkSearch.js +115 -0
- package/dist/src/search/DependencyGraph.d.ts +19 -0
- package/dist/src/search/DependencyGraph.js +180 -0
- package/dist/src/search/IndexIdentityGuard.d.ts +11 -0
- package/dist/src/search/IndexIdentityGuard.js +37 -0
- package/dist/src/search/ProjectCatalog.d.ts +11 -0
- package/dist/src/search/ProjectCatalog.js +38 -0
- package/dist/src/search/SymbolLookup.d.ts +24 -0
- package/dist/src/search/SymbolLookup.js +97 -0
- package/dist/src/search/chunks/CandidateFetcher.d.ts +19 -0
- package/dist/src/search/chunks/CandidateFetcher.js +40 -0
- package/dist/src/search/chunks/IterativeScanGate.d.ts +10 -0
- package/dist/src/search/chunks/IterativeScanGate.js +42 -0
- package/dist/src/search/chunks/RerankStage.d.ts +15 -0
- package/dist/src/search/chunks/RerankStage.js +42 -0
- package/dist/src/search/chunks/search-metrics.d.ts +18 -0
- package/dist/src/search/chunks/search-metrics.js +32 -0
- package/dist/src/search/chunks/search-plan.d.ts +18 -0
- package/dist/src/search/chunks/search-plan.js +19 -0
- package/dist/src/search/create-search-services.d.ts +26 -0
- package/dist/src/search/create-search-services.js +29 -0
- package/dist/src/search/index-paths.d.ts +1 -0
- package/dist/src/search/index-paths.js +5 -0
- package/dist/src/search/result-shaping.d.ts +4 -0
- package/dist/src/search/result-shaping.js +19 -0
- package/dist/src/search/symbol-sql.d.ts +13 -0
- package/dist/src/search/symbol-sql.js +66 -0
- package/dist/src/search/symbols/SymbolGrepFallback.d.ts +19 -0
- package/dist/src/search/symbols/SymbolGrepFallback.js +106 -0
- package/dist/src/search/symbols/SymbolIndexQuery.d.ts +14 -0
- package/dist/src/search/symbols/SymbolIndexQuery.js +52 -0
- package/dist/src/search/symbols/SymbolTextSearch.d.ts +13 -0
- package/dist/src/search/symbols/SymbolTextSearch.js +84 -0
- package/dist/src/search/symbols/TargetColumnGate.d.ts +7 -0
- package/dist/src/search/symbols/TargetColumnGate.js +23 -0
- package/dist/src/search/symbols/find-symbol-constants.d.ts +4 -0
- package/dist/src/search/symbols/find-symbol-constants.js +8 -0
- package/dist/src/search/symbols/grep-args.d.ts +3 -0
- package/dist/src/search/symbols/grep-args.js +7 -0
- package/dist/src/search/symbols/grep-patterns.d.ts +4 -0
- package/dist/src/search/symbols/grep-patterns.js +60 -0
- package/dist/src/services/AstParserService.d.ts +10 -106
- package/dist/src/services/AstParserService.js +37 -1068
- package/dist/src/services/DatabaseService.d.ts +10 -17
- package/dist/src/services/DatabaseService.js +71 -115
- package/dist/src/services/EmbedderFactory.d.ts +0 -4
- package/dist/src/services/EmbedderFactory.js +0 -5
- package/dist/src/services/IndexerService.d.ts +7 -26
- package/dist/src/services/IndexerService.js +38 -286
- package/dist/src/services/InfinityEmbedder.d.ts +0 -21
- package/dist/src/services/InfinityEmbedder.js +0 -15
- package/dist/src/services/LoggerService.d.ts +7 -5
- package/dist/src/services/LoggerService.js +37 -41
- package/dist/src/services/McpReadiness.d.ts +18 -0
- package/dist/src/services/McpReadiness.js +73 -0
- package/dist/src/services/McpServer.d.ts +50 -19
- package/dist/src/services/McpServer.js +132 -62
- package/dist/src/services/MonorepoAwareDiscoveryService.d.ts +1 -45
- package/dist/src/services/MonorepoAwareDiscoveryService.js +1 -51
- package/dist/src/services/NxMonorepoResolver.d.ts +0 -29
- package/dist/src/services/NxMonorepoResolver.js +5 -56
- package/dist/src/services/OpenAICompatibleEmbedder.d.ts +0 -6
- package/dist/src/services/OpenAICompatibleEmbedder.js +0 -14
- package/dist/src/services/ProjectDiscoveryService.d.ts +0 -4
- package/dist/src/services/ProjectDiscoveryService.js +0 -4
- package/dist/src/services/VoyageEmbedder.d.ts +0 -6
- package/dist/src/services/VoyageEmbedder.js +0 -6
- package/dist/src/services/WebServerService.d.ts +5 -56
- package/dist/src/services/WebServerService.js +25 -63
- package/dist/src/services/http-retry.d.ts +0 -7
- package/dist/src/services/http-retry.js +1 -10
- package/dist/src/services/infinity-provisioning.d.ts +0 -74
- package/dist/src/services/infinity-provisioning.js +5 -88
- package/dist/src/services/legacy-ollama-index.d.ts +0 -16
- package/dist/src/services/legacy-ollama-index.js +0 -23
- package/dist/src/services/reranker.d.ts +0 -9
- package/dist/src/services/reranker.js +46 -12
- package/dist/src/setup.d.ts +24 -24
- package/dist/src/setup.js +205 -103
- package/dist/src/symbol-name.d.ts +1 -12
- package/dist/src/symbol-name.js +16 -25
- package/dist/src/symbol-rows.d.ts +0 -14
- package/dist/src/symbol-rows.js +0 -14
- package/dist/src/tool-call-log.d.ts +2 -0
- package/dist/src/tool-call-log.js +24 -0
- package/dist/src/tools/FindSymbolTool.d.ts +17 -7
- package/dist/src/tools/FindSymbolTool.js +54 -35
- package/dist/src/tools/GetCallersTool.d.ts +16 -8
- package/dist/src/tools/GetCallersTool.js +65 -35
- package/dist/src/tools/GetDependenciesTool.d.ts +16 -8
- package/dist/src/tools/GetDependenciesTool.js +36 -29
- package/dist/src/tools/GetDependentsTool.d.ts +20 -8
- package/dist/src/tools/GetDependentsTool.js +48 -34
- package/dist/src/tools/ListFilesTool.d.ts +16 -8
- package/dist/src/tools/ListFilesTool.js +20 -26
- package/dist/src/tools/ListProjectsTool.d.ts +11 -7
- package/dist/src/tools/ListProjectsTool.js +13 -11
- package/dist/src/tools/McpTool.d.ts +17 -0
- package/dist/src/tools/McpTool.js +28 -0
- package/dist/src/tools/ReadFileRangeTool.d.ts +16 -8
- package/dist/src/tools/ReadFileRangeTool.js +23 -25
- package/dist/src/tools/ReadFileTool.d.ts +15 -8
- package/dist/src/tools/ReadFileTool.js +19 -24
- package/dist/src/tools/SearchCodebaseTool.d.ts +22 -10
- package/dist/src/tools/SearchCodebaseTool.js +71 -50
- package/dist/src/tools/format-helpers.d.ts +9 -9
- package/dist/src/tools/format-helpers.js +146 -28
- package/dist/src/tools/tool-args.d.ts +38 -0
- package/dist/src/tools/tool-args.js +95 -0
- package/dist/src/web/dashboard.d.ts +0 -8
- package/dist/src/web/dashboard.js +7 -10
- package/dist/src/workspace/GrepRunner.d.ts +15 -0
- package/dist/src/workspace/GrepRunner.js +104 -0
- package/dist/src/workspace/ProjectRoots.d.ts +22 -0
- package/dist/src/workspace/ProjectRoots.js +102 -0
- package/dist/src/workspace/ToolPaths.d.ts +31 -0
- package/dist/src/workspace/ToolPaths.js +312 -0
- package/dist/src/workspace/WorkspaceFiles.d.ts +19 -0
- package/dist/src/workspace/WorkspaceFiles.js +285 -0
- package/dist/src/workspace/fs-access.d.ts +9 -0
- package/dist/src/workspace/fs-access.js +47 -0
- package/dist/src/workspace/path-helpers.d.ts +3 -0
- package/dist/src/workspace/path-helpers.js +43 -0
- package/package.json +5 -4
- package/dist/src/interfaces/ISearcher.d.ts +0 -35
- package/dist/src/services/AstChunker.d.ts +0 -42
- package/dist/src/services/AstChunker.js +0 -158
- package/dist/src/services/SearcherService.d.ts +0 -342
- package/dist/src/services/SearcherService.js +0 -1199
- package/docs/web-dashboard.md +0 -206
- /package/dist/src/{interfaces/ISearcher.js → chunking/interfaces.js} +0 -0
|
@@ -36,194 +36,74 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.IndexerService = void 0;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
|
-
const crypto_1 = require("crypto");
|
|
40
|
-
const cli_progress_1 = require("cli-progress");
|
|
41
|
-
const drizzle_orm_1 = require("drizzle-orm");
|
|
42
|
-
const owner_path_1 = require("../owner-path");
|
|
43
|
-
const enriched_prompt_1 = require("../enriched-prompt");
|
|
44
|
-
const symbol_rows_1 = require("../symbol-rows");
|
|
45
|
-
const db_1 = require("../db");
|
|
46
39
|
const file_utils_1 = require("../file-utils");
|
|
47
40
|
const LoggerService_1 = require("./LoggerService");
|
|
48
|
-
const
|
|
49
|
-
const
|
|
41
|
+
const IndexStore_1 = require("../indexing/IndexStore");
|
|
42
|
+
const StaleFilePruner_1 = require("../indexing/StaleFilePruner");
|
|
43
|
+
const AnalysisBatcher_1 = require("../indexing/AnalysisBatcher");
|
|
44
|
+
const ChunkEmbedder_1 = require("../indexing/ChunkEmbedder");
|
|
45
|
+
const FileIngestor_1 = require("../indexing/FileIngestor");
|
|
46
|
+
const project_notices_1 = require("../indexing/project-notices");
|
|
47
|
+
const ConsoleScanReporter_1 = require("../indexing/ConsoleScanReporter");
|
|
48
|
+
const EmbeddingSchemaPreparer_1 = require("../indexing/EmbeddingSchemaPreparer");
|
|
50
49
|
class IndexerService {
|
|
51
50
|
db;
|
|
52
|
-
embedder;
|
|
53
51
|
ast;
|
|
54
|
-
chunker;
|
|
55
|
-
config;
|
|
56
52
|
logger;
|
|
53
|
+
store;
|
|
54
|
+
stalePruner;
|
|
55
|
+
batcher;
|
|
56
|
+
chunkEmbedder;
|
|
57
|
+
ingestor;
|
|
58
|
+
schema;
|
|
57
59
|
constructor(db, embedder, ast, chunker, config, logger = LoggerService_1.LoggerService.silent()) {
|
|
58
60
|
this.db = db;
|
|
59
|
-
this.embedder = embedder;
|
|
60
61
|
this.ast = ast;
|
|
61
|
-
this.chunker = chunker;
|
|
62
|
-
this.config = config;
|
|
63
62
|
this.logger = logger;
|
|
63
|
+
this.store = new IndexStore_1.IndexStore(db, config);
|
|
64
|
+
this.stalePruner = new StaleFilePruner_1.StaleFilePruner(db, config);
|
|
65
|
+
this.batcher = new AnalysisBatcher_1.AnalysisBatcher(ast, config);
|
|
66
|
+
this.chunkEmbedder = new ChunkEmbedder_1.ChunkEmbedder(embedder, config);
|
|
67
|
+
this.ingestor = new FileIngestor_1.FileIngestor(this.store, this.chunkEmbedder, chunker, config, logger);
|
|
68
|
+
this.schema = new EmbeddingSchemaPreparer_1.EmbeddingSchemaPreparer(db, embedder, config, logger);
|
|
64
69
|
}
|
|
65
|
-
/**
|
|
66
|
-
* Resolve the active embedding dimension (config override → registry → probe),
|
|
67
|
-
* reconcile it against `index_meta`, and prepare `code_chunk` accordingly:
|
|
68
|
-
* a dimension change drops+recreates the table; a same-dimension model/provider
|
|
69
|
-
* change clears its rows (vector spaces are not comparable across models); an
|
|
70
|
-
* unchanged model keeps the rows for incremental indexing. Back-compat: an
|
|
71
|
-
* existing populated table with no `index_meta` row is treated as the legacy
|
|
72
|
-
* `ollama`/`bge-m3`/1024 index. Writes `index_meta` to reflect the active model.
|
|
73
|
-
* Call once per run, before the scan loop.
|
|
74
|
-
*/
|
|
75
70
|
async prepareEmbeddingSchema() {
|
|
76
|
-
|
|
77
|
-
const next = {
|
|
78
|
-
provider,
|
|
79
|
-
model,
|
|
80
|
-
dimensions: await (0, constants_1.resolveDimension)(override, model, async () => {
|
|
81
|
-
const probe = await this.embedder.embed('probe', 'document');
|
|
82
|
-
return probe.length;
|
|
83
|
-
}),
|
|
84
|
-
};
|
|
85
|
-
const meta = await this.db.readIndexMeta();
|
|
86
|
-
if (!meta) {
|
|
87
|
-
const chunkCount = await this.countChunks();
|
|
88
|
-
if (chunkCount === 0) {
|
|
89
|
-
// Fresh index — create the table at the resolved width and record it.
|
|
90
|
-
await this.db.recreateChunkTable(next.dimensions);
|
|
91
|
-
await this.db.writeIndexMeta(next);
|
|
92
|
-
this.logger.debug('IndexerService: prepared fresh index', { ...next });
|
|
93
|
-
return next;
|
|
94
|
-
}
|
|
95
|
-
// Legacy index (pre-index_meta): assume the historical default model.
|
|
96
|
-
await this.reconcileIndex({ provider: 'ollama', model: 'bge-m3', dimensions: 1024 }, next);
|
|
97
|
-
return next;
|
|
98
|
-
}
|
|
99
|
-
await this.reconcileIndex(meta, next);
|
|
100
|
-
return next;
|
|
101
|
-
}
|
|
102
|
-
async reconcileIndex(prev, next) {
|
|
103
|
-
if (prev.dimensions !== next.dimensions) {
|
|
104
|
-
console.log(`Embedding dimension changed (${prev.dimensions} → ${next.dimensions}) — recreating code_chunk.`);
|
|
105
|
-
this.logger.info('IndexerService: dimension change, recreating code_chunk', { prev, next });
|
|
106
|
-
await this.db.recreateChunkTable(next.dimensions);
|
|
107
|
-
}
|
|
108
|
-
else if (prev.provider !== next.provider || prev.model !== next.model) {
|
|
109
|
-
console.log(`Embedding model changed (${prev.provider}/${prev.model} → ${next.provider}/${next.model}) — clearing index.`);
|
|
110
|
-
this.logger.info('IndexerService: model change, clearing code_chunk', { prev, next });
|
|
111
|
-
await this.db.query(`DELETE FROM code_chunk`);
|
|
112
|
-
}
|
|
113
|
-
await this.db.writeIndexMeta(next);
|
|
114
|
-
}
|
|
115
|
-
async countChunks() {
|
|
116
|
-
try {
|
|
117
|
-
const rows = await this.db.query(`SELECT COUNT(*)::int AS n FROM code_chunk`);
|
|
118
|
-
return Number(rows[0]?.n ?? 0);
|
|
119
|
-
}
|
|
120
|
-
catch (err) {
|
|
121
|
-
// A missing table means a fresh install → 0. Any other (transient) error
|
|
122
|
-
// must propagate — returning 0 here could wrongly recreate/drop a populated
|
|
123
|
-
// table on the `!meta` path.
|
|
124
|
-
if (/does not exist/i.test(err.message))
|
|
125
|
-
return 0;
|
|
126
|
-
throw err;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
async writeDepEdges(serviceName, relFilePath, edges, tx) {
|
|
130
|
-
const run = async (t) => {
|
|
131
|
-
await t.delete(db_1.codeDependency).where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(db_1.codeDependency.project, serviceName), (0, drizzle_orm_1.eq)(db_1.codeDependency.fromFile, relFilePath)));
|
|
132
|
-
if (edges.length > 0) {
|
|
133
|
-
await t.insert(db_1.codeDependency).values(edges);
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
if (tx)
|
|
137
|
-
await run(tx);
|
|
138
|
-
else
|
|
139
|
-
await this.db.transaction(run);
|
|
71
|
+
return this.schema.prepare();
|
|
140
72
|
}
|
|
141
73
|
async scanAndIndex(dir, serviceName, force = false, signal, preCollectedFiles, opts) {
|
|
142
74
|
const startTime = Date.now();
|
|
75
|
+
const reporter = new ConsoleScanReporter_1.ConsoleScanReporter();
|
|
143
76
|
this.logger.debug('IndexerService: scanAndIndex start', { serviceName, dir, force });
|
|
144
77
|
if (force) {
|
|
145
|
-
|
|
146
|
-
// transaction: a file whose re-ingestion later fails must hold no rows at
|
|
147
|
-
// all, never rows in the previous (pre-member-extraction) format.
|
|
148
|
-
await this.db.transaction(async (tx) => {
|
|
149
|
-
await tx.update(db_1.codeChunk)
|
|
150
|
-
.set({ lastModified: null, contentHash: null })
|
|
151
|
-
.where((0, drizzle_orm_1.eq)(db_1.codeChunk.serviceName, serviceName));
|
|
152
|
-
await tx.delete(db_1.codeSymbol).where((0, drizzle_orm_1.eq)(db_1.codeSymbol.project, serviceName));
|
|
153
|
-
await tx.delete(db_1.codeCall).where((0, drizzle_orm_1.eq)(db_1.codeCall.project, serviceName));
|
|
154
|
-
});
|
|
78
|
+
await this.store.resetProject(serviceName);
|
|
155
79
|
}
|
|
156
80
|
const files = preCollectedFiles ?? (0, file_utils_1.collectFiles)(dir, (0, file_utils_1.loadIgnore)(dir), dir);
|
|
157
81
|
this.logger.debug('IndexerService: scanAndIndex files collected', { serviceName, count: files.length, force });
|
|
158
|
-
const
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
if (staleFiles.length > 0) {
|
|
162
|
-
await this.db.deleteFiles(serviceName, staleFiles);
|
|
163
|
-
for (const f of staleFiles) {
|
|
164
|
-
console.log(` Removed stale: ${path.basename(f)}`);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
const bar = new cli_progress_1.SingleBar({
|
|
168
|
-
format: `{serviceName} {bar} {percentage}% | {value}/{total} | {duration_formatted} elapsed | ~{eta_formatted} left | {filename}`,
|
|
169
|
-
barCompleteChar: '█',
|
|
170
|
-
barIncompleteChar: '░',
|
|
171
|
-
hideCursor: true,
|
|
172
|
-
clearOnComplete: false,
|
|
173
|
-
}, cli_progress_1.Presets.shades_grey);
|
|
174
|
-
const warnings = [];
|
|
175
|
-
console.log(`\nIndexing ${serviceName}: ${files.length} files`);
|
|
176
|
-
const meta = (0, file_utils_1.readRagMeta)(dir);
|
|
177
|
-
if (meta === 'invalid') {
|
|
178
|
-
const msg = `.ragmeta.json found but invalid JSON`;
|
|
179
|
-
console.log(` ⚠ ${msg}`);
|
|
180
|
-
warnings.push(msg);
|
|
181
|
-
}
|
|
182
|
-
else if (meta !== 'missing') {
|
|
183
|
-
const parts = [meta.description, meta.stack && `[${meta.stack}]`].filter(Boolean).join(' ');
|
|
184
|
-
console.log(` ✓ .ragmeta.json: ${parts || '(no fields)'}`);
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
const msg = `No .ragmeta.json — add {"description":"...","stack":"...","notes":"..."} so list_projects can describe this project`;
|
|
188
|
-
console.log(` ⚠ ${msg}`);
|
|
189
|
-
warnings.push(msg);
|
|
82
|
+
const staleFiles = await this.stalePruner.prune(serviceName, files);
|
|
83
|
+
for (const f of staleFiles) {
|
|
84
|
+
reporter.staleRemoved(f);
|
|
190
85
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
warnings.push(msg);
|
|
195
|
-
}
|
|
196
|
-
if (files.length > this.config.indexer.astBatchSize) {
|
|
197
|
-
console.log(` ⚠ Large project (${files.length} files) — AST analysis uses batches of ${this.config.indexer.astBatchSize}; cross-batch dependency edges may be incomplete`);
|
|
198
|
-
}
|
|
199
|
-
bar.start(files.length, 0, { serviceName, filename: '' });
|
|
86
|
+
const notices = (0, project_notices_1.collectProjectNotices)(dir, files.length, this.batcher.batchSize);
|
|
87
|
+
reporter.begin(serviceName, files.length, notices);
|
|
88
|
+
const warnings = notices.filter(n => n.warning).map(n => n.message);
|
|
200
89
|
const stats = {
|
|
201
90
|
serviceName, indexed: 0, skipped: 0, failed: 0, chunks: 0, elapsedSec: 0, warnings,
|
|
202
91
|
};
|
|
203
92
|
const mtimeRefreshBatch = [];
|
|
204
|
-
const
|
|
205
|
-
for (let batchStart = 0; batchStart < files.length; batchStart += this.config.indexer.astBatchSize) {
|
|
206
|
-
if (signal?.aborted)
|
|
207
|
-
break;
|
|
208
|
-
const batch = files.slice(batchStart, batchStart + this.config.indexer.astBatchSize);
|
|
209
|
-
const analysisMap = await this.ast.analyzeProject(batch, serviceName, dir, {
|
|
210
|
-
skipDependencyResolution: isLargeProject,
|
|
211
|
-
rootTsConfigPath: opts?.rootTsConfigPath,
|
|
212
|
-
});
|
|
93
|
+
for await (const { batch, analysisMap } of this.batcher.batches(files, serviceName, dir, signal, opts?.rootTsConfigPath)) {
|
|
213
94
|
for (const filePath of batch) {
|
|
214
95
|
if (signal?.aborted) {
|
|
215
|
-
|
|
216
|
-
console.log(`\n Interrupted — ${serviceName}`);
|
|
96
|
+
reporter.interrupted(serviceName);
|
|
217
97
|
stats.elapsedSec = Math.round((Date.now() - startTime) / 100) / 10;
|
|
218
98
|
return stats;
|
|
219
99
|
}
|
|
220
|
-
|
|
100
|
+
reporter.file(path.relative(dir, filePath));
|
|
221
101
|
const mtimeMs = fs.statSync(filePath).mtimeMs;
|
|
222
102
|
const analysis = analysisMap.get(filePath);
|
|
223
103
|
if (analysis === undefined && /\.(ts|tsx|js|jsx)$/.test(filePath) && !/\.d\.ts$/.test(filePath)) {
|
|
224
104
|
this.logger.warn('IndexerService: no pre-computed analysis for TS file', { file: filePath });
|
|
225
105
|
}
|
|
226
|
-
const result = await this.ingestFile(filePath, serviceName, mtimeMs, dir, analysis
|
|
106
|
+
const result = await this.ingestor.ingestFile(filePath, serviceName, mtimeMs, dir, analysis);
|
|
227
107
|
if (result.pendingMtimeRefresh) {
|
|
228
108
|
mtimeRefreshBatch.push({ relFilePath: result.pendingMtimeRefresh, mtimeMs });
|
|
229
109
|
}
|
|
@@ -234,23 +114,16 @@ class IndexerService {
|
|
|
234
114
|
else
|
|
235
115
|
stats.failed++;
|
|
236
116
|
stats.chunks += result.chunks;
|
|
237
|
-
|
|
117
|
+
reporter.advance();
|
|
238
118
|
}
|
|
239
119
|
}
|
|
240
|
-
|
|
241
|
-
process.stdout.write('\x1B[J');
|
|
120
|
+
reporter.end();
|
|
242
121
|
if (mtimeRefreshBatch.length > 0) {
|
|
243
122
|
try {
|
|
244
|
-
await this.
|
|
245
|
-
FROM unnest($1::text[], $2::float8[]) AS t(fp, mtime)
|
|
246
|
-
WHERE "serviceName" = $3 AND "filePath" = t.fp`, [
|
|
247
|
-
mtimeRefreshBatch.map(r => r.relFilePath),
|
|
248
|
-
mtimeRefreshBatch.map(r => r.mtimeMs),
|
|
249
|
-
serviceName,
|
|
250
|
-
]);
|
|
123
|
+
await this.store.refreshMtimes(serviceName, mtimeRefreshBatch);
|
|
251
124
|
}
|
|
252
125
|
catch (err) {
|
|
253
|
-
this.logger.error('IndexerService: mtime refresh batch failed', {
|
|
126
|
+
this.logger.error('IndexerService: mtime refresh batch failed', { err });
|
|
254
127
|
}
|
|
255
128
|
}
|
|
256
129
|
this.ast.clearCache(dir);
|
|
@@ -265,12 +138,6 @@ class IndexerService {
|
|
|
265
138
|
});
|
|
266
139
|
return stats;
|
|
267
140
|
}
|
|
268
|
-
/**
|
|
269
|
-
* Scan several leaf projects in one call, each with its own `rootTsConfigPath`
|
|
270
|
-
* (a unit's children may belong to different monorepos). No pruning, no
|
|
271
|
-
* console output — callers (CLI or a future hook) own reporting. A rejecting
|
|
272
|
-
* `scanAndIndex` call stops the loop before the next target and propagates.
|
|
273
|
-
*/
|
|
274
141
|
async scanProjects(targets, force, signal, filesPerProject) {
|
|
275
142
|
const allStats = [];
|
|
276
143
|
for (let i = 0; i < targets.length; i++) {
|
|
@@ -296,126 +163,11 @@ class IndexerService {
|
|
|
296
163
|
}
|
|
297
164
|
catch (err) {
|
|
298
165
|
console.error(`Failed to prune project ${name}: ${err.message}`);
|
|
299
|
-
this.logger.error('IndexerService: pruneProject failed', { name,
|
|
166
|
+
this.logger.error('IndexerService: pruneProject failed', { name, err });
|
|
300
167
|
failed.push(name);
|
|
301
168
|
}
|
|
302
169
|
}
|
|
303
170
|
return { removed, failed };
|
|
304
171
|
}
|
|
305
|
-
static hashContent(content) {
|
|
306
|
-
return (0, crypto_1.createHash)('sha256').update(content).digest('hex');
|
|
307
|
-
}
|
|
308
|
-
async ingestFile(filePath, serviceName, mtimeMs, projectRoot, analysis, meta) {
|
|
309
|
-
try {
|
|
310
|
-
const relFilePath = path.relative(this.config.workspaceRoot, filePath);
|
|
311
|
-
const [existing] = await this.db.orm
|
|
312
|
-
.select({ id: db_1.codeChunk.id, lastModified: db_1.codeChunk.lastModified, contentHash: db_1.codeChunk.contentHash })
|
|
313
|
-
.from(db_1.codeChunk)
|
|
314
|
-
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(db_1.codeChunk.serviceName, serviceName), (0, drizzle_orm_1.eq)(db_1.codeChunk.filePath, relFilePath)))
|
|
315
|
-
.limit(1);
|
|
316
|
-
// Fast path: mtime unchanged — skip without reading file
|
|
317
|
-
if (existing?.lastModified === mtimeMs) {
|
|
318
|
-
return { status: 'skipped', chunks: 0 };
|
|
319
|
-
}
|
|
320
|
-
const t0 = Date.now();
|
|
321
|
-
const code = fs.readFileSync(filePath, 'utf-8');
|
|
322
|
-
const hash = IndexerService.hashContent(code);
|
|
323
|
-
// Content unchanged (mtime drifted — DB transfer, git clone, touch)
|
|
324
|
-
if (existing !== undefined && existing.contentHash !== null && existing.contentHash === hash) {
|
|
325
|
-
return { status: 'skipped', chunks: 0, pendingMtimeRefresh: relFilePath };
|
|
326
|
-
}
|
|
327
|
-
const tAst = Date.now();
|
|
328
|
-
const { edges: rawEdges, symbols: rawSymbols, members: rawMembers = [], calls: rawCalls, ownerRanges: rawOwnerRanges = [], graphqlNames: rawGraphqlNames = [], } = analysis ?? { edges: [], symbols: [], calls: [] };
|
|
329
|
-
// astMs is near-zero — actual AST time is spent upfront in analyzeProject()
|
|
330
|
-
// Normalize edges to workspace-relative paths
|
|
331
|
-
const edges = rawEdges
|
|
332
|
-
.filter(e => e.toFile.startsWith(this.config.workspaceRoot))
|
|
333
|
-
.map(e => ({
|
|
334
|
-
...e,
|
|
335
|
-
fromFile: path.relative(this.config.workspaceRoot, e.fromFile),
|
|
336
|
-
toFile: path.relative(this.config.workspaceRoot, e.toFile),
|
|
337
|
-
}));
|
|
338
|
-
// Normalize call edges to workspace-relative paths; keep only resolved internal calls
|
|
339
|
-
const calls = rawCalls
|
|
340
|
-
.filter(c => c.calleeFile.startsWith(this.config.workspaceRoot))
|
|
341
|
-
.map(c => ({
|
|
342
|
-
project: serviceName,
|
|
343
|
-
fromFile: relFilePath,
|
|
344
|
-
fromSymbol: c.fromSymbol,
|
|
345
|
-
calleeName: c.calleeName,
|
|
346
|
-
calleeFile: path.relative(this.config.workspaceRoot, c.calleeFile),
|
|
347
|
-
calleeSymbol: c.calleeSymbol,
|
|
348
|
-
line: c.line,
|
|
349
|
-
col: c.col,
|
|
350
|
-
}));
|
|
351
|
-
// symbols ∪ members ∪ graphqlNames → code_symbol rows: overload sets
|
|
352
|
-
// collapse to their representative row (graphqlNames bypass the
|
|
353
|
-
// collapse), then a final dedup by (container, name, kind, line).
|
|
354
|
-
const symbolRows = (0, symbol_rows_1.buildSymbolRows)(rawSymbols, rawMembers, rawGraphqlNames).map(s => ({ ...s, filePath: relFilePath }));
|
|
355
|
-
// Side-effect imports bind no name, so they stay out of the Dependencies: line.
|
|
356
|
-
const promptEdges = edges.filter(e => e.depType !== 'import-side-effect');
|
|
357
|
-
const astMs = Date.now() - tAst;
|
|
358
|
-
const chunks = await this.chunker.chunk(code, {
|
|
359
|
-
strategy: this.config.indexer.chunkStrategy,
|
|
360
|
-
isSchemaFile: SCHEMA_EXTENSIONS.test(filePath),
|
|
361
|
-
symbols: rawSymbols,
|
|
362
|
-
});
|
|
363
|
-
const relPath = path.relative(projectRoot, filePath);
|
|
364
|
-
// Ownership ranges (decorator-inclusive, symbols ∪ members minus
|
|
365
|
-
// method_signature) are built by AstParserService — the deepest range
|
|
366
|
-
// containing a chunk's start line wins.
|
|
367
|
-
const ownerRanges = rawOwnerRanges;
|
|
368
|
-
const t2 = Date.now();
|
|
369
|
-
const records = [];
|
|
370
|
-
const embedBatchSize = this.config.embedding.batchSize;
|
|
371
|
-
for (let i = 0; i < chunks.length; i += embedBatchSize) {
|
|
372
|
-
const batch = chunks.slice(i, i + embedBatchSize);
|
|
373
|
-
const prompts = batch.map(piece => (0, enriched_prompt_1.getEnrichedPrompt)(piece, relPath, serviceName, promptEdges, rawSymbols));
|
|
374
|
-
const vectors = await this.embedder.embedBatch(prompts, 'document');
|
|
375
|
-
for (let j = 0; j < batch.length; j++) {
|
|
376
|
-
const piece = batch[j];
|
|
377
|
-
records.push({
|
|
378
|
-
serviceName, filePath: relFilePath, startLine: piece.startLine,
|
|
379
|
-
content: piece.content,
|
|
380
|
-
embedding: `[${vectors[j]}]`,
|
|
381
|
-
lastModified: mtimeMs,
|
|
382
|
-
contentHash: hash,
|
|
383
|
-
ownerPath: (0, owner_path_1.resolveOwnerPath)(piece.startLine, ownerRanges),
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
const embedMs = Date.now() - t2;
|
|
388
|
-
const t3 = Date.now();
|
|
389
|
-
await this.db.transaction(async (tx) => {
|
|
390
|
-
await tx.delete(db_1.codeChunk).where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(db_1.codeChunk.serviceName, serviceName), (0, drizzle_orm_1.eq)(db_1.codeChunk.filePath, relFilePath)));
|
|
391
|
-
for (let i = 0; i < records.length; i += this.config.indexer.batchSize) {
|
|
392
|
-
await tx.insert(db_1.codeChunk).values(records.slice(i, i + this.config.indexer.batchSize));
|
|
393
|
-
}
|
|
394
|
-
await this.writeDepEdges(serviceName, relFilePath, edges, tx);
|
|
395
|
-
await tx.delete(db_1.codeSymbol).where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(db_1.codeSymbol.project, serviceName), (0, drizzle_orm_1.eq)(db_1.codeSymbol.filePath, relFilePath)));
|
|
396
|
-
if (symbolRows.length > 0) {
|
|
397
|
-
await tx.insert(db_1.codeSymbol).values(symbolRows);
|
|
398
|
-
}
|
|
399
|
-
await tx.delete(db_1.codeCall).where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(db_1.codeCall.project, serviceName), (0, drizzle_orm_1.eq)(db_1.codeCall.fromFile, relFilePath)));
|
|
400
|
-
if (calls.length > 0) {
|
|
401
|
-
await tx.insert(db_1.codeCall).values(calls);
|
|
402
|
-
}
|
|
403
|
-
});
|
|
404
|
-
const dbMs = Date.now() - t3;
|
|
405
|
-
if (chunks.length > 0) {
|
|
406
|
-
this.logger.debug('IndexerService: file indexed', {
|
|
407
|
-
file: relFilePath, chunks: chunks.length,
|
|
408
|
-
astMs, embedMs, dbMs, totalMs: Date.now() - t0,
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
return { status: 'indexed', chunks: chunks.length };
|
|
412
|
-
}
|
|
413
|
-
catch (err) {
|
|
414
|
-
const reason = err.message;
|
|
415
|
-
console.error(`\n[indexer] Failed: ${filePath} — ${reason}`);
|
|
416
|
-
this.logger.error('IndexerService: failed to index file', { file: filePath, reason });
|
|
417
|
-
return { status: 'failed', chunks: 0 };
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
172
|
}
|
|
421
173
|
exports.IndexerService = IndexerService;
|
|
@@ -4,35 +4,14 @@ import { OpenAICompatibleEmbedder, type EmbedderDeps } from './OpenAICompatibleE
|
|
|
4
4
|
import { serverRoot, probeInfinityHealth, listInfinityModels, type ProvisioningDeps } from './infinity-provisioning';
|
|
5
5
|
export { serverRoot, probeInfinityHealth, listInfinityModels };
|
|
6
6
|
export type { CommandResult } from './infinity-provisioning';
|
|
7
|
-
/** Extra injection seams for `InfinityEmbedder` beyond the shared `EmbedderDeps`. */
|
|
8
7
|
export interface InfinityDeps extends EmbedderDeps, ProvisioningDeps {
|
|
9
|
-
/**
|
|
10
|
-
* Path to the managed docker-compose.yml. Defaults to the file `rag-setup`
|
|
11
|
-
* writes into `~/.config/codesearch-mcp/`. A missing file (or one without an
|
|
12
|
-
* `infinity` service) means "external backend" — the Docker path is skipped.
|
|
13
|
-
*/
|
|
14
8
|
composePath?: string;
|
|
15
9
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Embedder for a local Infinity server. Inherits the OpenAI-style `/embeddings`
|
|
18
|
-
* HTTP path, batching, retry, and reranker wiring from `OpenAICompatibleEmbedder`
|
|
19
|
-
* unchanged — it adds ONLY container-readiness behavior (`ensureModelAvailable`,
|
|
20
|
-
* `listModels`), delegating to the standalone `infinity-provisioning` primitive
|
|
21
|
-
* because Infinity binds its model set at container startup and exposes no
|
|
22
|
-
* runtime model-pull API.
|
|
23
|
-
*/
|
|
24
10
|
export declare class InfinityEmbedder extends OpenAICompatibleEmbedder {
|
|
25
11
|
private readonly base;
|
|
26
12
|
private readonly composePath;
|
|
27
13
|
private readonly provisioningDeps;
|
|
28
14
|
constructor(config: Config, logger?: ILogger, deps?: InfinityDeps);
|
|
29
|
-
/**
|
|
30
|
-
* Index-time embed readiness (see `local-backend-provisioning`): verifies only
|
|
31
|
-
* the embedding model — indexing does not use the reranker, so a missing
|
|
32
|
-
* reranker model never blocks or restarts indexing. Whenever a recreate is
|
|
33
|
-
* needed, the full configured set is written so an already-served reranker
|
|
34
|
-
* model is never dropped. Called by `IndexCommand` before indexing.
|
|
35
|
-
*/
|
|
36
15
|
ensureModelAvailable(): Promise<void>;
|
|
37
16
|
listModels(): Promise<string[]>;
|
|
38
17
|
}
|
|
@@ -42,14 +42,6 @@ Object.defineProperty(exports, "serverRoot", { enumerable: true, get: function (
|
|
|
42
42
|
Object.defineProperty(exports, "probeInfinityHealth", { enumerable: true, get: function () { return infinity_provisioning_1.probeInfinityHealth; } });
|
|
43
43
|
Object.defineProperty(exports, "listInfinityModels", { enumerable: true, get: function () { return infinity_provisioning_1.listInfinityModels; } });
|
|
44
44
|
const path = __importStar(require("path"));
|
|
45
|
-
/**
|
|
46
|
-
* Embedder for a local Infinity server. Inherits the OpenAI-style `/embeddings`
|
|
47
|
-
* HTTP path, batching, retry, and reranker wiring from `OpenAICompatibleEmbedder`
|
|
48
|
-
* unchanged — it adds ONLY container-readiness behavior (`ensureModelAvailable`,
|
|
49
|
-
* `listModels`), delegating to the standalone `infinity-provisioning` primitive
|
|
50
|
-
* because Infinity binds its model set at container startup and exposes no
|
|
51
|
-
* runtime model-pull API.
|
|
52
|
-
*/
|
|
53
45
|
class InfinityEmbedder extends OpenAICompatibleEmbedder_1.OpenAICompatibleEmbedder {
|
|
54
46
|
base;
|
|
55
47
|
composePath;
|
|
@@ -65,13 +57,6 @@ class InfinityEmbedder extends OpenAICompatibleEmbedder_1.OpenAICompatibleEmbedd
|
|
|
65
57
|
readinessTimeoutMs: deps.readinessTimeoutMs,
|
|
66
58
|
};
|
|
67
59
|
}
|
|
68
|
-
/**
|
|
69
|
-
* Index-time embed readiness (see `local-backend-provisioning`): verifies only
|
|
70
|
-
* the embedding model — indexing does not use the reranker, so a missing
|
|
71
|
-
* reranker model never blocks or restarts indexing. Whenever a recreate is
|
|
72
|
-
* needed, the full configured set is written so an already-served reranker
|
|
73
|
-
* model is never dropped. Called by `IndexCommand` before indexing.
|
|
74
|
-
*/
|
|
75
60
|
async ensureModelAvailable() {
|
|
76
61
|
await (0, infinity_provisioning_1.ensureBackendReady)({
|
|
77
62
|
baseURL: this.config.embedding.baseURL,
|
|
@@ -3,17 +3,19 @@ import type { ILogger } from '../interfaces/ILogger';
|
|
|
3
3
|
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
4
4
|
export declare class LoggerService implements ILogger {
|
|
5
5
|
private readonly logger;
|
|
6
|
-
private readonly
|
|
7
|
-
constructor(
|
|
6
|
+
private readonly context;
|
|
7
|
+
private constructor();
|
|
8
8
|
static silent(): LoggerService;
|
|
9
9
|
static fromConfig(cfg: {
|
|
10
10
|
level: string;
|
|
11
11
|
dir?: string;
|
|
12
|
-
}, name?: string): LoggerService;
|
|
13
|
-
|
|
12
|
+
}, name?: string, bindings?: Record<string, unknown>): LoggerService;
|
|
13
|
+
static toStream(level: LogLevel, stream: pino.DestinationStream, bindings?: Record<string, unknown>): LoggerService;
|
|
14
|
+
private static fileTransport;
|
|
15
|
+
private static build;
|
|
14
16
|
debug(msg: string, data?: Record<string, unknown>): void;
|
|
15
17
|
info(msg: string, data?: Record<string, unknown>): void;
|
|
16
18
|
warn(msg: string, data?: Record<string, unknown>): void;
|
|
17
19
|
error(msg: string, data?: Record<string, unknown>): void;
|
|
18
|
-
|
|
20
|
+
withContext<T>(context: Record<string, unknown>, fn: () => Promise<T>): Promise<T>;
|
|
19
21
|
}
|
|
@@ -41,21 +41,20 @@ const pino_1 = __importDefault(require("pino"));
|
|
|
41
41
|
const path = __importStar(require("path"));
|
|
42
42
|
const os = __importStar(require("os"));
|
|
43
43
|
const fs = __importStar(require("fs"));
|
|
44
|
+
const async_hooks_1 = require("async_hooks");
|
|
45
|
+
const error_record_1 = require("../error-record");
|
|
44
46
|
const DEFAULT_LOG_DIR = path.join(os.homedir(), '.config', 'codesearch-mcp', 'logs');
|
|
45
47
|
class LoggerService {
|
|
46
48
|
logger;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
// metrics never reach stdout (owned by the MCP JSON transport).
|
|
50
|
-
metricsLogger;
|
|
51
|
-
constructor(logger, metricsLogger = null) {
|
|
49
|
+
context;
|
|
50
|
+
constructor(logger, context) {
|
|
52
51
|
this.logger = logger;
|
|
53
|
-
this.
|
|
52
|
+
this.context = context;
|
|
54
53
|
}
|
|
55
54
|
static silent() {
|
|
56
|
-
return
|
|
55
|
+
return LoggerService.build('debug', undefined);
|
|
57
56
|
}
|
|
58
|
-
static fromConfig(cfg, name) {
|
|
57
|
+
static fromConfig(cfg, name, bindings) {
|
|
59
58
|
const level = cfg.level;
|
|
60
59
|
const dirVal = cfg.dir;
|
|
61
60
|
const enabled = dirVal !== 'false' && dirVal !== '0';
|
|
@@ -66,45 +65,42 @@ class LoggerService {
|
|
|
66
65
|
? path.join(logDir, name, `${name}.log`)
|
|
67
66
|
: path.join(logDir, 'rag.log');
|
|
68
67
|
}
|
|
69
|
-
return LoggerService.
|
|
68
|
+
return LoggerService.build(level, filePath ? LoggerService.fileTransport(level, filePath) : undefined, bindings);
|
|
70
69
|
}
|
|
71
|
-
static
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
? (0, pino_1.default)({ level }, transport)
|
|
70
|
+
static toStream(level, stream, bindings) {
|
|
71
|
+
return LoggerService.build(level, stream, bindings);
|
|
72
|
+
}
|
|
73
|
+
static fileTransport(level, filePath) {
|
|
74
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
75
|
+
return pino_1.default.transport({
|
|
76
|
+
targets: [{
|
|
77
|
+
target: 'pino-roll',
|
|
78
|
+
options: {
|
|
79
|
+
file: filePath,
|
|
80
|
+
frequency: 'daily',
|
|
81
|
+
dateFormat: 'yyyy-MM-dd',
|
|
82
|
+
mkdir: true,
|
|
83
|
+
symlink: true,
|
|
84
|
+
limit: { count: 30 },
|
|
85
|
+
size: '50m',
|
|
86
|
+
},
|
|
87
|
+
level,
|
|
88
|
+
}],
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
static build(level, destination, bindings) {
|
|
92
|
+
const context = new async_hooks_1.AsyncLocalStorage();
|
|
93
|
+
const base = destination
|
|
94
|
+
? (0, pino_1.default)({ level, serializers: error_record_1.LOG_SERIALIZERS, mixin: () => ({ ...context.getStore() }) }, destination)
|
|
97
95
|
: (0, pino_1.default)({ level: 'silent' });
|
|
98
|
-
|
|
99
|
-
// metric(). Null when there is no file transport (default stdout must stay
|
|
100
|
-
// clean for the MCP transport).
|
|
101
|
-
const metricsLogger = transport ? logger.child({}, { level: 'info' }) : null;
|
|
102
|
-
return new LoggerService(logger, metricsLogger);
|
|
96
|
+
return new LoggerService(bindings ? base.child(bindings) : base, context);
|
|
103
97
|
}
|
|
104
98
|
debug(msg, data) { this.logger.debug(data ?? {}, msg); }
|
|
105
99
|
info(msg, data) { this.logger.info(data ?? {}, msg); }
|
|
106
100
|
warn(msg, data) { this.logger.warn(data ?? {}, msg); }
|
|
107
101
|
error(msg, data) { this.logger.error(data ?? {}, msg); }
|
|
108
|
-
|
|
102
|
+
withContext(context, fn) {
|
|
103
|
+
return this.context.run(context, fn);
|
|
104
|
+
}
|
|
109
105
|
}
|
|
110
106
|
exports.LoggerService = LoggerService;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IDatabase } from '../interfaces/IDatabase';
|
|
2
|
+
import type { IIndexIdentityGuard } from '../interfaces/IIndexIdentityGuard';
|
|
3
|
+
import type { ILogger } from '../interfaces/ILogger';
|
|
4
|
+
import type { IMcpReadiness, ReadinessCheck } from '../interfaces/IMcpReadiness';
|
|
5
|
+
export declare const CHECK_DEADLINE_MS: number;
|
|
6
|
+
export declare class McpReadiness implements IMcpReadiness {
|
|
7
|
+
private db;
|
|
8
|
+
private identity;
|
|
9
|
+
private logger;
|
|
10
|
+
private isReady;
|
|
11
|
+
private lastCause;
|
|
12
|
+
private inFlight;
|
|
13
|
+
constructor(db: Pick<IDatabase, 'initDb' | 'probe'>, identity: IIndexIdentityGuard, logger: ILogger);
|
|
14
|
+
get ready(): boolean;
|
|
15
|
+
start(): Promise<ReadinessCheck>;
|
|
16
|
+
ensureReady(): Promise<ReadinessCheck>;
|
|
17
|
+
private recheck;
|
|
18
|
+
}
|