opencode-codebase-index 0.24.0 → 0.25.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 +10 -0
- package/dist/cbi.cjs +14792 -0
- package/dist/cbi.cjs.map +1 -0
- package/dist/cbi.js +14786 -0
- package/dist/cbi.js.map +1 -0
- package/dist/cli.cjs +101 -3
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +101 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +97 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +97 -3
- package/dist/index.js.map +1 -1
- package/dist/pi-extension.cjs +93 -1
- package/dist/pi-extension.cjs.map +1 -1
- package/dist/pi-extension.js +93 -1
- 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.win32-x64-msvc.node +0 -0
- package/package.json +3 -2
package/dist/pi-extension.js
CHANGED
|
@@ -2043,6 +2043,26 @@ function formatCostEstimate(estimate) {
|
|
|
2043
2043
|
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
2044
2044
|
`;
|
|
2045
2045
|
}
|
|
2046
|
+
function formatDryRunEstimate(estimate) {
|
|
2047
|
+
return `Dry run: parsed the file set to measure the embedding workload. No embedding requests were made and the index was not changed.
|
|
2048
|
+
|
|
2049
|
+
Files to embed: ${estimate.filesCount.toLocaleString()}
|
|
2050
|
+
Chunks to embed: ${estimate.chunksCount.toLocaleString()}
|
|
2051
|
+
Tokens to embed: ${estimate.tokensToEmbed.toLocaleString()}
|
|
2052
|
+
|
|
2053
|
+
The "Tokens to embed" value uses the local estimateTokens(text) = ceil(len/4). It
|
|
2054
|
+
matches the live "Tokens used" counter only for providers that report usage on the
|
|
2055
|
+
same basis (ollama); for providers that report a server tokenizer count (OpenAI,
|
|
2056
|
+
Gemini, custom) it is only an estimate.
|
|
2057
|
+
|
|
2058
|
+
For a matching provider and a project-scoped force index, the force pass clears its
|
|
2059
|
+
own cached embeddings, so the live counter climbs to this number. A force index on a
|
|
2060
|
+
shared global index can reuse cached embeddings from other projects, and an
|
|
2061
|
+
incremental index counts cached chunks that are not re-embedded; in both cases this
|
|
2062
|
+
number is an upper bound on the live counter, so a progress percent against this
|
|
2063
|
+
total tops out below 100%.
|
|
2064
|
+
`;
|
|
2065
|
+
}
|
|
2046
2066
|
function formatBytes(bytes) {
|
|
2047
2067
|
if (bytes === 0) return "0 B";
|
|
2048
2068
|
const k = 1024;
|
|
@@ -8881,6 +8901,9 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
|
8881
8901
|
"enum_declaration",
|
|
8882
8902
|
"function_definition",
|
|
8883
8903
|
"class_definition",
|
|
8904
|
+
// Ruby module/class symbols that are declaration-bearing and navigable.
|
|
8905
|
+
"class",
|
|
8906
|
+
"module",
|
|
8884
8907
|
"class_specifier",
|
|
8885
8908
|
"struct_specifier",
|
|
8886
8909
|
"namespace_definition",
|
|
@@ -12481,6 +12504,70 @@ var Indexer = class _Indexer {
|
|
|
12481
12504
|
);
|
|
12482
12505
|
return createCostEstimate(files, configuredProviderInfo);
|
|
12483
12506
|
}
|
|
12507
|
+
// Dry-run counterpart to index()/forceIndex(): parse the real file set and sum
|
|
12508
|
+
// estimateTokens over the embedding text of every indexable chunk, without
|
|
12509
|
+
// calling the embedding provider or writing to the index. Read-only and
|
|
12510
|
+
// lock-free (mirrors estimateCost). The token sum is the exact value "Tokens
|
|
12511
|
+
// used" climbs to for a force index (cache bypassed); for an incremental it is
|
|
12512
|
+
// an upper bound because cached chunks are counted here but not re-embedded.
|
|
12513
|
+
// Used by index_codebase(dryRun:true) to give a stable, monotonic progress
|
|
12514
|
+
// denominator that matches the live "Tokens used" basis.
|
|
12515
|
+
async dryRunCost() {
|
|
12516
|
+
const { configuredProviderInfo } = await this.ensureInitialized();
|
|
12517
|
+
const maxChunkTokens = getSafeEmbeddingChunkTokenLimit(configuredProviderInfo);
|
|
12518
|
+
const includePatterns = [...this.config.include, ...this.config.additionalInclude];
|
|
12519
|
+
const { files } = await collectFiles(
|
|
12520
|
+
this.materializedProjectRoot,
|
|
12521
|
+
includePatterns,
|
|
12522
|
+
this.config.exclude,
|
|
12523
|
+
this.config.indexing.maxFileSize,
|
|
12524
|
+
this.getMaterializedKnowledgeBases(),
|
|
12525
|
+
{ maxDepth: this.config.indexing.maxDepth, maxFilesPerDirectory: this.config.indexing.maxFilesPerDirectory }
|
|
12526
|
+
);
|
|
12527
|
+
let filesCount = 0;
|
|
12528
|
+
let chunksCount = 0;
|
|
12529
|
+
let tokensToEmbed = 0;
|
|
12530
|
+
for (const batch of iterateOrderedFileBatches(files, (f) => f.size, this.fileBatchLimits)) {
|
|
12531
|
+
const loadedFiles = await Promise.all(batch.map(async (f) => {
|
|
12532
|
+
try {
|
|
12533
|
+
return {
|
|
12534
|
+
path: this.toStoredFilePath(f.path),
|
|
12535
|
+
content: await fsPromises3.readFile(f.path, "utf-8")
|
|
12536
|
+
};
|
|
12537
|
+
} catch {
|
|
12538
|
+
return null;
|
|
12539
|
+
}
|
|
12540
|
+
}));
|
|
12541
|
+
const readable = loadedFiles.filter(
|
|
12542
|
+
(f) => f !== null
|
|
12543
|
+
);
|
|
12544
|
+
filesCount += readable.length;
|
|
12545
|
+
const contentByPath = new Map(readable.map((f) => [f.path, f.content]));
|
|
12546
|
+
const parsedFiles = parseFiles(readable, this.config.indexing.linesPerChunk);
|
|
12547
|
+
for (const parsed of parsedFiles) {
|
|
12548
|
+
let chunksToProcess = parsed.chunks;
|
|
12549
|
+
if (this.config.indexing.fallbackToTextOnMaxChunks && chunksToProcess.length > this.config.indexing.maxChunksPerFile) {
|
|
12550
|
+
const content = contentByPath.get(parsed.path);
|
|
12551
|
+
if (content !== void 0) {
|
|
12552
|
+
chunksToProcess = parseFileAsText(parsed.path, content, this.config.indexing.linesPerChunk);
|
|
12553
|
+
}
|
|
12554
|
+
}
|
|
12555
|
+
chunksToProcess = selectIndexableChunks(
|
|
12556
|
+
chunksToProcess,
|
|
12557
|
+
this.config.indexing.maxChunksPerFile,
|
|
12558
|
+
this.config.indexing.semanticOnly
|
|
12559
|
+
);
|
|
12560
|
+
for (const chunk of chunksToProcess) {
|
|
12561
|
+
const texts = createEmbeddingTexts(chunk, parsed.path, maxChunkTokens);
|
|
12562
|
+
chunksCount += 1;
|
|
12563
|
+
for (const text3 of texts) {
|
|
12564
|
+
tokensToEmbed += estimateTokens(text3);
|
|
12565
|
+
}
|
|
12566
|
+
}
|
|
12567
|
+
}
|
|
12568
|
+
}
|
|
12569
|
+
return { filesCount, chunksCount, tokensToEmbed };
|
|
12570
|
+
}
|
|
12484
12571
|
async index(onProgress) {
|
|
12485
12572
|
return this.withIndexMutationLease("index", async (recoveredOwners) => {
|
|
12486
12573
|
return this.indexUnlocked(onProgress, recoveredOwners);
|
|
@@ -15027,6 +15114,9 @@ async function runIndexCodebase(projectRoot3, host, args, onProgress) {
|
|
|
15027
15114
|
if (args.estimateOnly) {
|
|
15028
15115
|
return { kind: "estimate", estimate: await indexer.estimateCost() };
|
|
15029
15116
|
}
|
|
15117
|
+
if (args.dryRun) {
|
|
15118
|
+
return { kind: "dryrun", dryrun: await indexer.dryRunCost() };
|
|
15119
|
+
}
|
|
15030
15120
|
const coordinated = runCoordinatedIndex(root, host, args.force ?? false, (progress) => {
|
|
15031
15121
|
if (onProgress) {
|
|
15032
15122
|
void onProgress(formatProgressTitle(progress), {
|
|
@@ -19103,12 +19193,14 @@ function codebaseIndexPiExtension(pi) {
|
|
|
19103
19193
|
parameters: Type2.Object({
|
|
19104
19194
|
force: Type2.Optional(Type2.Boolean({ default: false })),
|
|
19105
19195
|
estimateOnly: Type2.Optional(Type2.Boolean({ default: false })),
|
|
19196
|
+
dryRun: Type2.Optional(Type2.Boolean({ default: false })),
|
|
19106
19197
|
verbose: Type2.Optional(Type2.Boolean({ default: false }))
|
|
19107
19198
|
}),
|
|
19108
19199
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
19109
19200
|
try {
|
|
19110
19201
|
const result = await runIndexCodebase(projectRoot2(ctx), HOST2, params);
|
|
19111
19202
|
if (result.kind === "estimate") return text2(formatCostEstimate(result.estimate), result.estimate);
|
|
19203
|
+
if (result.kind === "dryrun") return text2(formatDryRunEstimate(result.dryrun), result.dryrun);
|
|
19112
19204
|
if (result.kind === "busy") return text2(result.text, { code: "INDEX_BUSY" });
|
|
19113
19205
|
if (result.kind === "message") return text2(result.text);
|
|
19114
19206
|
return text2(formatIndexStats(result.stats, params.verbose ?? false), result.stats);
|
|
@@ -19178,7 +19270,7 @@ function codebaseIndexPiExtension(pi) {
|
|
|
19178
19270
|
return {
|
|
19179
19271
|
systemPrompt: `${event.systemPrompt}
|
|
19180
19272
|
|
|
19181
|
-
Check index_status first when index readiness is unknown. Use codebase_context only when repository orientation is needed (for layout, key symbols, or cross-file dependency intent), not mechanically for every task. When using codebase_context for orientation, request a compact first pass (for example: tokenBudget: 600, limit: 5) and inspect returned evidence before broad search/grep/bash/read-style reads. Avoid repeating broad reads when the compact evidence already answers the question. Use implementation_lookup for known symbols and call_graph/call_graph_path after endpoints are identified for dependency flow.`
|
|
19273
|
+
Check index_status first when index readiness is unknown. Use codebase_context only when repository orientation is needed (for layout, key symbols, or cross-file dependency intent), not mechanically for every task. When using codebase_context for orientation, request a compact first pass (for example: tokenBudget: 600, limit: 5) and inspect returned evidence before broad search/grep/bash/read-style reads. For change requests with a known or strongly suspected target symbol, optionally use codebase_edit_context as a compact, bounded pre-edit context for source plus direct callers and callees. Avoid repeating broad reads when the compact evidence already answers the question. Use implementation_lookup for known symbols and call_graph/call_graph_path after endpoints are identified for dependency flow.`
|
|
19182
19274
|
};
|
|
19183
19275
|
});
|
|
19184
19276
|
pi.on("session_shutdown", async (_event, ctx) => {
|