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.cjs
CHANGED
|
@@ -2055,6 +2055,26 @@ function formatCostEstimate(estimate) {
|
|
|
2055
2055
|
\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
|
|
2056
2056
|
`;
|
|
2057
2057
|
}
|
|
2058
|
+
function formatDryRunEstimate(estimate) {
|
|
2059
|
+
return `Dry run: parsed the file set to measure the embedding workload. No embedding requests were made and the index was not changed.
|
|
2060
|
+
|
|
2061
|
+
Files to embed: ${estimate.filesCount.toLocaleString()}
|
|
2062
|
+
Chunks to embed: ${estimate.chunksCount.toLocaleString()}
|
|
2063
|
+
Tokens to embed: ${estimate.tokensToEmbed.toLocaleString()}
|
|
2064
|
+
|
|
2065
|
+
The "Tokens to embed" value uses the local estimateTokens(text) = ceil(len/4). It
|
|
2066
|
+
matches the live "Tokens used" counter only for providers that report usage on the
|
|
2067
|
+
same basis (ollama); for providers that report a server tokenizer count (OpenAI,
|
|
2068
|
+
Gemini, custom) it is only an estimate.
|
|
2069
|
+
|
|
2070
|
+
For a matching provider and a project-scoped force index, the force pass clears its
|
|
2071
|
+
own cached embeddings, so the live counter climbs to this number. A force index on a
|
|
2072
|
+
shared global index can reuse cached embeddings from other projects, and an
|
|
2073
|
+
incremental index counts cached chunks that are not re-embedded; in both cases this
|
|
2074
|
+
number is an upper bound on the live counter, so a progress percent against this
|
|
2075
|
+
total tops out below 100%.
|
|
2076
|
+
`;
|
|
2077
|
+
}
|
|
2058
2078
|
function formatBytes(bytes) {
|
|
2059
2079
|
if (bytes === 0) return "0 B";
|
|
2060
2080
|
const k = 1024;
|
|
@@ -8884,6 +8904,9 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
|
8884
8904
|
"enum_declaration",
|
|
8885
8905
|
"function_definition",
|
|
8886
8906
|
"class_definition",
|
|
8907
|
+
// Ruby module/class symbols that are declaration-bearing and navigable.
|
|
8908
|
+
"class",
|
|
8909
|
+
"module",
|
|
8887
8910
|
"class_specifier",
|
|
8888
8911
|
"struct_specifier",
|
|
8889
8912
|
"namespace_definition",
|
|
@@ -12484,6 +12507,70 @@ var Indexer = class _Indexer {
|
|
|
12484
12507
|
);
|
|
12485
12508
|
return createCostEstimate(files, configuredProviderInfo);
|
|
12486
12509
|
}
|
|
12510
|
+
// Dry-run counterpart to index()/forceIndex(): parse the real file set and sum
|
|
12511
|
+
// estimateTokens over the embedding text of every indexable chunk, without
|
|
12512
|
+
// calling the embedding provider or writing to the index. Read-only and
|
|
12513
|
+
// lock-free (mirrors estimateCost). The token sum is the exact value "Tokens
|
|
12514
|
+
// used" climbs to for a force index (cache bypassed); for an incremental it is
|
|
12515
|
+
// an upper bound because cached chunks are counted here but not re-embedded.
|
|
12516
|
+
// Used by index_codebase(dryRun:true) to give a stable, monotonic progress
|
|
12517
|
+
// denominator that matches the live "Tokens used" basis.
|
|
12518
|
+
async dryRunCost() {
|
|
12519
|
+
const { configuredProviderInfo } = await this.ensureInitialized();
|
|
12520
|
+
const maxChunkTokens = getSafeEmbeddingChunkTokenLimit(configuredProviderInfo);
|
|
12521
|
+
const includePatterns = [...this.config.include, ...this.config.additionalInclude];
|
|
12522
|
+
const { files } = await collectFiles(
|
|
12523
|
+
this.materializedProjectRoot,
|
|
12524
|
+
includePatterns,
|
|
12525
|
+
this.config.exclude,
|
|
12526
|
+
this.config.indexing.maxFileSize,
|
|
12527
|
+
this.getMaterializedKnowledgeBases(),
|
|
12528
|
+
{ maxDepth: this.config.indexing.maxDepth, maxFilesPerDirectory: this.config.indexing.maxFilesPerDirectory }
|
|
12529
|
+
);
|
|
12530
|
+
let filesCount = 0;
|
|
12531
|
+
let chunksCount = 0;
|
|
12532
|
+
let tokensToEmbed = 0;
|
|
12533
|
+
for (const batch of iterateOrderedFileBatches(files, (f) => f.size, this.fileBatchLimits)) {
|
|
12534
|
+
const loadedFiles = await Promise.all(batch.map(async (f) => {
|
|
12535
|
+
try {
|
|
12536
|
+
return {
|
|
12537
|
+
path: this.toStoredFilePath(f.path),
|
|
12538
|
+
content: await import_fs12.promises.readFile(f.path, "utf-8")
|
|
12539
|
+
};
|
|
12540
|
+
} catch {
|
|
12541
|
+
return null;
|
|
12542
|
+
}
|
|
12543
|
+
}));
|
|
12544
|
+
const readable = loadedFiles.filter(
|
|
12545
|
+
(f) => f !== null
|
|
12546
|
+
);
|
|
12547
|
+
filesCount += readable.length;
|
|
12548
|
+
const contentByPath = new Map(readable.map((f) => [f.path, f.content]));
|
|
12549
|
+
const parsedFiles = parseFiles(readable, this.config.indexing.linesPerChunk);
|
|
12550
|
+
for (const parsed of parsedFiles) {
|
|
12551
|
+
let chunksToProcess = parsed.chunks;
|
|
12552
|
+
if (this.config.indexing.fallbackToTextOnMaxChunks && chunksToProcess.length > this.config.indexing.maxChunksPerFile) {
|
|
12553
|
+
const content = contentByPath.get(parsed.path);
|
|
12554
|
+
if (content !== void 0) {
|
|
12555
|
+
chunksToProcess = parseFileAsText(parsed.path, content, this.config.indexing.linesPerChunk);
|
|
12556
|
+
}
|
|
12557
|
+
}
|
|
12558
|
+
chunksToProcess = selectIndexableChunks(
|
|
12559
|
+
chunksToProcess,
|
|
12560
|
+
this.config.indexing.maxChunksPerFile,
|
|
12561
|
+
this.config.indexing.semanticOnly
|
|
12562
|
+
);
|
|
12563
|
+
for (const chunk of chunksToProcess) {
|
|
12564
|
+
const texts = createEmbeddingTexts(chunk, parsed.path, maxChunkTokens);
|
|
12565
|
+
chunksCount += 1;
|
|
12566
|
+
for (const text3 of texts) {
|
|
12567
|
+
tokensToEmbed += estimateTokens(text3);
|
|
12568
|
+
}
|
|
12569
|
+
}
|
|
12570
|
+
}
|
|
12571
|
+
}
|
|
12572
|
+
return { filesCount, chunksCount, tokensToEmbed };
|
|
12573
|
+
}
|
|
12487
12574
|
async index(onProgress) {
|
|
12488
12575
|
return this.withIndexMutationLease("index", async (recoveredOwners) => {
|
|
12489
12576
|
return this.indexUnlocked(onProgress, recoveredOwners);
|
|
@@ -15030,6 +15117,9 @@ async function runIndexCodebase(projectRoot3, host, args, onProgress) {
|
|
|
15030
15117
|
if (args.estimateOnly) {
|
|
15031
15118
|
return { kind: "estimate", estimate: await indexer.estimateCost() };
|
|
15032
15119
|
}
|
|
15120
|
+
if (args.dryRun) {
|
|
15121
|
+
return { kind: "dryrun", dryrun: await indexer.dryRunCost() };
|
|
15122
|
+
}
|
|
15033
15123
|
const coordinated = runCoordinatedIndex(root, host, args.force ?? false, (progress) => {
|
|
15034
15124
|
if (onProgress) {
|
|
15035
15125
|
void onProgress(formatProgressTitle(progress), {
|
|
@@ -19106,12 +19196,14 @@ function codebaseIndexPiExtension(pi) {
|
|
|
19106
19196
|
parameters: import_typebox2.Type.Object({
|
|
19107
19197
|
force: import_typebox2.Type.Optional(import_typebox2.Type.Boolean({ default: false })),
|
|
19108
19198
|
estimateOnly: import_typebox2.Type.Optional(import_typebox2.Type.Boolean({ default: false })),
|
|
19199
|
+
dryRun: import_typebox2.Type.Optional(import_typebox2.Type.Boolean({ default: false })),
|
|
19109
19200
|
verbose: import_typebox2.Type.Optional(import_typebox2.Type.Boolean({ default: false }))
|
|
19110
19201
|
}),
|
|
19111
19202
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
19112
19203
|
try {
|
|
19113
19204
|
const result = await runIndexCodebase(projectRoot2(ctx), HOST2, params);
|
|
19114
19205
|
if (result.kind === "estimate") return text2(formatCostEstimate(result.estimate), result.estimate);
|
|
19206
|
+
if (result.kind === "dryrun") return text2(formatDryRunEstimate(result.dryrun), result.dryrun);
|
|
19115
19207
|
if (result.kind === "busy") return text2(result.text, { code: "INDEX_BUSY" });
|
|
19116
19208
|
if (result.kind === "message") return text2(result.text);
|
|
19117
19209
|
return text2(formatIndexStats(result.stats, params.verbose ?? false), result.stats);
|
|
@@ -19181,7 +19273,7 @@ function codebaseIndexPiExtension(pi) {
|
|
|
19181
19273
|
return {
|
|
19182
19274
|
systemPrompt: `${event.systemPrompt}
|
|
19183
19275
|
|
|
19184
|
-
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.`
|
|
19276
|
+
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.`
|
|
19185
19277
|
};
|
|
19186
19278
|
});
|
|
19187
19279
|
pi.on("session_shutdown", async (_event, ctx) => {
|