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