codesearch-mcp 0.3.0-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 +59 -6
- package/LICENSE +661 -21
- package/README.md +33 -17
- package/dist/app.js +13 -20
- 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/commands/EvalCommand.d.ts +7 -3
- package/dist/src/commands/EvalCommand.js +36 -158
- package/dist/src/commands/IndexCommand.d.ts +10 -4
- package/dist/src/commands/IndexCommand.js +52 -124
- package/dist/src/commands/McpCommand.d.ts +6 -3
- package/dist/src/commands/McpCommand.js +19 -14
- package/dist/src/commands/WebCommand.d.ts +9 -3
- package/dist/src/commands/WebCommand.js +17 -8
- 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-store.d.ts +0 -1
- package/dist/src/config-store.js +3 -4
- package/dist/src/config.d.ts +1 -1
- package/dist/src/config.js +1 -1
- package/dist/src/constants.d.ts +15 -0
- package/dist/src/constants.js +34 -6
- package/dist/src/container.d.ts +4 -2
- package/dist/src/container.js +7 -5
- package/dist/src/db/drizzle-types.d.ts +7 -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/declarations/DeclarationTree.d.ts +1 -1
- package/dist/src/eval-results.js +16 -2
- package/dist/src/eval-vector-index.d.ts +5 -0
- package/dist/src/eval-vector-index.js +60 -0
- package/dist/src/help.js +9 -1
- 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 +2 -1
- 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/IDatabase.d.ts +6 -2
- package/dist/src/interfaces/IDependencyGraph.d.ts +24 -0
- package/dist/src/interfaces/IDependencyGraph.js +2 -0
- 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/IMcpReadiness.d.ts +12 -0
- package/dist/src/interfaces/IMcpReadiness.js +2 -0
- package/dist/src/interfaces/IProjectCatalog.d.ts +13 -0
- package/dist/src/interfaces/IProjectCatalog.js +2 -0
- package/dist/src/interfaces/IProjectRoots.d.ts +3 -0
- package/dist/src/interfaces/IProjectRoots.js +2 -0
- package/dist/src/interfaces/IRetrievalEvaluator.d.ts +21 -2
- 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/project-scope.d.ts +1 -0
- package/dist/src/project-scope.js +5 -0
- package/dist/src/retrieval-eval.d.ts +2 -1
- package/dist/src/retrieval-eval.js +45 -2
- 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/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 +8 -44
- package/dist/src/services/AstParserService.js +19 -938
- package/dist/src/services/DatabaseService.d.ts +8 -10
- package/dist/src/services/DatabaseService.js +29 -86
- package/dist/src/services/IndexerService.d.ts +7 -10
- package/dist/src/services/IndexerService.js +36 -255
- package/dist/src/services/McpReadiness.d.ts +18 -0
- package/dist/src/services/McpReadiness.js +73 -0
- package/dist/src/services/McpServer.d.ts +32 -9
- package/dist/src/services/McpServer.js +78 -41
- package/dist/src/services/WebServerService.d.ts +4 -3
- package/dist/src/services/WebServerService.js +16 -8
- package/dist/src/setup.d.ts +16 -4
- package/dist/src/setup.js +115 -40
- package/dist/src/symbol-name.d.ts +1 -0
- package/dist/src/symbol-name.js +16 -12
- 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 +35 -28
- package/dist/src/tools/GetDependentsTool.d.ts +20 -8
- package/dist/src/tools/GetDependentsTool.js +47 -33
- 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 +69 -51
- package/dist/src/tools/format-helpers.d.ts +9 -3
- package/dist/src/tools/format-helpers.js +59 -14
- package/dist/src/tools/tool-args.d.ts +38 -0
- package/dist/src/tools/tool-args.js +95 -0
- 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 +4 -3
- package/dist/src/interfaces/ISearcher.d.ts +0 -46
- package/dist/src/services/SearcherService.d.ts +0 -235
- package/dist/src/services/SearcherService.js +0 -1118
- /package/dist/src/{interfaces/ISearcher.js → db/drizzle-types.js} +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GRAPHQL_NAME_RE = exports.GRAPHQL_OPERATION_KIND = exports.GRAPHQL_TYPE_DECORATORS = exports.GRAPHQL_MODULE = void 0;
|
|
4
|
+
exports.decoratorIdentifier = decoratorIdentifier;
|
|
5
|
+
exports.literalStringValue = literalStringValue;
|
|
6
|
+
exports.checkGraphqlGrammar = checkGraphqlGrammar;
|
|
7
|
+
exports.isAbstractGraphqlType = isAbstractGraphqlType;
|
|
8
|
+
exports.findNameProperty = findNameProperty;
|
|
9
|
+
exports.peekThroughWrapper = peekThroughWrapper;
|
|
10
|
+
exports.extractResolverIdentifier = extractResolverIdentifier;
|
|
11
|
+
const ts_morph_1 = require("ts-morph");
|
|
12
|
+
exports.GRAPHQL_MODULE = '@nestjs/graphql';
|
|
13
|
+
exports.GRAPHQL_TYPE_DECORATORS = new Set(['ObjectType', 'InputType', 'InterfaceType']);
|
|
14
|
+
exports.GRAPHQL_OPERATION_KIND = {
|
|
15
|
+
Query: 'graphql_query', Mutation: 'graphql_mutation', Subscription: 'graphql_subscription',
|
|
16
|
+
};
|
|
17
|
+
exports.GRAPHQL_NAME_RE = /^[_A-Za-z][_0-9A-Za-z]*$/;
|
|
18
|
+
function decoratorIdentifier(dec) {
|
|
19
|
+
const expr = dec.getExpression();
|
|
20
|
+
if (ts_morph_1.Node.isCallExpression(expr)) {
|
|
21
|
+
const callee = expr.getExpression();
|
|
22
|
+
return ts_morph_1.Node.isIdentifier(callee) ? callee : undefined;
|
|
23
|
+
}
|
|
24
|
+
return ts_morph_1.Node.isIdentifier(expr) ? expr : undefined;
|
|
25
|
+
}
|
|
26
|
+
function literalStringValue(node) {
|
|
27
|
+
if (ts_morph_1.Node.isStringLiteral(node) || ts_morph_1.Node.isNoSubstitutionTemplateLiteral(node))
|
|
28
|
+
return node.getLiteralValue();
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
function checkGraphqlGrammar(name) {
|
|
32
|
+
return exports.GRAPHQL_NAME_RE.test(name) ? { ok: true, name } : { ok: false, reason: 'invalid-name', value: name };
|
|
33
|
+
}
|
|
34
|
+
function isAbstractGraphqlType(args) {
|
|
35
|
+
return args.some((arg) => {
|
|
36
|
+
if (!ts_morph_1.Node.isObjectLiteralExpression(arg))
|
|
37
|
+
return false;
|
|
38
|
+
const prop = arg.getProperties().find((p) => {
|
|
39
|
+
if (!ts_morph_1.Node.isPropertyAssignment(p))
|
|
40
|
+
return false;
|
|
41
|
+
const nameNode = p.getNameNode();
|
|
42
|
+
if (ts_morph_1.Node.isIdentifier(nameNode))
|
|
43
|
+
return nameNode.getText() === 'isAbstract';
|
|
44
|
+
if (ts_morph_1.Node.isStringLiteral(nameNode))
|
|
45
|
+
return nameNode.getLiteralValue() === 'isAbstract';
|
|
46
|
+
return false;
|
|
47
|
+
});
|
|
48
|
+
const init = prop?.getInitializer();
|
|
49
|
+
return init !== undefined && ts_morph_1.Node.isTrueLiteral(init);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function findNameProperty(obj) {
|
|
53
|
+
return obj.getProperties().find((p) => {
|
|
54
|
+
if (!ts_morph_1.Node.isPropertyAssignment(p) && !ts_morph_1.Node.isShorthandPropertyAssignment(p))
|
|
55
|
+
return false;
|
|
56
|
+
const nameNode = p.getNameNode();
|
|
57
|
+
if (ts_morph_1.Node.isIdentifier(nameNode))
|
|
58
|
+
return nameNode.getText() === 'name';
|
|
59
|
+
if (ts_morph_1.Node.isStringLiteral(nameNode))
|
|
60
|
+
return nameNode.getLiteralValue() === 'name';
|
|
61
|
+
return false;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function peekThroughWrapper(node) {
|
|
65
|
+
let current = node;
|
|
66
|
+
let wrapped = false;
|
|
67
|
+
while (true) {
|
|
68
|
+
if (ts_morph_1.Node.isParenthesizedExpression(current) || ts_morph_1.Node.isAsExpression(current) || ts_morph_1.Node.isSatisfiesExpression(current) || ts_morph_1.Node.isNonNullExpression(current)) {
|
|
69
|
+
current = current.getExpression();
|
|
70
|
+
wrapped = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
return { inner: current, wrapped };
|
|
76
|
+
}
|
|
77
|
+
function extractResolverIdentifier(argNode) {
|
|
78
|
+
let target = argNode;
|
|
79
|
+
if (ts_morph_1.Node.isArrowFunction(target)) {
|
|
80
|
+
const body = target.getBody();
|
|
81
|
+
if (ts_morph_1.Node.isBlock(body))
|
|
82
|
+
return null;
|
|
83
|
+
target = body;
|
|
84
|
+
}
|
|
85
|
+
if (ts_morph_1.Node.isIdentifier(target))
|
|
86
|
+
return target;
|
|
87
|
+
if (ts_morph_1.Node.isArrayLiteralExpression(target)) {
|
|
88
|
+
const elements = target.getElements();
|
|
89
|
+
if (elements.length === 1 && ts_morph_1.Node.isIdentifier(elements[0]))
|
|
90
|
+
return elements[0];
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Node, type SourceFile } from 'ts-morph';
|
|
2
|
+
export type ResolveDeclaration = (identifier: Node) => Node | undefined;
|
|
3
|
+
export declare function getPos(sourceFile: SourceFile, node: Node): {
|
|
4
|
+
line: number;
|
|
5
|
+
col: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function lineTextAt(sourceLines: string[], sourceFile: SourceFile, node: Node): string;
|
|
8
|
+
export declare function memberName(nameNode: Node | undefined): string | null;
|
|
9
|
+
export declare function unwrapExpr(node: Node): Node;
|
|
10
|
+
export declare function unwrapParent(node: Node): Node | undefined;
|
|
11
|
+
export declare function defaultResolveDeclaration(identifier: Node): Node | undefined;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPos = getPos;
|
|
4
|
+
exports.lineTextAt = lineTextAt;
|
|
5
|
+
exports.memberName = memberName;
|
|
6
|
+
exports.unwrapExpr = unwrapExpr;
|
|
7
|
+
exports.unwrapParent = unwrapParent;
|
|
8
|
+
exports.defaultResolveDeclaration = defaultResolveDeclaration;
|
|
9
|
+
const ts_morph_1 = require("ts-morph");
|
|
10
|
+
function getPos(sourceFile, node) {
|
|
11
|
+
const { line, character } = sourceFile.compilerNode
|
|
12
|
+
.getLineAndCharacterOfPosition(node.getStart());
|
|
13
|
+
return { line: line + 1, col: character + 1 };
|
|
14
|
+
}
|
|
15
|
+
function lineTextAt(sourceLines, sourceFile, node) {
|
|
16
|
+
const { line } = getPos(sourceFile, node);
|
|
17
|
+
return (sourceLines[line - 1] ?? node.getText().split('\n')[0]).trim();
|
|
18
|
+
}
|
|
19
|
+
function memberName(nameNode) {
|
|
20
|
+
if (!nameNode)
|
|
21
|
+
return null;
|
|
22
|
+
if (ts_morph_1.Node.isPrivateIdentifier(nameNode))
|
|
23
|
+
return nameNode.getText();
|
|
24
|
+
if (ts_morph_1.Node.isIdentifier(nameNode))
|
|
25
|
+
return nameNode.getText();
|
|
26
|
+
if (ts_morph_1.Node.isStringLiteral(nameNode))
|
|
27
|
+
return nameNode.getLiteralValue();
|
|
28
|
+
if (ts_morph_1.Node.isNumericLiteral(nameNode))
|
|
29
|
+
return nameNode.getText();
|
|
30
|
+
if (ts_morph_1.Node.isComputedPropertyName(nameNode))
|
|
31
|
+
return nameNode.getText().replace(/\s+/g, '');
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
function unwrapExpr(node) {
|
|
35
|
+
let current = node;
|
|
36
|
+
while (ts_morph_1.Node.isParenthesizedExpression(current) || ts_morph_1.Node.isAsExpression(current) || ts_morph_1.Node.isSatisfiesExpression(current)) {
|
|
37
|
+
current = current.getExpression();
|
|
38
|
+
}
|
|
39
|
+
return current;
|
|
40
|
+
}
|
|
41
|
+
function unwrapParent(node) {
|
|
42
|
+
let current = node.getParent();
|
|
43
|
+
while (current && (ts_morph_1.Node.isParenthesizedExpression(current) || ts_morph_1.Node.isAsExpression(current) || ts_morph_1.Node.isSatisfiesExpression(current))) {
|
|
44
|
+
current = current.getParent();
|
|
45
|
+
}
|
|
46
|
+
return current;
|
|
47
|
+
}
|
|
48
|
+
function defaultResolveDeclaration(identifier) {
|
|
49
|
+
const sym = identifier.getSymbol();
|
|
50
|
+
if (!sym)
|
|
51
|
+
return undefined;
|
|
52
|
+
const firstDecl = sym.getDeclarations()?.[0];
|
|
53
|
+
const resolved = firstDecl && ts_morph_1.Node.isImportSpecifier(firstDecl) ? (sym.getAliasedSymbol() ?? sym) : sym;
|
|
54
|
+
return resolved.getDeclarations()?.[0];
|
|
55
|
+
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Config } from '../config';
|
|
2
|
+
import type { IDatabase, IChunkSearch, IProjectCatalog } from '../interfaces';
|
|
2
3
|
import type { ICommand } from './ICommand';
|
|
3
4
|
import type { ICorpusInspector } from '../interfaces/ICorpusInspector';
|
|
4
5
|
export declare class EvalCommand implements ICommand {
|
|
5
|
-
private
|
|
6
|
+
private db;
|
|
7
|
+
private chunks;
|
|
8
|
+
private catalog;
|
|
9
|
+
private config;
|
|
6
10
|
private argv1;
|
|
7
11
|
private corpusInspector;
|
|
8
12
|
private resultsDir;
|
|
9
|
-
constructor(
|
|
13
|
+
constructor(db: IDatabase, chunks: IChunkSearch, catalog: IProjectCatalog, config: Config, argv1: string, corpusInspector?: ICorpusInspector, resultsDir?: string);
|
|
10
14
|
execute(): Promise<void>;
|
|
11
15
|
}
|
|
@@ -36,87 +36,44 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.EvalCommand = void 0;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
|
-
const crypto = __importStar(require("crypto"));
|
|
40
|
-
const child_process_1 = require("child_process");
|
|
41
39
|
const retrieval_eval_1 = require("../retrieval-eval");
|
|
42
40
|
const eval_results_1 = require("../eval-results");
|
|
43
41
|
const eval_corpus_1 = require("../eval-corpus");
|
|
44
|
-
const
|
|
42
|
+
const eval_vector_index_1 = require("../eval-vector-index");
|
|
43
|
+
const constants_1 = require("../constants");
|
|
44
|
+
const eval_args_1 = require("./eval/eval-args");
|
|
45
|
+
const suite_loader_1 = require("./eval/suite-loader");
|
|
46
|
+
const eval_corpora_1 = require("./eval/eval-corpora");
|
|
47
|
+
const index_inspector_1 = require("./eval/index-inspector");
|
|
48
|
+
const staged_search_1 = require("./eval/staged-search");
|
|
49
|
+
const eval_metadata_1 = require("./eval/eval-metadata");
|
|
50
|
+
const baseline_comparison_1 = require("./eval/baseline-comparison");
|
|
45
51
|
const RESULTS_DIR_NAME = path.join('benchmarks', 'results');
|
|
46
|
-
const KEPT_CORPUS_DIR = path.join('benchmarks', 'corpus');
|
|
47
52
|
const _projectRoot = fs.existsSync(path.join(__dirname, '..', '..', 'package.json'))
|
|
48
53
|
? path.join(__dirname, '..', '..')
|
|
49
54
|
: path.join(__dirname, '..', '..', '..');
|
|
50
|
-
function gitCommit() {
|
|
51
|
-
try {
|
|
52
|
-
return (0, child_process_1.execFileSync)('git', ['rev-parse', 'HEAD'], { cwd: _projectRoot, encoding: 'utf-8' }).trim();
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
return 'unknown';
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function hashContent(text) {
|
|
59
|
-
return crypto.createHash('sha256').update(text).digest('hex').slice(0, 16);
|
|
60
|
-
}
|
|
61
|
-
function parseSuiteFlag(args) {
|
|
62
|
-
const i = args.indexOf('--suite');
|
|
63
|
-
if (i === -1)
|
|
64
|
-
return DEFAULT_SUITE_DIR;
|
|
65
|
-
const next = args[i + 1];
|
|
66
|
-
if (next === undefined || next.startsWith('-'))
|
|
67
|
-
throw new Error('--suite requires a path');
|
|
68
|
-
return next;
|
|
69
|
-
}
|
|
70
|
-
function parseBaselineFlag(args) {
|
|
71
|
-
const i = args.indexOf('--baseline');
|
|
72
|
-
if (i === -1)
|
|
73
|
-
return null;
|
|
74
|
-
const next = args[i + 1];
|
|
75
|
-
if (next === undefined || next.startsWith('-'))
|
|
76
|
-
throw new Error('--baseline requires a path');
|
|
77
|
-
return next;
|
|
78
|
-
}
|
|
79
|
-
function parseProjectFlag(args) {
|
|
80
|
-
const i = args.indexOf('--project');
|
|
81
|
-
if (i === -1)
|
|
82
|
-
return null;
|
|
83
|
-
const next = args[i + 1];
|
|
84
|
-
if (next === undefined || next.startsWith('-'))
|
|
85
|
-
throw new Error('--project requires a name');
|
|
86
|
-
return next;
|
|
87
|
-
}
|
|
88
|
-
function loadSuite(suitePath) {
|
|
89
|
-
const resolved = path.resolve(_projectRoot, suitePath);
|
|
90
|
-
const stat = fs.statSync(resolved);
|
|
91
|
-
if (stat.isDirectory()) {
|
|
92
|
-
const files = fs.readdirSync(resolved).filter(f => f.endsWith('.json')).sort();
|
|
93
|
-
const parts = files.map(f => fs.readFileSync(path.join(resolved, f), 'utf-8'));
|
|
94
|
-
const suites = parts.map(text => (0, retrieval_eval_1.parseSuite)(JSON.parse(text)));
|
|
95
|
-
return { suite: (0, retrieval_eval_1.mergeSuites)(suites), corpora: (0, retrieval_eval_1.corporaOf)(suites), rawContent: parts.join('\n'), label: 'all' };
|
|
96
|
-
}
|
|
97
|
-
const text = fs.readFileSync(resolved, 'utf-8');
|
|
98
|
-
const suite = (0, retrieval_eval_1.parseSuite)(JSON.parse(text));
|
|
99
|
-
return { suite, corpora: (0, retrieval_eval_1.corporaOf)([suite]), rawContent: text, label: path.basename(resolved, '.json') };
|
|
100
|
-
}
|
|
101
55
|
class EvalCommand {
|
|
102
|
-
|
|
56
|
+
db;
|
|
57
|
+
chunks;
|
|
58
|
+
catalog;
|
|
59
|
+
config;
|
|
103
60
|
argv1;
|
|
104
61
|
corpusInspector;
|
|
105
62
|
resultsDir;
|
|
106
|
-
constructor(
|
|
107
|
-
this.
|
|
63
|
+
constructor(db, chunks, catalog, config, argv1, corpusInspector = new eval_corpus_1.GitCorpusInspector(), resultsDir = path.join(_projectRoot, RESULTS_DIR_NAME)) {
|
|
64
|
+
this.db = db;
|
|
65
|
+
this.chunks = chunks;
|
|
66
|
+
this.catalog = catalog;
|
|
67
|
+
this.config = config;
|
|
108
68
|
this.argv1 = argv1;
|
|
109
69
|
this.corpusInspector = corpusInspector;
|
|
110
70
|
this.resultsDir = resultsDir;
|
|
111
71
|
}
|
|
112
72
|
async execute() {
|
|
113
|
-
const { db, searcher, config } = this.container;
|
|
114
73
|
const args = process.argv.slice(this.argv1 === 'rag-index' ? 3 : 4);
|
|
115
74
|
let suitePath, baselinePath, projectFilter;
|
|
116
75
|
try {
|
|
117
|
-
suitePath =
|
|
118
|
-
baselinePath = parseBaselineFlag(args);
|
|
119
|
-
projectFilter = parseProjectFlag(args);
|
|
76
|
+
({ suitePath, baselinePath, projectFilter } = (0, eval_args_1.parseEvalArgs)(args));
|
|
120
77
|
}
|
|
121
78
|
catch (err) {
|
|
122
79
|
console.error(`\n${err.message}`);
|
|
@@ -125,7 +82,7 @@ class EvalCommand {
|
|
|
125
82
|
}
|
|
126
83
|
let suite, corpora, rawContent, label;
|
|
127
84
|
try {
|
|
128
|
-
({ suite, corpora, rawContent, label } = loadSuite(suitePath));
|
|
85
|
+
({ suite, corpora, rawContent, label } = (0, suite_loader_1.loadSuite)(_projectRoot, suitePath));
|
|
129
86
|
}
|
|
130
87
|
catch (err) {
|
|
131
88
|
if (err instanceof retrieval_eval_1.EvalSuiteError) {
|
|
@@ -146,59 +103,16 @@ class EvalCommand {
|
|
|
146
103
|
return;
|
|
147
104
|
}
|
|
148
105
|
const runCorpora = corpora.filter(c => suite.cases.some(k => k.corpus === c.root));
|
|
149
|
-
|
|
150
|
-
for (const corpus of runCorpora) {
|
|
151
|
-
let failures;
|
|
152
|
-
try {
|
|
153
|
-
failures = await (0, eval_corpus_1.checkCorpus)(corpus, path.join(config.workspaceRoot, corpus.root), path.join(_projectRoot, KEPT_CORPUS_DIR, corpus.root), this.corpusInspector);
|
|
154
|
-
}
|
|
155
|
-
catch (err) {
|
|
156
|
-
failures = [`cannot inspect the checkout: ${err.message}`];
|
|
157
|
-
}
|
|
158
|
-
if (failures.length === 0)
|
|
159
|
-
continue;
|
|
160
|
-
refused = true;
|
|
161
|
-
console.error(`\nCorpus ${corpus.root} does not match ${corpus.commit}:`);
|
|
162
|
-
for (const f of failures)
|
|
163
|
-
console.error(` - ${f}`);
|
|
164
|
-
}
|
|
165
|
-
if (refused) {
|
|
166
|
-
console.error('\nNo search was run and no result file was written.');
|
|
167
|
-
process.exitCode = 1;
|
|
106
|
+
if (await (0, eval_corpora_1.refusesMovedCorpus)(runCorpora, this.config, _projectRoot, this.corpusInspector))
|
|
168
107
|
return;
|
|
169
|
-
|
|
170
|
-
await
|
|
171
|
-
const
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const files = await knownFilesCache.get(project);
|
|
178
|
-
return files.includes(file);
|
|
179
|
-
},
|
|
180
|
-
async ownerPathsOfFile(project, file) {
|
|
181
|
-
const rows = await db.query(`SELECT DISTINCT "ownerPath" FROM code_chunk WHERE "serviceName" = $1 AND "filePath" = $2 AND "ownerPath" IS NOT NULL`, [project, file]);
|
|
182
|
-
return rows.map(r => r.ownerPath);
|
|
183
|
-
},
|
|
184
|
-
async projectDir(project) {
|
|
185
|
-
return projectDirs.get(project) ?? null;
|
|
186
|
-
},
|
|
187
|
-
};
|
|
188
|
-
const toHits = (rows) => rows.map(r => ({ filePath: r.filePath, ownerPath: r.ownerPath ?? null }));
|
|
189
|
-
const search = async (query, limit, project, threshold) => {
|
|
190
|
-
const prepared = await searcher.prepareQuery(query);
|
|
191
|
-
const r = await searcher.searchChunksWithStages(prepared.query, limit, project, threshold, undefined, limit);
|
|
192
|
-
return {
|
|
193
|
-
pool: toHits(r.pool),
|
|
194
|
-
stages: r.stages.reranked
|
|
195
|
-
? { vector: toHits(r.stages.vector), reranked: toHits(r.stages.reranked) }
|
|
196
|
-
: { vector: toHits(r.stages.vector) },
|
|
197
|
-
rerankFailed: r.rerankFailed,
|
|
198
|
-
fetchLimit: r.fetchLimit,
|
|
199
|
-
indexParams: r.indexParams,
|
|
200
|
-
};
|
|
201
|
-
};
|
|
108
|
+
await this.db.initDbWithSchema();
|
|
109
|
+
const projectDirs = new Map((await this.catalog.listProjects()).map(p => [p.serviceName, p.relPath ?? null]));
|
|
110
|
+
const inspect = (0, index_inspector_1.createIndexInspector)(this.db, projectDirs);
|
|
111
|
+
const search = (0, staged_search_1.createStagedSearch)(this.chunks);
|
|
112
|
+
const thresholdWarning = (0, constants_1.thresholdMismatchWarning)(this.config.search.similarityThreshold, this.config.embedding.model);
|
|
113
|
+
if (thresholdWarning)
|
|
114
|
+
console.warn(`\n⚠ ${thresholdWarning}\n`);
|
|
115
|
+
const vectorIndex = await (0, eval_vector_index_1.describeVectorIndex)(this.db);
|
|
202
116
|
let outcome;
|
|
203
117
|
try {
|
|
204
118
|
outcome = await new retrieval_eval_1.RetrievalEvaluator().evaluate(suite, search, inspect, p => console.error((0, eval_results_1.renderProgress)(p)));
|
|
@@ -211,52 +125,16 @@ class EvalCommand {
|
|
|
211
125
|
return;
|
|
212
126
|
}
|
|
213
127
|
const { run, observed } = outcome;
|
|
214
|
-
const corpusRecords =
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
corpusRecords.push(record);
|
|
221
|
-
}
|
|
222
|
-
const indexMeta = await db.readIndexMeta();
|
|
223
|
-
const metadata = {
|
|
224
|
-
suitePath,
|
|
225
|
-
suiteHash: hashContent(rawContent),
|
|
226
|
-
embeddingProvider: config.embedding.provider,
|
|
227
|
-
embeddingModel: config.embedding.model,
|
|
228
|
-
rerankerModel: config.reranker.enabled ? config.reranker.model : null,
|
|
229
|
-
indexMeta: indexMeta ? { provider: indexMeta.provider, model: indexMeta.model, dimensions: indexMeta.dimensions } : null,
|
|
230
|
-
gitCommit: gitCommit(),
|
|
231
|
-
timestamp: new Date().toISOString(),
|
|
232
|
-
conditions: {
|
|
233
|
-
similarityThreshold: config.search.similarityThreshold,
|
|
234
|
-
overfetch: config.reranker.overfetch,
|
|
235
|
-
candidateFloor: config.reranker.candidateFloor,
|
|
236
|
-
fetchLimit: observed.fetchLimit,
|
|
237
|
-
efSearch: observed.efSearch,
|
|
238
|
-
iterativeScan: observed.iterativeScan,
|
|
239
|
-
},
|
|
240
|
-
corpora: corpusRecords,
|
|
241
|
-
liveCases: suite.cases.filter(c => !c.corpus).length,
|
|
242
|
-
};
|
|
128
|
+
const corpusRecords = await (0, eval_corpora_1.recordCorpora)(this.db, runCorpora, projectDirs);
|
|
129
|
+
const indexMeta = await this.db.readIndexMeta();
|
|
130
|
+
const metadata = (0, eval_metadata_1.buildResultMetadata)({
|
|
131
|
+
suitePath, rawContent, config: this.config, indexMeta, observed, vectorIndex, corpusRecords,
|
|
132
|
+
liveCases: suite.cases.filter(c => !c.corpus).length, projectRoot: _projectRoot,
|
|
133
|
+
});
|
|
243
134
|
const resultFile = { metadata, run };
|
|
244
135
|
for (const line of (0, eval_results_1.renderSummary)(resultFile))
|
|
245
136
|
console.log(line);
|
|
246
|
-
|
|
247
|
-
if (baselinePath) {
|
|
248
|
-
try {
|
|
249
|
-
const baseline = (0, eval_results_1.readResultFile)(path.resolve(_projectRoot, baselinePath));
|
|
250
|
-
const cmp = (0, retrieval_eval_1.compare)(baseline, resultFile);
|
|
251
|
-
comparison = { baselinePath, result: cmp };
|
|
252
|
-
for (const line of (0, eval_results_1.renderComparison)(baselinePath, cmp))
|
|
253
|
-
console.log(line);
|
|
254
|
-
}
|
|
255
|
-
catch (err) {
|
|
256
|
-
console.error(`\nFailed to read baseline '${baselinePath}': ${err.message}`);
|
|
257
|
-
process.exitCode = 1;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
137
|
+
const comparison = baselinePath ? (0, baseline_comparison_1.compareWithBaseline)(_projectRoot, baselinePath, resultFile) : undefined;
|
|
260
138
|
const { jsonPath, mdPath } = (0, eval_results_1.writeResultFiles)(this.resultsDir, label, resultFile, new Date(), comparison);
|
|
261
139
|
console.log(`\nResults written to:\n ${path.relative(_projectRoot, jsonPath)}\n ${path.relative(_projectRoot, mdPath)}`);
|
|
262
140
|
}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IndexerService } from '../services/IndexerService';
|
|
2
|
+
import type { Config } from '../config';
|
|
3
|
+
import type { IDatabase, IDependencyGraph, IEmbedder, IProjectDiscovery } from '../interfaces';
|
|
2
4
|
import type { ICommand } from './ICommand';
|
|
3
5
|
export declare class IndexCommand implements ICommand {
|
|
4
|
-
private
|
|
6
|
+
private db;
|
|
7
|
+
private embedder;
|
|
8
|
+
private indexer;
|
|
9
|
+
private dependencies;
|
|
10
|
+
private discovery;
|
|
11
|
+
private config;
|
|
5
12
|
private argv1;
|
|
6
|
-
constructor(
|
|
13
|
+
constructor(db: IDatabase, embedder: IEmbedder, indexer: IndexerService, dependencies: IDependencyGraph, discovery: IProjectDiscovery, config: Config, argv1: string);
|
|
7
14
|
execute(): Promise<void>;
|
|
8
|
-
private printSummary;
|
|
9
15
|
}
|
|
@@ -5,164 +5,92 @@ const interrupt_1 = require("../interrupt");
|
|
|
5
5
|
const project_selector_1 = require("../project-selector");
|
|
6
6
|
const graph_1 = require("../graph");
|
|
7
7
|
const MonorepoAwareDiscoveryService_1 = require("../services/MonorepoAwareDiscoveryService");
|
|
8
|
-
const project_scope_1 = require("../project-scope");
|
|
9
8
|
const file_utils_1 = require("../file-utils");
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
9
|
+
const index_args_1 = require("../index-args");
|
|
10
|
+
const scan_targets_1 = require("./index/scan-targets");
|
|
11
|
+
const legacy_ollama_guard_1 = require("./index/legacy-ollama-guard");
|
|
12
|
+
const embedding_setup_1 = require("./index/embedding-setup");
|
|
13
|
+
const prune_step_1 = require("./index/prune-step");
|
|
14
|
+
const backend_probe_1 = require("./index/backend-probe");
|
|
15
|
+
const index_summary_1 = require("./index/index-summary");
|
|
18
16
|
class IndexCommand {
|
|
19
|
-
|
|
17
|
+
db;
|
|
18
|
+
embedder;
|
|
19
|
+
indexer;
|
|
20
|
+
dependencies;
|
|
21
|
+
discovery;
|
|
22
|
+
config;
|
|
20
23
|
argv1;
|
|
21
|
-
constructor(
|
|
22
|
-
this.
|
|
24
|
+
constructor(db, embedder, indexer, dependencies, discovery, config, argv1) {
|
|
25
|
+
this.db = db;
|
|
26
|
+
this.embedder = embedder;
|
|
27
|
+
this.indexer = indexer;
|
|
28
|
+
this.dependencies = dependencies;
|
|
29
|
+
this.discovery = discovery;
|
|
30
|
+
this.config = config;
|
|
23
31
|
this.argv1 = argv1;
|
|
24
32
|
}
|
|
25
33
|
async execute() {
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
discovered = discovery.discover(config.workspaceRoot);
|
|
34
|
-
}
|
|
35
|
-
catch (err) {
|
|
36
|
-
console.error(`\n${err.message}`);
|
|
37
|
-
process.exitCode = 1;
|
|
34
|
+
const args = (0, index_args_1.parseIndexArgs)(process.argv.slice(this.argv1 === 'rag-index' ? 2 : 3));
|
|
35
|
+
const { force, forceSelect } = args;
|
|
36
|
+
const targets = await (0, scan_targets_1.resolveScanTargets)(this.discovery, this.config, args);
|
|
37
|
+
if (!targets)
|
|
38
|
+
return;
|
|
39
|
+
await this.db.initDbWithSchema();
|
|
40
|
+
if (!force && await (0, legacy_ollama_guard_1.refusesLegacyOllamaIndex)(this.db, this.config))
|
|
38
41
|
return;
|
|
39
|
-
}
|
|
40
|
-
let scanTargets;
|
|
41
|
-
if (projectFlag.present) {
|
|
42
|
-
let name = projectFlag.name;
|
|
43
|
-
if (name === undefined) {
|
|
44
|
-
if (discovered.length === 0) {
|
|
45
|
-
console.error('\nNo projects available to select.');
|
|
46
|
-
process.exitCode = 1;
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
name = await (0, project_selector_1.selectSingleProject)(discovered);
|
|
50
|
-
if (name === undefined) {
|
|
51
|
-
process.exitCode = 1;
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
const { targets, notFound } = (0, project_scope_1.resolveProjectNames)([name], discovered);
|
|
56
|
-
if (notFound.length > 0) {
|
|
57
|
-
const available = (0, project_scope_1.listAvailableNames)(discovered).join(', ');
|
|
58
|
-
console.error(`\nProject '${notFound[0]}' not found. Available projects: ${available}`);
|
|
59
|
-
process.exitCode = 1;
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
scanTargets = targets;
|
|
63
|
-
}
|
|
64
|
-
await db.initDbWithSchema();
|
|
65
|
-
if (!force) {
|
|
66
|
-
let identity;
|
|
67
|
-
try {
|
|
68
|
-
identity = await (0, legacy_ollama_index_1.resolveIndexedIdentity)(db);
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
console.error(`\n${err.message}`);
|
|
72
|
-
process.exitCode = 1;
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
if (identity?.provider === 'ollama') {
|
|
76
|
-
console.error(`\nThe existing index was built with ${identity.provider}/${identity.model}, but "ollama" is no ` +
|
|
77
|
-
`longer a supported embedding provider (configured: ${config.embedding.provider}/${config.embedding.model}). ` +
|
|
78
|
-
`Run \`rag-index --reindex\` to confirm rebuilding the index under the configured provider.`);
|
|
79
|
-
process.exitCode = 1;
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
42
|
let projects;
|
|
84
|
-
if (scanTargets) {
|
|
85
|
-
projects = scanTargets;
|
|
43
|
+
if (targets.scanTargets) {
|
|
44
|
+
projects = targets.scanTargets;
|
|
86
45
|
}
|
|
87
46
|
else {
|
|
88
|
-
const selected = await new project_selector_1.ProjectSelector(config.workspaceRoot).select(discovered, forceSelect);
|
|
47
|
+
const selected = await new project_selector_1.ProjectSelector(this.config.workspaceRoot).select(targets.discovered, forceSelect);
|
|
89
48
|
if (selected.length === 0)
|
|
90
49
|
return;
|
|
91
50
|
projects = (0, MonorepoAwareDiscoveryService_1.toLeafProjects)(selected);
|
|
92
51
|
}
|
|
93
|
-
const fullLeafProjects = (0, MonorepoAwareDiscoveryService_1.toLeafProjects)(discovered);
|
|
94
|
-
|
|
95
|
-
await embedder.ensureModelAvailable?.();
|
|
96
|
-
const meta = await indexer.prepareEmbeddingSchema();
|
|
97
|
-
console.log(`Embedding: ${meta.provider} / ${meta.model} (${meta.dimensions} dims)`);
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
console.error(`\nEmbedding setup failed: ${err.message}`);
|
|
101
|
-
process.exitCode = 1;
|
|
52
|
+
const fullLeafProjects = (0, MonorepoAwareDiscoveryService_1.toLeafProjects)(targets.discovered);
|
|
53
|
+
if (!await (0, embedding_setup_1.prepareEmbedding)(this.embedder, this.indexer))
|
|
102
54
|
return;
|
|
103
|
-
}
|
|
104
55
|
const controller = new AbortController();
|
|
105
56
|
const teardown = (0, interrupt_1.setupInterrupt)(controller);
|
|
106
57
|
try {
|
|
107
|
-
if (!scanTargets)
|
|
108
|
-
|
|
109
|
-
try {
|
|
110
|
-
pruneResult = await indexer.pruneProjects(projects.map(p => p.name));
|
|
111
|
-
}
|
|
112
|
-
catch (err) {
|
|
113
|
-
console.error(`\nPruning failed: ${err.message}`);
|
|
114
|
-
process.exitCode = 1;
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
const { removed, failed } = pruneResult;
|
|
118
|
-
for (const name of removed) {
|
|
119
|
-
console.log(`Removed project ${name} (not selected)`);
|
|
120
|
-
}
|
|
121
|
-
if (failed.length > 0) {
|
|
122
|
-
process.exitCode = 1;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
58
|
+
if (!targets.scanTargets && !await (0, prune_step_1.pruneUnselected)(this.indexer, projects))
|
|
59
|
+
return;
|
|
125
60
|
const filesPerProject = projects.map(p => (0, file_utils_1.collectFiles)(p.path, (0, file_utils_1.loadIgnore)(p.path), p.path));
|
|
126
61
|
const totalFiles = filesPerProject.reduce((sum, f) => sum + f.length, 0);
|
|
127
62
|
console.log(`\n${projects.length} projects — ${totalFiles} files total`);
|
|
128
63
|
if (force)
|
|
129
64
|
console.log('Reindex mode: all files will be re-indexed.');
|
|
130
|
-
const allStats = await indexer.scanProjects(projects, force, controller.signal, filesPerProject);
|
|
131
|
-
|
|
65
|
+
const allStats = await this.indexer.scanProjects(projects, force, controller.signal, filesPerProject);
|
|
66
|
+
const interrupted = controller.signal.aborted;
|
|
67
|
+
if (interrupted)
|
|
132
68
|
console.log('\nIndexing interrupted.');
|
|
133
|
-
|
|
134
|
-
|
|
69
|
+
(0, index_summary_1.printIndexSummary)(allStats);
|
|
70
|
+
const sum = (field) => allStats.reduce((total, s) => total + s[field], 0);
|
|
71
|
+
const failed = sum('failed');
|
|
72
|
+
const total = failed + sum('indexed') + sum('skipped');
|
|
73
|
+
if (failed > 0) {
|
|
74
|
+
console.error(`Indexing finished with ${failed} of ${total} file(s) failed.`);
|
|
75
|
+
}
|
|
76
|
+
if (!interrupted) {
|
|
135
77
|
try {
|
|
136
|
-
const projectEdges = await
|
|
137
|
-
(0, graph_1.generateProjectGraph)(fullLeafProjects, projectEdges, config.workspaceRoot);
|
|
78
|
+
const projectEdges = await this.dependencies.getProjectEdges();
|
|
79
|
+
(0, graph_1.generateProjectGraph)(fullLeafProjects, projectEdges, this.config.workspaceRoot);
|
|
138
80
|
}
|
|
139
81
|
catch (err) {
|
|
140
82
|
console.error(` ⚠ Could not build project graph: ${err.message}`);
|
|
141
83
|
}
|
|
142
84
|
}
|
|
85
|
+
if (failed > 0) {
|
|
86
|
+
const nothingUsable = sum('skipped') === 0 && sum('chunks') === 0;
|
|
87
|
+
const alreadyFailed = interrupted || !!process.exitCode || nothingUsable;
|
|
88
|
+
process.exitCode = alreadyFailed || !(await (0, backend_probe_1.isBackendAvailable)(this.db, this.embedder)) ? 1 : 2;
|
|
89
|
+
}
|
|
143
90
|
}
|
|
144
91
|
finally {
|
|
145
92
|
teardown();
|
|
146
93
|
}
|
|
147
94
|
}
|
|
148
|
-
printSummary(allStats) {
|
|
149
|
-
const cols = { name: 30, num: 8 };
|
|
150
|
-
const line = '─'.repeat(cols.name + cols.num * 5 + 5);
|
|
151
|
-
console.log('\n=== Indexing Summary ===');
|
|
152
|
-
console.log('Service'.padEnd(cols.name), 'Indexed'.padStart(cols.num), 'Skipped'.padStart(cols.num), 'Failed'.padStart(cols.num), 'Chunks'.padStart(cols.num), 'Time(s)'.padStart(cols.num));
|
|
153
|
-
console.log(line);
|
|
154
|
-
for (const s of allStats) {
|
|
155
|
-
console.log(s.serviceName.padEnd(cols.name), String(s.indexed).padStart(cols.num), String(s.skipped).padStart(cols.num), String(s.failed).padStart(cols.num), String(s.chunks).padStart(cols.num), String(s.elapsedSec).padStart(cols.num));
|
|
156
|
-
}
|
|
157
|
-
console.log(line);
|
|
158
|
-
const total = allStats.reduce((acc, s) => ({
|
|
159
|
-
indexed: acc.indexed + s.indexed,
|
|
160
|
-
skipped: acc.skipped + s.skipped,
|
|
161
|
-
failed: acc.failed + s.failed,
|
|
162
|
-
chunks: acc.chunks + s.chunks,
|
|
163
|
-
elapsedSec: acc.elapsedSec + s.elapsedSec,
|
|
164
|
-
}), { indexed: 0, skipped: 0, failed: 0, chunks: 0, elapsedSec: 0 });
|
|
165
|
-
console.log('TOTAL'.padEnd(cols.name), String(total.indexed).padStart(cols.num), String(total.skipped).padStart(cols.num), String(total.failed).padStart(cols.num), String(total.chunks).padStart(cols.num), String(total.elapsedSec.toFixed(1)).padStart(cols.num));
|
|
166
|
-
}
|
|
167
95
|
}
|
|
168
96
|
exports.IndexCommand = IndexCommand;
|