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.js
CHANGED
|
@@ -6,13 +6,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var
|
|
10
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
11
|
-
}) : x)(function(x) {
|
|
12
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
13
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
14
|
-
});
|
|
15
|
-
var __commonJS = (cb, mod) => function __require2() {
|
|
9
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
16
10
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
17
11
|
};
|
|
18
12
|
var __copyProps = (to, from, except, desc) => {
|
|
@@ -34,7 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
34
28
|
|
|
35
29
|
// node_modules/eventemitter3/index.js
|
|
36
30
|
var require_eventemitter3 = __commonJS({
|
|
37
|
-
"node_modules/eventemitter3/index.js"(exports,
|
|
31
|
+
"node_modules/eventemitter3/index.js"(exports, module2) {
|
|
38
32
|
"use strict";
|
|
39
33
|
var has = Object.prototype.hasOwnProperty;
|
|
40
34
|
var prefix = "~";
|
|
@@ -188,15 +182,15 @@ var require_eventemitter3 = __commonJS({
|
|
|
188
182
|
EventEmitter3.prototype.addListener = EventEmitter3.prototype.on;
|
|
189
183
|
EventEmitter3.prefixed = prefix;
|
|
190
184
|
EventEmitter3.EventEmitter = EventEmitter3;
|
|
191
|
-
if ("undefined" !== typeof
|
|
192
|
-
|
|
185
|
+
if ("undefined" !== typeof module2) {
|
|
186
|
+
module2.exports = EventEmitter3;
|
|
193
187
|
}
|
|
194
188
|
}
|
|
195
189
|
});
|
|
196
190
|
|
|
197
191
|
// node_modules/ignore/index.js
|
|
198
192
|
var require_ignore = __commonJS({
|
|
199
|
-
"node_modules/ignore/index.js"(exports,
|
|
193
|
+
"node_modules/ignore/index.js"(exports, module2) {
|
|
200
194
|
"use strict";
|
|
201
195
|
function makeArray(subject) {
|
|
202
196
|
return Array.isArray(subject) ? subject : [subject];
|
|
@@ -645,10 +639,10 @@ var require_ignore = __commonJS({
|
|
|
645
639
|
) {
|
|
646
640
|
setupWindows();
|
|
647
641
|
}
|
|
648
|
-
|
|
642
|
+
module2.exports = factory;
|
|
649
643
|
factory.default = factory;
|
|
650
|
-
|
|
651
|
-
define(
|
|
644
|
+
module2.exports.isPathValid = isPathValid;
|
|
645
|
+
define(module2.exports, /* @__PURE__ */ Symbol.for("setupWindows"), setupWindows);
|
|
652
646
|
}
|
|
653
647
|
});
|
|
654
648
|
|
|
@@ -664,7 +658,7 @@ var DEFAULT_INCLUDE = [
|
|
|
664
658
|
"**/*.{py,pyi}",
|
|
665
659
|
"**/*.{go,rs,java,kt,scala}",
|
|
666
660
|
"**/*.{c,cpp,cc,h,hpp}",
|
|
667
|
-
"**/*.{rb,php,swift}",
|
|
661
|
+
"**/*.{rb,php,inc,swift}",
|
|
668
662
|
"**/*.{vue,svelte,astro}",
|
|
669
663
|
"**/*.{sql,graphql,proto}",
|
|
670
664
|
"**/*.{yaml,yml,toml}",
|
|
@@ -759,6 +753,27 @@ var DEFAULT_PROVIDER_MODELS = {
|
|
|
759
753
|
"ollama": "nomic-embed-text"
|
|
760
754
|
};
|
|
761
755
|
|
|
756
|
+
// src/config/env-substitution.ts
|
|
757
|
+
var ENV_REFERENCE_PATTERN = /^\{env:([A-Z_][A-Z0-9_]*)\}$/;
|
|
758
|
+
var ENV_REFERENCE_LIKE_PATTERN = /\{env:[^}]+\}/;
|
|
759
|
+
function substituteEnvString(value, keyPath) {
|
|
760
|
+
const match = value.match(ENV_REFERENCE_PATTERN);
|
|
761
|
+
if (!match) {
|
|
762
|
+
if (ENV_REFERENCE_LIKE_PATTERN.test(value)) {
|
|
763
|
+
throw new Error(
|
|
764
|
+
`Invalid environment variable reference at '${keyPath}'. Expected the entire string to match '{env:VAR_NAME}' with VAR_NAME matching [A-Z_][A-Z0-9_]*.`
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
return value;
|
|
768
|
+
}
|
|
769
|
+
const variableName = match[1];
|
|
770
|
+
const envValue = process.env[variableName];
|
|
771
|
+
if (envValue === void 0) {
|
|
772
|
+
throw new Error(`Missing environment variable '${variableName}' referenced by config at '${keyPath}'.`);
|
|
773
|
+
}
|
|
774
|
+
return envValue;
|
|
775
|
+
}
|
|
776
|
+
|
|
762
777
|
// src/config/schema.ts
|
|
763
778
|
function getDefaultIndexingConfig() {
|
|
764
779
|
return {
|
|
@@ -816,11 +831,27 @@ function isValidScope(value) {
|
|
|
816
831
|
function isStringArray(value) {
|
|
817
832
|
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
818
833
|
}
|
|
834
|
+
function getResolvedString(value, keyPath) {
|
|
835
|
+
if (typeof value !== "string") {
|
|
836
|
+
return void 0;
|
|
837
|
+
}
|
|
838
|
+
return substituteEnvString(value, keyPath);
|
|
839
|
+
}
|
|
840
|
+
function getResolvedStringArray(value, keyPath) {
|
|
841
|
+
if (!isStringArray(value)) {
|
|
842
|
+
return void 0;
|
|
843
|
+
}
|
|
844
|
+
return value.map((item, index) => substituteEnvString(item, `${keyPath}[${index}]`));
|
|
845
|
+
}
|
|
819
846
|
function isValidLogLevel(value) {
|
|
820
847
|
return typeof value === "string" && VALID_LOG_LEVELS.includes(value);
|
|
821
848
|
}
|
|
822
849
|
function parseConfig(raw) {
|
|
823
850
|
const input = raw && typeof raw === "object" ? raw : {};
|
|
851
|
+
const embeddingProviderValue = getResolvedString(input.embeddingProvider, "$root.embeddingProvider");
|
|
852
|
+
const scopeValue = getResolvedString(input.scope, "$root.scope");
|
|
853
|
+
const includeValue = getResolvedStringArray(input.include, "$root.include");
|
|
854
|
+
const excludeValue = getResolvedStringArray(input.exclude, "$root.exclude");
|
|
824
855
|
const defaultIndexing = getDefaultIndexingConfig();
|
|
825
856
|
const defaultSearch = getDefaultSearchConfig();
|
|
826
857
|
const defaultDebug = getDefaultDebugConfig();
|
|
@@ -863,19 +894,23 @@ function parseConfig(raw) {
|
|
|
863
894
|
let embeddingProvider;
|
|
864
895
|
let embeddingModel = void 0;
|
|
865
896
|
let customProvider = void 0;
|
|
866
|
-
if (
|
|
897
|
+
if (embeddingProviderValue === "custom") {
|
|
867
898
|
embeddingProvider = "custom";
|
|
868
899
|
const rawCustom = input.customProvider && typeof input.customProvider === "object" ? input.customProvider : null;
|
|
869
|
-
|
|
900
|
+
const baseUrlValue = getResolvedString(rawCustom?.baseUrl, "$root.customProvider.baseUrl");
|
|
901
|
+
const modelValue = getResolvedString(rawCustom?.model, "$root.customProvider.model");
|
|
902
|
+
const apiKeyValue = getResolvedString(rawCustom?.apiKey, "$root.customProvider.apiKey");
|
|
903
|
+
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) {
|
|
870
904
|
customProvider = {
|
|
871
|
-
baseUrl:
|
|
872
|
-
model:
|
|
905
|
+
baseUrl: baseUrlValue.trim().replace(/\/+$/, ""),
|
|
906
|
+
model: modelValue,
|
|
873
907
|
dimensions: rawCustom.dimensions,
|
|
874
|
-
apiKey:
|
|
908
|
+
apiKey: apiKeyValue,
|
|
875
909
|
maxTokens: typeof rawCustom.maxTokens === "number" ? rawCustom.maxTokens : void 0,
|
|
876
910
|
timeoutMs: typeof rawCustom.timeoutMs === "number" ? Math.max(1e3, rawCustom.timeoutMs) : void 0,
|
|
877
911
|
concurrency: typeof rawCustom.concurrency === "number" ? Math.max(1, Math.floor(rawCustom.concurrency)) : void 0,
|
|
878
|
-
requestIntervalMs: typeof rawCustom.requestIntervalMs === "number" ? Math.max(0, Math.floor(rawCustom.requestIntervalMs)) : void 0
|
|
912
|
+
requestIntervalMs: typeof rawCustom.requestIntervalMs === "number" ? Math.max(0, Math.floor(rawCustom.requestIntervalMs)) : void 0,
|
|
913
|
+
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
|
|
879
914
|
};
|
|
880
915
|
if (!/\/v\d+\/?$/.test(customProvider.baseUrl)) {
|
|
881
916
|
console.warn(
|
|
@@ -887,10 +922,16 @@ function parseConfig(raw) {
|
|
|
887
922
|
"embeddingProvider is 'custom' but customProvider config is missing or invalid. Required fields: baseUrl (string), model (string), dimensions (positive integer)."
|
|
888
923
|
);
|
|
889
924
|
}
|
|
890
|
-
} else if (isValidProvider(
|
|
891
|
-
embeddingProvider =
|
|
892
|
-
|
|
893
|
-
|
|
925
|
+
} else if (isValidProvider(embeddingProviderValue)) {
|
|
926
|
+
embeddingProvider = embeddingProviderValue;
|
|
927
|
+
const rawEmbeddingModel = input.embeddingModel;
|
|
928
|
+
if (typeof rawEmbeddingModel === "string") {
|
|
929
|
+
const embeddingModelValue = substituteEnvString(rawEmbeddingModel, "$root.embeddingModel");
|
|
930
|
+
if (embeddingModelValue) {
|
|
931
|
+
embeddingModel = isValidModel(embeddingModelValue, embeddingProvider) ? embeddingModelValue : DEFAULT_PROVIDER_MODELS[embeddingProvider];
|
|
932
|
+
}
|
|
933
|
+
} else if (rawEmbeddingModel) {
|
|
934
|
+
embeddingModel = DEFAULT_PROVIDER_MODELS[embeddingProvider];
|
|
894
935
|
}
|
|
895
936
|
} else {
|
|
896
937
|
embeddingProvider = "auto";
|
|
@@ -899,9 +940,9 @@ function parseConfig(raw) {
|
|
|
899
940
|
embeddingProvider,
|
|
900
941
|
embeddingModel,
|
|
901
942
|
customProvider,
|
|
902
|
-
scope: isValidScope(
|
|
903
|
-
include:
|
|
904
|
-
exclude:
|
|
943
|
+
scope: isValidScope(scopeValue) ? scopeValue : "project",
|
|
944
|
+
include: includeValue ?? DEFAULT_INCLUDE,
|
|
945
|
+
exclude: excludeValue ?? DEFAULT_EXCLUDE,
|
|
905
946
|
indexing,
|
|
906
947
|
search,
|
|
907
948
|
debug
|
|
@@ -2085,7 +2126,8 @@ function createCustomProviderInfo(config) {
|
|
|
2085
2126
|
dimensions: config.dimensions,
|
|
2086
2127
|
maxTokens: config.maxTokens ?? 8192,
|
|
2087
2128
|
costPer1MTokens: 0,
|
|
2088
|
-
timeoutMs: config.timeoutMs ?? 3e4
|
|
2129
|
+
timeoutMs: config.timeoutMs ?? 3e4,
|
|
2130
|
+
maxBatchSize: config.maxBatchSize
|
|
2089
2131
|
}
|
|
2090
2132
|
};
|
|
2091
2133
|
}
|
|
@@ -2348,21 +2390,24 @@ var CustomEmbeddingProvider = class {
|
|
|
2348
2390
|
this.credentials = credentials;
|
|
2349
2391
|
this.modelInfo = modelInfo;
|
|
2350
2392
|
}
|
|
2351
|
-
|
|
2352
|
-
const
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
return
|
|
2361
|
-
embedding: result.embeddings[0],
|
|
2362
|
-
tokensUsed: result.totalTokensUsed
|
|
2363
|
-
};
|
|
2393
|
+
splitIntoRequestBatches(texts) {
|
|
2394
|
+
const maxBatchSize = this.modelInfo.maxBatchSize;
|
|
2395
|
+
if (!maxBatchSize || texts.length <= maxBatchSize) {
|
|
2396
|
+
return [texts];
|
|
2397
|
+
}
|
|
2398
|
+
const batches = [];
|
|
2399
|
+
for (let i = 0; i < texts.length; i += maxBatchSize) {
|
|
2400
|
+
batches.push(texts.slice(i, i + maxBatchSize));
|
|
2401
|
+
}
|
|
2402
|
+
return batches;
|
|
2364
2403
|
}
|
|
2365
|
-
async
|
|
2404
|
+
async embedRequest(texts) {
|
|
2405
|
+
if (texts.length === 0) {
|
|
2406
|
+
return {
|
|
2407
|
+
embeddings: [],
|
|
2408
|
+
totalTokensUsed: 0
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2366
2411
|
const headers = {
|
|
2367
2412
|
"Content-Type": "application/json"
|
|
2368
2413
|
};
|
|
@@ -2423,6 +2468,34 @@ var CustomEmbeddingProvider = class {
|
|
|
2423
2468
|
}
|
|
2424
2469
|
throw new Error("Custom embedding API returned unexpected response format. Expected OpenAI-compatible format with data[].embedding.");
|
|
2425
2470
|
}
|
|
2471
|
+
async embedQuery(query) {
|
|
2472
|
+
const result = await this.embedBatch([query]);
|
|
2473
|
+
return {
|
|
2474
|
+
embedding: result.embeddings[0],
|
|
2475
|
+
tokensUsed: result.totalTokensUsed
|
|
2476
|
+
};
|
|
2477
|
+
}
|
|
2478
|
+
async embedDocument(document) {
|
|
2479
|
+
const result = await this.embedBatch([document]);
|
|
2480
|
+
return {
|
|
2481
|
+
embedding: result.embeddings[0],
|
|
2482
|
+
tokensUsed: result.totalTokensUsed
|
|
2483
|
+
};
|
|
2484
|
+
}
|
|
2485
|
+
async embedBatch(texts) {
|
|
2486
|
+
const requestBatches = this.splitIntoRequestBatches(texts);
|
|
2487
|
+
const embeddings = [];
|
|
2488
|
+
let totalTokensUsed = 0;
|
|
2489
|
+
for (const batch of requestBatches) {
|
|
2490
|
+
const result = await this.embedRequest(batch);
|
|
2491
|
+
embeddings.push(...result.embeddings);
|
|
2492
|
+
totalTokensUsed += result.totalTokensUsed;
|
|
2493
|
+
}
|
|
2494
|
+
return {
|
|
2495
|
+
embeddings,
|
|
2496
|
+
totalTokensUsed
|
|
2497
|
+
};
|
|
2498
|
+
}
|
|
2426
2499
|
getModelInfo() {
|
|
2427
2500
|
return this.modelInfo;
|
|
2428
2501
|
}
|
|
@@ -2925,6 +2998,7 @@ function initializeLogger(config) {
|
|
|
2925
2998
|
// src/native/index.ts
|
|
2926
2999
|
import * as path3 from "path";
|
|
2927
3000
|
import * as os2 from "os";
|
|
3001
|
+
import * as module from "module";
|
|
2928
3002
|
import { fileURLToPath } from "url";
|
|
2929
3003
|
function getNativeBinding() {
|
|
2930
3004
|
const platform2 = os2.platform();
|
|
@@ -2944,17 +3018,22 @@ function getNativeBinding() {
|
|
|
2944
3018
|
throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
|
|
2945
3019
|
}
|
|
2946
3020
|
let currentDir;
|
|
3021
|
+
let requireTarget;
|
|
2947
3022
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
2948
3023
|
currentDir = path3.dirname(fileURLToPath(import.meta.url));
|
|
3024
|
+
requireTarget = import.meta.url;
|
|
2949
3025
|
} else if (typeof __dirname !== "undefined") {
|
|
2950
3026
|
currentDir = __dirname;
|
|
3027
|
+
requireTarget = __filename;
|
|
2951
3028
|
} else {
|
|
2952
3029
|
currentDir = process.cwd();
|
|
3030
|
+
requireTarget = path3.join(currentDir, "index.js");
|
|
2953
3031
|
}
|
|
2954
3032
|
const isDevMode = currentDir.includes("/src/native");
|
|
2955
3033
|
const packageRoot = isDevMode ? path3.resolve(currentDir, "../..") : path3.resolve(currentDir, "..");
|
|
2956
3034
|
const nativePath = path3.join(packageRoot, "native", bindingName);
|
|
2957
|
-
|
|
3035
|
+
const require2 = module.createRequire(requireTarget);
|
|
3036
|
+
return require2(nativePath);
|
|
2958
3037
|
}
|
|
2959
3038
|
var native = getNativeBinding();
|
|
2960
3039
|
function parseFiles(files) {
|
|
@@ -3436,7 +3515,36 @@ var Database = class {
|
|
|
3436
3515
|
// src/git/index.ts
|
|
3437
3516
|
import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync, statSync } from "fs";
|
|
3438
3517
|
import * as path4 from "path";
|
|
3439
|
-
|
|
3518
|
+
function readPackedRefs(gitDir) {
|
|
3519
|
+
const packedRefsPath = path4.join(gitDir, "packed-refs");
|
|
3520
|
+
if (!existsSync3(packedRefsPath)) {
|
|
3521
|
+
return [];
|
|
3522
|
+
}
|
|
3523
|
+
try {
|
|
3524
|
+
return readFileSync3(packedRefsPath, "utf-8").split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#") && !line.startsWith("^"));
|
|
3525
|
+
} catch {
|
|
3526
|
+
return [];
|
|
3527
|
+
}
|
|
3528
|
+
}
|
|
3529
|
+
function resolveCommonGitDir(gitDir) {
|
|
3530
|
+
const commonDirPath = path4.join(gitDir, "commondir");
|
|
3531
|
+
if (!existsSync3(commonDirPath)) {
|
|
3532
|
+
return gitDir;
|
|
3533
|
+
}
|
|
3534
|
+
try {
|
|
3535
|
+
const raw = readFileSync3(commonDirPath, "utf-8").trim();
|
|
3536
|
+
if (!raw) {
|
|
3537
|
+
return gitDir;
|
|
3538
|
+
}
|
|
3539
|
+
const resolved = path4.isAbsolute(raw) ? raw : path4.resolve(gitDir, raw);
|
|
3540
|
+
if (existsSync3(resolved)) {
|
|
3541
|
+
return resolved;
|
|
3542
|
+
}
|
|
3543
|
+
} catch {
|
|
3544
|
+
return gitDir;
|
|
3545
|
+
}
|
|
3546
|
+
return gitDir;
|
|
3547
|
+
}
|
|
3440
3548
|
function resolveGitDir(repoRoot) {
|
|
3441
3549
|
const gitPath = path4.join(repoRoot, ".git");
|
|
3442
3550
|
if (!existsSync3(gitPath)) {
|
|
@@ -3490,37 +3598,20 @@ function getCurrentBranch(repoRoot) {
|
|
|
3490
3598
|
}
|
|
3491
3599
|
function getBaseBranch(repoRoot) {
|
|
3492
3600
|
const gitDir = resolveGitDir(repoRoot);
|
|
3601
|
+
const refStoreDir = gitDir ? resolveCommonGitDir(gitDir) : null;
|
|
3493
3602
|
const candidates = ["main", "master", "develop", "trunk"];
|
|
3494
|
-
if (
|
|
3603
|
+
if (refStoreDir) {
|
|
3495
3604
|
for (const candidate of candidates) {
|
|
3496
|
-
const refPath = path4.join(
|
|
3605
|
+
const refPath = path4.join(refStoreDir, "refs", "heads", candidate);
|
|
3497
3606
|
if (existsSync3(refPath)) {
|
|
3498
3607
|
return candidate;
|
|
3499
3608
|
}
|
|
3500
|
-
const
|
|
3501
|
-
if (
|
|
3502
|
-
|
|
3503
|
-
const content = readFileSync3(packedRefsPath, "utf-8");
|
|
3504
|
-
if (content.includes(`refs/heads/${candidate}`)) {
|
|
3505
|
-
return candidate;
|
|
3506
|
-
}
|
|
3507
|
-
} catch {
|
|
3508
|
-
}
|
|
3609
|
+
const packedRefs = readPackedRefs(refStoreDir);
|
|
3610
|
+
if (packedRefs.some((line) => line.endsWith(` refs/heads/${candidate}`))) {
|
|
3611
|
+
return candidate;
|
|
3509
3612
|
}
|
|
3510
3613
|
}
|
|
3511
3614
|
}
|
|
3512
|
-
try {
|
|
3513
|
-
const result = execSync("git remote show origin", {
|
|
3514
|
-
cwd: repoRoot,
|
|
3515
|
-
encoding: "utf-8",
|
|
3516
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
3517
|
-
});
|
|
3518
|
-
const match = result.match(/HEAD branch: (.+)/);
|
|
3519
|
-
if (match) {
|
|
3520
|
-
return match[1].trim();
|
|
3521
|
-
}
|
|
3522
|
-
} catch {
|
|
3523
|
-
}
|
|
3524
3615
|
return getCurrentBranch(repoRoot) ?? "main";
|
|
3525
3616
|
}
|
|
3526
3617
|
function getBranchOrDefault(repoRoot) {
|
|
@@ -3538,7 +3629,7 @@ function getHeadPath(repoRoot) {
|
|
|
3538
3629
|
}
|
|
3539
3630
|
|
|
3540
3631
|
// src/indexer/index.ts
|
|
3541
|
-
var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust"]);
|
|
3632
|
+
var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust", "php"]);
|
|
3542
3633
|
var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
3543
3634
|
"function_declaration",
|
|
3544
3635
|
"function",
|
|
@@ -3559,7 +3650,8 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
|
3559
3650
|
"struct_item",
|
|
3560
3651
|
"enum_item",
|
|
3561
3652
|
"trait_item",
|
|
3562
|
-
"mod_item"
|
|
3653
|
+
"mod_item",
|
|
3654
|
+
"trait_declaration"
|
|
3563
3655
|
]);
|
|
3564
3656
|
function float32ArrayToBuffer(arr) {
|
|
3565
3657
|
const float32 = new Float32Array(arr);
|
|
@@ -3941,8 +4033,8 @@ function stripFilePathHint(query) {
|
|
|
3941
4033
|
const stripped = query.replace(FILE_PATH_HINT_SUFFIX_REGEX, "").trim();
|
|
3942
4034
|
return stripped.length > 0 ? stripped : query;
|
|
3943
4035
|
}
|
|
3944
|
-
function buildDeterministicIdentifierPass(query, candidates, limit) {
|
|
3945
|
-
if (
|
|
4036
|
+
function buildDeterministicIdentifierPass(query, candidates, limit, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
4037
|
+
if (!prioritizeSourcePaths) {
|
|
3946
4038
|
return [];
|
|
3947
4039
|
}
|
|
3948
4040
|
const primary = extractPrimaryIdentifierQueryHint(query);
|
|
@@ -4158,9 +4250,8 @@ function rankHybridResults(query, semanticResults, keywordResults, options) {
|
|
|
4158
4250
|
const fused = options.fusionStrategy === "rrf" ? fuseResultsRrf(semanticResults, keywordResults, options.rrfK, overfetchLimit) : fuseResultsWeighted(semanticResults, keywordResults, options.hybridWeight, overfetchLimit);
|
|
4159
4251
|
const rerankPoolLimit = Math.max(overfetchLimit, options.rerankTopN * 3, options.limit * 6);
|
|
4160
4252
|
const rerankPool = fused.slice(0, rerankPoolLimit);
|
|
4161
|
-
const intent = classifyQueryIntentRaw(query);
|
|
4162
4253
|
return rerankResults(query, rerankPool, options.rerankTopN, {
|
|
4163
|
-
prioritizeSourcePaths:
|
|
4254
|
+
prioritizeSourcePaths: options.prioritizeSourcePaths ?? classifyQueryIntentRaw(query) === "source"
|
|
4164
4255
|
});
|
|
4165
4256
|
}
|
|
4166
4257
|
function rankSemanticOnlyResults(query, semanticResults, options) {
|
|
@@ -4170,11 +4261,11 @@ function rankSemanticOnlyResults(query, semanticResults, options) {
|
|
|
4170
4261
|
prioritizeSourcePaths: options.prioritizeSourcePaths ?? false
|
|
4171
4262
|
});
|
|
4172
4263
|
}
|
|
4173
|
-
function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCandidates, database, branchChunkIds) {
|
|
4264
|
+
function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCandidates, database, branchChunkIds, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
4174
4265
|
if (combined.length === 0) {
|
|
4175
4266
|
return combined;
|
|
4176
4267
|
}
|
|
4177
|
-
if (
|
|
4268
|
+
if (!prioritizeSourcePaths) {
|
|
4178
4269
|
return combined;
|
|
4179
4270
|
}
|
|
4180
4271
|
const identifierHints = extractIdentifierHints(query);
|
|
@@ -4264,8 +4355,8 @@ function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCa
|
|
|
4264
4355
|
const remainder = combined.filter((candidate) => !promotedIds.has(candidate.id));
|
|
4265
4356
|
return [...promoted, ...remainder];
|
|
4266
4357
|
}
|
|
4267
|
-
function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallbackCandidates) {
|
|
4268
|
-
if (
|
|
4358
|
+
function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallbackCandidates, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
4359
|
+
if (!prioritizeSourcePaths) {
|
|
4269
4360
|
return [];
|
|
4270
4361
|
}
|
|
4271
4362
|
const identifierHints = extractIdentifierHints(query);
|
|
@@ -4410,8 +4501,8 @@ function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallb
|
|
|
4410
4501
|
const withFallback = Array.from(symbolCandidates.values()).sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));
|
|
4411
4502
|
return withFallback.slice(0, Math.max(limit * 2, limit));
|
|
4412
4503
|
}
|
|
4413
|
-
function buildIdentifierDefinitionLane(query, candidates, limit) {
|
|
4414
|
-
if (
|
|
4504
|
+
function buildIdentifierDefinitionLane(query, candidates, limit, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
4505
|
+
if (!prioritizeSourcePaths) {
|
|
4415
4506
|
return [];
|
|
4416
4507
|
}
|
|
4417
4508
|
const primaryHint = extractPrimaryIdentifierQueryHint(query);
|
|
@@ -5343,6 +5434,7 @@ var Indexer = class {
|
|
|
5343
5434
|
const rrfK = this.config.search.rrfK;
|
|
5344
5435
|
const rerankTopN = this.config.search.rerankTopN;
|
|
5345
5436
|
const filterByBranch = options?.filterByBranch ?? true;
|
|
5437
|
+
const sourceIntent = options?.definitionIntent === true || classifyQueryIntentRaw(query) === "source";
|
|
5346
5438
|
this.logger.search("debug", "Starting search", {
|
|
5347
5439
|
query,
|
|
5348
5440
|
maxResults,
|
|
@@ -5394,7 +5486,8 @@ var Indexer = class {
|
|
|
5394
5486
|
rrfK,
|
|
5395
5487
|
rerankTopN,
|
|
5396
5488
|
limit: maxResults,
|
|
5397
|
-
hybridWeight
|
|
5489
|
+
hybridWeight,
|
|
5490
|
+
prioritizeSourcePaths: sourceIntent
|
|
5398
5491
|
});
|
|
5399
5492
|
const fusionMs = performance2.now() - fusionStartTime;
|
|
5400
5493
|
const rescued = promoteIdentifierMatches(
|
|
@@ -5403,30 +5496,33 @@ var Indexer = class {
|
|
|
5403
5496
|
semanticCandidates,
|
|
5404
5497
|
keywordCandidates,
|
|
5405
5498
|
database,
|
|
5406
|
-
branchChunkIds
|
|
5499
|
+
branchChunkIds,
|
|
5500
|
+
sourceIntent
|
|
5407
5501
|
);
|
|
5408
5502
|
const union = unionCandidates(semanticCandidates, keywordCandidates);
|
|
5409
5503
|
const deterministicIdentifierLane = buildDeterministicIdentifierPass(
|
|
5410
5504
|
query,
|
|
5411
5505
|
union,
|
|
5412
|
-
maxResults
|
|
5506
|
+
maxResults,
|
|
5507
|
+
sourceIntent
|
|
5413
5508
|
);
|
|
5414
5509
|
const identifierLane = buildIdentifierDefinitionLane(
|
|
5415
5510
|
query,
|
|
5416
5511
|
union,
|
|
5417
|
-
maxResults
|
|
5512
|
+
maxResults,
|
|
5513
|
+
sourceIntent
|
|
5418
5514
|
);
|
|
5419
5515
|
const symbolLane = buildSymbolDefinitionLane(
|
|
5420
5516
|
query,
|
|
5421
5517
|
database,
|
|
5422
5518
|
branchChunkIds,
|
|
5423
5519
|
maxResults,
|
|
5424
|
-
union
|
|
5520
|
+
union,
|
|
5521
|
+
sourceIntent
|
|
5425
5522
|
);
|
|
5426
5523
|
const prePrimaryLane = mergeTieredResults(deterministicIdentifierLane, identifierLane, maxResults * 4);
|
|
5427
5524
|
const primaryLane = mergeTieredResults(prePrimaryLane, symbolLane, maxResults * 4);
|
|
5428
5525
|
const tiered = mergeTieredResults(primaryLane, rescued, maxResults * 4);
|
|
5429
|
-
const sourceIntent = classifyQueryIntentRaw(query) === "source";
|
|
5430
5526
|
const hasCodeHints = extractCodeTermHints(query).length > 0 || extractIdentifierHints(query).length > 0;
|
|
5431
5527
|
const baseFiltered = tiered.filter((r) => {
|
|
5432
5528
|
if (r.score < this.config.search.minScore) return false;
|
|
@@ -7872,6 +7968,22 @@ function formatLogs(logs) {
|
|
|
7872
7968
|
return `[${l.timestamp}] [${l.level.toUpperCase()}] [${l.category}] ${l.message}${dataStr}`;
|
|
7873
7969
|
}).join("\n");
|
|
7874
7970
|
}
|
|
7971
|
+
function formatDefinitionLookup(results, query) {
|
|
7972
|
+
if (results.length === 0) {
|
|
7973
|
+
return `No definition found for "${query}". Try codebase_search for broader discovery, or verify the symbol name.`;
|
|
7974
|
+
}
|
|
7975
|
+
const formatted = results.map((r, idx) => {
|
|
7976
|
+
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}`;
|
|
7977
|
+
return `${header2} (score: ${r.score.toFixed(2)})
|
|
7978
|
+
\`\`\`
|
|
7979
|
+
${truncateContent(r.content)}
|
|
7980
|
+
\`\`\``;
|
|
7981
|
+
});
|
|
7982
|
+
const header = results.length === 1 ? `Definition found for "${query}":` : `Found ${results.length} definition candidates for "${query}":`;
|
|
7983
|
+
return `${header}
|
|
7984
|
+
|
|
7985
|
+
${formatted.join("\n\n")}`;
|
|
7986
|
+
}
|
|
7875
7987
|
function formatSearchResults(results, scoreFormat = "similarity") {
|
|
7876
7988
|
const formatted = results.map((r, idx) => {
|
|
7877
7989
|
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}`;
|
|
@@ -8057,6 +8169,24 @@ var codebase_search = tool({
|
|
|
8057
8169
|
${formatSearchResults(results, "score")}`;
|
|
8058
8170
|
}
|
|
8059
8171
|
});
|
|
8172
|
+
var implementation_lookup = tool({
|
|
8173
|
+
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.",
|
|
8174
|
+
args: {
|
|
8175
|
+
query: z.string().describe("Symbol name or natural language description (e.g., 'validateToken', 'where is the payment handler defined')"),
|
|
8176
|
+
limit: z.number().optional().default(5).describe("Maximum number of results"),
|
|
8177
|
+
fileType: z.string().optional().describe("Filter by file extension (e.g., 'ts', 'py')"),
|
|
8178
|
+
directory: z.string().optional().describe("Filter by directory path (e.g., 'src/utils')")
|
|
8179
|
+
},
|
|
8180
|
+
async execute(args) {
|
|
8181
|
+
const indexer = getIndexer();
|
|
8182
|
+
const results = await indexer.search(args.query, args.limit ?? 5, {
|
|
8183
|
+
fileType: args.fileType,
|
|
8184
|
+
directory: args.directory,
|
|
8185
|
+
definitionIntent: true
|
|
8186
|
+
});
|
|
8187
|
+
return formatDefinitionLookup(results, args.query);
|
|
8188
|
+
}
|
|
8189
|
+
});
|
|
8060
8190
|
var call_graph = tool({
|
|
8061
8191
|
description: "Query the call graph to find callers or callees of a function/method. Use to understand code flow and dependencies between functions.",
|
|
8062
8192
|
args: {
|
|
@@ -8197,7 +8327,8 @@ var plugin = async ({ directory }) => {
|
|
|
8197
8327
|
index_metrics,
|
|
8198
8328
|
index_logs,
|
|
8199
8329
|
find_similar,
|
|
8200
|
-
call_graph
|
|
8330
|
+
call_graph,
|
|
8331
|
+
implementation_lookup
|
|
8201
8332
|
},
|
|
8202
8333
|
async config(cfg) {
|
|
8203
8334
|
cfg.command = cfg.command ?? {};
|