opencode-codebase-index 0.25.0 → 0.25.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/dist/cbi.cjs +1254 -258
- package/dist/cbi.cjs.map +1 -1
- package/dist/cbi.js +1318 -313
- package/dist/cbi.js.map +1 -1
- package/dist/cli.cjs +1617 -528
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1654 -556
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1519 -530
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1583 -585
- package/dist/index.js.map +1 -1
- package/dist/pi-extension.cjs +1492 -484
- package/dist/pi-extension.cjs.map +1 -1
- package/dist/pi-extension.js +1548 -531
- 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 +1 -1
package/dist/cbi.js
CHANGED
|
@@ -329,7 +329,7 @@ var require_ignore = __commonJS({
|
|
|
329
329
|
// path matching.
|
|
330
330
|
// - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
|
|
331
331
|
// @returns {TestResult} true if a file is ignored
|
|
332
|
-
test(
|
|
332
|
+
test(path35, checkUnignored, mode) {
|
|
333
333
|
let ignored = false;
|
|
334
334
|
let unignored = false;
|
|
335
335
|
let matchedRule;
|
|
@@ -338,7 +338,7 @@ var require_ignore = __commonJS({
|
|
|
338
338
|
if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
|
|
339
339
|
return;
|
|
340
340
|
}
|
|
341
|
-
const matched = rule[mode].test(
|
|
341
|
+
const matched = rule[mode].test(path35);
|
|
342
342
|
if (!matched) {
|
|
343
343
|
return;
|
|
344
344
|
}
|
|
@@ -359,17 +359,17 @@ var require_ignore = __commonJS({
|
|
|
359
359
|
var throwError = (message, Ctor) => {
|
|
360
360
|
throw new Ctor(message);
|
|
361
361
|
};
|
|
362
|
-
var checkPath = (
|
|
363
|
-
if (!isString(
|
|
362
|
+
var checkPath = (path35, originalPath, doThrow) => {
|
|
363
|
+
if (!isString(path35)) {
|
|
364
364
|
return doThrow(
|
|
365
365
|
`path must be a string, but got \`${originalPath}\``,
|
|
366
366
|
TypeError
|
|
367
367
|
);
|
|
368
368
|
}
|
|
369
|
-
if (!
|
|
369
|
+
if (!path35) {
|
|
370
370
|
return doThrow(`path must not be empty`, TypeError);
|
|
371
371
|
}
|
|
372
|
-
if (checkPath.isNotRelative(
|
|
372
|
+
if (checkPath.isNotRelative(path35)) {
|
|
373
373
|
const r = "`path.relative()`d";
|
|
374
374
|
return doThrow(
|
|
375
375
|
`path should be a ${r} string, but got "${originalPath}"`,
|
|
@@ -378,7 +378,7 @@ var require_ignore = __commonJS({
|
|
|
378
378
|
}
|
|
379
379
|
return true;
|
|
380
380
|
};
|
|
381
|
-
var isNotRelative = (
|
|
381
|
+
var isNotRelative = (path35) => REGEX_TEST_INVALID_PATH.test(path35);
|
|
382
382
|
checkPath.isNotRelative = isNotRelative;
|
|
383
383
|
checkPath.convert = (p) => p;
|
|
384
384
|
var Ignore2 = class {
|
|
@@ -408,19 +408,19 @@ var require_ignore = __commonJS({
|
|
|
408
408
|
}
|
|
409
409
|
// @returns {TestResult}
|
|
410
410
|
_test(originalPath, cache, checkUnignored, slices) {
|
|
411
|
-
const
|
|
411
|
+
const path35 = originalPath && checkPath.convert(originalPath);
|
|
412
412
|
checkPath(
|
|
413
|
-
|
|
413
|
+
path35,
|
|
414
414
|
originalPath,
|
|
415
415
|
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
416
416
|
);
|
|
417
|
-
return this._t(
|
|
417
|
+
return this._t(path35, cache, checkUnignored, slices);
|
|
418
418
|
}
|
|
419
|
-
checkIgnore(
|
|
420
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
421
|
-
return this.test(
|
|
419
|
+
checkIgnore(path35) {
|
|
420
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path35)) {
|
|
421
|
+
return this.test(path35);
|
|
422
422
|
}
|
|
423
|
-
const slices =
|
|
423
|
+
const slices = path35.split(SLASH).filter(Boolean);
|
|
424
424
|
slices.pop();
|
|
425
425
|
if (slices.length) {
|
|
426
426
|
const parent = this._t(
|
|
@@ -433,18 +433,18 @@ var require_ignore = __commonJS({
|
|
|
433
433
|
return parent;
|
|
434
434
|
}
|
|
435
435
|
}
|
|
436
|
-
return this._rules.test(
|
|
436
|
+
return this._rules.test(path35, false, MODE_CHECK_IGNORE);
|
|
437
437
|
}
|
|
438
|
-
_t(
|
|
439
|
-
if (
|
|
440
|
-
return cache[
|
|
438
|
+
_t(path35, cache, checkUnignored, slices) {
|
|
439
|
+
if (path35 in cache) {
|
|
440
|
+
return cache[path35];
|
|
441
441
|
}
|
|
442
442
|
if (!slices) {
|
|
443
|
-
slices =
|
|
443
|
+
slices = path35.split(SLASH).filter(Boolean);
|
|
444
444
|
}
|
|
445
445
|
slices.pop();
|
|
446
446
|
if (!slices.length) {
|
|
447
|
-
return cache[
|
|
447
|
+
return cache[path35] = this._rules.test(path35, checkUnignored, MODE_IGNORE);
|
|
448
448
|
}
|
|
449
449
|
const parent = this._t(
|
|
450
450
|
slices.join(SLASH) + SLASH,
|
|
@@ -452,29 +452,29 @@ var require_ignore = __commonJS({
|
|
|
452
452
|
checkUnignored,
|
|
453
453
|
slices
|
|
454
454
|
);
|
|
455
|
-
return cache[
|
|
455
|
+
return cache[path35] = parent.ignored ? parent : this._rules.test(path35, checkUnignored, MODE_IGNORE);
|
|
456
456
|
}
|
|
457
|
-
ignores(
|
|
458
|
-
return this._test(
|
|
457
|
+
ignores(path35) {
|
|
458
|
+
return this._test(path35, this._ignoreCache, false).ignored;
|
|
459
459
|
}
|
|
460
460
|
createFilter() {
|
|
461
|
-
return (
|
|
461
|
+
return (path35) => !this.ignores(path35);
|
|
462
462
|
}
|
|
463
463
|
filter(paths) {
|
|
464
464
|
return makeArray(paths).filter(this.createFilter());
|
|
465
465
|
}
|
|
466
466
|
// @returns {TestResult}
|
|
467
|
-
test(
|
|
468
|
-
return this._test(
|
|
467
|
+
test(path35) {
|
|
468
|
+
return this._test(path35, this._testCache, true);
|
|
469
469
|
}
|
|
470
470
|
};
|
|
471
471
|
var factory = (options) => new Ignore2(options);
|
|
472
|
-
var isPathValid = (
|
|
472
|
+
var isPathValid = (path35) => checkPath(path35 && checkPath.convert(path35), path35, RETURN_FALSE);
|
|
473
473
|
var setupWindows = () => {
|
|
474
474
|
const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
|
|
475
475
|
checkPath.convert = makePosix;
|
|
476
476
|
const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
|
|
477
|
-
checkPath.isNotRelative = (
|
|
477
|
+
checkPath.isNotRelative = (path35) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path35) || isNotRelative(path35);
|
|
478
478
|
};
|
|
479
479
|
if (
|
|
480
480
|
// Detect `process` so that it can run in browsers.
|
|
@@ -652,8 +652,8 @@ var require_eventemitter3 = __commonJS({
|
|
|
652
652
|
});
|
|
653
653
|
|
|
654
654
|
// src/adapters/cbi.ts
|
|
655
|
-
import { realpathSync as
|
|
656
|
-
import * as
|
|
655
|
+
import { realpathSync as realpathSync8 } from "fs";
|
|
656
|
+
import * as path34 from "path";
|
|
657
657
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
658
658
|
|
|
659
659
|
// src/config/host.ts
|
|
@@ -1720,8 +1720,8 @@ var autoDetectProviders = AUTO_DETECT_PROVIDER_ORDER.filter(
|
|
|
1720
1720
|
);
|
|
1721
1721
|
|
|
1722
1722
|
// src/tools/operations.ts
|
|
1723
|
-
import { existsSync as
|
|
1724
|
-
import * as
|
|
1723
|
+
import { existsSync as existsSync13, realpathSync as realpathSync6, statSync as statSync5 } from "fs";
|
|
1724
|
+
import * as path21 from "path";
|
|
1725
1725
|
|
|
1726
1726
|
// src/tools/knowledge-base-paths.ts
|
|
1727
1727
|
import * as path8 from "path";
|
|
@@ -2521,9 +2521,9 @@ ${truncateContent(r.content)}
|
|
|
2521
2521
|
}
|
|
2522
2522
|
|
|
2523
2523
|
// src/utils/auto-index.ts
|
|
2524
|
-
import { existsSync as
|
|
2525
|
-
import * as
|
|
2526
|
-
import * as
|
|
2524
|
+
import { existsSync as existsSync8, realpathSync as realpathSync4 } from "fs";
|
|
2525
|
+
import * as os4 from "os";
|
|
2526
|
+
import * as path12 from "path";
|
|
2527
2527
|
|
|
2528
2528
|
// src/indexer/index-lock.ts
|
|
2529
2529
|
import { randomUUID } from "crypto";
|
|
@@ -2780,7 +2780,7 @@ function removeDeadReclaimMarker(lockPath, expectedOwner) {
|
|
|
2780
2780
|
return true;
|
|
2781
2781
|
}
|
|
2782
2782
|
function reclaimDeadOwner(indexPath, lockPath, expectedOwner) {
|
|
2783
|
-
const
|
|
2783
|
+
const reclaimPath2 = path9.join(lockPath, RECLAIM_DIRECTORY_NAME);
|
|
2784
2784
|
const reclaimOwner = {
|
|
2785
2785
|
pid: process.pid,
|
|
2786
2786
|
hostname: os2.hostname(),
|
|
@@ -2789,19 +2789,19 @@ function reclaimDeadOwner(indexPath, lockPath, expectedOwner) {
|
|
|
2789
2789
|
expectedOwnerToken: expectedOwner.token
|
|
2790
2790
|
};
|
|
2791
2791
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
2792
|
-
if (publishJsonDirectory(
|
|
2792
|
+
if (publishJsonDirectory(reclaimPath2, reclaimOwner)) break;
|
|
2793
2793
|
if (attempt === 0 && removeDeadReclaimMarker(lockPath, expectedOwner)) continue;
|
|
2794
2794
|
return false;
|
|
2795
2795
|
}
|
|
2796
2796
|
try {
|
|
2797
|
-
const currentReclaimer = readReclaimOwner(
|
|
2797
|
+
const currentReclaimer = readReclaimOwner(reclaimPath2);
|
|
2798
2798
|
const currentOwner = readDirectoryOwner(lockPath);
|
|
2799
2799
|
if (!currentReclaimer || !sameReclaimOwner(currentReclaimer, reclaimOwner) || !currentOwner || !sameOwner(currentOwner, expectedOwner) || getOwnerLiveness(currentOwner) !== "dead") {
|
|
2800
2800
|
return false;
|
|
2801
2801
|
}
|
|
2802
2802
|
publishRecoveryMarker(indexPath, expectedOwner);
|
|
2803
2803
|
const ownerBeforeQuarantine = readDirectoryOwner(lockPath);
|
|
2804
|
-
const reclaimerBeforeQuarantine = readReclaimOwner(
|
|
2804
|
+
const reclaimerBeforeQuarantine = readReclaimOwner(reclaimPath2);
|
|
2805
2805
|
if (!ownerBeforeQuarantine || !sameOwner(ownerBeforeQuarantine, expectedOwner) || getOwnerLiveness(ownerBeforeQuarantine) !== "dead" || !reclaimerBeforeQuarantine || !sameReclaimOwner(reclaimerBeforeQuarantine, reclaimOwner)) {
|
|
2806
2806
|
return false;
|
|
2807
2807
|
}
|
|
@@ -2971,10 +2971,889 @@ function completeLeaseRecovery(lease) {
|
|
|
2971
2971
|
}
|
|
2972
2972
|
}
|
|
2973
2973
|
|
|
2974
|
+
// src/utils/background-worker.ts
|
|
2975
|
+
import { createHash, randomUUID as randomUUID2 } from "crypto";
|
|
2976
|
+
import {
|
|
2977
|
+
existsSync as existsSync6,
|
|
2978
|
+
lstatSync as lstatSync2,
|
|
2979
|
+
mkdirSync as mkdirSync2,
|
|
2980
|
+
readFileSync as readFileSync5,
|
|
2981
|
+
realpathSync as realpathSync3,
|
|
2982
|
+
renameSync as renameSync2,
|
|
2983
|
+
rmSync as rmSync2,
|
|
2984
|
+
writeFileSync as writeFileSync2
|
|
2985
|
+
} from "fs";
|
|
2986
|
+
import * as os3 from "os";
|
|
2987
|
+
import * as path10 from "path";
|
|
2988
|
+
var OWNER_FILE_NAME2 = "owner.json";
|
|
2989
|
+
var HEARTBEAT_FILE_PREFIX = "heartbeat.";
|
|
2990
|
+
var RECLAIM_DIRECTORY_NAME2 = "reclaim";
|
|
2991
|
+
var REFRESH_REQUEST_FILE_NAME = "refresh-request.json";
|
|
2992
|
+
var HEARTBEAT_INTERVAL_MS = 5e3;
|
|
2993
|
+
var STALE_LEASE_MS = 3e4;
|
|
2994
|
+
var RETRY_DELAY_MS = 5e3;
|
|
2995
|
+
var UUID_PATTERN2 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
2996
|
+
var BackgroundWorkerStopError = class extends Error {
|
|
2997
|
+
constructor(watcherError, autoIndexError) {
|
|
2998
|
+
super("Failed to stop background worker");
|
|
2999
|
+
this.watcherError = watcherError;
|
|
3000
|
+
this.autoIndexError = autoIndexError;
|
|
3001
|
+
this.name = "BackgroundWorkerStopError";
|
|
3002
|
+
}
|
|
3003
|
+
watcherError;
|
|
3004
|
+
autoIndexError;
|
|
3005
|
+
};
|
|
3006
|
+
var workers = /* @__PURE__ */ new Map();
|
|
3007
|
+
var workerKeysByProject = /* @__PURE__ */ new Map();
|
|
3008
|
+
var workerReplacementBarriers = /* @__PURE__ */ new Map();
|
|
3009
|
+
function getErrorCode2(error) {
|
|
3010
|
+
return typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
|
|
3011
|
+
}
|
|
3012
|
+
function canonicalizePath(targetPath) {
|
|
3013
|
+
const resolved = path10.resolve(targetPath);
|
|
3014
|
+
if (existsSync6(resolved)) {
|
|
3015
|
+
try {
|
|
3016
|
+
return realpathSync3.native(resolved);
|
|
3017
|
+
} catch {
|
|
3018
|
+
return resolved;
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
const parent = path10.dirname(resolved);
|
|
3022
|
+
if (parent === resolved) return resolved;
|
|
3023
|
+
return path10.join(canonicalizePath(parent), path10.basename(resolved));
|
|
3024
|
+
}
|
|
3025
|
+
function projectLookupKey(projectRoot, host) {
|
|
3026
|
+
return `${host}::${canonicalizePath(projectRoot)}`;
|
|
3027
|
+
}
|
|
3028
|
+
function resolveIdentity(projectRoot, config, host) {
|
|
3029
|
+
const canonicalProjectRoot = canonicalizePath(projectRoot);
|
|
3030
|
+
const canonicalIndexPath = canonicalizePath(resolveProjectIndexPath(projectRoot, config.scope, host));
|
|
3031
|
+
return {
|
|
3032
|
+
canonicalIndexPath,
|
|
3033
|
+
canonicalProjectRoot,
|
|
3034
|
+
key: `${canonicalIndexPath}::${canonicalProjectRoot}`
|
|
3035
|
+
};
|
|
3036
|
+
}
|
|
3037
|
+
function controllerKey(identity, host) {
|
|
3038
|
+
return `${identity.key}::${host}`;
|
|
3039
|
+
}
|
|
3040
|
+
function leaseDirectoryName(identity) {
|
|
3041
|
+
const hash = createHash("sha256").update(identity.key).digest("hex").slice(0, 32);
|
|
3042
|
+
return `background-worker.${hash}.lease`;
|
|
3043
|
+
}
|
|
3044
|
+
function leasePathFor(identity) {
|
|
3045
|
+
return path10.join(identity.canonicalIndexPath, leaseDirectoryName(identity));
|
|
3046
|
+
}
|
|
3047
|
+
function parseOwner2(value) {
|
|
3048
|
+
if (typeof value !== "object" || value === null) return null;
|
|
3049
|
+
const candidate = value;
|
|
3050
|
+
if (candidate.version !== 1) return null;
|
|
3051
|
+
if (!Number.isInteger(candidate.pid) || (candidate.pid ?? 0) <= 0) return null;
|
|
3052
|
+
if (typeof candidate.hostname !== "string" || candidate.hostname.length === 0) return null;
|
|
3053
|
+
if (typeof candidate.startedAt !== "string" || Number.isNaN(Date.parse(candidate.startedAt))) return null;
|
|
3054
|
+
if (typeof candidate.heartbeatAt !== "string" || Number.isNaN(Date.parse(candidate.heartbeatAt))) return null;
|
|
3055
|
+
if (typeof candidate.projectRoot !== "string" || candidate.projectRoot.length === 0) return null;
|
|
3056
|
+
if (typeof candidate.indexPath !== "string" || candidate.indexPath.length === 0) return null;
|
|
3057
|
+
if (typeof candidate.token !== "string" || !UUID_PATTERN2.test(candidate.token)) return null;
|
|
3058
|
+
return candidate;
|
|
3059
|
+
}
|
|
3060
|
+
function parseHeartbeat(value, expectedToken) {
|
|
3061
|
+
if (typeof value !== "object" || value === null) return null;
|
|
3062
|
+
const candidate = value;
|
|
3063
|
+
if (candidate.version !== 1 || candidate.token !== expectedToken) return null;
|
|
3064
|
+
if (typeof candidate.heartbeatAt !== "string" || Number.isNaN(Date.parse(candidate.heartbeatAt))) return null;
|
|
3065
|
+
return candidate;
|
|
3066
|
+
}
|
|
3067
|
+
function parseReclaimOwner2(value) {
|
|
3068
|
+
if (typeof value !== "object" || value === null) return null;
|
|
3069
|
+
const candidate = value;
|
|
3070
|
+
if (candidate.version !== 1) return null;
|
|
3071
|
+
if (!Number.isInteger(candidate.pid) || (candidate.pid ?? 0) <= 0) return null;
|
|
3072
|
+
if (typeof candidate.hostname !== "string" || candidate.hostname.length === 0) return null;
|
|
3073
|
+
if (typeof candidate.startedAt !== "string" || Number.isNaN(Date.parse(candidate.startedAt))) return null;
|
|
3074
|
+
if (typeof candidate.token !== "string" || !UUID_PATTERN2.test(candidate.token)) return null;
|
|
3075
|
+
if (candidate.expectedOwnerToken !== null && (typeof candidate.expectedOwnerToken !== "string" || !UUID_PATTERN2.test(candidate.expectedOwnerToken))) return null;
|
|
3076
|
+
return candidate;
|
|
3077
|
+
}
|
|
3078
|
+
function heartbeatPath(leasePath, token) {
|
|
3079
|
+
return path10.join(leasePath, `${HEARTBEAT_FILE_PREFIX}${token}.json`);
|
|
3080
|
+
}
|
|
3081
|
+
function reclaimPath(leasePath) {
|
|
3082
|
+
return path10.join(leasePath, RECLAIM_DIRECTORY_NAME2);
|
|
3083
|
+
}
|
|
3084
|
+
function refreshRequestPath(leasePath) {
|
|
3085
|
+
return path10.join(leasePath, REFRESH_REQUEST_FILE_NAME);
|
|
3086
|
+
}
|
|
3087
|
+
function readLeaseOwner(leasePath) {
|
|
3088
|
+
try {
|
|
3089
|
+
return parseOwner2(JSON.parse(readFileSync5(path10.join(leasePath, OWNER_FILE_NAME2), "utf-8")));
|
|
3090
|
+
} catch {
|
|
3091
|
+
return null;
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
function readOwner(leasePath) {
|
|
3095
|
+
const owner = readLeaseOwner(leasePath);
|
|
3096
|
+
if (!owner) return null;
|
|
3097
|
+
try {
|
|
3098
|
+
const heartbeat = parseHeartbeat(
|
|
3099
|
+
JSON.parse(readFileSync5(heartbeatPath(leasePath, owner.token), "utf-8")),
|
|
3100
|
+
owner.token
|
|
3101
|
+
);
|
|
3102
|
+
return heartbeat ? { ...owner, heartbeatAt: heartbeat.heartbeatAt } : owner;
|
|
3103
|
+
} catch {
|
|
3104
|
+
return owner;
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3107
|
+
function readReclaimOwner2(leasePath) {
|
|
3108
|
+
try {
|
|
3109
|
+
return parseReclaimOwner2(JSON.parse(readFileSync5(path10.join(reclaimPath(leasePath), OWNER_FILE_NAME2), "utf-8")));
|
|
3110
|
+
} catch {
|
|
3111
|
+
return null;
|
|
3112
|
+
}
|
|
3113
|
+
}
|
|
3114
|
+
function ownerLiveness(owner) {
|
|
3115
|
+
if (owner.hostname !== os3.hostname()) return "unknown";
|
|
3116
|
+
try {
|
|
3117
|
+
process.kill(owner.pid, 0);
|
|
3118
|
+
return "alive";
|
|
3119
|
+
} catch (error) {
|
|
3120
|
+
const code = getErrorCode2(error);
|
|
3121
|
+
if (code === "ESRCH") return "dead";
|
|
3122
|
+
if (code === "EPERM") return "alive";
|
|
3123
|
+
return "unknown";
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
function isHeartbeatExpired(owner) {
|
|
3127
|
+
return Date.now() - Date.parse(owner.heartbeatAt) >= STALE_LEASE_MS;
|
|
3128
|
+
}
|
|
3129
|
+
function sameOwner2(left, right) {
|
|
3130
|
+
return left.pid === right.pid && left.hostname === right.hostname && left.token === right.token;
|
|
3131
|
+
}
|
|
3132
|
+
function writeHeartbeat(leasePath, owner) {
|
|
3133
|
+
const targetPath = heartbeatPath(leasePath, owner.token);
|
|
3134
|
+
const temporaryPath = `${targetPath}.tmp.${process.pid}.${owner.token}.${randomUUID2()}`;
|
|
3135
|
+
const heartbeat = {
|
|
3136
|
+
version: 1,
|
|
3137
|
+
token: owner.token,
|
|
3138
|
+
heartbeatAt: owner.heartbeatAt
|
|
3139
|
+
};
|
|
3140
|
+
try {
|
|
3141
|
+
writeFileSync2(temporaryPath, JSON.stringify(heartbeat), {
|
|
3142
|
+
encoding: "utf-8",
|
|
3143
|
+
flag: "wx",
|
|
3144
|
+
mode: 384
|
|
3145
|
+
});
|
|
3146
|
+
renameSync2(temporaryPath, targetPath);
|
|
3147
|
+
const currentOwner = readLeaseOwner(leasePath);
|
|
3148
|
+
return currentOwner !== null && sameOwner2(currentOwner, owner);
|
|
3149
|
+
} finally {
|
|
3150
|
+
if (existsSync6(temporaryPath)) rmSync2(temporaryPath, { force: true });
|
|
3151
|
+
}
|
|
3152
|
+
}
|
|
3153
|
+
function requestRefreshFromLeader(leasePath, allowDisabledAutoIndex) {
|
|
3154
|
+
const requestPath = refreshRequestPath(leasePath);
|
|
3155
|
+
const temporaryPath = `${requestPath}.tmp.${process.pid}.${randomUUID2()}`;
|
|
3156
|
+
try {
|
|
3157
|
+
const request = {
|
|
3158
|
+
allowDisabledAutoIndex,
|
|
3159
|
+
requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3160
|
+
version: 1
|
|
3161
|
+
};
|
|
3162
|
+
writeFileSync2(temporaryPath, JSON.stringify(request), {
|
|
3163
|
+
encoding: "utf-8",
|
|
3164
|
+
flag: "wx",
|
|
3165
|
+
mode: 384
|
|
3166
|
+
});
|
|
3167
|
+
renameSync2(temporaryPath, requestPath);
|
|
3168
|
+
} catch (error) {
|
|
3169
|
+
if (getErrorCode2(error) !== "ENOENT") {
|
|
3170
|
+
console.error("[codebase-index] Failed to request background index refresh from the project worker:", error);
|
|
3171
|
+
}
|
|
3172
|
+
} finally {
|
|
3173
|
+
if (existsSync6(temporaryPath)) rmSync2(temporaryPath, { force: true });
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
function consumeRefreshRequest(leasePath) {
|
|
3177
|
+
const requestPath = refreshRequestPath(leasePath);
|
|
3178
|
+
const claimedPath = `${requestPath}.handling.${process.pid}.${randomUUID2()}`;
|
|
3179
|
+
try {
|
|
3180
|
+
renameSync2(requestPath, claimedPath);
|
|
3181
|
+
} catch (error) {
|
|
3182
|
+
if (getErrorCode2(error) === "ENOENT") return null;
|
|
3183
|
+
throw error;
|
|
3184
|
+
}
|
|
3185
|
+
try {
|
|
3186
|
+
const value = JSON.parse(readFileSync5(claimedPath, "utf-8"));
|
|
3187
|
+
return {
|
|
3188
|
+
allowDisabledAutoIndex: value.version === 1 && value.allowDisabledAutoIndex === true,
|
|
3189
|
+
requestedAt: typeof value.requestedAt === "string" ? value.requestedAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
3190
|
+
version: 1
|
|
3191
|
+
};
|
|
3192
|
+
} catch {
|
|
3193
|
+
return { allowDisabledAutoIndex: false, requestedAt: (/* @__PURE__ */ new Date()).toISOString(), version: 1 };
|
|
3194
|
+
} finally {
|
|
3195
|
+
rmSync2(claimedPath, { force: true });
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
function publishLease(leasePath, owner) {
|
|
3199
|
+
const candidatePath = `${leasePath}.candidate.${process.pid}.${owner.token}`;
|
|
3200
|
+
try {
|
|
3201
|
+
mkdirSync2(candidatePath, { mode: 448 });
|
|
3202
|
+
} catch (error) {
|
|
3203
|
+
if (getErrorCode2(error) === "ENOENT") return false;
|
|
3204
|
+
throw error;
|
|
3205
|
+
}
|
|
3206
|
+
try {
|
|
3207
|
+
writeFileSync2(path10.join(candidatePath, OWNER_FILE_NAME2), JSON.stringify(owner), {
|
|
3208
|
+
encoding: "utf-8",
|
|
3209
|
+
flag: "wx",
|
|
3210
|
+
mode: 384
|
|
3211
|
+
});
|
|
3212
|
+
if (existsSync6(leasePath)) return false;
|
|
3213
|
+
try {
|
|
3214
|
+
renameSync2(candidatePath, leasePath);
|
|
3215
|
+
return true;
|
|
3216
|
+
} catch (error) {
|
|
3217
|
+
if (existsSync6(leasePath) || getErrorCode2(error) === "ENOENT") return false;
|
|
3218
|
+
throw error;
|
|
3219
|
+
}
|
|
3220
|
+
} finally {
|
|
3221
|
+
if (existsSync6(candidatePath)) rmSync2(candidatePath, { recursive: true, force: true });
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3224
|
+
function sameReclaimOwner2(left, right) {
|
|
3225
|
+
return left.pid === right.pid && left.hostname === right.hostname && left.token === right.token && left.expectedOwnerToken === right.expectedOwnerToken;
|
|
3226
|
+
}
|
|
3227
|
+
function reclaimerLiveness(owner) {
|
|
3228
|
+
return ownerLiveness(owner);
|
|
3229
|
+
}
|
|
3230
|
+
function isReclaimMarkerExpired(leasePath, owner) {
|
|
3231
|
+
const startedAt = owner ? Date.parse(owner.startedAt) : (() => {
|
|
3232
|
+
try {
|
|
3233
|
+
return lstatSync2(reclaimPath(leasePath)).mtimeMs;
|
|
3234
|
+
} catch {
|
|
3235
|
+
return Date.now();
|
|
3236
|
+
}
|
|
3237
|
+
})();
|
|
3238
|
+
return Date.now() - startedAt >= STALE_LEASE_MS;
|
|
3239
|
+
}
|
|
3240
|
+
function hasActiveReclaimMarker(leasePath, owner) {
|
|
3241
|
+
const marker = readReclaimOwner2(leasePath);
|
|
3242
|
+
return marker !== null && marker.expectedOwnerToken === owner.token && (marker.hostname !== os3.hostname() || ownerLiveness(owner) !== "alive");
|
|
3243
|
+
}
|
|
3244
|
+
function publishReclaimMarker(leasePath, expectedOwner) {
|
|
3245
|
+
const markerPath = reclaimPath(leasePath);
|
|
3246
|
+
const owner = {
|
|
3247
|
+
version: 1,
|
|
3248
|
+
pid: process.pid,
|
|
3249
|
+
hostname: os3.hostname(),
|
|
3250
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3251
|
+
token: randomUUID2(),
|
|
3252
|
+
expectedOwnerToken: expectedOwner?.token ?? null
|
|
3253
|
+
};
|
|
3254
|
+
try {
|
|
3255
|
+
mkdirSync2(markerPath, { mode: 448 });
|
|
3256
|
+
} catch (error) {
|
|
3257
|
+
if (getErrorCode2(error) === "EEXIST" || getErrorCode2(error) === "ENOENT") return null;
|
|
3258
|
+
throw error;
|
|
3259
|
+
}
|
|
3260
|
+
try {
|
|
3261
|
+
writeFileSync2(path10.join(markerPath, OWNER_FILE_NAME2), JSON.stringify(owner), {
|
|
3262
|
+
encoding: "utf-8",
|
|
3263
|
+
flag: "wx",
|
|
3264
|
+
mode: 384
|
|
3265
|
+
});
|
|
3266
|
+
return owner;
|
|
3267
|
+
} catch (error) {
|
|
3268
|
+
rmSync2(markerPath, { recursive: true, force: true });
|
|
3269
|
+
throw error;
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
function removeExpiredReclaimMarker(leasePath, expectedOwner) {
|
|
3273
|
+
const marker = readReclaimOwner2(leasePath);
|
|
3274
|
+
const markerPath = reclaimPath(leasePath);
|
|
3275
|
+
if (!existsSync6(markerPath)) return false;
|
|
3276
|
+
if (marker && marker.expectedOwnerToken !== (expectedOwner?.token ?? null)) return false;
|
|
3277
|
+
if (marker && (reclaimerLiveness(marker) === "alive" || !isReclaimMarkerExpired(leasePath, marker))) return false;
|
|
3278
|
+
if (!marker && !isReclaimMarkerExpired(leasePath, null)) return false;
|
|
3279
|
+
const staleMarkerPath = `${markerPath}.stale.${marker?.pid ?? process.pid}.${marker?.token ?? randomUUID2()}.${randomUUID2()}`;
|
|
3280
|
+
try {
|
|
3281
|
+
renameSync2(markerPath, staleMarkerPath);
|
|
3282
|
+
} catch (error) {
|
|
3283
|
+
if (getErrorCode2(error) === "ENOENT") return false;
|
|
3284
|
+
throw error;
|
|
3285
|
+
}
|
|
3286
|
+
try {
|
|
3287
|
+
let claimedMarker = null;
|
|
3288
|
+
try {
|
|
3289
|
+
claimedMarker = parseReclaimOwner2(
|
|
3290
|
+
JSON.parse(readFileSync5(path10.join(staleMarkerPath, OWNER_FILE_NAME2), "utf-8"))
|
|
3291
|
+
);
|
|
3292
|
+
} catch {
|
|
3293
|
+
claimedMarker = null;
|
|
3294
|
+
}
|
|
3295
|
+
const markerMatches = marker ? claimedMarker !== null && sameReclaimOwner2(claimedMarker, marker) : claimedMarker === null;
|
|
3296
|
+
if (!markerMatches || !canReclaimLease(leasePath, expectedOwner)) {
|
|
3297
|
+
if (!existsSync6(markerPath) && existsSync6(staleMarkerPath)) renameSync2(staleMarkerPath, markerPath);
|
|
3298
|
+
return false;
|
|
3299
|
+
}
|
|
3300
|
+
rmSync2(staleMarkerPath, { recursive: true, force: true });
|
|
3301
|
+
return true;
|
|
3302
|
+
} catch (error) {
|
|
3303
|
+
if (getErrorCode2(error) === "ENOENT") return false;
|
|
3304
|
+
throw error;
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
function canReclaimLease(leasePath, expectedOwner) {
|
|
3308
|
+
if (!existsSync6(leasePath)) return false;
|
|
3309
|
+
if (!expectedOwner) return false;
|
|
3310
|
+
const currentOwner = readOwner(leasePath);
|
|
3311
|
+
if (!currentOwner || !sameOwner2(currentOwner, expectedOwner)) return false;
|
|
3312
|
+
if (currentOwner.hostname === os3.hostname()) {
|
|
3313
|
+
return ownerLiveness(currentOwner) === "dead";
|
|
3314
|
+
}
|
|
3315
|
+
return isHeartbeatExpired(currentOwner);
|
|
3316
|
+
}
|
|
3317
|
+
function reclaimLease(leasePath, expectedOwner) {
|
|
3318
|
+
let marker = null;
|
|
3319
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
3320
|
+
marker = publishReclaimMarker(leasePath, expectedOwner);
|
|
3321
|
+
if (marker) break;
|
|
3322
|
+
if (attempt === 0 && removeExpiredReclaimMarker(leasePath, expectedOwner)) continue;
|
|
3323
|
+
return false;
|
|
3324
|
+
}
|
|
3325
|
+
if (!marker) return false;
|
|
3326
|
+
const markerPath = reclaimPath(leasePath);
|
|
3327
|
+
try {
|
|
3328
|
+
const currentMarker = readReclaimOwner2(leasePath);
|
|
3329
|
+
if (!currentMarker || !sameReclaimOwner2(currentMarker, marker) || !canReclaimLease(leasePath, expectedOwner)) {
|
|
3330
|
+
return false;
|
|
3331
|
+
}
|
|
3332
|
+
const stalePath = `${leasePath}.stale.${process.pid}.${marker.token}`;
|
|
3333
|
+
renameSync2(leasePath, stalePath);
|
|
3334
|
+
const quarantinedOwner = readOwner(stalePath);
|
|
3335
|
+
const quarantinedMarker = readReclaimOwner2(stalePath);
|
|
3336
|
+
if (!quarantinedMarker || !sameReclaimOwner2(quarantinedMarker, marker) || expectedOwner !== null && (!quarantinedOwner || !sameOwner2(quarantinedOwner, expectedOwner))) {
|
|
3337
|
+
if (!existsSync6(leasePath) && existsSync6(stalePath)) renameSync2(stalePath, leasePath);
|
|
3338
|
+
return false;
|
|
3339
|
+
}
|
|
3340
|
+
rmSync2(stalePath, { recursive: true, force: true });
|
|
3341
|
+
return true;
|
|
3342
|
+
} catch (error) {
|
|
3343
|
+
if (getErrorCode2(error) === "ENOENT") return false;
|
|
3344
|
+
throw error;
|
|
3345
|
+
} finally {
|
|
3346
|
+
const currentMarker = readReclaimOwner2(leasePath);
|
|
3347
|
+
if (currentMarker && sameReclaimOwner2(currentMarker, marker)) {
|
|
3348
|
+
rmSync2(markerPath, { recursive: true, force: true });
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3352
|
+
function acquireLease(identity) {
|
|
3353
|
+
mkdirSync2(identity.canonicalIndexPath, { recursive: true, mode: 448 });
|
|
3354
|
+
const canonicalIndexPath = realpathSync3.native(identity.canonicalIndexPath);
|
|
3355
|
+
const leasePath = path10.join(canonicalIndexPath, leaseDirectoryName({ ...identity, canonicalIndexPath }));
|
|
3356
|
+
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
3357
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3358
|
+
const owner = {
|
|
3359
|
+
version: 1,
|
|
3360
|
+
pid: process.pid,
|
|
3361
|
+
hostname: os3.hostname(),
|
|
3362
|
+
startedAt: timestamp,
|
|
3363
|
+
heartbeatAt: timestamp,
|
|
3364
|
+
projectRoot: identity.canonicalProjectRoot,
|
|
3365
|
+
indexPath: canonicalIndexPath,
|
|
3366
|
+
token: randomUUID2()
|
|
3367
|
+
};
|
|
3368
|
+
if (publishLease(leasePath, owner)) {
|
|
3369
|
+
return { leasePath, owner };
|
|
3370
|
+
}
|
|
3371
|
+
const existingOwner = readOwner(leasePath);
|
|
3372
|
+
if (existingOwner) {
|
|
3373
|
+
if (canReclaimLease(leasePath, existingOwner) && reclaimLease(leasePath, existingOwner)) continue;
|
|
3374
|
+
return null;
|
|
3375
|
+
}
|
|
3376
|
+
return null;
|
|
3377
|
+
}
|
|
3378
|
+
return null;
|
|
3379
|
+
}
|
|
3380
|
+
function releaseLease(lease) {
|
|
3381
|
+
const currentOwner = readOwner(lease.leasePath);
|
|
3382
|
+
if (!currentOwner || !sameOwner2(currentOwner, lease.owner)) return false;
|
|
3383
|
+
const releasePath = `${lease.leasePath}.release.${lease.owner.pid}.${lease.owner.token}`;
|
|
3384
|
+
try {
|
|
3385
|
+
renameSync2(lease.leasePath, releasePath);
|
|
3386
|
+
} catch (error) {
|
|
3387
|
+
if (getErrorCode2(error) === "ENOENT") return false;
|
|
3388
|
+
throw error;
|
|
3389
|
+
}
|
|
3390
|
+
const claimedOwner = readOwner(releasePath);
|
|
3391
|
+
if (!claimedOwner || !sameOwner2(claimedOwner, lease.owner)) {
|
|
3392
|
+
if (!existsSync6(lease.leasePath) && existsSync6(releasePath)) {
|
|
3393
|
+
renameSync2(releasePath, lease.leasePath);
|
|
3394
|
+
}
|
|
3395
|
+
return false;
|
|
3396
|
+
}
|
|
3397
|
+
rmSync2(releasePath, { recursive: true, force: true });
|
|
3398
|
+
return true;
|
|
3399
|
+
}
|
|
3400
|
+
var BackgroundWorkerController = class {
|
|
3401
|
+
constructor(projectRoot, host, config, hooks, identity) {
|
|
3402
|
+
this.projectRoot = projectRoot;
|
|
3403
|
+
this.host = host;
|
|
3404
|
+
this.config = config;
|
|
3405
|
+
this.hooks = hooks;
|
|
3406
|
+
this.identity = identity;
|
|
3407
|
+
}
|
|
3408
|
+
projectRoot;
|
|
3409
|
+
host;
|
|
3410
|
+
config;
|
|
3411
|
+
hooks;
|
|
3412
|
+
identity;
|
|
3413
|
+
lease = null;
|
|
3414
|
+
watcher = null;
|
|
3415
|
+
leaderReady = Promise.resolve();
|
|
3416
|
+
heartbeatTimer = null;
|
|
3417
|
+
retryTimer = null;
|
|
3418
|
+
teardownRetryTimer = null;
|
|
3419
|
+
transition = Promise.resolve();
|
|
3420
|
+
stopPromise = null;
|
|
3421
|
+
stopped = false;
|
|
3422
|
+
stopping = false;
|
|
3423
|
+
losingLeadership = false;
|
|
3424
|
+
restartAfterStop = false;
|
|
3425
|
+
leaderWorkStopped = false;
|
|
3426
|
+
startingLeaderWork = false;
|
|
3427
|
+
stopAutoIndexOnTeardown = true;
|
|
3428
|
+
autoIndexStarted = false;
|
|
3429
|
+
reportedError = null;
|
|
3430
|
+
update(config, hooks, options) {
|
|
3431
|
+
const autoIndexWasEnabled = this.config.indexing.autoIndex;
|
|
3432
|
+
const shouldReplaceWatcher = this.watcher !== null && hooks.watcherFactory !== void 0 && (hooks.watcherFactory === null || hooks.replaceWatcher === true);
|
|
3433
|
+
this.config = config;
|
|
3434
|
+
this.hooks = {
|
|
3435
|
+
...this.hooks,
|
|
3436
|
+
...hooks,
|
|
3437
|
+
watcherFactory: hooks.watcherFactory === void 0 ? this.hooks.watcherFactory : hooks.watcherFactory,
|
|
3438
|
+
watcherFactoryForConfig: hooks.watcherFactoryForConfig === void 0 ? this.hooks.watcherFactoryForConfig : hooks.watcherFactoryForConfig
|
|
3439
|
+
};
|
|
3440
|
+
if (autoIndexWasEnabled && !config.indexing.autoIndex || options.restartAutoIndex === true && config.indexing.autoIndex && !this.startingLeaderWork) {
|
|
3441
|
+
this.autoIndexStarted = false;
|
|
3442
|
+
}
|
|
3443
|
+
if (!this.canRun()) {
|
|
3444
|
+
void this.stop().catch((error) => {
|
|
3445
|
+
console.error("[codebase-index] Failed to stop background worker after disabling automatic work:", error);
|
|
3446
|
+
});
|
|
3447
|
+
return;
|
|
3448
|
+
}
|
|
3449
|
+
if (shouldReplaceWatcher) {
|
|
3450
|
+
void this.enqueue(async () => {
|
|
3451
|
+
const watcher = this.watcher;
|
|
3452
|
+
if (watcher) {
|
|
3453
|
+
await watcher.stop();
|
|
3454
|
+
if (this.watcher === watcher) this.watcher = null;
|
|
3455
|
+
}
|
|
3456
|
+
if (this.lease && !this.stopped) this.startLeaderWork();
|
|
3457
|
+
}).catch((error) => {
|
|
3458
|
+
console.error("[codebase-index] Failed to replace background file watcher:", error);
|
|
3459
|
+
});
|
|
3460
|
+
}
|
|
3461
|
+
this.start();
|
|
3462
|
+
}
|
|
3463
|
+
startAfter(activation) {
|
|
3464
|
+
this.transition = activation.catch(() => void 0);
|
|
3465
|
+
this.start();
|
|
3466
|
+
}
|
|
3467
|
+
start() {
|
|
3468
|
+
if (!this.canRun() || this.losingLeadership) return;
|
|
3469
|
+
if (this.stopping) {
|
|
3470
|
+
this.restartAfterStop = true;
|
|
3471
|
+
return;
|
|
3472
|
+
}
|
|
3473
|
+
this.stopped = false;
|
|
3474
|
+
void this.enqueue(async () => {
|
|
3475
|
+
if (this.stopped || this.stopping || this.losingLeadership || !this.canRun()) return;
|
|
3476
|
+
if (!this.lease) {
|
|
3477
|
+
try {
|
|
3478
|
+
this.lease = acquireLease(this.identity);
|
|
3479
|
+
this.reportedError = null;
|
|
3480
|
+
} catch (error) {
|
|
3481
|
+
this.reportAcquireError(error);
|
|
3482
|
+
this.scheduleRetry();
|
|
3483
|
+
return;
|
|
3484
|
+
}
|
|
3485
|
+
}
|
|
3486
|
+
if (!this.lease) {
|
|
3487
|
+
this.scheduleRetry();
|
|
3488
|
+
return;
|
|
3489
|
+
}
|
|
3490
|
+
this.startHeartbeat();
|
|
3491
|
+
this.startLeaderWork();
|
|
3492
|
+
});
|
|
3493
|
+
}
|
|
3494
|
+
waitForStart() {
|
|
3495
|
+
return this.transition.catch(() => void 0).then(() => this.leaderReady);
|
|
3496
|
+
}
|
|
3497
|
+
requestRefresh(allowDisabledAutoIndex = false) {
|
|
3498
|
+
this.start();
|
|
3499
|
+
if (!this.isLeader()) {
|
|
3500
|
+
requestRefreshFromLeader(leasePathFor(this.identity), allowDisabledAutoIndex);
|
|
3501
|
+
return;
|
|
3502
|
+
}
|
|
3503
|
+
void this.enqueue(async () => {
|
|
3504
|
+
if (this.stopped || !this.lease) return;
|
|
3505
|
+
this.hooks.startAutoIndex("retrieval", allowDisabledAutoIndex);
|
|
3506
|
+
});
|
|
3507
|
+
}
|
|
3508
|
+
isLeader() {
|
|
3509
|
+
return this.lease !== null && !this.stopping && !this.losingLeadership;
|
|
3510
|
+
}
|
|
3511
|
+
isStopping() {
|
|
3512
|
+
return this.stopping;
|
|
3513
|
+
}
|
|
3514
|
+
getHooksForConfig(config) {
|
|
3515
|
+
const watcherFactoryForConfig = this.hooks.watcherFactoryForConfig;
|
|
3516
|
+
if (!watcherFactoryForConfig) return this.hooks;
|
|
3517
|
+
return {
|
|
3518
|
+
...this.hooks,
|
|
3519
|
+
watcherFactory: watcherFactoryForConfig(config),
|
|
3520
|
+
replaceWatcher: true
|
|
3521
|
+
};
|
|
3522
|
+
}
|
|
3523
|
+
attachWatcher(watcherFactory, watcherFactoryForConfig) {
|
|
3524
|
+
if (this.hooks.watcherFactory !== void 0) return;
|
|
3525
|
+
this.hooks = {
|
|
3526
|
+
...this.hooks,
|
|
3527
|
+
watcherFactory,
|
|
3528
|
+
watcherFactoryForConfig: watcherFactoryForConfig ?? this.hooks.watcherFactoryForConfig
|
|
3529
|
+
};
|
|
3530
|
+
this.start();
|
|
3531
|
+
}
|
|
3532
|
+
async stop(stopAutoIndex = true) {
|
|
3533
|
+
if (this.stopPromise) return this.stopPromise;
|
|
3534
|
+
this.stopped = true;
|
|
3535
|
+
this.stopping = true;
|
|
3536
|
+
this.stopAutoIndexOnTeardown &&= stopAutoIndex;
|
|
3537
|
+
this.clearRetryTimer();
|
|
3538
|
+
const attempt = this.enqueue(async () => {
|
|
3539
|
+
try {
|
|
3540
|
+
const lease = this.lease;
|
|
3541
|
+
if (this.leaderWorkStopped) {
|
|
3542
|
+
if (lease) {
|
|
3543
|
+
this.releaseStoppedLease(lease);
|
|
3544
|
+
} else {
|
|
3545
|
+
this.finishStoppedLease();
|
|
3546
|
+
}
|
|
3547
|
+
return;
|
|
3548
|
+
}
|
|
3549
|
+
const hadLeaderWork = lease !== null || this.watcher !== null || this.autoIndexStarted;
|
|
3550
|
+
const stopped = await this.stopLeaderWork(hadLeaderWork && this.stopAutoIndexOnTeardown);
|
|
3551
|
+
if (!lease) {
|
|
3552
|
+
this.finishStoppedLease();
|
|
3553
|
+
return;
|
|
3554
|
+
}
|
|
3555
|
+
if (!stopped.completed) {
|
|
3556
|
+
this.releaseLeaseWhenAutoIndexStops(lease, stopped.completion);
|
|
3557
|
+
return;
|
|
3558
|
+
}
|
|
3559
|
+
this.leaderWorkStopped = true;
|
|
3560
|
+
this.releaseStoppedLease(lease);
|
|
3561
|
+
} catch (error) {
|
|
3562
|
+
this.scheduleTeardownRetry();
|
|
3563
|
+
throw error;
|
|
3564
|
+
}
|
|
3565
|
+
});
|
|
3566
|
+
const completion = attempt.finally(() => {
|
|
3567
|
+
if (this.stopPromise === completion) this.stopPromise = null;
|
|
3568
|
+
});
|
|
3569
|
+
this.stopPromise = completion;
|
|
3570
|
+
return completion;
|
|
3571
|
+
}
|
|
3572
|
+
canRun() {
|
|
3573
|
+
return this.config.indexing.autoIndex || this.hooks.watcherFactory != null;
|
|
3574
|
+
}
|
|
3575
|
+
enqueue(operation) {
|
|
3576
|
+
const next = this.transition.catch(() => void 0).then(operation);
|
|
3577
|
+
this.transition = next;
|
|
3578
|
+
return next;
|
|
3579
|
+
}
|
|
3580
|
+
startLeaderWork() {
|
|
3581
|
+
if (this.stopped || this.stopping || this.losingLeadership) return;
|
|
3582
|
+
this.startingLeaderWork = true;
|
|
3583
|
+
try {
|
|
3584
|
+
if (this.config.indexing.autoIndex && !this.autoIndexStarted) {
|
|
3585
|
+
this.autoIndexStarted = true;
|
|
3586
|
+
this.hooks.startAutoIndex("startup");
|
|
3587
|
+
}
|
|
3588
|
+
if (!this.watcher && this.hooks.watcherFactory) {
|
|
3589
|
+
try {
|
|
3590
|
+
const watcher = this.hooks.watcherFactory();
|
|
3591
|
+
this.watcher = watcher;
|
|
3592
|
+
this.leaderReady = watcher.whenReady?.().catch((error) => {
|
|
3593
|
+
console.error("[codebase-index] Failed while waiting for background file watcher startup:", error);
|
|
3594
|
+
}) ?? Promise.resolve();
|
|
3595
|
+
} catch (error) {
|
|
3596
|
+
console.error("[codebase-index] Failed to start background file watcher:", error);
|
|
3597
|
+
this.leaderReady = Promise.resolve();
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
} finally {
|
|
3601
|
+
this.startingLeaderWork = false;
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
async stopLeaderWork(stopAutoIndex) {
|
|
3605
|
+
const watcher = this.watcher;
|
|
3606
|
+
let watcherError;
|
|
3607
|
+
if (watcher) {
|
|
3608
|
+
try {
|
|
3609
|
+
await watcher.stop();
|
|
3610
|
+
if (this.watcher === watcher) this.watcher = null;
|
|
3611
|
+
} catch (error) {
|
|
3612
|
+
watcherError = error;
|
|
3613
|
+
}
|
|
3614
|
+
}
|
|
3615
|
+
let autoIndexError;
|
|
3616
|
+
let autoIndexStop = {
|
|
3617
|
+
completed: true,
|
|
3618
|
+
completion: Promise.resolve()
|
|
3619
|
+
};
|
|
3620
|
+
if (stopAutoIndex) {
|
|
3621
|
+
try {
|
|
3622
|
+
autoIndexStop = await this.hooks.stopAutoIndex();
|
|
3623
|
+
this.autoIndexStarted = false;
|
|
3624
|
+
} catch (error) {
|
|
3625
|
+
autoIndexError = error;
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
if (watcherError !== void 0 || autoIndexError !== void 0) {
|
|
3629
|
+
throw new BackgroundWorkerStopError(watcherError, autoIndexError);
|
|
3630
|
+
}
|
|
3631
|
+
return autoIndexStop;
|
|
3632
|
+
}
|
|
3633
|
+
releaseLeaseWhenAutoIndexStops(lease, completion) {
|
|
3634
|
+
void completion.then(
|
|
3635
|
+
() => {
|
|
3636
|
+
void this.enqueue(async () => {
|
|
3637
|
+
if (this.lease !== lease || !this.stopping) return;
|
|
3638
|
+
this.leaderWorkStopped = true;
|
|
3639
|
+
this.releaseStoppedLease(lease);
|
|
3640
|
+
}).catch((error) => {
|
|
3641
|
+
console.error("[codebase-index] Failed to release background worker lease after automatic indexing stopped:", error);
|
|
3642
|
+
this.scheduleTeardownRetry();
|
|
3643
|
+
});
|
|
3644
|
+
},
|
|
3645
|
+
(error) => {
|
|
3646
|
+
console.error("[codebase-index] Failed while waiting for automatic indexing to stop:", error);
|
|
3647
|
+
this.scheduleTeardownRetry();
|
|
3648
|
+
}
|
|
3649
|
+
);
|
|
3650
|
+
}
|
|
3651
|
+
releaseStoppedLease(lease) {
|
|
3652
|
+
if (this.lease !== lease) {
|
|
3653
|
+
this.finishStoppedLease();
|
|
3654
|
+
return;
|
|
3655
|
+
}
|
|
3656
|
+
releaseLease(lease);
|
|
3657
|
+
this.lease = null;
|
|
3658
|
+
this.finishStoppedLease();
|
|
3659
|
+
}
|
|
3660
|
+
finishStoppedLease() {
|
|
3661
|
+
this.leaderWorkStopped = false;
|
|
3662
|
+
this.stopAutoIndexOnTeardown = true;
|
|
3663
|
+
this.stopping = false;
|
|
3664
|
+
this.clearTimers();
|
|
3665
|
+
this.restartAfterTeardown();
|
|
3666
|
+
if (!this.stopped || this.stopping) return;
|
|
3667
|
+
const projectKey = projectLookupKey(this.projectRoot, this.host);
|
|
3668
|
+
const key = controllerKey(this.identity, this.host);
|
|
3669
|
+
if (workers.get(key) === this) workers.delete(key);
|
|
3670
|
+
if (workerKeysByProject.get(projectKey) === key) workerKeysByProject.delete(projectKey);
|
|
3671
|
+
}
|
|
3672
|
+
startHeartbeat() {
|
|
3673
|
+
if (this.heartbeatTimer) return;
|
|
3674
|
+
const heartbeat = () => {
|
|
3675
|
+
void this.heartbeat();
|
|
3676
|
+
};
|
|
3677
|
+
this.heartbeatTimer = setInterval(heartbeat, HEARTBEAT_INTERVAL_MS);
|
|
3678
|
+
this.heartbeatTimer.unref?.();
|
|
3679
|
+
}
|
|
3680
|
+
async heartbeat() {
|
|
3681
|
+
const lease = this.lease;
|
|
3682
|
+
if (!lease || this.losingLeadership || this.stopped && !this.stopping) return;
|
|
3683
|
+
if (hasActiveReclaimMarker(lease.leasePath, lease.owner)) {
|
|
3684
|
+
await this.loseLeadership();
|
|
3685
|
+
return;
|
|
3686
|
+
}
|
|
3687
|
+
const currentOwner = readOwner(lease.leasePath);
|
|
3688
|
+
if (!currentOwner || !sameOwner2(currentOwner, lease.owner)) {
|
|
3689
|
+
await this.loseLeadership();
|
|
3690
|
+
return;
|
|
3691
|
+
}
|
|
3692
|
+
try {
|
|
3693
|
+
const nextOwner = { ...lease.owner, heartbeatAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
3694
|
+
if (!writeHeartbeat(lease.leasePath, nextOwner)) {
|
|
3695
|
+
await this.loseLeadership();
|
|
3696
|
+
return;
|
|
3697
|
+
}
|
|
3698
|
+
lease.owner = nextOwner;
|
|
3699
|
+
const refreshRequest = !this.stopping ? consumeRefreshRequest(lease.leasePath) : null;
|
|
3700
|
+
if (refreshRequest) {
|
|
3701
|
+
this.hooks.startAutoIndex("retrieval", refreshRequest.allowDisabledAutoIndex);
|
|
3702
|
+
}
|
|
3703
|
+
} catch (error) {
|
|
3704
|
+
const ownerAfterError = readOwner(lease.leasePath);
|
|
3705
|
+
if (hasActiveReclaimMarker(lease.leasePath, lease.owner) || !ownerAfterError || !sameOwner2(ownerAfterError, lease.owner)) {
|
|
3706
|
+
await this.loseLeadership();
|
|
3707
|
+
return;
|
|
3708
|
+
}
|
|
3709
|
+
console.error("[codebase-index] Failed to renew background worker lease:", error);
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
async loseLeadership() {
|
|
3713
|
+
if (this.losingLeadership) return;
|
|
3714
|
+
this.losingLeadership = true;
|
|
3715
|
+
this.clearHeartbeat();
|
|
3716
|
+
await this.enqueue(async () => this.stopAfterLeadershipLoss());
|
|
3717
|
+
}
|
|
3718
|
+
async stopAfterLeadershipLoss() {
|
|
3719
|
+
const lease = this.lease;
|
|
3720
|
+
if (!lease) {
|
|
3721
|
+
this.losingLeadership = false;
|
|
3722
|
+
return;
|
|
3723
|
+
}
|
|
3724
|
+
try {
|
|
3725
|
+
const stopped = await this.stopLeaderWork(true);
|
|
3726
|
+
this.lease = null;
|
|
3727
|
+
this.losingLeadership = false;
|
|
3728
|
+
if (stopped.completed) {
|
|
3729
|
+
this.scheduleRetry();
|
|
3730
|
+
} else {
|
|
3731
|
+
void stopped.completion.then(() => this.scheduleRetry());
|
|
3732
|
+
}
|
|
3733
|
+
} catch (error) {
|
|
3734
|
+
console.error("[codebase-index] Failed to stop background work after losing its lease:", error);
|
|
3735
|
+
this.scheduleLostLeadershipTeardownRetry();
|
|
3736
|
+
}
|
|
3737
|
+
}
|
|
3738
|
+
scheduleRetry() {
|
|
3739
|
+
if (this.stopped || !this.canRun() || this.retryTimer) return;
|
|
3740
|
+
this.retryTimer = setTimeout(() => {
|
|
3741
|
+
this.retryTimer = null;
|
|
3742
|
+
this.start();
|
|
3743
|
+
}, RETRY_DELAY_MS);
|
|
3744
|
+
this.retryTimer.unref?.();
|
|
3745
|
+
}
|
|
3746
|
+
scheduleTeardownRetry() {
|
|
3747
|
+
if (!this.stopping || this.teardownRetryTimer) return;
|
|
3748
|
+
this.teardownRetryTimer = setTimeout(() => {
|
|
3749
|
+
this.teardownRetryTimer = null;
|
|
3750
|
+
void this.stop(this.stopAutoIndexOnTeardown).catch((error) => {
|
|
3751
|
+
console.error("[codebase-index] Failed to retry background worker teardown:", error);
|
|
3752
|
+
});
|
|
3753
|
+
}, RETRY_DELAY_MS);
|
|
3754
|
+
this.teardownRetryTimer.unref?.();
|
|
3755
|
+
}
|
|
3756
|
+
restartAfterTeardown() {
|
|
3757
|
+
if (!this.restartAfterStop || !this.canRun() || this.losingLeadership) return;
|
|
3758
|
+
this.restartAfterStop = false;
|
|
3759
|
+
this.stopped = false;
|
|
3760
|
+
this.start();
|
|
3761
|
+
}
|
|
3762
|
+
scheduleLostLeadershipTeardownRetry() {
|
|
3763
|
+
if (this.stopped || !this.losingLeadership || this.retryTimer) return;
|
|
3764
|
+
this.retryTimer = setTimeout(() => {
|
|
3765
|
+
this.retryTimer = null;
|
|
3766
|
+
void this.enqueue(async () => this.stopAfterLeadershipLoss());
|
|
3767
|
+
}, RETRY_DELAY_MS);
|
|
3768
|
+
this.retryTimer.unref?.();
|
|
3769
|
+
}
|
|
3770
|
+
clearHeartbeat() {
|
|
3771
|
+
if (!this.heartbeatTimer) return;
|
|
3772
|
+
clearInterval(this.heartbeatTimer);
|
|
3773
|
+
this.heartbeatTimer = null;
|
|
3774
|
+
}
|
|
3775
|
+
clearTimers() {
|
|
3776
|
+
this.clearHeartbeat();
|
|
3777
|
+
this.clearRetryTimer();
|
|
3778
|
+
if (this.teardownRetryTimer) {
|
|
3779
|
+
clearTimeout(this.teardownRetryTimer);
|
|
3780
|
+
this.teardownRetryTimer = null;
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
clearRetryTimer() {
|
|
3784
|
+
if (!this.retryTimer) return;
|
|
3785
|
+
clearTimeout(this.retryTimer);
|
|
3786
|
+
this.retryTimer = null;
|
|
3787
|
+
}
|
|
3788
|
+
reportAcquireError(error) {
|
|
3789
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3790
|
+
if (this.reportedError === message) return;
|
|
3791
|
+
this.reportedError = message;
|
|
3792
|
+
console.error("[codebase-index] Failed to acquire background worker lease:", error);
|
|
3793
|
+
}
|
|
3794
|
+
};
|
|
3795
|
+
function configureBackgroundWorker(projectRoot, host, config, hooks, options = {}) {
|
|
3796
|
+
const projectKey = projectLookupKey(projectRoot, host);
|
|
3797
|
+
const identity = resolveIdentity(projectRoot, config, host);
|
|
3798
|
+
const key = controllerKey(identity, host);
|
|
3799
|
+
const previousKey = workerKeysByProject.get(projectKey);
|
|
3800
|
+
if (previousKey && previousKey !== key) {
|
|
3801
|
+
const previous = workers.get(previousKey);
|
|
3802
|
+
const previousBarrier = workerReplacementBarriers.get(projectKey) ?? Promise.resolve();
|
|
3803
|
+
const stopPrevious = previous?.stop(options.stopPreviousAutoIndex ?? true) ?? Promise.resolve();
|
|
3804
|
+
const activation = Promise.all([previousBarrier, stopPrevious]).then(() => void 0);
|
|
3805
|
+
workerReplacementBarriers.set(projectKey, activation);
|
|
3806
|
+
workers.delete(previousKey);
|
|
3807
|
+
const worker2 = new BackgroundWorkerController(projectRoot, host, config, hooks, identity);
|
|
3808
|
+
worker2.startAfter(activation);
|
|
3809
|
+
workers.set(key, worker2);
|
|
3810
|
+
workerKeysByProject.set(projectKey, key);
|
|
3811
|
+
return;
|
|
3812
|
+
}
|
|
3813
|
+
let worker = workers.get(key);
|
|
3814
|
+
if (!worker) {
|
|
3815
|
+
worker = new BackgroundWorkerController(projectRoot, host, config, hooks, identity);
|
|
3816
|
+
workers.set(key, worker);
|
|
3817
|
+
} else {
|
|
3818
|
+
worker.update(config, hooks, options);
|
|
3819
|
+
}
|
|
3820
|
+
workerKeysByProject.set(projectKey, key);
|
|
3821
|
+
worker.start();
|
|
3822
|
+
}
|
|
3823
|
+
function updateBackgroundWorkerConfig(projectRoot, host, config) {
|
|
3824
|
+
const projectKey = projectLookupKey(projectRoot, host);
|
|
3825
|
+
const key = workerKeysByProject.get(projectKey);
|
|
3826
|
+
const worker = key ? workers.get(key) : void 0;
|
|
3827
|
+
if (!worker) return;
|
|
3828
|
+
configureBackgroundWorker(projectRoot, host, config, worker.getHooksForConfig(config), {
|
|
3829
|
+
stopPreviousAutoIndex: false,
|
|
3830
|
+
restartAutoIndex: true
|
|
3831
|
+
});
|
|
3832
|
+
}
|
|
3833
|
+
function requestBackgroundWorkerRefresh(projectRoot, host, allowDisabledAutoIndex = false) {
|
|
3834
|
+
const key = workerKeysByProject.get(projectLookupKey(projectRoot, host));
|
|
3835
|
+
workers.get(key ?? "")?.requestRefresh(allowDisabledAutoIndex);
|
|
3836
|
+
}
|
|
3837
|
+
function isBackgroundWorkerManaged(projectRoot, host) {
|
|
3838
|
+
const key = workerKeysByProject.get(projectLookupKey(projectRoot, host));
|
|
3839
|
+
return key !== void 0 && workers.has(key);
|
|
3840
|
+
}
|
|
3841
|
+
function isBackgroundWorkerLeader(projectRoot, host) {
|
|
3842
|
+
const key = workerKeysByProject.get(projectLookupKey(projectRoot, host));
|
|
3843
|
+
return key !== void 0 && workers.get(key)?.isLeader() === true;
|
|
3844
|
+
}
|
|
3845
|
+
async function stopBackgroundWorker(projectRoot, host) {
|
|
3846
|
+
const projectKey = projectLookupKey(projectRoot, host);
|
|
3847
|
+
const key = workerKeysByProject.get(projectKey);
|
|
3848
|
+
const worker = key ? workers.get(key) : void 0;
|
|
3849
|
+
if (!worker) return;
|
|
3850
|
+
await worker.stop();
|
|
3851
|
+
}
|
|
3852
|
+
|
|
2974
3853
|
// src/utils/files.ts
|
|
2975
3854
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
2976
|
-
import { existsSync as
|
|
2977
|
-
import * as
|
|
3855
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6, promises as fsPromises } from "fs";
|
|
3856
|
+
import * as path11 from "path";
|
|
2978
3857
|
var PROJECT_MARKERS = [
|
|
2979
3858
|
".git",
|
|
2980
3859
|
"package.json",
|
|
@@ -2992,7 +3871,7 @@ var PROJECT_MARKERS = [
|
|
|
2992
3871
|
];
|
|
2993
3872
|
function hasProjectMarker(projectRoot) {
|
|
2994
3873
|
for (const marker of PROJECT_MARKERS) {
|
|
2995
|
-
if (
|
|
3874
|
+
if (existsSync7(path11.join(projectRoot, marker))) {
|
|
2996
3875
|
return true;
|
|
2997
3876
|
}
|
|
2998
3877
|
}
|
|
@@ -3019,13 +3898,40 @@ function createIgnoreFilter(projectRoot) {
|
|
|
3019
3898
|
"**/*build*/**"
|
|
3020
3899
|
];
|
|
3021
3900
|
ig.add(defaultIgnores);
|
|
3022
|
-
const gitignorePath =
|
|
3023
|
-
if (
|
|
3024
|
-
const gitignoreContent =
|
|
3901
|
+
const gitignorePath = path11.join(projectRoot, ".gitignore");
|
|
3902
|
+
if (existsSync7(gitignorePath)) {
|
|
3903
|
+
const gitignoreContent = readFileSync6(gitignorePath, "utf-8");
|
|
3025
3904
|
ig.add(gitignoreContent);
|
|
3026
3905
|
}
|
|
3027
3906
|
return ig;
|
|
3028
3907
|
}
|
|
3908
|
+
function toPosixRelativePath(relativePath) {
|
|
3909
|
+
return relativePath.split(path11.sep).join("/");
|
|
3910
|
+
}
|
|
3911
|
+
function matchesAnyGlob(filePath, patterns) {
|
|
3912
|
+
const normalized = toPosixRelativePath(filePath);
|
|
3913
|
+
return patterns.some((pattern) => matchGlob(normalized, pattern));
|
|
3914
|
+
}
|
|
3915
|
+
function isExcludedByPatterns(relativePath, excludePatterns) {
|
|
3916
|
+
return matchesAnyGlob(relativePath, excludePatterns);
|
|
3917
|
+
}
|
|
3918
|
+
function isExcludedDirectory(relativePath, excludePatterns) {
|
|
3919
|
+
const normalized = toPosixRelativePath(relativePath);
|
|
3920
|
+
if (matchesAnyGlob(normalized, excludePatterns)) {
|
|
3921
|
+
return true;
|
|
3922
|
+
}
|
|
3923
|
+
for (const pattern of excludePatterns) {
|
|
3924
|
+
const posixPattern = toPosixRelativePath(pattern).replace(/\/+$/, "");
|
|
3925
|
+
if (!posixPattern.endsWith("/**")) {
|
|
3926
|
+
continue;
|
|
3927
|
+
}
|
|
3928
|
+
const directoryPattern = posixPattern.slice(0, -3);
|
|
3929
|
+
if (directoryPattern && matchesAnyGlob(normalized, [directoryPattern])) {
|
|
3930
|
+
return true;
|
|
3931
|
+
}
|
|
3932
|
+
}
|
|
3933
|
+
return false;
|
|
3934
|
+
}
|
|
3029
3935
|
function matchGlob(filePath, pattern) {
|
|
3030
3936
|
if (pattern.startsWith("**/")) {
|
|
3031
3937
|
const withoutPrefix = pattern.slice(3);
|
|
@@ -3046,8 +3952,8 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
|
|
|
3046
3952
|
const filesInDir = [];
|
|
3047
3953
|
const subdirs = [];
|
|
3048
3954
|
for (const entry of entries) {
|
|
3049
|
-
const fullPath =
|
|
3050
|
-
const relativePath =
|
|
3955
|
+
const fullPath = path11.join(dir, entry.name);
|
|
3956
|
+
const relativePath = toPosixRelativePath(path11.relative(projectRoot, fullPath));
|
|
3051
3957
|
if (isHiddenPathSegment(entry.name)) {
|
|
3052
3958
|
if (entry.isDirectory()) {
|
|
3053
3959
|
skipped.push({ path: relativePath, reason: "excluded" });
|
|
@@ -3065,6 +3971,10 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
|
|
|
3065
3971
|
continue;
|
|
3066
3972
|
}
|
|
3067
3973
|
if (entry.isDirectory()) {
|
|
3974
|
+
if (isExcludedDirectory(relativePath, excludePatterns)) {
|
|
3975
|
+
skipped.push({ path: relativePath, reason: "excluded" });
|
|
3976
|
+
continue;
|
|
3977
|
+
}
|
|
3068
3978
|
subdirs.push({ fullPath, relativePath });
|
|
3069
3979
|
} else if (entry.isFile()) {
|
|
3070
3980
|
const stat2 = await fsPromises.stat(fullPath);
|
|
@@ -3072,20 +3982,11 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
|
|
|
3072
3982
|
skipped.push({ path: relativePath, reason: "too_large" });
|
|
3073
3983
|
continue;
|
|
3074
3984
|
}
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
continue;
|
|
3079
|
-
}
|
|
3080
|
-
}
|
|
3081
|
-
let matched = false;
|
|
3082
|
-
for (const pattern of includePatterns) {
|
|
3083
|
-
if (matchGlob(relativePath, pattern)) {
|
|
3084
|
-
matched = true;
|
|
3085
|
-
break;
|
|
3086
|
-
}
|
|
3985
|
+
if (isExcludedByPatterns(relativePath, excludePatterns)) {
|
|
3986
|
+
skipped.push({ path: relativePath, reason: "excluded" });
|
|
3987
|
+
continue;
|
|
3087
3988
|
}
|
|
3088
|
-
if (
|
|
3989
|
+
if (matchesAnyGlob(relativePath, includePatterns)) {
|
|
3089
3990
|
filesInDir.push({ path: fullPath, size: stat2.size });
|
|
3090
3991
|
}
|
|
3091
3992
|
}
|
|
@@ -3096,7 +3997,7 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
|
|
|
3096
3997
|
yield f;
|
|
3097
3998
|
}
|
|
3098
3999
|
for (let i = options.maxFilesPerDirectory; i < filesInDir.length; i++) {
|
|
3099
|
-
skipped.push({ path:
|
|
4000
|
+
skipped.push({ path: toPosixRelativePath(path11.relative(projectRoot, filesInDir[i].path)), reason: "excluded" });
|
|
3100
4001
|
}
|
|
3101
4002
|
const canRecurse = options.maxDepth === -1 || currentDepth < options.maxDepth;
|
|
3102
4003
|
if (canRecurse) {
|
|
@@ -3136,8 +4037,8 @@ async function collectFiles(projectRoot, includePatterns, excludePatterns, maxFi
|
|
|
3136
4037
|
if (additionalRoots && additionalRoots.length > 0) {
|
|
3137
4038
|
const normalizedRoots = /* @__PURE__ */ new Set();
|
|
3138
4039
|
for (const kbRoot of additionalRoots) {
|
|
3139
|
-
const resolved =
|
|
3140
|
-
|
|
4040
|
+
const resolved = path11.normalize(
|
|
4041
|
+
path11.isAbsolute(kbRoot) ? kbRoot : path11.resolve(projectRoot, kbRoot)
|
|
3141
4042
|
);
|
|
3142
4043
|
normalizedRoots.add(resolved);
|
|
3143
4044
|
}
|
|
@@ -3178,7 +4079,7 @@ function getErrorMessage(error) {
|
|
|
3178
4079
|
return error instanceof Error ? error.message : String(error);
|
|
3179
4080
|
}
|
|
3180
4081
|
function runCommand(file, args, options) {
|
|
3181
|
-
return new Promise((
|
|
4082
|
+
return new Promise((resolve20, reject) => {
|
|
3182
4083
|
childProcess.execFile(
|
|
3183
4084
|
file,
|
|
3184
4085
|
args,
|
|
@@ -3188,7 +4089,7 @@ function runCommand(file, args, options) {
|
|
|
3188
4089
|
reject(error);
|
|
3189
4090
|
return;
|
|
3190
4091
|
}
|
|
3191
|
-
|
|
4092
|
+
resolve20(stdout);
|
|
3192
4093
|
}
|
|
3193
4094
|
);
|
|
3194
4095
|
});
|
|
@@ -3280,29 +4181,29 @@ var AutoIndexCancelledError = class extends Error {
|
|
|
3280
4181
|
function now() {
|
|
3281
4182
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3282
4183
|
}
|
|
3283
|
-
function
|
|
3284
|
-
const resolved =
|
|
3285
|
-
if (
|
|
4184
|
+
function canonicalizePath2(targetPath) {
|
|
4185
|
+
const resolved = path12.resolve(targetPath);
|
|
4186
|
+
if (existsSync8(resolved)) {
|
|
3286
4187
|
try {
|
|
3287
|
-
return
|
|
4188
|
+
return realpathSync4.native(resolved);
|
|
3288
4189
|
} catch {
|
|
3289
4190
|
return resolved;
|
|
3290
4191
|
}
|
|
3291
4192
|
}
|
|
3292
|
-
const parent =
|
|
4193
|
+
const parent = path12.dirname(resolved);
|
|
3293
4194
|
if (parent === resolved) return resolved;
|
|
3294
|
-
return
|
|
4195
|
+
return path12.join(canonicalizePath2(parent), path12.basename(resolved));
|
|
3295
4196
|
}
|
|
3296
4197
|
function isHomeDirectory(projectRoot) {
|
|
3297
|
-
return
|
|
4198
|
+
return canonicalizePath2(projectRoot) === canonicalizePath2(os4.homedir());
|
|
3298
4199
|
}
|
|
3299
|
-
function
|
|
3300
|
-
return `${host}::${
|
|
4200
|
+
function projectLookupKey2(projectRoot, host) {
|
|
4201
|
+
return `${host}::${canonicalizePath2(projectRoot)}`;
|
|
3301
4202
|
}
|
|
3302
4203
|
function coordinatorKey(projectRoot, config, host) {
|
|
3303
|
-
const canonicalProjectRoot =
|
|
4204
|
+
const canonicalProjectRoot = canonicalizePath2(projectRoot);
|
|
3304
4205
|
const indexPath = resolveProjectIndexPath(projectRoot, config.scope, host);
|
|
3305
|
-
return `${
|
|
4206
|
+
return `${canonicalizePath2(indexPath)}::${canonicalProjectRoot}`;
|
|
3306
4207
|
}
|
|
3307
4208
|
function getProjectSafety(projectRoot, config) {
|
|
3308
4209
|
if (isHomeDirectory(projectRoot)) {
|
|
@@ -3333,10 +4234,10 @@ function safeFailureMessage(error) {
|
|
|
3333
4234
|
}
|
|
3334
4235
|
function cancellableDelay(delayMs, signal) {
|
|
3335
4236
|
if (signal.aborted) return Promise.reject(new AutoIndexCancelledError());
|
|
3336
|
-
return new Promise((
|
|
4237
|
+
return new Promise((resolve20, reject) => {
|
|
3337
4238
|
const timer = setTimeout(() => {
|
|
3338
4239
|
signal.removeEventListener("abort", onAbort);
|
|
3339
|
-
|
|
4240
|
+
resolve20();
|
|
3340
4241
|
}, delayMs);
|
|
3341
4242
|
timer.unref?.();
|
|
3342
4243
|
const onAbort = () => {
|
|
@@ -3348,18 +4249,44 @@ function cancellableDelay(delayMs, signal) {
|
|
|
3348
4249
|
}
|
|
3349
4250
|
function withTimeout(promise, timeoutMs) {
|
|
3350
4251
|
if (timeoutMs <= 0) return Promise.resolve(void 0);
|
|
3351
|
-
return new Promise((
|
|
3352
|
-
const timer = setTimeout(() =>
|
|
4252
|
+
return new Promise((resolve20) => {
|
|
4253
|
+
const timer = setTimeout(() => resolve20(void 0), timeoutMs);
|
|
3353
4254
|
timer.unref?.();
|
|
3354
4255
|
void promise.then((value) => {
|
|
3355
4256
|
clearTimeout(timer);
|
|
3356
|
-
|
|
4257
|
+
resolve20(value);
|
|
3357
4258
|
}, () => {
|
|
3358
4259
|
clearTimeout(timer);
|
|
3359
|
-
|
|
4260
|
+
resolve20(void 0);
|
|
3360
4261
|
});
|
|
3361
4262
|
});
|
|
3362
4263
|
}
|
|
4264
|
+
function settlesWithin(promise, timeoutMs) {
|
|
4265
|
+
if (timeoutMs <= 0) return Promise.resolve(false);
|
|
4266
|
+
return new Promise((resolve20) => {
|
|
4267
|
+
let settled = false;
|
|
4268
|
+
const timer = setTimeout(() => {
|
|
4269
|
+
if (settled) return;
|
|
4270
|
+
settled = true;
|
|
4271
|
+
resolve20(false);
|
|
4272
|
+
}, timeoutMs);
|
|
4273
|
+
timer.unref?.();
|
|
4274
|
+
void promise.then(
|
|
4275
|
+
() => {
|
|
4276
|
+
if (settled) return;
|
|
4277
|
+
settled = true;
|
|
4278
|
+
clearTimeout(timer);
|
|
4279
|
+
resolve20(true);
|
|
4280
|
+
},
|
|
4281
|
+
() => {
|
|
4282
|
+
if (settled) return;
|
|
4283
|
+
settled = true;
|
|
4284
|
+
clearTimeout(timer);
|
|
4285
|
+
resolve20(true);
|
|
4286
|
+
}
|
|
4287
|
+
);
|
|
4288
|
+
});
|
|
4289
|
+
}
|
|
3363
4290
|
function requestPriority(request) {
|
|
3364
4291
|
if (request.force) return 4;
|
|
3365
4292
|
if (request.source === "manual") return 3;
|
|
@@ -3370,6 +4297,7 @@ function mergeRequests(current, next) {
|
|
|
3370
4297
|
if (!current) return next;
|
|
3371
4298
|
const preferred = requestPriority(next) > requestPriority(current) ? next : current;
|
|
3372
4299
|
return {
|
|
4300
|
+
allowDisabledAutoIndex: current.allowDisabledAutoIndex || next.allowDisabledAutoIndex,
|
|
3373
4301
|
checkFreshness: current.checkFreshness && next.checkFreshness,
|
|
3374
4302
|
force: current.force || next.force,
|
|
3375
4303
|
onProgress: next.onProgress ?? current.onProgress,
|
|
@@ -3431,11 +4359,11 @@ var AutoIndexCoordinator = class {
|
|
|
3431
4359
|
progress: this.status.progress ? { ...this.status.progress } : void 0
|
|
3432
4360
|
};
|
|
3433
4361
|
}
|
|
3434
|
-
start(source) {
|
|
4362
|
+
start(source, allowDisabledAutoIndex = false) {
|
|
3435
4363
|
this.refreshSafety();
|
|
3436
|
-
if (!this.registration.config.indexing.autoIndex || !this.registration.safeToRun) return null;
|
|
4364
|
+
if (!this.registration.config.indexing.autoIndex && !allowDisabledAutoIndex || !this.registration.safeToRun) return null;
|
|
3437
4365
|
if (this.status.state === "failed") return this.inFlight;
|
|
3438
|
-
return this.request({ checkFreshness: true, force: false, source });
|
|
4366
|
+
return this.request({ allowDisabledAutoIndex, checkFreshness: true, force: false, source });
|
|
3439
4367
|
}
|
|
3440
4368
|
request(request) {
|
|
3441
4369
|
if (this.stopped) {
|
|
@@ -3510,13 +4438,15 @@ var AutoIndexCoordinator = class {
|
|
|
3510
4438
|
retryAttempt: void 0
|
|
3511
4439
|
});
|
|
3512
4440
|
const inFlight = this.inFlight;
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
} else {
|
|
3517
|
-
await withTimeout(inFlight, SHUTDOWN_WAIT_MS);
|
|
3518
|
-
}
|
|
4441
|
+
const completion = inFlight ? inFlight.then(() => void 0, () => void 0) : Promise.resolve();
|
|
4442
|
+
if (!inFlight) {
|
|
4443
|
+
return { completed: true, completion };
|
|
3519
4444
|
}
|
|
4445
|
+
if (waitForCompletion) {
|
|
4446
|
+
await completion;
|
|
4447
|
+
return { completed: true, completion };
|
|
4448
|
+
}
|
|
4449
|
+
return { completed: await settlesWithin(completion, SHUTDOWN_WAIT_MS), completion };
|
|
3520
4450
|
}
|
|
3521
4451
|
startRequest(request) {
|
|
3522
4452
|
if (this.stopped || !this.canRun(request)) {
|
|
@@ -3705,7 +4635,7 @@ var AutoIndexCoordinator = class {
|
|
|
3705
4635
|
if (request.source === "manual" || request.source === "watcher") {
|
|
3706
4636
|
return true;
|
|
3707
4637
|
}
|
|
3708
|
-
return this.registration.safeToRun && this.registration.config.indexing.autoIndex;
|
|
4638
|
+
return this.registration.safeToRun && (this.registration.config.indexing.autoIndex || request.allowDisabledAutoIndex === true);
|
|
3709
4639
|
}
|
|
3710
4640
|
shouldDeferForBattery(request) {
|
|
3711
4641
|
return this.registration.backgroundIndexingPolicy !== null && (request.source === "startup" || request.source === "watcher");
|
|
@@ -3738,17 +4668,17 @@ var AutoIndexCoordinator = class {
|
|
|
3738
4668
|
}
|
|
3739
4669
|
}
|
|
3740
4670
|
waitForBatteryRetry(delayMs) {
|
|
3741
|
-
return new Promise((
|
|
4671
|
+
return new Promise((resolve20) => {
|
|
3742
4672
|
const timer = setTimeout(() => {
|
|
3743
4673
|
if (this.batteryRetryTimer === timer) {
|
|
3744
4674
|
this.batteryRetryTimer = null;
|
|
3745
4675
|
this.resolveBatteryRetry = null;
|
|
3746
4676
|
}
|
|
3747
|
-
|
|
4677
|
+
resolve20();
|
|
3748
4678
|
}, delayMs);
|
|
3749
4679
|
timer.unref?.();
|
|
3750
4680
|
this.batteryRetryTimer = timer;
|
|
3751
|
-
this.resolveBatteryRetry =
|
|
4681
|
+
this.resolveBatteryRetry = resolve20;
|
|
3752
4682
|
});
|
|
3753
4683
|
}
|
|
3754
4684
|
cancelBatteryRetry() {
|
|
@@ -3756,9 +4686,9 @@ var AutoIndexCoordinator = class {
|
|
|
3756
4686
|
clearTimeout(this.batteryRetryTimer);
|
|
3757
4687
|
this.batteryRetryTimer = null;
|
|
3758
4688
|
}
|
|
3759
|
-
const
|
|
4689
|
+
const resolve20 = this.resolveBatteryRetry;
|
|
3760
4690
|
this.resolveBatteryRetry = null;
|
|
3761
|
-
|
|
4691
|
+
resolve20?.();
|
|
3762
4692
|
}
|
|
3763
4693
|
finishBatteryCheck(batteryCheck) {
|
|
3764
4694
|
if (this.batteryCheck !== batteryCheck) return;
|
|
@@ -3771,12 +4701,25 @@ var AutoIndexCoordinator = class {
|
|
|
3771
4701
|
}
|
|
3772
4702
|
};
|
|
3773
4703
|
function getCoordinator(projectRoot, host) {
|
|
3774
|
-
const key = coordinatorKeysByProject.get(
|
|
4704
|
+
const key = coordinatorKeysByProject.get(projectLookupKey2(projectRoot, host));
|
|
3775
4705
|
return key ? coordinators.get(key) ?? null : null;
|
|
3776
4706
|
}
|
|
3777
|
-
function
|
|
3778
|
-
|
|
4707
|
+
function synchronizeBackgroundWorker(projectRoot, host, config, safeToRun) {
|
|
4708
|
+
if (safeToRun) {
|
|
4709
|
+
updateBackgroundWorkerConfig(projectRoot, host, config);
|
|
4710
|
+
return;
|
|
4711
|
+
}
|
|
4712
|
+
void stopBackgroundWorker(projectRoot, host).catch((error) => {
|
|
4713
|
+
console.error("[codebase-index] Failed to stop background worker after project safety changed:", error);
|
|
4714
|
+
});
|
|
4715
|
+
}
|
|
4716
|
+
function configureAutoIndex(projectRoot, host, config, getIndexer, options = {}) {
|
|
4717
|
+
const projectKey = projectLookupKey2(projectRoot, host);
|
|
3779
4718
|
const safety = getProjectSafety(projectRoot, config);
|
|
4719
|
+
const synchronizeWorker = options.synchronizeBackgroundWorker ?? true;
|
|
4720
|
+
if (options.preserveManagedWorker === true && isBackgroundWorkerManaged(projectRoot, host)) {
|
|
4721
|
+
return;
|
|
4722
|
+
}
|
|
3780
4723
|
const registration = {
|
|
3781
4724
|
backgroundIndexingPolicy: createBackgroundIndexingPolicy(
|
|
3782
4725
|
config.indexing.pauseBackgroundIndexingOnBattery
|
|
@@ -3794,6 +4737,9 @@ function configureAutoIndex(projectRoot, host, config, getIndexer) {
|
|
|
3794
4737
|
const stopPrevious = previousCoordinator?.stop(true) ?? Promise.resolve();
|
|
3795
4738
|
const activation = Promise.all([previousBarrier, stopPrevious]).then(() => void 0);
|
|
3796
4739
|
coordinatorReplacementBarriers.set(projectKey, activation);
|
|
4740
|
+
if (synchronizeWorker) {
|
|
4741
|
+
synchronizeBackgroundWorker(projectRoot, host, config, safety.safeToRun);
|
|
4742
|
+
}
|
|
3797
4743
|
coordinators.delete(previousKey);
|
|
3798
4744
|
const coordinator2 = new AutoIndexCoordinator(registration);
|
|
3799
4745
|
coordinator2.activateAfter(activation);
|
|
@@ -3809,6 +4755,9 @@ function configureAutoIndex(projectRoot, host, config, getIndexer) {
|
|
|
3809
4755
|
coordinator.update(registration);
|
|
3810
4756
|
}
|
|
3811
4757
|
coordinatorKeysByProject.set(projectKey, key);
|
|
4758
|
+
if (synchronizeWorker) {
|
|
4759
|
+
synchronizeBackgroundWorker(projectRoot, host, config, safety.safeToRun);
|
|
4760
|
+
}
|
|
3812
4761
|
}
|
|
3813
4762
|
function runCoordinatedIndex(projectRoot, host, force, onProgress) {
|
|
3814
4763
|
return getCoordinator(projectRoot, host)?.request({
|
|
@@ -3843,15 +4792,23 @@ async function waitForAutoIndexForRetrieval(projectRoot, host) {
|
|
|
3843
4792
|
};
|
|
3844
4793
|
}
|
|
3845
4794
|
try {
|
|
3846
|
-
|
|
4795
|
+
const readiness = await getSearchReadiness(coordinator);
|
|
4796
|
+
if (readiness.searchable) {
|
|
4797
|
+
return { ready: true };
|
|
4798
|
+
}
|
|
4799
|
+
if (readiness.blocked) return unavailableSnapshotResult(readiness.reason);
|
|
3847
4800
|
} catch {
|
|
3848
4801
|
}
|
|
3849
|
-
const job =
|
|
4802
|
+
const job = startRetrievalRefresh(projectRoot, host, coordinator);
|
|
3850
4803
|
if (job) {
|
|
3851
4804
|
await withTimeout(job, coordinator.getWaitMs());
|
|
4805
|
+
} else if (isBackgroundWorkerManaged(projectRoot, host)) {
|
|
4806
|
+
await waitForPublishedSnapshot(coordinator, coordinator.getWaitMs());
|
|
3852
4807
|
}
|
|
3853
4808
|
try {
|
|
3854
|
-
|
|
4809
|
+
const readiness = await getSearchReadiness(coordinator);
|
|
4810
|
+
if (readiness.searchable) return { ready: true };
|
|
4811
|
+
if (readiness.blocked) return unavailableSnapshotResult(readiness.reason);
|
|
3855
4812
|
} catch {
|
|
3856
4813
|
}
|
|
3857
4814
|
const status = coordinator.snapshot();
|
|
@@ -3872,18 +4829,45 @@ async function waitForAutoIndexForRetrieval(projectRoot, host) {
|
|
|
3872
4829
|
text: `Automatic indexing is ${status.state}. Retry shortly or call index_status for progress. You can also run index_codebase explicitly.`
|
|
3873
4830
|
};
|
|
3874
4831
|
}
|
|
3875
|
-
async function
|
|
4832
|
+
async function getSearchReadiness(coordinator) {
|
|
3876
4833
|
const indexer = coordinator.getIndexer();
|
|
3877
4834
|
if (indexer.getIndexFreshness) {
|
|
3878
4835
|
const freshness = await indexer.getIndexFreshness();
|
|
3879
|
-
|
|
4836
|
+
const searchable = freshness.readable && freshness.current && freshness.reason === "current";
|
|
4837
|
+
return {
|
|
4838
|
+
blocked: freshness.reason === "unreadable" || freshness.reason === "incompatible" || freshness.reason === "failed-batches" || freshness.reason === "migration-required",
|
|
4839
|
+
reason: freshness.reason,
|
|
4840
|
+
searchable
|
|
4841
|
+
};
|
|
4842
|
+
}
|
|
4843
|
+
const indexed = (await indexer.getStatus()).indexed;
|
|
4844
|
+
return { blocked: false, searchable: indexed };
|
|
4845
|
+
}
|
|
4846
|
+
function unavailableSnapshotResult(reason) {
|
|
4847
|
+
const detail = reason === "incompatible" ? "The existing index is incompatible with the configured embedding provider." : reason === "migration-required" ? "The existing index requires a storage migration." : reason === "failed-batches" ? "The existing index has failed embedding batches." : "The existing index is unreadable.";
|
|
4848
|
+
return {
|
|
4849
|
+
ready: false,
|
|
4850
|
+
text: `${detail} Run index_codebase before retrying retrieval.`
|
|
4851
|
+
};
|
|
4852
|
+
}
|
|
4853
|
+
function startRetrievalRefresh(projectRoot, host, coordinator) {
|
|
4854
|
+
if (isBackgroundWorkerManaged(projectRoot, host)) {
|
|
4855
|
+
requestBackgroundWorkerRefresh(projectRoot, host, true);
|
|
4856
|
+
return isBackgroundWorkerLeader(projectRoot, host) ? coordinator.currentJob() : null;
|
|
4857
|
+
}
|
|
4858
|
+
return coordinator.start("retrieval") ?? coordinator.currentJob();
|
|
4859
|
+
}
|
|
4860
|
+
async function waitForPublishedSnapshot(coordinator, waitMs) {
|
|
4861
|
+
const deadline = Date.now() + waitMs;
|
|
4862
|
+
while (Date.now() < deadline) {
|
|
4863
|
+
if ((await getSearchReadiness(coordinator)).searchable) return;
|
|
4864
|
+
await new Promise((resolve20) => setTimeout(resolve20, Math.min(250, deadline - Date.now())));
|
|
3880
4865
|
}
|
|
3881
|
-
return (await indexer.getStatus()).indexed;
|
|
3882
4866
|
}
|
|
3883
4867
|
|
|
3884
4868
|
// src/tools/config-state.ts
|
|
3885
|
-
import { existsSync as
|
|
3886
|
-
import * as
|
|
4869
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
4870
|
+
import * as path13 from "path";
|
|
3887
4871
|
function normalizeKnowledgeBasePaths(config, projectRoot) {
|
|
3888
4872
|
const normalized = { ...config };
|
|
3889
4873
|
if (Array.isArray(normalized.knowledgeBases)) {
|
|
@@ -3904,8 +4888,8 @@ function loadRuntimeConfig(projectRoot, host) {
|
|
|
3904
4888
|
}
|
|
3905
4889
|
|
|
3906
4890
|
// src/indexer/index.ts
|
|
3907
|
-
import { existsSync as
|
|
3908
|
-
import * as
|
|
4891
|
+
import { existsSync as existsSync12, readFileSync as readFileSync9, statSync as statSync4, writeFileSync as writeFileSync4, renameSync as renameSync4, unlinkSync as unlinkSync2, mkdirSync as mkdirSync5, promises as fsPromises3 } from "fs";
|
|
4892
|
+
import * as path20 from "path";
|
|
3909
4893
|
import { performance as performance2 } from "perf_hooks";
|
|
3910
4894
|
import { execFile as execFile5 } from "child_process";
|
|
3911
4895
|
import { promisify as promisify4 } from "util";
|
|
@@ -3932,7 +4916,7 @@ function pTimeout(promise, options) {
|
|
|
3932
4916
|
} = options;
|
|
3933
4917
|
let timer;
|
|
3934
4918
|
let abortHandler;
|
|
3935
|
-
const wrappedPromise = new Promise((
|
|
4919
|
+
const wrappedPromise = new Promise((resolve20, reject) => {
|
|
3936
4920
|
if (typeof milliseconds !== "number" || Math.sign(milliseconds) !== 1) {
|
|
3937
4921
|
throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${milliseconds}\``);
|
|
3938
4922
|
}
|
|
@@ -3946,7 +4930,7 @@ function pTimeout(promise, options) {
|
|
|
3946
4930
|
};
|
|
3947
4931
|
signal.addEventListener("abort", abortHandler, { once: true });
|
|
3948
4932
|
}
|
|
3949
|
-
promise.then(
|
|
4933
|
+
promise.then(resolve20, reject);
|
|
3950
4934
|
if (milliseconds === Number.POSITIVE_INFINITY) {
|
|
3951
4935
|
return;
|
|
3952
4936
|
}
|
|
@@ -3954,7 +4938,7 @@ function pTimeout(promise, options) {
|
|
|
3954
4938
|
timer = customTimers.setTimeout.call(void 0, () => {
|
|
3955
4939
|
if (fallback) {
|
|
3956
4940
|
try {
|
|
3957
|
-
|
|
4941
|
+
resolve20(fallback());
|
|
3958
4942
|
} catch (error) {
|
|
3959
4943
|
reject(error);
|
|
3960
4944
|
}
|
|
@@ -3964,7 +4948,7 @@ function pTimeout(promise, options) {
|
|
|
3964
4948
|
promise.cancel();
|
|
3965
4949
|
}
|
|
3966
4950
|
if (message === false) {
|
|
3967
|
-
|
|
4951
|
+
resolve20();
|
|
3968
4952
|
} else if (message instanceof Error) {
|
|
3969
4953
|
reject(message);
|
|
3970
4954
|
} else {
|
|
@@ -4366,7 +5350,7 @@ var PQueue = class extends import_index.default {
|
|
|
4366
5350
|
// Assign unique ID if not provided
|
|
4367
5351
|
id: options.id ?? (this.#idAssigner++).toString()
|
|
4368
5352
|
};
|
|
4369
|
-
return new Promise((
|
|
5353
|
+
return new Promise((resolve20, reject) => {
|
|
4370
5354
|
const taskSymbol = /* @__PURE__ */ Symbol(`task-${options.id}`);
|
|
4371
5355
|
let cleanupQueueAbortHandler = () => void 0;
|
|
4372
5356
|
const run = async () => {
|
|
@@ -4406,7 +5390,7 @@ var PQueue = class extends import_index.default {
|
|
|
4406
5390
|
})]);
|
|
4407
5391
|
}
|
|
4408
5392
|
const result = await operation;
|
|
4409
|
-
|
|
5393
|
+
resolve20(result);
|
|
4410
5394
|
this.emit("completed", result);
|
|
4411
5395
|
} catch (error) {
|
|
4412
5396
|
reject(error);
|
|
@@ -4594,13 +5578,13 @@ var PQueue = class extends import_index.default {
|
|
|
4594
5578
|
});
|
|
4595
5579
|
}
|
|
4596
5580
|
async #onEvent(event, filter) {
|
|
4597
|
-
return new Promise((
|
|
5581
|
+
return new Promise((resolve20) => {
|
|
4598
5582
|
const listener = () => {
|
|
4599
5583
|
if (filter && !filter()) {
|
|
4600
5584
|
return;
|
|
4601
5585
|
}
|
|
4602
5586
|
this.off(event, listener);
|
|
4603
|
-
|
|
5587
|
+
resolve20();
|
|
4604
5588
|
};
|
|
4605
5589
|
this.on(event, listener);
|
|
4606
5590
|
});
|
|
@@ -4886,7 +5870,7 @@ async function onAttemptFailure({ error, attemptNumber, retriesConsumed, startTi
|
|
|
4886
5870
|
const finalDelay = Math.min(delayTime, remainingTime);
|
|
4887
5871
|
options.signal?.throwIfAborted();
|
|
4888
5872
|
if (finalDelay > 0) {
|
|
4889
|
-
await new Promise((
|
|
5873
|
+
await new Promise((resolve20, reject) => {
|
|
4890
5874
|
const onAbort = () => {
|
|
4891
5875
|
clearTimeout(timeoutToken);
|
|
4892
5876
|
options.signal?.removeEventListener("abort", onAbort);
|
|
@@ -4894,7 +5878,7 @@ async function onAttemptFailure({ error, attemptNumber, retriesConsumed, startTi
|
|
|
4894
5878
|
};
|
|
4895
5879
|
const timeoutToken = setTimeout(() => {
|
|
4896
5880
|
options.signal?.removeEventListener("abort", onAbort);
|
|
4897
|
-
|
|
5881
|
+
resolve20();
|
|
4898
5882
|
}, finalDelay);
|
|
4899
5883
|
if (options.unref) {
|
|
4900
5884
|
timeoutToken.unref?.();
|
|
@@ -4955,17 +5939,17 @@ async function pRetry(input, options = {}) {
|
|
|
4955
5939
|
}
|
|
4956
5940
|
|
|
4957
5941
|
// src/embeddings/detector.ts
|
|
4958
|
-
import { existsSync as
|
|
4959
|
-
import * as
|
|
4960
|
-
import * as
|
|
5942
|
+
import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
|
|
5943
|
+
import * as path14 from "path";
|
|
5944
|
+
import * as os5 from "os";
|
|
4961
5945
|
function getOpenCodeAuthPath() {
|
|
4962
|
-
return
|
|
5946
|
+
return path14.join(os5.homedir(), ".local", "share", "opencode", "auth.json");
|
|
4963
5947
|
}
|
|
4964
5948
|
function loadOpenCodeAuth() {
|
|
4965
5949
|
const authPath = getOpenCodeAuthPath();
|
|
4966
5950
|
try {
|
|
4967
|
-
if (
|
|
4968
|
-
return JSON.parse(
|
|
5951
|
+
if (existsSync10(authPath)) {
|
|
5952
|
+
return JSON.parse(readFileSync7(authPath, "utf-8"));
|
|
4969
5953
|
}
|
|
4970
5954
|
} catch {
|
|
4971
5955
|
}
|
|
@@ -5256,17 +6240,17 @@ function validateExternalUrl(urlString) {
|
|
|
5256
6240
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
5257
6241
|
return { valid: false, reason: `Blocked protocol: ${parsed.protocol}` };
|
|
5258
6242
|
}
|
|
5259
|
-
const
|
|
5260
|
-
if (BLOCKED_HOSTNAMES.has(
|
|
5261
|
-
return { valid: false, reason: `Blocked: cloud metadata service (${
|
|
6243
|
+
const hostname3 = parsed.hostname.toLowerCase();
|
|
6244
|
+
if (BLOCKED_HOSTNAMES.has(hostname3)) {
|
|
6245
|
+
return { valid: false, reason: `Blocked: cloud metadata service (${hostname3})` };
|
|
5262
6246
|
}
|
|
5263
6247
|
for (const pattern of BLOCKED_METADATA_IPS) {
|
|
5264
|
-
if (pattern.test(
|
|
5265
|
-
return { valid: false, reason: `Blocked: cloud metadata IP (${
|
|
6248
|
+
if (pattern.test(hostname3)) {
|
|
6249
|
+
return { valid: false, reason: `Blocked: cloud metadata IP (${hostname3})` };
|
|
5266
6250
|
}
|
|
5267
6251
|
}
|
|
5268
|
-
if (/^169\.254\./.test(
|
|
5269
|
-
return { valid: false, reason: `Blocked: link-local address (${
|
|
6252
|
+
if (/^169\.254\./.test(hostname3)) {
|
|
6253
|
+
return { valid: false, reason: `Blocked: link-local address (${hostname3})` };
|
|
5270
6254
|
}
|
|
5271
6255
|
return { valid: true };
|
|
5272
6256
|
}
|
|
@@ -6358,8 +7342,8 @@ function extractParamNames(params) {
|
|
|
6358
7342
|
}
|
|
6359
7343
|
|
|
6360
7344
|
// src/native/binding.ts
|
|
6361
|
-
import * as
|
|
6362
|
-
import * as
|
|
7345
|
+
import * as os6 from "os";
|
|
7346
|
+
import * as path15 from "path";
|
|
6363
7347
|
import * as module from "module";
|
|
6364
7348
|
import { fileURLToPath } from "url";
|
|
6365
7349
|
|
|
@@ -6395,7 +7379,7 @@ var MCP_BINARY_CURRENT_NAME = CURRENT_PRODUCT.mcpBinary;
|
|
|
6395
7379
|
var STABLE_NATIVE_BINARY_NAME = IDENTITY_CATALOG.native.binaryName;
|
|
6396
7380
|
|
|
6397
7381
|
// src/native/binding.ts
|
|
6398
|
-
function getNativeBindingFilename(platform2 =
|
|
7382
|
+
function getNativeBindingFilename(platform2 = os6.platform(), arch2 = os6.arch()) {
|
|
6399
7383
|
if (platform2 === "darwin" && arch2 === "arm64") {
|
|
6400
7384
|
return `${STABLE_NATIVE_BINARY_NAME}.darwin-arm64.node`;
|
|
6401
7385
|
}
|
|
@@ -6413,25 +7397,25 @@ function getNativeBindingFilename(platform2 = os5.platform(), arch2 = os5.arch()
|
|
|
6413
7397
|
}
|
|
6414
7398
|
throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
|
|
6415
7399
|
}
|
|
6416
|
-
function resolveNativeBindingPath(packageRoot, platform2 =
|
|
6417
|
-
return
|
|
7400
|
+
function resolveNativeBindingPath(packageRoot, platform2 = os6.platform(), arch2 = os6.arch()) {
|
|
7401
|
+
return path15.join(packageRoot, "native", getNativeBindingFilename(platform2, arch2));
|
|
6418
7402
|
}
|
|
6419
7403
|
function getNativeBinding() {
|
|
6420
7404
|
let currentDir;
|
|
6421
7405
|
let requireTarget;
|
|
6422
7406
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
6423
|
-
currentDir =
|
|
7407
|
+
currentDir = path15.dirname(fileURLToPath(import.meta.url));
|
|
6424
7408
|
requireTarget = import.meta.url;
|
|
6425
7409
|
} else if (typeof __dirname !== "undefined") {
|
|
6426
7410
|
currentDir = __dirname;
|
|
6427
7411
|
requireTarget = __filename;
|
|
6428
7412
|
} else {
|
|
6429
7413
|
currentDir = process.cwd();
|
|
6430
|
-
requireTarget =
|
|
7414
|
+
requireTarget = path15.join(currentDir, "index.js");
|
|
6431
7415
|
}
|
|
6432
7416
|
const normalizedDir = currentDir.replace(/\\/g, "/");
|
|
6433
|
-
const isDevMode = normalizedDir.includes("/src/native") || currentDir.includes(
|
|
6434
|
-
const packageRoot = isDevMode ?
|
|
7417
|
+
const isDevMode = normalizedDir.includes("/src/native") || currentDir.includes(path15.join("src", "native"));
|
|
7418
|
+
const packageRoot = isDevMode ? path15.resolve(currentDir, "../..") : path15.resolve(currentDir, "..");
|
|
6435
7419
|
const nativePath = resolveNativeBindingPath(packageRoot);
|
|
6436
7420
|
const require2 = module.createRequire(requireTarget);
|
|
6437
7421
|
return require2(nativePath);
|
|
@@ -7015,8 +7999,8 @@ var Database = class _Database {
|
|
|
7015
7999
|
|
|
7016
8000
|
// src/git/branch-materialization.ts
|
|
7017
8001
|
import { promises as fsPromises2 } from "fs";
|
|
7018
|
-
import * as
|
|
7019
|
-
import * as
|
|
8002
|
+
import * as os7 from "os";
|
|
8003
|
+
import * as path16 from "path";
|
|
7020
8004
|
|
|
7021
8005
|
// src/git/branch-resolution.ts
|
|
7022
8006
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -7335,13 +8319,13 @@ async function isWorktreeRegistered(projectRoot, worktreePath) {
|
|
|
7335
8319
|
return false;
|
|
7336
8320
|
}
|
|
7337
8321
|
function isPathWithinRoot(filePath, rootPath) {
|
|
7338
|
-
const relative12 =
|
|
7339
|
-
return relative12 === "" || !relative12.startsWith(`..${
|
|
8322
|
+
const relative12 = path16.relative(path16.resolve(rootPath), path16.resolve(filePath));
|
|
8323
|
+
return relative12 === "" || !relative12.startsWith(`..${path16.sep}`) && relative12 !== ".." && !path16.isAbsolute(relative12);
|
|
7340
8324
|
}
|
|
7341
8325
|
async function pruneExactMissingWorktreeRegistration(projectRoot, worktreePath) {
|
|
7342
8326
|
if (await pathExists(worktreePath)) return false;
|
|
7343
8327
|
const commonDir = await runGit(projectRoot, ["rev-parse", "--path-format=absolute", "--git-common-dir"]);
|
|
7344
|
-
const registrationsRoot =
|
|
8328
|
+
const registrationsRoot = path16.join(commonDir, "worktrees");
|
|
7345
8329
|
let entries;
|
|
7346
8330
|
try {
|
|
7347
8331
|
entries = await fsPromises2.readdir(registrationsRoot, { withFileTypes: true });
|
|
@@ -7352,16 +8336,16 @@ async function pruneExactMissingWorktreeRegistration(projectRoot, worktreePath)
|
|
|
7352
8336
|
const target = canonicalizePathForComparison(worktreePath);
|
|
7353
8337
|
for (const entry of entries) {
|
|
7354
8338
|
if (!entry.isDirectory()) continue;
|
|
7355
|
-
const registrationPath =
|
|
8339
|
+
const registrationPath = path16.join(registrationsRoot, entry.name);
|
|
7356
8340
|
if (!isPathWithinRoot(registrationPath, registrationsRoot)) continue;
|
|
7357
8341
|
let gitdirPath;
|
|
7358
8342
|
try {
|
|
7359
|
-
gitdirPath = (await fsPromises2.readFile(
|
|
8343
|
+
gitdirPath = (await fsPromises2.readFile(path16.join(registrationPath, "gitdir"), "utf8")).trim();
|
|
7360
8344
|
} catch {
|
|
7361
8345
|
continue;
|
|
7362
8346
|
}
|
|
7363
|
-
const resolvedGitdirPath =
|
|
7364
|
-
if (canonicalizePathForComparison(
|
|
8347
|
+
const resolvedGitdirPath = path16.isAbsolute(gitdirPath) ? gitdirPath : path16.resolve(registrationPath, gitdirPath);
|
|
8348
|
+
if (canonicalizePathForComparison(path16.dirname(resolvedGitdirPath)) !== target) continue;
|
|
7365
8349
|
await fsPromises2.rm(registrationPath, { recursive: true, force: true });
|
|
7366
8350
|
return true;
|
|
7367
8351
|
}
|
|
@@ -7379,7 +8363,7 @@ async function removeWorktree(projectRoot, worktreePath) {
|
|
|
7379
8363
|
registered = await isWorktreeRegistered(projectRoot, worktreePath);
|
|
7380
8364
|
} catch (error) {
|
|
7381
8365
|
errors.push(asError(error));
|
|
7382
|
-
throw new AggregateError(errors, `Could not verify temporary worktree deregistration; preserved ${
|
|
8366
|
+
throw new AggregateError(errors, `Could not verify temporary worktree deregistration; preserved ${path16.dirname(worktreePath)}`);
|
|
7383
8367
|
}
|
|
7384
8368
|
if (registered) {
|
|
7385
8369
|
try {
|
|
@@ -7395,7 +8379,7 @@ async function removeWorktree(projectRoot, worktreePath) {
|
|
|
7395
8379
|
registered = await isWorktreeRegistered(projectRoot, worktreePath);
|
|
7396
8380
|
} catch (error) {
|
|
7397
8381
|
errors.push(asError(error));
|
|
7398
|
-
throw new AggregateError(errors, `Could not verify temporary worktree deregistration; preserved ${
|
|
8382
|
+
throw new AggregateError(errors, `Could not verify temporary worktree deregistration; preserved ${path16.dirname(worktreePath)}`);
|
|
7399
8383
|
}
|
|
7400
8384
|
}
|
|
7401
8385
|
if (registered && !await pathExists(worktreePath)) {
|
|
@@ -7408,13 +8392,13 @@ async function removeWorktree(projectRoot, worktreePath) {
|
|
|
7408
8392
|
}
|
|
7409
8393
|
if (registered) {
|
|
7410
8394
|
errors.push(new Error(`Temporary worktree remains registered: ${worktreePath}`));
|
|
7411
|
-
throw new AggregateError(errors, `Failed to deregister temporary worktree; preserved ${
|
|
8395
|
+
throw new AggregateError(errors, `Failed to deregister temporary worktree; preserved ${path16.dirname(worktreePath)}`);
|
|
7412
8396
|
}
|
|
7413
8397
|
try {
|
|
7414
|
-
await fsPromises2.rm(
|
|
8398
|
+
await fsPromises2.rm(path16.dirname(worktreePath), { recursive: true, force: true });
|
|
7415
8399
|
} catch (error) {
|
|
7416
8400
|
errors.push(asError(error));
|
|
7417
|
-
throw new AggregateError(errors, `Deregistered the temporary worktree but could not remove ${
|
|
8401
|
+
throw new AggregateError(errors, `Deregistered the temporary worktree but could not remove ${path16.dirname(worktreePath)}`);
|
|
7418
8402
|
}
|
|
7419
8403
|
}
|
|
7420
8404
|
async function cleanupTemporaryWorktree(projectRoot, worktreePath, temporaryRoot) {
|
|
@@ -7450,9 +8434,9 @@ async function withMaterializedBranch(request, callback) {
|
|
|
7450
8434
|
`Git ref ${JSON.stringify(request.ref ?? request.branch)} is not available locally. For an unfetched branch, pass a remote-qualified name such as origin/feature.`
|
|
7451
8435
|
);
|
|
7452
8436
|
}
|
|
7453
|
-
const temporaryRoot = await fsPromises2.mkdtemp(
|
|
7454
|
-
const worktreePath =
|
|
7455
|
-
const hooksPath =
|
|
8437
|
+
const temporaryRoot = await fsPromises2.mkdtemp(path16.join(os7.tmpdir(), "codebase-index-branch-"));
|
|
8438
|
+
const worktreePath = path16.join(temporaryRoot, "worktree");
|
|
8439
|
+
const hooksPath = path16.join(temporaryRoot, "hooks");
|
|
7456
8440
|
await fsPromises2.mkdir(hooksPath);
|
|
7457
8441
|
const info = {
|
|
7458
8442
|
branch: request.branch,
|
|
@@ -7503,8 +8487,8 @@ async function withMaterializedBranch(request, callback) {
|
|
|
7503
8487
|
|
|
7504
8488
|
// src/tools/changed-files.ts
|
|
7505
8489
|
import { execFile as execFile3 } from "child_process";
|
|
7506
|
-
import { realpathSync as
|
|
7507
|
-
import * as
|
|
8490
|
+
import { realpathSync as realpathSync5 } from "fs";
|
|
8491
|
+
import * as path17 from "path";
|
|
7508
8492
|
import { promisify as promisify2 } from "util";
|
|
7509
8493
|
var execFileAsync2 = promisify2(execFile3);
|
|
7510
8494
|
var GH_PR_VIEW_FIELDS = [
|
|
@@ -7646,9 +8630,9 @@ function getHeadRepositoryIdentity(data, host) {
|
|
|
7646
8630
|
return `${host}/${owner.toLowerCase()}/${repository.replace(/\.git$/i, "").toLowerCase()}`;
|
|
7647
8631
|
}
|
|
7648
8632
|
function getLocalRepositoryIdentity(projectRoot) {
|
|
7649
|
-
let canonicalRoot =
|
|
8633
|
+
let canonicalRoot = path17.resolve(projectRoot);
|
|
7650
8634
|
try {
|
|
7651
|
-
canonicalRoot =
|
|
8635
|
+
canonicalRoot = realpathSync5.native(canonicalRoot);
|
|
7652
8636
|
} catch {
|
|
7653
8637
|
}
|
|
7654
8638
|
return `local:${canonicalRoot}`;
|
|
@@ -7707,17 +8691,17 @@ async function getMergeBase(projectRoot, baseCommit, headCommit) {
|
|
|
7707
8691
|
return commit;
|
|
7708
8692
|
}
|
|
7709
8693
|
function normalizeFiles(rawFiles, projectRoot) {
|
|
7710
|
-
const root =
|
|
8694
|
+
const root = path17.resolve(projectRoot);
|
|
7711
8695
|
const seen = /* @__PURE__ */ new Set();
|
|
7712
8696
|
const result = [];
|
|
7713
8697
|
for (const raw of rawFiles) {
|
|
7714
8698
|
if (raw.length === 0) continue;
|
|
7715
|
-
const absolute =
|
|
7716
|
-
const relative12 =
|
|
7717
|
-
if (
|
|
8699
|
+
const absolute = path17.resolve(root, raw);
|
|
8700
|
+
const relative12 = path17.relative(root, absolute);
|
|
8701
|
+
if (path17.isAbsolute(raw) || relative12 === ".." || relative12.startsWith(`..${path17.sep}`) || path17.isAbsolute(relative12)) {
|
|
7718
8702
|
throw new Error(`Changed file escapes the project root: ${JSON.stringify(raw)}`);
|
|
7719
8703
|
}
|
|
7720
|
-
const cleaned = relative12.startsWith(`.${
|
|
8704
|
+
const cleaned = relative12.startsWith(`.${path17.sep}`) ? relative12.slice(2) : relative12;
|
|
7721
8705
|
if (!seen.has(cleaned)) {
|
|
7722
8706
|
seen.add(cleaned);
|
|
7723
8707
|
result.push(cleaned);
|
|
@@ -7728,7 +8712,7 @@ function normalizeFiles(rawFiles, projectRoot) {
|
|
|
7728
8712
|
|
|
7729
8713
|
// src/indexer/git-blame.ts
|
|
7730
8714
|
import { execFile as execFile4 } from "child_process";
|
|
7731
|
-
import * as
|
|
8715
|
+
import * as path18 from "path";
|
|
7732
8716
|
import { promisify as promisify3 } from "util";
|
|
7733
8717
|
var execFileAsync3 = promisify3(execFile4);
|
|
7734
8718
|
function parseGitBlamePorcelain(output) {
|
|
@@ -7766,7 +8750,7 @@ function parseGitBlamePorcelain(output) {
|
|
|
7766
8750
|
return Array.from(commits.values()).filter((commit) => commit.lines > 0).sort((a, b) => b.lines - a.lines || b.committedAt - a.committedAt)[0];
|
|
7767
8751
|
}
|
|
7768
8752
|
async function getChunkGitBlame(projectRoot, filePath, startLine, endLine) {
|
|
7769
|
-
const relativePath =
|
|
8753
|
+
const relativePath = path18.relative(projectRoot, filePath);
|
|
7770
8754
|
try {
|
|
7771
8755
|
const { stdout } = await execFileAsync3(
|
|
7772
8756
|
"git",
|
|
@@ -8345,8 +9329,8 @@ function pathSegmentsForAffinityMatch(filePath) {
|
|
|
8345
9329
|
if (segments.length === 0) {
|
|
8346
9330
|
return [];
|
|
8347
9331
|
}
|
|
8348
|
-
const
|
|
8349
|
-
const basenameWithoutExt =
|
|
9332
|
+
const basename7 = segments[segments.length - 1] ?? "";
|
|
9333
|
+
const basenameWithoutExt = basename7.replace(/\.[^/.]+$/u, "");
|
|
8350
9334
|
const normalizedSegments = segments.map((segment) => segment.toLowerCase());
|
|
8351
9335
|
return Array.from(/* @__PURE__ */ new Set([
|
|
8352
9336
|
...normalizedSegments,
|
|
@@ -8655,8 +9639,8 @@ function hasAllEmbeddingParts(parts, expectedPartCount) {
|
|
|
8655
9639
|
|
|
8656
9640
|
// src/indexer/failed-state-persistence.ts
|
|
8657
9641
|
import * as fs2 from "fs";
|
|
8658
|
-
import { createHash, randomBytes as randomBytes3 } from "crypto";
|
|
8659
|
-
import * as
|
|
9642
|
+
import { createHash as createHash2, randomBytes as randomBytes3 } from "crypto";
|
|
9643
|
+
import * as path19 from "path";
|
|
8660
9644
|
import { StringDecoder } from "string_decoder";
|
|
8661
9645
|
var CURRENT_FAILED_BATCH_VERSION = 1;
|
|
8662
9646
|
var DEFAULT_MALFORMED_LINE_ACTION = "skip";
|
|
@@ -8674,7 +9658,7 @@ function* readFailedBatchRecords(filePath, options = {}) {
|
|
|
8674
9658
|
function createFailedBatchWriter(targetPath) {
|
|
8675
9659
|
const temporaryPath = createTemporaryPath(targetPath);
|
|
8676
9660
|
let finalized = false;
|
|
8677
|
-
fs2.mkdirSync(
|
|
9661
|
+
fs2.mkdirSync(path19.dirname(targetPath), { recursive: true });
|
|
8678
9662
|
fs2.closeSync(fs2.openSync(temporaryPath, "w"));
|
|
8679
9663
|
const write = (record) => {
|
|
8680
9664
|
if (finalized) {
|
|
@@ -8693,7 +9677,7 @@ function createFailedBatchWriter(targetPath) {
|
|
|
8693
9677
|
if (lines.length === 0) {
|
|
8694
9678
|
return;
|
|
8695
9679
|
}
|
|
8696
|
-
fs2.mkdirSync(
|
|
9680
|
+
fs2.mkdirSync(path19.dirname(targetPath), { recursive: true });
|
|
8697
9681
|
fs2.appendFileSync(temporaryPath, `${lines.join("\n")}
|
|
8698
9682
|
`, "utf-8");
|
|
8699
9683
|
};
|
|
@@ -8701,7 +9685,7 @@ function createFailedBatchWriter(targetPath) {
|
|
|
8701
9685
|
if (finalized) {
|
|
8702
9686
|
return;
|
|
8703
9687
|
}
|
|
8704
|
-
fs2.mkdirSync(
|
|
9688
|
+
fs2.mkdirSync(path19.dirname(targetPath), { recursive: true });
|
|
8705
9689
|
fs2.renameSync(temporaryPath, targetPath);
|
|
8706
9690
|
finalized = true;
|
|
8707
9691
|
};
|
|
@@ -8847,10 +9831,10 @@ function stripLeadingBomAndWhitespace(value) {
|
|
|
8847
9831
|
return result;
|
|
8848
9832
|
}
|
|
8849
9833
|
function createTemporaryPath(targetPath) {
|
|
8850
|
-
const randomId =
|
|
8851
|
-
const targetDir =
|
|
8852
|
-
const baseName =
|
|
8853
|
-
return
|
|
9834
|
+
const randomId = createHash2("sha1").update(`${Date.now()}:${randomBytes3(8).toString("hex")}`).digest("hex");
|
|
9835
|
+
const targetDir = path19.dirname(targetPath);
|
|
9836
|
+
const baseName = path19.basename(targetPath);
|
|
9837
|
+
return path19.join(targetDir, `.${baseName}.${randomId}.tmp`);
|
|
8854
9838
|
}
|
|
8855
9839
|
function handleMalformedLine(filePath, lineNumber, line, error, options) {
|
|
8856
9840
|
const action = options.malformedLineAction ?? DEFAULT_MALFORMED_LINE_ACTION;
|
|
@@ -9096,9 +10080,9 @@ var SWIFT_PARSER_VERSION = "1";
|
|
|
9096
10080
|
var METAL_PARSER_VERSION = "1";
|
|
9097
10081
|
var SYMBOL_EXTRACTOR_VERSION = "1";
|
|
9098
10082
|
function isPathWithinRoot2(filePath, rootPath) {
|
|
9099
|
-
const normalizedFilePath =
|
|
9100
|
-
const normalizedRoot =
|
|
9101
|
-
return normalizedFilePath === normalizedRoot || normalizedFilePath.startsWith(`${normalizedRoot}${
|
|
10083
|
+
const normalizedFilePath = path20.resolve(filePath);
|
|
10084
|
+
const normalizedRoot = path20.resolve(rootPath);
|
|
10085
|
+
return normalizedFilePath === normalizedRoot || normalizedFilePath.startsWith(`${normalizedRoot}${path20.sep}`);
|
|
9102
10086
|
}
|
|
9103
10087
|
function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCandidates, database, branchChunkIds, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
|
|
9104
10088
|
if (combined.length === 0) {
|
|
@@ -9429,10 +10413,10 @@ function matchesHardSearchFilters(candidate, options, projectRoot) {
|
|
|
9429
10413
|
}
|
|
9430
10414
|
if (options?.directory) {
|
|
9431
10415
|
const candidatePath = canonicalizePathForComparison(
|
|
9432
|
-
|
|
10416
|
+
path20.resolve(projectRoot, candidate.metadata.filePath.replace(/\\/g, path20.sep))
|
|
9433
10417
|
);
|
|
9434
10418
|
const directoryPath = canonicalizePathForComparison(
|
|
9435
|
-
|
|
10419
|
+
path20.resolve(projectRoot, options.directory.trim().replace(/\\/g, path20.sep))
|
|
9436
10420
|
);
|
|
9437
10421
|
if (!isPathWithinRoot2(candidatePath, directoryPath)) return false;
|
|
9438
10422
|
}
|
|
@@ -9545,26 +10529,37 @@ var Indexer = class _Indexer {
|
|
|
9545
10529
|
return this.indexPathOverride ?? resolveProjectIndexPath(this.projectRoot, this.config.scope, this.host);
|
|
9546
10530
|
}
|
|
9547
10531
|
toCanonicalFilePath(filePath) {
|
|
9548
|
-
if (!
|
|
10532
|
+
if (!path20.isAbsolute(filePath)) {
|
|
9549
10533
|
return this.resolveStoredFilePath(filePath, this.projectRoot);
|
|
9550
10534
|
}
|
|
9551
|
-
if (
|
|
10535
|
+
if (path20.resolve(this.materializedProjectRoot) === path20.resolve(this.projectRoot) || !isPathWithinRoot2(filePath, this.materializedProjectRoot)) {
|
|
9552
10536
|
return filePath;
|
|
9553
10537
|
}
|
|
9554
|
-
return
|
|
10538
|
+
return path20.resolve(this.projectRoot, path20.relative(this.materializedProjectRoot, filePath));
|
|
9555
10539
|
}
|
|
9556
10540
|
toStoredFilePath(filePath) {
|
|
9557
10541
|
const canonicalFilePath = this.toCanonicalFilePath(filePath);
|
|
9558
10542
|
if (this.config.scope !== "project" || !isPathWithinRoot2(canonicalFilePath, this.projectRoot)) {
|
|
9559
10543
|
return canonicalFilePath;
|
|
9560
10544
|
}
|
|
9561
|
-
return
|
|
10545
|
+
return path20.relative(this.projectRoot, canonicalFilePath).split(path20.sep).join("/");
|
|
10546
|
+
}
|
|
10547
|
+
isStoredPathExcluded(storedPath) {
|
|
10548
|
+
let matchPath = storedPath.split(path20.sep).join("/");
|
|
10549
|
+
if (path20.isAbsolute(storedPath)) {
|
|
10550
|
+
const relativePath = path20.relative(this.projectRoot, storedPath).split(path20.sep).join("/");
|
|
10551
|
+
if (relativePath.startsWith("..") || path20.isAbsolute(relativePath)) {
|
|
10552
|
+
return false;
|
|
10553
|
+
}
|
|
10554
|
+
matchPath = relativePath;
|
|
10555
|
+
}
|
|
10556
|
+
return isExcludedByPatterns(matchPath, this.config.exclude);
|
|
9562
10557
|
}
|
|
9563
10558
|
resolveStoredFilePath(filePath, rootPath = this.projectRoot) {
|
|
9564
|
-
if (
|
|
10559
|
+
if (path20.isAbsolute(filePath)) {
|
|
9565
10560
|
return filePath;
|
|
9566
10561
|
}
|
|
9567
|
-
const resolvedPath =
|
|
10562
|
+
const resolvedPath = path20.resolve(rootPath, ...filePath.split("/"));
|
|
9568
10563
|
if (!isPathWithinRoot2(resolvedPath, rootPath)) {
|
|
9569
10564
|
throw new Error(`Stored project path escapes project root: ${JSON.stringify(filePath)}`);
|
|
9570
10565
|
}
|
|
@@ -9588,7 +10583,7 @@ var Indexer = class _Indexer {
|
|
|
9588
10583
|
}
|
|
9589
10584
|
toMaterializedFilePath(filePath) {
|
|
9590
10585
|
const storedFilePath = this.toStoredFilePath(filePath);
|
|
9591
|
-
if (
|
|
10586
|
+
if (path20.isAbsolute(storedFilePath)) {
|
|
9592
10587
|
return storedFilePath;
|
|
9593
10588
|
}
|
|
9594
10589
|
return this.resolveStoredFilePath(storedFilePath, this.materializedProjectRoot);
|
|
@@ -9605,10 +10600,10 @@ var Indexer = class _Indexer {
|
|
|
9605
10600
|
}
|
|
9606
10601
|
getRuntimeArtifactPath(fileName) {
|
|
9607
10602
|
const namespace = this.getRuntimeArtifactNamespace();
|
|
9608
|
-
if (!namespace) return
|
|
9609
|
-
const extension =
|
|
10603
|
+
if (!namespace) return path20.join(this.indexPath, fileName);
|
|
10604
|
+
const extension = path20.extname(fileName);
|
|
9610
10605
|
const baseName = fileName.slice(0, fileName.length - extension.length);
|
|
9611
|
-
return
|
|
10606
|
+
return path20.join(this.indexPath, `${baseName}.${namespace}${extension}`);
|
|
9612
10607
|
}
|
|
9613
10608
|
refreshRuntimeArtifactPaths() {
|
|
9614
10609
|
this.fileHashCachePath = this.getRuntimeArtifactPath("file-hashes.json");
|
|
@@ -9621,14 +10616,14 @@ var Indexer = class _Indexer {
|
|
|
9621
10616
|
getMaterializedKnowledgeBases() {
|
|
9622
10617
|
const canonicalProjectRoot = this.getCanonicalPath(this.projectRoot);
|
|
9623
10618
|
return this.config.knowledgeBases.map((knowledgeBase) => {
|
|
9624
|
-
const configuredPath =
|
|
10619
|
+
const configuredPath = path20.isAbsolute(knowledgeBase) ? knowledgeBase : path20.resolve(this.projectRoot, knowledgeBase);
|
|
9625
10620
|
const canonicalPath = this.getCanonicalPath(configuredPath);
|
|
9626
10621
|
if (!isPathWithinRoot2(canonicalPath, canonicalProjectRoot)) {
|
|
9627
10622
|
return canonicalPath;
|
|
9628
10623
|
}
|
|
9629
|
-
return
|
|
10624
|
+
return path20.resolve(
|
|
9630
10625
|
this.materializedProjectRoot,
|
|
9631
|
-
|
|
10626
|
+
path20.relative(canonicalProjectRoot, canonicalPath)
|
|
9632
10627
|
);
|
|
9633
10628
|
});
|
|
9634
10629
|
}
|
|
@@ -9636,7 +10631,7 @@ var Indexer = class _Indexer {
|
|
|
9636
10631
|
try {
|
|
9637
10632
|
return canonicalizePathForComparison(targetPath);
|
|
9638
10633
|
} catch {
|
|
9639
|
-
return
|
|
10634
|
+
return path20.resolve(targetPath);
|
|
9640
10635
|
}
|
|
9641
10636
|
}
|
|
9642
10637
|
getProjectIdentityHash(projectRoot) {
|
|
@@ -9717,7 +10712,7 @@ var Indexer = class _Indexer {
|
|
|
9717
10712
|
} catch (error) {
|
|
9718
10713
|
releaseError = error;
|
|
9719
10714
|
this.writerArtifactFingerprint = null;
|
|
9720
|
-
if (!
|
|
10715
|
+
if (!existsSync12(lease.lockPath) && this.activeIndexLease?.owner.token === lease.owner.token) {
|
|
9721
10716
|
this.activeIndexLease = null;
|
|
9722
10717
|
}
|
|
9723
10718
|
}
|
|
@@ -9735,12 +10730,12 @@ var Indexer = class _Indexer {
|
|
|
9735
10730
|
return this.activeIndexLease;
|
|
9736
10731
|
}
|
|
9737
10732
|
loadFileHashCache() {
|
|
9738
|
-
if (!
|
|
10733
|
+
if (!existsSync12(this.fileHashCachePath)) {
|
|
9739
10734
|
this.fileHashCache = /* @__PURE__ */ new Map();
|
|
9740
10735
|
return;
|
|
9741
10736
|
}
|
|
9742
10737
|
try {
|
|
9743
|
-
const data =
|
|
10738
|
+
const data = readFileSync9(this.fileHashCachePath, "utf-8");
|
|
9744
10739
|
const parsed = JSON.parse(data);
|
|
9745
10740
|
this.fileHashCache = new Map(Object.entries(parsed));
|
|
9746
10741
|
} catch (error) {
|
|
@@ -9762,24 +10757,24 @@ var Indexer = class _Indexer {
|
|
|
9762
10757
|
atomicWriteSync(targetPath, data) {
|
|
9763
10758
|
const lease = this.requireActiveLease();
|
|
9764
10759
|
const tempPath = createLeaseTemporaryPath(targetPath, lease.owner, "tmp");
|
|
9765
|
-
|
|
10760
|
+
mkdirSync5(path20.dirname(targetPath), { recursive: true });
|
|
9766
10761
|
try {
|
|
9767
|
-
|
|
9768
|
-
|
|
10762
|
+
writeFileSync4(tempPath, data);
|
|
10763
|
+
renameSync4(tempPath, targetPath);
|
|
9769
10764
|
} finally {
|
|
9770
10765
|
removeLeaseTemporaryPath(tempPath);
|
|
9771
10766
|
}
|
|
9772
10767
|
}
|
|
9773
10768
|
saveInvertedIndex(invertedIndex) {
|
|
9774
10769
|
this.atomicWriteSync(
|
|
9775
|
-
|
|
10770
|
+
path20.join(this.indexPath, "inverted-index.json"),
|
|
9776
10771
|
invertedIndex.serialize()
|
|
9777
10772
|
);
|
|
9778
10773
|
}
|
|
9779
10774
|
getScopedRoots(projectRoot = this.projectRoot) {
|
|
9780
10775
|
const roots = /* @__PURE__ */ new Set([this.getCanonicalPath(projectRoot)]);
|
|
9781
10776
|
for (const kbRoot of this.config.knowledgeBases) {
|
|
9782
|
-
roots.add(this.getCanonicalPath(
|
|
10777
|
+
roots.add(this.getCanonicalPath(path20.resolve(projectRoot, kbRoot)));
|
|
9783
10778
|
}
|
|
9784
10779
|
return Array.from(roots);
|
|
9785
10780
|
}
|
|
@@ -10196,7 +11191,7 @@ var Indexer = class _Indexer {
|
|
|
10196
11191
|
return configuredProviderInfo !== null && recovery.embeddingProvider === configuredProviderInfo.provider && recovery.embeddingModel === configuredProviderInfo.modelInfo.model && recovery.embeddingDimensions === configuredProviderInfo.modelInfo.dimensions && recovery.embeddingStrategyVersion === EMBEDDING_STRATEGY_VERSION;
|
|
10197
11192
|
}
|
|
10198
11193
|
hasUnknownLegacyForceIndexClear(owner) {
|
|
10199
|
-
return owner.operation === "force-index" && owner.clearRecovery === void 0 && owner.recoveryProtocolVersion !== 1 &&
|
|
11194
|
+
return owner.operation === "force-index" && owner.clearRecovery === void 0 && owner.recoveryProtocolVersion !== 1 && existsSync12(path20.join(this.indexPath, "force-index-phase"));
|
|
10200
11195
|
}
|
|
10201
11196
|
async recoverFromInterruptedIndexingUnlocked(owners) {
|
|
10202
11197
|
for (const owner of owners) {
|
|
@@ -10382,7 +11377,7 @@ var Indexer = class _Indexer {
|
|
|
10382
11377
|
}
|
|
10383
11378
|
}
|
|
10384
11379
|
clearFailedBatchState() {
|
|
10385
|
-
if (
|
|
11380
|
+
if (existsSync12(this.failedBatchesPath)) {
|
|
10386
11381
|
try {
|
|
10387
11382
|
unlinkSync2(this.failedBatchesPath);
|
|
10388
11383
|
} catch {
|
|
@@ -10584,7 +11579,7 @@ var Indexer = class _Indexer {
|
|
|
10584
11579
|
await options.queue.onSizeLessThan(Math.max(1, options.providerRateLimits.concurrency));
|
|
10585
11580
|
const task = options.queue.add(async () => {
|
|
10586
11581
|
if (options.rateLimitState.backoffMs > 0) {
|
|
10587
|
-
await new Promise((
|
|
11582
|
+
await new Promise((resolve20) => setTimeout(resolve20, options.rateLimitState.backoffMs));
|
|
10588
11583
|
}
|
|
10589
11584
|
try {
|
|
10590
11585
|
const embeddingResult = await pRetry(
|
|
@@ -11003,12 +11998,12 @@ var Indexer = class _Indexer {
|
|
|
11003
11998
|
}
|
|
11004
11999
|
}
|
|
11005
12000
|
captureReaderArtifactFingerprint() {
|
|
11006
|
-
const storePath =
|
|
12001
|
+
const storePath = path20.join(this.indexPath, "vectors");
|
|
11007
12002
|
return {
|
|
11008
12003
|
vectors: `${this.getReaderFileFingerprint(storePath)}|${this.getReaderFileFingerprint(`${storePath}.meta.json`)}`,
|
|
11009
|
-
keyword: this.getReaderFileFingerprint(
|
|
11010
|
-
database: this.getReaderFileFingerprint(
|
|
11011
|
-
databaseIdentity: this.getReaderFileFingerprint(
|
|
12004
|
+
keyword: this.getReaderFileFingerprint(path20.join(this.indexPath, "inverted-index.json")),
|
|
12005
|
+
database: this.getReaderFileFingerprint(path20.join(this.indexPath, "codebase.db")),
|
|
12006
|
+
databaseIdentity: this.getReaderFileFingerprint(path20.join(this.indexPath, "codebase.db"), true)
|
|
11012
12007
|
};
|
|
11013
12008
|
}
|
|
11014
12009
|
refreshReaderArtifacts() {
|
|
@@ -11033,13 +12028,13 @@ var Indexer = class _Indexer {
|
|
|
11033
12028
|
issues.set(component, this.createReadIssue(component, message));
|
|
11034
12029
|
this.readerArtifactRetryAfter.set(component, Date.now() + READER_ARTIFACT_RETRY_INTERVAL_MS);
|
|
11035
12030
|
};
|
|
11036
|
-
const storePath =
|
|
12031
|
+
const storePath = path20.join(this.indexPath, "vectors");
|
|
11037
12032
|
const vectorMetadataPath = `${storePath}.meta.json`;
|
|
11038
|
-
const invertedIndexPath =
|
|
11039
|
-
const dbPath =
|
|
12033
|
+
const invertedIndexPath = path20.join(this.indexPath, "inverted-index.json");
|
|
12034
|
+
const dbPath = path20.join(this.indexPath, "codebase.db");
|
|
11040
12035
|
if (vectorsChanged || retryDue("vectors")) {
|
|
11041
|
-
const vectorStoreExists =
|
|
11042
|
-
const vectorMetadataExists =
|
|
12036
|
+
const vectorStoreExists = existsSync12(storePath);
|
|
12037
|
+
const vectorMetadataExists = existsSync12(vectorMetadataPath);
|
|
11043
12038
|
if (vectorStoreExists && vectorMetadataExists) {
|
|
11044
12039
|
try {
|
|
11045
12040
|
const store = new VectorStore(storePath, this.configuredProviderInfo.modelInfo.dimensions);
|
|
@@ -11054,8 +12049,8 @@ var Indexer = class _Indexer {
|
|
|
11054
12049
|
setIssue("vectors", this.getVectorReadIssueMessage());
|
|
11055
12050
|
}
|
|
11056
12051
|
}
|
|
11057
|
-
if (keywordChanged || retryDue("keyword") || !
|
|
11058
|
-
if (
|
|
12052
|
+
if (keywordChanged || retryDue("keyword") || !existsSync12(invertedIndexPath) && (this.store?.count() ?? 0) > 0) {
|
|
12053
|
+
if (existsSync12(invertedIndexPath)) {
|
|
11059
12054
|
try {
|
|
11060
12055
|
const invertedIndex = new InvertedIndex(invertedIndexPath);
|
|
11061
12056
|
invertedIndex.load();
|
|
@@ -11070,7 +12065,7 @@ var Indexer = class _Indexer {
|
|
|
11070
12065
|
}
|
|
11071
12066
|
}
|
|
11072
12067
|
if (databaseReplaced || databaseChanged && issues.has("database") || retryDue("database")) {
|
|
11073
|
-
if (
|
|
12068
|
+
if (existsSync12(dbPath)) {
|
|
11074
12069
|
try {
|
|
11075
12070
|
const database = Database.openReadOnly(dbPath);
|
|
11076
12071
|
if (this.database) {
|
|
@@ -11152,11 +12147,11 @@ var Indexer = class _Indexer {
|
|
|
11152
12147
|
});
|
|
11153
12148
|
this.provider = createEmbeddingProvider(this.configuredProviderInfo);
|
|
11154
12149
|
const dimensions = this.configuredProviderInfo.modelInfo.dimensions;
|
|
11155
|
-
const storePath =
|
|
12150
|
+
const storePath = path20.join(this.indexPath, "vectors");
|
|
11156
12151
|
const vectorMetadataPath = `${storePath}.meta.json`;
|
|
11157
|
-
const invertedIndexPath =
|
|
11158
|
-
const dbPath =
|
|
11159
|
-
let dbIsNew = !
|
|
12152
|
+
const invertedIndexPath = path20.join(this.indexPath, "inverted-index.json");
|
|
12153
|
+
const dbPath = path20.join(this.indexPath, "codebase.db");
|
|
12154
|
+
let dbIsNew = !existsSync12(dbPath);
|
|
11160
12155
|
const readerArtifactFingerprint = mode === "reader" ? this.captureReaderArtifactFingerprint() : null;
|
|
11161
12156
|
if (mode === "writer") {
|
|
11162
12157
|
await fsPromises3.mkdir(this.indexPath, { recursive: true });
|
|
@@ -11188,14 +12183,14 @@ var Indexer = class _Indexer {
|
|
|
11188
12183
|
}
|
|
11189
12184
|
}
|
|
11190
12185
|
this.store = new VectorStore(storePath, dimensions);
|
|
11191
|
-
if (
|
|
12186
|
+
if (existsSync12(storePath) || existsSync12(vectorMetadataPath)) {
|
|
11192
12187
|
this.store.load();
|
|
11193
12188
|
}
|
|
11194
12189
|
this.invertedIndex = new InvertedIndex(invertedIndexPath);
|
|
11195
12190
|
try {
|
|
11196
12191
|
this.invertedIndex.load();
|
|
11197
12192
|
} catch {
|
|
11198
|
-
if (
|
|
12193
|
+
if (existsSync12(invertedIndexPath)) {
|
|
11199
12194
|
await fsPromises3.unlink(invertedIndexPath);
|
|
11200
12195
|
}
|
|
11201
12196
|
this.invertedIndex = new InvertedIndex(invertedIndexPath);
|
|
@@ -11213,8 +12208,8 @@ var Indexer = class _Indexer {
|
|
|
11213
12208
|
}
|
|
11214
12209
|
} else {
|
|
11215
12210
|
this.store = new VectorStore(storePath, dimensions);
|
|
11216
|
-
const vectorStoreExists =
|
|
11217
|
-
const vectorMetadataExists =
|
|
12211
|
+
const vectorStoreExists = existsSync12(storePath);
|
|
12212
|
+
const vectorMetadataExists = existsSync12(vectorMetadataPath);
|
|
11218
12213
|
const vectorReadFailureMessage = this.getVectorReadIssueMessage();
|
|
11219
12214
|
if (vectorStoreExists !== vectorMetadataExists) {
|
|
11220
12215
|
this.recordReadIssue("vectors", vectorReadFailureMessage);
|
|
@@ -11227,7 +12222,7 @@ var Indexer = class _Indexer {
|
|
|
11227
12222
|
}
|
|
11228
12223
|
}
|
|
11229
12224
|
this.invertedIndex = new InvertedIndex(invertedIndexPath);
|
|
11230
|
-
if (
|
|
12225
|
+
if (existsSync12(invertedIndexPath)) {
|
|
11231
12226
|
try {
|
|
11232
12227
|
this.invertedIndex.load();
|
|
11233
12228
|
} catch (error) {
|
|
@@ -11241,7 +12236,7 @@ var Indexer = class _Indexer {
|
|
|
11241
12236
|
} else if (this.store.count() > 0) {
|
|
11242
12237
|
this.recordReadIssue("keyword", this.getKeywordReadIssueMessage());
|
|
11243
12238
|
}
|
|
11244
|
-
if (
|
|
12239
|
+
if (existsSync12(dbPath)) {
|
|
11245
12240
|
try {
|
|
11246
12241
|
this.database = Database.openReadOnly(dbPath);
|
|
11247
12242
|
} catch (error) {
|
|
@@ -11333,7 +12328,7 @@ var Indexer = class _Indexer {
|
|
|
11333
12328
|
if (await this.tryResetCorruptedIndex("running automatic orphan garbage collection", error)) {
|
|
11334
12329
|
return {
|
|
11335
12330
|
resetCorruptedIndex: true,
|
|
11336
|
-
warning: this.getCorruptedIndexWarning(
|
|
12331
|
+
warning: this.getCorruptedIndexWarning(path20.join(this.indexPath, "codebase.db"))
|
|
11337
12332
|
};
|
|
11338
12333
|
}
|
|
11339
12334
|
throw error;
|
|
@@ -11348,7 +12343,7 @@ var Indexer = class _Indexer {
|
|
|
11348
12343
|
return;
|
|
11349
12344
|
}
|
|
11350
12345
|
const retainedEntries = store.getAllMetadata().filter(({ key }) => !excludedSet.has(key));
|
|
11351
|
-
const storeBasePath =
|
|
12346
|
+
const storeBasePath = path20.join(this.indexPath, "vectors");
|
|
11352
12347
|
const storeIndexPath = storeBasePath;
|
|
11353
12348
|
const storeMetadataPath = `${storeBasePath}.meta.json`;
|
|
11354
12349
|
const lease = this.requireActiveLease();
|
|
@@ -11358,19 +12353,19 @@ var Indexer = class _Indexer {
|
|
|
11358
12353
|
let backedUpMetadata = false;
|
|
11359
12354
|
let rebuiltCount = 0;
|
|
11360
12355
|
let skippedCount = 0;
|
|
11361
|
-
if (
|
|
12356
|
+
if (existsSync12(backupIndexPath)) {
|
|
11362
12357
|
unlinkSync2(backupIndexPath);
|
|
11363
12358
|
}
|
|
11364
|
-
if (
|
|
12359
|
+
if (existsSync12(backupMetadataPath)) {
|
|
11365
12360
|
unlinkSync2(backupMetadataPath);
|
|
11366
12361
|
}
|
|
11367
12362
|
try {
|
|
11368
|
-
if (
|
|
11369
|
-
|
|
12363
|
+
if (existsSync12(storeIndexPath)) {
|
|
12364
|
+
renameSync4(storeIndexPath, backupIndexPath);
|
|
11370
12365
|
backedUpIndex = true;
|
|
11371
12366
|
}
|
|
11372
|
-
if (
|
|
11373
|
-
|
|
12367
|
+
if (existsSync12(storeMetadataPath)) {
|
|
12368
|
+
renameSync4(storeMetadataPath, backupMetadataPath);
|
|
11374
12369
|
backedUpMetadata = true;
|
|
11375
12370
|
}
|
|
11376
12371
|
store.clear();
|
|
@@ -11390,10 +12385,10 @@ var Indexer = class _Indexer {
|
|
|
11390
12385
|
rebuiltCount += 1;
|
|
11391
12386
|
}
|
|
11392
12387
|
store.save();
|
|
11393
|
-
if (backedUpIndex &&
|
|
12388
|
+
if (backedUpIndex && existsSync12(backupIndexPath)) {
|
|
11394
12389
|
unlinkSync2(backupIndexPath);
|
|
11395
12390
|
}
|
|
11396
|
-
if (backedUpMetadata &&
|
|
12391
|
+
if (backedUpMetadata && existsSync12(backupMetadataPath)) {
|
|
11397
12392
|
unlinkSync2(backupMetadataPath);
|
|
11398
12393
|
}
|
|
11399
12394
|
this.logger.gc("info", "Rebuilt vector store to avoid native remove", {
|
|
@@ -11406,17 +12401,17 @@ var Indexer = class _Indexer {
|
|
|
11406
12401
|
store.clear();
|
|
11407
12402
|
} catch {
|
|
11408
12403
|
}
|
|
11409
|
-
if (
|
|
12404
|
+
if (existsSync12(storeIndexPath)) {
|
|
11410
12405
|
unlinkSync2(storeIndexPath);
|
|
11411
12406
|
}
|
|
11412
|
-
if (
|
|
12407
|
+
if (existsSync12(storeMetadataPath)) {
|
|
11413
12408
|
unlinkSync2(storeMetadataPath);
|
|
11414
12409
|
}
|
|
11415
|
-
if (backedUpIndex &&
|
|
11416
|
-
|
|
12410
|
+
if (backedUpIndex && existsSync12(backupIndexPath)) {
|
|
12411
|
+
renameSync4(backupIndexPath, storeIndexPath);
|
|
11417
12412
|
}
|
|
11418
|
-
if (backedUpMetadata &&
|
|
11419
|
-
|
|
12413
|
+
if (backedUpMetadata && existsSync12(backupMetadataPath)) {
|
|
12414
|
+
renameSync4(backupMetadataPath, storeMetadataPath);
|
|
11420
12415
|
}
|
|
11421
12416
|
if (backedUpIndex || backedUpMetadata) {
|
|
11422
12417
|
store.load();
|
|
@@ -11431,11 +12426,11 @@ var Indexer = class _Indexer {
|
|
|
11431
12426
|
return `Detected a corrupted local SQLite index at ${dbPath} and reset the local index. Run index_codebase to rebuild search data.`;
|
|
11432
12427
|
}
|
|
11433
12428
|
async removeProjectRuntimeStateArtifacts() {
|
|
11434
|
-
if (!
|
|
12429
|
+
if (!existsSync12(this.indexPath)) return;
|
|
11435
12430
|
const names = await fsPromises3.readdir(this.indexPath);
|
|
11436
12431
|
const runtimeStatePattern = /^(?:file-hashes|failed-batches)(?:\.[a-f0-9]{16})?\.json$/;
|
|
11437
12432
|
await Promise.all(
|
|
11438
|
-
names.filter((name) => runtimeStatePattern.test(name)).map((name) => fsPromises3.rm(
|
|
12433
|
+
names.filter((name) => runtimeStatePattern.test(name)).map((name) => fsPromises3.rm(path20.join(this.indexPath, name), { force: true }))
|
|
11439
12434
|
);
|
|
11440
12435
|
}
|
|
11441
12436
|
async resetLocalIndexArtifacts() {
|
|
@@ -11451,13 +12446,13 @@ var Indexer = class _Indexer {
|
|
|
11451
12446
|
this.readerArtifactRetryAfter.clear();
|
|
11452
12447
|
this.fileHashCache.clear();
|
|
11453
12448
|
const resetPaths = [
|
|
11454
|
-
|
|
11455
|
-
|
|
11456
|
-
|
|
11457
|
-
|
|
11458
|
-
|
|
11459
|
-
|
|
11460
|
-
|
|
12449
|
+
path20.join(this.indexPath, "codebase.db"),
|
|
12450
|
+
path20.join(this.indexPath, "codebase.db-shm"),
|
|
12451
|
+
path20.join(this.indexPath, "codebase.db-wal"),
|
|
12452
|
+
path20.join(this.indexPath, "vectors"),
|
|
12453
|
+
path20.join(this.indexPath, "vectors.usearch"),
|
|
12454
|
+
path20.join(this.indexPath, "vectors.meta.json"),
|
|
12455
|
+
path20.join(this.indexPath, "inverted-index.json")
|
|
11461
12456
|
];
|
|
11462
12457
|
await Promise.all(resetPaths.map((targetPath) => fsPromises3.rm(targetPath, { recursive: true, force: true })));
|
|
11463
12458
|
await this.removeProjectRuntimeStateArtifacts();
|
|
@@ -11467,7 +12462,7 @@ var Indexer = class _Indexer {
|
|
|
11467
12462
|
if (!isSqliteCorruptionError(error)) {
|
|
11468
12463
|
return false;
|
|
11469
12464
|
}
|
|
11470
|
-
const dbPath =
|
|
12465
|
+
const dbPath = path20.join(this.indexPath, "codebase.db");
|
|
11471
12466
|
const warning = this.getCorruptedIndexWarning(dbPath);
|
|
11472
12467
|
const errorMessage = getErrorMessage4(error);
|
|
11473
12468
|
if (this.config.scope === "global") {
|
|
@@ -11854,10 +12849,10 @@ var Indexer = class _Indexer {
|
|
|
11854
12849
|
const reparseCachedMetalFiles = database.getMetadata(metalParserMetadataKey) !== METAL_PARSER_VERSION;
|
|
11855
12850
|
const symbolExtractorMetadataKey = this.getSymbolExtractorVersionMetadataKey();
|
|
11856
12851
|
const refreshCachedSymbols = database.getMetadata(symbolExtractorMetadataKey) !== SYMBOL_EXTRACTOR_VERSION;
|
|
11857
|
-
if (reparseCachedSwiftFiles && Array.from(this.fileHashCache.keys()).some((filePath) =>
|
|
12852
|
+
if (reparseCachedSwiftFiles && Array.from(this.fileHashCache.keys()).some((filePath) => path20.extname(filePath).toLowerCase() === ".swift")) {
|
|
11858
12853
|
this.logger.info("Reindexing cached Swift files for parser support");
|
|
11859
12854
|
}
|
|
11860
|
-
if (reparseCachedMetalFiles && Array.from(this.fileHashCache.keys()).some((filePath) =>
|
|
12855
|
+
if (reparseCachedMetalFiles && Array.from(this.fileHashCache.keys()).some((filePath) => path20.extname(filePath).toLowerCase() === ".metal")) {
|
|
11861
12856
|
this.logger.info("Reindexing cached Metal files for parser support");
|
|
11862
12857
|
}
|
|
11863
12858
|
const includePatterns = [...this.config.include, ...this.config.additionalInclude];
|
|
@@ -11901,8 +12896,8 @@ var Indexer = class _Indexer {
|
|
|
11901
12896
|
const needsCallGraphRefresh = cachedHashMatches && needsCallGraphResolutionMigration && database.getChunksByFile(storedPath).some(
|
|
11902
12897
|
(chunk) => chunk.language === "php" || chunk.language === "c" || chunk.language === "cpp"
|
|
11903
12898
|
);
|
|
11904
|
-
const requiresSwiftParserUpgrade = reparseCachedSwiftFiles &&
|
|
11905
|
-
const requiresMetalParserUpgrade = reparseCachedMetalFiles &&
|
|
12899
|
+
const requiresSwiftParserUpgrade = reparseCachedSwiftFiles && path20.extname(storedPath).toLowerCase() === ".swift";
|
|
12900
|
+
const requiresMetalParserUpgrade = reparseCachedMetalFiles && path20.extname(storedPath).toLowerCase() === ".metal";
|
|
11906
12901
|
const inMigrationScope = forceScopedReembed && scopedRoots !== null && this.isFileInCurrentScope(storedPath, scopedRoots);
|
|
11907
12902
|
if (cachedHashMatches && !inMigrationScope && !needsCallGraphRefresh && !requiresSwiftParserUpgrade && !requiresMetalParserUpgrade && !refreshCachedSymbols) {
|
|
11908
12903
|
unchangedFilePaths.add(storedPath);
|
|
@@ -11961,7 +12956,7 @@ var Indexer = class _Indexer {
|
|
|
11961
12956
|
}
|
|
11962
12957
|
}
|
|
11963
12958
|
}
|
|
11964
|
-
const shouldRetryFailedPath = (filePath) => filePath !== null && currentFileHashes.has(filePath) && unchangedFilePaths.has(filePath);
|
|
12959
|
+
const shouldRetryFailedPath = (filePath) => filePath !== null && !this.isStoredPathExcluded(filePath) && currentFileHashes.has(filePath) && unchangedFilePaths.has(filePath);
|
|
11965
12960
|
const failedProcessing = this.prepareFailedBatchProcessing(scopedRoots, shouldRetryFailedPath);
|
|
11966
12961
|
const maxChunkTokens = getSafeEmbeddingChunkTokenLimit(configuredProviderInfo);
|
|
11967
12962
|
const providerRateLimits = this.getProviderRateLimits(configuredProviderInfo.provider);
|
|
@@ -12065,7 +13060,7 @@ var Indexer = class _Indexer {
|
|
|
12065
13060
|
throw new Error(`Parsed file was not present in its source batch: ${parsed.path}`);
|
|
12066
13061
|
}
|
|
12067
13062
|
if (parsed.chunks.length === 0) {
|
|
12068
|
-
stats.parseFailures.push(
|
|
13063
|
+
stats.parseFailures.push(path20.isAbsolute(parsed.path) ? path20.relative(this.projectRoot, parsed.path) : parsed.path);
|
|
12069
13064
|
}
|
|
12070
13065
|
let chunksToProcess = parsed.chunks;
|
|
12071
13066
|
if (this.config.indexing.fallbackToTextOnMaxChunks && chunksToProcess.length > this.config.indexing.maxChunksPerFile) {
|
|
@@ -12400,8 +13395,8 @@ var Indexer = class _Indexer {
|
|
|
12400
13395
|
previousBranchSymbolIds,
|
|
12401
13396
|
Array.from(allSymbolIds)
|
|
12402
13397
|
);
|
|
12403
|
-
const vectorPath =
|
|
12404
|
-
const shouldFingerprintLegacyPair = !store.hasFingerprint() &&
|
|
13398
|
+
const vectorPath = path20.join(this.indexPath, "vectors");
|
|
13399
|
+
const shouldFingerprintLegacyPair = !store.hasFingerprint() && existsSync12(vectorPath) && existsSync12(`${vectorPath}.meta.json`);
|
|
12405
13400
|
if (backfilledBlameMetadata || shouldFingerprintLegacyPair || removedStoredChunks) {
|
|
12406
13401
|
store.save();
|
|
12407
13402
|
}
|
|
@@ -13196,7 +14191,7 @@ var Indexer = class _Indexer {
|
|
|
13196
14191
|
const missingChunkKeys = [];
|
|
13197
14192
|
const chunkKeysByRemovedFile = /* @__PURE__ */ new Map();
|
|
13198
14193
|
for (const [filePath, chunkKeys] of filePathsToChunkKeys) {
|
|
13199
|
-
if (!
|
|
14194
|
+
if (!existsSync12(this.toMaterializedFilePath(filePath))) {
|
|
13200
14195
|
chunkKeysByRemovedFile.set(filePath, chunkKeys);
|
|
13201
14196
|
for (const key of chunkKeys) {
|
|
13202
14197
|
missingChunkKeys.push(key);
|
|
@@ -13259,7 +14254,7 @@ var Indexer = class _Indexer {
|
|
|
13259
14254
|
gcOrphanSymbols: 0,
|
|
13260
14255
|
gcOrphanCallEdges: 0,
|
|
13261
14256
|
resetCorruptedIndex: true,
|
|
13262
|
-
warning: this.getCorruptedIndexWarning(
|
|
14257
|
+
warning: this.getCorruptedIndexWarning(path20.join(this.indexPath, "codebase.db"))
|
|
13263
14258
|
};
|
|
13264
14259
|
}
|
|
13265
14260
|
this.logger.recordGc(removedCount, gcOrphanChunks, gcOrphanEmbeddings);
|
|
@@ -13289,7 +14284,8 @@ var Indexer = class _Indexer {
|
|
|
13289
14284
|
const maxChunkTokens = getSafeEmbeddingChunkTokenLimit(configuredProviderInfo);
|
|
13290
14285
|
const providerRateLimits = this.getProviderRateLimits(configuredProviderInfo.provider);
|
|
13291
14286
|
const roots = this.config.scope === "global" ? this.getScopedRoots() : null;
|
|
13292
|
-
const
|
|
14287
|
+
const shouldProcessFailedPath = (filePath) => filePath === null || !this.isStoredPathExcluded(filePath);
|
|
14288
|
+
const failedProcessing = this.prepareFailedBatchProcessing(roots, shouldProcessFailedPath);
|
|
13293
14289
|
if (failedProcessing.latestById.size === 0) {
|
|
13294
14290
|
this.finalizeFailedBatchWriteState(failedProcessing.state);
|
|
13295
14291
|
return { succeeded: 0, failed: 0, remaining: 0 };
|
|
@@ -13302,7 +14298,7 @@ var Indexer = class _Indexer {
|
|
|
13302
14298
|
const retryableChunks = this.iterateLatestFailedChunks(
|
|
13303
14299
|
failedProcessing.latestById,
|
|
13304
14300
|
roots,
|
|
13305
|
-
|
|
14301
|
+
shouldProcessFailedPath,
|
|
13306
14302
|
maxChunkTokens
|
|
13307
14303
|
);
|
|
13308
14304
|
for (const retryBatch of iterateOrderedFileBatches(
|
|
@@ -13572,9 +14568,9 @@ var Indexer = class _Indexer {
|
|
|
13572
14568
|
this.requireReadableComponents(readIssues, "database");
|
|
13573
14569
|
let shortest = [];
|
|
13574
14570
|
for (const branchKey of this.getBranchCatalogKeys()) {
|
|
13575
|
-
const
|
|
13576
|
-
if (
|
|
13577
|
-
shortest =
|
|
14571
|
+
const path35 = database.findShortestPath(fromName, toName, branchKey, maxDepth);
|
|
14572
|
+
if (path35.length > 0 && (shortest.length === 0 || path35.length < shortest.length)) {
|
|
14573
|
+
shortest = path35;
|
|
13578
14574
|
}
|
|
13579
14575
|
}
|
|
13580
14576
|
return shortest.map((hop) => this.resolveFilePathRecord(hop));
|
|
@@ -13622,13 +14618,13 @@ var Indexer = class _Indexer {
|
|
|
13622
14618
|
}
|
|
13623
14619
|
}
|
|
13624
14620
|
if (!found) continue;
|
|
13625
|
-
const
|
|
14621
|
+
const path35 = [];
|
|
13626
14622
|
let currentSymbolId = toSymbolId;
|
|
13627
14623
|
while (true) {
|
|
13628
14624
|
const symbol = symbolsById.get(currentSymbolId);
|
|
13629
14625
|
if (!symbol) break;
|
|
13630
14626
|
const parent = parentBySymbolId.get(currentSymbolId);
|
|
13631
|
-
|
|
14627
|
+
path35.push({
|
|
13632
14628
|
symbolId: symbol.id,
|
|
13633
14629
|
symbolName: symbol.name,
|
|
13634
14630
|
filePath: symbol.filePath,
|
|
@@ -13638,9 +14634,9 @@ var Indexer = class _Indexer {
|
|
|
13638
14634
|
if (!parent) break;
|
|
13639
14635
|
currentSymbolId = parent.parentId;
|
|
13640
14636
|
}
|
|
13641
|
-
|
|
13642
|
-
if (
|
|
13643
|
-
shortest =
|
|
14637
|
+
path35.reverse();
|
|
14638
|
+
if (path35.length > 0 && (shortest.length === 0 || path35.length < shortest.length)) {
|
|
14639
|
+
shortest = path35;
|
|
13644
14640
|
}
|
|
13645
14641
|
}
|
|
13646
14642
|
return shortest.map((hop) => this.resolveFilePathRecord(hop));
|
|
@@ -13791,7 +14787,7 @@ var Indexer = class _Indexer {
|
|
|
13791
14787
|
);
|
|
13792
14788
|
}
|
|
13793
14789
|
}
|
|
13794
|
-
const toStoredChangedFiles = (filePaths) => filePaths.map((filePath) => this.toStoredFilePath(
|
|
14790
|
+
const toStoredChangedFiles = (filePaths) => filePaths.map((filePath) => this.toStoredFilePath(path20.resolve(this.projectRoot, filePath)));
|
|
13795
14791
|
const storedChangedFiles = toStoredChangedFiles(changedFiles);
|
|
13796
14792
|
const directSymbols = database.getSymbolsForFiles(storedChangedFiles, branchKey);
|
|
13797
14793
|
const directIds = directSymbols.map((s) => s.id);
|
|
@@ -13940,12 +14936,12 @@ var Indexer = class _Indexer {
|
|
|
13940
14936
|
if (meta.filePath) filePaths.add(meta.filePath);
|
|
13941
14937
|
}
|
|
13942
14938
|
const directory = options?.directory?.replace(/\/$/, "");
|
|
13943
|
-
const absoluteDirectoryFilter = directory ?
|
|
14939
|
+
const absoluteDirectoryFilter = directory ? path20.resolve(this.projectRoot, directory) : void 0;
|
|
13944
14940
|
for (const filePath of filePaths) {
|
|
13945
14941
|
if (directory) {
|
|
13946
14942
|
const absoluteFilePath = this.resolveStoredFilePath(filePath);
|
|
13947
14943
|
const matchesRelative = filePath === directory || filePath.startsWith(directory + "/");
|
|
13948
|
-
const matchesProjectRelative = absoluteDirectoryFilter !== void 0 && (absoluteFilePath === absoluteDirectoryFilter || absoluteFilePath.startsWith(absoluteDirectoryFilter +
|
|
14944
|
+
const matchesProjectRelative = absoluteDirectoryFilter !== void 0 && (absoluteFilePath === absoluteDirectoryFilter || absoluteFilePath.startsWith(absoluteDirectoryFilter + path20.sep));
|
|
13949
14945
|
if (!matchesRelative && !matchesProjectRelative) {
|
|
13950
14946
|
continue;
|
|
13951
14947
|
}
|
|
@@ -14034,15 +15030,24 @@ function getOrCreateIndexer(projectRoot, host) {
|
|
|
14034
15030
|
}
|
|
14035
15031
|
const indexer = new Indexer(projectRoot, config, host);
|
|
14036
15032
|
indexerCache.set(key, indexer);
|
|
14037
|
-
configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host)
|
|
15033
|
+
configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host), {
|
|
15034
|
+
preserveManagedWorker: true,
|
|
15035
|
+
synchronizeBackgroundWorker: false
|
|
15036
|
+
});
|
|
14038
15037
|
return indexer;
|
|
14039
15038
|
}
|
|
14040
|
-
function initializeTools(projectRoot, config, host) {
|
|
15039
|
+
function initializeTools(projectRoot, config, host, options = {}) {
|
|
14041
15040
|
defaultProjectRoots.set(host, projectRoot);
|
|
14042
15041
|
const key = getIndexerCacheKey(projectRoot, host);
|
|
15042
|
+
if (options.preserveManagedWorker === true && isBackgroundWorkerManaged(projectRoot, host) && indexerCache.has(key)) {
|
|
15043
|
+
return;
|
|
15044
|
+
}
|
|
14043
15045
|
configCache.set(key, config);
|
|
14044
15046
|
indexerCache.set(key, new Indexer(projectRoot, config, host));
|
|
14045
|
-
configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host)
|
|
15047
|
+
configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host), {
|
|
15048
|
+
preserveManagedWorker: options.preserveManagedWorker,
|
|
15049
|
+
synchronizeBackgroundWorker: false
|
|
15050
|
+
});
|
|
14046
15051
|
}
|
|
14047
15052
|
function getIndexerForProject(projectRoot, host) {
|
|
14048
15053
|
const root = getProjectRoot(projectRoot, host);
|
|
@@ -14072,7 +15077,7 @@ function trimOrUndefined(value) {
|
|
|
14072
15077
|
return normalized || void 0;
|
|
14073
15078
|
}
|
|
14074
15079
|
function normalizeCallGraphPath(value) {
|
|
14075
|
-
let normalized =
|
|
15080
|
+
let normalized = path21.posix.normalize(value.trim().replaceAll("\\", "/"));
|
|
14076
15081
|
if (normalized.startsWith("./")) {
|
|
14077
15082
|
normalized = normalized.slice(2);
|
|
14078
15083
|
}
|
|
@@ -14287,39 +15292,39 @@ async function executeCallGraph(projectRoot, host, args) {
|
|
|
14287
15292
|
|
|
14288
15293
|
// src/adapters/mcp/cli.ts
|
|
14289
15294
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
14290
|
-
import { realpathSync as
|
|
14291
|
-
import * as
|
|
14292
|
-
import * as
|
|
15295
|
+
import { realpathSync as realpathSync7, writeFileSync as writeFileSync7 } from "fs";
|
|
15296
|
+
import * as os9 from "os";
|
|
15297
|
+
import * as path33 from "path";
|
|
14293
15298
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
14294
15299
|
|
|
14295
15300
|
// src/eval/reports.ts
|
|
14296
|
-
import { mkdirSync as
|
|
14297
|
-
import * as
|
|
15301
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
|
|
15302
|
+
import * as path22 from "path";
|
|
14298
15303
|
|
|
14299
15304
|
// src/eval/runner.ts
|
|
14300
15305
|
import * as crypto2 from "crypto";
|
|
14301
|
-
import { existsSync as
|
|
14302
|
-
import * as
|
|
15306
|
+
import { existsSync as existsSync15 } from "fs";
|
|
15307
|
+
import * as path24 from "path";
|
|
14303
15308
|
|
|
14304
15309
|
// src/eval/runner-config.ts
|
|
14305
|
-
import { existsSync as
|
|
14306
|
-
import * as
|
|
14307
|
-
import * as
|
|
15310
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync7, readFileSync as readFileSync11, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "fs";
|
|
15311
|
+
import * as os8 from "os";
|
|
15312
|
+
import * as path23 from "path";
|
|
14308
15313
|
|
|
14309
15314
|
// src/eval/schema.ts
|
|
14310
|
-
import { readFileSync as
|
|
15315
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
14311
15316
|
|
|
14312
15317
|
// src/eval/cli.ts
|
|
14313
|
-
import * as
|
|
15318
|
+
import * as path26 from "path";
|
|
14314
15319
|
|
|
14315
15320
|
// src/eval/cli-parser.ts
|
|
14316
|
-
import * as
|
|
15321
|
+
import * as path25 from "path";
|
|
14317
15322
|
|
|
14318
15323
|
// src/adapters/mcp/server.ts
|
|
14319
15324
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
14320
15325
|
|
|
14321
15326
|
// src/package-metadata.ts
|
|
14322
|
-
import { readFileSync as
|
|
15327
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
14323
15328
|
|
|
14324
15329
|
// src/adapters/mcp/register-prompts.ts
|
|
14325
15330
|
import { z } from "zod";
|
|
@@ -14418,26 +15423,26 @@ var MCP_TOOL_NAMES = [
|
|
|
14418
15423
|
];
|
|
14419
15424
|
|
|
14420
15425
|
// src/watcher/file-watcher.ts
|
|
14421
|
-
import { existsSync as
|
|
14422
|
-
import * as
|
|
15426
|
+
import { existsSync as existsSync16, statSync as statSync6 } from "fs";
|
|
15427
|
+
import * as path29 from "path";
|
|
14423
15428
|
|
|
14424
15429
|
// src/watcher/native-recursive-watcher.ts
|
|
14425
15430
|
import { watch } from "fs";
|
|
14426
|
-
import * as
|
|
15431
|
+
import * as path27 from "path";
|
|
14427
15432
|
|
|
14428
15433
|
// src/watcher/snapshot.ts
|
|
14429
15434
|
import * as fsPromises4 from "fs/promises";
|
|
14430
|
-
import * as
|
|
15435
|
+
import * as path28 from "path";
|
|
14431
15436
|
|
|
14432
15437
|
// src/watcher/git-head-watcher.ts
|
|
14433
|
-
import * as
|
|
15438
|
+
import * as path30 from "path";
|
|
14434
15439
|
|
|
14435
15440
|
// src/tools/visualize/activity.ts
|
|
14436
15441
|
import { execFileSync } from "child_process";
|
|
14437
|
-
import * as
|
|
15442
|
+
import * as path31 from "path";
|
|
14438
15443
|
|
|
14439
15444
|
// src/tools/visualize/transform.ts
|
|
14440
|
-
import * as
|
|
15445
|
+
import * as path32 from "path";
|
|
14441
15446
|
|
|
14442
15447
|
// src/adapters/mcp/cli.ts
|
|
14443
15448
|
function parseIndexArgs(argv, cwd) {
|
|
@@ -14459,7 +15464,7 @@ function parseIndexArgs(argv, cwd) {
|
|
|
14459
15464
|
if (!arg.startsWith("--project=")) {
|
|
14460
15465
|
i += 1;
|
|
14461
15466
|
}
|
|
14462
|
-
project =
|
|
15467
|
+
project = path33.resolve(cwd, value);
|
|
14463
15468
|
continue;
|
|
14464
15469
|
}
|
|
14465
15470
|
if (arg === "--config" || arg.startsWith("--config=")) {
|
|
@@ -14470,7 +15475,7 @@ function parseIndexArgs(argv, cwd) {
|
|
|
14470
15475
|
if (!arg.startsWith("--config=")) {
|
|
14471
15476
|
i += 1;
|
|
14472
15477
|
}
|
|
14473
|
-
config =
|
|
15478
|
+
config = path33.resolve(cwd, value);
|
|
14474
15479
|
continue;
|
|
14475
15480
|
}
|
|
14476
15481
|
if (arg === "--host" || arg.startsWith("--host=")) {
|
|
@@ -14634,7 +15639,7 @@ function parseCbiCommandArgs(command, args, cwd) {
|
|
|
14634
15639
|
if (arg === "--help" || arg === "-h") throw new Error("help-requested");
|
|
14635
15640
|
if (arg === "--project" || arg.startsWith("--project=")) {
|
|
14636
15641
|
const parsed = optionValue(args, index, "project");
|
|
14637
|
-
project =
|
|
15642
|
+
project = path34.resolve(cwd, parsed.value);
|
|
14638
15643
|
index += parsed.consumed;
|
|
14639
15644
|
continue;
|
|
14640
15645
|
}
|
|
@@ -14646,7 +15651,7 @@ function parseCbiCommandArgs(command, args, cwd) {
|
|
|
14646
15651
|
}
|
|
14647
15652
|
if (arg === "--config" || arg.startsWith("--config=")) {
|
|
14648
15653
|
const parsed = optionValue(args, index, "config");
|
|
14649
|
-
config =
|
|
15654
|
+
config = path34.resolve(cwd, parsed.value);
|
|
14650
15655
|
index += parsed.consumed;
|
|
14651
15656
|
continue;
|
|
14652
15657
|
}
|
|
@@ -14659,7 +15664,7 @@ function parseCbiCommandArgs(command, args, cwd) {
|
|
|
14659
15664
|
}
|
|
14660
15665
|
if (command === "graph" && (arg === "--file" || arg.startsWith("--file="))) {
|
|
14661
15666
|
const parsed = optionValue(args, index, "file");
|
|
14662
|
-
filePath =
|
|
15667
|
+
filePath = path34.resolve(cwd, parsed.value);
|
|
14663
15668
|
index += parsed.consumed;
|
|
14664
15669
|
continue;
|
|
14665
15670
|
}
|
|
@@ -14758,7 +15763,7 @@ async function runCbiCli(argv, cwd, deps = {}) {
|
|
|
14758
15763
|
}
|
|
14759
15764
|
}
|
|
14760
15765
|
function isCbiEntrypoint(moduleUrl, argvPath) {
|
|
14761
|
-
return argvPath !== void 0 &&
|
|
15766
|
+
return argvPath !== void 0 && realpathSync8(fileURLToPath3(moduleUrl)) === realpathSync8(argvPath);
|
|
14762
15767
|
}
|
|
14763
15768
|
|
|
14764
15769
|
// src/cbi.ts
|