opencode-codebase-index 0.17.1 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +45 -8
- package/THIRD_PARTY_LICENSES.md +64 -0
- package/dist/cli.cjs +576 -346
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +582 -352
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +342 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +356 -128
- package/dist/index.js.map +1 -1
- package/dist/pi-extension.cjs +735 -505
- package/dist/pi-extension.cjs.map +1 -1
- package/dist/pi-extension.js +697 -467
- 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 +2 -1
package/dist/index.js
CHANGED
|
@@ -670,7 +670,8 @@ var DEFAULT_INCLUDE = [
|
|
|
670
670
|
"**/*.{sh,bash,zsh}",
|
|
671
671
|
"**/*.{txt,html,htm}",
|
|
672
672
|
"**/*.zig",
|
|
673
|
-
"**/*.gd"
|
|
673
|
+
"**/*.gd",
|
|
674
|
+
"**/*.metal"
|
|
674
675
|
];
|
|
675
676
|
var DEFAULT_EXCLUDE = [
|
|
676
677
|
"**/node_modules/**",
|
|
@@ -861,6 +862,9 @@ function isValidProvider(value) {
|
|
|
861
862
|
return typeof value === "string" && Object.keys(EMBEDDING_MODELS).includes(value);
|
|
862
863
|
}
|
|
863
864
|
function isValidModel(value, provider) {
|
|
865
|
+
if (typeof value === "string" && provider === "ollama" && value.trim().length > 0) {
|
|
866
|
+
return true;
|
|
867
|
+
}
|
|
864
868
|
return typeof value === "string" && Object.keys(EMBEDDING_MODELS[provider]).includes(value);
|
|
865
869
|
}
|
|
866
870
|
function isValidScope(value) {
|
|
@@ -1043,7 +1047,7 @@ var autoDetectProviders = AUTO_DETECT_PROVIDER_ORDER.filter(
|
|
|
1043
1047
|
);
|
|
1044
1048
|
|
|
1045
1049
|
// src/config/merger.ts
|
|
1046
|
-
import { existsSync as existsSync4,
|
|
1050
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
|
|
1047
1051
|
import * as path6 from "path";
|
|
1048
1052
|
|
|
1049
1053
|
// src/config/paths.ts
|
|
@@ -1225,16 +1229,6 @@ function resolveWorktreeFallbackPath(projectRoot, relativePath) {
|
|
|
1225
1229
|
const fallbackPath = path3.join(mainRepoRoot, relativePath);
|
|
1226
1230
|
return existsSync3(fallbackPath) ? fallbackPath : null;
|
|
1227
1231
|
}
|
|
1228
|
-
function resolveWorktreeFallbackProjectIndexPath(projectRoot, host) {
|
|
1229
|
-
const inheritedHostPath = resolveWorktreeFallbackPath(projectRoot, getProjectIndexRelativePath(host));
|
|
1230
|
-
if (inheritedHostPath) {
|
|
1231
|
-
return inheritedHostPath;
|
|
1232
|
-
}
|
|
1233
|
-
if (host !== "opencode") {
|
|
1234
|
-
return resolveWorktreeFallbackPath(projectRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
|
|
1235
|
-
}
|
|
1236
|
-
return null;
|
|
1237
|
-
}
|
|
1238
1232
|
function getHostProjectConfigRelativePath(host) {
|
|
1239
1233
|
return getProjectConfigRelativePath(host);
|
|
1240
1234
|
}
|
|
@@ -1339,6 +1333,9 @@ function resolveProjectIndexPath(projectRoot, scope, host = "opencode") {
|
|
|
1339
1333
|
if (hasHostProjectConfig(projectRoot, host)) {
|
|
1340
1334
|
return localIndexPath;
|
|
1341
1335
|
}
|
|
1336
|
+
if (resolveWorktreeMainRepoRoot(projectRoot)) {
|
|
1337
|
+
return localIndexPath;
|
|
1338
|
+
}
|
|
1342
1339
|
const hostFallback = resolveWorktreeFallbackPath(projectRoot, getProjectIndexRelativePath(host));
|
|
1343
1340
|
if (hostFallback) {
|
|
1344
1341
|
return hostFallback;
|
|
@@ -1511,12 +1508,6 @@ function loadJsonFile(filePath) {
|
|
|
1511
1508
|
function loadConfigFile(filePath) {
|
|
1512
1509
|
return loadJsonFile(filePath);
|
|
1513
1510
|
}
|
|
1514
|
-
function materializeLocalProjectConfig(projectRoot, config, host = "opencode") {
|
|
1515
|
-
const localConfigPath = resolveWritableProjectConfigPath(projectRoot, host);
|
|
1516
|
-
mkdirSync(path6.dirname(localConfigPath), { recursive: true });
|
|
1517
|
-
writeFileSync(localConfigPath, JSON.stringify(config, null, 2), "utf-8");
|
|
1518
|
-
return localConfigPath;
|
|
1519
|
-
}
|
|
1520
1511
|
function loadProjectConfigLayer(projectRoot, host = "opencode") {
|
|
1521
1512
|
const projectConfigPath = resolveProjectConfigPath(projectRoot, host);
|
|
1522
1513
|
const projectConfig = loadJsonFile(projectConfigPath);
|
|
@@ -1592,13 +1583,13 @@ import { randomUUID } from "crypto";
|
|
|
1592
1583
|
import {
|
|
1593
1584
|
existsSync as existsSync5,
|
|
1594
1585
|
lstatSync,
|
|
1595
|
-
mkdirSync
|
|
1586
|
+
mkdirSync,
|
|
1596
1587
|
readFileSync as readFileSync4,
|
|
1597
1588
|
readdirSync as readdirSync2,
|
|
1598
1589
|
realpathSync,
|
|
1599
1590
|
renameSync,
|
|
1600
1591
|
rmSync,
|
|
1601
|
-
writeFileSync
|
|
1592
|
+
writeFileSync
|
|
1602
1593
|
} from "fs";
|
|
1603
1594
|
import * as os2 from "os";
|
|
1604
1595
|
import * as path7 from "path";
|
|
@@ -1709,13 +1700,13 @@ function sameReclaimOwner(left, right) {
|
|
|
1709
1700
|
function publishJsonDirectory(finalPath, value) {
|
|
1710
1701
|
const candidatePath = `${finalPath}.candidate.${process.pid}.${randomUUID()}`;
|
|
1711
1702
|
try {
|
|
1712
|
-
|
|
1703
|
+
mkdirSync(candidatePath, { mode: 448 });
|
|
1713
1704
|
} catch (error) {
|
|
1714
1705
|
if (getErrorCode(error) === "ENOENT") return false;
|
|
1715
1706
|
throw error;
|
|
1716
1707
|
}
|
|
1717
1708
|
try {
|
|
1718
|
-
|
|
1709
|
+
writeFileSync(path7.join(candidatePath, OWNER_FILE_NAME), JSON.stringify(value), {
|
|
1719
1710
|
encoding: "utf-8",
|
|
1720
1711
|
flag: "wx",
|
|
1721
1712
|
mode: 384
|
|
@@ -1885,7 +1876,7 @@ function isTransientIndexLockContention(error) {
|
|
|
1885
1876
|
return error.reason === "active" || error.reason === "reclaiming";
|
|
1886
1877
|
}
|
|
1887
1878
|
function acquireIndexLock(indexPath, operation) {
|
|
1888
|
-
|
|
1879
|
+
mkdirSync(indexPath, { recursive: true });
|
|
1889
1880
|
const canonicalIndexPath = realpathSync.native(indexPath);
|
|
1890
1881
|
const lockPath = path7.join(canonicalIndexPath, "indexing.lock");
|
|
1891
1882
|
cleanupDeadPublicationCandidates(canonicalIndexPath);
|
|
@@ -1955,40 +1946,6 @@ function releaseIndexLock(lease) {
|
|
|
1955
1946
|
}
|
|
1956
1947
|
return true;
|
|
1957
1948
|
}
|
|
1958
|
-
async function withIndexLock(indexPath, operation, callback, options = {}) {
|
|
1959
|
-
const lease = acquireIndexLock(indexPath, operation);
|
|
1960
|
-
let result;
|
|
1961
|
-
let callbackError;
|
|
1962
|
-
let callbackFailed = false;
|
|
1963
|
-
try {
|
|
1964
|
-
result = await callback(lease);
|
|
1965
|
-
} catch (error) {
|
|
1966
|
-
callbackFailed = true;
|
|
1967
|
-
callbackError = error;
|
|
1968
|
-
}
|
|
1969
|
-
if (!callbackFailed && options.completeRecoveries !== false) {
|
|
1970
|
-
try {
|
|
1971
|
-
completeLeaseRecovery(lease);
|
|
1972
|
-
} catch (error) {
|
|
1973
|
-
callbackFailed = true;
|
|
1974
|
-
callbackError = error;
|
|
1975
|
-
}
|
|
1976
|
-
}
|
|
1977
|
-
let releaseError;
|
|
1978
|
-
try {
|
|
1979
|
-
if (!releaseIndexLock(lease)) {
|
|
1980
|
-
releaseError = new Error(`Lost ownership of index mutation lease ${lease.owner.token}`);
|
|
1981
|
-
}
|
|
1982
|
-
} catch (error) {
|
|
1983
|
-
releaseError = error;
|
|
1984
|
-
}
|
|
1985
|
-
if (releaseError !== void 0) {
|
|
1986
|
-
if (callbackFailed) throw new AggregateError([callbackError, releaseError], "Index mutation and lease release both failed");
|
|
1987
|
-
throw releaseError;
|
|
1988
|
-
}
|
|
1989
|
-
if (callbackFailed) throw callbackError;
|
|
1990
|
-
return result;
|
|
1991
|
-
}
|
|
1992
1949
|
function createLeaseTemporaryPath(targetPath, owner, kind = "tmp") {
|
|
1993
1950
|
if (kind === "bak") return `${targetPath}.bak.${owner.pid}.${owner.token}`;
|
|
1994
1951
|
temporaryCounter += 1;
|
|
@@ -2027,7 +1984,7 @@ import { existsSync as existsSync10, realpathSync as realpathSync2, statSync as
|
|
|
2027
1984
|
import * as path16 from "path";
|
|
2028
1985
|
|
|
2029
1986
|
// src/indexer/index.ts
|
|
2030
|
-
import { existsSync as existsSync8, readFileSync as readFileSync7, statSync as statSync3, writeFileSync as
|
|
1987
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7, statSync as statSync3, writeFileSync as writeFileSync2, renameSync as renameSync2, unlinkSync, mkdirSync as mkdirSync2, promises as fsPromises2 } from "fs";
|
|
2031
1988
|
import * as path13 from "path";
|
|
2032
1989
|
import { performance as performance2 } from "perf_hooks";
|
|
2033
1990
|
import { execFile as execFile3 } from "child_process";
|
|
@@ -3095,6 +3052,9 @@ function loadOpenCodeAuth() {
|
|
|
3095
3052
|
return {};
|
|
3096
3053
|
}
|
|
3097
3054
|
async function detectEmbeddingProvider(preferredProvider, model) {
|
|
3055
|
+
if (preferredProvider === "ollama") {
|
|
3056
|
+
return detectOllamaProvider(model);
|
|
3057
|
+
}
|
|
3098
3058
|
const credentials = await getProviderCredentials(preferredProvider);
|
|
3099
3059
|
if (credentials) {
|
|
3100
3060
|
if (!model) {
|
|
@@ -3110,10 +3070,16 @@ async function detectEmbeddingProvider(preferredProvider, model) {
|
|
|
3110
3070
|
);
|
|
3111
3071
|
}
|
|
3112
3072
|
const providerModels = EMBEDDING_MODELS[preferredProvider];
|
|
3073
|
+
const modelInfo = Object.values(providerModels).find((candidate) => candidate.model === model);
|
|
3074
|
+
if (!modelInfo) {
|
|
3075
|
+
throw new Error(
|
|
3076
|
+
`Model '${model}' is not supported by provider '${preferredProvider}'`
|
|
3077
|
+
);
|
|
3078
|
+
}
|
|
3113
3079
|
return {
|
|
3114
3080
|
provider: preferredProvider,
|
|
3115
3081
|
credentials,
|
|
3116
|
-
modelInfo
|
|
3082
|
+
modelInfo
|
|
3117
3083
|
};
|
|
3118
3084
|
}
|
|
3119
3085
|
throw new Error(
|
|
@@ -3122,6 +3088,13 @@ async function detectEmbeddingProvider(preferredProvider, model) {
|
|
|
3122
3088
|
}
|
|
3123
3089
|
async function tryDetectProvider() {
|
|
3124
3090
|
for (const provider of autoDetectProviders) {
|
|
3091
|
+
if (provider === "ollama") {
|
|
3092
|
+
const ollamaProvider = await tryDetectOllamaProvider();
|
|
3093
|
+
if (ollamaProvider) {
|
|
3094
|
+
return ollamaProvider;
|
|
3095
|
+
}
|
|
3096
|
+
continue;
|
|
3097
|
+
}
|
|
3125
3098
|
const credentials = await getProviderCredentials(provider);
|
|
3126
3099
|
if (credentials) {
|
|
3127
3100
|
return {
|
|
@@ -3189,32 +3162,105 @@ function getGoogleCredentials() {
|
|
|
3189
3162
|
}
|
|
3190
3163
|
return null;
|
|
3191
3164
|
}
|
|
3192
|
-
async function
|
|
3193
|
-
const
|
|
3165
|
+
async function fetchOllama(url, init) {
|
|
3166
|
+
const controller = new AbortController();
|
|
3167
|
+
const timeoutId = setTimeout(() => controller.abort(), 2e3);
|
|
3194
3168
|
try {
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
const response = await fetch(`${baseUrl}/api/tags`, {
|
|
3198
|
-
signal: controller.signal
|
|
3199
|
-
});
|
|
3169
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
3170
|
+
} finally {
|
|
3200
3171
|
clearTimeout(timeoutId);
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3174
|
+
async function getOllamaCredentials() {
|
|
3175
|
+
const baseUrl = (process.env.OLLAMA_HOST || "http://localhost:11434").replace(/\/+$/, "");
|
|
3176
|
+
try {
|
|
3177
|
+
const response = await fetchOllama(`${baseUrl}/api/tags`);
|
|
3201
3178
|
if (response.ok) {
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
if (hasEmbeddingModel) {
|
|
3207
|
-
return {
|
|
3208
|
-
provider: "ollama",
|
|
3209
|
-
baseUrl
|
|
3210
|
-
};
|
|
3211
|
-
}
|
|
3179
|
+
return {
|
|
3180
|
+
provider: "ollama",
|
|
3181
|
+
baseUrl
|
|
3182
|
+
};
|
|
3212
3183
|
}
|
|
3213
3184
|
} catch {
|
|
3214
3185
|
return null;
|
|
3215
3186
|
}
|
|
3216
3187
|
return null;
|
|
3217
3188
|
}
|
|
3189
|
+
function findCatalogOllamaModel(model) {
|
|
3190
|
+
const stableName = model.endsWith(":latest") ? model.slice(0, -":latest".length) : model;
|
|
3191
|
+
return Object.values(EMBEDDING_MODELS.ollama).find((candidate) => candidate.model === stableName) ?? null;
|
|
3192
|
+
}
|
|
3193
|
+
function getPositiveIntegerMetadata(modelInfo, suffix) {
|
|
3194
|
+
const values = Object.entries(modelInfo).filter(([key]) => key.endsWith(suffix)).map(([, value]) => value).filter((value) => typeof value === "number" && Number.isInteger(value) && value > 0);
|
|
3195
|
+
return values.length === 1 ? values[0] : null;
|
|
3196
|
+
}
|
|
3197
|
+
async function fetchOllamaModelInfo(credentials, model) {
|
|
3198
|
+
const response = await fetchOllama(`${credentials.baseUrl}/api/show`, {
|
|
3199
|
+
method: "POST",
|
|
3200
|
+
headers: { "Content-Type": "application/json" },
|
|
3201
|
+
body: JSON.stringify({ model })
|
|
3202
|
+
});
|
|
3203
|
+
if (!response.ok) {
|
|
3204
|
+
return null;
|
|
3205
|
+
}
|
|
3206
|
+
const data = await response.json();
|
|
3207
|
+
if (!data.capabilities?.includes("embedding") || !data.model_info) {
|
|
3208
|
+
return null;
|
|
3209
|
+
}
|
|
3210
|
+
const dimensions = getPositiveIntegerMetadata(data.model_info, ".embedding_length");
|
|
3211
|
+
const maxTokens = getPositiveIntegerMetadata(data.model_info, ".context_length");
|
|
3212
|
+
if (!dimensions || !maxTokens) {
|
|
3213
|
+
return null;
|
|
3214
|
+
}
|
|
3215
|
+
return {
|
|
3216
|
+
provider: "ollama",
|
|
3217
|
+
model,
|
|
3218
|
+
dimensions,
|
|
3219
|
+
maxTokens,
|
|
3220
|
+
costPer1MTokens: 0
|
|
3221
|
+
};
|
|
3222
|
+
}
|
|
3223
|
+
async function listOllamaModels(credentials) {
|
|
3224
|
+
const response = await fetchOllama(`${credentials.baseUrl}/api/tags`);
|
|
3225
|
+
if (!response.ok) {
|
|
3226
|
+
return [];
|
|
3227
|
+
}
|
|
3228
|
+
const data = await response.json();
|
|
3229
|
+
return [...new Set((data.models ?? []).map((entry) => entry.name ?? entry.model).filter((name) => typeof name === "string" && name.trim().length > 0))];
|
|
3230
|
+
}
|
|
3231
|
+
async function detectOllamaProvider(model) {
|
|
3232
|
+
const credentials = await getOllamaCredentials();
|
|
3233
|
+
if (!credentials) {
|
|
3234
|
+
throw new Error("Preferred provider 'ollama' is not configured or authenticated");
|
|
3235
|
+
}
|
|
3236
|
+
const requestedModel = model?.trim();
|
|
3237
|
+
if (requestedModel) {
|
|
3238
|
+
const catalogModel = findCatalogOllamaModel(requestedModel);
|
|
3239
|
+
if (catalogModel) {
|
|
3240
|
+
return { provider: "ollama", credentials, modelInfo: catalogModel };
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
const candidates = requestedModel ? [requestedModel] : await listOllamaModels(credentials);
|
|
3244
|
+
for (const candidate of candidates) {
|
|
3245
|
+
const modelInfo = await fetchOllamaModelInfo(credentials, candidate);
|
|
3246
|
+
if (modelInfo) {
|
|
3247
|
+
return {
|
|
3248
|
+
provider: "ollama",
|
|
3249
|
+
credentials,
|
|
3250
|
+
modelInfo: findCatalogOllamaModel(candidate) ?? modelInfo
|
|
3251
|
+
};
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
const detail = model ? `Model '${model}' is not installed or is not embedding-capable` : "No installed embedding-capable Ollama model was found";
|
|
3255
|
+
throw new Error(detail);
|
|
3256
|
+
}
|
|
3257
|
+
async function tryDetectOllamaProvider() {
|
|
3258
|
+
try {
|
|
3259
|
+
return await detectOllamaProvider();
|
|
3260
|
+
} catch {
|
|
3261
|
+
return null;
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3218
3264
|
function getProviderDisplayName(provider) {
|
|
3219
3265
|
switch (provider) {
|
|
3220
3266
|
case "github-copilot":
|
|
@@ -3554,6 +3600,7 @@ var GoogleEmbeddingProvider = class _GoogleEmbeddingProvider extends BaseEmbeddi
|
|
|
3554
3600
|
// src/embeddings/providers/ollama.ts
|
|
3555
3601
|
var OllamaEmbeddingProvider = class _OllamaEmbeddingProvider extends BaseEmbeddingProvider {
|
|
3556
3602
|
static MIN_TRUNCATION_CHARS = 512;
|
|
3603
|
+
static REQUEST_TIMEOUT_MS = 12e4;
|
|
3557
3604
|
constructor(credentials, modelInfo) {
|
|
3558
3605
|
super(credentials, modelInfo);
|
|
3559
3606
|
}
|
|
@@ -3628,22 +3675,45 @@ var OllamaEmbeddingProvider = class _OllamaEmbeddingProvider extends BaseEmbeddi
|
|
|
3628
3675
|
}
|
|
3629
3676
|
}
|
|
3630
3677
|
async embedSingle(text) {
|
|
3631
|
-
const
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3678
|
+
const controller = new AbortController();
|
|
3679
|
+
const timeout = setTimeout(
|
|
3680
|
+
() => controller.abort(),
|
|
3681
|
+
_OllamaEmbeddingProvider.REQUEST_TIMEOUT_MS
|
|
3682
|
+
);
|
|
3683
|
+
let response;
|
|
3684
|
+
try {
|
|
3685
|
+
response = await fetch(`${this.credentials.baseUrl}/api/embeddings`, {
|
|
3686
|
+
method: "POST",
|
|
3687
|
+
headers: {
|
|
3688
|
+
"Content-Type": "application/json"
|
|
3689
|
+
},
|
|
3690
|
+
body: JSON.stringify({
|
|
3691
|
+
model: this.modelInfo.model,
|
|
3692
|
+
prompt: text,
|
|
3693
|
+
truncate: false
|
|
3694
|
+
}),
|
|
3695
|
+
signal: controller.signal
|
|
3696
|
+
});
|
|
3697
|
+
} catch (error) {
|
|
3698
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
3699
|
+
throw new Error(
|
|
3700
|
+
`Ollama embedding request timed out after ${_OllamaEmbeddingProvider.REQUEST_TIMEOUT_MS}ms`
|
|
3701
|
+
);
|
|
3702
|
+
}
|
|
3703
|
+
throw error;
|
|
3704
|
+
} finally {
|
|
3705
|
+
clearTimeout(timeout);
|
|
3706
|
+
}
|
|
3642
3707
|
if (!response.ok) {
|
|
3643
3708
|
const error = (await response.text()).slice(0, 500);
|
|
3644
3709
|
throw new Error(`Ollama embedding API error: ${response.status} - ${error}`);
|
|
3645
3710
|
}
|
|
3646
3711
|
const data = await response.json();
|
|
3712
|
+
if (!Array.isArray(data.embedding) || data.embedding.length !== this.modelInfo.dimensions || data.embedding.some((value) => typeof value !== "number" || !Number.isFinite(value))) {
|
|
3713
|
+
throw new Error(
|
|
3714
|
+
`Ollama returned an invalid embedding; expected ${this.modelInfo.dimensions} finite dimensions`
|
|
3715
|
+
);
|
|
3716
|
+
}
|
|
3647
3717
|
return {
|
|
3648
3718
|
embedding: data.embedding,
|
|
3649
3719
|
tokensUsed: this.estimateTokens(text)
|
|
@@ -4506,7 +4576,9 @@ function mapChunk(c) {
|
|
|
4506
4576
|
return {
|
|
4507
4577
|
content: c.content,
|
|
4508
4578
|
startLine: c.startLine ?? c.start_line,
|
|
4579
|
+
startCol: c.startCol ?? c.start_col,
|
|
4509
4580
|
endLine: c.endLine ?? c.end_line,
|
|
4581
|
+
endCol: c.endCol ?? c.end_col,
|
|
4510
4582
|
chunkType: c.chunkType ?? c.chunk_type,
|
|
4511
4583
|
name: c.name ?? void 0,
|
|
4512
4584
|
language: c.language
|
|
@@ -4627,6 +4699,7 @@ function getEmbeddingHeaderParts(chunk, filePath) {
|
|
|
4627
4699
|
javascript: "JavaScript",
|
|
4628
4700
|
python: "Python",
|
|
4629
4701
|
rust: "Rust",
|
|
4702
|
+
swift: "Swift",
|
|
4630
4703
|
go: "Go",
|
|
4631
4704
|
java: "Java"
|
|
4632
4705
|
};
|
|
@@ -4635,7 +4708,16 @@ function getEmbeddingHeaderParts(chunk, filePath) {
|
|
|
4635
4708
|
function: "function",
|
|
4636
4709
|
arrow_function: "arrow function",
|
|
4637
4710
|
method_definition: "method",
|
|
4711
|
+
method_declaration: "method",
|
|
4712
|
+
protocol_function_declaration: "protocol requirement",
|
|
4713
|
+
init_declaration: "initializer",
|
|
4714
|
+
deinit_declaration: "deinitializer",
|
|
4715
|
+
subscript_declaration: "subscript",
|
|
4638
4716
|
class_declaration: "class",
|
|
4717
|
+
actor_declaration: "actor",
|
|
4718
|
+
extension_declaration: "extension",
|
|
4719
|
+
protocol_declaration: "protocol",
|
|
4720
|
+
struct_declaration: "struct",
|
|
4639
4721
|
interface_declaration: "interface",
|
|
4640
4722
|
type_alias_declaration: "type alias",
|
|
4641
4723
|
enum_declaration: "enum",
|
|
@@ -5306,8 +5388,18 @@ async function getChunkGitBlame(projectRoot, filePath, startLine, endLine) {
|
|
|
5306
5388
|
}
|
|
5307
5389
|
|
|
5308
5390
|
// src/indexer/index.ts
|
|
5309
|
-
var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust", "php", "apex", "zig", "gdscript", "matlab", "bash"]);
|
|
5310
|
-
var CASE_INSENSITIVE_LANGUAGES = /* @__PURE__ */ new Set(["apex"]);
|
|
5391
|
+
var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust", "swift", "php", "apex", "zig", "gdscript", "matlab", "bash", "c", "cpp", "metal"]);
|
|
5392
|
+
var CASE_INSENSITIVE_LANGUAGES = /* @__PURE__ */ new Set(["apex", "php"]);
|
|
5393
|
+
var CALL_GRAPH_RESOLUTION_VERSION = "4";
|
|
5394
|
+
var PHP_FUNCTION_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
5395
|
+
"function_declaration",
|
|
5396
|
+
"function",
|
|
5397
|
+
"function_definition"
|
|
5398
|
+
]);
|
|
5399
|
+
var PHP_CLASS_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
5400
|
+
"class_declaration",
|
|
5401
|
+
"class_definition"
|
|
5402
|
+
]);
|
|
5311
5403
|
var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
5312
5404
|
"function_declaration",
|
|
5313
5405
|
"function",
|
|
@@ -5320,6 +5412,9 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
|
5320
5412
|
"enum_declaration",
|
|
5321
5413
|
"function_definition",
|
|
5322
5414
|
"class_definition",
|
|
5415
|
+
"class_specifier",
|
|
5416
|
+
"struct_specifier",
|
|
5417
|
+
"namespace_definition",
|
|
5323
5418
|
"decorated_definition",
|
|
5324
5419
|
"method_declaration",
|
|
5325
5420
|
"type_declaration",
|
|
@@ -5335,6 +5430,14 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
|
5335
5430
|
"test_declaration",
|
|
5336
5431
|
"struct_declaration",
|
|
5337
5432
|
"union_declaration",
|
|
5433
|
+
// Synthetic Swift declarations or declarations specific to tree-sitter-swift.
|
|
5434
|
+
"actor_declaration",
|
|
5435
|
+
"extension_declaration",
|
|
5436
|
+
"protocol_declaration",
|
|
5437
|
+
"protocol_function_declaration",
|
|
5438
|
+
"init_declaration",
|
|
5439
|
+
"deinit_declaration",
|
|
5440
|
+
"subscript_declaration",
|
|
5338
5441
|
// GDScript declarations whose names participate in the call graph.
|
|
5339
5442
|
// `function_definition` and `class_definition` are already in the set
|
|
5340
5443
|
// above (shared with Python/C/Bash and Python, respectively).
|
|
@@ -5344,6 +5447,53 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
|
5344
5447
|
"const_statement",
|
|
5345
5448
|
"class_name_statement"
|
|
5346
5449
|
]);
|
|
5450
|
+
var C_FAMILY_TYPE_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set(["class_specifier", "struct_specifier"]);
|
|
5451
|
+
function isCompatibleCFamilyCallTarget(language, callType, symbolKind) {
|
|
5452
|
+
if (language !== "c" && language !== "cpp") return true;
|
|
5453
|
+
if (symbolKind === "namespace_definition") return callType === "Import";
|
|
5454
|
+
const isTypeSymbol = C_FAMILY_TYPE_SYMBOL_CHUNK_TYPES.has(symbolKind);
|
|
5455
|
+
if (callType === "Constructor" || callType === "Inherits" || callType === "Implements") {
|
|
5456
|
+
return isTypeSymbol;
|
|
5457
|
+
}
|
|
5458
|
+
return !isTypeSymbol;
|
|
5459
|
+
}
|
|
5460
|
+
var EXECUTABLE_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
|
|
5461
|
+
"function_declaration",
|
|
5462
|
+
"function",
|
|
5463
|
+
"arrow_function",
|
|
5464
|
+
"method_definition",
|
|
5465
|
+
"function_definition",
|
|
5466
|
+
"method_declaration",
|
|
5467
|
+
"function_item",
|
|
5468
|
+
"protocol_function_declaration",
|
|
5469
|
+
"init_declaration",
|
|
5470
|
+
"deinit_declaration",
|
|
5471
|
+
"subscript_declaration",
|
|
5472
|
+
"constructor_definition",
|
|
5473
|
+
"trigger_declaration",
|
|
5474
|
+
"test_declaration"
|
|
5475
|
+
]);
|
|
5476
|
+
function findEnclosingSymbol(symbols, line, column) {
|
|
5477
|
+
let best;
|
|
5478
|
+
for (const symbol of symbols) {
|
|
5479
|
+
if (line < symbol.startLine || line > symbol.endLine) continue;
|
|
5480
|
+
if (column !== void 0 && (line === symbol.startLine && column < symbol.startCol || line === symbol.endLine && column >= symbol.endCol)) {
|
|
5481
|
+
continue;
|
|
5482
|
+
}
|
|
5483
|
+
if (!best) {
|
|
5484
|
+
best = symbol;
|
|
5485
|
+
continue;
|
|
5486
|
+
}
|
|
5487
|
+
const span = symbol.endLine - symbol.startLine;
|
|
5488
|
+
const bestSpan = best.endLine - best.startLine;
|
|
5489
|
+
const isNarrowerPositionRange = column !== void 0 && span === bestSpan && symbol.startLine === best.startLine && symbol.endLine === best.endLine && symbol.startCol >= best.startCol && symbol.endCol <= best.endCol && (symbol.startCol > best.startCol || symbol.endCol < best.endCol);
|
|
5490
|
+
const isMoreSpecificTie = span === bestSpan && symbol.startLine === best.startLine && EXECUTABLE_SYMBOL_CHUNK_TYPES.has(symbol.kind) && !EXECUTABLE_SYMBOL_CHUNK_TYPES.has(best.kind);
|
|
5491
|
+
if (span < bestSpan || span === bestSpan && symbol.startLine > best.startLine || isNarrowerPositionRange || isMoreSpecificTie) {
|
|
5492
|
+
best = symbol;
|
|
5493
|
+
}
|
|
5494
|
+
}
|
|
5495
|
+
return best;
|
|
5496
|
+
}
|
|
5347
5497
|
function float32ArrayToBuffer(arr) {
|
|
5348
5498
|
const float32 = new Float32Array(arr);
|
|
5349
5499
|
return Buffer.from(float32.buffer);
|
|
@@ -5428,6 +5578,8 @@ function hasBlameMetadata(metadata) {
|
|
|
5428
5578
|
}
|
|
5429
5579
|
var INDEX_METADATA_VERSION = "1";
|
|
5430
5580
|
var EMBEDDING_STRATEGY_VERSION = "2";
|
|
5581
|
+
var SWIFT_PARSER_VERSION = "1";
|
|
5582
|
+
var METAL_PARSER_VERSION = "1";
|
|
5431
5583
|
var RANKING_TOKEN_CACHE_LIMIT = 4096;
|
|
5432
5584
|
var RANK_HYBRID_CACHE_LIMIT = 256;
|
|
5433
5585
|
function createPendingChunkStorageText(texts) {
|
|
@@ -5750,15 +5902,25 @@ function chunkTypeBoost(chunkType) {
|
|
|
5750
5902
|
case "function_declaration":
|
|
5751
5903
|
case "method":
|
|
5752
5904
|
case "method_definition":
|
|
5905
|
+
case "method_declaration":
|
|
5906
|
+
case "protocol_function_declaration":
|
|
5907
|
+
case "init_declaration":
|
|
5908
|
+
case "deinit_declaration":
|
|
5909
|
+
case "subscript_declaration":
|
|
5753
5910
|
case "class":
|
|
5754
5911
|
case "class_declaration":
|
|
5912
|
+
case "actor_declaration":
|
|
5913
|
+
case "extension_declaration":
|
|
5755
5914
|
return 0.2;
|
|
5756
5915
|
case "interface":
|
|
5757
5916
|
case "type":
|
|
5758
5917
|
case "enum":
|
|
5918
|
+
case "enum_declaration":
|
|
5759
5919
|
case "struct":
|
|
5920
|
+
case "struct_declaration":
|
|
5760
5921
|
case "impl":
|
|
5761
5922
|
case "trait":
|
|
5923
|
+
case "protocol_declaration":
|
|
5762
5924
|
case "module":
|
|
5763
5925
|
return 0.1;
|
|
5764
5926
|
default:
|
|
@@ -5865,11 +6027,21 @@ function isImplementationChunkType(chunkType) {
|
|
|
5865
6027
|
"function_declaration",
|
|
5866
6028
|
"method",
|
|
5867
6029
|
"method_definition",
|
|
6030
|
+
"method_declaration",
|
|
6031
|
+
"protocol_function_declaration",
|
|
6032
|
+
"init_declaration",
|
|
6033
|
+
"deinit_declaration",
|
|
6034
|
+
"subscript_declaration",
|
|
5868
6035
|
"class",
|
|
5869
6036
|
"class_declaration",
|
|
6037
|
+
"actor_declaration",
|
|
6038
|
+
"extension_declaration",
|
|
5870
6039
|
"interface",
|
|
6040
|
+
"protocol_declaration",
|
|
5871
6041
|
"type",
|
|
5872
6042
|
"enum",
|
|
6043
|
+
"enum_declaration",
|
|
6044
|
+
"struct_declaration",
|
|
5873
6045
|
"module"
|
|
5874
6046
|
].includes(chunkType);
|
|
5875
6047
|
}
|
|
@@ -6821,9 +6993,9 @@ var Indexer = class {
|
|
|
6821
6993
|
atomicWriteSync(targetPath, data) {
|
|
6822
6994
|
const lease = this.requireActiveLease();
|
|
6823
6995
|
const tempPath = createLeaseTemporaryPath(targetPath, lease.owner, "tmp");
|
|
6824
|
-
|
|
6996
|
+
mkdirSync2(path13.dirname(targetPath), { recursive: true });
|
|
6825
6997
|
try {
|
|
6826
|
-
|
|
6998
|
+
writeFileSync2(tempPath, data);
|
|
6827
6999
|
renameSync2(tempPath, targetPath);
|
|
6828
7000
|
} finally {
|
|
6829
7001
|
removeLeaseTemporaryPath(tempPath);
|
|
@@ -6872,6 +7044,29 @@ var Indexer = class {
|
|
|
6872
7044
|
const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
|
|
6873
7045
|
return `index.forceReembed.${projectHash}`;
|
|
6874
7046
|
}
|
|
7047
|
+
getCallGraphResolutionMetadataKey() {
|
|
7048
|
+
if (this.config.scope !== "global") {
|
|
7049
|
+
return "index.callGraphResolutionVersion";
|
|
7050
|
+
}
|
|
7051
|
+
const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
|
|
7052
|
+
return `index.callGraphResolutionVersion.${projectHash}`;
|
|
7053
|
+
}
|
|
7054
|
+
getSwiftParserVersionMetadataKey() {
|
|
7055
|
+
const key = "index.parser.swiftVersion";
|
|
7056
|
+
if (this.config.scope !== "global") {
|
|
7057
|
+
return key;
|
|
7058
|
+
}
|
|
7059
|
+
const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
|
|
7060
|
+
return `${key}.${projectHash}`;
|
|
7061
|
+
}
|
|
7062
|
+
getMetalParserVersionMetadataKey() {
|
|
7063
|
+
const key = "index.parser.metalVersion";
|
|
7064
|
+
if (this.config.scope !== "global") {
|
|
7065
|
+
return key;
|
|
7066
|
+
}
|
|
7067
|
+
const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
|
|
7068
|
+
return `${key}.${projectHash}`;
|
|
7069
|
+
}
|
|
6875
7070
|
hasProjectForceReembedPending() {
|
|
6876
7071
|
return this.config.scope === "global" && this.database?.getMetadata(this.getProjectForceReembedMetadataKey()) === "true";
|
|
6877
7072
|
}
|
|
@@ -8032,6 +8227,7 @@ var Indexer = class {
|
|
|
8032
8227
|
this.database.setMetadata("index.embeddingProvider", provider.provider);
|
|
8033
8228
|
this.database.setMetadata("index.embeddingModel", provider.modelInfo.model);
|
|
8034
8229
|
this.database.setMetadata("index.embeddingDimensions", provider.modelInfo.dimensions.toString());
|
|
8230
|
+
this.database.setMetadata(this.getCallGraphResolutionMetadataKey(), CALL_GRAPH_RESOLUTION_VERSION);
|
|
8035
8231
|
if (this.config.scope === "global") {
|
|
8036
8232
|
if (completeProjectEmbeddingStrategyReset) {
|
|
8037
8233
|
this.database.setMetadata(this.getProjectEmbeddingStrategyMetadataKey(), EMBEDDING_STRATEGY_VERSION);
|
|
@@ -8219,6 +8415,20 @@ var Indexer = class {
|
|
|
8219
8415
|
totalChunks: 0
|
|
8220
8416
|
});
|
|
8221
8417
|
this.loadFileHashCache();
|
|
8418
|
+
const swiftParserMetadataKey = this.getSwiftParserVersionMetadataKey();
|
|
8419
|
+
const reparseCachedSwiftFiles = database.getMetadata(swiftParserMetadataKey) !== SWIFT_PARSER_VERSION;
|
|
8420
|
+
const metalParserMetadataKey = this.getMetalParserVersionMetadataKey();
|
|
8421
|
+
const reparseCachedMetalFiles = database.getMetadata(metalParserMetadataKey) !== METAL_PARSER_VERSION;
|
|
8422
|
+
if (reparseCachedSwiftFiles && Array.from(this.fileHashCache.keys()).some(
|
|
8423
|
+
(filePath) => path13.extname(filePath).toLowerCase() === ".swift"
|
|
8424
|
+
)) {
|
|
8425
|
+
this.logger.info("Reindexing cached Swift files for parser support");
|
|
8426
|
+
}
|
|
8427
|
+
if (reparseCachedMetalFiles && Array.from(this.fileHashCache.keys()).some(
|
|
8428
|
+
(filePath) => path13.extname(filePath).toLowerCase() === ".metal"
|
|
8429
|
+
)) {
|
|
8430
|
+
this.logger.info("Reindexing cached Metal files for parser support");
|
|
8431
|
+
}
|
|
8222
8432
|
const includePatterns = [...this.config.include, ...this.config.additionalInclude];
|
|
8223
8433
|
const { files, skipped } = await collectFiles(
|
|
8224
8434
|
this.projectRoot,
|
|
@@ -8238,10 +8448,17 @@ var Indexer = class {
|
|
|
8238
8448
|
const changedFiles = [];
|
|
8239
8449
|
const unchangedFilePaths = /* @__PURE__ */ new Set();
|
|
8240
8450
|
const currentFileHashes = /* @__PURE__ */ new Map();
|
|
8451
|
+
const needsCallGraphResolutionMigration = database.getMetadata(this.getCallGraphResolutionMetadataKey()) !== CALL_GRAPH_RESOLUTION_VERSION;
|
|
8241
8452
|
for (const f of files) {
|
|
8242
8453
|
const currentHash = hashFile(f.path);
|
|
8243
8454
|
currentFileHashes.set(f.path, currentHash);
|
|
8244
|
-
|
|
8455
|
+
const cachedHashMatches = this.fileHashCache.get(f.path) === currentHash;
|
|
8456
|
+
const needsCallGraphRefresh = cachedHashMatches && needsCallGraphResolutionMigration && database.getChunksByFile(f.path).some(
|
|
8457
|
+
(chunk) => chunk.language === "php" || chunk.language === "c" || chunk.language === "cpp"
|
|
8458
|
+
);
|
|
8459
|
+
const requiresSwiftParserUpgrade = reparseCachedSwiftFiles && path13.extname(f.path).toLowerCase() === ".swift";
|
|
8460
|
+
const requiresMetalParserUpgrade = reparseCachedMetalFiles && path13.extname(f.path).toLowerCase() === ".metal";
|
|
8461
|
+
if (cachedHashMatches && !needsCallGraphRefresh && !requiresSwiftParserUpgrade && !requiresMetalParserUpgrade) {
|
|
8245
8462
|
unchangedFilePaths.add(f.path);
|
|
8246
8463
|
this.logger.recordCacheHit();
|
|
8247
8464
|
} else {
|
|
@@ -8443,16 +8660,28 @@ var Indexer = class {
|
|
|
8443
8660
|
const fileSymbols = [];
|
|
8444
8661
|
for (const chunk of parsed.chunks) {
|
|
8445
8662
|
if (!chunk.name || !CALL_GRAPH_SYMBOL_CHUNK_TYPES.has(chunk.chunkType)) continue;
|
|
8446
|
-
const
|
|
8663
|
+
const existingMetalSymbol = chunk.language === "metal" ? fileSymbols.find(
|
|
8664
|
+
(symbol2) => symbol2.name === chunk.name && symbol2.kind === chunk.chunkType && symbol2.startLine <= chunk.endLine && chunk.startLine <= symbol2.endLine
|
|
8665
|
+
) : void 0;
|
|
8666
|
+
if (existingMetalSymbol) {
|
|
8667
|
+
existingMetalSymbol.startLine = Math.min(existingMetalSymbol.startLine, chunk.startLine);
|
|
8668
|
+
existingMetalSymbol.endLine = Math.max(existingMetalSymbol.endLine, chunk.endLine);
|
|
8669
|
+
existingMetalSymbol.startCol = Math.min(existingMetalSymbol.startCol, chunk.startCol ?? 0);
|
|
8670
|
+
existingMetalSymbol.endCol = Math.max(existingMetalSymbol.endCol, chunk.endCol ?? 0);
|
|
8671
|
+
continue;
|
|
8672
|
+
}
|
|
8673
|
+
const symbolId = `sym_${hashContent(
|
|
8674
|
+
parsed.path + ":" + chunk.name + ":" + chunk.chunkType + ":" + chunk.startLine + ":" + (chunk.startCol ?? 0)
|
|
8675
|
+
).slice(0, 16)}`;
|
|
8447
8676
|
const symbol = {
|
|
8448
8677
|
id: symbolId,
|
|
8449
8678
|
filePath: parsed.path,
|
|
8450
8679
|
name: chunk.name,
|
|
8451
8680
|
kind: chunk.chunkType,
|
|
8452
8681
|
startLine: chunk.startLine,
|
|
8453
|
-
startCol: 0,
|
|
8682
|
+
startCol: chunk.startCol ?? 0,
|
|
8454
8683
|
endLine: chunk.endLine,
|
|
8455
|
-
endCol: 0,
|
|
8684
|
+
endCol: chunk.endCol ?? 0,
|
|
8456
8685
|
language: chunk.language
|
|
8457
8686
|
};
|
|
8458
8687
|
fileSymbols.push(symbol);
|
|
@@ -8477,8 +8706,10 @@ var Indexer = class {
|
|
|
8477
8706
|
if (callSites.length === 0) continue;
|
|
8478
8707
|
const edges = [];
|
|
8479
8708
|
for (const site of callSites) {
|
|
8480
|
-
const enclosingSymbol =
|
|
8481
|
-
|
|
8709
|
+
const enclosingSymbol = findEnclosingSymbol(
|
|
8710
|
+
fileSymbols,
|
|
8711
|
+
site.line,
|
|
8712
|
+
site.column
|
|
8482
8713
|
);
|
|
8483
8714
|
if (!enclosingSymbol) continue;
|
|
8484
8715
|
const edgeId = `edge_${hashContent(enclosingSymbol.id + ":" + site.calleeName + ":" + site.line + ":" + site.column).slice(0, 16)}`;
|
|
@@ -8497,7 +8728,21 @@ var Indexer = class {
|
|
|
8497
8728
|
if (edges.length > 0) {
|
|
8498
8729
|
database.upsertCallEdgesBatch(edges);
|
|
8499
8730
|
for (const edge of edges) {
|
|
8500
|
-
|
|
8731
|
+
let candidates = symbolsByName.get(normalizeSymbolKey(edge.targetName));
|
|
8732
|
+
if (fileLanguage === "php" && candidates) {
|
|
8733
|
+
if (edge.callType === "Constructor") {
|
|
8734
|
+
candidates = candidates.filter(
|
|
8735
|
+
(candidate) => PHP_CLASS_SYMBOL_CHUNK_TYPES.has(candidate.kind)
|
|
8736
|
+
);
|
|
8737
|
+
} else if (edge.callType === "Call") {
|
|
8738
|
+
candidates = candidates.filter(
|
|
8739
|
+
(candidate) => PHP_FUNCTION_SYMBOL_CHUNK_TYPES.has(candidate.kind)
|
|
8740
|
+
);
|
|
8741
|
+
}
|
|
8742
|
+
}
|
|
8743
|
+
candidates = candidates?.filter(
|
|
8744
|
+
(symbol) => isCompatibleCFamilyCallTarget(fileLanguage, edge.callType, symbol.kind)
|
|
8745
|
+
);
|
|
8501
8746
|
if (candidates && candidates.length === 1) {
|
|
8502
8747
|
database.resolveCallEdge(edge.id, candidates[0].id);
|
|
8503
8748
|
}
|
|
@@ -8552,6 +8797,8 @@ var Indexer = class {
|
|
|
8552
8797
|
this.saveFileHashCache();
|
|
8553
8798
|
this.saveFailedBatches([]);
|
|
8554
8799
|
}
|
|
8800
|
+
database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);
|
|
8801
|
+
database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);
|
|
8555
8802
|
this.saveIndexMetadata(configuredProviderInfo);
|
|
8556
8803
|
this.indexCompatibility = { compatible: true };
|
|
8557
8804
|
stats.durationMs = Date.now() - startTime;
|
|
@@ -8579,6 +8826,8 @@ var Indexer = class {
|
|
|
8579
8826
|
this.saveFileHashCache();
|
|
8580
8827
|
this.saveFailedBatches([]);
|
|
8581
8828
|
}
|
|
8829
|
+
database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);
|
|
8830
|
+
database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);
|
|
8582
8831
|
this.saveIndexMetadata(configuredProviderInfo);
|
|
8583
8832
|
this.indexCompatibility = { compatible: true };
|
|
8584
8833
|
stats.durationMs = Date.now() - startTime;
|
|
@@ -8849,6 +9098,8 @@ var Indexer = class {
|
|
|
8849
9098
|
if (forceScopedReembed && failedForcedChunkIds.size === 0) {
|
|
8850
9099
|
database.deleteMetadata(this.getProjectForceReembedMetadataKey());
|
|
8851
9100
|
}
|
|
9101
|
+
database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);
|
|
9102
|
+
database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);
|
|
8852
9103
|
this.saveIndexMetadata(configuredProviderInfo);
|
|
8853
9104
|
this.indexCompatibility = { compatible: true };
|
|
8854
9105
|
this.logger.recordIndexingEnd();
|
|
@@ -10403,7 +10654,7 @@ ${truncateContent(r.content)}
|
|
|
10403
10654
|
}
|
|
10404
10655
|
|
|
10405
10656
|
// src/tools/config-state.ts
|
|
10406
|
-
import { existsSync as existsSync9, mkdirSync as
|
|
10657
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
10407
10658
|
import * as path15 from "path";
|
|
10408
10659
|
function normalizeKnowledgeBasePaths(config, projectRoot) {
|
|
10409
10660
|
const normalized = { ...config };
|
|
@@ -10434,7 +10685,7 @@ function saveConfig(projectRoot, config, host = "opencode") {
|
|
|
10434
10685
|
const configDir = path15.dirname(configPath);
|
|
10435
10686
|
const configBaseDir = path15.dirname(configDir);
|
|
10436
10687
|
if (!existsSync9(configDir)) {
|
|
10437
|
-
|
|
10688
|
+
mkdirSync3(configDir, { recursive: true });
|
|
10438
10689
|
}
|
|
10439
10690
|
const serializableConfig = { ...config };
|
|
10440
10691
|
if (Array.isArray(serializableConfig.knowledgeBases)) {
|
|
@@ -10442,7 +10693,7 @@ function saveConfig(projectRoot, config, host = "opencode") {
|
|
|
10442
10693
|
(kb) => serializeConfigPathValue(kb, configBaseDir)
|
|
10443
10694
|
);
|
|
10444
10695
|
}
|
|
10445
|
-
|
|
10696
|
+
writeFileSync3(configPath, JSON.stringify(serializableConfig, null, 2) + "\n", "utf-8");
|
|
10446
10697
|
}
|
|
10447
10698
|
|
|
10448
10699
|
// src/tools/operations.ts
|
|
@@ -10509,15 +10760,6 @@ function refreshIndexerForDirectory(projectRoot, host = "opencode", config = par
|
|
|
10509
10760
|
indexerCache.set(key, indexer);
|
|
10510
10761
|
configCache.set(key, config);
|
|
10511
10762
|
}
|
|
10512
|
-
function shouldForceLocalizeProjectIndex(projectRoot, host = "opencode") {
|
|
10513
|
-
const root = getProjectRoot(projectRoot, host);
|
|
10514
|
-
const localIndexPath = path16.join(root, getHostProjectIndexRelativePath(host));
|
|
10515
|
-
if (existsSync10(localIndexPath)) {
|
|
10516
|
-
return false;
|
|
10517
|
-
}
|
|
10518
|
-
const inheritedIndexPath = resolveWorktreeFallbackProjectIndexPath(root, host);
|
|
10519
|
-
return inheritedIndexPath !== null;
|
|
10520
|
-
}
|
|
10521
10763
|
async function searchCodebase(projectRoot, host, query, options = {}) {
|
|
10522
10764
|
const indexer = getIndexerForProject(projectRoot, host);
|
|
10523
10765
|
return indexer.search(query, options.limit, {
|
|
@@ -10567,9 +10809,7 @@ async function getCallGraphPath(projectRoot, host, from, to, maxDepth) {
|
|
|
10567
10809
|
}
|
|
10568
10810
|
async function runIndexCodebase(projectRoot, host, args, onProgress) {
|
|
10569
10811
|
const root = getProjectRoot(projectRoot, host);
|
|
10570
|
-
const
|
|
10571
|
-
let indexer = getIndexerForProject(root, host);
|
|
10572
|
-
const runtimeConfig = configCache.get(key);
|
|
10812
|
+
const indexer = getIndexerForProject(root, host);
|
|
10573
10813
|
try {
|
|
10574
10814
|
if (args.estimateOnly) {
|
|
10575
10815
|
return { kind: "estimate", estimate: await indexer.estimateCost() };
|
|
@@ -10590,19 +10830,7 @@ async function runIndexCodebase(projectRoot, host, args, onProgress) {
|
|
|
10590
10830
|
return Promise.resolve();
|
|
10591
10831
|
});
|
|
10592
10832
|
};
|
|
10593
|
-
|
|
10594
|
-
if (args.force && shouldForceLocalizeProjectIndex(root, host)) {
|
|
10595
|
-
const inheritedIndexPath = resolveProjectIndexPath(root, runtimeConfig.scope, host);
|
|
10596
|
-
stats = await withIndexLock(inheritedIndexPath, "force-index", async () => {
|
|
10597
|
-
materializeLocalProjectConfig(root, loadProjectConfigLayer(root, host), host);
|
|
10598
|
-
refreshIndexerForDirectory(root, host, runtimeConfig);
|
|
10599
|
-
indexer = getIndexerForProject(root, host);
|
|
10600
|
-
return runIndex(indexer);
|
|
10601
|
-
}, { completeRecoveries: false });
|
|
10602
|
-
} else {
|
|
10603
|
-
stats = await runIndex(indexer);
|
|
10604
|
-
}
|
|
10605
|
-
return { kind: "stats", stats };
|
|
10833
|
+
return { kind: "stats", stats: await runIndex(indexer) };
|
|
10606
10834
|
} catch (error) {
|
|
10607
10835
|
const busyResult = getIndexBusyResult(error);
|
|
10608
10836
|
if (!busyResult) throw error;
|
|
@@ -13227,7 +13455,7 @@ async function resolveCodebaseContext(projectRoot, host, input) {
|
|
|
13227
13455
|
}
|
|
13228
13456
|
|
|
13229
13457
|
// src/tools/index.ts
|
|
13230
|
-
import { writeFileSync as
|
|
13458
|
+
import { writeFileSync as writeFileSync4 } from "fs";
|
|
13231
13459
|
import * as os5 from "os";
|
|
13232
13460
|
import * as path21 from "path";
|
|
13233
13461
|
|
|
@@ -14204,7 +14432,7 @@ var index_visualize = tool2({
|
|
|
14204
14432
|
}
|
|
14205
14433
|
const html = generateVisualizationHtml(vizData);
|
|
14206
14434
|
const outputPath = path21.join(os5.tmpdir(), `call-graph-${Date.now()}.html`);
|
|
14207
|
-
|
|
14435
|
+
writeFileSync4(outputPath, html, "utf-8");
|
|
14208
14436
|
let result = `Temporal call graph visualization generated: ${outputPath}
|
|
14209
14437
|
|
|
14210
14438
|
`;
|