opencode-codebase-index 0.19.1 → 0.20.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +7 -5
- package/dist/cli.cjs +765 -124
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +765 -124
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +400 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +400 -55
- package/dist/index.js.map +1 -1
- package/dist/pi-extension.cjs +361 -48
- package/dist/pi-extension.cjs.map +1 -1
- package/dist/pi-extension.js +361 -48
- package/dist/pi-extension.js.map +1 -1
- package/native/codebase-index-native.darwin-arm64.node +0 -0
- package/native/codebase-index-native.darwin-x64.node +0 -0
- package/native/codebase-index-native.linux-arm64-gnu.node +0 -0
- package/native/codebase-index-native.linux-x64-gnu.node +0 -0
- package/native/codebase-index-native.win32-x64-msvc.node +0 -0
- package/package.json +4 -3
package/dist/pi-extension.cjs
CHANGED
|
@@ -786,6 +786,7 @@ function getDefaultIndexingConfig() {
|
|
|
786
786
|
autoIndexMaxRetries: 5,
|
|
787
787
|
autoIndexRetryDelayMs: 100,
|
|
788
788
|
watchFiles: true,
|
|
789
|
+
pauseBackgroundIndexingOnBattery: false,
|
|
789
790
|
maxFileSize: 1048576,
|
|
790
791
|
maxChunksPerFile: 100,
|
|
791
792
|
semanticOnly: false,
|
|
@@ -917,6 +918,7 @@ function parseConfig(raw) {
|
|
|
917
918
|
autoIndexMaxRetries: typeof rawIndexing.autoIndexMaxRetries === "number" ? Math.min(10, Math.max(0, Math.floor(rawIndexing.autoIndexMaxRetries))) : defaultIndexing.autoIndexMaxRetries,
|
|
918
919
|
autoIndexRetryDelayMs: typeof rawIndexing.autoIndexRetryDelayMs === "number" ? Math.min(1e4, Math.max(10, Math.floor(rawIndexing.autoIndexRetryDelayMs))) : defaultIndexing.autoIndexRetryDelayMs,
|
|
919
920
|
watchFiles: typeof rawIndexing.watchFiles === "boolean" ? rawIndexing.watchFiles : defaultIndexing.watchFiles,
|
|
921
|
+
pauseBackgroundIndexingOnBattery: typeof rawIndexing.pauseBackgroundIndexingOnBattery === "boolean" ? rawIndexing.pauseBackgroundIndexingOnBattery : defaultIndexing.pauseBackgroundIndexingOnBattery,
|
|
920
922
|
maxFileSize: typeof rawIndexing.maxFileSize === "number" ? rawIndexing.maxFileSize : defaultIndexing.maxFileSize,
|
|
921
923
|
maxChunksPerFile: typeof rawIndexing.maxChunksPerFile === "number" ? Math.max(1, rawIndexing.maxChunksPerFile) : defaultIndexing.maxChunksPerFile,
|
|
922
924
|
semanticOnly: typeof rawIndexing.semanticOnly === "boolean" ? rawIndexing.semanticOnly : defaultIndexing.semanticOnly,
|
|
@@ -3996,9 +3998,21 @@ function parseFiles(files) {
|
|
|
3996
3998
|
return result.map((f) => ({
|
|
3997
3999
|
path: f.path,
|
|
3998
4000
|
chunks: f.chunks.map(mapChunk),
|
|
4001
|
+
symbols: (f.symbols ?? []).map(mapParsedSymbol),
|
|
3999
4002
|
hash: f.hash
|
|
4000
4003
|
}));
|
|
4001
4004
|
}
|
|
4005
|
+
function mapParsedSymbol(symbol) {
|
|
4006
|
+
return {
|
|
4007
|
+
name: symbol.name,
|
|
4008
|
+
kind: symbol.kind,
|
|
4009
|
+
startLine: symbol.startLine ?? symbol.start_line,
|
|
4010
|
+
startCol: symbol.startCol ?? symbol.start_col,
|
|
4011
|
+
endLine: symbol.endLine ?? symbol.end_line,
|
|
4012
|
+
endCol: symbol.endCol ?? symbol.end_col,
|
|
4013
|
+
language: symbol.language
|
|
4014
|
+
};
|
|
4015
|
+
}
|
|
4002
4016
|
function mapChunk(c) {
|
|
4003
4017
|
return {
|
|
4004
4018
|
content: c.content,
|
|
@@ -6515,6 +6529,7 @@ var INDEX_METADATA_VERSION = "1";
|
|
|
6515
6529
|
var EMBEDDING_STRATEGY_VERSION = "2";
|
|
6516
6530
|
var SWIFT_PARSER_VERSION = "1";
|
|
6517
6531
|
var METAL_PARSER_VERSION = "1";
|
|
6532
|
+
var SYMBOL_EXTRACTOR_VERSION = "1";
|
|
6518
6533
|
var RANKING_TOKEN_CACHE_LIMIT = 4096;
|
|
6519
6534
|
var RANK_HYBRID_CACHE_LIMIT = 256;
|
|
6520
6535
|
function createPendingChunkStorageText(texts) {
|
|
@@ -6816,7 +6831,7 @@ function classifyQueryIntentRaw(query) {
|
|
|
6816
6831
|
return "neutral";
|
|
6817
6832
|
}
|
|
6818
6833
|
function isImplementationChunkType(chunkType) {
|
|
6819
|
-
return [
|
|
6834
|
+
return CALL_GRAPH_SYMBOL_CHUNK_TYPES.has(chunkType) || [
|
|
6820
6835
|
"export_statement",
|
|
6821
6836
|
"function",
|
|
6822
6837
|
"function_declaration",
|
|
@@ -7261,7 +7276,7 @@ function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCa
|
|
|
7261
7276
|
const remainder = combined.filter((candidate) => !promotedIds.has(candidate.id));
|
|
7262
7277
|
return [...promoted, ...remainder];
|
|
7263
7278
|
}
|
|
7264
|
-
function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallbackCandidates, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
7279
|
+
function buildSymbolDefinitionLane(query, database, branchChunkIds, branchSymbolIds, limit, fallbackCandidates, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
7265
7280
|
if (!prioritizeSourcePaths) {
|
|
7266
7281
|
return [];
|
|
7267
7282
|
}
|
|
@@ -7275,14 +7290,14 @@ function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallb
|
|
|
7275
7290
|
const primaryHint = extractPrimaryIdentifierQueryHint(query);
|
|
7276
7291
|
const upsertChunkCandidate = (chunk, identifier, normalizedIdentifier, baseScore) => {
|
|
7277
7292
|
if (branchChunkIds && !branchChunkIds.has(chunk.chunkId)) {
|
|
7278
|
-
return;
|
|
7293
|
+
return false;
|
|
7279
7294
|
}
|
|
7280
7295
|
const chunkType = chunk.nodeType ?? "other";
|
|
7281
7296
|
if (!isImplementationChunkType(chunkType)) {
|
|
7282
|
-
return;
|
|
7297
|
+
return false;
|
|
7283
7298
|
}
|
|
7284
7299
|
if (!isLikelyImplementationPath2(chunk.filePath)) {
|
|
7285
|
-
return;
|
|
7300
|
+
return false;
|
|
7286
7301
|
}
|
|
7287
7302
|
const nameLower = (chunk.name ?? "").toLowerCase();
|
|
7288
7303
|
const exactName = nameLower === identifier || nameLower.replace(/_/g, "") === normalizedIdentifier;
|
|
@@ -7304,6 +7319,7 @@ function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallb
|
|
|
7304
7319
|
}
|
|
7305
7320
|
});
|
|
7306
7321
|
}
|
|
7322
|
+
return true;
|
|
7307
7323
|
};
|
|
7308
7324
|
const normalizedHints = identifierHints.flatMap((hint) => [
|
|
7309
7325
|
hint,
|
|
@@ -7325,12 +7341,46 @@ function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallb
|
|
|
7325
7341
|
dedupSymbols.set(symbol.id, symbol);
|
|
7326
7342
|
}
|
|
7327
7343
|
for (const symbol of dedupSymbols.values()) {
|
|
7344
|
+
if (branchSymbolIds && !branchSymbolIds.has(symbol.id)) {
|
|
7345
|
+
continue;
|
|
7346
|
+
}
|
|
7347
|
+
if (filePathHint && !pathMatchesHint(symbol.filePath, filePathHint)) {
|
|
7348
|
+
continue;
|
|
7349
|
+
}
|
|
7328
7350
|
const chunks = database.getChunksByFile(symbol.filePath);
|
|
7351
|
+
let foundCoveringChunk = false;
|
|
7329
7352
|
for (const chunk of chunks) {
|
|
7330
7353
|
if (chunk.startLine > symbol.startLine || chunk.endLine < symbol.endLine) {
|
|
7331
7354
|
continue;
|
|
7332
7355
|
}
|
|
7333
|
-
|
|
7356
|
+
const chunkName = (chunk.name ?? "").toLowerCase();
|
|
7357
|
+
const symbolName2 = symbol.name.toLowerCase();
|
|
7358
|
+
if (chunkName !== symbolName2 && chunkName.replace(/_/g, "") !== symbolName2.replace(/_/g, "")) {
|
|
7359
|
+
continue;
|
|
7360
|
+
}
|
|
7361
|
+
foundCoveringChunk = upsertChunkCandidate(chunk, identifier, normalizedIdentifier) || foundCoveringChunk;
|
|
7362
|
+
}
|
|
7363
|
+
if (foundCoveringChunk || !isLikelyImplementationPath2(symbol.filePath)) {
|
|
7364
|
+
continue;
|
|
7365
|
+
}
|
|
7366
|
+
const symbolName = symbol.name.toLowerCase();
|
|
7367
|
+
const exactName = symbolName === identifier || symbolName.replace(/_/g, "") === normalizedIdentifier;
|
|
7368
|
+
const score = exactName ? 0.99 : 0.88;
|
|
7369
|
+
const existing = symbolCandidates.get(symbol.id);
|
|
7370
|
+
if (!existing || score > existing.score) {
|
|
7371
|
+
symbolCandidates.set(symbol.id, {
|
|
7372
|
+
id: symbol.id,
|
|
7373
|
+
score,
|
|
7374
|
+
metadata: {
|
|
7375
|
+
filePath: symbol.filePath,
|
|
7376
|
+
startLine: symbol.startLine,
|
|
7377
|
+
endLine: symbol.endLine,
|
|
7378
|
+
chunkType: symbol.kind,
|
|
7379
|
+
name: symbol.name,
|
|
7380
|
+
language: symbol.language,
|
|
7381
|
+
hash: symbol.id
|
|
7382
|
+
}
|
|
7383
|
+
});
|
|
7334
7384
|
}
|
|
7335
7385
|
}
|
|
7336
7386
|
const dedupChunksByName = /* @__PURE__ */ new Map();
|
|
@@ -7338,6 +7388,9 @@ function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallb
|
|
|
7338
7388
|
dedupChunksByName.set(chunk.chunkId, chunk);
|
|
7339
7389
|
}
|
|
7340
7390
|
for (const chunk of dedupChunksByName.values()) {
|
|
7391
|
+
if (filePathHint && !pathMatchesHint(chunk.filePath, filePathHint)) {
|
|
7392
|
+
continue;
|
|
7393
|
+
}
|
|
7341
7394
|
upsertChunkCandidate(chunk, identifier, normalizedIdentifier);
|
|
7342
7395
|
}
|
|
7343
7396
|
}
|
|
@@ -7879,6 +7932,10 @@ var Indexer = class _Indexer {
|
|
|
7879
7932
|
const projectHash = hashContent(path12.resolve(this.projectRoot)).slice(0, 16);
|
|
7880
7933
|
return `${key}.${projectHash}`;
|
|
7881
7934
|
}
|
|
7935
|
+
getSymbolExtractorVersionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
|
|
7936
|
+
const branchKey = this.getBranchCatalogKeyFor(catalogIdentity);
|
|
7937
|
+
return `index.symbolExtractorVersion.${hashContent(branchKey).slice(0, 24)}`;
|
|
7938
|
+
}
|
|
7882
7939
|
hasProjectForceReembedPending() {
|
|
7883
7940
|
return this.config.scope === "global" && this.database?.getMetadata(this.getProjectForceReembedMetadataKey()) === "true";
|
|
7884
7941
|
}
|
|
@@ -9222,7 +9279,8 @@ var Indexer = class _Indexer {
|
|
|
9222
9279
|
}
|
|
9223
9280
|
const branchKey = this.getBranchCatalogKey();
|
|
9224
9281
|
const alreadyIndexed = database.getBranchChunkIds(branchKey).length > 0 && database.getBranchSymbolIds(branchKey).length > 0;
|
|
9225
|
-
|
|
9282
|
+
const symbolsCurrent = database.getMetadata(this.getSymbolExtractorVersionMetadataKey()) === SYMBOL_EXTRACTOR_VERSION;
|
|
9283
|
+
if (alreadyIndexed && symbolsCurrent && this.getStoredBranchCommit(database) === normalizedCommit) {
|
|
9226
9284
|
return { prepared: false };
|
|
9227
9285
|
}
|
|
9228
9286
|
const stats = await this.indexUnlocked(onProgress, [], true);
|
|
@@ -9281,6 +9339,8 @@ var Indexer = class _Indexer {
|
|
|
9281
9339
|
const reparseCachedSwiftFiles = database.getMetadata(swiftParserMetadataKey) !== SWIFT_PARSER_VERSION;
|
|
9282
9340
|
const metalParserMetadataKey = this.getMetalParserVersionMetadataKey();
|
|
9283
9341
|
const reparseCachedMetalFiles = database.getMetadata(metalParserMetadataKey) !== METAL_PARSER_VERSION;
|
|
9342
|
+
const symbolExtractorMetadataKey = this.getSymbolExtractorVersionMetadataKey();
|
|
9343
|
+
const refreshCachedSymbols = database.getMetadata(symbolExtractorMetadataKey) !== SYMBOL_EXTRACTOR_VERSION;
|
|
9284
9344
|
if (reparseCachedSwiftFiles && Array.from(this.fileHashCache.keys()).some(
|
|
9285
9345
|
(filePath) => path12.extname(filePath).toLowerCase() === ".swift"
|
|
9286
9346
|
)) {
|
|
@@ -9324,7 +9384,7 @@ var Indexer = class _Indexer {
|
|
|
9324
9384
|
);
|
|
9325
9385
|
const requiresSwiftParserUpgrade = reparseCachedSwiftFiles && path12.extname(canonicalPath).toLowerCase() === ".swift";
|
|
9326
9386
|
const requiresMetalParserUpgrade = reparseCachedMetalFiles && path12.extname(canonicalPath).toLowerCase() === ".metal";
|
|
9327
|
-
if (cachedHashMatches && !needsCallGraphRefresh && !requiresSwiftParserUpgrade && !requiresMetalParserUpgrade) {
|
|
9387
|
+
if (cachedHashMatches && !needsCallGraphRefresh && !requiresSwiftParserUpgrade && !requiresMetalParserUpgrade && !refreshCachedSymbols) {
|
|
9328
9388
|
unchangedFilePaths.add(canonicalPath);
|
|
9329
9389
|
this.logger.recordCacheHit();
|
|
9330
9390
|
} else {
|
|
@@ -9535,37 +9595,27 @@ var Indexer = class _Indexer {
|
|
|
9535
9595
|
const parsed = parsedFiles[i];
|
|
9536
9596
|
const changedFile = changedFiles[i];
|
|
9537
9597
|
const fileSymbols = [];
|
|
9538
|
-
for (const
|
|
9539
|
-
if (!
|
|
9540
|
-
const existingMetalSymbol = chunk.language === "metal" ? fileSymbols.find(
|
|
9541
|
-
(symbol2) => symbol2.name === chunk.name && symbol2.kind === chunk.chunkType && symbol2.startLine <= chunk.endLine && chunk.startLine <= symbol2.endLine
|
|
9542
|
-
) : void 0;
|
|
9543
|
-
if (existingMetalSymbol) {
|
|
9544
|
-
existingMetalSymbol.startLine = Math.min(existingMetalSymbol.startLine, chunk.startLine);
|
|
9545
|
-
existingMetalSymbol.endLine = Math.max(existingMetalSymbol.endLine, chunk.endLine);
|
|
9546
|
-
existingMetalSymbol.startCol = Math.min(existingMetalSymbol.startCol, chunk.startCol ?? 0);
|
|
9547
|
-
existingMetalSymbol.endCol = Math.max(existingMetalSymbol.endCol, chunk.endCol ?? 0);
|
|
9548
|
-
continue;
|
|
9549
|
-
}
|
|
9598
|
+
for (const parsedSymbol of parsed.symbols) {
|
|
9599
|
+
if (!CALL_GRAPH_SYMBOL_CHUNK_TYPES.has(parsedSymbol.kind)) continue;
|
|
9550
9600
|
const preparedNamespace = this.getPreparedBranchNamespace();
|
|
9551
9601
|
const symbolId = `sym_${hashContent(
|
|
9552
|
-
(preparedNamespace ? `${preparedNamespace}:` : "") + parsed.path + ":" +
|
|
9602
|
+
(preparedNamespace ? `${preparedNamespace}:` : "") + parsed.path + ":" + parsedSymbol.name + ":" + parsedSymbol.kind + ":" + parsedSymbol.startLine + ":" + parsedSymbol.startCol + ":" + changedFile.hash
|
|
9553
9603
|
).slice(0, 16)}`;
|
|
9554
9604
|
const symbol = {
|
|
9555
9605
|
id: symbolId,
|
|
9556
9606
|
filePath: parsed.path,
|
|
9557
|
-
name:
|
|
9558
|
-
kind:
|
|
9559
|
-
startLine:
|
|
9560
|
-
startCol:
|
|
9561
|
-
endLine:
|
|
9562
|
-
endCol:
|
|
9563
|
-
language:
|
|
9607
|
+
name: parsedSymbol.name,
|
|
9608
|
+
kind: parsedSymbol.kind,
|
|
9609
|
+
startLine: parsedSymbol.startLine,
|
|
9610
|
+
startCol: parsedSymbol.startCol,
|
|
9611
|
+
endLine: parsedSymbol.endLine,
|
|
9612
|
+
endCol: parsedSymbol.endCol,
|
|
9613
|
+
language: parsedSymbol.language
|
|
9564
9614
|
};
|
|
9565
9615
|
fileSymbols.push(symbol);
|
|
9566
9616
|
allSymbolIds.add(symbolId);
|
|
9567
9617
|
}
|
|
9568
|
-
const fileLanguage = parsed.chunks[0]?.language;
|
|
9618
|
+
const fileLanguage = parsed.symbols[0]?.language ?? parsed.chunks[0]?.language;
|
|
9569
9619
|
const isCaseInsensitiveLanguage = !!fileLanguage && CASE_INSENSITIVE_LANGUAGES.has(fileLanguage);
|
|
9570
9620
|
const normalizeSymbolKey = (name) => isCaseInsensitiveLanguage ? name.toLowerCase() : name;
|
|
9571
9621
|
const symbolsByName = /* @__PURE__ */ new Map();
|
|
@@ -9681,6 +9731,7 @@ var Indexer = class _Indexer {
|
|
|
9681
9731
|
}
|
|
9682
9732
|
database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);
|
|
9683
9733
|
database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);
|
|
9734
|
+
database.setMetadata(symbolExtractorMetadataKey, SYMBOL_EXTRACTOR_VERSION);
|
|
9684
9735
|
this.saveBranchCommit(database, indexedCommit);
|
|
9685
9736
|
this.saveIndexMetadata(configuredProviderInfo);
|
|
9686
9737
|
this.indexCompatibility = { compatible: true };
|
|
@@ -9717,6 +9768,7 @@ var Indexer = class _Indexer {
|
|
|
9717
9768
|
}
|
|
9718
9769
|
database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);
|
|
9719
9770
|
database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);
|
|
9771
|
+
database.setMetadata(symbolExtractorMetadataKey, SYMBOL_EXTRACTOR_VERSION);
|
|
9720
9772
|
this.saveBranchCommit(database, indexedCommit);
|
|
9721
9773
|
this.saveIndexMetadata(configuredProviderInfo);
|
|
9722
9774
|
this.indexCompatibility = { compatible: true };
|
|
@@ -9996,6 +10048,7 @@ var Indexer = class _Indexer {
|
|
|
9996
10048
|
}
|
|
9997
10049
|
database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);
|
|
9998
10050
|
database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);
|
|
10051
|
+
database.setMetadata(symbolExtractorMetadataKey, SYMBOL_EXTRACTOR_VERSION);
|
|
9999
10052
|
this.saveBranchCommit(database, indexedCommit);
|
|
10000
10053
|
this.saveIndexMetadata(configuredProviderInfo);
|
|
10001
10054
|
this.indexCompatibility = { compatible: true };
|
|
@@ -10134,10 +10187,11 @@ var Indexer = class _Indexer {
|
|
|
10134
10187
|
const keywordResults = await this.keywordSearch(query, maxResults * 4, store, invertedIndex);
|
|
10135
10188
|
const keywordMs = import_perf_hooks.performance.now() - keywordStartTime;
|
|
10136
10189
|
let branchChunkIds = null;
|
|
10190
|
+
let branchSymbolIds = null;
|
|
10137
10191
|
if (filterByBranch && (this.config.scope === "global" || this.currentBranch !== "default")) {
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
);
|
|
10192
|
+
const branchCatalogKeys = this.getBranchCatalogKeys();
|
|
10193
|
+
branchChunkIds = new Set(branchCatalogKeys.flatMap((branchKey) => database.getBranchChunkIds(branchKey)));
|
|
10194
|
+
branchSymbolIds = new Set(branchCatalogKeys.flatMap((branchKey) => database.getBranchSymbolIds(branchKey)));
|
|
10141
10195
|
}
|
|
10142
10196
|
const prefilterStartTime = import_perf_hooks.performance.now();
|
|
10143
10197
|
const shouldPrefilterByBranch = branchChunkIds !== null && (this.config.scope === "global" || branchChunkIds.size > 0);
|
|
@@ -10209,6 +10263,7 @@ var Indexer = class _Indexer {
|
|
|
10209
10263
|
query,
|
|
10210
10264
|
database,
|
|
10211
10265
|
branchChunkIds,
|
|
10266
|
+
branchSymbolIds,
|
|
10212
10267
|
maxResults,
|
|
10213
10268
|
union,
|
|
10214
10269
|
sourceIntent
|
|
@@ -10222,7 +10277,7 @@ var Indexer = class _Indexer {
|
|
|
10222
10277
|
(r) => isLikelyImplementationPath2(r.metadata.filePath) && isImplementationChunkType(r.metadata.chunkType)
|
|
10223
10278
|
);
|
|
10224
10279
|
const filtered = (sourceIntent && hasCodeHints && implementationOnly.length > 0 ? implementationOnly : baseFiltered).slice(0, maxResults);
|
|
10225
|
-
const identifierFallback = !options?.definitionIntent && filtered.length === 0 && identifierHints.length > 0 ? buildSymbolDefinitionLane(query, database, branchChunkIds, maxResults, union, true).filter((r) => matchesSearchFilters(r, options, this.config.search.minScore)).slice(0, maxResults) : [];
|
|
10280
|
+
const identifierFallback = !options?.definitionIntent && filtered.length === 0 && identifierHints.length > 0 ? buildSymbolDefinitionLane(query, database, branchChunkIds, branchSymbolIds, maxResults, union, true).filter((r) => matchesSearchFilters(r, options, this.config.search.minScore)).slice(0, maxResults) : [];
|
|
10226
10281
|
const finalResults = filtered.length > 0 ? filtered : identifierFallback;
|
|
10227
10282
|
const totalSearchMs = import_perf_hooks.performance.now() - searchStartTime;
|
|
10228
10283
|
this.logger.recordSearch(totalSearchMs, {
|
|
@@ -10379,7 +10434,7 @@ var Indexer = class _Indexer {
|
|
|
10379
10434
|
const extension = path12.extname(filePath).toLowerCase();
|
|
10380
10435
|
return extension === ".php" || extension === ".c" || extension === ".cc" || extension === ".cpp" || extension === ".cxx";
|
|
10381
10436
|
});
|
|
10382
|
-
if (hasSwiftFiles && database.getMetadata(this.getSwiftParserVersionMetadataKey()) !== SWIFT_PARSER_VERSION || hasMetalFiles && database.getMetadata(this.getMetalParserVersionMetadataKey()) !== METAL_PARSER_VERSION || hasCallGraphMigrationFiles && database.getMetadata(this.getCallGraphResolutionMetadataKey()) !== CALL_GRAPH_RESOLUTION_VERSION) {
|
|
10437
|
+
if (hasSwiftFiles && database.getMetadata(this.getSwiftParserVersionMetadataKey()) !== SWIFT_PARSER_VERSION || hasMetalFiles && database.getMetadata(this.getMetalParserVersionMetadataKey()) !== METAL_PARSER_VERSION || database.getMetadata(this.getSymbolExtractorVersionMetadataKey()) !== SYMBOL_EXTRACTOR_VERSION || hasCallGraphMigrationFiles && database.getMetadata(this.getCallGraphResolutionMetadataKey()) !== CALL_GRAPH_RESOLUTION_VERSION) {
|
|
10383
10438
|
return { readable: true, current: false, reason: "migration-required" };
|
|
10384
10439
|
}
|
|
10385
10440
|
if (isGitRepo(this.materializedProjectRoot)) {
|
|
@@ -11087,7 +11142,10 @@ var Indexer = class _Indexer {
|
|
|
11087
11142
|
const requestedRef = opts.pr !== void 0 ? expectedCommit : headRefName ?? resolvedBranch;
|
|
11088
11143
|
const storedCommit = this.getStoredBranchCommit(database, catalogIdentity);
|
|
11089
11144
|
const catalogIdentityMatches = storedCommit === expectedCommit;
|
|
11090
|
-
|
|
11145
|
+
const symbolsCurrent = database.getMetadata(
|
|
11146
|
+
this.getSymbolExtractorVersionMetadataKey(catalogIdentity)
|
|
11147
|
+
) === SYMBOL_EXTRACTOR_VERSION;
|
|
11148
|
+
if (branchSymbols.length === 0 || !catalogIdentityMatches || !symbolsCurrent) {
|
|
11091
11149
|
if (!resolvedBranch || resolvedBranch === "default") {
|
|
11092
11150
|
throw new Error("Run index_codebase first to build the call graph and symbol index for this project.");
|
|
11093
11151
|
}
|
|
@@ -11429,8 +11487,17 @@ function fitTextToContextBudget(text3, tokenBudget) {
|
|
|
11429
11487
|
function normalizedLineRange(result) {
|
|
11430
11488
|
return result.startLine <= result.endLine ? { start: result.startLine, end: result.endLine } : { start: result.endLine, end: result.startLine };
|
|
11431
11489
|
}
|
|
11432
|
-
function rankContextCandidates(results) {
|
|
11433
|
-
return results.map((result, originalIndex) => ({ result, originalIndex })).sort((left, right) =>
|
|
11490
|
+
function rankContextCandidates(results, preferImplementationPaths) {
|
|
11491
|
+
return results.map((result, originalIndex) => ({ result, originalIndex })).sort((left, right) => {
|
|
11492
|
+
if (preferImplementationPaths) {
|
|
11493
|
+
const leftIsImplementation = isLikelyImplementationPath(left.result.filePath);
|
|
11494
|
+
const rightIsImplementation = isLikelyImplementationPath(right.result.filePath);
|
|
11495
|
+
if (leftIsImplementation !== rightIsImplementation) {
|
|
11496
|
+
return leftIsImplementation ? -1 : 1;
|
|
11497
|
+
}
|
|
11498
|
+
}
|
|
11499
|
+
return right.result.score - left.result.score || left.originalIndex - right.originalIndex;
|
|
11500
|
+
});
|
|
11434
11501
|
}
|
|
11435
11502
|
function deduplicateContextCandidates(candidates) {
|
|
11436
11503
|
const acceptedByFile = /* @__PURE__ */ new Map();
|
|
@@ -11519,7 +11586,12 @@ function buildContextPack(results, options = {}) {
|
|
|
11519
11586
|
const maxResults = Math.max(0, Math.floor(options.maxResults ?? results.length));
|
|
11520
11587
|
const includeExactSearchHandoff = options.includeExactSearchHandoff ?? false;
|
|
11521
11588
|
const candidateCount = results.length;
|
|
11522
|
-
const deduplicated = deduplicateContextCandidates(
|
|
11589
|
+
const deduplicated = deduplicateContextCandidates(
|
|
11590
|
+
rankContextCandidates(
|
|
11591
|
+
results,
|
|
11592
|
+
options.preferImplementationPaths ?? false
|
|
11593
|
+
)
|
|
11594
|
+
);
|
|
11523
11595
|
const diversified = diversifyContextCandidates(deduplicated);
|
|
11524
11596
|
const duplicateCount = candidateCount - deduplicated.length;
|
|
11525
11597
|
const selectable = diversified.slice(0, maxResults);
|
|
@@ -11891,7 +11963,7 @@ ${truncateContent(r.content)}
|
|
|
11891
11963
|
}
|
|
11892
11964
|
|
|
11893
11965
|
// src/utils/effectiveness-metrics.ts
|
|
11894
|
-
var EFFECTIVENESS_METRICS_SCHEMA_VERSION =
|
|
11966
|
+
var EFFECTIVENESS_METRICS_SCHEMA_VERSION = 3;
|
|
11895
11967
|
var MAX_EFFECTIVENESS_COUNTER = 1e9;
|
|
11896
11968
|
var EFFECTIVENESS_TOOL_ROUTES = [
|
|
11897
11969
|
"context-conceptual",
|
|
@@ -11937,6 +12009,9 @@ var EFFECTIVENESS_SCOPE_RELAXATION_BUCKETS = ["none", "directory", "file-type",
|
|
|
11937
12009
|
function emptyCounterMap(values) {
|
|
11938
12010
|
return Object.fromEntries(values.map((value) => [value, 0]));
|
|
11939
12011
|
}
|
|
12012
|
+
function emptyRouteCounterMap(routes, values) {
|
|
12013
|
+
return Object.fromEntries(routes.map((route) => [route, emptyCounterMap(values)]));
|
|
12014
|
+
}
|
|
11940
12015
|
function boundedNumber(value) {
|
|
11941
12016
|
if (value === void 0 || !Number.isFinite(value)) return 0;
|
|
11942
12017
|
return Math.max(0, Math.floor(value));
|
|
@@ -11985,6 +12060,11 @@ function allowedValue(value, allowed, fallback) {
|
|
|
11985
12060
|
function cloneCounterMap(counters) {
|
|
11986
12061
|
return { ...counters };
|
|
11987
12062
|
}
|
|
12063
|
+
function cloneRouteCounterMap(counters) {
|
|
12064
|
+
return Object.fromEntries(
|
|
12065
|
+
EFFECTIVENESS_TOOL_ROUTES.map((route) => [route, cloneCounterMap(counters[route])])
|
|
12066
|
+
);
|
|
12067
|
+
}
|
|
11988
12068
|
var EffectivenessMetrics = class {
|
|
11989
12069
|
constructor(counterCap = MAX_EFFECTIVENESS_COUNTER) {
|
|
11990
12070
|
this.counterCap = counterCap;
|
|
@@ -12000,7 +12080,7 @@ var EffectivenessMetrics = class {
|
|
|
12000
12080
|
lifetime: "process",
|
|
12001
12081
|
reset: "index_metrics-reset-or-process-exit",
|
|
12002
12082
|
maxCounterValue: this.counterCap,
|
|
12003
|
-
dimensions: "bounded-
|
|
12083
|
+
dimensions: "bounded-route-and-bucketed-performance-only"
|
|
12004
12084
|
},
|
|
12005
12085
|
totalCalls: 0,
|
|
12006
12086
|
toolRoute: emptyCounterMap(EFFECTIVENESS_TOOL_ROUTES),
|
|
@@ -12012,7 +12092,14 @@ var EffectivenessMetrics = class {
|
|
|
12012
12092
|
tokenBudget: emptyCounterMap(EFFECTIVENESS_TOKEN_BUDGET_BUCKETS),
|
|
12013
12093
|
returnedTokenEstimate: emptyCounterMap(EFFECTIVENESS_RETURNED_TOKEN_BUCKETS),
|
|
12014
12094
|
exactHandoffEmitted: emptyCounterMap(EFFECTIVENESS_BOOLEAN_BUCKETS),
|
|
12015
|
-
scopeRelaxation: emptyCounterMap(EFFECTIVENESS_SCOPE_RELAXATION_BUCKETS)
|
|
12095
|
+
scopeRelaxation: emptyCounterMap(EFFECTIVENESS_SCOPE_RELAXATION_BUCKETS),
|
|
12096
|
+
routeOutcome: emptyRouteCounterMap(EFFECTIVENESS_TOOL_ROUTES, EFFECTIVENESS_OUTCOMES),
|
|
12097
|
+
routeLatency: emptyRouteCounterMap(EFFECTIVENESS_TOOL_ROUTES, EFFECTIVENESS_LATENCY_BUCKETS),
|
|
12098
|
+
routeResultCount: emptyRouteCounterMap(EFFECTIVENESS_TOOL_ROUTES, EFFECTIVENESS_RESULT_COUNT_BUCKETS),
|
|
12099
|
+
routeReturnedTokenEstimate: emptyRouteCounterMap(
|
|
12100
|
+
EFFECTIVENESS_TOOL_ROUTES,
|
|
12101
|
+
EFFECTIVENESS_RETURNED_TOKEN_BUCKETS
|
|
12102
|
+
)
|
|
12016
12103
|
};
|
|
12017
12104
|
}
|
|
12018
12105
|
increment(counters, key) {
|
|
@@ -12034,12 +12121,19 @@ var EffectivenessMetrics = class {
|
|
|
12034
12121
|
this.increment(this.snapshot.hostMode, host);
|
|
12035
12122
|
this.increment(this.snapshot.outcome, outcome);
|
|
12036
12123
|
this.increment(this.snapshot.recoveryUsed, recoveryUsed);
|
|
12037
|
-
|
|
12038
|
-
|
|
12124
|
+
const resultCountBucketValue = resultCountBucket(event.resultCount);
|
|
12125
|
+
const latencyBucketValue = latencyBucket(event.latencyMs);
|
|
12126
|
+
const returnedTokenBucketValue = returnedTokenBucket(event.returnedTokenEstimate);
|
|
12127
|
+
this.increment(this.snapshot.resultCount, resultCountBucketValue);
|
|
12128
|
+
this.increment(this.snapshot.latency, latencyBucketValue);
|
|
12039
12129
|
this.increment(this.snapshot.tokenBudget, tokenBudgetBucket(event.tokenBudget));
|
|
12040
|
-
this.increment(this.snapshot.returnedTokenEstimate,
|
|
12130
|
+
this.increment(this.snapshot.returnedTokenEstimate, returnedTokenBucketValue);
|
|
12041
12131
|
this.increment(this.snapshot.exactHandoffEmitted, exactHandoffEmitted);
|
|
12042
12132
|
this.increment(this.snapshot.scopeRelaxation, scopeRelaxation);
|
|
12133
|
+
this.increment(this.snapshot.routeOutcome[route], outcome);
|
|
12134
|
+
this.increment(this.snapshot.routeLatency[route], latencyBucketValue);
|
|
12135
|
+
this.increment(this.snapshot.routeResultCount[route], resultCountBucketValue);
|
|
12136
|
+
this.increment(this.snapshot.routeReturnedTokenEstimate[route], returnedTokenBucketValue);
|
|
12043
12137
|
}
|
|
12044
12138
|
getSnapshot() {
|
|
12045
12139
|
return {
|
|
@@ -12054,7 +12148,11 @@ var EffectivenessMetrics = class {
|
|
|
12054
12148
|
tokenBudget: cloneCounterMap(this.snapshot.tokenBudget),
|
|
12055
12149
|
returnedTokenEstimate: cloneCounterMap(this.snapshot.returnedTokenEstimate),
|
|
12056
12150
|
exactHandoffEmitted: cloneCounterMap(this.snapshot.exactHandoffEmitted),
|
|
12057
|
-
scopeRelaxation: cloneCounterMap(this.snapshot.scopeRelaxation)
|
|
12151
|
+
scopeRelaxation: cloneCounterMap(this.snapshot.scopeRelaxation),
|
|
12152
|
+
routeOutcome: cloneRouteCounterMap(this.snapshot.routeOutcome),
|
|
12153
|
+
routeLatency: cloneRouteCounterMap(this.snapshot.routeLatency),
|
|
12154
|
+
routeResultCount: cloneRouteCounterMap(this.snapshot.routeResultCount),
|
|
12155
|
+
routeReturnedTokenEstimate: cloneRouteCounterMap(this.snapshot.routeReturnedTokenEstimate)
|
|
12058
12156
|
};
|
|
12059
12157
|
}
|
|
12060
12158
|
reset() {
|
|
@@ -12073,6 +12171,7 @@ function resetProcessEffectivenessMetrics() {
|
|
|
12073
12171
|
}
|
|
12074
12172
|
function formatEffectivenessMetrics(snapshot) {
|
|
12075
12173
|
const formatCounters = (counters) => Object.entries(counters).map(([bucket, count]) => `${bucket}=${count}`).join(", ");
|
|
12174
|
+
const formatRouteCounters = (counters) => EFFECTIVENESS_TOOL_ROUTES.map((route) => `${route} => ${formatCounters(counters[route])}`).join("; ");
|
|
12076
12175
|
const lines = [
|
|
12077
12176
|
`Privacy-safe effectiveness (schema v${snapshot.schemaVersion}):`,
|
|
12078
12177
|
` Retention: ${snapshot.retention.storage}, ${snapshot.retention.lifetime}-lifetime; reset with index_metrics(reset=true) or process exit`,
|
|
@@ -12087,6 +12186,10 @@ function formatEffectivenessMetrics(snapshot) {
|
|
|
12087
12186
|
` Latency bucket: ${formatCounters(snapshot.latency)}`,
|
|
12088
12187
|
` Token-budget bucket: ${formatCounters(snapshot.tokenBudget)}`,
|
|
12089
12188
|
` Returned-token estimate: ${formatCounters(snapshot.returnedTokenEstimate)}`,
|
|
12189
|
+
` Route outcome buckets: ${formatRouteCounters(snapshot.routeOutcome)}`,
|
|
12190
|
+
` Route latency buckets: ${formatRouteCounters(snapshot.routeLatency)}`,
|
|
12191
|
+
` Route result-count buckets: ${formatRouteCounters(snapshot.routeResultCount)}`,
|
|
12192
|
+
` Route returned-token buckets: ${formatRouteCounters(snapshot.routeReturnedTokenEstimate)}`,
|
|
12090
12193
|
` Exact handoff emitted: ${formatCounters(snapshot.exactHandoffEmitted)}`,
|
|
12091
12194
|
` Scope relaxation: ${formatCounters(snapshot.scopeRelaxation)}`,
|
|
12092
12195
|
" Privacy: no queries, response text, source, symbols, paths, repository names, user identity, or stable identifiers are retained."
|
|
@@ -12098,6 +12201,103 @@ function formatEffectivenessMetrics(snapshot) {
|
|
|
12098
12201
|
var import_fs10 = require("fs");
|
|
12099
12202
|
var os6 = __toESM(require("os"), 1);
|
|
12100
12203
|
var path14 = __toESM(require("path"), 1);
|
|
12204
|
+
|
|
12205
|
+
// src/utils/power-source.ts
|
|
12206
|
+
var childProcess = __toESM(require("child_process"), 1);
|
|
12207
|
+
var POWER_SOURCE_RECHECK_DELAY_MS = 6e4;
|
|
12208
|
+
var PMSET_TIMEOUT_MS = 5e3;
|
|
12209
|
+
function getErrorMessage4(error) {
|
|
12210
|
+
return error instanceof Error ? error.message : String(error);
|
|
12211
|
+
}
|
|
12212
|
+
function runCommand(file, args, options) {
|
|
12213
|
+
return new Promise((resolve12, reject) => {
|
|
12214
|
+
childProcess.execFile(
|
|
12215
|
+
file,
|
|
12216
|
+
args,
|
|
12217
|
+
{ encoding: "utf8", timeout: options.timeoutMs },
|
|
12218
|
+
(error, stdout) => {
|
|
12219
|
+
if (error) {
|
|
12220
|
+
reject(error);
|
|
12221
|
+
return;
|
|
12222
|
+
}
|
|
12223
|
+
resolve12(stdout);
|
|
12224
|
+
}
|
|
12225
|
+
);
|
|
12226
|
+
});
|
|
12227
|
+
}
|
|
12228
|
+
function parseMacOsPowerSource(output) {
|
|
12229
|
+
const match = output.match(/Now drawing from '([^']+)'/i);
|
|
12230
|
+
if (!match) {
|
|
12231
|
+
return "unknown";
|
|
12232
|
+
}
|
|
12233
|
+
const source = match[1].toLowerCase();
|
|
12234
|
+
if (source === "battery power") {
|
|
12235
|
+
return "battery";
|
|
12236
|
+
}
|
|
12237
|
+
if (source === "ac power") {
|
|
12238
|
+
return "ac";
|
|
12239
|
+
}
|
|
12240
|
+
return "unknown";
|
|
12241
|
+
}
|
|
12242
|
+
async function readMacOsPowerSource(commandRunner = runCommand) {
|
|
12243
|
+
const output = await commandRunner(
|
|
12244
|
+
"/usr/bin/pmset",
|
|
12245
|
+
["-g", "batt"],
|
|
12246
|
+
{ timeoutMs: PMSET_TIMEOUT_MS }
|
|
12247
|
+
);
|
|
12248
|
+
return parseMacOsPowerSource(output);
|
|
12249
|
+
}
|
|
12250
|
+
var MacOsBackgroundIndexingPolicy = class {
|
|
12251
|
+
constructor(readPowerSource, recheckDelayMs) {
|
|
12252
|
+
this.readPowerSource = readPowerSource;
|
|
12253
|
+
this.recheckDelayMs = recheckDelayMs;
|
|
12254
|
+
}
|
|
12255
|
+
readPowerSource;
|
|
12256
|
+
recheckDelayMs;
|
|
12257
|
+
lastPaused = null;
|
|
12258
|
+
reportedFailure = false;
|
|
12259
|
+
isPaused() {
|
|
12260
|
+
return this.checkPowerSource();
|
|
12261
|
+
}
|
|
12262
|
+
async checkPowerSource() {
|
|
12263
|
+
try {
|
|
12264
|
+
const source = await this.readPowerSource();
|
|
12265
|
+
if (source === "unknown") {
|
|
12266
|
+
throw new Error("pmset returned an unrecognized power source");
|
|
12267
|
+
}
|
|
12268
|
+
this.reportedFailure = false;
|
|
12269
|
+
const paused = source === "battery";
|
|
12270
|
+
if (paused && this.lastPaused !== true) {
|
|
12271
|
+
console.warn("[codebase-index] Background indexing paused while macOS is using battery power.");
|
|
12272
|
+
} else if (!paused && this.lastPaused === true) {
|
|
12273
|
+
console.warn("[codebase-index] AC power detected; resuming pending background indexing.");
|
|
12274
|
+
}
|
|
12275
|
+
this.lastPaused = paused;
|
|
12276
|
+
return paused;
|
|
12277
|
+
} catch (error) {
|
|
12278
|
+
if (!this.reportedFailure) {
|
|
12279
|
+
console.error(
|
|
12280
|
+
`[codebase-index] Failed to determine the macOS power source; background indexing will continue: ${getErrorMessage4(error)}`
|
|
12281
|
+
);
|
|
12282
|
+
this.reportedFailure = true;
|
|
12283
|
+
}
|
|
12284
|
+
this.lastPaused = false;
|
|
12285
|
+
return false;
|
|
12286
|
+
}
|
|
12287
|
+
}
|
|
12288
|
+
};
|
|
12289
|
+
function createBackgroundIndexingPolicy(pauseOnBattery, options = {}) {
|
|
12290
|
+
const platform2 = options.platform ?? process.platform;
|
|
12291
|
+
if (!pauseOnBattery || platform2 !== "darwin") {
|
|
12292
|
+
return null;
|
|
12293
|
+
}
|
|
12294
|
+
return new MacOsBackgroundIndexingPolicy(
|
|
12295
|
+
options.readPowerSource ?? readMacOsPowerSource,
|
|
12296
|
+
options.recheckDelayMs ?? POWER_SOURCE_RECHECK_DELAY_MS
|
|
12297
|
+
);
|
|
12298
|
+
}
|
|
12299
|
+
|
|
12300
|
+
// src/utils/auto-index.ts
|
|
12101
12301
|
var MAX_RETRY_DELAY_MS = 1e4;
|
|
12102
12302
|
var SHUTDOWN_WAIT_MS = 2e3;
|
|
12103
12303
|
var coordinators = /* @__PURE__ */ new Map();
|
|
@@ -12214,7 +12414,13 @@ var AutoIndexCoordinator = class {
|
|
|
12214
12414
|
activation = Promise.resolve();
|
|
12215
12415
|
inFlight = null;
|
|
12216
12416
|
activeRequest = null;
|
|
12417
|
+
batteryCheck = null;
|
|
12418
|
+
batteryIndexJob = null;
|
|
12419
|
+
batteryDeferredRequest = null;
|
|
12420
|
+
batteryRetryTimer = null;
|
|
12421
|
+
resolveBatteryRetry = null;
|
|
12217
12422
|
pendingRequest = null;
|
|
12423
|
+
pendingFollowUp = null;
|
|
12218
12424
|
abortController = null;
|
|
12219
12425
|
stopped = false;
|
|
12220
12426
|
constructor(registration) {
|
|
@@ -12227,6 +12433,7 @@ var AutoIndexCoordinator = class {
|
|
|
12227
12433
|
};
|
|
12228
12434
|
}
|
|
12229
12435
|
update(registration) {
|
|
12436
|
+
const pauseOnBatteryChanged = registration.config.indexing.pauseBackgroundIndexingOnBattery !== this.registration.config.indexing.pauseBackgroundIndexingOnBattery;
|
|
12230
12437
|
this.registration = registration;
|
|
12231
12438
|
this.status.enabled = registration.config.indexing.autoIndex;
|
|
12232
12439
|
this.status.blockedReason = registration.blockedReason;
|
|
@@ -12242,6 +12449,9 @@ var AutoIndexCoordinator = class {
|
|
|
12242
12449
|
this.setState("idle", { source: void 0 });
|
|
12243
12450
|
}
|
|
12244
12451
|
}
|
|
12452
|
+
if (pauseOnBatteryChanged) {
|
|
12453
|
+
this.cancelBatteryRetry();
|
|
12454
|
+
}
|
|
12245
12455
|
}
|
|
12246
12456
|
activateAfter(activation) {
|
|
12247
12457
|
this.activation = activation;
|
|
@@ -12263,7 +12473,26 @@ var AutoIndexCoordinator = class {
|
|
|
12263
12473
|
if (this.stopped) {
|
|
12264
12474
|
return Promise.resolve({ outcome: "stopped" });
|
|
12265
12475
|
}
|
|
12266
|
-
return this.activation.then(() => this.
|
|
12476
|
+
return this.activation.then(() => this.enqueueBatteryAwareRequest(request));
|
|
12477
|
+
}
|
|
12478
|
+
enqueueBatteryAwareRequest(request) {
|
|
12479
|
+
if (!this.shouldDeferForBattery(request)) {
|
|
12480
|
+
return this.enqueueRequest(request);
|
|
12481
|
+
}
|
|
12482
|
+
if (this.batteryCheck && this.batteryIndexJob !== null && this.batteryIndexJob === this.inFlight) {
|
|
12483
|
+
return this.enqueueRequest(request);
|
|
12484
|
+
}
|
|
12485
|
+
this.batteryDeferredRequest = mergeRequests(this.batteryDeferredRequest, request);
|
|
12486
|
+
if (this.batteryCheck) {
|
|
12487
|
+
return this.batteryCheck;
|
|
12488
|
+
}
|
|
12489
|
+
const batteryCheck = this.waitForACPower();
|
|
12490
|
+
this.batteryCheck = batteryCheck;
|
|
12491
|
+
void batteryCheck.then(
|
|
12492
|
+
() => this.finishBatteryCheck(batteryCheck),
|
|
12493
|
+
() => this.finishBatteryCheck(batteryCheck)
|
|
12494
|
+
);
|
|
12495
|
+
return batteryCheck;
|
|
12267
12496
|
}
|
|
12268
12497
|
enqueueRequest(request) {
|
|
12269
12498
|
if (this.stopped || !this.canRun(request)) {
|
|
@@ -12281,6 +12510,11 @@ var AutoIndexCoordinator = class {
|
|
|
12281
12510
|
}
|
|
12282
12511
|
if (request.source === "watcher") {
|
|
12283
12512
|
this.pendingRequest = mergeRequests(this.pendingRequest, request);
|
|
12513
|
+
const active = this.inFlight;
|
|
12514
|
+
return active.then(() => {
|
|
12515
|
+
if (this.stopped) return { outcome: "stopped" };
|
|
12516
|
+
return this.pendingFollowUp ?? { outcome: "stopped" };
|
|
12517
|
+
});
|
|
12284
12518
|
}
|
|
12285
12519
|
return this.inFlight;
|
|
12286
12520
|
}
|
|
@@ -12297,6 +12531,8 @@ var AutoIndexCoordinator = class {
|
|
|
12297
12531
|
}
|
|
12298
12532
|
async stop(waitForCompletion = false) {
|
|
12299
12533
|
this.stopped = true;
|
|
12534
|
+
this.batteryDeferredRequest = null;
|
|
12535
|
+
this.cancelBatteryRetry();
|
|
12300
12536
|
this.pendingRequest = null;
|
|
12301
12537
|
this.abortController?.abort();
|
|
12302
12538
|
this.setState("stopped", {
|
|
@@ -12326,10 +12562,20 @@ var AutoIndexCoordinator = class {
|
|
|
12326
12562
|
this.inFlight = null;
|
|
12327
12563
|
this.activeRequest = null;
|
|
12328
12564
|
this.abortController = null;
|
|
12565
|
+
if (this.batteryIndexJob === job) {
|
|
12566
|
+
this.batteryIndexJob = null;
|
|
12567
|
+
this.batteryCheck = null;
|
|
12568
|
+
}
|
|
12329
12569
|
const pending = this.pendingRequest;
|
|
12330
12570
|
this.pendingRequest = null;
|
|
12331
12571
|
if (pending && !this.stopped) {
|
|
12332
|
-
this.
|
|
12572
|
+
const followUp = this.request(pending);
|
|
12573
|
+
this.pendingFollowUp = followUp;
|
|
12574
|
+
void followUp.then(() => {
|
|
12575
|
+
if (this.pendingFollowUp === followUp) {
|
|
12576
|
+
this.pendingFollowUp = null;
|
|
12577
|
+
}
|
|
12578
|
+
});
|
|
12333
12579
|
}
|
|
12334
12580
|
});
|
|
12335
12581
|
return job;
|
|
@@ -12493,6 +12739,68 @@ var AutoIndexCoordinator = class {
|
|
|
12493
12739
|
}
|
|
12494
12740
|
return this.registration.safeToRun && this.registration.config.indexing.autoIndex;
|
|
12495
12741
|
}
|
|
12742
|
+
shouldDeferForBattery(request) {
|
|
12743
|
+
return this.registration.backgroundIndexingPolicy !== null && (request.source === "startup" || request.source === "watcher");
|
|
12744
|
+
}
|
|
12745
|
+
async waitForACPower() {
|
|
12746
|
+
while (!this.stopped) {
|
|
12747
|
+
const policy = this.registration.backgroundIndexingPolicy;
|
|
12748
|
+
if (!policy || !await this.isBatteryPauseActive(policy)) {
|
|
12749
|
+
const request = this.batteryDeferredRequest;
|
|
12750
|
+
this.batteryDeferredRequest = null;
|
|
12751
|
+
if (!request) return { outcome: "stopped" };
|
|
12752
|
+
const job = this.enqueueRequest(request);
|
|
12753
|
+
if (this.inFlight === job) {
|
|
12754
|
+
this.batteryIndexJob = job;
|
|
12755
|
+
}
|
|
12756
|
+
return job;
|
|
12757
|
+
}
|
|
12758
|
+
await this.waitForBatteryRetry(policy.recheckDelayMs);
|
|
12759
|
+
}
|
|
12760
|
+
return { outcome: "stopped" };
|
|
12761
|
+
}
|
|
12762
|
+
async isBatteryPauseActive(policy) {
|
|
12763
|
+
try {
|
|
12764
|
+
return await policy.isPaused();
|
|
12765
|
+
} catch (error) {
|
|
12766
|
+
console.error(
|
|
12767
|
+
`[codebase-index] Failed to apply the background indexing power policy; background indexing will continue: ${safeFailureMessage(error)}`
|
|
12768
|
+
);
|
|
12769
|
+
return false;
|
|
12770
|
+
}
|
|
12771
|
+
}
|
|
12772
|
+
waitForBatteryRetry(delayMs) {
|
|
12773
|
+
return new Promise((resolve12) => {
|
|
12774
|
+
const timer = setTimeout(() => {
|
|
12775
|
+
if (this.batteryRetryTimer === timer) {
|
|
12776
|
+
this.batteryRetryTimer = null;
|
|
12777
|
+
this.resolveBatteryRetry = null;
|
|
12778
|
+
}
|
|
12779
|
+
resolve12();
|
|
12780
|
+
}, delayMs);
|
|
12781
|
+
timer.unref?.();
|
|
12782
|
+
this.batteryRetryTimer = timer;
|
|
12783
|
+
this.resolveBatteryRetry = resolve12;
|
|
12784
|
+
});
|
|
12785
|
+
}
|
|
12786
|
+
cancelBatteryRetry() {
|
|
12787
|
+
if (this.batteryRetryTimer) {
|
|
12788
|
+
clearTimeout(this.batteryRetryTimer);
|
|
12789
|
+
this.batteryRetryTimer = null;
|
|
12790
|
+
}
|
|
12791
|
+
const resolve12 = this.resolveBatteryRetry;
|
|
12792
|
+
this.resolveBatteryRetry = null;
|
|
12793
|
+
resolve12?.();
|
|
12794
|
+
}
|
|
12795
|
+
finishBatteryCheck(batteryCheck) {
|
|
12796
|
+
if (this.batteryCheck !== batteryCheck) return;
|
|
12797
|
+
this.batteryCheck = null;
|
|
12798
|
+
const deferredRequest = this.batteryDeferredRequest;
|
|
12799
|
+
this.batteryDeferredRequest = null;
|
|
12800
|
+
if (deferredRequest && !this.stopped) {
|
|
12801
|
+
void this.request(deferredRequest);
|
|
12802
|
+
}
|
|
12803
|
+
}
|
|
12496
12804
|
};
|
|
12497
12805
|
function getCoordinator(projectRoot3, host) {
|
|
12498
12806
|
const key = coordinatorKeysByProject.get(projectLookupKey(projectRoot3, host));
|
|
@@ -12502,6 +12810,9 @@ function configureAutoIndex(projectRoot3, host, config, getIndexer) {
|
|
|
12502
12810
|
const projectKey = projectLookupKey(projectRoot3, host);
|
|
12503
12811
|
const safety = getProjectSafety(projectRoot3, config);
|
|
12504
12812
|
const registration = {
|
|
12813
|
+
backgroundIndexingPolicy: createBackgroundIndexingPolicy(
|
|
12814
|
+
config.indexing.pauseBackgroundIndexingOnBattery
|
|
12815
|
+
),
|
|
12505
12816
|
config,
|
|
12506
12817
|
getIndexer,
|
|
12507
12818
|
projectRoot: projectRoot3,
|
|
@@ -13849,6 +14160,7 @@ Explicit symbol lookup only; conceptual search was not attempted.`
|
|
|
13849
14160
|
const results = await tryConceptualSearch(attempt.queryText, attempt.scope, attempt.relaxed);
|
|
13850
14161
|
if (results.length > 0) {
|
|
13851
14162
|
const heading = buildPackHeading("conceptual", decisions);
|
|
14163
|
+
const intent = analyzeQueryIntent(attempt.queryText);
|
|
13852
14164
|
return toResult(
|
|
13853
14165
|
"conceptual",
|
|
13854
14166
|
attempt.queryText,
|
|
@@ -13856,7 +14168,8 @@ Explicit symbol lookup only; conceptual search was not attempted.`
|
|
|
13856
14168
|
tokenBudget,
|
|
13857
14169
|
maxResults: limit,
|
|
13858
14170
|
heading,
|
|
13859
|
-
includeExactSearchHandoff: true
|
|
14171
|
+
includeExactSearchHandoff: true,
|
|
14172
|
+
preferImplementationPaths: intent.preferSourcePaths || intent.primary !== "docs" && intent.primary !== "test"
|
|
13860
14173
|
})
|
|
13861
14174
|
);
|
|
13862
14175
|
}
|