opencode-codebase-index 0.5.2 → 0.6.1
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/README.md +208 -105
- package/commands/definition.md +24 -0
- package/dist/cli.cjs +1442 -200
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1415 -179
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +217 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +218 -87
- package/dist/index.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 +8 -1
package/dist/index.cjs
CHANGED
|
@@ -33,7 +33,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
33
33
|
|
|
34
34
|
// node_modules/eventemitter3/index.js
|
|
35
35
|
var require_eventemitter3 = __commonJS({
|
|
36
|
-
"node_modules/eventemitter3/index.js"(exports2,
|
|
36
|
+
"node_modules/eventemitter3/index.js"(exports2, module3) {
|
|
37
37
|
"use strict";
|
|
38
38
|
var has = Object.prototype.hasOwnProperty;
|
|
39
39
|
var prefix = "~";
|
|
@@ -187,15 +187,15 @@ var require_eventemitter3 = __commonJS({
|
|
|
187
187
|
EventEmitter3.prototype.addListener = EventEmitter3.prototype.on;
|
|
188
188
|
EventEmitter3.prefixed = prefix;
|
|
189
189
|
EventEmitter3.EventEmitter = EventEmitter3;
|
|
190
|
-
if ("undefined" !== typeof
|
|
191
|
-
|
|
190
|
+
if ("undefined" !== typeof module3) {
|
|
191
|
+
module3.exports = EventEmitter3;
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
});
|
|
195
195
|
|
|
196
196
|
// node_modules/ignore/index.js
|
|
197
197
|
var require_ignore = __commonJS({
|
|
198
|
-
"node_modules/ignore/index.js"(exports2,
|
|
198
|
+
"node_modules/ignore/index.js"(exports2, module3) {
|
|
199
199
|
"use strict";
|
|
200
200
|
function makeArray(subject) {
|
|
201
201
|
return Array.isArray(subject) ? subject : [subject];
|
|
@@ -644,10 +644,10 @@ var require_ignore = __commonJS({
|
|
|
644
644
|
) {
|
|
645
645
|
setupWindows();
|
|
646
646
|
}
|
|
647
|
-
|
|
647
|
+
module3.exports = factory;
|
|
648
648
|
factory.default = factory;
|
|
649
|
-
|
|
650
|
-
define(
|
|
649
|
+
module3.exports.isPathValid = isPathValid;
|
|
650
|
+
define(module3.exports, /* @__PURE__ */ Symbol.for("setupWindows"), setupWindows);
|
|
651
651
|
}
|
|
652
652
|
});
|
|
653
653
|
|
|
@@ -668,7 +668,7 @@ var DEFAULT_INCLUDE = [
|
|
|
668
668
|
"**/*.{py,pyi}",
|
|
669
669
|
"**/*.{go,rs,java,kt,scala}",
|
|
670
670
|
"**/*.{c,cpp,cc,h,hpp}",
|
|
671
|
-
"**/*.{rb,php,swift}",
|
|
671
|
+
"**/*.{rb,php,inc,swift}",
|
|
672
672
|
"**/*.{vue,svelte,astro}",
|
|
673
673
|
"**/*.{sql,graphql,proto}",
|
|
674
674
|
"**/*.{yaml,yml,toml}",
|
|
@@ -763,6 +763,27 @@ var DEFAULT_PROVIDER_MODELS = {
|
|
|
763
763
|
"ollama": "nomic-embed-text"
|
|
764
764
|
};
|
|
765
765
|
|
|
766
|
+
// src/config/env-substitution.ts
|
|
767
|
+
var ENV_REFERENCE_PATTERN = /^\{env:([A-Z_][A-Z0-9_]*)\}$/;
|
|
768
|
+
var ENV_REFERENCE_LIKE_PATTERN = /\{env:[^}]+\}/;
|
|
769
|
+
function substituteEnvString(value, keyPath) {
|
|
770
|
+
const match = value.match(ENV_REFERENCE_PATTERN);
|
|
771
|
+
if (!match) {
|
|
772
|
+
if (ENV_REFERENCE_LIKE_PATTERN.test(value)) {
|
|
773
|
+
throw new Error(
|
|
774
|
+
`Invalid environment variable reference at '${keyPath}'. Expected the entire string to match '{env:VAR_NAME}' with VAR_NAME matching [A-Z_][A-Z0-9_]*.`
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
return value;
|
|
778
|
+
}
|
|
779
|
+
const variableName = match[1];
|
|
780
|
+
const envValue = process.env[variableName];
|
|
781
|
+
if (envValue === void 0) {
|
|
782
|
+
throw new Error(`Missing environment variable '${variableName}' referenced by config at '${keyPath}'.`);
|
|
783
|
+
}
|
|
784
|
+
return envValue;
|
|
785
|
+
}
|
|
786
|
+
|
|
766
787
|
// src/config/schema.ts
|
|
767
788
|
function getDefaultIndexingConfig() {
|
|
768
789
|
return {
|
|
@@ -820,11 +841,27 @@ function isValidScope(value) {
|
|
|
820
841
|
function isStringArray(value) {
|
|
821
842
|
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
822
843
|
}
|
|
844
|
+
function getResolvedString(value, keyPath) {
|
|
845
|
+
if (typeof value !== "string") {
|
|
846
|
+
return void 0;
|
|
847
|
+
}
|
|
848
|
+
return substituteEnvString(value, keyPath);
|
|
849
|
+
}
|
|
850
|
+
function getResolvedStringArray(value, keyPath) {
|
|
851
|
+
if (!isStringArray(value)) {
|
|
852
|
+
return void 0;
|
|
853
|
+
}
|
|
854
|
+
return value.map((item, index) => substituteEnvString(item, `${keyPath}[${index}]`));
|
|
855
|
+
}
|
|
823
856
|
function isValidLogLevel(value) {
|
|
824
857
|
return typeof value === "string" && VALID_LOG_LEVELS.includes(value);
|
|
825
858
|
}
|
|
826
859
|
function parseConfig(raw) {
|
|
827
860
|
const input = raw && typeof raw === "object" ? raw : {};
|
|
861
|
+
const embeddingProviderValue = getResolvedString(input.embeddingProvider, "$root.embeddingProvider");
|
|
862
|
+
const scopeValue = getResolvedString(input.scope, "$root.scope");
|
|
863
|
+
const includeValue = getResolvedStringArray(input.include, "$root.include");
|
|
864
|
+
const excludeValue = getResolvedStringArray(input.exclude, "$root.exclude");
|
|
828
865
|
const defaultIndexing = getDefaultIndexingConfig();
|
|
829
866
|
const defaultSearch = getDefaultSearchConfig();
|
|
830
867
|
const defaultDebug = getDefaultDebugConfig();
|
|
@@ -867,19 +904,23 @@ function parseConfig(raw) {
|
|
|
867
904
|
let embeddingProvider;
|
|
868
905
|
let embeddingModel = void 0;
|
|
869
906
|
let customProvider = void 0;
|
|
870
|
-
if (
|
|
907
|
+
if (embeddingProviderValue === "custom") {
|
|
871
908
|
embeddingProvider = "custom";
|
|
872
909
|
const rawCustom = input.customProvider && typeof input.customProvider === "object" ? input.customProvider : null;
|
|
873
|
-
|
|
910
|
+
const baseUrlValue = getResolvedString(rawCustom?.baseUrl, "$root.customProvider.baseUrl");
|
|
911
|
+
const modelValue = getResolvedString(rawCustom?.model, "$root.customProvider.model");
|
|
912
|
+
const apiKeyValue = getResolvedString(rawCustom?.apiKey, "$root.customProvider.apiKey");
|
|
913
|
+
if (rawCustom && typeof baseUrlValue === "string" && baseUrlValue.trim().length > 0 && typeof modelValue === "string" && modelValue.trim().length > 0 && typeof rawCustom.dimensions === "number" && Number.isInteger(rawCustom.dimensions) && rawCustom.dimensions > 0) {
|
|
874
914
|
customProvider = {
|
|
875
|
-
baseUrl:
|
|
876
|
-
model:
|
|
915
|
+
baseUrl: baseUrlValue.trim().replace(/\/+$/, ""),
|
|
916
|
+
model: modelValue,
|
|
877
917
|
dimensions: rawCustom.dimensions,
|
|
878
|
-
apiKey:
|
|
918
|
+
apiKey: apiKeyValue,
|
|
879
919
|
maxTokens: typeof rawCustom.maxTokens === "number" ? rawCustom.maxTokens : void 0,
|
|
880
920
|
timeoutMs: typeof rawCustom.timeoutMs === "number" ? Math.max(1e3, rawCustom.timeoutMs) : void 0,
|
|
881
921
|
concurrency: typeof rawCustom.concurrency === "number" ? Math.max(1, Math.floor(rawCustom.concurrency)) : void 0,
|
|
882
|
-
requestIntervalMs: typeof rawCustom.requestIntervalMs === "number" ? Math.max(0, Math.floor(rawCustom.requestIntervalMs)) : void 0
|
|
922
|
+
requestIntervalMs: typeof rawCustom.requestIntervalMs === "number" ? Math.max(0, Math.floor(rawCustom.requestIntervalMs)) : void 0,
|
|
923
|
+
maxBatchSize: typeof rawCustom.maxBatchSize === "number" ? Math.max(1, Math.floor(rawCustom.maxBatchSize)) : typeof rawCustom.max_batch_size === "number" ? Math.max(1, Math.floor(rawCustom.max_batch_size)) : void 0
|
|
883
924
|
};
|
|
884
925
|
if (!/\/v\d+\/?$/.test(customProvider.baseUrl)) {
|
|
885
926
|
console.warn(
|
|
@@ -891,10 +932,16 @@ function parseConfig(raw) {
|
|
|
891
932
|
"embeddingProvider is 'custom' but customProvider config is missing or invalid. Required fields: baseUrl (string), model (string), dimensions (positive integer)."
|
|
892
933
|
);
|
|
893
934
|
}
|
|
894
|
-
} else if (isValidProvider(
|
|
895
|
-
embeddingProvider =
|
|
896
|
-
|
|
897
|
-
|
|
935
|
+
} else if (isValidProvider(embeddingProviderValue)) {
|
|
936
|
+
embeddingProvider = embeddingProviderValue;
|
|
937
|
+
const rawEmbeddingModel = input.embeddingModel;
|
|
938
|
+
if (typeof rawEmbeddingModel === "string") {
|
|
939
|
+
const embeddingModelValue = substituteEnvString(rawEmbeddingModel, "$root.embeddingModel");
|
|
940
|
+
if (embeddingModelValue) {
|
|
941
|
+
embeddingModel = isValidModel(embeddingModelValue, embeddingProvider) ? embeddingModelValue : DEFAULT_PROVIDER_MODELS[embeddingProvider];
|
|
942
|
+
}
|
|
943
|
+
} else if (rawEmbeddingModel) {
|
|
944
|
+
embeddingModel = DEFAULT_PROVIDER_MODELS[embeddingProvider];
|
|
898
945
|
}
|
|
899
946
|
} else {
|
|
900
947
|
embeddingProvider = "auto";
|
|
@@ -903,9 +950,9 @@ function parseConfig(raw) {
|
|
|
903
950
|
embeddingProvider,
|
|
904
951
|
embeddingModel,
|
|
905
952
|
customProvider,
|
|
906
|
-
scope: isValidScope(
|
|
907
|
-
include:
|
|
908
|
-
exclude:
|
|
953
|
+
scope: isValidScope(scopeValue) ? scopeValue : "project",
|
|
954
|
+
include: includeValue ?? DEFAULT_INCLUDE,
|
|
955
|
+
exclude: excludeValue ?? DEFAULT_EXCLUDE,
|
|
909
956
|
indexing,
|
|
910
957
|
search,
|
|
911
958
|
debug
|
|
@@ -2089,7 +2136,8 @@ function createCustomProviderInfo(config) {
|
|
|
2089
2136
|
dimensions: config.dimensions,
|
|
2090
2137
|
maxTokens: config.maxTokens ?? 8192,
|
|
2091
2138
|
costPer1MTokens: 0,
|
|
2092
|
-
timeoutMs: config.timeoutMs ?? 3e4
|
|
2139
|
+
timeoutMs: config.timeoutMs ?? 3e4,
|
|
2140
|
+
maxBatchSize: config.maxBatchSize
|
|
2093
2141
|
}
|
|
2094
2142
|
};
|
|
2095
2143
|
}
|
|
@@ -2352,21 +2400,24 @@ var CustomEmbeddingProvider = class {
|
|
|
2352
2400
|
this.credentials = credentials;
|
|
2353
2401
|
this.modelInfo = modelInfo;
|
|
2354
2402
|
}
|
|
2355
|
-
|
|
2356
|
-
const
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
return
|
|
2365
|
-
embedding: result.embeddings[0],
|
|
2366
|
-
tokensUsed: result.totalTokensUsed
|
|
2367
|
-
};
|
|
2403
|
+
splitIntoRequestBatches(texts) {
|
|
2404
|
+
const maxBatchSize = this.modelInfo.maxBatchSize;
|
|
2405
|
+
if (!maxBatchSize || texts.length <= maxBatchSize) {
|
|
2406
|
+
return [texts];
|
|
2407
|
+
}
|
|
2408
|
+
const batches = [];
|
|
2409
|
+
for (let i = 0; i < texts.length; i += maxBatchSize) {
|
|
2410
|
+
batches.push(texts.slice(i, i + maxBatchSize));
|
|
2411
|
+
}
|
|
2412
|
+
return batches;
|
|
2368
2413
|
}
|
|
2369
|
-
async
|
|
2414
|
+
async embedRequest(texts) {
|
|
2415
|
+
if (texts.length === 0) {
|
|
2416
|
+
return {
|
|
2417
|
+
embeddings: [],
|
|
2418
|
+
totalTokensUsed: 0
|
|
2419
|
+
};
|
|
2420
|
+
}
|
|
2370
2421
|
const headers = {
|
|
2371
2422
|
"Content-Type": "application/json"
|
|
2372
2423
|
};
|
|
@@ -2427,6 +2478,34 @@ var CustomEmbeddingProvider = class {
|
|
|
2427
2478
|
}
|
|
2428
2479
|
throw new Error("Custom embedding API returned unexpected response format. Expected OpenAI-compatible format with data[].embedding.");
|
|
2429
2480
|
}
|
|
2481
|
+
async embedQuery(query) {
|
|
2482
|
+
const result = await this.embedBatch([query]);
|
|
2483
|
+
return {
|
|
2484
|
+
embedding: result.embeddings[0],
|
|
2485
|
+
tokensUsed: result.totalTokensUsed
|
|
2486
|
+
};
|
|
2487
|
+
}
|
|
2488
|
+
async embedDocument(document) {
|
|
2489
|
+
const result = await this.embedBatch([document]);
|
|
2490
|
+
return {
|
|
2491
|
+
embedding: result.embeddings[0],
|
|
2492
|
+
tokensUsed: result.totalTokensUsed
|
|
2493
|
+
};
|
|
2494
|
+
}
|
|
2495
|
+
async embedBatch(texts) {
|
|
2496
|
+
const requestBatches = this.splitIntoRequestBatches(texts);
|
|
2497
|
+
const embeddings = [];
|
|
2498
|
+
let totalTokensUsed = 0;
|
|
2499
|
+
for (const batch of requestBatches) {
|
|
2500
|
+
const result = await this.embedRequest(batch);
|
|
2501
|
+
embeddings.push(...result.embeddings);
|
|
2502
|
+
totalTokensUsed += result.totalTokensUsed;
|
|
2503
|
+
}
|
|
2504
|
+
return {
|
|
2505
|
+
embeddings,
|
|
2506
|
+
totalTokensUsed
|
|
2507
|
+
};
|
|
2508
|
+
}
|
|
2430
2509
|
getModelInfo() {
|
|
2431
2510
|
return this.modelInfo;
|
|
2432
2511
|
}
|
|
@@ -2929,6 +3008,7 @@ function initializeLogger(config) {
|
|
|
2929
3008
|
// src/native/index.ts
|
|
2930
3009
|
var path3 = __toESM(require("path"), 1);
|
|
2931
3010
|
var os2 = __toESM(require("os"), 1);
|
|
3011
|
+
var module2 = __toESM(require("module"), 1);
|
|
2932
3012
|
var import_url = require("url");
|
|
2933
3013
|
var import_meta = {};
|
|
2934
3014
|
function getNativeBinding() {
|
|
@@ -2949,17 +3029,22 @@ function getNativeBinding() {
|
|
|
2949
3029
|
throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
|
|
2950
3030
|
}
|
|
2951
3031
|
let currentDir;
|
|
3032
|
+
let requireTarget;
|
|
2952
3033
|
if (typeof import_meta !== "undefined" && import_meta.url) {
|
|
2953
3034
|
currentDir = path3.dirname((0, import_url.fileURLToPath)(import_meta.url));
|
|
3035
|
+
requireTarget = import_meta.url;
|
|
2954
3036
|
} else if (typeof __dirname !== "undefined") {
|
|
2955
3037
|
currentDir = __dirname;
|
|
3038
|
+
requireTarget = __filename;
|
|
2956
3039
|
} else {
|
|
2957
3040
|
currentDir = process.cwd();
|
|
3041
|
+
requireTarget = path3.join(currentDir, "index.js");
|
|
2958
3042
|
}
|
|
2959
3043
|
const isDevMode = currentDir.includes("/src/native");
|
|
2960
3044
|
const packageRoot = isDevMode ? path3.resolve(currentDir, "../..") : path3.resolve(currentDir, "..");
|
|
2961
3045
|
const nativePath = path3.join(packageRoot, "native", bindingName);
|
|
2962
|
-
|
|
3046
|
+
const require2 = module2.createRequire(requireTarget);
|
|
3047
|
+
return require2(nativePath);
|
|
2963
3048
|
}
|
|
2964
3049
|
var native = getNativeBinding();
|
|
2965
3050
|
function parseFiles(files) {
|
|
@@ -3441,7 +3526,36 @@ var Database = class {
|
|
|
3441
3526
|
// src/git/index.ts
|
|
3442
3527
|
var import_fs3 = require("fs");
|
|
3443
3528
|
var path4 = __toESM(require("path"), 1);
|
|
3444
|
-
|
|
3529
|
+
function readPackedRefs(gitDir) {
|
|
3530
|
+
const packedRefsPath = path4.join(gitDir, "packed-refs");
|
|
3531
|
+
if (!(0, import_fs3.existsSync)(packedRefsPath)) {
|
|
3532
|
+
return [];
|
|
3533
|
+
}
|
|
3534
|
+
try {
|
|
3535
|
+
return (0, import_fs3.readFileSync)(packedRefsPath, "utf-8").split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#") && !line.startsWith("^"));
|
|
3536
|
+
} catch {
|
|
3537
|
+
return [];
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3540
|
+
function resolveCommonGitDir(gitDir) {
|
|
3541
|
+
const commonDirPath = path4.join(gitDir, "commondir");
|
|
3542
|
+
if (!(0, import_fs3.existsSync)(commonDirPath)) {
|
|
3543
|
+
return gitDir;
|
|
3544
|
+
}
|
|
3545
|
+
try {
|
|
3546
|
+
const raw = (0, import_fs3.readFileSync)(commonDirPath, "utf-8").trim();
|
|
3547
|
+
if (!raw) {
|
|
3548
|
+
return gitDir;
|
|
3549
|
+
}
|
|
3550
|
+
const resolved = path4.isAbsolute(raw) ? raw : path4.resolve(gitDir, raw);
|
|
3551
|
+
if ((0, import_fs3.existsSync)(resolved)) {
|
|
3552
|
+
return resolved;
|
|
3553
|
+
}
|
|
3554
|
+
} catch {
|
|
3555
|
+
return gitDir;
|
|
3556
|
+
}
|
|
3557
|
+
return gitDir;
|
|
3558
|
+
}
|
|
3445
3559
|
function resolveGitDir(repoRoot) {
|
|
3446
3560
|
const gitPath = path4.join(repoRoot, ".git");
|
|
3447
3561
|
if (!(0, import_fs3.existsSync)(gitPath)) {
|
|
@@ -3495,37 +3609,20 @@ function getCurrentBranch(repoRoot) {
|
|
|
3495
3609
|
}
|
|
3496
3610
|
function getBaseBranch(repoRoot) {
|
|
3497
3611
|
const gitDir = resolveGitDir(repoRoot);
|
|
3612
|
+
const refStoreDir = gitDir ? resolveCommonGitDir(gitDir) : null;
|
|
3498
3613
|
const candidates = ["main", "master", "develop", "trunk"];
|
|
3499
|
-
if (
|
|
3614
|
+
if (refStoreDir) {
|
|
3500
3615
|
for (const candidate of candidates) {
|
|
3501
|
-
const refPath = path4.join(
|
|
3616
|
+
const refPath = path4.join(refStoreDir, "refs", "heads", candidate);
|
|
3502
3617
|
if ((0, import_fs3.existsSync)(refPath)) {
|
|
3503
3618
|
return candidate;
|
|
3504
3619
|
}
|
|
3505
|
-
const
|
|
3506
|
-
if ((
|
|
3507
|
-
|
|
3508
|
-
const content = (0, import_fs3.readFileSync)(packedRefsPath, "utf-8");
|
|
3509
|
-
if (content.includes(`refs/heads/${candidate}`)) {
|
|
3510
|
-
return candidate;
|
|
3511
|
-
}
|
|
3512
|
-
} catch {
|
|
3513
|
-
}
|
|
3620
|
+
const packedRefs = readPackedRefs(refStoreDir);
|
|
3621
|
+
if (packedRefs.some((line) => line.endsWith(` refs/heads/${candidate}`))) {
|
|
3622
|
+
return candidate;
|
|
3514
3623
|
}
|
|
3515
3624
|
}
|
|
3516
3625
|
}
|
|
3517
|
-
try {
|
|
3518
|
-
const result = (0, import_child_process.execSync)("git remote show origin", {
|
|
3519
|
-
cwd: repoRoot,
|
|
3520
|
-
encoding: "utf-8",
|
|
3521
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
3522
|
-
});
|
|
3523
|
-
const match = result.match(/HEAD branch: (.+)/);
|
|
3524
|
-
if (match) {
|
|
3525
|
-
return match[1].trim();
|
|
3526
|
-
}
|
|
3527
|
-
} catch {
|
|
3528
|
-
}
|
|
3529
3626
|
return getCurrentBranch(repoRoot) ?? "main";
|
|
3530
3627
|
}
|
|
3531
3628
|
function getBranchOrDefault(repoRoot) {
|
|
@@ -3543,7 +3640,7 @@ function getHeadPath(repoRoot) {
|
|
|
3543
3640
|
}
|
|
3544
3641
|
|
|
3545
3642
|
// src/indexer/index.ts
|
|
3546
|
-
var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust"]);
|
|
3643
|
+
var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust", "php"]);
|
|
3547
3644
|
var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
3548
3645
|
"function_declaration",
|
|
3549
3646
|
"function",
|
|
@@ -3564,7 +3661,8 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
|
3564
3661
|
"struct_item",
|
|
3565
3662
|
"enum_item",
|
|
3566
3663
|
"trait_item",
|
|
3567
|
-
"mod_item"
|
|
3664
|
+
"mod_item",
|
|
3665
|
+
"trait_declaration"
|
|
3568
3666
|
]);
|
|
3569
3667
|
function float32ArrayToBuffer(arr) {
|
|
3570
3668
|
const float32 = new Float32Array(arr);
|
|
@@ -3946,8 +4044,8 @@ function stripFilePathHint(query) {
|
|
|
3946
4044
|
const stripped = query.replace(FILE_PATH_HINT_SUFFIX_REGEX, "").trim();
|
|
3947
4045
|
return stripped.length > 0 ? stripped : query;
|
|
3948
4046
|
}
|
|
3949
|
-
function buildDeterministicIdentifierPass(query, candidates, limit) {
|
|
3950
|
-
if (
|
|
4047
|
+
function buildDeterministicIdentifierPass(query, candidates, limit, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
4048
|
+
if (!prioritizeSourcePaths) {
|
|
3951
4049
|
return [];
|
|
3952
4050
|
}
|
|
3953
4051
|
const primary = extractPrimaryIdentifierQueryHint(query);
|
|
@@ -4163,9 +4261,8 @@ function rankHybridResults(query, semanticResults, keywordResults, options) {
|
|
|
4163
4261
|
const fused = options.fusionStrategy === "rrf" ? fuseResultsRrf(semanticResults, keywordResults, options.rrfK, overfetchLimit) : fuseResultsWeighted(semanticResults, keywordResults, options.hybridWeight, overfetchLimit);
|
|
4164
4262
|
const rerankPoolLimit = Math.max(overfetchLimit, options.rerankTopN * 3, options.limit * 6);
|
|
4165
4263
|
const rerankPool = fused.slice(0, rerankPoolLimit);
|
|
4166
|
-
const intent = classifyQueryIntentRaw(query);
|
|
4167
4264
|
return rerankResults(query, rerankPool, options.rerankTopN, {
|
|
4168
|
-
prioritizeSourcePaths:
|
|
4265
|
+
prioritizeSourcePaths: options.prioritizeSourcePaths ?? classifyQueryIntentRaw(query) === "source"
|
|
4169
4266
|
});
|
|
4170
4267
|
}
|
|
4171
4268
|
function rankSemanticOnlyResults(query, semanticResults, options) {
|
|
@@ -4175,11 +4272,11 @@ function rankSemanticOnlyResults(query, semanticResults, options) {
|
|
|
4175
4272
|
prioritizeSourcePaths: options.prioritizeSourcePaths ?? false
|
|
4176
4273
|
});
|
|
4177
4274
|
}
|
|
4178
|
-
function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCandidates, database, branchChunkIds) {
|
|
4275
|
+
function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCandidates, database, branchChunkIds, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
4179
4276
|
if (combined.length === 0) {
|
|
4180
4277
|
return combined;
|
|
4181
4278
|
}
|
|
4182
|
-
if (
|
|
4279
|
+
if (!prioritizeSourcePaths) {
|
|
4183
4280
|
return combined;
|
|
4184
4281
|
}
|
|
4185
4282
|
const identifierHints = extractIdentifierHints(query);
|
|
@@ -4269,8 +4366,8 @@ function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCa
|
|
|
4269
4366
|
const remainder = combined.filter((candidate) => !promotedIds.has(candidate.id));
|
|
4270
4367
|
return [...promoted, ...remainder];
|
|
4271
4368
|
}
|
|
4272
|
-
function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallbackCandidates) {
|
|
4273
|
-
if (
|
|
4369
|
+
function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallbackCandidates, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
4370
|
+
if (!prioritizeSourcePaths) {
|
|
4274
4371
|
return [];
|
|
4275
4372
|
}
|
|
4276
4373
|
const identifierHints = extractIdentifierHints(query);
|
|
@@ -4415,8 +4512,8 @@ function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallb
|
|
|
4415
4512
|
const withFallback = Array.from(symbolCandidates.values()).sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));
|
|
4416
4513
|
return withFallback.slice(0, Math.max(limit * 2, limit));
|
|
4417
4514
|
}
|
|
4418
|
-
function buildIdentifierDefinitionLane(query, candidates, limit) {
|
|
4419
|
-
if (
|
|
4515
|
+
function buildIdentifierDefinitionLane(query, candidates, limit, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
4516
|
+
if (!prioritizeSourcePaths) {
|
|
4420
4517
|
return [];
|
|
4421
4518
|
}
|
|
4422
4519
|
const primaryHint = extractPrimaryIdentifierQueryHint(query);
|
|
@@ -5348,6 +5445,7 @@ var Indexer = class {
|
|
|
5348
5445
|
const rrfK = this.config.search.rrfK;
|
|
5349
5446
|
const rerankTopN = this.config.search.rerankTopN;
|
|
5350
5447
|
const filterByBranch = options?.filterByBranch ?? true;
|
|
5448
|
+
const sourceIntent = options?.definitionIntent === true || classifyQueryIntentRaw(query) === "source";
|
|
5351
5449
|
this.logger.search("debug", "Starting search", {
|
|
5352
5450
|
query,
|
|
5353
5451
|
maxResults,
|
|
@@ -5399,7 +5497,8 @@ var Indexer = class {
|
|
|
5399
5497
|
rrfK,
|
|
5400
5498
|
rerankTopN,
|
|
5401
5499
|
limit: maxResults,
|
|
5402
|
-
hybridWeight
|
|
5500
|
+
hybridWeight,
|
|
5501
|
+
prioritizeSourcePaths: sourceIntent
|
|
5403
5502
|
});
|
|
5404
5503
|
const fusionMs = import_perf_hooks.performance.now() - fusionStartTime;
|
|
5405
5504
|
const rescued = promoteIdentifierMatches(
|
|
@@ -5408,30 +5507,33 @@ var Indexer = class {
|
|
|
5408
5507
|
semanticCandidates,
|
|
5409
5508
|
keywordCandidates,
|
|
5410
5509
|
database,
|
|
5411
|
-
branchChunkIds
|
|
5510
|
+
branchChunkIds,
|
|
5511
|
+
sourceIntent
|
|
5412
5512
|
);
|
|
5413
5513
|
const union = unionCandidates(semanticCandidates, keywordCandidates);
|
|
5414
5514
|
const deterministicIdentifierLane = buildDeterministicIdentifierPass(
|
|
5415
5515
|
query,
|
|
5416
5516
|
union,
|
|
5417
|
-
maxResults
|
|
5517
|
+
maxResults,
|
|
5518
|
+
sourceIntent
|
|
5418
5519
|
);
|
|
5419
5520
|
const identifierLane = buildIdentifierDefinitionLane(
|
|
5420
5521
|
query,
|
|
5421
5522
|
union,
|
|
5422
|
-
maxResults
|
|
5523
|
+
maxResults,
|
|
5524
|
+
sourceIntent
|
|
5423
5525
|
);
|
|
5424
5526
|
const symbolLane = buildSymbolDefinitionLane(
|
|
5425
5527
|
query,
|
|
5426
5528
|
database,
|
|
5427
5529
|
branchChunkIds,
|
|
5428
5530
|
maxResults,
|
|
5429
|
-
union
|
|
5531
|
+
union,
|
|
5532
|
+
sourceIntent
|
|
5430
5533
|
);
|
|
5431
5534
|
const prePrimaryLane = mergeTieredResults(deterministicIdentifierLane, identifierLane, maxResults * 4);
|
|
5432
5535
|
const primaryLane = mergeTieredResults(prePrimaryLane, symbolLane, maxResults * 4);
|
|
5433
5536
|
const tiered = mergeTieredResults(primaryLane, rescued, maxResults * 4);
|
|
5434
|
-
const sourceIntent = classifyQueryIntentRaw(query) === "source";
|
|
5435
5537
|
const hasCodeHints = extractCodeTermHints(query).length > 0 || extractIdentifierHints(query).length > 0;
|
|
5436
5538
|
const baseFiltered = tiered.filter((r) => {
|
|
5437
5539
|
if (r.score < this.config.search.minScore) return false;
|
|
@@ -7877,6 +7979,22 @@ function formatLogs(logs) {
|
|
|
7877
7979
|
return `[${l.timestamp}] [${l.level.toUpperCase()}] [${l.category}] ${l.message}${dataStr}`;
|
|
7878
7980
|
}).join("\n");
|
|
7879
7981
|
}
|
|
7982
|
+
function formatDefinitionLookup(results, query) {
|
|
7983
|
+
if (results.length === 0) {
|
|
7984
|
+
return `No definition found for "${query}". Try codebase_search for broader discovery, or verify the symbol name.`;
|
|
7985
|
+
}
|
|
7986
|
+
const formatted = results.map((r, idx) => {
|
|
7987
|
+
const header2 = r.name ? `[${idx + 1}] ${r.chunkType} "${r.name}" in ${r.filePath}:${r.startLine}-${r.endLine}` : `[${idx + 1}] ${r.chunkType} in ${r.filePath}:${r.startLine}-${r.endLine}`;
|
|
7988
|
+
return `${header2} (score: ${r.score.toFixed(2)})
|
|
7989
|
+
\`\`\`
|
|
7990
|
+
${truncateContent(r.content)}
|
|
7991
|
+
\`\`\``;
|
|
7992
|
+
});
|
|
7993
|
+
const header = results.length === 1 ? `Definition found for "${query}":` : `Found ${results.length} definition candidates for "${query}":`;
|
|
7994
|
+
return `${header}
|
|
7995
|
+
|
|
7996
|
+
${formatted.join("\n\n")}`;
|
|
7997
|
+
}
|
|
7880
7998
|
function formatSearchResults(results, scoreFormat = "similarity") {
|
|
7881
7999
|
const formatted = results.map((r, idx) => {
|
|
7882
8000
|
const header = r.name ? `[${idx + 1}] ${r.chunkType} "${r.name}" in ${r.filePath}:${r.startLine}-${r.endLine}` : `[${idx + 1}] ${r.chunkType} in ${r.filePath}:${r.startLine}-${r.endLine}`;
|
|
@@ -8062,6 +8180,24 @@ var codebase_search = (0, import_plugin.tool)({
|
|
|
8062
8180
|
${formatSearchResults(results, "score")}`;
|
|
8063
8181
|
}
|
|
8064
8182
|
});
|
|
8183
|
+
var implementation_lookup = (0, import_plugin.tool)({
|
|
8184
|
+
description: "Jump to symbol definition. Find WHERE something is defined. Returns the authoritative source location(s) for a function, class, method, type, or variable. Prefers real implementation files over tests, docs, examples, and fixtures. Use when you need the definition site, not all usages.",
|
|
8185
|
+
args: {
|
|
8186
|
+
query: z.string().describe("Symbol name or natural language description (e.g., 'validateToken', 'where is the payment handler defined')"),
|
|
8187
|
+
limit: z.number().optional().default(5).describe("Maximum number of results"),
|
|
8188
|
+
fileType: z.string().optional().describe("Filter by file extension (e.g., 'ts', 'py')"),
|
|
8189
|
+
directory: z.string().optional().describe("Filter by directory path (e.g., 'src/utils')")
|
|
8190
|
+
},
|
|
8191
|
+
async execute(args) {
|
|
8192
|
+
const indexer = getIndexer();
|
|
8193
|
+
const results = await indexer.search(args.query, args.limit ?? 5, {
|
|
8194
|
+
fileType: args.fileType,
|
|
8195
|
+
directory: args.directory,
|
|
8196
|
+
definitionIntent: true
|
|
8197
|
+
});
|
|
8198
|
+
return formatDefinitionLookup(results, args.query);
|
|
8199
|
+
}
|
|
8200
|
+
});
|
|
8065
8201
|
var call_graph = (0, import_plugin.tool)({
|
|
8066
8202
|
description: "Query the call graph to find callers or callees of a function/method. Use to understand code flow and dependencies between functions.",
|
|
8067
8203
|
args: {
|
|
@@ -8203,7 +8339,8 @@ var plugin = async ({ directory }) => {
|
|
|
8203
8339
|
index_metrics,
|
|
8204
8340
|
index_logs,
|
|
8205
8341
|
find_similar,
|
|
8206
|
-
call_graph
|
|
8342
|
+
call_graph,
|
|
8343
|
+
implementation_lookup
|
|
8207
8344
|
},
|
|
8208
8345
|
async config(cfg) {
|
|
8209
8346
|
cfg.command = cfg.command ?? {};
|