opencode-codebase-index 0.22.3 → 0.22.4
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/dist/cli.cjs +647 -94
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +647 -94
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +421 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +421 -55
- package/dist/index.js.map +1 -1
- package/dist/pi-extension.cjs +401 -48
- package/dist/pi-extension.cjs.map +1 -1
- package/dist/pi-extension.js +401 -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 +13 -9
package/dist/pi-extension.cjs
CHANGED
|
@@ -2053,6 +2053,9 @@ function findKnowledgeBasePathIndex(knowledgeBases, inputPath, projectRoot3) {
|
|
|
2053
2053
|
}
|
|
2054
2054
|
|
|
2055
2055
|
// src/tools/contracts.ts
|
|
2056
|
+
var MIN_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT = 1;
|
|
2057
|
+
var MAX_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT = 20;
|
|
2058
|
+
var DEFAULT_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT = 5;
|
|
2056
2059
|
var CODE_COMMUNITIES_MIN_SIZE = 1;
|
|
2057
2060
|
var CODE_COMMUNITIES_DEFAULT_LIMIT = 20;
|
|
2058
2061
|
var CODE_COMMUNITIES_MAX_LIMIT = 100;
|
|
@@ -2676,6 +2679,16 @@ function compactEvidenceValue(value, maxChars) {
|
|
|
2676
2679
|
}
|
|
2677
2680
|
var MAX_EXACT_SEARCH_HANDOFF_NAMES = 3;
|
|
2678
2681
|
var MAX_EXACT_SEARCH_HANDOFF_NAME_CHARS = 64;
|
|
2682
|
+
function toContextPackTraceCandidate(result) {
|
|
2683
|
+
return {
|
|
2684
|
+
filePath: result.filePath,
|
|
2685
|
+
startLine: result.startLine,
|
|
2686
|
+
endLine: result.endLine,
|
|
2687
|
+
score: result.score,
|
|
2688
|
+
chunkType: result.chunkType,
|
|
2689
|
+
name: result.name
|
|
2690
|
+
};
|
|
2691
|
+
}
|
|
2679
2692
|
function formatExactSearchHandoff(results) {
|
|
2680
2693
|
const suggestedNames = [];
|
|
2681
2694
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -2724,13 +2737,13 @@ function buildContextPack(results, options = {}) {
|
|
|
2724
2737
|
const maxResults = Math.max(0, Math.floor(options.maxResults ?? results.length));
|
|
2725
2738
|
const includeExactSearchHandoff = options.includeExactSearchHandoff ?? false;
|
|
2726
2739
|
const candidateCount = results.length;
|
|
2727
|
-
const
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
);
|
|
2733
|
-
const
|
|
2740
|
+
const preserveInputOrder = options.preserveInputOrder ?? false;
|
|
2741
|
+
const ranked = preserveInputOrder ? results.map((result, originalIndex) => ({ result, originalIndex })) : rankContextCandidates(results, options.preferImplementationPaths ?? false);
|
|
2742
|
+
const rankedCandidates = ranked.map((entry) => toContextPackTraceCandidate(entry.result));
|
|
2743
|
+
const deduplicated = deduplicateContextCandidates(ranked);
|
|
2744
|
+
const deduplicatedCandidates = deduplicated.map((result) => toContextPackTraceCandidate(result));
|
|
2745
|
+
const diversified = preserveInputOrder ? deduplicated : diversifyContextCandidates(deduplicated);
|
|
2746
|
+
const diversifiedCandidates = diversified.map((result) => toContextPackTraceCandidate(result));
|
|
2734
2747
|
const duplicateCount = candidateCount - deduplicated.length;
|
|
2735
2748
|
const selectable = diversified.slice(0, maxResults);
|
|
2736
2749
|
const limitOmittedCount = deduplicated.length - selectable.length;
|
|
@@ -2763,6 +2776,15 @@ function buildContextPack(results, options = {}) {
|
|
|
2763
2776
|
const fitted = fitTextToContextBudget(text3, tokenBudget);
|
|
2764
2777
|
const budgetOmittedCount = selectable.length - selected.length;
|
|
2765
2778
|
const omittedCount = candidateCount - selected.length;
|
|
2779
|
+
if (options.trace) {
|
|
2780
|
+
options.trace({
|
|
2781
|
+
inputCandidates: results.map(toContextPackTraceCandidate),
|
|
2782
|
+
rankedCandidates,
|
|
2783
|
+
deduplicatedCandidates,
|
|
2784
|
+
diversifiedCandidates,
|
|
2785
|
+
selectedCandidates: selected.map(toContextPackTraceCandidate)
|
|
2786
|
+
});
|
|
2787
|
+
}
|
|
2766
2788
|
return {
|
|
2767
2789
|
requestedTokenBudget,
|
|
2768
2790
|
tokenBudget,
|
|
@@ -8578,12 +8600,12 @@ function diversifyGroupBySymbol(entries, getCandidate) {
|
|
|
8578
8600
|
return [...primary, ...remainder];
|
|
8579
8601
|
}
|
|
8580
8602
|
function buildDiversityKey(metadata) {
|
|
8581
|
-
const
|
|
8603
|
+
const normalizedPath2 = metadata.filePath.toLowerCase();
|
|
8582
8604
|
const normalizedName = (metadata.name ?? "").trim().toLowerCase();
|
|
8583
8605
|
if (normalizedName.length > 0) {
|
|
8584
|
-
return `${
|
|
8606
|
+
return `${normalizedPath2}#${normalizedName}`;
|
|
8585
8607
|
}
|
|
8586
|
-
return
|
|
8608
|
+
return normalizedPath2;
|
|
8587
8609
|
}
|
|
8588
8610
|
function rankHybridResults(query, semanticResults, keywordResults, options) {
|
|
8589
8611
|
const prioritizeSourcePaths = options.prioritizeSourcePaths ?? classifyQueryIntentRaw(query) === "source";
|
|
@@ -9032,9 +9054,9 @@ function normalizeFilePathForHintMatch(filePath) {
|
|
|
9032
9054
|
return filePath.replace(/\\/g, "/").toLowerCase().replace(/^\.\//, "");
|
|
9033
9055
|
}
|
|
9034
9056
|
function pathMatchesHint(filePath, hint) {
|
|
9035
|
-
const
|
|
9057
|
+
const normalizedPath2 = normalizeFilePathForHintMatch(filePath);
|
|
9036
9058
|
const normalizedHint = normalizeFilePathForHintMatch(hint);
|
|
9037
|
-
return
|
|
9059
|
+
return normalizedPath2.endsWith(normalizedHint) || normalizedPath2.includes(`/${normalizedHint}`) || normalizedPath2.includes(normalizedHint);
|
|
9038
9060
|
}
|
|
9039
9061
|
function extractFilePathHint(query) {
|
|
9040
9062
|
const match = query.match(FILE_PATH_HINT_SUFFIX_REGEX);
|
|
@@ -12907,6 +12929,20 @@ var Indexer = class _Indexer {
|
|
|
12907
12929
|
requestedLimit = nextLimit;
|
|
12908
12930
|
}
|
|
12909
12931
|
}
|
|
12932
|
+
buildCandidateSnapshot(candidate) {
|
|
12933
|
+
return {
|
|
12934
|
+
id: candidate.id,
|
|
12935
|
+
filePath: candidate.metadata.filePath,
|
|
12936
|
+
startLine: candidate.metadata.startLine,
|
|
12937
|
+
endLine: candidate.metadata.endLine,
|
|
12938
|
+
score: candidate.score,
|
|
12939
|
+
chunkType: candidate.metadata.chunkType,
|
|
12940
|
+
name: candidate.metadata.name
|
|
12941
|
+
};
|
|
12942
|
+
}
|
|
12943
|
+
buildCandidateSnapshotList(candidates) {
|
|
12944
|
+
return candidates.map((candidate) => this.buildCandidateSnapshot(candidate));
|
|
12945
|
+
}
|
|
12910
12946
|
searchSemanticCandidates(store, embedding, initialLimit, branchChunkIds, shouldPrefilterByBranch) {
|
|
12911
12947
|
return this.searchCandidatesWithBranchPrefilter(
|
|
12912
12948
|
initialLimit,
|
|
@@ -13098,6 +13134,16 @@ var Indexer = class _Indexer {
|
|
|
13098
13134
|
prefilterMs: Math.round(prefilterMs * 100) / 100,
|
|
13099
13135
|
fusionMs: Math.round(fusionMs * 100) / 100
|
|
13100
13136
|
});
|
|
13137
|
+
if (options?.trace) {
|
|
13138
|
+
options.trace({
|
|
13139
|
+
semanticCandidates: this.buildCandidateSnapshotList(scopedSemanticCandidates),
|
|
13140
|
+
keywordCandidates: this.buildCandidateSnapshotList(scopedKeywordCandidates),
|
|
13141
|
+
hybridCandidates: this.buildCandidateSnapshotList(combined),
|
|
13142
|
+
postExternalRerankCandidates: this.buildCandidateSnapshotList(rerankedCombined),
|
|
13143
|
+
tieredCandidates: this.buildCandidateSnapshotList(tiered),
|
|
13144
|
+
finalCandidates: this.buildCandidateSnapshotList(finalResults)
|
|
13145
|
+
});
|
|
13146
|
+
}
|
|
13101
13147
|
const metadataOnly = options?.metadataOnly ?? false;
|
|
13102
13148
|
return Promise.all(
|
|
13103
13149
|
finalResults.map(async (r) => {
|
|
@@ -14358,7 +14404,8 @@ async function searchCodebase(projectRoot3, host, query, options = {}) {
|
|
|
14358
14404
|
definitionIntent: options.definitionIntent,
|
|
14359
14405
|
blameAuthor: options.blameAuthor,
|
|
14360
14406
|
blameSha: options.blameSha,
|
|
14361
|
-
blameSince: options.blameSince
|
|
14407
|
+
blameSince: options.blameSince,
|
|
14408
|
+
trace: options.trace
|
|
14362
14409
|
});
|
|
14363
14410
|
}
|
|
14364
14411
|
async function searchCodebaseWithEffectiveness(projectRoot3, host, route, query, options, render) {
|
|
@@ -14412,15 +14459,19 @@ async function implementationLookup(projectRoot3, host, query, options = {}) {
|
|
|
14412
14459
|
return indexer.search(query, options.limit, {
|
|
14413
14460
|
fileType: options.fileType,
|
|
14414
14461
|
directory: options.directory,
|
|
14415
|
-
definitionIntent: true
|
|
14462
|
+
definitionIntent: true,
|
|
14463
|
+
trace: options.trace
|
|
14416
14464
|
});
|
|
14417
14465
|
}
|
|
14418
14466
|
async function getCallGraphData(projectRoot3, host, params) {
|
|
14419
14467
|
await ensureAutoIndexReadyForRetrieval(projectRoot3, host);
|
|
14420
14468
|
const root = getProjectRoot(projectRoot3, host);
|
|
14421
14469
|
const indexer = getIndexerForProject(root, host);
|
|
14470
|
+
return getCallGraphDataForIndexer(indexer, root, params);
|
|
14471
|
+
}
|
|
14472
|
+
async function getCallGraphDataForIndexer(indexer, projectRoot3, params) {
|
|
14422
14473
|
const symbols = await indexer.getCallGraphSymbols();
|
|
14423
|
-
const resolution = resolveCallGraphSymbol(symbols,
|
|
14474
|
+
const resolution = resolveCallGraphSymbol(symbols, projectRoot3, params.name, params.filePath, params.symbolId);
|
|
14424
14475
|
const direction = params.direction === "callees" ? "callees" : "callers";
|
|
14425
14476
|
if (resolution.status !== "resolved") {
|
|
14426
14477
|
return { direction, resolution, callers: [], callees: [], relationshipType: params.relationshipType };
|
|
@@ -14648,17 +14699,17 @@ async function getIndexLogs(projectRoot3, host, args) {
|
|
|
14648
14699
|
function addKnowledgeBase(projectRoot3, host, knowledgeBasePath) {
|
|
14649
14700
|
const root = getProjectRoot(projectRoot3, host);
|
|
14650
14701
|
const inputPath = knowledgeBasePath.trim();
|
|
14651
|
-
const
|
|
14702
|
+
const normalizedPath2 = path20.resolve(
|
|
14652
14703
|
path20.isAbsolute(inputPath) ? inputPath : resolveKnowledgeBasePath(inputPath, root)
|
|
14653
14704
|
);
|
|
14654
|
-
if (!(0, import_fs13.existsSync)(
|
|
14655
|
-
return `Error: Directory does not exist: ${
|
|
14705
|
+
if (!(0, import_fs13.existsSync)(normalizedPath2)) {
|
|
14706
|
+
return `Error: Directory does not exist: ${normalizedPath2}`;
|
|
14656
14707
|
}
|
|
14657
14708
|
let realPath;
|
|
14658
14709
|
try {
|
|
14659
|
-
realPath = (0, import_fs13.realpathSync)(
|
|
14710
|
+
realPath = (0, import_fs13.realpathSync)(normalizedPath2);
|
|
14660
14711
|
} catch {
|
|
14661
|
-
return `Error: Cannot resolve path: ${
|
|
14712
|
+
return `Error: Cannot resolve path: ${normalizedPath2}`;
|
|
14662
14713
|
}
|
|
14663
14714
|
const blockedPrefixes = [
|
|
14664
14715
|
"/etc",
|
|
@@ -14681,34 +14732,34 @@ function addKnowledgeBase(projectRoot3, host, knowledgeBasePath) {
|
|
|
14681
14732
|
];
|
|
14682
14733
|
for (const prefix of blockedPrefixes) {
|
|
14683
14734
|
if (realPath === prefix || realPath.startsWith(`${prefix}/`)) {
|
|
14684
|
-
return `Error: Adding sensitive directory as knowledge base is not allowed: ${
|
|
14735
|
+
return `Error: Adding sensitive directory as knowledge base is not allowed: ${normalizedPath2}`;
|
|
14685
14736
|
}
|
|
14686
14737
|
}
|
|
14687
14738
|
for (const dotDir of sensitiveDotDirs) {
|
|
14688
14739
|
const sensitiveDir = path20.join(homeDir, dotDir);
|
|
14689
14740
|
if (sensitiveDir && (realPath === sensitiveDir || realPath.startsWith(`${sensitiveDir}/`))) {
|
|
14690
|
-
return `Error: Adding sensitive directory as knowledge base is not allowed: ${
|
|
14741
|
+
return `Error: Adding sensitive directory as knowledge base is not allowed: ${normalizedPath2}`;
|
|
14691
14742
|
}
|
|
14692
14743
|
}
|
|
14693
14744
|
try {
|
|
14694
|
-
const stat = (0, import_fs13.statSync)(
|
|
14745
|
+
const stat = (0, import_fs13.statSync)(normalizedPath2);
|
|
14695
14746
|
if (!stat.isDirectory()) {
|
|
14696
|
-
return `Error: Path is not a directory: ${
|
|
14747
|
+
return `Error: Path is not a directory: ${normalizedPath2}`;
|
|
14697
14748
|
}
|
|
14698
14749
|
} catch (error) {
|
|
14699
|
-
return `Error: Cannot access directory: ${
|
|
14750
|
+
return `Error: Cannot access directory: ${normalizedPath2} - ${error instanceof Error ? error.message : String(error)}`;
|
|
14700
14751
|
}
|
|
14701
14752
|
const config = loadEditableConfig(root, host);
|
|
14702
14753
|
const knowledgeBases = Array.isArray(config.knowledgeBases) ? config.knowledgeBases : [];
|
|
14703
|
-
const alreadyExists = hasMatchingKnowledgeBasePath(knowledgeBases,
|
|
14754
|
+
const alreadyExists = hasMatchingKnowledgeBasePath(knowledgeBases, normalizedPath2, root);
|
|
14704
14755
|
if (alreadyExists) {
|
|
14705
|
-
return `Knowledge base already configured: ${
|
|
14756
|
+
return `Knowledge base already configured: ${normalizedPath2}`;
|
|
14706
14757
|
}
|
|
14707
|
-
knowledgeBases.push(
|
|
14758
|
+
knowledgeBases.push(normalizedPath2);
|
|
14708
14759
|
config.knowledgeBases = knowledgeBases;
|
|
14709
14760
|
saveConfig(root, config, host);
|
|
14710
14761
|
refreshIndexerForDirectory(root, host);
|
|
14711
|
-
let result = `${
|
|
14762
|
+
let result = `${normalizedPath2}
|
|
14712
14763
|
`;
|
|
14713
14764
|
result += `Total knowledge bases: ${knowledgeBases.length}
|
|
14714
14765
|
`;
|
|
@@ -14883,6 +14934,27 @@ function buildRecoveryDetails(attempts, successIndex) {
|
|
|
14883
14934
|
successfulAttemptIndex: successIndex
|
|
14884
14935
|
};
|
|
14885
14936
|
}
|
|
14937
|
+
function serializeAttempts(attempts) {
|
|
14938
|
+
return attempts.map((attempt) => ({
|
|
14939
|
+
kind: attempt.kind,
|
|
14940
|
+
scope: attempt.scope,
|
|
14941
|
+
resultCount: attempt.resultCount,
|
|
14942
|
+
relaxedFields: attempt.relaxedFields
|
|
14943
|
+
}));
|
|
14944
|
+
}
|
|
14945
|
+
function buildSearchDiagnostic(attempt) {
|
|
14946
|
+
if (!attempt) {
|
|
14947
|
+
return void 0;
|
|
14948
|
+
}
|
|
14949
|
+
return {
|
|
14950
|
+
route: attempt.kind,
|
|
14951
|
+
routedQuery: attempt.query,
|
|
14952
|
+
searchQuery: attempt.query,
|
|
14953
|
+
searchScope: attempt.scopeFilter,
|
|
14954
|
+
searchTrace: attempt.searchTrace,
|
|
14955
|
+
contextPackTrace: attempt.contextPackTrace
|
|
14956
|
+
};
|
|
14957
|
+
}
|
|
14886
14958
|
function trimOrUndefined2(value) {
|
|
14887
14959
|
const normalized = value?.trim();
|
|
14888
14960
|
if (!normalized) {
|
|
@@ -14922,6 +14994,7 @@ async function resolveSearchContext(input, operations) {
|
|
|
14922
14994
|
const hasFilters = Boolean(fileType || directory);
|
|
14923
14995
|
const relaxedFields = relaxedHintFields(fileType, directory);
|
|
14924
14996
|
const attempts = [];
|
|
14997
|
+
const attemptStates = [];
|
|
14925
14998
|
const decisions = {
|
|
14926
14999
|
inferredDefinitionMiss: false,
|
|
14927
15000
|
fallbackFromOriginalConceptualToInferred: false,
|
|
@@ -14950,8 +15023,20 @@ async function resolveSearchContext(input, operations) {
|
|
|
14950
15023
|
if (seenAttempts.has(key)) {
|
|
14951
15024
|
return [];
|
|
14952
15025
|
}
|
|
14953
|
-
const
|
|
15026
|
+
const attemptState = {
|
|
15027
|
+
kind,
|
|
15028
|
+
scope: describeScope(scope.fileType, scope.directory),
|
|
15029
|
+
resultCount: 0,
|
|
15030
|
+
relaxedFields: [...relaxedFieldsForAttempt],
|
|
15031
|
+
query: attemptQuery,
|
|
15032
|
+
scopeFilter: scope
|
|
15033
|
+
};
|
|
15034
|
+
const results = await runAttempt((trace) => {
|
|
15035
|
+
attemptState.searchTrace = trace;
|
|
15036
|
+
});
|
|
15037
|
+
attemptState.resultCount = results.length;
|
|
14954
15038
|
seenAttempts.add(key);
|
|
15039
|
+
attemptStates.push(attemptState);
|
|
14955
15040
|
attempts.push({
|
|
14956
15041
|
kind,
|
|
14957
15042
|
scope: describeScope(scope.fileType, scope.directory),
|
|
@@ -14971,7 +15056,7 @@ async function resolveSearchContext(input, operations) {
|
|
|
14971
15056
|
symbol,
|
|
14972
15057
|
scope,
|
|
14973
15058
|
relaxedFieldsForAttempt,
|
|
14974
|
-
() => operations.lookup(symbol, MAX_CONTEXT_RESULT_LIMIT, scope)
|
|
15059
|
+
(trace) => operations.lookup(symbol, MAX_CONTEXT_RESULT_LIMIT, scope, input.diagnostic ? trace : void 0)
|
|
14975
15060
|
);
|
|
14976
15061
|
};
|
|
14977
15062
|
const tryConceptualSearch = async (searchQuery, scope, relaxedFieldsForAttempt) => {
|
|
@@ -14980,13 +15065,23 @@ async function resolveSearchContext(input, operations) {
|
|
|
14980
15065
|
searchQuery,
|
|
14981
15066
|
scope,
|
|
14982
15067
|
relaxedFieldsForAttempt,
|
|
14983
|
-
() => operations.search(searchQuery, MAX_CONTEXT_RESULT_LIMIT, scope)
|
|
15068
|
+
(trace) => operations.search(searchQuery, MAX_CONTEXT_RESULT_LIMIT, scope, input.diagnostic ? trace : void 0)
|
|
14984
15069
|
);
|
|
14985
15070
|
};
|
|
14986
|
-
const
|
|
15071
|
+
const findSuccessfulAttemptState = (route) => {
|
|
15072
|
+
for (let index = attemptStates.length - 1; index >= 0; index -= 1) {
|
|
15073
|
+
const attempt = attemptStates[index];
|
|
15074
|
+
if (attempt.kind === route && attempt.resultCount > 0) {
|
|
15075
|
+
return attempt;
|
|
15076
|
+
}
|
|
15077
|
+
}
|
|
15078
|
+
return void 0;
|
|
15079
|
+
};
|
|
15080
|
+
const toResult = (route, routedQuery, pack, successfulAttempt) => {
|
|
14987
15081
|
const base = packedResult(route, routedQuery, pack);
|
|
14988
15082
|
const baseDetails = base.details;
|
|
14989
15083
|
const successIndex = findSuccessfulAttemptIndex(route, attempts);
|
|
15084
|
+
const successState = successfulAttempt ?? findSuccessfulAttemptState(route);
|
|
14990
15085
|
return {
|
|
14991
15086
|
text: base.text,
|
|
14992
15087
|
details: {
|
|
@@ -14994,7 +15089,10 @@ async function resolveSearchContext(input, operations) {
|
|
|
14994
15089
|
tokenBudget: baseDetails.tokenBudget,
|
|
14995
15090
|
tokenEstimate: baseDetails.tokenEstimate,
|
|
14996
15091
|
truncated: false,
|
|
14997
|
-
recovery: buildRecoveryDetails(
|
|
15092
|
+
recovery: buildRecoveryDetails(serializeAttempts(attemptStates), successIndex),
|
|
15093
|
+
...input.diagnostic && {
|
|
15094
|
+
diagnostic: buildSearchDiagnostic(successState)
|
|
15095
|
+
}
|
|
14998
15096
|
}
|
|
14999
15097
|
};
|
|
15000
15098
|
};
|
|
@@ -15008,8 +15106,18 @@ async function resolveSearchContext(input, operations) {
|
|
|
15008
15106
|
buildContextPack(scopedDefinitionResults, {
|
|
15009
15107
|
tokenBudget,
|
|
15010
15108
|
maxResults: limit,
|
|
15011
|
-
heading
|
|
15012
|
-
|
|
15109
|
+
heading,
|
|
15110
|
+
preserveInputOrder: true,
|
|
15111
|
+
...input.diagnostic ? {
|
|
15112
|
+
trace: (trace) => {
|
|
15113
|
+
const attemptState = findSuccessfulAttemptState("definition");
|
|
15114
|
+
if (attemptState) {
|
|
15115
|
+
attemptState.contextPackTrace = trace;
|
|
15116
|
+
}
|
|
15117
|
+
}
|
|
15118
|
+
} : void 0
|
|
15119
|
+
}),
|
|
15120
|
+
findSuccessfulAttemptState("definition")
|
|
15013
15121
|
);
|
|
15014
15122
|
}
|
|
15015
15123
|
if (explicitSymbol) {
|
|
@@ -15027,8 +15135,18 @@ async function resolveSearchContext(input, operations) {
|
|
|
15027
15135
|
buildContextPack(unscopedDefinitionResults, {
|
|
15028
15136
|
tokenBudget,
|
|
15029
15137
|
maxResults: limit,
|
|
15030
|
-
heading: heading2
|
|
15031
|
-
|
|
15138
|
+
heading: heading2,
|
|
15139
|
+
preserveInputOrder: true,
|
|
15140
|
+
...input.diagnostic ? {
|
|
15141
|
+
trace: (trace) => {
|
|
15142
|
+
const attemptState = findSuccessfulAttemptState("definition");
|
|
15143
|
+
if (attemptState) {
|
|
15144
|
+
attemptState.contextPackTrace = trace;
|
|
15145
|
+
}
|
|
15146
|
+
}
|
|
15147
|
+
} : void 0
|
|
15148
|
+
}),
|
|
15149
|
+
findSuccessfulAttemptState("definition")
|
|
15032
15150
|
);
|
|
15033
15151
|
}
|
|
15034
15152
|
}
|
|
@@ -15047,7 +15165,10 @@ Explicit symbol lookup only; conceptual search was not attempted.`
|
|
|
15047
15165
|
tokenBudget: heading.tokenBudget,
|
|
15048
15166
|
tokenEstimate: heading.tokenEstimate,
|
|
15049
15167
|
truncated: heading.truncated,
|
|
15050
|
-
recovery: buildRecoveryDetails(
|
|
15168
|
+
recovery: buildRecoveryDetails(serializeAttempts(attemptStates), null),
|
|
15169
|
+
...input.diagnostic && {
|
|
15170
|
+
diagnostic: buildSearchDiagnostic(attemptStates[attemptStates.length - 1])
|
|
15171
|
+
}
|
|
15051
15172
|
}
|
|
15052
15173
|
};
|
|
15053
15174
|
}
|
|
@@ -15087,8 +15208,17 @@ Explicit symbol lookup only; conceptual search was not attempted.`
|
|
|
15087
15208
|
maxResults: limit,
|
|
15088
15209
|
heading,
|
|
15089
15210
|
includeExactSearchHandoff: true,
|
|
15090
|
-
preferImplementationPaths: intent.preferSourcePaths || intent.primary !== "docs" && intent.primary !== "test"
|
|
15091
|
-
|
|
15211
|
+
preferImplementationPaths: intent.preferSourcePaths || intent.primary !== "docs" && intent.primary !== "test",
|
|
15212
|
+
...input.diagnostic ? {
|
|
15213
|
+
trace: (trace) => {
|
|
15214
|
+
const attemptState = findSuccessfulAttemptState("conceptual");
|
|
15215
|
+
if (attemptState) {
|
|
15216
|
+
attemptState.contextPackTrace = trace;
|
|
15217
|
+
}
|
|
15218
|
+
}
|
|
15219
|
+
} : void 0
|
|
15220
|
+
}),
|
|
15221
|
+
findSuccessfulAttemptState("conceptual")
|
|
15092
15222
|
);
|
|
15093
15223
|
}
|
|
15094
15224
|
}
|
|
@@ -15104,7 +15234,10 @@ Explicit symbol lookup only; conceptual search was not attempted.`
|
|
|
15104
15234
|
tokenBudget: fallbackText.tokenBudget,
|
|
15105
15235
|
tokenEstimate: fallbackText.tokenEstimate,
|
|
15106
15236
|
truncated: fallbackText.truncated,
|
|
15107
|
-
recovery: buildRecoveryDetails(
|
|
15237
|
+
recovery: buildRecoveryDetails(serializeAttempts(attemptStates), null),
|
|
15238
|
+
...input.diagnostic && {
|
|
15239
|
+
diagnostic: buildSearchDiagnostic(attemptStates[attemptStates.length - 1])
|
|
15240
|
+
}
|
|
15108
15241
|
}
|
|
15109
15242
|
};
|
|
15110
15243
|
}
|
|
@@ -15185,17 +15318,27 @@ async function resolveCodebaseContextUnmeasured(projectRoot3, host, input) {
|
|
|
15185
15318
|
details: fittedDetails("path", fitted, 0)
|
|
15186
15319
|
};
|
|
15187
15320
|
}
|
|
15188
|
-
return resolveSearchContext({
|
|
15189
|
-
|
|
15321
|
+
return resolveSearchContext({
|
|
15322
|
+
query: input.query,
|
|
15323
|
+
symbol,
|
|
15324
|
+
limit,
|
|
15325
|
+
tokenBudget,
|
|
15326
|
+
fileType,
|
|
15327
|
+
directory,
|
|
15328
|
+
diagnostic: input.diagnostic
|
|
15329
|
+
}, {
|
|
15330
|
+
lookup: (lookupSymbol, retrievalLimit, scope, trace) => implementationLookup(projectRoot3, host, lookupSymbol, {
|
|
15190
15331
|
limit: retrievalLimit,
|
|
15191
15332
|
fileType: scope.fileType,
|
|
15192
|
-
directory: scope.directory
|
|
15333
|
+
directory: scope.directory,
|
|
15334
|
+
trace
|
|
15193
15335
|
}),
|
|
15194
|
-
search: (queryText, retrievalLimit, scope) => searchCodebase(projectRoot3, host, queryText, {
|
|
15336
|
+
search: (queryText, retrievalLimit, scope, trace) => searchCodebase(projectRoot3, host, queryText, {
|
|
15195
15337
|
limit: retrievalLimit,
|
|
15196
15338
|
fileType: scope.fileType,
|
|
15197
15339
|
directory: scope.directory,
|
|
15198
|
-
metadataOnly: true
|
|
15340
|
+
metadataOnly: true,
|
|
15341
|
+
trace
|
|
15199
15342
|
})
|
|
15200
15343
|
});
|
|
15201
15344
|
}
|
|
@@ -15260,12 +15403,188 @@ async function resolveCodebaseContext(projectRoot3, host, input) {
|
|
|
15260
15403
|
}
|
|
15261
15404
|
}
|
|
15262
15405
|
|
|
15406
|
+
// src/tools/edit-context.ts
|
|
15407
|
+
function edgeLimit(value) {
|
|
15408
|
+
if (value === null || value === void 0 || !Number.isFinite(value)) {
|
|
15409
|
+
return DEFAULT_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT;
|
|
15410
|
+
}
|
|
15411
|
+
return Math.min(
|
|
15412
|
+
MAX_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT,
|
|
15413
|
+
Math.max(MIN_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT, Math.floor(value))
|
|
15414
|
+
);
|
|
15415
|
+
}
|
|
15416
|
+
function normalizedPath(value) {
|
|
15417
|
+
return value.replaceAll("\\", "/").replace(/^\.\//, "");
|
|
15418
|
+
}
|
|
15419
|
+
function pathsMatch(left, right) {
|
|
15420
|
+
const normalizedLeft = normalizedPath(left);
|
|
15421
|
+
const normalizedRight = normalizedPath(right);
|
|
15422
|
+
return normalizedLeft === normalizedRight || normalizedLeft.endsWith(`/${normalizedRight}`) || normalizedRight.endsWith(`/${normalizedLeft}`);
|
|
15423
|
+
}
|
|
15424
|
+
function targetSource(results, resolution) {
|
|
15425
|
+
return results.find((result) => pathsMatch(result.filePath, resolution.filePath) && result.startLine <= resolution.startLine && result.endLine >= resolution.startLine) ?? results.find((result) => pathsMatch(result.filePath, resolution.filePath) && result.name === resolution.name);
|
|
15426
|
+
}
|
|
15427
|
+
function formatSource(result) {
|
|
15428
|
+
const name = result.name ? ` ${result.name}` : "";
|
|
15429
|
+
return [
|
|
15430
|
+
"## Target implementation",
|
|
15431
|
+
`${result.filePath}:${result.startLine}-${result.endLine} (${result.chunkType}${name})`,
|
|
15432
|
+
"```",
|
|
15433
|
+
result.content,
|
|
15434
|
+
"```"
|
|
15435
|
+
].join("\n");
|
|
15436
|
+
}
|
|
15437
|
+
function formatCallers(edges) {
|
|
15438
|
+
if (edges.length === 0) return "## Direct callers\nNone found.";
|
|
15439
|
+
return [
|
|
15440
|
+
"## Direct callers",
|
|
15441
|
+
...edges.map((edge) => `- ${edge.fromSymbolName ?? "<unknown>"} at ${edge.fromSymbolFilePath ?? "<unknown file>"}:${edge.line} (${edge.callType}, ${edge.isResolved ? "resolved" : "unresolved"})`)
|
|
15442
|
+
].join("\n");
|
|
15443
|
+
}
|
|
15444
|
+
function formatCallees(edges, sourceFilePath) {
|
|
15445
|
+
if (edges.length === 0) return "## Direct callees\nNone found.";
|
|
15446
|
+
return [
|
|
15447
|
+
"## Direct callees",
|
|
15448
|
+
...edges.map((edge) => `- ${edge.targetName} from ${sourceFilePath}:${edge.line} (${edge.callType}, ${edge.isResolved ? "resolved" : "unresolved"})`)
|
|
15449
|
+
].join("\n");
|
|
15450
|
+
}
|
|
15451
|
+
function formatResolutionRisk(resolution) {
|
|
15452
|
+
if (resolution.status === "ambiguous") {
|
|
15453
|
+
const candidates = resolution.candidates.map((candidate) => `${candidate.filePath}:${candidate.startLine}`).join(", ");
|
|
15454
|
+
return `Risk: symbol "${resolution.name}" is ambiguous. Pass filePath to select a target.${candidates ? ` Candidates: ${candidates}.` : ""}`;
|
|
15455
|
+
}
|
|
15456
|
+
if (resolution.filePath && resolution.totalCandidates > 0) {
|
|
15457
|
+
return `Risk: symbol "${resolution.name}" did not resolve at filePath="${resolution.filePath}". Review the conceptual evidence before editing.`;
|
|
15458
|
+
}
|
|
15459
|
+
return `Risk: symbol "${resolution.name}" could not be resolved. Review the conceptual evidence before editing.`;
|
|
15460
|
+
}
|
|
15461
|
+
async function fallbackPack(dependencies, query, risk, resolution, tokenBudget, candidateSource = []) {
|
|
15462
|
+
const conceptual = await dependencies.searchCodebase(query, { limit: 5 });
|
|
15463
|
+
const pack = buildContextPack([...candidateSource, ...conceptual], {
|
|
15464
|
+
tokenBudget: tokenBudget ?? void 0,
|
|
15465
|
+
heading: "## Conceptual evidence",
|
|
15466
|
+
maxResults: 5,
|
|
15467
|
+
includeExactSearchHandoff: false,
|
|
15468
|
+
preferImplementationPaths: true
|
|
15469
|
+
});
|
|
15470
|
+
const fitted = fitTextToContextBudget(`${risk}
|
|
15471
|
+
|
|
15472
|
+
${pack.text}`, tokenBudget ?? void 0);
|
|
15473
|
+
return {
|
|
15474
|
+
text: fitted.text,
|
|
15475
|
+
details: {
|
|
15476
|
+
resolution,
|
|
15477
|
+
tokenBudget: fitted.tokenBudget,
|
|
15478
|
+
tokenEstimate: fitted.tokenEstimate,
|
|
15479
|
+
truncated: fitted.truncated,
|
|
15480
|
+
sourceIncluded: candidateSource.length > 0,
|
|
15481
|
+
callerCount: 0,
|
|
15482
|
+
calleeCount: 0
|
|
15483
|
+
}
|
|
15484
|
+
};
|
|
15485
|
+
}
|
|
15486
|
+
async function resolveCodebaseEditContextWithDependencies(input, dependencies) {
|
|
15487
|
+
const symbol = input.symbol?.trim();
|
|
15488
|
+
if (!symbol) {
|
|
15489
|
+
return fallbackPack(
|
|
15490
|
+
dependencies,
|
|
15491
|
+
input.query,
|
|
15492
|
+
"Risk: no authoritative symbol was supplied. Review the conceptual evidence before editing.",
|
|
15493
|
+
"not_requested",
|
|
15494
|
+
input.tokenBudget
|
|
15495
|
+
);
|
|
15496
|
+
}
|
|
15497
|
+
let callersResult;
|
|
15498
|
+
try {
|
|
15499
|
+
callersResult = await dependencies.getCallGraphData({
|
|
15500
|
+
name: symbol,
|
|
15501
|
+
filePath: input.filePath ?? void 0,
|
|
15502
|
+
direction: "callers"
|
|
15503
|
+
});
|
|
15504
|
+
} catch (error) {
|
|
15505
|
+
const candidates = await dependencies.implementationLookup(symbol, { limit: 5 });
|
|
15506
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
15507
|
+
return fallbackPack(
|
|
15508
|
+
dependencies,
|
|
15509
|
+
input.query,
|
|
15510
|
+
`Risk: graph data is unavailable (${message}). Target and dependencies are not graph-verified.`,
|
|
15511
|
+
"graph_unavailable",
|
|
15512
|
+
input.tokenBudget,
|
|
15513
|
+
candidates
|
|
15514
|
+
);
|
|
15515
|
+
}
|
|
15516
|
+
if (callersResult.resolution.status !== "resolved") {
|
|
15517
|
+
return fallbackPack(
|
|
15518
|
+
dependencies,
|
|
15519
|
+
input.query,
|
|
15520
|
+
formatResolutionRisk(callersResult.resolution),
|
|
15521
|
+
callersResult.resolution.status,
|
|
15522
|
+
input.tokenBudget
|
|
15523
|
+
);
|
|
15524
|
+
}
|
|
15525
|
+
const resolution = callersResult.resolution;
|
|
15526
|
+
const [definitionsResult, calleesResult] = await Promise.allSettled([
|
|
15527
|
+
dependencies.implementationLookup(symbol, { limit: 10 }),
|
|
15528
|
+
dependencies.getCallGraphData({
|
|
15529
|
+
name: symbol,
|
|
15530
|
+
filePath: input.filePath ?? resolution.filePath,
|
|
15531
|
+
direction: "callees"
|
|
15532
|
+
})
|
|
15533
|
+
]);
|
|
15534
|
+
if (definitionsResult.status === "rejected") throw definitionsResult.reason;
|
|
15535
|
+
let graphRisk;
|
|
15536
|
+
let callees = [];
|
|
15537
|
+
if (calleesResult.status === "rejected") {
|
|
15538
|
+
const message = calleesResult.reason instanceof Error ? calleesResult.reason.message : String(calleesResult.reason);
|
|
15539
|
+
graphRisk = `Risk: callee graph data is unavailable (${message}). Dependency evidence is incomplete.`;
|
|
15540
|
+
} else if (calleesResult.value.resolution.status !== "resolved") {
|
|
15541
|
+
graphRisk = "Risk: the target resolved for callers but not callees. Dependency evidence is incomplete.";
|
|
15542
|
+
} else {
|
|
15543
|
+
callees = calleesResult.value.callees.slice(0, edgeLimit(input.calleeLimit));
|
|
15544
|
+
}
|
|
15545
|
+
const source = targetSource(definitionsResult.value, resolution);
|
|
15546
|
+
const callers = callersResult.callers.slice(0, edgeLimit(input.callerLimit));
|
|
15547
|
+
const sourceBudget = Math.max(
|
|
15548
|
+
MIN_CONTEXT_PACK_TOKEN_BUDGET,
|
|
15549
|
+
Math.floor((input.tokenBudget ?? DEFAULT_CONTEXT_PACK_TOKEN_BUDGET) * 0.6)
|
|
15550
|
+
);
|
|
15551
|
+
const sourceText = source ? fitTextToContextBudget(formatSource(source), sourceBudget).text : `## Target implementation
|
|
15552
|
+
Risk: no implementation source matched the resolved target at ${resolution.filePath}:${resolution.startLine}.`;
|
|
15553
|
+
const fitted = fitTextToContextBudget([
|
|
15554
|
+
`# Pre-edit context for ${resolution.name}`,
|
|
15555
|
+
graphRisk,
|
|
15556
|
+
sourceText,
|
|
15557
|
+
formatCallers(callers),
|
|
15558
|
+
formatCallees(callees, resolution.filePath)
|
|
15559
|
+
].filter((section) => section !== void 0).join("\n\n"), input.tokenBudget ?? void 0);
|
|
15560
|
+
return {
|
|
15561
|
+
text: fitted.text,
|
|
15562
|
+
details: {
|
|
15563
|
+
resolution: "resolved",
|
|
15564
|
+
tokenBudget: fitted.tokenBudget,
|
|
15565
|
+
tokenEstimate: fitted.tokenEstimate,
|
|
15566
|
+
truncated: fitted.truncated,
|
|
15567
|
+
sourceIncluded: source !== void 0,
|
|
15568
|
+
callerCount: callers.length,
|
|
15569
|
+
calleeCount: callees.length
|
|
15570
|
+
}
|
|
15571
|
+
};
|
|
15572
|
+
}
|
|
15573
|
+
async function resolveCodebaseEditContext(projectRoot3, host, input) {
|
|
15574
|
+
return resolveCodebaseEditContextWithDependencies(input, {
|
|
15575
|
+
searchCodebase: (query, options) => searchCodebase(projectRoot3, host, query, options),
|
|
15576
|
+
implementationLookup: (query, options) => implementationLookup(projectRoot3, host, query, options),
|
|
15577
|
+
getCallGraphData: (params) => getCallGraphData(projectRoot3, host, params)
|
|
15578
|
+
});
|
|
15579
|
+
}
|
|
15580
|
+
|
|
15263
15581
|
// src/adapters/pi/call-graph.ts
|
|
15264
15582
|
var import_typebox = require("typebox");
|
|
15265
15583
|
|
|
15266
15584
|
// src/tools/tool-names.ts
|
|
15267
15585
|
var TOOL_NAME = {
|
|
15268
15586
|
CODEBASE_CONTEXT: "codebase_context",
|
|
15587
|
+
CODEBASE_EDIT_CONTEXT: "codebase_edit_context",
|
|
15269
15588
|
CODEBASE_SEARCH: "codebase_search",
|
|
15270
15589
|
CODEBASE_PEEK: "codebase_peek",
|
|
15271
15590
|
FIND_SIMILAR: "find_similar",
|
|
@@ -15289,6 +15608,7 @@ var TOOL_NAME = {
|
|
|
15289
15608
|
};
|
|
15290
15609
|
var PORTABLE_TOOL_NAMES = [
|
|
15291
15610
|
TOOL_NAME.CODEBASE_CONTEXT,
|
|
15611
|
+
TOOL_NAME.CODEBASE_EDIT_CONTEXT,
|
|
15292
15612
|
TOOL_NAME.CODEBASE_SEARCH,
|
|
15293
15613
|
TOOL_NAME.CODEBASE_PEEK,
|
|
15294
15614
|
TOOL_NAME.INDEX_CODEBASE,
|
|
@@ -15305,6 +15625,7 @@ var PORTABLE_TOOL_NAMES = [
|
|
|
15305
15625
|
];
|
|
15306
15626
|
var OPENCODE_TOOL_NAMES = [
|
|
15307
15627
|
TOOL_NAME.CODEBASE_CONTEXT,
|
|
15628
|
+
TOOL_NAME.CODEBASE_EDIT_CONTEXT,
|
|
15308
15629
|
TOOL_NAME.CODEBASE_SEARCH,
|
|
15309
15630
|
TOOL_NAME.CODEBASE_PEEK,
|
|
15310
15631
|
TOOL_NAME.INDEX_CODEBASE,
|
|
@@ -15325,6 +15646,7 @@ var OPENCODE_TOOL_NAMES = [
|
|
|
15325
15646
|
];
|
|
15326
15647
|
var PI_TOOL_NAMES = [
|
|
15327
15648
|
TOOL_NAME.CODEBASE_CONTEXT,
|
|
15649
|
+
TOOL_NAME.CODEBASE_EDIT_CONTEXT,
|
|
15328
15650
|
TOOL_NAME.CODEBASE_SEARCH,
|
|
15329
15651
|
TOOL_NAME.CODEBASE_PEEK,
|
|
15330
15652
|
TOOL_NAME.FIND_SIMILAR,
|
|
@@ -15439,6 +15761,7 @@ function codebaseIndexPiExtension(pi) {
|
|
|
15439
15761
|
import_typebox2.Type.Integer({ minimum: MIN_CONTEXT_PATH_DEPTH, maximum: MAX_CONTEXT_PATH_DEPTH }),
|
|
15440
15762
|
import_typebox2.Type.Null()
|
|
15441
15763
|
], { default: 10, description: `Maximum call-graph traversal depth (${MIN_CONTEXT_PATH_DEPTH}-${MAX_CONTEXT_PATH_DEPTH})` })),
|
|
15764
|
+
diagnostic: import_typebox2.Type.Optional(import_typebox2.Type.Union([import_typebox2.Type.Boolean(), import_typebox2.Type.Null()], { description: "Collect diagnostic routing and search traces without changing normal output." })),
|
|
15442
15765
|
fileType: import_typebox2.Type.Optional(import_typebox2.Type.Union([import_typebox2.Type.String(), import_typebox2.Type.Null()], { description: "Filter by file extension, e.g., ts, py, rs" })),
|
|
15443
15766
|
directory: import_typebox2.Type.Optional(import_typebox2.Type.Union([import_typebox2.Type.String(), import_typebox2.Type.Null()], { description: "Filter by directory path" })),
|
|
15444
15767
|
tokenBudget: import_typebox2.Type.Optional(import_typebox2.Type.Union([
|
|
@@ -15450,10 +15773,40 @@ function codebaseIndexPiExtension(pi) {
|
|
|
15450
15773
|
}))
|
|
15451
15774
|
}),
|
|
15452
15775
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
15453
|
-
const
|
|
15776
|
+
const normalizedParams = {
|
|
15777
|
+
...params,
|
|
15778
|
+
diagnostic: params.diagnostic ?? void 0
|
|
15779
|
+
};
|
|
15780
|
+
const result = await resolveCodebaseContext(projectRoot2(ctx), HOST2, normalizedParams);
|
|
15454
15781
|
return text2(result.text, result.details);
|
|
15455
15782
|
}
|
|
15456
15783
|
});
|
|
15784
|
+
pi.registerTool({
|
|
15785
|
+
name: TOOL_NAME.CODEBASE_EDIT_CONTEXT,
|
|
15786
|
+
label: "Codebase Edit Context",
|
|
15787
|
+
description: "PRE-EDIT TOOL for a known or suspected symbol. Returns bounded target source and direct graph evidence, with a risk-marked fallback when unresolved.",
|
|
15788
|
+
parameters: import_typebox2.Type.Object({
|
|
15789
|
+
query: import_typebox2.Type.String({ description: "The requested change or target behavior" }),
|
|
15790
|
+
symbol: import_typebox2.Type.Optional(import_typebox2.Type.Union([import_typebox2.Type.String(), import_typebox2.Type.Null()])),
|
|
15791
|
+
filePath: import_typebox2.Type.Optional(import_typebox2.Type.Union([import_typebox2.Type.String(), import_typebox2.Type.Null()])),
|
|
15792
|
+
callerLimit: import_typebox2.Type.Optional(import_typebox2.Type.Union([
|
|
15793
|
+
import_typebox2.Type.Integer({ minimum: MIN_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT, maximum: MAX_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT }),
|
|
15794
|
+
import_typebox2.Type.Null()
|
|
15795
|
+
], { default: DEFAULT_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT })),
|
|
15796
|
+
calleeLimit: import_typebox2.Type.Optional(import_typebox2.Type.Union([
|
|
15797
|
+
import_typebox2.Type.Integer({ minimum: MIN_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT, maximum: MAX_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT }),
|
|
15798
|
+
import_typebox2.Type.Null()
|
|
15799
|
+
], { default: DEFAULT_CODEBASE_EDIT_CONTEXT_EDGE_LIMIT })),
|
|
15800
|
+
tokenBudget: import_typebox2.Type.Optional(import_typebox2.Type.Union([
|
|
15801
|
+
import_typebox2.Type.Integer({ minimum: MIN_CONTEXT_PACK_TOKEN_BUDGET, maximum: MAX_CONTEXT_PACK_TOKEN_BUDGET }),
|
|
15802
|
+
import_typebox2.Type.Null()
|
|
15803
|
+
], { default: DEFAULT_CONTEXT_PACK_TOKEN_BUDGET }))
|
|
15804
|
+
}),
|
|
15805
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
15806
|
+
const result = await resolveCodebaseEditContext(projectRoot2(ctx), HOST2, params);
|
|
15807
|
+
return text2(result.text);
|
|
15808
|
+
}
|
|
15809
|
+
});
|
|
15457
15810
|
pi.registerTool({
|
|
15458
15811
|
name: TOOL_NAME.CODEBASE_SEARCH,
|
|
15459
15812
|
label: "Codebase Search",
|