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/cli.cjs
CHANGED
|
@@ -496,7 +496,7 @@ var require_ignore = __commonJS({
|
|
|
496
496
|
// path matching.
|
|
497
497
|
// - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
|
|
498
498
|
// @returns {TestResult} true if a file is ignored
|
|
499
|
-
test(
|
|
499
|
+
test(path34, checkUnignored, mode) {
|
|
500
500
|
let ignored = false;
|
|
501
501
|
let unignored = false;
|
|
502
502
|
let matchedRule;
|
|
@@ -505,7 +505,7 @@ var require_ignore = __commonJS({
|
|
|
505
505
|
if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
|
|
506
506
|
return;
|
|
507
507
|
}
|
|
508
|
-
const matched = rule[mode].test(
|
|
508
|
+
const matched = rule[mode].test(path34);
|
|
509
509
|
if (!matched) {
|
|
510
510
|
return;
|
|
511
511
|
}
|
|
@@ -526,17 +526,17 @@ var require_ignore = __commonJS({
|
|
|
526
526
|
var throwError = (message, Ctor) => {
|
|
527
527
|
throw new Ctor(message);
|
|
528
528
|
};
|
|
529
|
-
var checkPath = (
|
|
530
|
-
if (!isString(
|
|
529
|
+
var checkPath = (path34, originalPath, doThrow) => {
|
|
530
|
+
if (!isString(path34)) {
|
|
531
531
|
return doThrow(
|
|
532
532
|
`path must be a string, but got \`${originalPath}\``,
|
|
533
533
|
TypeError
|
|
534
534
|
);
|
|
535
535
|
}
|
|
536
|
-
if (!
|
|
536
|
+
if (!path34) {
|
|
537
537
|
return doThrow(`path must not be empty`, TypeError);
|
|
538
538
|
}
|
|
539
|
-
if (checkPath.isNotRelative(
|
|
539
|
+
if (checkPath.isNotRelative(path34)) {
|
|
540
540
|
const r = "`path.relative()`d";
|
|
541
541
|
return doThrow(
|
|
542
542
|
`path should be a ${r} string, but got "${originalPath}"`,
|
|
@@ -545,7 +545,7 @@ var require_ignore = __commonJS({
|
|
|
545
545
|
}
|
|
546
546
|
return true;
|
|
547
547
|
};
|
|
548
|
-
var isNotRelative = (
|
|
548
|
+
var isNotRelative = (path34) => REGEX_TEST_INVALID_PATH.test(path34);
|
|
549
549
|
checkPath.isNotRelative = isNotRelative;
|
|
550
550
|
checkPath.convert = (p) => p;
|
|
551
551
|
var Ignore2 = class {
|
|
@@ -575,19 +575,19 @@ var require_ignore = __commonJS({
|
|
|
575
575
|
}
|
|
576
576
|
// @returns {TestResult}
|
|
577
577
|
_test(originalPath, cache, checkUnignored, slices) {
|
|
578
|
-
const
|
|
578
|
+
const path34 = originalPath && checkPath.convert(originalPath);
|
|
579
579
|
checkPath(
|
|
580
|
-
|
|
580
|
+
path34,
|
|
581
581
|
originalPath,
|
|
582
582
|
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
583
583
|
);
|
|
584
|
-
return this._t(
|
|
584
|
+
return this._t(path34, cache, checkUnignored, slices);
|
|
585
585
|
}
|
|
586
|
-
checkIgnore(
|
|
587
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
588
|
-
return this.test(
|
|
586
|
+
checkIgnore(path34) {
|
|
587
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path34)) {
|
|
588
|
+
return this.test(path34);
|
|
589
589
|
}
|
|
590
|
-
const slices =
|
|
590
|
+
const slices = path34.split(SLASH2).filter(Boolean);
|
|
591
591
|
slices.pop();
|
|
592
592
|
if (slices.length) {
|
|
593
593
|
const parent = this._t(
|
|
@@ -600,18 +600,18 @@ var require_ignore = __commonJS({
|
|
|
600
600
|
return parent;
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
|
-
return this._rules.test(
|
|
603
|
+
return this._rules.test(path34, false, MODE_CHECK_IGNORE);
|
|
604
604
|
}
|
|
605
|
-
_t(
|
|
606
|
-
if (
|
|
607
|
-
return cache[
|
|
605
|
+
_t(path34, cache, checkUnignored, slices) {
|
|
606
|
+
if (path34 in cache) {
|
|
607
|
+
return cache[path34];
|
|
608
608
|
}
|
|
609
609
|
if (!slices) {
|
|
610
|
-
slices =
|
|
610
|
+
slices = path34.split(SLASH2).filter(Boolean);
|
|
611
611
|
}
|
|
612
612
|
slices.pop();
|
|
613
613
|
if (!slices.length) {
|
|
614
|
-
return cache[
|
|
614
|
+
return cache[path34] = this._rules.test(path34, checkUnignored, MODE_IGNORE);
|
|
615
615
|
}
|
|
616
616
|
const parent = this._t(
|
|
617
617
|
slices.join(SLASH2) + SLASH2,
|
|
@@ -619,29 +619,29 @@ var require_ignore = __commonJS({
|
|
|
619
619
|
checkUnignored,
|
|
620
620
|
slices
|
|
621
621
|
);
|
|
622
|
-
return cache[
|
|
622
|
+
return cache[path34] = parent.ignored ? parent : this._rules.test(path34, checkUnignored, MODE_IGNORE);
|
|
623
623
|
}
|
|
624
|
-
ignores(
|
|
625
|
-
return this._test(
|
|
624
|
+
ignores(path34) {
|
|
625
|
+
return this._test(path34, this._ignoreCache, false).ignored;
|
|
626
626
|
}
|
|
627
627
|
createFilter() {
|
|
628
|
-
return (
|
|
628
|
+
return (path34) => !this.ignores(path34);
|
|
629
629
|
}
|
|
630
630
|
filter(paths) {
|
|
631
631
|
return makeArray(paths).filter(this.createFilter());
|
|
632
632
|
}
|
|
633
633
|
// @returns {TestResult}
|
|
634
|
-
test(
|
|
635
|
-
return this._test(
|
|
634
|
+
test(path34) {
|
|
635
|
+
return this._test(path34, this._testCache, true);
|
|
636
636
|
}
|
|
637
637
|
};
|
|
638
638
|
var factory = (options) => new Ignore2(options);
|
|
639
|
-
var isPathValid = (
|
|
639
|
+
var isPathValid = (path34) => checkPath(path34 && checkPath.convert(path34), path34, RETURN_FALSE);
|
|
640
640
|
var setupWindows = () => {
|
|
641
641
|
const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
|
|
642
642
|
checkPath.convert = makePosix;
|
|
643
643
|
const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
|
|
644
|
-
checkPath.isNotRelative = (
|
|
644
|
+
checkPath.isNotRelative = (path34) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path34) || isNotRelative(path34);
|
|
645
645
|
};
|
|
646
646
|
if (
|
|
647
647
|
// Detect `process` so that it can run in browsers.
|
|
@@ -668,8 +668,8 @@ module.exports = __toCommonJS(cli_exports);
|
|
|
668
668
|
// src/adapters/mcp/cli.ts
|
|
669
669
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
670
670
|
var import_fs20 = require("fs");
|
|
671
|
-
var
|
|
672
|
-
var
|
|
671
|
+
var os9 = __toESM(require("os"), 1);
|
|
672
|
+
var path33 = __toESM(require("path"), 1);
|
|
673
673
|
var import_url = require("url");
|
|
674
674
|
|
|
675
675
|
// src/config/constants.ts
|
|
@@ -1197,9 +1197,9 @@ var import_fs = require("fs");
|
|
|
1197
1197
|
var path = __toESM(require("path"), 1);
|
|
1198
1198
|
|
|
1199
1199
|
// src/eval/report-formatters.ts
|
|
1200
|
-
function assertFiniteNumber(value,
|
|
1200
|
+
function assertFiniteNumber(value, path34) {
|
|
1201
1201
|
if (typeof value !== "number" || Number.isNaN(value) || !Number.isFinite(value)) {
|
|
1202
|
-
throw new Error(`${
|
|
1202
|
+
throw new Error(`${path34} must be a finite number`);
|
|
1203
1203
|
}
|
|
1204
1204
|
return value;
|
|
1205
1205
|
}
|
|
@@ -1439,7 +1439,7 @@ function buildPerQueryArtifact(perQuery) {
|
|
|
1439
1439
|
// src/eval/runner.ts
|
|
1440
1440
|
var crypto2 = __toESM(require("crypto"), 1);
|
|
1441
1441
|
var import_fs17 = require("fs");
|
|
1442
|
-
var
|
|
1442
|
+
var path24 = __toESM(require("path"), 1);
|
|
1443
1443
|
var import_perf_hooks2 = require("perf_hooks");
|
|
1444
1444
|
|
|
1445
1445
|
// src/indexer/index.ts
|
|
@@ -1471,7 +1471,7 @@ function pTimeout(promise, options) {
|
|
|
1471
1471
|
} = options;
|
|
1472
1472
|
let timer;
|
|
1473
1473
|
let abortHandler;
|
|
1474
|
-
const wrappedPromise = new Promise((
|
|
1474
|
+
const wrappedPromise = new Promise((resolve21, reject) => {
|
|
1475
1475
|
if (typeof milliseconds !== "number" || Math.sign(milliseconds) !== 1) {
|
|
1476
1476
|
throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${milliseconds}\``);
|
|
1477
1477
|
}
|
|
@@ -1485,7 +1485,7 @@ function pTimeout(promise, options) {
|
|
|
1485
1485
|
};
|
|
1486
1486
|
signal.addEventListener("abort", abortHandler, { once: true });
|
|
1487
1487
|
}
|
|
1488
|
-
promise.then(
|
|
1488
|
+
promise.then(resolve21, reject);
|
|
1489
1489
|
if (milliseconds === Number.POSITIVE_INFINITY) {
|
|
1490
1490
|
return;
|
|
1491
1491
|
}
|
|
@@ -1493,7 +1493,7 @@ function pTimeout(promise, options) {
|
|
|
1493
1493
|
timer = customTimers.setTimeout.call(void 0, () => {
|
|
1494
1494
|
if (fallback) {
|
|
1495
1495
|
try {
|
|
1496
|
-
|
|
1496
|
+
resolve21(fallback());
|
|
1497
1497
|
} catch (error) {
|
|
1498
1498
|
reject(error);
|
|
1499
1499
|
}
|
|
@@ -1503,7 +1503,7 @@ function pTimeout(promise, options) {
|
|
|
1503
1503
|
promise.cancel();
|
|
1504
1504
|
}
|
|
1505
1505
|
if (message === false) {
|
|
1506
|
-
|
|
1506
|
+
resolve21();
|
|
1507
1507
|
} else if (message instanceof Error) {
|
|
1508
1508
|
reject(message);
|
|
1509
1509
|
} else {
|
|
@@ -1905,7 +1905,7 @@ var PQueue = class extends import_index.default {
|
|
|
1905
1905
|
// Assign unique ID if not provided
|
|
1906
1906
|
id: options.id ?? (this.#idAssigner++).toString()
|
|
1907
1907
|
};
|
|
1908
|
-
return new Promise((
|
|
1908
|
+
return new Promise((resolve21, reject) => {
|
|
1909
1909
|
const taskSymbol = /* @__PURE__ */ Symbol(`task-${options.id}`);
|
|
1910
1910
|
let cleanupQueueAbortHandler = () => void 0;
|
|
1911
1911
|
const run = async () => {
|
|
@@ -1945,7 +1945,7 @@ var PQueue = class extends import_index.default {
|
|
|
1945
1945
|
})]);
|
|
1946
1946
|
}
|
|
1947
1947
|
const result = await operation;
|
|
1948
|
-
|
|
1948
|
+
resolve21(result);
|
|
1949
1949
|
this.emit("completed", result);
|
|
1950
1950
|
} catch (error) {
|
|
1951
1951
|
reject(error);
|
|
@@ -2133,13 +2133,13 @@ var PQueue = class extends import_index.default {
|
|
|
2133
2133
|
});
|
|
2134
2134
|
}
|
|
2135
2135
|
async #onEvent(event, filter) {
|
|
2136
|
-
return new Promise((
|
|
2136
|
+
return new Promise((resolve21) => {
|
|
2137
2137
|
const listener = () => {
|
|
2138
2138
|
if (filter && !filter()) {
|
|
2139
2139
|
return;
|
|
2140
2140
|
}
|
|
2141
2141
|
this.off(event, listener);
|
|
2142
|
-
|
|
2142
|
+
resolve21();
|
|
2143
2143
|
};
|
|
2144
2144
|
this.on(event, listener);
|
|
2145
2145
|
});
|
|
@@ -2425,7 +2425,7 @@ async function onAttemptFailure({ error, attemptNumber, retriesConsumed, startTi
|
|
|
2425
2425
|
const finalDelay = Math.min(delayTime, remainingTime);
|
|
2426
2426
|
options.signal?.throwIfAborted();
|
|
2427
2427
|
if (finalDelay > 0) {
|
|
2428
|
-
await new Promise((
|
|
2428
|
+
await new Promise((resolve21, reject) => {
|
|
2429
2429
|
const onAbort = () => {
|
|
2430
2430
|
clearTimeout(timeoutToken);
|
|
2431
2431
|
options.signal?.removeEventListener("abort", onAbort);
|
|
@@ -2433,7 +2433,7 @@ async function onAttemptFailure({ error, attemptNumber, retriesConsumed, startTi
|
|
|
2433
2433
|
};
|
|
2434
2434
|
const timeoutToken = setTimeout(() => {
|
|
2435
2435
|
options.signal?.removeEventListener("abort", onAbort);
|
|
2436
|
-
|
|
2436
|
+
resolve21();
|
|
2437
2437
|
}, finalDelay);
|
|
2438
2438
|
if (options.unref) {
|
|
2439
2439
|
timeoutToken.unref?.();
|
|
@@ -2795,17 +2795,17 @@ function validateExternalUrl(urlString) {
|
|
|
2795
2795
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
2796
2796
|
return { valid: false, reason: `Blocked protocol: ${parsed.protocol}` };
|
|
2797
2797
|
}
|
|
2798
|
-
const
|
|
2799
|
-
if (BLOCKED_HOSTNAMES.has(
|
|
2800
|
-
return { valid: false, reason: `Blocked: cloud metadata service (${
|
|
2798
|
+
const hostname3 = parsed.hostname.toLowerCase();
|
|
2799
|
+
if (BLOCKED_HOSTNAMES.has(hostname3)) {
|
|
2800
|
+
return { valid: false, reason: `Blocked: cloud metadata service (${hostname3})` };
|
|
2801
2801
|
}
|
|
2802
2802
|
for (const pattern of BLOCKED_METADATA_IPS) {
|
|
2803
|
-
if (pattern.test(
|
|
2804
|
-
return { valid: false, reason: `Blocked: cloud metadata IP (${
|
|
2803
|
+
if (pattern.test(hostname3)) {
|
|
2804
|
+
return { valid: false, reason: `Blocked: cloud metadata IP (${hostname3})` };
|
|
2805
2805
|
}
|
|
2806
2806
|
}
|
|
2807
|
-
if (/^169\.254\./.test(
|
|
2808
|
-
return { valid: false, reason: `Blocked: link-local address (${
|
|
2807
|
+
if (/^169\.254\./.test(hostname3)) {
|
|
2808
|
+
return { valid: false, reason: `Blocked: link-local address (${hostname3})` };
|
|
2809
2809
|
}
|
|
2810
2810
|
return { valid: true };
|
|
2811
2811
|
}
|
|
@@ -3391,26 +3391,46 @@ function createIgnoreFilter(projectRoot) {
|
|
|
3391
3391
|
}
|
|
3392
3392
|
return ig;
|
|
3393
3393
|
}
|
|
3394
|
-
function
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3394
|
+
function toPosixRelativePath(relativePath) {
|
|
3395
|
+
return relativePath.split(path4.sep).join("/");
|
|
3396
|
+
}
|
|
3397
|
+
function matchesAnyGlob(filePath, patterns) {
|
|
3398
|
+
const normalized = toPosixRelativePath(filePath);
|
|
3399
|
+
return patterns.some((pattern) => matchGlob(normalized, pattern));
|
|
3400
|
+
}
|
|
3401
|
+
function isExcludedByPatterns(relativePath, excludePatterns) {
|
|
3402
|
+
return matchesAnyGlob(relativePath, excludePatterns);
|
|
3403
|
+
}
|
|
3404
|
+
function isExcludedDirectory(relativePath, excludePatterns) {
|
|
3405
|
+
const normalized = toPosixRelativePath(relativePath);
|
|
3406
|
+
if (matchesAnyGlob(normalized, excludePatterns)) {
|
|
3407
|
+
return true;
|
|
3401
3408
|
}
|
|
3402
3409
|
for (const pattern of excludePatterns) {
|
|
3403
|
-
|
|
3404
|
-
|
|
3410
|
+
const posixPattern = toPosixRelativePath(pattern).replace(/\/+$/, "");
|
|
3411
|
+
if (!posixPattern.endsWith("/**")) {
|
|
3412
|
+
continue;
|
|
3405
3413
|
}
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
if (matchGlob(relativePath, pattern)) {
|
|
3414
|
+
const directoryPattern = posixPattern.slice(0, -3);
|
|
3415
|
+
if (directoryPattern && matchesAnyGlob(normalized, [directoryPattern])) {
|
|
3409
3416
|
return true;
|
|
3410
3417
|
}
|
|
3411
3418
|
}
|
|
3412
3419
|
return false;
|
|
3413
3420
|
}
|
|
3421
|
+
function shouldIncludeFile(filePath, projectRoot, includePatterns, excludePatterns, ignoreFilter) {
|
|
3422
|
+
const relativePath = toPosixRelativePath(path4.relative(projectRoot, filePath));
|
|
3423
|
+
if (hasFilteredPathSegment(relativePath, "/")) {
|
|
3424
|
+
return false;
|
|
3425
|
+
}
|
|
3426
|
+
if (ignoreFilter.ignores(relativePath)) {
|
|
3427
|
+
return false;
|
|
3428
|
+
}
|
|
3429
|
+
if (isExcludedByPatterns(relativePath, excludePatterns)) {
|
|
3430
|
+
return false;
|
|
3431
|
+
}
|
|
3432
|
+
return matchesAnyGlob(relativePath, includePatterns);
|
|
3433
|
+
}
|
|
3414
3434
|
function matchGlob(filePath, pattern) {
|
|
3415
3435
|
if (pattern.startsWith("**/")) {
|
|
3416
3436
|
const withoutPrefix = pattern.slice(3);
|
|
@@ -3432,7 +3452,7 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
|
|
|
3432
3452
|
const subdirs = [];
|
|
3433
3453
|
for (const entry of entries) {
|
|
3434
3454
|
const fullPath = path4.join(dir, entry.name);
|
|
3435
|
-
const relativePath = path4.relative(projectRoot, fullPath);
|
|
3455
|
+
const relativePath = toPosixRelativePath(path4.relative(projectRoot, fullPath));
|
|
3436
3456
|
if (isHiddenPathSegment(entry.name)) {
|
|
3437
3457
|
if (entry.isDirectory()) {
|
|
3438
3458
|
skipped.push({ path: relativePath, reason: "excluded" });
|
|
@@ -3450,6 +3470,10 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
|
|
|
3450
3470
|
continue;
|
|
3451
3471
|
}
|
|
3452
3472
|
if (entry.isDirectory()) {
|
|
3473
|
+
if (isExcludedDirectory(relativePath, excludePatterns)) {
|
|
3474
|
+
skipped.push({ path: relativePath, reason: "excluded" });
|
|
3475
|
+
continue;
|
|
3476
|
+
}
|
|
3453
3477
|
subdirs.push({ fullPath, relativePath });
|
|
3454
3478
|
} else if (entry.isFile()) {
|
|
3455
3479
|
const stat5 = await import_fs3.promises.stat(fullPath);
|
|
@@ -3457,20 +3481,11 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
|
|
|
3457
3481
|
skipped.push({ path: relativePath, reason: "too_large" });
|
|
3458
3482
|
continue;
|
|
3459
3483
|
}
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
continue;
|
|
3464
|
-
}
|
|
3465
|
-
}
|
|
3466
|
-
let matched = false;
|
|
3467
|
-
for (const pattern of includePatterns) {
|
|
3468
|
-
if (matchGlob(relativePath, pattern)) {
|
|
3469
|
-
matched = true;
|
|
3470
|
-
break;
|
|
3471
|
-
}
|
|
3484
|
+
if (isExcludedByPatterns(relativePath, excludePatterns)) {
|
|
3485
|
+
skipped.push({ path: relativePath, reason: "excluded" });
|
|
3486
|
+
continue;
|
|
3472
3487
|
}
|
|
3473
|
-
if (
|
|
3488
|
+
if (matchesAnyGlob(relativePath, includePatterns)) {
|
|
3474
3489
|
filesInDir.push({ path: fullPath, size: stat5.size });
|
|
3475
3490
|
}
|
|
3476
3491
|
}
|
|
@@ -3481,7 +3496,7 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
|
|
|
3481
3496
|
yield f;
|
|
3482
3497
|
}
|
|
3483
3498
|
for (let i = options.maxFilesPerDirectory; i < filesInDir.length; i++) {
|
|
3484
|
-
skipped.push({ path: path4.relative(projectRoot, filesInDir[i].path), reason: "excluded" });
|
|
3499
|
+
skipped.push({ path: toPosixRelativePath(path4.relative(projectRoot, filesInDir[i].path)), reason: "excluded" });
|
|
3485
3500
|
}
|
|
3486
3501
|
const canRecurse = options.maxDepth === -1 || currentDepth < options.maxDepth;
|
|
3487
3502
|
if (canRecurse) {
|
|
@@ -7102,8 +7117,8 @@ function pathSegmentsForAffinityMatch(filePath) {
|
|
|
7102
7117
|
if (segments.length === 0) {
|
|
7103
7118
|
return [];
|
|
7104
7119
|
}
|
|
7105
|
-
const
|
|
7106
|
-
const basenameWithoutExt =
|
|
7120
|
+
const basename9 = segments[segments.length - 1] ?? "";
|
|
7121
|
+
const basenameWithoutExt = basename9.replace(/\.[^/.]+$/u, "");
|
|
7107
7122
|
const normalizedSegments = segments.map((segment) => segment.toLowerCase());
|
|
7108
7123
|
return Array.from(/* @__PURE__ */ new Set([
|
|
7109
7124
|
...normalizedSegments,
|
|
@@ -7516,7 +7531,7 @@ function removeDeadReclaimMarker(lockPath, expectedOwner) {
|
|
|
7516
7531
|
return true;
|
|
7517
7532
|
}
|
|
7518
7533
|
function reclaimDeadOwner(indexPath, lockPath, expectedOwner) {
|
|
7519
|
-
const
|
|
7534
|
+
const reclaimPath2 = path13.join(lockPath, RECLAIM_DIRECTORY_NAME);
|
|
7520
7535
|
const reclaimOwner = {
|
|
7521
7536
|
pid: process.pid,
|
|
7522
7537
|
hostname: os5.hostname(),
|
|
@@ -7525,19 +7540,19 @@ function reclaimDeadOwner(indexPath, lockPath, expectedOwner) {
|
|
|
7525
7540
|
expectedOwnerToken: expectedOwner.token
|
|
7526
7541
|
};
|
|
7527
7542
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
7528
|
-
if (publishJsonDirectory(
|
|
7543
|
+
if (publishJsonDirectory(reclaimPath2, reclaimOwner)) break;
|
|
7529
7544
|
if (attempt === 0 && removeDeadReclaimMarker(lockPath, expectedOwner)) continue;
|
|
7530
7545
|
return false;
|
|
7531
7546
|
}
|
|
7532
7547
|
try {
|
|
7533
|
-
const currentReclaimer = readReclaimOwner(
|
|
7548
|
+
const currentReclaimer = readReclaimOwner(reclaimPath2);
|
|
7534
7549
|
const currentOwner = readDirectoryOwner(lockPath);
|
|
7535
7550
|
if (!currentReclaimer || !sameReclaimOwner(currentReclaimer, reclaimOwner) || !currentOwner || !sameOwner(currentOwner, expectedOwner) || getOwnerLiveness(currentOwner) !== "dead") {
|
|
7536
7551
|
return false;
|
|
7537
7552
|
}
|
|
7538
7553
|
publishRecoveryMarker(indexPath, expectedOwner);
|
|
7539
7554
|
const ownerBeforeQuarantine = readDirectoryOwner(lockPath);
|
|
7540
|
-
const reclaimerBeforeQuarantine = readReclaimOwner(
|
|
7555
|
+
const reclaimerBeforeQuarantine = readReclaimOwner(reclaimPath2);
|
|
7541
7556
|
if (!ownerBeforeQuarantine || !sameOwner(ownerBeforeQuarantine, expectedOwner) || getOwnerLiveness(ownerBeforeQuarantine) !== "dead" || !reclaimerBeforeQuarantine || !sameReclaimOwner(reclaimerBeforeQuarantine, reclaimOwner)) {
|
|
7542
7557
|
return false;
|
|
7543
7558
|
}
|
|
@@ -8753,6 +8768,17 @@ var Indexer = class _Indexer {
|
|
|
8753
8768
|
}
|
|
8754
8769
|
return path15.relative(this.projectRoot, canonicalFilePath).split(path15.sep).join("/");
|
|
8755
8770
|
}
|
|
8771
|
+
isStoredPathExcluded(storedPath) {
|
|
8772
|
+
let matchPath = storedPath.split(path15.sep).join("/");
|
|
8773
|
+
if (path15.isAbsolute(storedPath)) {
|
|
8774
|
+
const relativePath = path15.relative(this.projectRoot, storedPath).split(path15.sep).join("/");
|
|
8775
|
+
if (relativePath.startsWith("..") || path15.isAbsolute(relativePath)) {
|
|
8776
|
+
return false;
|
|
8777
|
+
}
|
|
8778
|
+
matchPath = relativePath;
|
|
8779
|
+
}
|
|
8780
|
+
return isExcludedByPatterns(matchPath, this.config.exclude);
|
|
8781
|
+
}
|
|
8756
8782
|
resolveStoredFilePath(filePath, rootPath = this.projectRoot) {
|
|
8757
8783
|
if (path15.isAbsolute(filePath)) {
|
|
8758
8784
|
return filePath;
|
|
@@ -9777,7 +9803,7 @@ var Indexer = class _Indexer {
|
|
|
9777
9803
|
await options.queue.onSizeLessThan(Math.max(1, options.providerRateLimits.concurrency));
|
|
9778
9804
|
const task = options.queue.add(async () => {
|
|
9779
9805
|
if (options.rateLimitState.backoffMs > 0) {
|
|
9780
|
-
await new Promise((
|
|
9806
|
+
await new Promise((resolve21) => setTimeout(resolve21, options.rateLimitState.backoffMs));
|
|
9781
9807
|
}
|
|
9782
9808
|
try {
|
|
9783
9809
|
const embeddingResult = await pRetry(
|
|
@@ -11154,7 +11180,7 @@ var Indexer = class _Indexer {
|
|
|
11154
11180
|
}
|
|
11155
11181
|
}
|
|
11156
11182
|
}
|
|
11157
|
-
const shouldRetryFailedPath = (filePath) => filePath !== null && currentFileHashes.has(filePath) && unchangedFilePaths.has(filePath);
|
|
11183
|
+
const shouldRetryFailedPath = (filePath) => filePath !== null && !this.isStoredPathExcluded(filePath) && currentFileHashes.has(filePath) && unchangedFilePaths.has(filePath);
|
|
11158
11184
|
const failedProcessing = this.prepareFailedBatchProcessing(scopedRoots, shouldRetryFailedPath);
|
|
11159
11185
|
const maxChunkTokens = getSafeEmbeddingChunkTokenLimit(configuredProviderInfo);
|
|
11160
11186
|
const providerRateLimits = this.getProviderRateLimits(configuredProviderInfo.provider);
|
|
@@ -12482,7 +12508,8 @@ var Indexer = class _Indexer {
|
|
|
12482
12508
|
const maxChunkTokens = getSafeEmbeddingChunkTokenLimit(configuredProviderInfo);
|
|
12483
12509
|
const providerRateLimits = this.getProviderRateLimits(configuredProviderInfo.provider);
|
|
12484
12510
|
const roots = this.config.scope === "global" ? this.getScopedRoots() : null;
|
|
12485
|
-
const
|
|
12511
|
+
const shouldProcessFailedPath = (filePath) => filePath === null || !this.isStoredPathExcluded(filePath);
|
|
12512
|
+
const failedProcessing = this.prepareFailedBatchProcessing(roots, shouldProcessFailedPath);
|
|
12486
12513
|
if (failedProcessing.latestById.size === 0) {
|
|
12487
12514
|
this.finalizeFailedBatchWriteState(failedProcessing.state);
|
|
12488
12515
|
return { succeeded: 0, failed: 0, remaining: 0 };
|
|
@@ -12495,7 +12522,7 @@ var Indexer = class _Indexer {
|
|
|
12495
12522
|
const retryableChunks = this.iterateLatestFailedChunks(
|
|
12496
12523
|
failedProcessing.latestById,
|
|
12497
12524
|
roots,
|
|
12498
|
-
|
|
12525
|
+
shouldProcessFailedPath,
|
|
12499
12526
|
maxChunkTokens
|
|
12500
12527
|
);
|
|
12501
12528
|
for (const retryBatch of iterateOrderedFileBatches(
|
|
@@ -12765,9 +12792,9 @@ var Indexer = class _Indexer {
|
|
|
12765
12792
|
this.requireReadableComponents(readIssues, "database");
|
|
12766
12793
|
let shortest = [];
|
|
12767
12794
|
for (const branchKey of this.getBranchCatalogKeys()) {
|
|
12768
|
-
const
|
|
12769
|
-
if (
|
|
12770
|
-
shortest =
|
|
12795
|
+
const path34 = database.findShortestPath(fromName, toName, branchKey, maxDepth);
|
|
12796
|
+
if (path34.length > 0 && (shortest.length === 0 || path34.length < shortest.length)) {
|
|
12797
|
+
shortest = path34;
|
|
12771
12798
|
}
|
|
12772
12799
|
}
|
|
12773
12800
|
return shortest.map((hop) => this.resolveFilePathRecord(hop));
|
|
@@ -12815,13 +12842,13 @@ var Indexer = class _Indexer {
|
|
|
12815
12842
|
}
|
|
12816
12843
|
}
|
|
12817
12844
|
if (!found) continue;
|
|
12818
|
-
const
|
|
12845
|
+
const path34 = [];
|
|
12819
12846
|
let currentSymbolId = toSymbolId;
|
|
12820
12847
|
while (true) {
|
|
12821
12848
|
const symbol = symbolsById.get(currentSymbolId);
|
|
12822
12849
|
if (!symbol) break;
|
|
12823
12850
|
const parent = parentBySymbolId.get(currentSymbolId);
|
|
12824
|
-
|
|
12851
|
+
path34.push({
|
|
12825
12852
|
symbolId: symbol.id,
|
|
12826
12853
|
symbolName: symbol.name,
|
|
12827
12854
|
filePath: symbol.filePath,
|
|
@@ -12831,9 +12858,9 @@ var Indexer = class _Indexer {
|
|
|
12831
12858
|
if (!parent) break;
|
|
12832
12859
|
currentSymbolId = parent.parentId;
|
|
12833
12860
|
}
|
|
12834
|
-
|
|
12835
|
-
if (
|
|
12836
|
-
shortest =
|
|
12861
|
+
path34.reverse();
|
|
12862
|
+
if (path34.length > 0 && (shortest.length === 0 || path34.length < shortest.length)) {
|
|
12863
|
+
shortest = path34;
|
|
12837
12864
|
}
|
|
12838
12865
|
}
|
|
12839
12866
|
return shortest.map((hop) => this.resolveFilePathRecord(hop));
|
|
@@ -13217,7 +13244,7 @@ var CODE_COMMUNITIES_MAX_COUPLING_LIMIT = 100;
|
|
|
13217
13244
|
|
|
13218
13245
|
// src/tools/operations.ts
|
|
13219
13246
|
var import_fs14 = require("fs");
|
|
13220
|
-
var
|
|
13247
|
+
var path22 = __toESM(require("path"), 1);
|
|
13221
13248
|
|
|
13222
13249
|
// src/tools/knowledge-base-paths.ts
|
|
13223
13250
|
var path16 = __toESM(require("path"), 1);
|
|
@@ -13512,8 +13539,8 @@ function formatExactSearchHandoff(results) {
|
|
|
13512
13539
|
}
|
|
13513
13540
|
function formatContextEvidence(result, index) {
|
|
13514
13541
|
const symbol = result.name ? ` ${JSON.stringify(compactEvidenceValue(result.name, 80))}` : "";
|
|
13515
|
-
const
|
|
13516
|
-
return `[${index}] ${result.chunkType}${symbol} in ${
|
|
13542
|
+
const path34 = compactEvidenceValue(result.filePath, 120);
|
|
13543
|
+
return `[${index}] ${result.chunkType}${symbol} in ${path34}:${result.startLine}-${result.endLine} (score ${result.score.toFixed(2)})`;
|
|
13517
13544
|
}
|
|
13518
13545
|
function formatContextPack(heading, selected, candidateCount, duplicateCount, limitOmittedCount, budgetOmittedCount, includeExactSearchHandoff) {
|
|
13519
13546
|
const lines = selected.map((result, index) => formatContextEvidence(result, index + 1));
|
|
@@ -14156,8 +14183,897 @@ function formatEffectivenessMetrics(snapshot) {
|
|
|
14156
14183
|
|
|
14157
14184
|
// src/utils/auto-index.ts
|
|
14158
14185
|
var import_fs11 = require("fs");
|
|
14186
|
+
var os7 = __toESM(require("os"), 1);
|
|
14187
|
+
var path18 = __toESM(require("path"), 1);
|
|
14188
|
+
|
|
14189
|
+
// src/utils/background-worker.ts
|
|
14190
|
+
var import_node_crypto2 = require("crypto");
|
|
14191
|
+
var import_node_fs = require("fs");
|
|
14159
14192
|
var os6 = __toESM(require("os"), 1);
|
|
14160
14193
|
var path17 = __toESM(require("path"), 1);
|
|
14194
|
+
var OWNER_FILE_NAME2 = "owner.json";
|
|
14195
|
+
var HEARTBEAT_FILE_PREFIX = "heartbeat.";
|
|
14196
|
+
var RECLAIM_DIRECTORY_NAME2 = "reclaim";
|
|
14197
|
+
var REFRESH_REQUEST_FILE_NAME = "refresh-request.json";
|
|
14198
|
+
var HEARTBEAT_INTERVAL_MS = 5e3;
|
|
14199
|
+
var STALE_LEASE_MS = 3e4;
|
|
14200
|
+
var RETRY_DELAY_MS = 5e3;
|
|
14201
|
+
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;
|
|
14202
|
+
var BackgroundWorkerStopError = class extends Error {
|
|
14203
|
+
constructor(watcherError, autoIndexError) {
|
|
14204
|
+
super("Failed to stop background worker");
|
|
14205
|
+
this.watcherError = watcherError;
|
|
14206
|
+
this.autoIndexError = autoIndexError;
|
|
14207
|
+
this.name = "BackgroundWorkerStopError";
|
|
14208
|
+
}
|
|
14209
|
+
watcherError;
|
|
14210
|
+
autoIndexError;
|
|
14211
|
+
};
|
|
14212
|
+
var workers = /* @__PURE__ */ new Map();
|
|
14213
|
+
var workerKeysByProject = /* @__PURE__ */ new Map();
|
|
14214
|
+
var workerReplacementBarriers = /* @__PURE__ */ new Map();
|
|
14215
|
+
function getErrorCode2(error) {
|
|
14216
|
+
return typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
|
|
14217
|
+
}
|
|
14218
|
+
function canonicalizePath(targetPath) {
|
|
14219
|
+
const resolved = path17.resolve(targetPath);
|
|
14220
|
+
if ((0, import_node_fs.existsSync)(resolved)) {
|
|
14221
|
+
try {
|
|
14222
|
+
return import_node_fs.realpathSync.native(resolved);
|
|
14223
|
+
} catch {
|
|
14224
|
+
return resolved;
|
|
14225
|
+
}
|
|
14226
|
+
}
|
|
14227
|
+
const parent = path17.dirname(resolved);
|
|
14228
|
+
if (parent === resolved) return resolved;
|
|
14229
|
+
return path17.join(canonicalizePath(parent), path17.basename(resolved));
|
|
14230
|
+
}
|
|
14231
|
+
function projectLookupKey(projectRoot, host) {
|
|
14232
|
+
return `${host}::${canonicalizePath(projectRoot)}`;
|
|
14233
|
+
}
|
|
14234
|
+
function getBackgroundWorkerProjectKey(projectRoot, host) {
|
|
14235
|
+
return projectLookupKey(projectRoot, host);
|
|
14236
|
+
}
|
|
14237
|
+
function resolveIdentity(projectRoot, config, host) {
|
|
14238
|
+
const canonicalProjectRoot = canonicalizePath(projectRoot);
|
|
14239
|
+
const canonicalIndexPath = canonicalizePath(resolveProjectIndexPath(projectRoot, config.scope, host));
|
|
14240
|
+
return {
|
|
14241
|
+
canonicalIndexPath,
|
|
14242
|
+
canonicalProjectRoot,
|
|
14243
|
+
key: `${canonicalIndexPath}::${canonicalProjectRoot}`
|
|
14244
|
+
};
|
|
14245
|
+
}
|
|
14246
|
+
function controllerKey(identity, host) {
|
|
14247
|
+
return `${identity.key}::${host}`;
|
|
14248
|
+
}
|
|
14249
|
+
function leaseDirectoryName(identity) {
|
|
14250
|
+
const hash = (0, import_node_crypto2.createHash)("sha256").update(identity.key).digest("hex").slice(0, 32);
|
|
14251
|
+
return `background-worker.${hash}.lease`;
|
|
14252
|
+
}
|
|
14253
|
+
function leasePathFor(identity) {
|
|
14254
|
+
return path17.join(identity.canonicalIndexPath, leaseDirectoryName(identity));
|
|
14255
|
+
}
|
|
14256
|
+
function parseOwner2(value) {
|
|
14257
|
+
if (typeof value !== "object" || value === null) return null;
|
|
14258
|
+
const candidate = value;
|
|
14259
|
+
if (candidate.version !== 1) return null;
|
|
14260
|
+
if (!Number.isInteger(candidate.pid) || (candidate.pid ?? 0) <= 0) return null;
|
|
14261
|
+
if (typeof candidate.hostname !== "string" || candidate.hostname.length === 0) return null;
|
|
14262
|
+
if (typeof candidate.startedAt !== "string" || Number.isNaN(Date.parse(candidate.startedAt))) return null;
|
|
14263
|
+
if (typeof candidate.heartbeatAt !== "string" || Number.isNaN(Date.parse(candidate.heartbeatAt))) return null;
|
|
14264
|
+
if (typeof candidate.projectRoot !== "string" || candidate.projectRoot.length === 0) return null;
|
|
14265
|
+
if (typeof candidate.indexPath !== "string" || candidate.indexPath.length === 0) return null;
|
|
14266
|
+
if (typeof candidate.token !== "string" || !UUID_PATTERN2.test(candidate.token)) return null;
|
|
14267
|
+
return candidate;
|
|
14268
|
+
}
|
|
14269
|
+
function parseHeartbeat(value, expectedToken) {
|
|
14270
|
+
if (typeof value !== "object" || value === null) return null;
|
|
14271
|
+
const candidate = value;
|
|
14272
|
+
if (candidate.version !== 1 || candidate.token !== expectedToken) return null;
|
|
14273
|
+
if (typeof candidate.heartbeatAt !== "string" || Number.isNaN(Date.parse(candidate.heartbeatAt))) return null;
|
|
14274
|
+
return candidate;
|
|
14275
|
+
}
|
|
14276
|
+
function parseReclaimOwner2(value) {
|
|
14277
|
+
if (typeof value !== "object" || value === null) return null;
|
|
14278
|
+
const candidate = value;
|
|
14279
|
+
if (candidate.version !== 1) return null;
|
|
14280
|
+
if (!Number.isInteger(candidate.pid) || (candidate.pid ?? 0) <= 0) return null;
|
|
14281
|
+
if (typeof candidate.hostname !== "string" || candidate.hostname.length === 0) return null;
|
|
14282
|
+
if (typeof candidate.startedAt !== "string" || Number.isNaN(Date.parse(candidate.startedAt))) return null;
|
|
14283
|
+
if (typeof candidate.token !== "string" || !UUID_PATTERN2.test(candidate.token)) return null;
|
|
14284
|
+
if (candidate.expectedOwnerToken !== null && (typeof candidate.expectedOwnerToken !== "string" || !UUID_PATTERN2.test(candidate.expectedOwnerToken))) return null;
|
|
14285
|
+
return candidate;
|
|
14286
|
+
}
|
|
14287
|
+
function heartbeatPath(leasePath, token) {
|
|
14288
|
+
return path17.join(leasePath, `${HEARTBEAT_FILE_PREFIX}${token}.json`);
|
|
14289
|
+
}
|
|
14290
|
+
function reclaimPath(leasePath) {
|
|
14291
|
+
return path17.join(leasePath, RECLAIM_DIRECTORY_NAME2);
|
|
14292
|
+
}
|
|
14293
|
+
function refreshRequestPath(leasePath) {
|
|
14294
|
+
return path17.join(leasePath, REFRESH_REQUEST_FILE_NAME);
|
|
14295
|
+
}
|
|
14296
|
+
function readLeaseOwner(leasePath) {
|
|
14297
|
+
try {
|
|
14298
|
+
return parseOwner2(JSON.parse((0, import_node_fs.readFileSync)(path17.join(leasePath, OWNER_FILE_NAME2), "utf-8")));
|
|
14299
|
+
} catch {
|
|
14300
|
+
return null;
|
|
14301
|
+
}
|
|
14302
|
+
}
|
|
14303
|
+
function readOwner(leasePath) {
|
|
14304
|
+
const owner = readLeaseOwner(leasePath);
|
|
14305
|
+
if (!owner) return null;
|
|
14306
|
+
try {
|
|
14307
|
+
const heartbeat = parseHeartbeat(
|
|
14308
|
+
JSON.parse((0, import_node_fs.readFileSync)(heartbeatPath(leasePath, owner.token), "utf-8")),
|
|
14309
|
+
owner.token
|
|
14310
|
+
);
|
|
14311
|
+
return heartbeat ? { ...owner, heartbeatAt: heartbeat.heartbeatAt } : owner;
|
|
14312
|
+
} catch {
|
|
14313
|
+
return owner;
|
|
14314
|
+
}
|
|
14315
|
+
}
|
|
14316
|
+
function readReclaimOwner2(leasePath) {
|
|
14317
|
+
try {
|
|
14318
|
+
return parseReclaimOwner2(JSON.parse((0, import_node_fs.readFileSync)(path17.join(reclaimPath(leasePath), OWNER_FILE_NAME2), "utf-8")));
|
|
14319
|
+
} catch {
|
|
14320
|
+
return null;
|
|
14321
|
+
}
|
|
14322
|
+
}
|
|
14323
|
+
function ownerLiveness(owner) {
|
|
14324
|
+
if (owner.hostname !== os6.hostname()) return "unknown";
|
|
14325
|
+
try {
|
|
14326
|
+
process.kill(owner.pid, 0);
|
|
14327
|
+
return "alive";
|
|
14328
|
+
} catch (error) {
|
|
14329
|
+
const code = getErrorCode2(error);
|
|
14330
|
+
if (code === "ESRCH") return "dead";
|
|
14331
|
+
if (code === "EPERM") return "alive";
|
|
14332
|
+
return "unknown";
|
|
14333
|
+
}
|
|
14334
|
+
}
|
|
14335
|
+
function isHeartbeatExpired(owner) {
|
|
14336
|
+
return Date.now() - Date.parse(owner.heartbeatAt) >= STALE_LEASE_MS;
|
|
14337
|
+
}
|
|
14338
|
+
function sameOwner2(left, right) {
|
|
14339
|
+
return left.pid === right.pid && left.hostname === right.hostname && left.token === right.token;
|
|
14340
|
+
}
|
|
14341
|
+
function writeHeartbeat(leasePath, owner) {
|
|
14342
|
+
const targetPath = heartbeatPath(leasePath, owner.token);
|
|
14343
|
+
const temporaryPath = `${targetPath}.tmp.${process.pid}.${owner.token}.${(0, import_node_crypto2.randomUUID)()}`;
|
|
14344
|
+
const heartbeat = {
|
|
14345
|
+
version: 1,
|
|
14346
|
+
token: owner.token,
|
|
14347
|
+
heartbeatAt: owner.heartbeatAt
|
|
14348
|
+
};
|
|
14349
|
+
try {
|
|
14350
|
+
(0, import_node_fs.writeFileSync)(temporaryPath, JSON.stringify(heartbeat), {
|
|
14351
|
+
encoding: "utf-8",
|
|
14352
|
+
flag: "wx",
|
|
14353
|
+
mode: 384
|
|
14354
|
+
});
|
|
14355
|
+
(0, import_node_fs.renameSync)(temporaryPath, targetPath);
|
|
14356
|
+
const currentOwner = readLeaseOwner(leasePath);
|
|
14357
|
+
return currentOwner !== null && sameOwner2(currentOwner, owner);
|
|
14358
|
+
} finally {
|
|
14359
|
+
if ((0, import_node_fs.existsSync)(temporaryPath)) (0, import_node_fs.rmSync)(temporaryPath, { force: true });
|
|
14360
|
+
}
|
|
14361
|
+
}
|
|
14362
|
+
function requestRefreshFromLeader(leasePath, allowDisabledAutoIndex) {
|
|
14363
|
+
const requestPath = refreshRequestPath(leasePath);
|
|
14364
|
+
const temporaryPath = `${requestPath}.tmp.${process.pid}.${(0, import_node_crypto2.randomUUID)()}`;
|
|
14365
|
+
try {
|
|
14366
|
+
const request = {
|
|
14367
|
+
allowDisabledAutoIndex,
|
|
14368
|
+
requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14369
|
+
version: 1
|
|
14370
|
+
};
|
|
14371
|
+
(0, import_node_fs.writeFileSync)(temporaryPath, JSON.stringify(request), {
|
|
14372
|
+
encoding: "utf-8",
|
|
14373
|
+
flag: "wx",
|
|
14374
|
+
mode: 384
|
|
14375
|
+
});
|
|
14376
|
+
(0, import_node_fs.renameSync)(temporaryPath, requestPath);
|
|
14377
|
+
} catch (error) {
|
|
14378
|
+
if (getErrorCode2(error) !== "ENOENT") {
|
|
14379
|
+
console.error("[codebase-index] Failed to request background index refresh from the project worker:", error);
|
|
14380
|
+
}
|
|
14381
|
+
} finally {
|
|
14382
|
+
if ((0, import_node_fs.existsSync)(temporaryPath)) (0, import_node_fs.rmSync)(temporaryPath, { force: true });
|
|
14383
|
+
}
|
|
14384
|
+
}
|
|
14385
|
+
function consumeRefreshRequest(leasePath) {
|
|
14386
|
+
const requestPath = refreshRequestPath(leasePath);
|
|
14387
|
+
const claimedPath = `${requestPath}.handling.${process.pid}.${(0, import_node_crypto2.randomUUID)()}`;
|
|
14388
|
+
try {
|
|
14389
|
+
(0, import_node_fs.renameSync)(requestPath, claimedPath);
|
|
14390
|
+
} catch (error) {
|
|
14391
|
+
if (getErrorCode2(error) === "ENOENT") return null;
|
|
14392
|
+
throw error;
|
|
14393
|
+
}
|
|
14394
|
+
try {
|
|
14395
|
+
const value = JSON.parse((0, import_node_fs.readFileSync)(claimedPath, "utf-8"));
|
|
14396
|
+
return {
|
|
14397
|
+
allowDisabledAutoIndex: value.version === 1 && value.allowDisabledAutoIndex === true,
|
|
14398
|
+
requestedAt: typeof value.requestedAt === "string" ? value.requestedAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
14399
|
+
version: 1
|
|
14400
|
+
};
|
|
14401
|
+
} catch {
|
|
14402
|
+
return { allowDisabledAutoIndex: false, requestedAt: (/* @__PURE__ */ new Date()).toISOString(), version: 1 };
|
|
14403
|
+
} finally {
|
|
14404
|
+
(0, import_node_fs.rmSync)(claimedPath, { force: true });
|
|
14405
|
+
}
|
|
14406
|
+
}
|
|
14407
|
+
function publishLease(leasePath, owner) {
|
|
14408
|
+
const candidatePath = `${leasePath}.candidate.${process.pid}.${owner.token}`;
|
|
14409
|
+
try {
|
|
14410
|
+
(0, import_node_fs.mkdirSync)(candidatePath, { mode: 448 });
|
|
14411
|
+
} catch (error) {
|
|
14412
|
+
if (getErrorCode2(error) === "ENOENT") return false;
|
|
14413
|
+
throw error;
|
|
14414
|
+
}
|
|
14415
|
+
try {
|
|
14416
|
+
(0, import_node_fs.writeFileSync)(path17.join(candidatePath, OWNER_FILE_NAME2), JSON.stringify(owner), {
|
|
14417
|
+
encoding: "utf-8",
|
|
14418
|
+
flag: "wx",
|
|
14419
|
+
mode: 384
|
|
14420
|
+
});
|
|
14421
|
+
if ((0, import_node_fs.existsSync)(leasePath)) return false;
|
|
14422
|
+
try {
|
|
14423
|
+
(0, import_node_fs.renameSync)(candidatePath, leasePath);
|
|
14424
|
+
return true;
|
|
14425
|
+
} catch (error) {
|
|
14426
|
+
if ((0, import_node_fs.existsSync)(leasePath) || getErrorCode2(error) === "ENOENT") return false;
|
|
14427
|
+
throw error;
|
|
14428
|
+
}
|
|
14429
|
+
} finally {
|
|
14430
|
+
if ((0, import_node_fs.existsSync)(candidatePath)) (0, import_node_fs.rmSync)(candidatePath, { recursive: true, force: true });
|
|
14431
|
+
}
|
|
14432
|
+
}
|
|
14433
|
+
function sameReclaimOwner2(left, right) {
|
|
14434
|
+
return left.pid === right.pid && left.hostname === right.hostname && left.token === right.token && left.expectedOwnerToken === right.expectedOwnerToken;
|
|
14435
|
+
}
|
|
14436
|
+
function reclaimerLiveness(owner) {
|
|
14437
|
+
return ownerLiveness(owner);
|
|
14438
|
+
}
|
|
14439
|
+
function isReclaimMarkerExpired(leasePath, owner) {
|
|
14440
|
+
const startedAt = owner ? Date.parse(owner.startedAt) : (() => {
|
|
14441
|
+
try {
|
|
14442
|
+
return (0, import_node_fs.lstatSync)(reclaimPath(leasePath)).mtimeMs;
|
|
14443
|
+
} catch {
|
|
14444
|
+
return Date.now();
|
|
14445
|
+
}
|
|
14446
|
+
})();
|
|
14447
|
+
return Date.now() - startedAt >= STALE_LEASE_MS;
|
|
14448
|
+
}
|
|
14449
|
+
function hasActiveReclaimMarker(leasePath, owner) {
|
|
14450
|
+
const marker = readReclaimOwner2(leasePath);
|
|
14451
|
+
return marker !== null && marker.expectedOwnerToken === owner.token && (marker.hostname !== os6.hostname() || ownerLiveness(owner) !== "alive");
|
|
14452
|
+
}
|
|
14453
|
+
function publishReclaimMarker(leasePath, expectedOwner) {
|
|
14454
|
+
const markerPath = reclaimPath(leasePath);
|
|
14455
|
+
const owner = {
|
|
14456
|
+
version: 1,
|
|
14457
|
+
pid: process.pid,
|
|
14458
|
+
hostname: os6.hostname(),
|
|
14459
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14460
|
+
token: (0, import_node_crypto2.randomUUID)(),
|
|
14461
|
+
expectedOwnerToken: expectedOwner?.token ?? null
|
|
14462
|
+
};
|
|
14463
|
+
try {
|
|
14464
|
+
(0, import_node_fs.mkdirSync)(markerPath, { mode: 448 });
|
|
14465
|
+
} catch (error) {
|
|
14466
|
+
if (getErrorCode2(error) === "EEXIST" || getErrorCode2(error) === "ENOENT") return null;
|
|
14467
|
+
throw error;
|
|
14468
|
+
}
|
|
14469
|
+
try {
|
|
14470
|
+
(0, import_node_fs.writeFileSync)(path17.join(markerPath, OWNER_FILE_NAME2), JSON.stringify(owner), {
|
|
14471
|
+
encoding: "utf-8",
|
|
14472
|
+
flag: "wx",
|
|
14473
|
+
mode: 384
|
|
14474
|
+
});
|
|
14475
|
+
return owner;
|
|
14476
|
+
} catch (error) {
|
|
14477
|
+
(0, import_node_fs.rmSync)(markerPath, { recursive: true, force: true });
|
|
14478
|
+
throw error;
|
|
14479
|
+
}
|
|
14480
|
+
}
|
|
14481
|
+
function removeExpiredReclaimMarker(leasePath, expectedOwner) {
|
|
14482
|
+
const marker = readReclaimOwner2(leasePath);
|
|
14483
|
+
const markerPath = reclaimPath(leasePath);
|
|
14484
|
+
if (!(0, import_node_fs.existsSync)(markerPath)) return false;
|
|
14485
|
+
if (marker && marker.expectedOwnerToken !== (expectedOwner?.token ?? null)) return false;
|
|
14486
|
+
if (marker && (reclaimerLiveness(marker) === "alive" || !isReclaimMarkerExpired(leasePath, marker))) return false;
|
|
14487
|
+
if (!marker && !isReclaimMarkerExpired(leasePath, null)) return false;
|
|
14488
|
+
const staleMarkerPath = `${markerPath}.stale.${marker?.pid ?? process.pid}.${marker?.token ?? (0, import_node_crypto2.randomUUID)()}.${(0, import_node_crypto2.randomUUID)()}`;
|
|
14489
|
+
try {
|
|
14490
|
+
(0, import_node_fs.renameSync)(markerPath, staleMarkerPath);
|
|
14491
|
+
} catch (error) {
|
|
14492
|
+
if (getErrorCode2(error) === "ENOENT") return false;
|
|
14493
|
+
throw error;
|
|
14494
|
+
}
|
|
14495
|
+
try {
|
|
14496
|
+
let claimedMarker = null;
|
|
14497
|
+
try {
|
|
14498
|
+
claimedMarker = parseReclaimOwner2(
|
|
14499
|
+
JSON.parse((0, import_node_fs.readFileSync)(path17.join(staleMarkerPath, OWNER_FILE_NAME2), "utf-8"))
|
|
14500
|
+
);
|
|
14501
|
+
} catch {
|
|
14502
|
+
claimedMarker = null;
|
|
14503
|
+
}
|
|
14504
|
+
const markerMatches = marker ? claimedMarker !== null && sameReclaimOwner2(claimedMarker, marker) : claimedMarker === null;
|
|
14505
|
+
if (!markerMatches || !canReclaimLease(leasePath, expectedOwner)) {
|
|
14506
|
+
if (!(0, import_node_fs.existsSync)(markerPath) && (0, import_node_fs.existsSync)(staleMarkerPath)) (0, import_node_fs.renameSync)(staleMarkerPath, markerPath);
|
|
14507
|
+
return false;
|
|
14508
|
+
}
|
|
14509
|
+
(0, import_node_fs.rmSync)(staleMarkerPath, { recursive: true, force: true });
|
|
14510
|
+
return true;
|
|
14511
|
+
} catch (error) {
|
|
14512
|
+
if (getErrorCode2(error) === "ENOENT") return false;
|
|
14513
|
+
throw error;
|
|
14514
|
+
}
|
|
14515
|
+
}
|
|
14516
|
+
function canReclaimLease(leasePath, expectedOwner) {
|
|
14517
|
+
if (!(0, import_node_fs.existsSync)(leasePath)) return false;
|
|
14518
|
+
if (!expectedOwner) return false;
|
|
14519
|
+
const currentOwner = readOwner(leasePath);
|
|
14520
|
+
if (!currentOwner || !sameOwner2(currentOwner, expectedOwner)) return false;
|
|
14521
|
+
if (currentOwner.hostname === os6.hostname()) {
|
|
14522
|
+
return ownerLiveness(currentOwner) === "dead";
|
|
14523
|
+
}
|
|
14524
|
+
return isHeartbeatExpired(currentOwner);
|
|
14525
|
+
}
|
|
14526
|
+
function reclaimLease(leasePath, expectedOwner) {
|
|
14527
|
+
let marker = null;
|
|
14528
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
14529
|
+
marker = publishReclaimMarker(leasePath, expectedOwner);
|
|
14530
|
+
if (marker) break;
|
|
14531
|
+
if (attempt === 0 && removeExpiredReclaimMarker(leasePath, expectedOwner)) continue;
|
|
14532
|
+
return false;
|
|
14533
|
+
}
|
|
14534
|
+
if (!marker) return false;
|
|
14535
|
+
const markerPath = reclaimPath(leasePath);
|
|
14536
|
+
try {
|
|
14537
|
+
const currentMarker = readReclaimOwner2(leasePath);
|
|
14538
|
+
if (!currentMarker || !sameReclaimOwner2(currentMarker, marker) || !canReclaimLease(leasePath, expectedOwner)) {
|
|
14539
|
+
return false;
|
|
14540
|
+
}
|
|
14541
|
+
const stalePath = `${leasePath}.stale.${process.pid}.${marker.token}`;
|
|
14542
|
+
(0, import_node_fs.renameSync)(leasePath, stalePath);
|
|
14543
|
+
const quarantinedOwner = readOwner(stalePath);
|
|
14544
|
+
const quarantinedMarker = readReclaimOwner2(stalePath);
|
|
14545
|
+
if (!quarantinedMarker || !sameReclaimOwner2(quarantinedMarker, marker) || expectedOwner !== null && (!quarantinedOwner || !sameOwner2(quarantinedOwner, expectedOwner))) {
|
|
14546
|
+
if (!(0, import_node_fs.existsSync)(leasePath) && (0, import_node_fs.existsSync)(stalePath)) (0, import_node_fs.renameSync)(stalePath, leasePath);
|
|
14547
|
+
return false;
|
|
14548
|
+
}
|
|
14549
|
+
(0, import_node_fs.rmSync)(stalePath, { recursive: true, force: true });
|
|
14550
|
+
return true;
|
|
14551
|
+
} catch (error) {
|
|
14552
|
+
if (getErrorCode2(error) === "ENOENT") return false;
|
|
14553
|
+
throw error;
|
|
14554
|
+
} finally {
|
|
14555
|
+
const currentMarker = readReclaimOwner2(leasePath);
|
|
14556
|
+
if (currentMarker && sameReclaimOwner2(currentMarker, marker)) {
|
|
14557
|
+
(0, import_node_fs.rmSync)(markerPath, { recursive: true, force: true });
|
|
14558
|
+
}
|
|
14559
|
+
}
|
|
14560
|
+
}
|
|
14561
|
+
function acquireLease(identity) {
|
|
14562
|
+
(0, import_node_fs.mkdirSync)(identity.canonicalIndexPath, { recursive: true, mode: 448 });
|
|
14563
|
+
const canonicalIndexPath = import_node_fs.realpathSync.native(identity.canonicalIndexPath);
|
|
14564
|
+
const leasePath = path17.join(canonicalIndexPath, leaseDirectoryName({ ...identity, canonicalIndexPath }));
|
|
14565
|
+
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
14566
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
14567
|
+
const owner = {
|
|
14568
|
+
version: 1,
|
|
14569
|
+
pid: process.pid,
|
|
14570
|
+
hostname: os6.hostname(),
|
|
14571
|
+
startedAt: timestamp,
|
|
14572
|
+
heartbeatAt: timestamp,
|
|
14573
|
+
projectRoot: identity.canonicalProjectRoot,
|
|
14574
|
+
indexPath: canonicalIndexPath,
|
|
14575
|
+
token: (0, import_node_crypto2.randomUUID)()
|
|
14576
|
+
};
|
|
14577
|
+
if (publishLease(leasePath, owner)) {
|
|
14578
|
+
return { leasePath, owner };
|
|
14579
|
+
}
|
|
14580
|
+
const existingOwner = readOwner(leasePath);
|
|
14581
|
+
if (existingOwner) {
|
|
14582
|
+
if (canReclaimLease(leasePath, existingOwner) && reclaimLease(leasePath, existingOwner)) continue;
|
|
14583
|
+
return null;
|
|
14584
|
+
}
|
|
14585
|
+
return null;
|
|
14586
|
+
}
|
|
14587
|
+
return null;
|
|
14588
|
+
}
|
|
14589
|
+
function releaseLease(lease) {
|
|
14590
|
+
const currentOwner = readOwner(lease.leasePath);
|
|
14591
|
+
if (!currentOwner || !sameOwner2(currentOwner, lease.owner)) return false;
|
|
14592
|
+
const releasePath = `${lease.leasePath}.release.${lease.owner.pid}.${lease.owner.token}`;
|
|
14593
|
+
try {
|
|
14594
|
+
(0, import_node_fs.renameSync)(lease.leasePath, releasePath);
|
|
14595
|
+
} catch (error) {
|
|
14596
|
+
if (getErrorCode2(error) === "ENOENT") return false;
|
|
14597
|
+
throw error;
|
|
14598
|
+
}
|
|
14599
|
+
const claimedOwner = readOwner(releasePath);
|
|
14600
|
+
if (!claimedOwner || !sameOwner2(claimedOwner, lease.owner)) {
|
|
14601
|
+
if (!(0, import_node_fs.existsSync)(lease.leasePath) && (0, import_node_fs.existsSync)(releasePath)) {
|
|
14602
|
+
(0, import_node_fs.renameSync)(releasePath, lease.leasePath);
|
|
14603
|
+
}
|
|
14604
|
+
return false;
|
|
14605
|
+
}
|
|
14606
|
+
(0, import_node_fs.rmSync)(releasePath, { recursive: true, force: true });
|
|
14607
|
+
return true;
|
|
14608
|
+
}
|
|
14609
|
+
var BackgroundWorkerController = class {
|
|
14610
|
+
constructor(projectRoot, host, config, hooks, identity) {
|
|
14611
|
+
this.projectRoot = projectRoot;
|
|
14612
|
+
this.host = host;
|
|
14613
|
+
this.config = config;
|
|
14614
|
+
this.hooks = hooks;
|
|
14615
|
+
this.identity = identity;
|
|
14616
|
+
}
|
|
14617
|
+
projectRoot;
|
|
14618
|
+
host;
|
|
14619
|
+
config;
|
|
14620
|
+
hooks;
|
|
14621
|
+
identity;
|
|
14622
|
+
lease = null;
|
|
14623
|
+
watcher = null;
|
|
14624
|
+
leaderReady = Promise.resolve();
|
|
14625
|
+
heartbeatTimer = null;
|
|
14626
|
+
retryTimer = null;
|
|
14627
|
+
teardownRetryTimer = null;
|
|
14628
|
+
transition = Promise.resolve();
|
|
14629
|
+
stopPromise = null;
|
|
14630
|
+
stopped = false;
|
|
14631
|
+
stopping = false;
|
|
14632
|
+
losingLeadership = false;
|
|
14633
|
+
restartAfterStop = false;
|
|
14634
|
+
leaderWorkStopped = false;
|
|
14635
|
+
startingLeaderWork = false;
|
|
14636
|
+
stopAutoIndexOnTeardown = true;
|
|
14637
|
+
autoIndexStarted = false;
|
|
14638
|
+
reportedError = null;
|
|
14639
|
+
update(config, hooks, options) {
|
|
14640
|
+
const autoIndexWasEnabled = this.config.indexing.autoIndex;
|
|
14641
|
+
const shouldReplaceWatcher = this.watcher !== null && hooks.watcherFactory !== void 0 && (hooks.watcherFactory === null || hooks.replaceWatcher === true);
|
|
14642
|
+
this.config = config;
|
|
14643
|
+
this.hooks = {
|
|
14644
|
+
...this.hooks,
|
|
14645
|
+
...hooks,
|
|
14646
|
+
watcherFactory: hooks.watcherFactory === void 0 ? this.hooks.watcherFactory : hooks.watcherFactory,
|
|
14647
|
+
watcherFactoryForConfig: hooks.watcherFactoryForConfig === void 0 ? this.hooks.watcherFactoryForConfig : hooks.watcherFactoryForConfig
|
|
14648
|
+
};
|
|
14649
|
+
if (autoIndexWasEnabled && !config.indexing.autoIndex || options.restartAutoIndex === true && config.indexing.autoIndex && !this.startingLeaderWork) {
|
|
14650
|
+
this.autoIndexStarted = false;
|
|
14651
|
+
}
|
|
14652
|
+
if (!this.canRun()) {
|
|
14653
|
+
void this.stop().catch((error) => {
|
|
14654
|
+
console.error("[codebase-index] Failed to stop background worker after disabling automatic work:", error);
|
|
14655
|
+
});
|
|
14656
|
+
return;
|
|
14657
|
+
}
|
|
14658
|
+
if (shouldReplaceWatcher) {
|
|
14659
|
+
void this.enqueue(async () => {
|
|
14660
|
+
const watcher = this.watcher;
|
|
14661
|
+
if (watcher) {
|
|
14662
|
+
await watcher.stop();
|
|
14663
|
+
if (this.watcher === watcher) this.watcher = null;
|
|
14664
|
+
}
|
|
14665
|
+
if (this.lease && !this.stopped) this.startLeaderWork();
|
|
14666
|
+
}).catch((error) => {
|
|
14667
|
+
console.error("[codebase-index] Failed to replace background file watcher:", error);
|
|
14668
|
+
});
|
|
14669
|
+
}
|
|
14670
|
+
this.start();
|
|
14671
|
+
}
|
|
14672
|
+
startAfter(activation) {
|
|
14673
|
+
this.transition = activation.catch(() => void 0);
|
|
14674
|
+
this.start();
|
|
14675
|
+
}
|
|
14676
|
+
start() {
|
|
14677
|
+
if (!this.canRun() || this.losingLeadership) return;
|
|
14678
|
+
if (this.stopping) {
|
|
14679
|
+
this.restartAfterStop = true;
|
|
14680
|
+
return;
|
|
14681
|
+
}
|
|
14682
|
+
this.stopped = false;
|
|
14683
|
+
void this.enqueue(async () => {
|
|
14684
|
+
if (this.stopped || this.stopping || this.losingLeadership || !this.canRun()) return;
|
|
14685
|
+
if (!this.lease) {
|
|
14686
|
+
try {
|
|
14687
|
+
this.lease = acquireLease(this.identity);
|
|
14688
|
+
this.reportedError = null;
|
|
14689
|
+
} catch (error) {
|
|
14690
|
+
this.reportAcquireError(error);
|
|
14691
|
+
this.scheduleRetry();
|
|
14692
|
+
return;
|
|
14693
|
+
}
|
|
14694
|
+
}
|
|
14695
|
+
if (!this.lease) {
|
|
14696
|
+
this.scheduleRetry();
|
|
14697
|
+
return;
|
|
14698
|
+
}
|
|
14699
|
+
this.startHeartbeat();
|
|
14700
|
+
this.startLeaderWork();
|
|
14701
|
+
});
|
|
14702
|
+
}
|
|
14703
|
+
waitForStart() {
|
|
14704
|
+
return this.transition.catch(() => void 0).then(() => this.leaderReady);
|
|
14705
|
+
}
|
|
14706
|
+
requestRefresh(allowDisabledAutoIndex = false) {
|
|
14707
|
+
this.start();
|
|
14708
|
+
if (!this.isLeader()) {
|
|
14709
|
+
requestRefreshFromLeader(leasePathFor(this.identity), allowDisabledAutoIndex);
|
|
14710
|
+
return;
|
|
14711
|
+
}
|
|
14712
|
+
void this.enqueue(async () => {
|
|
14713
|
+
if (this.stopped || !this.lease) return;
|
|
14714
|
+
this.hooks.startAutoIndex("retrieval", allowDisabledAutoIndex);
|
|
14715
|
+
});
|
|
14716
|
+
}
|
|
14717
|
+
isLeader() {
|
|
14718
|
+
return this.lease !== null && !this.stopping && !this.losingLeadership;
|
|
14719
|
+
}
|
|
14720
|
+
isStopping() {
|
|
14721
|
+
return this.stopping;
|
|
14722
|
+
}
|
|
14723
|
+
getHooksForConfig(config) {
|
|
14724
|
+
const watcherFactoryForConfig = this.hooks.watcherFactoryForConfig;
|
|
14725
|
+
if (!watcherFactoryForConfig) return this.hooks;
|
|
14726
|
+
return {
|
|
14727
|
+
...this.hooks,
|
|
14728
|
+
watcherFactory: watcherFactoryForConfig(config),
|
|
14729
|
+
replaceWatcher: true
|
|
14730
|
+
};
|
|
14731
|
+
}
|
|
14732
|
+
attachWatcher(watcherFactory, watcherFactoryForConfig) {
|
|
14733
|
+
if (this.hooks.watcherFactory !== void 0) return;
|
|
14734
|
+
this.hooks = {
|
|
14735
|
+
...this.hooks,
|
|
14736
|
+
watcherFactory,
|
|
14737
|
+
watcherFactoryForConfig: watcherFactoryForConfig ?? this.hooks.watcherFactoryForConfig
|
|
14738
|
+
};
|
|
14739
|
+
this.start();
|
|
14740
|
+
}
|
|
14741
|
+
async stop(stopAutoIndex = true) {
|
|
14742
|
+
if (this.stopPromise) return this.stopPromise;
|
|
14743
|
+
this.stopped = true;
|
|
14744
|
+
this.stopping = true;
|
|
14745
|
+
this.stopAutoIndexOnTeardown &&= stopAutoIndex;
|
|
14746
|
+
this.clearRetryTimer();
|
|
14747
|
+
const attempt = this.enqueue(async () => {
|
|
14748
|
+
try {
|
|
14749
|
+
const lease = this.lease;
|
|
14750
|
+
if (this.leaderWorkStopped) {
|
|
14751
|
+
if (lease) {
|
|
14752
|
+
this.releaseStoppedLease(lease);
|
|
14753
|
+
} else {
|
|
14754
|
+
this.finishStoppedLease();
|
|
14755
|
+
}
|
|
14756
|
+
return;
|
|
14757
|
+
}
|
|
14758
|
+
const hadLeaderWork = lease !== null || this.watcher !== null || this.autoIndexStarted;
|
|
14759
|
+
const stopped = await this.stopLeaderWork(hadLeaderWork && this.stopAutoIndexOnTeardown);
|
|
14760
|
+
if (!lease) {
|
|
14761
|
+
this.finishStoppedLease();
|
|
14762
|
+
return;
|
|
14763
|
+
}
|
|
14764
|
+
if (!stopped.completed) {
|
|
14765
|
+
this.releaseLeaseWhenAutoIndexStops(lease, stopped.completion);
|
|
14766
|
+
return;
|
|
14767
|
+
}
|
|
14768
|
+
this.leaderWorkStopped = true;
|
|
14769
|
+
this.releaseStoppedLease(lease);
|
|
14770
|
+
} catch (error) {
|
|
14771
|
+
this.scheduleTeardownRetry();
|
|
14772
|
+
throw error;
|
|
14773
|
+
}
|
|
14774
|
+
});
|
|
14775
|
+
const completion = attempt.finally(() => {
|
|
14776
|
+
if (this.stopPromise === completion) this.stopPromise = null;
|
|
14777
|
+
});
|
|
14778
|
+
this.stopPromise = completion;
|
|
14779
|
+
return completion;
|
|
14780
|
+
}
|
|
14781
|
+
canRun() {
|
|
14782
|
+
return this.config.indexing.autoIndex || this.hooks.watcherFactory != null;
|
|
14783
|
+
}
|
|
14784
|
+
enqueue(operation) {
|
|
14785
|
+
const next = this.transition.catch(() => void 0).then(operation);
|
|
14786
|
+
this.transition = next;
|
|
14787
|
+
return next;
|
|
14788
|
+
}
|
|
14789
|
+
startLeaderWork() {
|
|
14790
|
+
if (this.stopped || this.stopping || this.losingLeadership) return;
|
|
14791
|
+
this.startingLeaderWork = true;
|
|
14792
|
+
try {
|
|
14793
|
+
if (this.config.indexing.autoIndex && !this.autoIndexStarted) {
|
|
14794
|
+
this.autoIndexStarted = true;
|
|
14795
|
+
this.hooks.startAutoIndex("startup");
|
|
14796
|
+
}
|
|
14797
|
+
if (!this.watcher && this.hooks.watcherFactory) {
|
|
14798
|
+
try {
|
|
14799
|
+
const watcher = this.hooks.watcherFactory();
|
|
14800
|
+
this.watcher = watcher;
|
|
14801
|
+
this.leaderReady = watcher.whenReady?.().catch((error) => {
|
|
14802
|
+
console.error("[codebase-index] Failed while waiting for background file watcher startup:", error);
|
|
14803
|
+
}) ?? Promise.resolve();
|
|
14804
|
+
} catch (error) {
|
|
14805
|
+
console.error("[codebase-index] Failed to start background file watcher:", error);
|
|
14806
|
+
this.leaderReady = Promise.resolve();
|
|
14807
|
+
}
|
|
14808
|
+
}
|
|
14809
|
+
} finally {
|
|
14810
|
+
this.startingLeaderWork = false;
|
|
14811
|
+
}
|
|
14812
|
+
}
|
|
14813
|
+
async stopLeaderWork(stopAutoIndex) {
|
|
14814
|
+
const watcher = this.watcher;
|
|
14815
|
+
let watcherError;
|
|
14816
|
+
if (watcher) {
|
|
14817
|
+
try {
|
|
14818
|
+
await watcher.stop();
|
|
14819
|
+
if (this.watcher === watcher) this.watcher = null;
|
|
14820
|
+
} catch (error) {
|
|
14821
|
+
watcherError = error;
|
|
14822
|
+
}
|
|
14823
|
+
}
|
|
14824
|
+
let autoIndexError;
|
|
14825
|
+
let autoIndexStop = {
|
|
14826
|
+
completed: true,
|
|
14827
|
+
completion: Promise.resolve()
|
|
14828
|
+
};
|
|
14829
|
+
if (stopAutoIndex) {
|
|
14830
|
+
try {
|
|
14831
|
+
autoIndexStop = await this.hooks.stopAutoIndex();
|
|
14832
|
+
this.autoIndexStarted = false;
|
|
14833
|
+
} catch (error) {
|
|
14834
|
+
autoIndexError = error;
|
|
14835
|
+
}
|
|
14836
|
+
}
|
|
14837
|
+
if (watcherError !== void 0 || autoIndexError !== void 0) {
|
|
14838
|
+
throw new BackgroundWorkerStopError(watcherError, autoIndexError);
|
|
14839
|
+
}
|
|
14840
|
+
return autoIndexStop;
|
|
14841
|
+
}
|
|
14842
|
+
releaseLeaseWhenAutoIndexStops(lease, completion) {
|
|
14843
|
+
void completion.then(
|
|
14844
|
+
() => {
|
|
14845
|
+
void this.enqueue(async () => {
|
|
14846
|
+
if (this.lease !== lease || !this.stopping) return;
|
|
14847
|
+
this.leaderWorkStopped = true;
|
|
14848
|
+
this.releaseStoppedLease(lease);
|
|
14849
|
+
}).catch((error) => {
|
|
14850
|
+
console.error("[codebase-index] Failed to release background worker lease after automatic indexing stopped:", error);
|
|
14851
|
+
this.scheduleTeardownRetry();
|
|
14852
|
+
});
|
|
14853
|
+
},
|
|
14854
|
+
(error) => {
|
|
14855
|
+
console.error("[codebase-index] Failed while waiting for automatic indexing to stop:", error);
|
|
14856
|
+
this.scheduleTeardownRetry();
|
|
14857
|
+
}
|
|
14858
|
+
);
|
|
14859
|
+
}
|
|
14860
|
+
releaseStoppedLease(lease) {
|
|
14861
|
+
if (this.lease !== lease) {
|
|
14862
|
+
this.finishStoppedLease();
|
|
14863
|
+
return;
|
|
14864
|
+
}
|
|
14865
|
+
releaseLease(lease);
|
|
14866
|
+
this.lease = null;
|
|
14867
|
+
this.finishStoppedLease();
|
|
14868
|
+
}
|
|
14869
|
+
finishStoppedLease() {
|
|
14870
|
+
this.leaderWorkStopped = false;
|
|
14871
|
+
this.stopAutoIndexOnTeardown = true;
|
|
14872
|
+
this.stopping = false;
|
|
14873
|
+
this.clearTimers();
|
|
14874
|
+
this.restartAfterTeardown();
|
|
14875
|
+
if (!this.stopped || this.stopping) return;
|
|
14876
|
+
const projectKey = projectLookupKey(this.projectRoot, this.host);
|
|
14877
|
+
const key = controllerKey(this.identity, this.host);
|
|
14878
|
+
if (workers.get(key) === this) workers.delete(key);
|
|
14879
|
+
if (workerKeysByProject.get(projectKey) === key) workerKeysByProject.delete(projectKey);
|
|
14880
|
+
}
|
|
14881
|
+
startHeartbeat() {
|
|
14882
|
+
if (this.heartbeatTimer) return;
|
|
14883
|
+
const heartbeat = () => {
|
|
14884
|
+
void this.heartbeat();
|
|
14885
|
+
};
|
|
14886
|
+
this.heartbeatTimer = setInterval(heartbeat, HEARTBEAT_INTERVAL_MS);
|
|
14887
|
+
this.heartbeatTimer.unref?.();
|
|
14888
|
+
}
|
|
14889
|
+
async heartbeat() {
|
|
14890
|
+
const lease = this.lease;
|
|
14891
|
+
if (!lease || this.losingLeadership || this.stopped && !this.stopping) return;
|
|
14892
|
+
if (hasActiveReclaimMarker(lease.leasePath, lease.owner)) {
|
|
14893
|
+
await this.loseLeadership();
|
|
14894
|
+
return;
|
|
14895
|
+
}
|
|
14896
|
+
const currentOwner = readOwner(lease.leasePath);
|
|
14897
|
+
if (!currentOwner || !sameOwner2(currentOwner, lease.owner)) {
|
|
14898
|
+
await this.loseLeadership();
|
|
14899
|
+
return;
|
|
14900
|
+
}
|
|
14901
|
+
try {
|
|
14902
|
+
const nextOwner = { ...lease.owner, heartbeatAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
14903
|
+
if (!writeHeartbeat(lease.leasePath, nextOwner)) {
|
|
14904
|
+
await this.loseLeadership();
|
|
14905
|
+
return;
|
|
14906
|
+
}
|
|
14907
|
+
lease.owner = nextOwner;
|
|
14908
|
+
const refreshRequest = !this.stopping ? consumeRefreshRequest(lease.leasePath) : null;
|
|
14909
|
+
if (refreshRequest) {
|
|
14910
|
+
this.hooks.startAutoIndex("retrieval", refreshRequest.allowDisabledAutoIndex);
|
|
14911
|
+
}
|
|
14912
|
+
} catch (error) {
|
|
14913
|
+
const ownerAfterError = readOwner(lease.leasePath);
|
|
14914
|
+
if (hasActiveReclaimMarker(lease.leasePath, lease.owner) || !ownerAfterError || !sameOwner2(ownerAfterError, lease.owner)) {
|
|
14915
|
+
await this.loseLeadership();
|
|
14916
|
+
return;
|
|
14917
|
+
}
|
|
14918
|
+
console.error("[codebase-index] Failed to renew background worker lease:", error);
|
|
14919
|
+
}
|
|
14920
|
+
}
|
|
14921
|
+
async loseLeadership() {
|
|
14922
|
+
if (this.losingLeadership) return;
|
|
14923
|
+
this.losingLeadership = true;
|
|
14924
|
+
this.clearHeartbeat();
|
|
14925
|
+
await this.enqueue(async () => this.stopAfterLeadershipLoss());
|
|
14926
|
+
}
|
|
14927
|
+
async stopAfterLeadershipLoss() {
|
|
14928
|
+
const lease = this.lease;
|
|
14929
|
+
if (!lease) {
|
|
14930
|
+
this.losingLeadership = false;
|
|
14931
|
+
return;
|
|
14932
|
+
}
|
|
14933
|
+
try {
|
|
14934
|
+
const stopped = await this.stopLeaderWork(true);
|
|
14935
|
+
this.lease = null;
|
|
14936
|
+
this.losingLeadership = false;
|
|
14937
|
+
if (stopped.completed) {
|
|
14938
|
+
this.scheduleRetry();
|
|
14939
|
+
} else {
|
|
14940
|
+
void stopped.completion.then(() => this.scheduleRetry());
|
|
14941
|
+
}
|
|
14942
|
+
} catch (error) {
|
|
14943
|
+
console.error("[codebase-index] Failed to stop background work after losing its lease:", error);
|
|
14944
|
+
this.scheduleLostLeadershipTeardownRetry();
|
|
14945
|
+
}
|
|
14946
|
+
}
|
|
14947
|
+
scheduleRetry() {
|
|
14948
|
+
if (this.stopped || !this.canRun() || this.retryTimer) return;
|
|
14949
|
+
this.retryTimer = setTimeout(() => {
|
|
14950
|
+
this.retryTimer = null;
|
|
14951
|
+
this.start();
|
|
14952
|
+
}, RETRY_DELAY_MS);
|
|
14953
|
+
this.retryTimer.unref?.();
|
|
14954
|
+
}
|
|
14955
|
+
scheduleTeardownRetry() {
|
|
14956
|
+
if (!this.stopping || this.teardownRetryTimer) return;
|
|
14957
|
+
this.teardownRetryTimer = setTimeout(() => {
|
|
14958
|
+
this.teardownRetryTimer = null;
|
|
14959
|
+
void this.stop(this.stopAutoIndexOnTeardown).catch((error) => {
|
|
14960
|
+
console.error("[codebase-index] Failed to retry background worker teardown:", error);
|
|
14961
|
+
});
|
|
14962
|
+
}, RETRY_DELAY_MS);
|
|
14963
|
+
this.teardownRetryTimer.unref?.();
|
|
14964
|
+
}
|
|
14965
|
+
restartAfterTeardown() {
|
|
14966
|
+
if (!this.restartAfterStop || !this.canRun() || this.losingLeadership) return;
|
|
14967
|
+
this.restartAfterStop = false;
|
|
14968
|
+
this.stopped = false;
|
|
14969
|
+
this.start();
|
|
14970
|
+
}
|
|
14971
|
+
scheduleLostLeadershipTeardownRetry() {
|
|
14972
|
+
if (this.stopped || !this.losingLeadership || this.retryTimer) return;
|
|
14973
|
+
this.retryTimer = setTimeout(() => {
|
|
14974
|
+
this.retryTimer = null;
|
|
14975
|
+
void this.enqueue(async () => this.stopAfterLeadershipLoss());
|
|
14976
|
+
}, RETRY_DELAY_MS);
|
|
14977
|
+
this.retryTimer.unref?.();
|
|
14978
|
+
}
|
|
14979
|
+
clearHeartbeat() {
|
|
14980
|
+
if (!this.heartbeatTimer) return;
|
|
14981
|
+
clearInterval(this.heartbeatTimer);
|
|
14982
|
+
this.heartbeatTimer = null;
|
|
14983
|
+
}
|
|
14984
|
+
clearTimers() {
|
|
14985
|
+
this.clearHeartbeat();
|
|
14986
|
+
this.clearRetryTimer();
|
|
14987
|
+
if (this.teardownRetryTimer) {
|
|
14988
|
+
clearTimeout(this.teardownRetryTimer);
|
|
14989
|
+
this.teardownRetryTimer = null;
|
|
14990
|
+
}
|
|
14991
|
+
}
|
|
14992
|
+
clearRetryTimer() {
|
|
14993
|
+
if (!this.retryTimer) return;
|
|
14994
|
+
clearTimeout(this.retryTimer);
|
|
14995
|
+
this.retryTimer = null;
|
|
14996
|
+
}
|
|
14997
|
+
reportAcquireError(error) {
|
|
14998
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
14999
|
+
if (this.reportedError === message) return;
|
|
15000
|
+
this.reportedError = message;
|
|
15001
|
+
console.error("[codebase-index] Failed to acquire background worker lease:", error);
|
|
15002
|
+
}
|
|
15003
|
+
};
|
|
15004
|
+
function configureBackgroundWorker(projectRoot, host, config, hooks, options = {}) {
|
|
15005
|
+
const projectKey = projectLookupKey(projectRoot, host);
|
|
15006
|
+
const identity = resolveIdentity(projectRoot, config, host);
|
|
15007
|
+
const key = controllerKey(identity, host);
|
|
15008
|
+
const previousKey = workerKeysByProject.get(projectKey);
|
|
15009
|
+
if (previousKey && previousKey !== key) {
|
|
15010
|
+
const previous = workers.get(previousKey);
|
|
15011
|
+
const previousBarrier = workerReplacementBarriers.get(projectKey) ?? Promise.resolve();
|
|
15012
|
+
const stopPrevious = previous?.stop(options.stopPreviousAutoIndex ?? true) ?? Promise.resolve();
|
|
15013
|
+
const activation = Promise.all([previousBarrier, stopPrevious]).then(() => void 0);
|
|
15014
|
+
workerReplacementBarriers.set(projectKey, activation);
|
|
15015
|
+
workers.delete(previousKey);
|
|
15016
|
+
const worker2 = new BackgroundWorkerController(projectRoot, host, config, hooks, identity);
|
|
15017
|
+
worker2.startAfter(activation);
|
|
15018
|
+
workers.set(key, worker2);
|
|
15019
|
+
workerKeysByProject.set(projectKey, key);
|
|
15020
|
+
return;
|
|
15021
|
+
}
|
|
15022
|
+
let worker = workers.get(key);
|
|
15023
|
+
if (!worker) {
|
|
15024
|
+
worker = new BackgroundWorkerController(projectRoot, host, config, hooks, identity);
|
|
15025
|
+
workers.set(key, worker);
|
|
15026
|
+
} else {
|
|
15027
|
+
worker.update(config, hooks, options);
|
|
15028
|
+
}
|
|
15029
|
+
workerKeysByProject.set(projectKey, key);
|
|
15030
|
+
worker.start();
|
|
15031
|
+
}
|
|
15032
|
+
function attachBackgroundWorkerWatcher(projectRoot, host, watcherFactory, watcherFactoryForConfig) {
|
|
15033
|
+
const key = workerKeysByProject.get(projectLookupKey(projectRoot, host));
|
|
15034
|
+
workers.get(key ?? "")?.attachWatcher(watcherFactory, watcherFactoryForConfig);
|
|
15035
|
+
}
|
|
15036
|
+
function updateBackgroundWorkerConfig(projectRoot, host, config) {
|
|
15037
|
+
const projectKey = projectLookupKey(projectRoot, host);
|
|
15038
|
+
const key = workerKeysByProject.get(projectKey);
|
|
15039
|
+
const worker = key ? workers.get(key) : void 0;
|
|
15040
|
+
if (!worker) return;
|
|
15041
|
+
configureBackgroundWorker(projectRoot, host, config, worker.getHooksForConfig(config), {
|
|
15042
|
+
stopPreviousAutoIndex: false,
|
|
15043
|
+
restartAutoIndex: true
|
|
15044
|
+
});
|
|
15045
|
+
}
|
|
15046
|
+
function requestBackgroundWorker(projectRoot, host) {
|
|
15047
|
+
const key = workerKeysByProject.get(projectLookupKey(projectRoot, host));
|
|
15048
|
+
workers.get(key ?? "")?.start();
|
|
15049
|
+
}
|
|
15050
|
+
function waitForBackgroundWorkerStart(projectRoot, host) {
|
|
15051
|
+
const key = workerKeysByProject.get(projectLookupKey(projectRoot, host));
|
|
15052
|
+
return workers.get(key ?? "")?.waitForStart() ?? Promise.resolve();
|
|
15053
|
+
}
|
|
15054
|
+
function requestBackgroundWorkerRefresh(projectRoot, host, allowDisabledAutoIndex = false) {
|
|
15055
|
+
const key = workerKeysByProject.get(projectLookupKey(projectRoot, host));
|
|
15056
|
+
workers.get(key ?? "")?.requestRefresh(allowDisabledAutoIndex);
|
|
15057
|
+
}
|
|
15058
|
+
function isBackgroundWorkerManaged(projectRoot, host) {
|
|
15059
|
+
const key = workerKeysByProject.get(projectLookupKey(projectRoot, host));
|
|
15060
|
+
return key !== void 0 && workers.has(key);
|
|
15061
|
+
}
|
|
15062
|
+
function isBackgroundWorkerLeader(projectRoot, host) {
|
|
15063
|
+
const key = workerKeysByProject.get(projectLookupKey(projectRoot, host));
|
|
15064
|
+
return key !== void 0 && workers.get(key)?.isLeader() === true;
|
|
15065
|
+
}
|
|
15066
|
+
function isBackgroundWorkerStopping(projectRoot, host) {
|
|
15067
|
+
const key = workerKeysByProject.get(projectLookupKey(projectRoot, host));
|
|
15068
|
+
return key !== void 0 && workers.get(key)?.isStopping() === true;
|
|
15069
|
+
}
|
|
15070
|
+
async function stopBackgroundWorker(projectRoot, host) {
|
|
15071
|
+
const projectKey = projectLookupKey(projectRoot, host);
|
|
15072
|
+
const key = workerKeysByProject.get(projectKey);
|
|
15073
|
+
const worker = key ? workers.get(key) : void 0;
|
|
15074
|
+
if (!worker) return;
|
|
15075
|
+
await worker.stop();
|
|
15076
|
+
}
|
|
14161
15077
|
|
|
14162
15078
|
// src/utils/power-source.ts
|
|
14163
15079
|
var childProcess = __toESM(require("child_process"), 1);
|
|
@@ -14167,7 +15083,7 @@ function getErrorMessage4(error) {
|
|
|
14167
15083
|
return error instanceof Error ? error.message : String(error);
|
|
14168
15084
|
}
|
|
14169
15085
|
function runCommand(file, args, options) {
|
|
14170
|
-
return new Promise((
|
|
15086
|
+
return new Promise((resolve21, reject) => {
|
|
14171
15087
|
childProcess.execFile(
|
|
14172
15088
|
file,
|
|
14173
15089
|
args,
|
|
@@ -14177,7 +15093,7 @@ function runCommand(file, args, options) {
|
|
|
14177
15093
|
reject(error);
|
|
14178
15094
|
return;
|
|
14179
15095
|
}
|
|
14180
|
-
|
|
15096
|
+
resolve21(stdout);
|
|
14181
15097
|
}
|
|
14182
15098
|
);
|
|
14183
15099
|
});
|
|
@@ -14269,8 +15185,8 @@ var AutoIndexCancelledError = class extends Error {
|
|
|
14269
15185
|
function now() {
|
|
14270
15186
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
14271
15187
|
}
|
|
14272
|
-
function
|
|
14273
|
-
const resolved =
|
|
15188
|
+
function canonicalizePath2(targetPath) {
|
|
15189
|
+
const resolved = path18.resolve(targetPath);
|
|
14274
15190
|
if ((0, import_fs11.existsSync)(resolved)) {
|
|
14275
15191
|
try {
|
|
14276
15192
|
return import_fs11.realpathSync.native(resolved);
|
|
@@ -14278,20 +15194,20 @@ function canonicalizePath(targetPath) {
|
|
|
14278
15194
|
return resolved;
|
|
14279
15195
|
}
|
|
14280
15196
|
}
|
|
14281
|
-
const parent =
|
|
15197
|
+
const parent = path18.dirname(resolved);
|
|
14282
15198
|
if (parent === resolved) return resolved;
|
|
14283
|
-
return
|
|
15199
|
+
return path18.join(canonicalizePath2(parent), path18.basename(resolved));
|
|
14284
15200
|
}
|
|
14285
15201
|
function isHomeDirectory(projectRoot) {
|
|
14286
|
-
return
|
|
15202
|
+
return canonicalizePath2(projectRoot) === canonicalizePath2(os7.homedir());
|
|
14287
15203
|
}
|
|
14288
|
-
function
|
|
14289
|
-
return `${host}::${
|
|
15204
|
+
function projectLookupKey2(projectRoot, host) {
|
|
15205
|
+
return `${host}::${canonicalizePath2(projectRoot)}`;
|
|
14290
15206
|
}
|
|
14291
15207
|
function coordinatorKey(projectRoot, config, host) {
|
|
14292
|
-
const canonicalProjectRoot =
|
|
15208
|
+
const canonicalProjectRoot = canonicalizePath2(projectRoot);
|
|
14293
15209
|
const indexPath = resolveProjectIndexPath(projectRoot, config.scope, host);
|
|
14294
|
-
return `${
|
|
15210
|
+
return `${canonicalizePath2(indexPath)}::${canonicalProjectRoot}`;
|
|
14295
15211
|
}
|
|
14296
15212
|
function getProjectSafety(projectRoot, config) {
|
|
14297
15213
|
if (isHomeDirectory(projectRoot)) {
|
|
@@ -14322,10 +15238,10 @@ function safeFailureMessage(error) {
|
|
|
14322
15238
|
}
|
|
14323
15239
|
function cancellableDelay(delayMs, signal) {
|
|
14324
15240
|
if (signal.aborted) return Promise.reject(new AutoIndexCancelledError());
|
|
14325
|
-
return new Promise((
|
|
15241
|
+
return new Promise((resolve21, reject) => {
|
|
14326
15242
|
const timer = setTimeout(() => {
|
|
14327
15243
|
signal.removeEventListener("abort", onAbort);
|
|
14328
|
-
|
|
15244
|
+
resolve21();
|
|
14329
15245
|
}, delayMs);
|
|
14330
15246
|
timer.unref?.();
|
|
14331
15247
|
const onAbort = () => {
|
|
@@ -14337,18 +15253,44 @@ function cancellableDelay(delayMs, signal) {
|
|
|
14337
15253
|
}
|
|
14338
15254
|
function withTimeout(promise, timeoutMs) {
|
|
14339
15255
|
if (timeoutMs <= 0) return Promise.resolve(void 0);
|
|
14340
|
-
return new Promise((
|
|
14341
|
-
const timer = setTimeout(() =>
|
|
15256
|
+
return new Promise((resolve21) => {
|
|
15257
|
+
const timer = setTimeout(() => resolve21(void 0), timeoutMs);
|
|
14342
15258
|
timer.unref?.();
|
|
14343
15259
|
void promise.then((value) => {
|
|
14344
15260
|
clearTimeout(timer);
|
|
14345
|
-
|
|
15261
|
+
resolve21(value);
|
|
14346
15262
|
}, () => {
|
|
14347
15263
|
clearTimeout(timer);
|
|
14348
|
-
|
|
15264
|
+
resolve21(void 0);
|
|
14349
15265
|
});
|
|
14350
15266
|
});
|
|
14351
15267
|
}
|
|
15268
|
+
function settlesWithin(promise, timeoutMs) {
|
|
15269
|
+
if (timeoutMs <= 0) return Promise.resolve(false);
|
|
15270
|
+
return new Promise((resolve21) => {
|
|
15271
|
+
let settled = false;
|
|
15272
|
+
const timer = setTimeout(() => {
|
|
15273
|
+
if (settled) return;
|
|
15274
|
+
settled = true;
|
|
15275
|
+
resolve21(false);
|
|
15276
|
+
}, timeoutMs);
|
|
15277
|
+
timer.unref?.();
|
|
15278
|
+
void promise.then(
|
|
15279
|
+
() => {
|
|
15280
|
+
if (settled) return;
|
|
15281
|
+
settled = true;
|
|
15282
|
+
clearTimeout(timer);
|
|
15283
|
+
resolve21(true);
|
|
15284
|
+
},
|
|
15285
|
+
() => {
|
|
15286
|
+
if (settled) return;
|
|
15287
|
+
settled = true;
|
|
15288
|
+
clearTimeout(timer);
|
|
15289
|
+
resolve21(true);
|
|
15290
|
+
}
|
|
15291
|
+
);
|
|
15292
|
+
});
|
|
15293
|
+
}
|
|
14352
15294
|
function requestPriority(request) {
|
|
14353
15295
|
if (request.force) return 4;
|
|
14354
15296
|
if (request.source === "manual") return 3;
|
|
@@ -14359,6 +15301,7 @@ function mergeRequests(current, next) {
|
|
|
14359
15301
|
if (!current) return next;
|
|
14360
15302
|
const preferred = requestPriority(next) > requestPriority(current) ? next : current;
|
|
14361
15303
|
return {
|
|
15304
|
+
allowDisabledAutoIndex: current.allowDisabledAutoIndex || next.allowDisabledAutoIndex,
|
|
14362
15305
|
checkFreshness: current.checkFreshness && next.checkFreshness,
|
|
14363
15306
|
force: current.force || next.force,
|
|
14364
15307
|
onProgress: next.onProgress ?? current.onProgress,
|
|
@@ -14420,11 +15363,11 @@ var AutoIndexCoordinator = class {
|
|
|
14420
15363
|
progress: this.status.progress ? { ...this.status.progress } : void 0
|
|
14421
15364
|
};
|
|
14422
15365
|
}
|
|
14423
|
-
start(source) {
|
|
15366
|
+
start(source, allowDisabledAutoIndex = false) {
|
|
14424
15367
|
this.refreshSafety();
|
|
14425
|
-
if (!this.registration.config.indexing.autoIndex || !this.registration.safeToRun) return null;
|
|
15368
|
+
if (!this.registration.config.indexing.autoIndex && !allowDisabledAutoIndex || !this.registration.safeToRun) return null;
|
|
14426
15369
|
if (this.status.state === "failed") return this.inFlight;
|
|
14427
|
-
return this.request({ checkFreshness: true, force: false, source });
|
|
15370
|
+
return this.request({ allowDisabledAutoIndex, checkFreshness: true, force: false, source });
|
|
14428
15371
|
}
|
|
14429
15372
|
request(request) {
|
|
14430
15373
|
if (this.stopped) {
|
|
@@ -14499,13 +15442,15 @@ var AutoIndexCoordinator = class {
|
|
|
14499
15442
|
retryAttempt: void 0
|
|
14500
15443
|
});
|
|
14501
15444
|
const inFlight = this.inFlight;
|
|
14502
|
-
|
|
14503
|
-
|
|
14504
|
-
|
|
14505
|
-
} else {
|
|
14506
|
-
await withTimeout(inFlight, SHUTDOWN_WAIT_MS);
|
|
14507
|
-
}
|
|
15445
|
+
const completion = inFlight ? inFlight.then(() => void 0, () => void 0) : Promise.resolve();
|
|
15446
|
+
if (!inFlight) {
|
|
15447
|
+
return { completed: true, completion };
|
|
14508
15448
|
}
|
|
15449
|
+
if (waitForCompletion) {
|
|
15450
|
+
await completion;
|
|
15451
|
+
return { completed: true, completion };
|
|
15452
|
+
}
|
|
15453
|
+
return { completed: await settlesWithin(completion, SHUTDOWN_WAIT_MS), completion };
|
|
14509
15454
|
}
|
|
14510
15455
|
startRequest(request) {
|
|
14511
15456
|
if (this.stopped || !this.canRun(request)) {
|
|
@@ -14694,7 +15639,7 @@ var AutoIndexCoordinator = class {
|
|
|
14694
15639
|
if (request.source === "manual" || request.source === "watcher") {
|
|
14695
15640
|
return true;
|
|
14696
15641
|
}
|
|
14697
|
-
return this.registration.safeToRun && this.registration.config.indexing.autoIndex;
|
|
15642
|
+
return this.registration.safeToRun && (this.registration.config.indexing.autoIndex || request.allowDisabledAutoIndex === true);
|
|
14698
15643
|
}
|
|
14699
15644
|
shouldDeferForBattery(request) {
|
|
14700
15645
|
return this.registration.backgroundIndexingPolicy !== null && (request.source === "startup" || request.source === "watcher");
|
|
@@ -14727,17 +15672,17 @@ var AutoIndexCoordinator = class {
|
|
|
14727
15672
|
}
|
|
14728
15673
|
}
|
|
14729
15674
|
waitForBatteryRetry(delayMs) {
|
|
14730
|
-
return new Promise((
|
|
15675
|
+
return new Promise((resolve21) => {
|
|
14731
15676
|
const timer = setTimeout(() => {
|
|
14732
15677
|
if (this.batteryRetryTimer === timer) {
|
|
14733
15678
|
this.batteryRetryTimer = null;
|
|
14734
15679
|
this.resolveBatteryRetry = null;
|
|
14735
15680
|
}
|
|
14736
|
-
|
|
15681
|
+
resolve21();
|
|
14737
15682
|
}, delayMs);
|
|
14738
15683
|
timer.unref?.();
|
|
14739
15684
|
this.batteryRetryTimer = timer;
|
|
14740
|
-
this.resolveBatteryRetry =
|
|
15685
|
+
this.resolveBatteryRetry = resolve21;
|
|
14741
15686
|
});
|
|
14742
15687
|
}
|
|
14743
15688
|
cancelBatteryRetry() {
|
|
@@ -14745,9 +15690,9 @@ var AutoIndexCoordinator = class {
|
|
|
14745
15690
|
clearTimeout(this.batteryRetryTimer);
|
|
14746
15691
|
this.batteryRetryTimer = null;
|
|
14747
15692
|
}
|
|
14748
|
-
const
|
|
15693
|
+
const resolve21 = this.resolveBatteryRetry;
|
|
14749
15694
|
this.resolveBatteryRetry = null;
|
|
14750
|
-
|
|
15695
|
+
resolve21?.();
|
|
14751
15696
|
}
|
|
14752
15697
|
finishBatteryCheck(batteryCheck) {
|
|
14753
15698
|
if (this.batteryCheck !== batteryCheck) return;
|
|
@@ -14760,12 +15705,25 @@ var AutoIndexCoordinator = class {
|
|
|
14760
15705
|
}
|
|
14761
15706
|
};
|
|
14762
15707
|
function getCoordinator(projectRoot, host) {
|
|
14763
|
-
const key = coordinatorKeysByProject.get(
|
|
15708
|
+
const key = coordinatorKeysByProject.get(projectLookupKey2(projectRoot, host));
|
|
14764
15709
|
return key ? coordinators.get(key) ?? null : null;
|
|
14765
15710
|
}
|
|
14766
|
-
function
|
|
14767
|
-
|
|
15711
|
+
function synchronizeBackgroundWorker(projectRoot, host, config, safeToRun) {
|
|
15712
|
+
if (safeToRun) {
|
|
15713
|
+
updateBackgroundWorkerConfig(projectRoot, host, config);
|
|
15714
|
+
return;
|
|
15715
|
+
}
|
|
15716
|
+
void stopBackgroundWorker(projectRoot, host).catch((error) => {
|
|
15717
|
+
console.error("[codebase-index] Failed to stop background worker after project safety changed:", error);
|
|
15718
|
+
});
|
|
15719
|
+
}
|
|
15720
|
+
function configureAutoIndex(projectRoot, host, config, getIndexer, options = {}) {
|
|
15721
|
+
const projectKey = projectLookupKey2(projectRoot, host);
|
|
14768
15722
|
const safety = getProjectSafety(projectRoot, config);
|
|
15723
|
+
const synchronizeWorker = options.synchronizeBackgroundWorker ?? true;
|
|
15724
|
+
if (options.preserveManagedWorker === true && isBackgroundWorkerManaged(projectRoot, host)) {
|
|
15725
|
+
return;
|
|
15726
|
+
}
|
|
14769
15727
|
const registration = {
|
|
14770
15728
|
backgroundIndexingPolicy: createBackgroundIndexingPolicy(
|
|
14771
15729
|
config.indexing.pauseBackgroundIndexingOnBattery
|
|
@@ -14783,6 +15741,9 @@ function configureAutoIndex(projectRoot, host, config, getIndexer) {
|
|
|
14783
15741
|
const stopPrevious = previousCoordinator?.stop(true) ?? Promise.resolve();
|
|
14784
15742
|
const activation = Promise.all([previousBarrier, stopPrevious]).then(() => void 0);
|
|
14785
15743
|
coordinatorReplacementBarriers.set(projectKey, activation);
|
|
15744
|
+
if (synchronizeWorker) {
|
|
15745
|
+
synchronizeBackgroundWorker(projectRoot, host, config, safety.safeToRun);
|
|
15746
|
+
}
|
|
14786
15747
|
coordinators.delete(previousKey);
|
|
14787
15748
|
const coordinator2 = new AutoIndexCoordinator(registration);
|
|
14788
15749
|
coordinator2.activateAfter(activation);
|
|
@@ -14798,11 +15759,17 @@ function configureAutoIndex(projectRoot, host, config, getIndexer) {
|
|
|
14798
15759
|
coordinator.update(registration);
|
|
14799
15760
|
}
|
|
14800
15761
|
coordinatorKeysByProject.set(projectKey, key);
|
|
15762
|
+
if (synchronizeWorker) {
|
|
15763
|
+
synchronizeBackgroundWorker(projectRoot, host, config, safety.safeToRun);
|
|
15764
|
+
}
|
|
14801
15765
|
}
|
|
14802
|
-
function
|
|
14803
|
-
return getCoordinator(projectRoot, host)?.start(source) ?? null;
|
|
15766
|
+
function startAutoIndexForBackgroundWorker(projectRoot, host, source = "startup", allowDisabledAutoIndex = false) {
|
|
15767
|
+
return getCoordinator(projectRoot, host)?.start(source, allowDisabledAutoIndex) ?? null;
|
|
14804
15768
|
}
|
|
14805
15769
|
function requestBackgroundIndex(projectRoot, host) {
|
|
15770
|
+
if (isBackgroundWorkerManaged(projectRoot, host) && !isBackgroundWorkerLeader(projectRoot, host)) {
|
|
15771
|
+
return null;
|
|
15772
|
+
}
|
|
14806
15773
|
return getCoordinator(projectRoot, host)?.request({
|
|
14807
15774
|
checkFreshness: false,
|
|
14808
15775
|
force: false,
|
|
@@ -14842,15 +15809,23 @@ async function waitForAutoIndexForRetrieval(projectRoot, host) {
|
|
|
14842
15809
|
};
|
|
14843
15810
|
}
|
|
14844
15811
|
try {
|
|
14845
|
-
|
|
15812
|
+
const readiness = await getSearchReadiness(coordinator);
|
|
15813
|
+
if (readiness.searchable) {
|
|
15814
|
+
return { ready: true };
|
|
15815
|
+
}
|
|
15816
|
+
if (readiness.blocked) return unavailableSnapshotResult(readiness.reason);
|
|
14846
15817
|
} catch {
|
|
14847
15818
|
}
|
|
14848
|
-
const job =
|
|
15819
|
+
const job = startRetrievalRefresh(projectRoot, host, coordinator);
|
|
14849
15820
|
if (job) {
|
|
14850
15821
|
await withTimeout(job, coordinator.getWaitMs());
|
|
15822
|
+
} else if (isBackgroundWorkerManaged(projectRoot, host)) {
|
|
15823
|
+
await waitForPublishedSnapshot(coordinator, coordinator.getWaitMs());
|
|
14851
15824
|
}
|
|
14852
15825
|
try {
|
|
14853
|
-
|
|
15826
|
+
const readiness = await getSearchReadiness(coordinator);
|
|
15827
|
+
if (readiness.searchable) return { ready: true };
|
|
15828
|
+
if (readiness.blocked) return unavailableSnapshotResult(readiness.reason);
|
|
14854
15829
|
} catch {
|
|
14855
15830
|
}
|
|
14856
15831
|
const status = coordinator.snapshot();
|
|
@@ -14871,31 +15846,62 @@ async function waitForAutoIndexForRetrieval(projectRoot, host) {
|
|
|
14871
15846
|
text: `Automatic indexing is ${status.state}. Retry shortly or call index_status for progress. You can also run index_codebase explicitly.`
|
|
14872
15847
|
};
|
|
14873
15848
|
}
|
|
14874
|
-
async function
|
|
14875
|
-
|
|
15849
|
+
async function stopAutoIndexForBackgroundWorker(projectRoot, host, waitForCompletion = false) {
|
|
15850
|
+
const coordinator = getCoordinator(projectRoot, host);
|
|
15851
|
+
if (!coordinator) {
|
|
15852
|
+
return { completed: true, completion: Promise.resolve() };
|
|
15853
|
+
}
|
|
15854
|
+
return coordinator.stop(waitForCompletion);
|
|
14876
15855
|
}
|
|
14877
|
-
async function
|
|
15856
|
+
async function getSearchReadiness(coordinator) {
|
|
14878
15857
|
const indexer = coordinator.getIndexer();
|
|
14879
15858
|
if (indexer.getIndexFreshness) {
|
|
14880
15859
|
const freshness = await indexer.getIndexFreshness();
|
|
14881
|
-
|
|
15860
|
+
const searchable = freshness.readable && freshness.current && freshness.reason === "current";
|
|
15861
|
+
return {
|
|
15862
|
+
blocked: freshness.reason === "unreadable" || freshness.reason === "incompatible" || freshness.reason === "failed-batches" || freshness.reason === "migration-required",
|
|
15863
|
+
reason: freshness.reason,
|
|
15864
|
+
searchable
|
|
15865
|
+
};
|
|
15866
|
+
}
|
|
15867
|
+
const indexed = (await indexer.getStatus()).indexed;
|
|
15868
|
+
return { blocked: false, searchable: indexed };
|
|
15869
|
+
}
|
|
15870
|
+
function unavailableSnapshotResult(reason) {
|
|
15871
|
+
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.";
|
|
15872
|
+
return {
|
|
15873
|
+
ready: false,
|
|
15874
|
+
text: `${detail} Run index_codebase before retrying retrieval.`
|
|
15875
|
+
};
|
|
15876
|
+
}
|
|
15877
|
+
function startRetrievalRefresh(projectRoot, host, coordinator) {
|
|
15878
|
+
if (isBackgroundWorkerManaged(projectRoot, host)) {
|
|
15879
|
+
requestBackgroundWorkerRefresh(projectRoot, host, true);
|
|
15880
|
+
return isBackgroundWorkerLeader(projectRoot, host) ? coordinator.currentJob() : null;
|
|
15881
|
+
}
|
|
15882
|
+
return coordinator.start("retrieval") ?? coordinator.currentJob();
|
|
15883
|
+
}
|
|
15884
|
+
async function waitForPublishedSnapshot(coordinator, waitMs) {
|
|
15885
|
+
const deadline = Date.now() + waitMs;
|
|
15886
|
+
while (Date.now() < deadline) {
|
|
15887
|
+
if ((await getSearchReadiness(coordinator)).searchable) return;
|
|
15888
|
+
await new Promise((resolve21) => setTimeout(resolve21, Math.min(250, deadline - Date.now())));
|
|
14882
15889
|
}
|
|
14883
|
-
return (await indexer.getStatus()).indexed;
|
|
14884
15890
|
}
|
|
14885
15891
|
|
|
14886
15892
|
// src/tools/config-state.ts
|
|
14887
15893
|
var import_fs13 = require("fs");
|
|
14888
|
-
var
|
|
15894
|
+
var path21 = __toESM(require("path"), 1);
|
|
14889
15895
|
|
|
14890
15896
|
// src/config/merger.ts
|
|
14891
15897
|
var import_fs12 = require("fs");
|
|
14892
|
-
var
|
|
15898
|
+
var path20 = __toESM(require("path"), 1);
|
|
14893
15899
|
|
|
14894
15900
|
// src/config/rebase.ts
|
|
14895
|
-
var
|
|
15901
|
+
var path19 = __toESM(require("path"), 1);
|
|
14896
15902
|
function isWithinRoot(rootDir, targetPath) {
|
|
14897
|
-
const relativePath =
|
|
14898
|
-
return relativePath === "" || !relativePath.startsWith("..") && !
|
|
15903
|
+
const relativePath = path19.relative(rootDir, targetPath);
|
|
15904
|
+
return relativePath === "" || !relativePath.startsWith("..") && !path19.isAbsolute(relativePath);
|
|
14899
15905
|
}
|
|
14900
15906
|
function rebasePathEntries(values, fromDir, toDir) {
|
|
14901
15907
|
if (!Array.isArray(values)) {
|
|
@@ -14903,10 +15909,10 @@ function rebasePathEntries(values, fromDir, toDir) {
|
|
|
14903
15909
|
}
|
|
14904
15910
|
return values.filter((value) => typeof value === "string").map((value) => {
|
|
14905
15911
|
const trimmed = value.trim();
|
|
14906
|
-
if (!trimmed ||
|
|
15912
|
+
if (!trimmed || path19.isAbsolute(trimmed)) {
|
|
14907
15913
|
return trimmed;
|
|
14908
15914
|
}
|
|
14909
|
-
return normalizePathSeparators(
|
|
15915
|
+
return normalizePathSeparators(path19.normalize(path19.relative(toDir, path19.resolve(fromDir, trimmed))));
|
|
14910
15916
|
}).filter(Boolean);
|
|
14911
15917
|
}
|
|
14912
15918
|
function resolveInheritedKnowledgeBaseEntries(values, sourceRoot, targetRoot) {
|
|
@@ -14918,17 +15924,17 @@ function resolveInheritedKnowledgeBaseEntries(values, sourceRoot, targetRoot) {
|
|
|
14918
15924
|
if (!trimmed) {
|
|
14919
15925
|
return trimmed;
|
|
14920
15926
|
}
|
|
14921
|
-
if (
|
|
15927
|
+
if (path19.isAbsolute(trimmed)) {
|
|
14922
15928
|
if (isWithinRoot(sourceRoot, trimmed)) {
|
|
14923
|
-
return normalizePathSeparators(
|
|
15929
|
+
return normalizePathSeparators(path19.normalize(path19.relative(sourceRoot, trimmed) || "."));
|
|
14924
15930
|
}
|
|
14925
|
-
return
|
|
15931
|
+
return path19.normalize(trimmed);
|
|
14926
15932
|
}
|
|
14927
|
-
const resolvedFromSource =
|
|
15933
|
+
const resolvedFromSource = path19.resolve(sourceRoot, trimmed);
|
|
14928
15934
|
if (isWithinRoot(sourceRoot, resolvedFromSource)) {
|
|
14929
|
-
return normalizePathSeparators(
|
|
15935
|
+
return normalizePathSeparators(path19.normalize(trimmed));
|
|
14930
15936
|
}
|
|
14931
|
-
return normalizePathSeparators(
|
|
15937
|
+
return normalizePathSeparators(path19.normalize(path19.relative(targetRoot, resolvedFromSource)));
|
|
14932
15938
|
}).filter(Boolean);
|
|
14933
15939
|
}
|
|
14934
15940
|
|
|
@@ -14966,8 +15972,8 @@ function mergeUniqueStringArray(values) {
|
|
|
14966
15972
|
return [...new Set(values.map((value) => String(value).trim()))];
|
|
14967
15973
|
}
|
|
14968
15974
|
function normalizeKnowledgeBasePath2(value) {
|
|
14969
|
-
let normalized =
|
|
14970
|
-
const root =
|
|
15975
|
+
let normalized = path20.normalize(String(value).trim());
|
|
15976
|
+
const root = path20.parse(normalized).root;
|
|
14971
15977
|
while (normalized.length > root.length && /[\\/]$/.test(normalized)) {
|
|
14972
15978
|
normalized = normalized.slice(0, -1);
|
|
14973
15979
|
}
|
|
@@ -15025,7 +16031,7 @@ function loadProjectConfigLayer(projectRoot, host) {
|
|
|
15025
16031
|
return {};
|
|
15026
16032
|
}
|
|
15027
16033
|
const normalizedConfig = { ...projectConfig };
|
|
15028
|
-
const projectConfigBaseDir =
|
|
16034
|
+
const projectConfigBaseDir = path20.dirname(path20.dirname(projectConfigPath));
|
|
15029
16035
|
if (Array.isArray(normalizedConfig.knowledgeBases)) {
|
|
15030
16036
|
normalizedConfig.knowledgeBases = resolveInheritedKnowledgeBaseEntries(
|
|
15031
16037
|
normalizedConfig.knowledgeBases,
|
|
@@ -15115,8 +16121,8 @@ function loadEditableConfig(projectRoot, host) {
|
|
|
15115
16121
|
}
|
|
15116
16122
|
function saveConfig(projectRoot, config, host) {
|
|
15117
16123
|
const configPath = getConfigPath(projectRoot, host);
|
|
15118
|
-
const configDir =
|
|
15119
|
-
const configBaseDir =
|
|
16124
|
+
const configDir = path21.dirname(configPath);
|
|
16125
|
+
const configBaseDir = path21.dirname(configDir);
|
|
15120
16126
|
if (!(0, import_fs13.existsSync)(configDir)) {
|
|
15121
16127
|
(0, import_fs13.mkdirSync)(configDir, { recursive: true });
|
|
15122
16128
|
}
|
|
@@ -15205,15 +16211,24 @@ function getOrCreateIndexer(projectRoot, host) {
|
|
|
15205
16211
|
}
|
|
15206
16212
|
const indexer = new Indexer(projectRoot, config, host);
|
|
15207
16213
|
indexerCache.set(key, indexer);
|
|
15208
|
-
configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host)
|
|
16214
|
+
configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host), {
|
|
16215
|
+
preserveManagedWorker: true,
|
|
16216
|
+
synchronizeBackgroundWorker: false
|
|
16217
|
+
});
|
|
15209
16218
|
return indexer;
|
|
15210
16219
|
}
|
|
15211
|
-
function initializeTools(projectRoot, config, host) {
|
|
16220
|
+
function initializeTools(projectRoot, config, host, options = {}) {
|
|
15212
16221
|
defaultProjectRoots.set(host, projectRoot);
|
|
15213
16222
|
const key = getIndexerCacheKey(projectRoot, host);
|
|
16223
|
+
if (options.preserveManagedWorker === true && isBackgroundWorkerManaged(projectRoot, host) && indexerCache.has(key)) {
|
|
16224
|
+
return;
|
|
16225
|
+
}
|
|
15214
16226
|
configCache.set(key, config);
|
|
15215
16227
|
indexerCache.set(key, new Indexer(projectRoot, config, host));
|
|
15216
|
-
configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host)
|
|
16228
|
+
configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host), {
|
|
16229
|
+
preserveManagedWorker: options.preserveManagedWorker,
|
|
16230
|
+
synchronizeBackgroundWorker: false
|
|
16231
|
+
});
|
|
15217
16232
|
}
|
|
15218
16233
|
function getIndexerForProject(projectRoot, host) {
|
|
15219
16234
|
const root = getProjectRoot(projectRoot, host);
|
|
@@ -15227,7 +16242,9 @@ function refreshIndexerForDirectory(projectRoot, host, config = parseConfig(load
|
|
|
15227
16242
|
const key = getIndexerCacheKey(projectRoot, host);
|
|
15228
16243
|
configCache.set(key, config);
|
|
15229
16244
|
indexerCache.set(key, new Indexer(projectRoot, config, host));
|
|
15230
|
-
configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host)
|
|
16245
|
+
configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host), {
|
|
16246
|
+
synchronizeBackgroundWorker: true
|
|
16247
|
+
});
|
|
15231
16248
|
return config;
|
|
15232
16249
|
}
|
|
15233
16250
|
var AutoIndexRetrievalUnavailableError = class extends Error {
|
|
@@ -15254,7 +16271,7 @@ function trimOrUndefined(value) {
|
|
|
15254
16271
|
return normalized || void 0;
|
|
15255
16272
|
}
|
|
15256
16273
|
function normalizeCallGraphPath(value) {
|
|
15257
|
-
let normalized =
|
|
16274
|
+
let normalized = path22.posix.normalize(value.trim().replaceAll("\\", "/"));
|
|
15258
16275
|
if (normalized.startsWith("./")) {
|
|
15259
16276
|
normalized = normalized.slice(2);
|
|
15260
16277
|
}
|
|
@@ -15447,12 +16464,12 @@ async function getCallGraphPath(projectRoot, host, from, to, maxDepth, fromFileP
|
|
|
15447
16464
|
if (fromResolution.status !== "resolved" || toResolution.status !== "resolved") {
|
|
15448
16465
|
return { from: fromResolution, to: toResolution, path: [] };
|
|
15449
16466
|
}
|
|
15450
|
-
const
|
|
16467
|
+
const path34 = await indexer.findCallPathBySymbolIds(
|
|
15451
16468
|
fromResolution.symbolId,
|
|
15452
16469
|
toResolution.symbolId,
|
|
15453
16470
|
maxDepth
|
|
15454
16471
|
);
|
|
15455
|
-
return { from: fromResolution, to: toResolution, path:
|
|
16472
|
+
return { from: fromResolution, to: toResolution, path: path34 };
|
|
15456
16473
|
}
|
|
15457
16474
|
async function runIndexCodebase(projectRoot, host, args, onProgress) {
|
|
15458
16475
|
const root = getProjectRoot(projectRoot, host);
|
|
@@ -15650,8 +16667,8 @@ async function getIndexLogs(projectRoot, host, args) {
|
|
|
15650
16667
|
function addKnowledgeBase(projectRoot, host, knowledgeBasePath) {
|
|
15651
16668
|
const root = getProjectRoot(projectRoot, host);
|
|
15652
16669
|
const inputPath = knowledgeBasePath.trim();
|
|
15653
|
-
const normalizedPath3 =
|
|
15654
|
-
|
|
16670
|
+
const normalizedPath3 = path22.resolve(
|
|
16671
|
+
path22.isAbsolute(inputPath) ? inputPath : resolveKnowledgeBasePath(inputPath, root)
|
|
15655
16672
|
);
|
|
15656
16673
|
if (!(0, import_fs14.existsSync)(normalizedPath3)) {
|
|
15657
16674
|
return `Error: Directory does not exist: ${normalizedPath3}`;
|
|
@@ -15687,7 +16704,7 @@ function addKnowledgeBase(projectRoot, host, knowledgeBasePath) {
|
|
|
15687
16704
|
}
|
|
15688
16705
|
}
|
|
15689
16706
|
for (const dotDir of sensitiveDotDirs) {
|
|
15690
|
-
const sensitiveDir =
|
|
16707
|
+
const sensitiveDir = path22.join(homeDir, dotDir);
|
|
15691
16708
|
if (sensitiveDir && (realPath === sensitiveDir || realPath.startsWith(`${sensitiveDir}/`))) {
|
|
15692
16709
|
return `Error: Adding sensitive directory as knowledge base is not allowed: ${normalizedPath3}`;
|
|
15693
16710
|
}
|
|
@@ -15750,7 +16767,7 @@ function listKnowledgeBases(projectRoot, host) {
|
|
|
15750
16767
|
}
|
|
15751
16768
|
result += "\n";
|
|
15752
16769
|
}
|
|
15753
|
-
const hasHostConfig = (0, import_fs14.existsSync)(
|
|
16770
|
+
const hasHostConfig = (0, import_fs14.existsSync)(path22.join(root, getHostProjectConfigRelativePath(host)));
|
|
15754
16771
|
if (hasHostConfig) {
|
|
15755
16772
|
result += `
|
|
15756
16773
|
Config sources: 1 file(s).`;
|
|
@@ -16223,7 +17240,7 @@ async function resolveCodebaseContextUnmeasured(projectRoot, host, input) {
|
|
|
16223
17240
|
const directory = input.directory ?? void 0;
|
|
16224
17241
|
const tokenBudget = input.tokenBudget ?? void 0;
|
|
16225
17242
|
if (from && to) {
|
|
16226
|
-
const
|
|
17243
|
+
const path34 = await getCallGraphPath(
|
|
16227
17244
|
projectRoot,
|
|
16228
17245
|
host,
|
|
16229
17246
|
from,
|
|
@@ -16232,25 +17249,25 @@ async function resolveCodebaseContextUnmeasured(projectRoot, host, input) {
|
|
|
16232
17249
|
fromFilePath,
|
|
16233
17250
|
toFilePath
|
|
16234
17251
|
);
|
|
16235
|
-
const pathText = formatCallGraphPathResult(
|
|
16236
|
-
if (
|
|
17252
|
+
const pathText = formatCallGraphPathResult(path34);
|
|
17253
|
+
if (path34.path.length > 0) {
|
|
16237
17254
|
const fitted2 = fitTextToContextBudget(
|
|
16238
17255
|
pathText,
|
|
16239
17256
|
tokenBudget
|
|
16240
17257
|
);
|
|
16241
17258
|
return {
|
|
16242
17259
|
text: fitted2.text,
|
|
16243
|
-
details: fittedDetails("path", fitted2,
|
|
17260
|
+
details: fittedDetails("path", fitted2, path34.path.length)
|
|
16244
17261
|
};
|
|
16245
17262
|
}
|
|
16246
|
-
if (
|
|
17263
|
+
if (path34.from.status !== "resolved" || path34.to.status !== "resolved") {
|
|
16247
17264
|
const fitted2 = fitTextToContextBudget(pathText, tokenBudget);
|
|
16248
17265
|
return {
|
|
16249
17266
|
text: fitted2.text,
|
|
16250
17267
|
details: fittedDetails("path", fitted2, 0)
|
|
16251
17268
|
};
|
|
16252
17269
|
}
|
|
16253
|
-
const resolvedFrom =
|
|
17270
|
+
const resolvedFrom = path34.from;
|
|
16254
17271
|
const { callers } = await getCallGraphData(projectRoot, host, {
|
|
16255
17272
|
name: to,
|
|
16256
17273
|
direction: "callers",
|
|
@@ -16728,9 +17745,9 @@ function getRelevantEvidence(query) {
|
|
|
16728
17745
|
});
|
|
16729
17746
|
}
|
|
16730
17747
|
if (query.expected.acceptableFiles) {
|
|
16731
|
-
for (const
|
|
17748
|
+
for (const path34 of query.expected.acceptableFiles) {
|
|
16732
17749
|
legacyEvidence.push({
|
|
16733
|
-
path:
|
|
17750
|
+
path: path34,
|
|
16734
17751
|
...query.expected.symbol !== void 0 ? { symbol: query.expected.symbol } : {},
|
|
16735
17752
|
relevance: 1
|
|
16736
17753
|
});
|
|
@@ -17053,8 +18070,8 @@ function computeEvalMetrics(queries, perQuery, embeddingCallCount, embeddingToke
|
|
|
17053
18070
|
|
|
17054
18071
|
// src/eval/runner-config.ts
|
|
17055
18072
|
var import_fs15 = require("fs");
|
|
17056
|
-
var
|
|
17057
|
-
var
|
|
18073
|
+
var os8 = __toESM(require("os"), 1);
|
|
18074
|
+
var path23 = __toESM(require("path"), 1);
|
|
17058
18075
|
function isRecord2(value) {
|
|
17059
18076
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17060
18077
|
}
|
|
@@ -17098,20 +18115,20 @@ function parseJsonConfigFile(filePath) {
|
|
|
17098
18115
|
}
|
|
17099
18116
|
}
|
|
17100
18117
|
function toAbsolute(projectRoot, maybeRelative) {
|
|
17101
|
-
return
|
|
18118
|
+
return path23.isAbsolute(maybeRelative) ? maybeRelative : path23.join(projectRoot, maybeRelative);
|
|
17102
18119
|
}
|
|
17103
18120
|
function isProjectScopedConfigPath(configPath) {
|
|
17104
|
-
return
|
|
18121
|
+
return path23.basename(configPath) === "codebase-index.json" && path23.basename(path23.dirname(configPath)) === ".opencode";
|
|
17105
18122
|
}
|
|
17106
18123
|
function normalizeEvalConfigKnowledgeBases(rawConfig, projectRoot, resolvedConfigPath) {
|
|
17107
18124
|
const config = rawConfig && typeof rawConfig === "object" ? { ...rawConfig } : {};
|
|
17108
18125
|
const rebaseEntries = (values) => isProjectScopedConfigPath(resolvedConfigPath) ? resolveInheritedKnowledgeBaseEntries(
|
|
17109
18126
|
values,
|
|
17110
|
-
|
|
18127
|
+
path23.dirname(path23.dirname(resolvedConfigPath)),
|
|
17111
18128
|
projectRoot
|
|
17112
18129
|
) : rebasePathEntries(
|
|
17113
18130
|
values,
|
|
17114
|
-
|
|
18131
|
+
path23.dirname(resolvedConfigPath),
|
|
17115
18132
|
projectRoot
|
|
17116
18133
|
);
|
|
17117
18134
|
if (Array.isArray(config.knowledgeBases)) {
|
|
@@ -17139,7 +18156,7 @@ function loadRawConfig(projectRoot, configPath) {
|
|
|
17139
18156
|
projectConfig
|
|
17140
18157
|
);
|
|
17141
18158
|
}
|
|
17142
|
-
const globalConfig =
|
|
18159
|
+
const globalConfig = path23.join(os8.homedir(), ".config", "opencode", "codebase-index.json");
|
|
17143
18160
|
if ((0, import_fs15.existsSync)(globalConfig)) {
|
|
17144
18161
|
return parseJsonConfigFile(globalConfig);
|
|
17145
18162
|
}
|
|
@@ -17149,10 +18166,10 @@ function getIndexRootPath(projectRoot, scope) {
|
|
|
17149
18166
|
return scope === "global" ? getGlobalIndexPath("opencode") : resolveProjectIndexPath(projectRoot, scope, "opencode");
|
|
17150
18167
|
}
|
|
17151
18168
|
function getLocalProjectIndexRoot(projectRoot) {
|
|
17152
|
-
return
|
|
18169
|
+
return path23.join(projectRoot, ".opencode", "index");
|
|
17153
18170
|
}
|
|
17154
18171
|
function getLocalProjectConfigPath(projectRoot) {
|
|
17155
|
-
return
|
|
18172
|
+
return path23.join(projectRoot, ".opencode", "codebase-index.json");
|
|
17156
18173
|
}
|
|
17157
18174
|
function clearIndexRoot(projectRoot, scope) {
|
|
17158
18175
|
const indexRoot = scope === "global" ? getIndexRootPath(projectRoot, scope) : getLocalProjectIndexRoot(projectRoot);
|
|
@@ -17174,7 +18191,7 @@ function ensureLocalEvalProjectConfig(projectRoot, configPath) {
|
|
|
17174
18191
|
projectRoot,
|
|
17175
18192
|
resolvedConfigPath
|
|
17176
18193
|
);
|
|
17177
|
-
(0, import_fs15.mkdirSync)(
|
|
18194
|
+
(0, import_fs15.mkdirSync)(path23.dirname(localConfigPath), { recursive: true });
|
|
17178
18195
|
(0, import_fs15.writeFileSync)(localConfigPath, JSON.stringify(sourceConfig, null, 2), "utf-8");
|
|
17179
18196
|
return localConfigPath;
|
|
17180
18197
|
}
|
|
@@ -17227,68 +18244,68 @@ function isStringArray4(value) {
|
|
|
17227
18244
|
function isNonEmptyString(value) {
|
|
17228
18245
|
return typeof value === "string" && value.trim().length > 0;
|
|
17229
18246
|
}
|
|
17230
|
-
function asPositiveNumber(value,
|
|
18247
|
+
function asPositiveNumber(value, path34) {
|
|
17231
18248
|
if (typeof value !== "number" || Number.isNaN(value) || value < 0) {
|
|
17232
|
-
throw new Error(`${
|
|
18249
|
+
throw new Error(`${path34} must be a non-negative number`);
|
|
17233
18250
|
}
|
|
17234
18251
|
return value;
|
|
17235
18252
|
}
|
|
17236
|
-
function parseQueryType(value,
|
|
18253
|
+
function parseQueryType(value, path34) {
|
|
17237
18254
|
if (value === "definition" || value === "implementation-intent" || value === "similarity" || value === "keyword-heavy" || value === "conceptual") {
|
|
17238
18255
|
return value;
|
|
17239
18256
|
}
|
|
17240
18257
|
throw new Error(
|
|
17241
|
-
`${
|
|
18258
|
+
`${path34} must be one of: definition, implementation-intent, similarity, keyword-heavy, conceptual`
|
|
17242
18259
|
);
|
|
17243
18260
|
}
|
|
17244
|
-
function parseExpectedRoute(value,
|
|
18261
|
+
function parseExpectedRoute(value, path34) {
|
|
17245
18262
|
if (value === void 0) return void 0;
|
|
17246
18263
|
if (value === "search" || value === "definition") return value;
|
|
17247
|
-
throw new Error(`${
|
|
18264
|
+
throw new Error(`${path34} must be one of: search, definition`);
|
|
17248
18265
|
}
|
|
17249
|
-
function parseExpectedOutcome(value,
|
|
18266
|
+
function parseExpectedOutcome(value, path34) {
|
|
17250
18267
|
if (value === void 0) return void 0;
|
|
17251
18268
|
if (value === "results" || value === "no-results") {
|
|
17252
18269
|
return value;
|
|
17253
18270
|
}
|
|
17254
|
-
throw new Error(`${
|
|
18271
|
+
throw new Error(`${path34} must be one of: results, no-results`);
|
|
17255
18272
|
}
|
|
17256
|
-
function parseRecoveryExpectation(value,
|
|
18273
|
+
function parseRecoveryExpectation(value, path34) {
|
|
17257
18274
|
if (value === void 0) return void 0;
|
|
17258
18275
|
if (value === "none" || value === "filter-relaxed") {
|
|
17259
18276
|
return value;
|
|
17260
18277
|
}
|
|
17261
|
-
throw new Error(`${
|
|
18278
|
+
throw new Error(`${path34} must be one of: none, filter-relaxed`);
|
|
17262
18279
|
}
|
|
17263
|
-
function parseQueryDifficulty(value,
|
|
18280
|
+
function parseQueryDifficulty(value, path34) {
|
|
17264
18281
|
if (value === void 0) return void 0;
|
|
17265
18282
|
if (value === "easy" || value === "medium" || value === "hard") {
|
|
17266
18283
|
return value;
|
|
17267
18284
|
}
|
|
17268
|
-
throw new Error(`${
|
|
18285
|
+
throw new Error(`${path34} must be one of: easy, medium, hard`);
|
|
17269
18286
|
}
|
|
17270
|
-
function parseQueryTags(value,
|
|
18287
|
+
function parseQueryTags(value, path34) {
|
|
17271
18288
|
if (value === void 0) return void 0;
|
|
17272
18289
|
if (!isStringArray4(value) || value.some((tag) => tag.trim().length === 0)) {
|
|
17273
|
-
throw new Error(`${
|
|
18290
|
+
throw new Error(`${path34} must be an array of non-empty strings`);
|
|
17274
18291
|
}
|
|
17275
18292
|
if (value.length > 16) {
|
|
17276
|
-
throw new Error(`${
|
|
18293
|
+
throw new Error(`${path34} must contain at most 16 tags`);
|
|
17277
18294
|
}
|
|
17278
18295
|
return value;
|
|
17279
18296
|
}
|
|
17280
|
-
function parseQueryArgs(value,
|
|
18297
|
+
function parseQueryArgs(value, path34) {
|
|
17281
18298
|
if (value === void 0) return void 0;
|
|
17282
18299
|
if (!isRecord3(value)) {
|
|
17283
|
-
throw new Error(`${
|
|
17284
|
-
}
|
|
17285
|
-
const symbol = parseStringOrUndefined(value.symbol, `${
|
|
17286
|
-
const filePath = parseStringOrUndefined(value.filePath, `${
|
|
17287
|
-
const fileType = parseStringOrUndefined(value.fileType, `${
|
|
17288
|
-
const directory = parseStringOrUndefined(value.directory, `${
|
|
17289
|
-
const callerLimit = parsePositiveIntegerOrUndefined(value.callerLimit, `${
|
|
17290
|
-
const calleeLimit = parsePositiveIntegerOrUndefined(value.calleeLimit, `${
|
|
17291
|
-
const tokenBudget = parsePositiveIntegerOrUndefined(value.tokenBudget, `${
|
|
18300
|
+
throw new Error(`${path34} must be an object`);
|
|
18301
|
+
}
|
|
18302
|
+
const symbol = parseStringOrUndefined(value.symbol, `${path34}.symbol`);
|
|
18303
|
+
const filePath = parseStringOrUndefined(value.filePath, `${path34}.filePath`);
|
|
18304
|
+
const fileType = parseStringOrUndefined(value.fileType, `${path34}.fileType`);
|
|
18305
|
+
const directory = parseStringOrUndefined(value.directory, `${path34}.directory`);
|
|
18306
|
+
const callerLimit = parsePositiveIntegerOrUndefined(value.callerLimit, `${path34}.callerLimit`);
|
|
18307
|
+
const calleeLimit = parsePositiveIntegerOrUndefined(value.calleeLimit, `${path34}.calleeLimit`);
|
|
18308
|
+
const tokenBudget = parsePositiveIntegerOrUndefined(value.tokenBudget, `${path34}.tokenBudget`);
|
|
17292
18309
|
return {
|
|
17293
18310
|
...symbol !== void 0 ? { symbol } : {},
|
|
17294
18311
|
...filePath !== void 0 ? { filePath } : {},
|
|
@@ -17299,50 +18316,50 @@ function parseQueryArgs(value, path33) {
|
|
|
17299
18316
|
...tokenBudget !== void 0 ? { tokenBudget } : {}
|
|
17300
18317
|
};
|
|
17301
18318
|
}
|
|
17302
|
-
function parsePositiveIntegerOrUndefined(value,
|
|
18319
|
+
function parsePositiveIntegerOrUndefined(value, path34) {
|
|
17303
18320
|
if (value === void 0 || value === null) return void 0;
|
|
17304
18321
|
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
17305
|
-
throw new Error(`${
|
|
18322
|
+
throw new Error(`${path34} must be a positive integer`);
|
|
17306
18323
|
}
|
|
17307
18324
|
return value;
|
|
17308
18325
|
}
|
|
17309
18326
|
var SEMVER_VERSION_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
17310
|
-
function parseSemanticVersion(value,
|
|
18327
|
+
function parseSemanticVersion(value, path34) {
|
|
17311
18328
|
if (!isNonEmptyString(value)) {
|
|
17312
|
-
throw new Error(`${
|
|
18329
|
+
throw new Error(`${path34} must be a non-empty string`);
|
|
17313
18330
|
}
|
|
17314
18331
|
if (!SEMVER_VERSION_PATTERN.test(value)) {
|
|
17315
|
-
throw new Error(`${
|
|
18332
|
+
throw new Error(`${path34} must be a valid semantic version (MAJOR.MINOR.PATCH)`);
|
|
17316
18333
|
}
|
|
17317
18334
|
return value;
|
|
17318
18335
|
}
|
|
17319
|
-
function parseRetrievalMode(value,
|
|
18336
|
+
function parseRetrievalMode(value, path34) {
|
|
17320
18337
|
if (value === void 0 || value === "search") return "search";
|
|
17321
18338
|
if (value === "context" || value === "edit-context") return value;
|
|
17322
|
-
throw new Error(`${
|
|
18339
|
+
throw new Error(`${path34} must be one of: search, context, edit-context`);
|
|
17323
18340
|
}
|
|
17324
|
-
function parseStringOrUndefined(value,
|
|
18341
|
+
function parseStringOrUndefined(value, path34) {
|
|
17325
18342
|
if (value === void 0 || value === null) return void 0;
|
|
17326
18343
|
if (!isNonEmptyString(value)) {
|
|
17327
|
-
throw new Error(`${
|
|
18344
|
+
throw new Error(`${path34} must be a non-empty string`);
|
|
17328
18345
|
}
|
|
17329
18346
|
return value;
|
|
17330
18347
|
}
|
|
17331
|
-
function parseGradedEvidence(value,
|
|
18348
|
+
function parseGradedEvidence(value, path34) {
|
|
17332
18349
|
if (value === void 0) return [];
|
|
17333
18350
|
if (!Array.isArray(value)) {
|
|
17334
|
-
throw new Error(`${
|
|
18351
|
+
throw new Error(`${path34} must be an array`);
|
|
17335
18352
|
}
|
|
17336
18353
|
return value.map((entry, index) => {
|
|
17337
18354
|
if (!isRecord3(entry)) {
|
|
17338
|
-
throw new Error(`${
|
|
18355
|
+
throw new Error(`${path34}[${index}] must be an object`);
|
|
17339
18356
|
}
|
|
17340
|
-
const evidencePath = parseStringOrUndefined(entry.path, `${
|
|
18357
|
+
const evidencePath = parseStringOrUndefined(entry.path, `${path34}[${index}].path`);
|
|
17341
18358
|
if (evidencePath === void 0) {
|
|
17342
|
-
throw new Error(`${
|
|
18359
|
+
throw new Error(`${path34}[${index}].path is required`);
|
|
17343
18360
|
}
|
|
17344
|
-
const symbol = parseStringOrUndefined(entry.symbol, `${
|
|
17345
|
-
const relevance = parseEvidenceRelevance(entry.relevance, `${
|
|
18361
|
+
const symbol = parseStringOrUndefined(entry.symbol, `${path34}[${index}].symbol`);
|
|
18362
|
+
const relevance = parseEvidenceRelevance(entry.relevance, `${path34}[${index}].relevance`);
|
|
17346
18363
|
return {
|
|
17347
18364
|
path: evidencePath,
|
|
17348
18365
|
...symbol !== void 0 ? { symbol } : {},
|
|
@@ -17350,27 +18367,27 @@ function parseGradedEvidence(value, path33) {
|
|
|
17350
18367
|
};
|
|
17351
18368
|
});
|
|
17352
18369
|
}
|
|
17353
|
-
function parseEvidenceRelevance(value,
|
|
18370
|
+
function parseEvidenceRelevance(value, path34) {
|
|
17354
18371
|
if (value === void 0) {
|
|
17355
|
-
throw new Error(`${
|
|
18372
|
+
throw new Error(`${path34} is required`);
|
|
17356
18373
|
}
|
|
17357
18374
|
if (value !== 1 && value !== 2 && value !== 3) {
|
|
17358
|
-
throw new Error(`${
|
|
18375
|
+
throw new Error(`${path34} must be 1, 2, or 3`);
|
|
17359
18376
|
}
|
|
17360
18377
|
return value;
|
|
17361
18378
|
}
|
|
17362
|
-
function parseExpectedGraphNeighbor(value,
|
|
18379
|
+
function parseExpectedGraphNeighbor(value, path34) {
|
|
17363
18380
|
if (value === void 0) return void 0;
|
|
17364
18381
|
if (!isRecord3(value)) {
|
|
17365
|
-
throw new Error(`${
|
|
18382
|
+
throw new Error(`${path34} must be an object`);
|
|
17366
18383
|
}
|
|
17367
18384
|
if (value.direction !== "caller" && value.direction !== "callee") {
|
|
17368
|
-
throw new Error(`${
|
|
18385
|
+
throw new Error(`${path34}.direction must be one of: caller, callee`);
|
|
17369
18386
|
}
|
|
17370
|
-
const filePath = parseStringOrUndefined(value.filePath, `${
|
|
17371
|
-
const symbol = parseStringOrUndefined(value.symbol, `${
|
|
18387
|
+
const filePath = parseStringOrUndefined(value.filePath, `${path34}.filePath`);
|
|
18388
|
+
const symbol = parseStringOrUndefined(value.symbol, `${path34}.symbol`);
|
|
17372
18389
|
if (filePath === void 0 && symbol === void 0) {
|
|
17373
|
-
throw new Error(`${
|
|
18390
|
+
throw new Error(`${path34} must include filePath or symbol`);
|
|
17374
18391
|
}
|
|
17375
18392
|
return {
|
|
17376
18393
|
direction: value.direction,
|
|
@@ -17378,9 +18395,9 @@ function parseExpectedGraphNeighbor(value, path33) {
|
|
|
17378
18395
|
...symbol !== void 0 ? { symbol } : {}
|
|
17379
18396
|
};
|
|
17380
18397
|
}
|
|
17381
|
-
function parseExpected(input,
|
|
18398
|
+
function parseExpected(input, path34) {
|
|
17382
18399
|
if (!isRecord3(input)) {
|
|
17383
|
-
throw new Error(`${
|
|
18400
|
+
throw new Error(`${path34} must be an object`);
|
|
17384
18401
|
}
|
|
17385
18402
|
const filePathRaw = input.filePath;
|
|
17386
18403
|
const acceptableFilesRaw = input.acceptableFiles;
|
|
@@ -17391,29 +18408,29 @@ function parseExpected(input, path33) {
|
|
|
17391
18408
|
const recoveryExpectationRaw = input.recoveryExpectation;
|
|
17392
18409
|
const gradedEvidenceRaw = input.gradedEvidence;
|
|
17393
18410
|
const graphNeighborRaw = input.graphNeighbor;
|
|
17394
|
-
const filePath = parseStringOrUndefined(filePathRaw, `${
|
|
18411
|
+
const filePath = parseStringOrUndefined(filePathRaw, `${path34}.filePath`);
|
|
17395
18412
|
const acceptableFiles = isStringArray4(acceptableFilesRaw) ? acceptableFilesRaw : void 0;
|
|
17396
|
-
const gradedEvidence = parseGradedEvidence(gradedEvidenceRaw, `${
|
|
17397
|
-
const graphNeighbor = parseExpectedGraphNeighbor(graphNeighborRaw, `${
|
|
17398
|
-
const expectedOutcome = parseExpectedOutcome(expectedOutcomeRaw, `${
|
|
18413
|
+
const gradedEvidence = parseGradedEvidence(gradedEvidenceRaw, `${path34}.gradedEvidence`);
|
|
18414
|
+
const graphNeighbor = parseExpectedGraphNeighbor(graphNeighborRaw, `${path34}.graphNeighbor`);
|
|
18415
|
+
const expectedOutcome = parseExpectedOutcome(expectedOutcomeRaw, `${path34}.expectedOutcome`);
|
|
17399
18416
|
if (expectedOutcome !== "no-results" && !filePath && (!acceptableFiles || acceptableFiles.length === 0) && gradedEvidence.length === 0) {
|
|
17400
18417
|
throw new Error(
|
|
17401
|
-
`${
|
|
18418
|
+
`${path34} must include expected.filePath, expected.acceptableFiles, or expected.gradedEvidence`
|
|
17402
18419
|
);
|
|
17403
18420
|
}
|
|
17404
18421
|
if (acceptableFilesRaw !== void 0 && !isStringArray4(acceptableFilesRaw)) {
|
|
17405
|
-
throw new Error(`${
|
|
18422
|
+
throw new Error(`${path34}.acceptableFiles must be an array of strings`);
|
|
17406
18423
|
}
|
|
17407
18424
|
if (symbolRaw !== void 0 && typeof symbolRaw !== "string") {
|
|
17408
|
-
throw new Error(`${
|
|
18425
|
+
throw new Error(`${path34}.symbol must be a string when provided`);
|
|
17409
18426
|
}
|
|
17410
18427
|
if (branchRaw !== void 0 && typeof branchRaw !== "string") {
|
|
17411
|
-
throw new Error(`${
|
|
18428
|
+
throw new Error(`${path34}.branch must be a string when provided`);
|
|
17412
18429
|
}
|
|
17413
|
-
const expectedRoute = parseExpectedRoute(expectedRouteRaw, `${
|
|
18430
|
+
const expectedRoute = parseExpectedRoute(expectedRouteRaw, `${path34}.expectedRoute`);
|
|
17414
18431
|
const recoveryExpectation = parseRecoveryExpectation(
|
|
17415
18432
|
recoveryExpectationRaw,
|
|
17416
|
-
`${
|
|
18433
|
+
`${path34}.recoveryExpectation`
|
|
17417
18434
|
);
|
|
17418
18435
|
return {
|
|
17419
18436
|
filePath,
|
|
@@ -17427,13 +18444,13 @@ function parseExpected(input, path33) {
|
|
|
17427
18444
|
...graphNeighbor !== void 0 ? { graphNeighbor } : {}
|
|
17428
18445
|
};
|
|
17429
18446
|
}
|
|
17430
|
-
function parseQueryLanguage(value,
|
|
17431
|
-
return parseStringOrUndefined(value,
|
|
18447
|
+
function parseQueryLanguage(value, path34) {
|
|
18448
|
+
return parseStringOrUndefined(value, path34);
|
|
17432
18449
|
}
|
|
17433
18450
|
function parseQuery(input, index) {
|
|
17434
|
-
const
|
|
18451
|
+
const path34 = `queries[${index}]`;
|
|
17435
18452
|
if (!isRecord3(input)) {
|
|
17436
|
-
throw new Error(`${
|
|
18453
|
+
throw new Error(`${path34} must be an object`);
|
|
17437
18454
|
}
|
|
17438
18455
|
const id = input.id;
|
|
17439
18456
|
const query = input.query;
|
|
@@ -17445,21 +18462,21 @@ function parseQuery(input, index) {
|
|
|
17445
18462
|
const tags = input.tags;
|
|
17446
18463
|
const args = input.args;
|
|
17447
18464
|
if (typeof id !== "string" || id.trim().length === 0) {
|
|
17448
|
-
throw new Error(`${
|
|
18465
|
+
throw new Error(`${path34}.id must be a non-empty string`);
|
|
17449
18466
|
}
|
|
17450
18467
|
if (typeof query !== "string" || query.trim().length === 0) {
|
|
17451
|
-
throw new Error(`${
|
|
18468
|
+
throw new Error(`${path34}.query must be a non-empty string`);
|
|
17452
18469
|
}
|
|
17453
18470
|
return {
|
|
17454
18471
|
id,
|
|
17455
18472
|
query,
|
|
17456
|
-
queryType: parseQueryType(queryType, `${
|
|
17457
|
-
retrievalMode: parseRetrievalMode(retrievalMode, `${
|
|
17458
|
-
language: parseQueryLanguage(language, `${
|
|
17459
|
-
difficulty: parseQueryDifficulty(difficulty, `${
|
|
17460
|
-
args: parseQueryArgs(args, `${
|
|
17461
|
-
tags: parseQueryTags(tags, `${
|
|
17462
|
-
expected: parseExpected(expected, `${
|
|
18473
|
+
queryType: parseQueryType(queryType, `${path34}.queryType`),
|
|
18474
|
+
retrievalMode: parseRetrievalMode(retrievalMode, `${path34}.retrievalMode`),
|
|
18475
|
+
language: parseQueryLanguage(language, `${path34}.language`),
|
|
18476
|
+
difficulty: parseQueryDifficulty(difficulty, `${path34}.difficulty`),
|
|
18477
|
+
args: parseQueryArgs(args, `${path34}.args`),
|
|
18478
|
+
tags: parseQueryTags(tags, `${path34}.tags`),
|
|
18479
|
+
expected: parseExpected(expected, `${path34}.expected`)
|
|
17463
18480
|
};
|
|
17464
18481
|
}
|
|
17465
18482
|
function parseGoldenDataset(raw, sourceLabel) {
|
|
@@ -17875,13 +18892,13 @@ async function runEvaluation(options) {
|
|
|
17875
18892
|
};
|
|
17876
18893
|
const outputDir = createRunDirectory(toAbsolute(options.projectRoot, options.outputRoot));
|
|
17877
18894
|
const perQueryArtifact = buildPerQueryArtifact(perQuery);
|
|
17878
|
-
writeJson(
|
|
17879
|
-
writeJson(
|
|
18895
|
+
writeJson(path24.join(outputDir, "summary.json"), summary);
|
|
18896
|
+
writeJson(path24.join(outputDir, "per-query.json"), perQueryArtifact);
|
|
17880
18897
|
let comparison;
|
|
17881
18898
|
if (againstPath) {
|
|
17882
18899
|
const baseline = loadSummary(againstPath);
|
|
17883
18900
|
comparison = compareSummaries(summary, baseline, againstPath);
|
|
17884
|
-
writeJson(
|
|
18901
|
+
writeJson(path24.join(outputDir, "compare.json"), comparison);
|
|
17885
18902
|
}
|
|
17886
18903
|
let gate;
|
|
17887
18904
|
if (options.ciMode) {
|
|
@@ -17894,7 +18911,7 @@ async function runEvaluation(options) {
|
|
|
17894
18911
|
if ((0, import_fs17.existsSync)(resolvedBaseline)) {
|
|
17895
18912
|
const baselineSummary = loadSummary(resolvedBaseline);
|
|
17896
18913
|
comparison = compareSummaries(summary, baselineSummary, resolvedBaseline);
|
|
17897
|
-
writeJson(
|
|
18914
|
+
writeJson(path24.join(outputDir, "compare.json"), comparison);
|
|
17898
18915
|
} else if (budget.failOnMissingBaseline) {
|
|
17899
18916
|
throw new Error(
|
|
17900
18917
|
`Budget baseline is missing: ${resolvedBaseline}. Set failOnMissingBaseline=false to allow CI run without baseline.`
|
|
@@ -17904,7 +18921,7 @@ async function runEvaluation(options) {
|
|
|
17904
18921
|
gate = evaluateBudgetGate(budget, summary, comparison);
|
|
17905
18922
|
}
|
|
17906
18923
|
const markdown = createSummaryMarkdown(summary, comparison, gate);
|
|
17907
|
-
writeText(
|
|
18924
|
+
writeText(path24.join(outputDir, "summary.md"), markdown);
|
|
17908
18925
|
return { outputDir, summary, perQuery, comparison, gate };
|
|
17909
18926
|
} finally {
|
|
17910
18927
|
await indexer.close();
|
|
@@ -17962,23 +18979,23 @@ async function runSweep(options, sweep) {
|
|
|
17962
18979
|
bestByMrrAt10,
|
|
17963
18980
|
bestByP95Latency
|
|
17964
18981
|
};
|
|
17965
|
-
writeJson(
|
|
18982
|
+
writeJson(path24.join(outputDir, "compare.json"), aggregate);
|
|
17966
18983
|
const md = createSummaryMarkdown(
|
|
17967
18984
|
bestByHitAt5?.summary ?? runs[0].summary,
|
|
17968
18985
|
bestByHitAt5?.comparison,
|
|
17969
18986
|
void 0,
|
|
17970
18987
|
aggregate
|
|
17971
18988
|
);
|
|
17972
|
-
writeText(
|
|
17973
|
-
writeJson(
|
|
18989
|
+
writeText(path24.join(outputDir, "summary.md"), md);
|
|
18990
|
+
writeJson(path24.join(outputDir, "summary.json"), bestByHitAt5?.summary ?? runs[0].summary);
|
|
17974
18991
|
return { outputDir, aggregate };
|
|
17975
18992
|
}
|
|
17976
18993
|
|
|
17977
18994
|
// src/eval/cli.ts
|
|
17978
|
-
var
|
|
18995
|
+
var path26 = __toESM(require("path"), 1);
|
|
17979
18996
|
|
|
17980
18997
|
// src/eval/cli-parser.ts
|
|
17981
|
-
var
|
|
18998
|
+
var path25 = __toESM(require("path"), 1);
|
|
17982
18999
|
function printUsage() {
|
|
17983
19000
|
console.log(`
|
|
17984
19001
|
Usage:
|
|
@@ -18050,12 +19067,12 @@ function parseEvalArgs(argv, cwd) {
|
|
|
18050
19067
|
const arg = argv[i];
|
|
18051
19068
|
const next = argv[i + 1];
|
|
18052
19069
|
if (arg === "--project" && next) {
|
|
18053
|
-
parsed.projectRoot =
|
|
19070
|
+
parsed.projectRoot = path25.resolve(cwd, next);
|
|
18054
19071
|
i += 1;
|
|
18055
19072
|
continue;
|
|
18056
19073
|
}
|
|
18057
19074
|
if (arg === "--config" && next) {
|
|
18058
|
-
parsed.configPath =
|
|
19075
|
+
parsed.configPath = path25.resolve(cwd, next);
|
|
18059
19076
|
i += 1;
|
|
18060
19077
|
continue;
|
|
18061
19078
|
}
|
|
@@ -18251,22 +19268,22 @@ async function handleEvalCommand(args, cwd) {
|
|
|
18251
19268
|
if (!parsed.againstPath.endsWith(".json")) {
|
|
18252
19269
|
throw new Error("eval diff --against must point to a summary JSON file");
|
|
18253
19270
|
}
|
|
18254
|
-
const currentSummary = loadSummary(
|
|
19271
|
+
const currentSummary = loadSummary(path26.resolve(parsed.projectRoot, currentPath), {
|
|
18255
19272
|
allowLegacyDiversityMetrics: true
|
|
18256
19273
|
});
|
|
18257
|
-
const baselineSummary = loadSummary(
|
|
19274
|
+
const baselineSummary = loadSummary(path26.resolve(parsed.projectRoot, parsed.againstPath), {
|
|
18258
19275
|
allowLegacyDiversityMetrics: true
|
|
18259
19276
|
});
|
|
18260
19277
|
const comparison = compareSummaries(
|
|
18261
19278
|
currentSummary,
|
|
18262
19279
|
baselineSummary,
|
|
18263
|
-
|
|
19280
|
+
path26.resolve(parsed.projectRoot, parsed.againstPath)
|
|
18264
19281
|
);
|
|
18265
|
-
const outputDir = createRunDirectory(
|
|
19282
|
+
const outputDir = createRunDirectory(path26.resolve(parsed.projectRoot, parsed.outputRoot));
|
|
18266
19283
|
const summaryMd = createSummaryMarkdown(currentSummary, comparison);
|
|
18267
|
-
writeJson(
|
|
18268
|
-
writeText(
|
|
18269
|
-
writeJson(
|
|
19284
|
+
writeJson(path26.join(outputDir, "compare.json"), comparison);
|
|
19285
|
+
writeText(path26.join(outputDir, "summary.md"), summaryMd);
|
|
19286
|
+
writeJson(path26.join(outputDir, "summary.json"), currentSummary);
|
|
18270
19287
|
console.log(`Eval diff complete. Artifacts: ${outputDir}`);
|
|
18271
19288
|
return 0;
|
|
18272
19289
|
}
|
|
@@ -18428,7 +19445,7 @@ async function executeCallGraph(projectRoot, host, args) {
|
|
|
18428
19445
|
return { text: formatCallGraphResult(await getCallGraphData(projectRoot, host, args)) };
|
|
18429
19446
|
}
|
|
18430
19447
|
async function executeCallGraphPath(projectRoot, host, args) {
|
|
18431
|
-
const
|
|
19448
|
+
const path34 = await getCallGraphPath(
|
|
18432
19449
|
projectRoot,
|
|
18433
19450
|
host,
|
|
18434
19451
|
args.from,
|
|
@@ -18437,7 +19454,7 @@ async function executeCallGraphPath(projectRoot, host, args) {
|
|
|
18437
19454
|
args.fromFilePath,
|
|
18438
19455
|
args.toFilePath
|
|
18439
19456
|
);
|
|
18440
|
-
return { text: formatCallGraphPathResult(
|
|
19457
|
+
return { text: formatCallGraphPathResult(path34) };
|
|
18441
19458
|
}
|
|
18442
19459
|
async function executeCodeCommunities(projectRoot, host, args) {
|
|
18443
19460
|
const result = await getCodeCommunities(projectRoot, host, args);
|
|
@@ -18932,10 +19949,65 @@ ${formatSearchResults(results)}` }] };
|
|
|
18932
19949
|
}
|
|
18933
19950
|
|
|
18934
19951
|
// src/adapters/mcp/server.ts
|
|
19952
|
+
var mcpWorkerReferences = /* @__PURE__ */ new Map();
|
|
19953
|
+
var mcpWorkerTeardowns = /* @__PURE__ */ new Map();
|
|
19954
|
+
function retainMcpBackgroundWorker(projectRoot, host) {
|
|
19955
|
+
const key = getBackgroundWorkerProjectKey(projectRoot, host);
|
|
19956
|
+
mcpWorkerReferences.set(key, (mcpWorkerReferences.get(key) ?? 0) + 1);
|
|
19957
|
+
}
|
|
19958
|
+
async function releaseMcpBackgroundWorker(projectRoot, host) {
|
|
19959
|
+
const key = getBackgroundWorkerProjectKey(projectRoot, host);
|
|
19960
|
+
const references = mcpWorkerReferences.get(key) ?? 0;
|
|
19961
|
+
if (references > 1) {
|
|
19962
|
+
mcpWorkerReferences.set(key, references - 1);
|
|
19963
|
+
return;
|
|
19964
|
+
}
|
|
19965
|
+
mcpWorkerReferences.delete(key);
|
|
19966
|
+
const teardown = stopBackgroundWorker(projectRoot, host);
|
|
19967
|
+
mcpWorkerTeardowns.set(key, teardown);
|
|
19968
|
+
try {
|
|
19969
|
+
await teardown;
|
|
19970
|
+
} finally {
|
|
19971
|
+
if (mcpWorkerTeardowns.get(key) === teardown) {
|
|
19972
|
+
mcpWorkerTeardowns.delete(key);
|
|
19973
|
+
}
|
|
19974
|
+
}
|
|
19975
|
+
}
|
|
18935
19976
|
function getServerInstructions(host) {
|
|
18936
19977
|
const hostText = `host ${host}`;
|
|
18937
19978
|
return `This MCP server is the preferred codebase-understanding path for ${hostText}. Start a repository task with index_status when index readiness or freshness is unknown. Use codebase_context as the preferred first entry point because it returns a token-budgeted location pack and routes to definitions or call-graph helpers when symbol intent is present. For code changes with a known or suspected symbol target, optionally call codebase_edit_context as a compact pre-edit step for bounded source plus direct callers and callees before broad file reads. Keep the default tokenBudget for normal discovery, then use implementation_lookup, codebase_search, or a targeted file read only for selected locations that need source content. Use codebase_peek for direct conceptual location lookup. For exact identifiers or exhaustive matches, use grep. After identifying symbols, use call_graph or call_graph_path to trace dependencies. If the index is unavailable, run index_codebase, then retry the retrieval tool.`;
|
|
18938
19979
|
}
|
|
19980
|
+
function configureMcpBackgroundWorker(projectRoot, config, host, watcherFactory, watcherFactoryForConfig) {
|
|
19981
|
+
if (!getProjectSafety(projectRoot, config).safeToRun) {
|
|
19982
|
+
return { managesWorker: false };
|
|
19983
|
+
}
|
|
19984
|
+
if (isBackgroundWorkerManaged(projectRoot, host)) {
|
|
19985
|
+
const key = getBackgroundWorkerProjectKey(projectRoot, host);
|
|
19986
|
+
if ((mcpWorkerReferences.get(key) ?? 0) === 0 && !mcpWorkerTeardowns.has(key)) {
|
|
19987
|
+
return { managesWorker: false };
|
|
19988
|
+
}
|
|
19989
|
+
if (watcherFactory !== void 0) {
|
|
19990
|
+
attachBackgroundWorkerWatcher(projectRoot, host, watcherFactory, watcherFactoryForConfig);
|
|
19991
|
+
}
|
|
19992
|
+
if (mcpWorkerTeardowns.has(key) || isBackgroundWorkerStopping(projectRoot, host)) {
|
|
19993
|
+
requestBackgroundWorker(projectRoot, host);
|
|
19994
|
+
}
|
|
19995
|
+
return { managesWorker: true };
|
|
19996
|
+
}
|
|
19997
|
+
configureBackgroundWorker(projectRoot, host, config, {
|
|
19998
|
+
startAutoIndex: (source, allowDisabledAutoIndex) => {
|
|
19999
|
+
startAutoIndexForBackgroundWorker(projectRoot, host, source, allowDisabledAutoIndex);
|
|
20000
|
+
},
|
|
20001
|
+
stopAutoIndex: () => stopAutoIndexForBackgroundWorker(projectRoot, host),
|
|
20002
|
+
watcherFactory,
|
|
20003
|
+
watcherFactoryForConfig
|
|
20004
|
+
});
|
|
20005
|
+
return { managesWorker: true };
|
|
20006
|
+
}
|
|
20007
|
+
function attachMcpBackgroundWatcher(projectRoot, config, host, watcherFactory, watcherFactoryForConfig) {
|
|
20008
|
+
configureMcpBackgroundWorker(projectRoot, config, host, watcherFactory, watcherFactoryForConfig);
|
|
20009
|
+
return waitForBackgroundWorkerStart(projectRoot, host);
|
|
20010
|
+
}
|
|
18939
20011
|
function createMcpServer(projectRoot, config, host) {
|
|
18940
20012
|
const server = new import_mcp.McpServer({
|
|
18941
20013
|
name: MCP_SERVER_CURRENT_NAME,
|
|
@@ -18943,11 +20015,14 @@ function createMcpServer(projectRoot, config, host) {
|
|
|
18943
20015
|
}, {
|
|
18944
20016
|
instructions: getServerInstructions(host)
|
|
18945
20017
|
});
|
|
18946
|
-
initializeTools(projectRoot, config, host);
|
|
18947
|
-
|
|
20018
|
+
initializeTools(projectRoot, config, host, { preserveManagedWorker: true });
|
|
20019
|
+
const backgroundWorker = configureMcpBackgroundWorker(projectRoot, config, host);
|
|
20020
|
+
if (backgroundWorker.managesWorker) {
|
|
20021
|
+
retainMcpBackgroundWorker(projectRoot, host);
|
|
20022
|
+
}
|
|
18948
20023
|
let stopCoordinationPromise = null;
|
|
18949
20024
|
const stopCoordination = () => {
|
|
18950
|
-
stopCoordinationPromise ??=
|
|
20025
|
+
stopCoordinationPromise ??= backgroundWorker.managesWorker ? releaseMcpBackgroundWorker(projectRoot, host) : Promise.resolve();
|
|
18951
20026
|
return stopCoordinationPromise;
|
|
18952
20027
|
};
|
|
18953
20028
|
const closeProtocol = server.server.close.bind(server.server);
|
|
@@ -18963,7 +20038,9 @@ function createMcpServer(projectRoot, config, host) {
|
|
|
18963
20038
|
const onServerClose = server.server.onclose;
|
|
18964
20039
|
server.server.onclose = () => {
|
|
18965
20040
|
onServerClose?.();
|
|
18966
|
-
void stopCoordination()
|
|
20041
|
+
void stopCoordination().catch((error) => {
|
|
20042
|
+
console.error("[codebase-index] Failed to stop MCP background worker after transport close:", error);
|
|
20043
|
+
});
|
|
18967
20044
|
};
|
|
18968
20045
|
registerMcpTools(server, {
|
|
18969
20046
|
projectRoot,
|
|
@@ -18978,7 +20055,7 @@ var import_fs19 = require("fs");
|
|
|
18978
20055
|
|
|
18979
20056
|
// node_modules/chokidar/index.js
|
|
18980
20057
|
var import_node_events = require("events");
|
|
18981
|
-
var
|
|
20058
|
+
var import_node_fs3 = require("fs");
|
|
18982
20059
|
var import_promises3 = require("fs/promises");
|
|
18983
20060
|
var sp2 = __toESM(require("path"), 1);
|
|
18984
20061
|
|
|
@@ -19066,7 +20143,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
19066
20143
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
19067
20144
|
const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
|
|
19068
20145
|
if (wantBigintFsStats) {
|
|
19069
|
-
this._stat = (
|
|
20146
|
+
this._stat = (path34) => statMethod(path34, { bigint: true });
|
|
19070
20147
|
} else {
|
|
19071
20148
|
this._stat = statMethod;
|
|
19072
20149
|
}
|
|
@@ -19091,8 +20168,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
19091
20168
|
const par = this.parent;
|
|
19092
20169
|
const fil = par && par.files;
|
|
19093
20170
|
if (fil && fil.length > 0) {
|
|
19094
|
-
const { path:
|
|
19095
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
20171
|
+
const { path: path34, depth } = par;
|
|
20172
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path34));
|
|
19096
20173
|
const awaited = await Promise.all(slice);
|
|
19097
20174
|
for (const entry of awaited) {
|
|
19098
20175
|
if (!entry)
|
|
@@ -19132,21 +20209,21 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
19132
20209
|
this.reading = false;
|
|
19133
20210
|
}
|
|
19134
20211
|
}
|
|
19135
|
-
async _exploreDir(
|
|
20212
|
+
async _exploreDir(path34, depth) {
|
|
19136
20213
|
let files;
|
|
19137
20214
|
try {
|
|
19138
|
-
files = await (0, import_promises.readdir)(
|
|
20215
|
+
files = await (0, import_promises.readdir)(path34, this._rdOptions);
|
|
19139
20216
|
} catch (error) {
|
|
19140
20217
|
this._onError(error);
|
|
19141
20218
|
}
|
|
19142
|
-
return { files, depth, path:
|
|
20219
|
+
return { files, depth, path: path34 };
|
|
19143
20220
|
}
|
|
19144
|
-
async _formatEntry(dirent,
|
|
20221
|
+
async _formatEntry(dirent, path34) {
|
|
19145
20222
|
let entry;
|
|
19146
|
-
const
|
|
20223
|
+
const basename9 = this._isDirent ? dirent.name : dirent;
|
|
19147
20224
|
try {
|
|
19148
|
-
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(
|
|
19149
|
-
entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename:
|
|
20225
|
+
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path34, basename9));
|
|
20226
|
+
entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename9 };
|
|
19150
20227
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
19151
20228
|
} catch (err) {
|
|
19152
20229
|
this._onError(err);
|
|
@@ -19216,7 +20293,7 @@ function readdirp(root, options = {}) {
|
|
|
19216
20293
|
}
|
|
19217
20294
|
|
|
19218
20295
|
// node_modules/chokidar/handler.js
|
|
19219
|
-
var
|
|
20296
|
+
var import_node_fs2 = require("fs");
|
|
19220
20297
|
var import_promises2 = require("fs/promises");
|
|
19221
20298
|
var import_node_os = require("os");
|
|
19222
20299
|
var sp = __toESM(require("path"), 1);
|
|
@@ -19545,16 +20622,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
19545
20622
|
};
|
|
19546
20623
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
19547
20624
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
19548
|
-
function createFsWatchInstance(
|
|
20625
|
+
function createFsWatchInstance(path34, options, listener, errHandler, emitRaw) {
|
|
19549
20626
|
const handleEvent = (rawEvent, evPath) => {
|
|
19550
|
-
listener(
|
|
19551
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
19552
|
-
if (evPath &&
|
|
19553
|
-
fsWatchBroadcast(sp.resolve(
|
|
20627
|
+
listener(path34);
|
|
20628
|
+
emitRaw(rawEvent, evPath, { watchedPath: path34 });
|
|
20629
|
+
if (evPath && path34 !== evPath) {
|
|
20630
|
+
fsWatchBroadcast(sp.resolve(path34, evPath), KEY_LISTENERS, sp.join(path34, evPath));
|
|
19554
20631
|
}
|
|
19555
20632
|
};
|
|
19556
20633
|
try {
|
|
19557
|
-
return (0,
|
|
20634
|
+
return (0, import_node_fs2.watch)(path34, {
|
|
19558
20635
|
persistent: options.persistent
|
|
19559
20636
|
}, handleEvent);
|
|
19560
20637
|
} catch (error) {
|
|
@@ -19570,12 +20647,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
19570
20647
|
listener(val1, val2, val3);
|
|
19571
20648
|
});
|
|
19572
20649
|
};
|
|
19573
|
-
var setFsWatchListener = (
|
|
20650
|
+
var setFsWatchListener = (path34, fullPath, options, handlers) => {
|
|
19574
20651
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
19575
20652
|
let cont = FsWatchInstances.get(fullPath);
|
|
19576
20653
|
let watcher;
|
|
19577
20654
|
if (!options.persistent) {
|
|
19578
|
-
watcher = createFsWatchInstance(
|
|
20655
|
+
watcher = createFsWatchInstance(path34, options, listener, errHandler, rawEmitter);
|
|
19579
20656
|
if (!watcher)
|
|
19580
20657
|
return;
|
|
19581
20658
|
return watcher.close.bind(watcher);
|
|
@@ -19586,7 +20663,7 @@ var setFsWatchListener = (path33, fullPath, options, handlers) => {
|
|
|
19586
20663
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
19587
20664
|
} else {
|
|
19588
20665
|
watcher = createFsWatchInstance(
|
|
19589
|
-
|
|
20666
|
+
path34,
|
|
19590
20667
|
options,
|
|
19591
20668
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
19592
20669
|
errHandler,
|
|
@@ -19601,7 +20678,7 @@ var setFsWatchListener = (path33, fullPath, options, handlers) => {
|
|
|
19601
20678
|
cont.watcherUnusable = true;
|
|
19602
20679
|
if (isWindows && error.code === "EPERM") {
|
|
19603
20680
|
try {
|
|
19604
|
-
const fd = await (0, import_promises2.open)(
|
|
20681
|
+
const fd = await (0, import_promises2.open)(path34, "r");
|
|
19605
20682
|
await fd.close();
|
|
19606
20683
|
broadcastErr(error);
|
|
19607
20684
|
} catch (err) {
|
|
@@ -19632,12 +20709,12 @@ var setFsWatchListener = (path33, fullPath, options, handlers) => {
|
|
|
19632
20709
|
};
|
|
19633
20710
|
};
|
|
19634
20711
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
19635
|
-
var setFsWatchFileListener = (
|
|
20712
|
+
var setFsWatchFileListener = (path34, fullPath, options, handlers) => {
|
|
19636
20713
|
const { listener, rawEmitter } = handlers;
|
|
19637
20714
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
19638
20715
|
const copts = cont && cont.options;
|
|
19639
20716
|
if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
|
|
19640
|
-
(0,
|
|
20717
|
+
(0, import_node_fs2.unwatchFile)(fullPath);
|
|
19641
20718
|
cont = void 0;
|
|
19642
20719
|
}
|
|
19643
20720
|
if (cont) {
|
|
@@ -19648,13 +20725,13 @@ var setFsWatchFileListener = (path33, fullPath, options, handlers) => {
|
|
|
19648
20725
|
listeners: listener,
|
|
19649
20726
|
rawEmitters: rawEmitter,
|
|
19650
20727
|
options,
|
|
19651
|
-
watcher: (0,
|
|
20728
|
+
watcher: (0, import_node_fs2.watchFile)(fullPath, options, (curr, prev) => {
|
|
19652
20729
|
foreach(cont.rawEmitters, (rawEmitter2) => {
|
|
19653
20730
|
rawEmitter2(EV.CHANGE, fullPath, { curr, prev });
|
|
19654
20731
|
});
|
|
19655
20732
|
const currmtime = curr.mtimeMs;
|
|
19656
20733
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
19657
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
20734
|
+
foreach(cont.listeners, (listener2) => listener2(path34, curr));
|
|
19658
20735
|
}
|
|
19659
20736
|
})
|
|
19660
20737
|
};
|
|
@@ -19665,7 +20742,7 @@ var setFsWatchFileListener = (path33, fullPath, options, handlers) => {
|
|
|
19665
20742
|
delFromSet(cont, KEY_RAW, rawEmitter);
|
|
19666
20743
|
if (isEmptySet(cont.listeners)) {
|
|
19667
20744
|
FsWatchFileInstances.delete(fullPath);
|
|
19668
|
-
(0,
|
|
20745
|
+
(0, import_node_fs2.unwatchFile)(fullPath);
|
|
19669
20746
|
cont.options = cont.watcher = void 0;
|
|
19670
20747
|
Object.freeze(cont);
|
|
19671
20748
|
}
|
|
@@ -19684,13 +20761,13 @@ var NodeFsHandler = class {
|
|
|
19684
20761
|
* @param listener on fs change
|
|
19685
20762
|
* @returns closer for the watcher instance
|
|
19686
20763
|
*/
|
|
19687
|
-
_watchWithNodeFs(
|
|
20764
|
+
_watchWithNodeFs(path34, listener) {
|
|
19688
20765
|
const opts = this.fsw.options;
|
|
19689
|
-
const directory = sp.dirname(
|
|
19690
|
-
const
|
|
20766
|
+
const directory = sp.dirname(path34);
|
|
20767
|
+
const basename9 = sp.basename(path34);
|
|
19691
20768
|
const parent = this.fsw._getWatchedDir(directory);
|
|
19692
|
-
parent.add(
|
|
19693
|
-
const absolutePath = sp.resolve(
|
|
20769
|
+
parent.add(basename9);
|
|
20770
|
+
const absolutePath = sp.resolve(path34);
|
|
19694
20771
|
const options = {
|
|
19695
20772
|
persistent: opts.persistent
|
|
19696
20773
|
};
|
|
@@ -19699,13 +20776,13 @@ var NodeFsHandler = class {
|
|
|
19699
20776
|
let closer;
|
|
19700
20777
|
if (opts.usePolling) {
|
|
19701
20778
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
19702
|
-
options.interval = enableBin && isBinaryPath(
|
|
19703
|
-
closer = setFsWatchFileListener(
|
|
20779
|
+
options.interval = enableBin && isBinaryPath(basename9) ? opts.binaryInterval : opts.interval;
|
|
20780
|
+
closer = setFsWatchFileListener(path34, absolutePath, options, {
|
|
19704
20781
|
listener,
|
|
19705
20782
|
rawEmitter: this.fsw._emitRaw
|
|
19706
20783
|
});
|
|
19707
20784
|
} else {
|
|
19708
|
-
closer = setFsWatchListener(
|
|
20785
|
+
closer = setFsWatchListener(path34, absolutePath, options, {
|
|
19709
20786
|
listener,
|
|
19710
20787
|
errHandler: this._boundHandleError,
|
|
19711
20788
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -19721,13 +20798,13 @@ var NodeFsHandler = class {
|
|
|
19721
20798
|
if (this.fsw.closed) {
|
|
19722
20799
|
return;
|
|
19723
20800
|
}
|
|
19724
|
-
const
|
|
19725
|
-
const
|
|
19726
|
-
const parent = this.fsw._getWatchedDir(
|
|
20801
|
+
const dirname16 = sp.dirname(file);
|
|
20802
|
+
const basename9 = sp.basename(file);
|
|
20803
|
+
const parent = this.fsw._getWatchedDir(dirname16);
|
|
19727
20804
|
let prevStats = stats;
|
|
19728
|
-
if (parent.has(
|
|
20805
|
+
if (parent.has(basename9))
|
|
19729
20806
|
return;
|
|
19730
|
-
const listener = async (
|
|
20807
|
+
const listener = async (path34, newStats) => {
|
|
19731
20808
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
19732
20809
|
return;
|
|
19733
20810
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -19741,18 +20818,18 @@ var NodeFsHandler = class {
|
|
|
19741
20818
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
19742
20819
|
}
|
|
19743
20820
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
19744
|
-
this.fsw._closeFile(
|
|
20821
|
+
this.fsw._closeFile(path34);
|
|
19745
20822
|
prevStats = newStats2;
|
|
19746
20823
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
19747
20824
|
if (closer2)
|
|
19748
|
-
this.fsw._addPathCloser(
|
|
20825
|
+
this.fsw._addPathCloser(path34, closer2);
|
|
19749
20826
|
} else {
|
|
19750
20827
|
prevStats = newStats2;
|
|
19751
20828
|
}
|
|
19752
20829
|
} catch (error) {
|
|
19753
|
-
this.fsw._remove(
|
|
20830
|
+
this.fsw._remove(dirname16, basename9);
|
|
19754
20831
|
}
|
|
19755
|
-
} else if (parent.has(
|
|
20832
|
+
} else if (parent.has(basename9)) {
|
|
19756
20833
|
const at = newStats.atimeMs;
|
|
19757
20834
|
const mt = newStats.mtimeMs;
|
|
19758
20835
|
if (!at || at <= mt || mt !== prevStats.mtimeMs) {
|
|
@@ -19777,7 +20854,7 @@ var NodeFsHandler = class {
|
|
|
19777
20854
|
* @param item basename of this item
|
|
19778
20855
|
* @returns true if no more processing is needed for this entry.
|
|
19779
20856
|
*/
|
|
19780
|
-
async _handleSymlink(entry, directory,
|
|
20857
|
+
async _handleSymlink(entry, directory, path34, item) {
|
|
19781
20858
|
if (this.fsw.closed) {
|
|
19782
20859
|
return;
|
|
19783
20860
|
}
|
|
@@ -19787,7 +20864,7 @@ var NodeFsHandler = class {
|
|
|
19787
20864
|
this.fsw._incrReadyCount();
|
|
19788
20865
|
let linkPath;
|
|
19789
20866
|
try {
|
|
19790
|
-
linkPath = await (0, import_promises2.realpath)(
|
|
20867
|
+
linkPath = await (0, import_promises2.realpath)(path34);
|
|
19791
20868
|
} catch (e) {
|
|
19792
20869
|
this.fsw._emitReady();
|
|
19793
20870
|
return true;
|
|
@@ -19797,12 +20874,12 @@ var NodeFsHandler = class {
|
|
|
19797
20874
|
if (dir.has(item)) {
|
|
19798
20875
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
19799
20876
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
19800
|
-
this.fsw._emit(EV.CHANGE,
|
|
20877
|
+
this.fsw._emit(EV.CHANGE, path34, entry.stats);
|
|
19801
20878
|
}
|
|
19802
20879
|
} else {
|
|
19803
20880
|
dir.add(item);
|
|
19804
20881
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
19805
|
-
this.fsw._emit(EV.ADD,
|
|
20882
|
+
this.fsw._emit(EV.ADD, path34, entry.stats);
|
|
19806
20883
|
}
|
|
19807
20884
|
this.fsw._emitReady();
|
|
19808
20885
|
return true;
|
|
@@ -19832,9 +20909,9 @@ var NodeFsHandler = class {
|
|
|
19832
20909
|
return;
|
|
19833
20910
|
}
|
|
19834
20911
|
const item = entry.path;
|
|
19835
|
-
let
|
|
20912
|
+
let path34 = sp.join(directory, item);
|
|
19836
20913
|
current.add(item);
|
|
19837
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
20914
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path34, item)) {
|
|
19838
20915
|
return;
|
|
19839
20916
|
}
|
|
19840
20917
|
if (this.fsw.closed) {
|
|
@@ -19843,11 +20920,11 @@ var NodeFsHandler = class {
|
|
|
19843
20920
|
}
|
|
19844
20921
|
if (item === target || !target && !previous.has(item)) {
|
|
19845
20922
|
this.fsw._incrReadyCount();
|
|
19846
|
-
|
|
19847
|
-
this._addToNodeFs(
|
|
20923
|
+
path34 = sp.join(dir, sp.relative(dir, path34));
|
|
20924
|
+
this._addToNodeFs(path34, initialAdd, wh, depth + 1);
|
|
19848
20925
|
}
|
|
19849
20926
|
}).on(EV.ERROR, this._boundHandleError);
|
|
19850
|
-
return new Promise((
|
|
20927
|
+
return new Promise((resolve21, reject) => {
|
|
19851
20928
|
if (!stream)
|
|
19852
20929
|
return reject();
|
|
19853
20930
|
stream.once(STR_END, () => {
|
|
@@ -19856,7 +20933,7 @@ var NodeFsHandler = class {
|
|
|
19856
20933
|
return;
|
|
19857
20934
|
}
|
|
19858
20935
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
19859
|
-
|
|
20936
|
+
resolve21(void 0);
|
|
19860
20937
|
previous.getChildren().filter((item) => {
|
|
19861
20938
|
return item !== directory && !current.has(item);
|
|
19862
20939
|
}).forEach((item) => {
|
|
@@ -19913,13 +20990,13 @@ var NodeFsHandler = class {
|
|
|
19913
20990
|
* @param depth Child path actually targeted for watch
|
|
19914
20991
|
* @param target Child path actually targeted for watch
|
|
19915
20992
|
*/
|
|
19916
|
-
async _addToNodeFs(
|
|
20993
|
+
async _addToNodeFs(path34, initialAdd, priorWh, depth, target) {
|
|
19917
20994
|
const ready = this.fsw._emitReady;
|
|
19918
|
-
if (this.fsw._isIgnored(
|
|
20995
|
+
if (this.fsw._isIgnored(path34) || this.fsw.closed) {
|
|
19919
20996
|
ready();
|
|
19920
20997
|
return false;
|
|
19921
20998
|
}
|
|
19922
|
-
const wh = this.fsw._getWatchHelpers(
|
|
20999
|
+
const wh = this.fsw._getWatchHelpers(path34);
|
|
19923
21000
|
if (priorWh) {
|
|
19924
21001
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
19925
21002
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -19935,8 +21012,8 @@ var NodeFsHandler = class {
|
|
|
19935
21012
|
const follow = this.fsw.options.followSymlinks;
|
|
19936
21013
|
let closer;
|
|
19937
21014
|
if (stats.isDirectory()) {
|
|
19938
|
-
const absPath = sp.resolve(
|
|
19939
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
21015
|
+
const absPath = sp.resolve(path34);
|
|
21016
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path34) : path34;
|
|
19940
21017
|
if (this.fsw.closed)
|
|
19941
21018
|
return;
|
|
19942
21019
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -19946,29 +21023,29 @@ var NodeFsHandler = class {
|
|
|
19946
21023
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
19947
21024
|
}
|
|
19948
21025
|
} else if (stats.isSymbolicLink()) {
|
|
19949
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
21026
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path34) : path34;
|
|
19950
21027
|
if (this.fsw.closed)
|
|
19951
21028
|
return;
|
|
19952
21029
|
const parent = sp.dirname(wh.watchPath);
|
|
19953
21030
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
19954
21031
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
19955
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
21032
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path34, wh, targetPath);
|
|
19956
21033
|
if (this.fsw.closed)
|
|
19957
21034
|
return;
|
|
19958
21035
|
if (targetPath !== void 0) {
|
|
19959
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
21036
|
+
this.fsw._symlinkPaths.set(sp.resolve(path34), targetPath);
|
|
19960
21037
|
}
|
|
19961
21038
|
} else {
|
|
19962
21039
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
19963
21040
|
}
|
|
19964
21041
|
ready();
|
|
19965
21042
|
if (closer)
|
|
19966
|
-
this.fsw._addPathCloser(
|
|
21043
|
+
this.fsw._addPathCloser(path34, closer);
|
|
19967
21044
|
return false;
|
|
19968
21045
|
} catch (error) {
|
|
19969
21046
|
if (this.fsw._handleError(error)) {
|
|
19970
21047
|
ready();
|
|
19971
|
-
return
|
|
21048
|
+
return path34;
|
|
19972
21049
|
}
|
|
19973
21050
|
}
|
|
19974
21051
|
}
|
|
@@ -20011,24 +21088,24 @@ function createPattern(matcher) {
|
|
|
20011
21088
|
}
|
|
20012
21089
|
return () => false;
|
|
20013
21090
|
}
|
|
20014
|
-
function normalizePath3(
|
|
20015
|
-
if (typeof
|
|
21091
|
+
function normalizePath3(path34) {
|
|
21092
|
+
if (typeof path34 !== "string")
|
|
20016
21093
|
throw new Error("string expected");
|
|
20017
|
-
|
|
20018
|
-
|
|
21094
|
+
path34 = sp2.normalize(path34);
|
|
21095
|
+
path34 = path34.replace(/\\/g, "/");
|
|
20019
21096
|
let prepend = false;
|
|
20020
|
-
if (
|
|
21097
|
+
if (path34.startsWith("//"))
|
|
20021
21098
|
prepend = true;
|
|
20022
|
-
|
|
21099
|
+
path34 = path34.replace(DOUBLE_SLASH_RE, "/");
|
|
20023
21100
|
if (prepend)
|
|
20024
|
-
|
|
20025
|
-
return
|
|
21101
|
+
path34 = "/" + path34;
|
|
21102
|
+
return path34;
|
|
20026
21103
|
}
|
|
20027
21104
|
function matchPatterns(patterns, testString, stats) {
|
|
20028
|
-
const
|
|
21105
|
+
const path34 = normalizePath3(testString);
|
|
20029
21106
|
for (let index = 0; index < patterns.length; index++) {
|
|
20030
21107
|
const pattern = patterns[index];
|
|
20031
|
-
if (pattern(
|
|
21108
|
+
if (pattern(path34, stats)) {
|
|
20032
21109
|
return true;
|
|
20033
21110
|
}
|
|
20034
21111
|
}
|
|
@@ -20066,19 +21143,19 @@ var toUnix = (string) => {
|
|
|
20066
21143
|
}
|
|
20067
21144
|
return str;
|
|
20068
21145
|
};
|
|
20069
|
-
var normalizePathToUnix = (
|
|
20070
|
-
var normalizeIgnored = (cwd = "") => (
|
|
20071
|
-
if (typeof
|
|
20072
|
-
return normalizePathToUnix(sp2.isAbsolute(
|
|
21146
|
+
var normalizePathToUnix = (path34) => toUnix(sp2.normalize(toUnix(path34)));
|
|
21147
|
+
var normalizeIgnored = (cwd = "") => (path34) => {
|
|
21148
|
+
if (typeof path34 === "string") {
|
|
21149
|
+
return normalizePathToUnix(sp2.isAbsolute(path34) ? path34 : sp2.join(cwd, path34));
|
|
20073
21150
|
} else {
|
|
20074
|
-
return
|
|
21151
|
+
return path34;
|
|
20075
21152
|
}
|
|
20076
21153
|
};
|
|
20077
|
-
var getAbsolutePath = (
|
|
20078
|
-
if (sp2.isAbsolute(
|
|
20079
|
-
return
|
|
21154
|
+
var getAbsolutePath = (path34, cwd) => {
|
|
21155
|
+
if (sp2.isAbsolute(path34)) {
|
|
21156
|
+
return path34;
|
|
20080
21157
|
}
|
|
20081
|
-
return sp2.join(cwd,
|
|
21158
|
+
return sp2.join(cwd, path34);
|
|
20082
21159
|
};
|
|
20083
21160
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
20084
21161
|
var DirEntry = class {
|
|
@@ -20143,10 +21220,10 @@ var WatchHelper = class {
|
|
|
20143
21220
|
dirParts;
|
|
20144
21221
|
followSymlinks;
|
|
20145
21222
|
statMethod;
|
|
20146
|
-
constructor(
|
|
21223
|
+
constructor(path34, follow, fsw) {
|
|
20147
21224
|
this.fsw = fsw;
|
|
20148
|
-
const watchPath =
|
|
20149
|
-
this.path =
|
|
21225
|
+
const watchPath = path34;
|
|
21226
|
+
this.path = path34 = path34.replace(REPLACER_RE, "");
|
|
20150
21227
|
this.watchPath = watchPath;
|
|
20151
21228
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
20152
21229
|
this.dirParts = [];
|
|
@@ -20286,20 +21363,20 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
20286
21363
|
this._closePromise = void 0;
|
|
20287
21364
|
let paths = unifyPaths(paths_);
|
|
20288
21365
|
if (cwd) {
|
|
20289
|
-
paths = paths.map((
|
|
20290
|
-
const absPath = getAbsolutePath(
|
|
21366
|
+
paths = paths.map((path34) => {
|
|
21367
|
+
const absPath = getAbsolutePath(path34, cwd);
|
|
20291
21368
|
return absPath;
|
|
20292
21369
|
});
|
|
20293
21370
|
}
|
|
20294
|
-
paths.forEach((
|
|
20295
|
-
this._removeIgnoredPath(
|
|
21371
|
+
paths.forEach((path34) => {
|
|
21372
|
+
this._removeIgnoredPath(path34);
|
|
20296
21373
|
});
|
|
20297
21374
|
this._userIgnored = void 0;
|
|
20298
21375
|
if (!this._readyCount)
|
|
20299
21376
|
this._readyCount = 0;
|
|
20300
21377
|
this._readyCount += paths.length;
|
|
20301
|
-
Promise.all(paths.map(async (
|
|
20302
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
21378
|
+
Promise.all(paths.map(async (path34) => {
|
|
21379
|
+
const res = await this._nodeFsHandler._addToNodeFs(path34, !_internal, void 0, 0, _origAdd);
|
|
20303
21380
|
if (res)
|
|
20304
21381
|
this._emitReady();
|
|
20305
21382
|
return res;
|
|
@@ -20321,17 +21398,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
20321
21398
|
return this;
|
|
20322
21399
|
const paths = unifyPaths(paths_);
|
|
20323
21400
|
const { cwd } = this.options;
|
|
20324
|
-
paths.forEach((
|
|
20325
|
-
if (!sp2.isAbsolute(
|
|
21401
|
+
paths.forEach((path34) => {
|
|
21402
|
+
if (!sp2.isAbsolute(path34) && !this._closers.has(path34)) {
|
|
20326
21403
|
if (cwd)
|
|
20327
|
-
|
|
20328
|
-
|
|
21404
|
+
path34 = sp2.join(cwd, path34);
|
|
21405
|
+
path34 = sp2.resolve(path34);
|
|
20329
21406
|
}
|
|
20330
|
-
this._closePath(
|
|
20331
|
-
this._addIgnoredPath(
|
|
20332
|
-
if (this._watched.has(
|
|
21407
|
+
this._closePath(path34);
|
|
21408
|
+
this._addIgnoredPath(path34);
|
|
21409
|
+
if (this._watched.has(path34)) {
|
|
20333
21410
|
this._addIgnoredPath({
|
|
20334
|
-
path:
|
|
21411
|
+
path: path34,
|
|
20335
21412
|
recursive: true
|
|
20336
21413
|
});
|
|
20337
21414
|
}
|
|
@@ -20395,38 +21472,38 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
20395
21472
|
* @param stats arguments to be passed with event
|
|
20396
21473
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
20397
21474
|
*/
|
|
20398
|
-
async _emit(event,
|
|
21475
|
+
async _emit(event, path34, stats) {
|
|
20399
21476
|
if (this.closed)
|
|
20400
21477
|
return;
|
|
20401
21478
|
const opts = this.options;
|
|
20402
21479
|
if (isWindows)
|
|
20403
|
-
|
|
21480
|
+
path34 = sp2.normalize(path34);
|
|
20404
21481
|
if (opts.cwd)
|
|
20405
|
-
|
|
20406
|
-
const args = [
|
|
21482
|
+
path34 = sp2.relative(opts.cwd, path34);
|
|
21483
|
+
const args = [path34];
|
|
20407
21484
|
if (stats != null)
|
|
20408
21485
|
args.push(stats);
|
|
20409
21486
|
const awf = opts.awaitWriteFinish;
|
|
20410
21487
|
let pw;
|
|
20411
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
21488
|
+
if (awf && (pw = this._pendingWrites.get(path34))) {
|
|
20412
21489
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
20413
21490
|
return this;
|
|
20414
21491
|
}
|
|
20415
21492
|
if (opts.atomic) {
|
|
20416
21493
|
if (event === EVENTS.UNLINK) {
|
|
20417
|
-
this._pendingUnlinks.set(
|
|
21494
|
+
this._pendingUnlinks.set(path34, [event, ...args]);
|
|
20418
21495
|
setTimeout(() => {
|
|
20419
|
-
this._pendingUnlinks.forEach((entry,
|
|
21496
|
+
this._pendingUnlinks.forEach((entry, path35) => {
|
|
20420
21497
|
this.emit(...entry);
|
|
20421
21498
|
this.emit(EVENTS.ALL, ...entry);
|
|
20422
|
-
this._pendingUnlinks.delete(
|
|
21499
|
+
this._pendingUnlinks.delete(path35);
|
|
20423
21500
|
});
|
|
20424
21501
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
20425
21502
|
return this;
|
|
20426
21503
|
}
|
|
20427
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
21504
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path34)) {
|
|
20428
21505
|
event = EVENTS.CHANGE;
|
|
20429
|
-
this._pendingUnlinks.delete(
|
|
21506
|
+
this._pendingUnlinks.delete(path34);
|
|
20430
21507
|
}
|
|
20431
21508
|
}
|
|
20432
21509
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -20444,16 +21521,16 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
20444
21521
|
this.emitWithAll(event, args);
|
|
20445
21522
|
}
|
|
20446
21523
|
};
|
|
20447
|
-
this._awaitWriteFinish(
|
|
21524
|
+
this._awaitWriteFinish(path34, awf.stabilityThreshold, event, awfEmit);
|
|
20448
21525
|
return this;
|
|
20449
21526
|
}
|
|
20450
21527
|
if (event === EVENTS.CHANGE) {
|
|
20451
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
21528
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path34, 50);
|
|
20452
21529
|
if (isThrottled)
|
|
20453
21530
|
return this;
|
|
20454
21531
|
}
|
|
20455
21532
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
20456
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
21533
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path34) : path34;
|
|
20457
21534
|
let stats2;
|
|
20458
21535
|
try {
|
|
20459
21536
|
stats2 = await (0, import_promises3.stat)(fullPath);
|
|
@@ -20484,23 +21561,23 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
20484
21561
|
* @param timeout duration of time to suppress duplicate actions
|
|
20485
21562
|
* @returns tracking object or false if action should be suppressed
|
|
20486
21563
|
*/
|
|
20487
|
-
_throttle(actionType,
|
|
21564
|
+
_throttle(actionType, path34, timeout) {
|
|
20488
21565
|
if (!this._throttled.has(actionType)) {
|
|
20489
21566
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
20490
21567
|
}
|
|
20491
21568
|
const action = this._throttled.get(actionType);
|
|
20492
21569
|
if (!action)
|
|
20493
21570
|
throw new Error("invalid throttle");
|
|
20494
|
-
const actionPath = action.get(
|
|
21571
|
+
const actionPath = action.get(path34);
|
|
20495
21572
|
if (actionPath) {
|
|
20496
21573
|
actionPath.count++;
|
|
20497
21574
|
return false;
|
|
20498
21575
|
}
|
|
20499
21576
|
let timeoutObject;
|
|
20500
21577
|
const clear = () => {
|
|
20501
|
-
const item = action.get(
|
|
21578
|
+
const item = action.get(path34);
|
|
20502
21579
|
const count = item ? item.count : 0;
|
|
20503
|
-
action.delete(
|
|
21580
|
+
action.delete(path34);
|
|
20504
21581
|
clearTimeout(timeoutObject);
|
|
20505
21582
|
if (item)
|
|
20506
21583
|
clearTimeout(item.timeoutObject);
|
|
@@ -20508,7 +21585,7 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
20508
21585
|
};
|
|
20509
21586
|
timeoutObject = setTimeout(clear, timeout);
|
|
20510
21587
|
const thr = { timeoutObject, clear, count: 0 };
|
|
20511
|
-
action.set(
|
|
21588
|
+
action.set(path34, thr);
|
|
20512
21589
|
return thr;
|
|
20513
21590
|
}
|
|
20514
21591
|
_incrReadyCount() {
|
|
@@ -20522,44 +21599,44 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
20522
21599
|
* @param event
|
|
20523
21600
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
20524
21601
|
*/
|
|
20525
|
-
_awaitWriteFinish(
|
|
21602
|
+
_awaitWriteFinish(path34, threshold, event, awfEmit) {
|
|
20526
21603
|
const awf = this.options.awaitWriteFinish;
|
|
20527
21604
|
if (typeof awf !== "object")
|
|
20528
21605
|
return;
|
|
20529
21606
|
const pollInterval = awf.pollInterval;
|
|
20530
21607
|
let timeoutHandler;
|
|
20531
|
-
let fullPath =
|
|
20532
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
20533
|
-
fullPath = sp2.join(this.options.cwd,
|
|
21608
|
+
let fullPath = path34;
|
|
21609
|
+
if (this.options.cwd && !sp2.isAbsolute(path34)) {
|
|
21610
|
+
fullPath = sp2.join(this.options.cwd, path34);
|
|
20534
21611
|
}
|
|
20535
21612
|
const now2 = /* @__PURE__ */ new Date();
|
|
20536
21613
|
const writes = this._pendingWrites;
|
|
20537
21614
|
function awaitWriteFinishFn(prevStat) {
|
|
20538
|
-
(0,
|
|
20539
|
-
if (err || !writes.has(
|
|
21615
|
+
(0, import_node_fs3.stat)(fullPath, (err, curStat) => {
|
|
21616
|
+
if (err || !writes.has(path34)) {
|
|
20540
21617
|
if (err && err.code !== "ENOENT")
|
|
20541
21618
|
awfEmit(err);
|
|
20542
21619
|
return;
|
|
20543
21620
|
}
|
|
20544
21621
|
const now3 = Number(/* @__PURE__ */ new Date());
|
|
20545
21622
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
20546
|
-
writes.get(
|
|
21623
|
+
writes.get(path34).lastChange = now3;
|
|
20547
21624
|
}
|
|
20548
|
-
const pw = writes.get(
|
|
21625
|
+
const pw = writes.get(path34);
|
|
20549
21626
|
const df = now3 - pw.lastChange;
|
|
20550
21627
|
if (df >= threshold) {
|
|
20551
|
-
writes.delete(
|
|
21628
|
+
writes.delete(path34);
|
|
20552
21629
|
awfEmit(void 0, curStat);
|
|
20553
21630
|
} else {
|
|
20554
21631
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
20555
21632
|
}
|
|
20556
21633
|
});
|
|
20557
21634
|
}
|
|
20558
|
-
if (!writes.has(
|
|
20559
|
-
writes.set(
|
|
21635
|
+
if (!writes.has(path34)) {
|
|
21636
|
+
writes.set(path34, {
|
|
20560
21637
|
lastChange: now2,
|
|
20561
21638
|
cancelWait: () => {
|
|
20562
|
-
writes.delete(
|
|
21639
|
+
writes.delete(path34);
|
|
20563
21640
|
clearTimeout(timeoutHandler);
|
|
20564
21641
|
return event;
|
|
20565
21642
|
}
|
|
@@ -20570,8 +21647,8 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
20570
21647
|
/**
|
|
20571
21648
|
* Determines whether user has asked to ignore this path.
|
|
20572
21649
|
*/
|
|
20573
|
-
_isIgnored(
|
|
20574
|
-
if (this.options.atomic && DOT_RE.test(
|
|
21650
|
+
_isIgnored(path34, stats) {
|
|
21651
|
+
if (this.options.atomic && DOT_RE.test(path34))
|
|
20575
21652
|
return true;
|
|
20576
21653
|
if (!this._userIgnored) {
|
|
20577
21654
|
const { cwd } = this.options;
|
|
@@ -20581,17 +21658,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
20581
21658
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
20582
21659
|
this._userIgnored = anymatch(list, void 0);
|
|
20583
21660
|
}
|
|
20584
|
-
return this._userIgnored(
|
|
21661
|
+
return this._userIgnored(path34, stats);
|
|
20585
21662
|
}
|
|
20586
|
-
_isntIgnored(
|
|
20587
|
-
return !this._isIgnored(
|
|
21663
|
+
_isntIgnored(path34, stat5) {
|
|
21664
|
+
return !this._isIgnored(path34, stat5);
|
|
20588
21665
|
}
|
|
20589
21666
|
/**
|
|
20590
21667
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
20591
21668
|
* @param path file or directory pattern being watched
|
|
20592
21669
|
*/
|
|
20593
|
-
_getWatchHelpers(
|
|
20594
|
-
return new WatchHelper(
|
|
21670
|
+
_getWatchHelpers(path34) {
|
|
21671
|
+
return new WatchHelper(path34, this.options.followSymlinks, this);
|
|
20595
21672
|
}
|
|
20596
21673
|
// Directory helpers
|
|
20597
21674
|
// -----------------
|
|
@@ -20623,63 +21700,63 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
20623
21700
|
* @param item base path of item/directory
|
|
20624
21701
|
*/
|
|
20625
21702
|
_remove(directory, item, isDirectory) {
|
|
20626
|
-
const
|
|
20627
|
-
const fullPath = sp2.resolve(
|
|
20628
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
20629
|
-
if (!this._throttle("remove",
|
|
21703
|
+
const path34 = sp2.join(directory, item);
|
|
21704
|
+
const fullPath = sp2.resolve(path34);
|
|
21705
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path34) || this._watched.has(fullPath);
|
|
21706
|
+
if (!this._throttle("remove", path34, 100))
|
|
20630
21707
|
return;
|
|
20631
21708
|
if (!isDirectory && this._watched.size === 1) {
|
|
20632
21709
|
this.add(directory, item, true);
|
|
20633
21710
|
}
|
|
20634
|
-
const wp = this._getWatchedDir(
|
|
21711
|
+
const wp = this._getWatchedDir(path34);
|
|
20635
21712
|
const nestedDirectoryChildren = wp.getChildren();
|
|
20636
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
21713
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path34, nested));
|
|
20637
21714
|
const parent = this._getWatchedDir(directory);
|
|
20638
21715
|
const wasTracked = parent.has(item);
|
|
20639
21716
|
parent.remove(item);
|
|
20640
21717
|
if (this._symlinkPaths.has(fullPath)) {
|
|
20641
21718
|
this._symlinkPaths.delete(fullPath);
|
|
20642
21719
|
}
|
|
20643
|
-
let relPath =
|
|
21720
|
+
let relPath = path34;
|
|
20644
21721
|
if (this.options.cwd)
|
|
20645
|
-
relPath = sp2.relative(this.options.cwd,
|
|
21722
|
+
relPath = sp2.relative(this.options.cwd, path34);
|
|
20646
21723
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
20647
21724
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
20648
21725
|
if (event === EVENTS.ADD)
|
|
20649
21726
|
return;
|
|
20650
21727
|
}
|
|
20651
|
-
this._watched.delete(
|
|
21728
|
+
this._watched.delete(path34);
|
|
20652
21729
|
this._watched.delete(fullPath);
|
|
20653
21730
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
20654
|
-
if (wasTracked && !this._isIgnored(
|
|
20655
|
-
this._emit(eventName,
|
|
20656
|
-
this._closePath(
|
|
21731
|
+
if (wasTracked && !this._isIgnored(path34))
|
|
21732
|
+
this._emit(eventName, path34);
|
|
21733
|
+
this._closePath(path34);
|
|
20657
21734
|
}
|
|
20658
21735
|
/**
|
|
20659
21736
|
* Closes all watchers for a path
|
|
20660
21737
|
*/
|
|
20661
|
-
_closePath(
|
|
20662
|
-
this._closeFile(
|
|
20663
|
-
const dir = sp2.dirname(
|
|
20664
|
-
this._getWatchedDir(dir).remove(sp2.basename(
|
|
21738
|
+
_closePath(path34) {
|
|
21739
|
+
this._closeFile(path34);
|
|
21740
|
+
const dir = sp2.dirname(path34);
|
|
21741
|
+
this._getWatchedDir(dir).remove(sp2.basename(path34));
|
|
20665
21742
|
}
|
|
20666
21743
|
/**
|
|
20667
21744
|
* Closes only file-specific watchers
|
|
20668
21745
|
*/
|
|
20669
|
-
_closeFile(
|
|
20670
|
-
const closers = this._closers.get(
|
|
21746
|
+
_closeFile(path34) {
|
|
21747
|
+
const closers = this._closers.get(path34);
|
|
20671
21748
|
if (!closers)
|
|
20672
21749
|
return;
|
|
20673
21750
|
closers.forEach((closer) => closer());
|
|
20674
|
-
this._closers.delete(
|
|
21751
|
+
this._closers.delete(path34);
|
|
20675
21752
|
}
|
|
20676
|
-
_addPathCloser(
|
|
21753
|
+
_addPathCloser(path34, closer) {
|
|
20677
21754
|
if (!closer)
|
|
20678
21755
|
return;
|
|
20679
|
-
let list = this._closers.get(
|
|
21756
|
+
let list = this._closers.get(path34);
|
|
20680
21757
|
if (!list) {
|
|
20681
21758
|
list = [];
|
|
20682
|
-
this._closers.set(
|
|
21759
|
+
this._closers.set(path34, list);
|
|
20683
21760
|
}
|
|
20684
21761
|
list.push(closer);
|
|
20685
21762
|
}
|
|
@@ -20709,11 +21786,11 @@ function watch(paths, options = {}) {
|
|
|
20709
21786
|
var chokidar_default = { watch, FSWatcher };
|
|
20710
21787
|
|
|
20711
21788
|
// src/watcher/file-watcher.ts
|
|
20712
|
-
var
|
|
21789
|
+
var path29 = __toESM(require("path"), 1);
|
|
20713
21790
|
|
|
20714
21791
|
// src/watcher/native-recursive-watcher.ts
|
|
20715
|
-
var
|
|
20716
|
-
var
|
|
21792
|
+
var import_node_fs4 = require("fs");
|
|
21793
|
+
var path27 = __toESM(require("path"), 1);
|
|
20717
21794
|
var NativeRecursiveWatcher = class {
|
|
20718
21795
|
constructor(root, onChange, options = {}) {
|
|
20719
21796
|
this.root = root;
|
|
@@ -20761,26 +21838,26 @@ var NativeRecursiveWatcher = class {
|
|
|
20761
21838
|
toAbsolutePath(filename) {
|
|
20762
21839
|
if (filename == null) return null;
|
|
20763
21840
|
const normalizedFilename = typeof filename === "string" ? filename : filename.toString();
|
|
20764
|
-
const absolutePath =
|
|
20765
|
-
const relativePath =
|
|
20766
|
-
const outsideRoot = relativePath === ".." || relativePath.startsWith(`..${
|
|
21841
|
+
const absolutePath = path27.resolve(this.root, normalizedFilename);
|
|
21842
|
+
const relativePath = path27.relative(this.root, absolutePath);
|
|
21843
|
+
const outsideRoot = relativePath === ".." || relativePath.startsWith(`..${path27.sep}`) || path27.isAbsolute(relativePath);
|
|
20767
21844
|
return outsideRoot ? null : absolutePath;
|
|
20768
21845
|
}
|
|
20769
|
-
defaultWatchFactory = (root, listener, options) => (0,
|
|
21846
|
+
defaultWatchFactory = (root, listener, options) => (0, import_node_fs4.watch)(root, options, listener);
|
|
20770
21847
|
};
|
|
20771
21848
|
|
|
20772
21849
|
// src/watcher/snapshot.ts
|
|
20773
21850
|
var fsPromises4 = __toESM(require("fs/promises"), 1);
|
|
20774
|
-
var
|
|
21851
|
+
var path28 = __toESM(require("path"), 1);
|
|
20775
21852
|
async function buildFileSnapshotScan(projectRoot, config, configPaths = []) {
|
|
20776
|
-
const normalizedProjectRoot =
|
|
21853
|
+
const normalizedProjectRoot = path28.resolve(projectRoot);
|
|
20777
21854
|
const ignoreFilter = createIgnoreFilter(normalizedProjectRoot);
|
|
20778
21855
|
const includePatterns = [...config.include, ...config.additionalInclude ?? []];
|
|
20779
21856
|
const maxDepth = config.indexing?.maxDepth ?? -1;
|
|
20780
21857
|
const snapshot = /* @__PURE__ */ new Map();
|
|
20781
21858
|
const unreadablePrefixes = /* @__PURE__ */ new Set();
|
|
20782
21859
|
const includeFile = async (filePath) => {
|
|
20783
|
-
const normalizedPath3 =
|
|
21860
|
+
const normalizedPath3 = path28.resolve(filePath);
|
|
20784
21861
|
if (!shouldIncludeFile(normalizedPath3, normalizedProjectRoot, includePatterns, config.exclude, ignoreFilter)) return;
|
|
20785
21862
|
const stat5 = await readStatIfFile(normalizedPath3, unreadablePrefixes);
|
|
20786
21863
|
if (stat5) snapshot.set(normalizedPath3, { size: stat5.size, mtimeMs: stat5.mtimeMs });
|
|
@@ -20792,16 +21869,16 @@ async function buildFileSnapshotScan(projectRoot, config, configPaths = []) {
|
|
|
20792
21869
|
} catch (error) {
|
|
20793
21870
|
if (isMissingFsError(error)) return;
|
|
20794
21871
|
if (isPermissionFsError(error)) {
|
|
20795
|
-
unreadablePrefixes.add(
|
|
21872
|
+
unreadablePrefixes.add(path28.resolve(directoryPath));
|
|
20796
21873
|
return;
|
|
20797
21874
|
}
|
|
20798
21875
|
throw error;
|
|
20799
21876
|
}
|
|
20800
21877
|
for (const entry of entries) {
|
|
20801
|
-
const fullPath =
|
|
20802
|
-
const relativePath =
|
|
21878
|
+
const fullPath = path28.join(directoryPath, entry.name);
|
|
21879
|
+
const relativePath = path28.relative(normalizedProjectRoot, fullPath);
|
|
20803
21880
|
if (entry.isDirectory()) {
|
|
20804
|
-
if (hasFilteredPathSegment(relativePath,
|
|
21881
|
+
if (hasFilteredPathSegment(relativePath, path28.sep) || isRestrictedDirectory(relativePath, path28.sep)) continue;
|
|
20805
21882
|
if (ignoreFilter.ignores(relativePath)) continue;
|
|
20806
21883
|
if (maxDepth === -1 || depth < maxDepth) await walk(fullPath, depth + 1);
|
|
20807
21884
|
} else if (entry.isFile()) {
|
|
@@ -20814,19 +21891,19 @@ async function buildFileSnapshotScan(projectRoot, config, configPaths = []) {
|
|
|
20814
21891
|
return { entries: snapshot, unreadablePrefixes };
|
|
20815
21892
|
}
|
|
20816
21893
|
async function buildFileSnapshotForPathScan(projectRoot, config, configPaths, targetPath) {
|
|
20817
|
-
const normalizedProjectRoot =
|
|
20818
|
-
const normalizedTargetPath =
|
|
21894
|
+
const normalizedProjectRoot = path28.resolve(projectRoot);
|
|
21895
|
+
const normalizedTargetPath = path28.resolve(targetPath);
|
|
20819
21896
|
if (!isWithinPath(normalizedProjectRoot, normalizedTargetPath)) {
|
|
20820
21897
|
return { entries: /* @__PURE__ */ new Map(), unreadablePrefixes: /* @__PURE__ */ new Set() };
|
|
20821
21898
|
}
|
|
20822
21899
|
const ignoreFilter = createIgnoreFilter(normalizedProjectRoot);
|
|
20823
21900
|
const includePatterns = [...config.include, ...config.additionalInclude ?? []];
|
|
20824
21901
|
const maxDepth = config.indexing?.maxDepth ?? -1;
|
|
20825
|
-
const explicitConfigPaths = new Set(configPaths.map((configPath) =>
|
|
21902
|
+
const explicitConfigPaths = new Set(configPaths.map((configPath) => path28.resolve(configPath)));
|
|
20826
21903
|
const snapshot = /* @__PURE__ */ new Map();
|
|
20827
21904
|
const unreadablePrefixes = /* @__PURE__ */ new Set();
|
|
20828
21905
|
const includeFile = async (filePath) => {
|
|
20829
|
-
const normalizedPath3 =
|
|
21906
|
+
const normalizedPath3 = path28.resolve(filePath);
|
|
20830
21907
|
if (!explicitConfigPaths.has(normalizedPath3) && !shouldIncludeFile(
|
|
20831
21908
|
normalizedPath3,
|
|
20832
21909
|
normalizedProjectRoot,
|
|
@@ -20844,16 +21921,16 @@ async function buildFileSnapshotForPathScan(projectRoot, config, configPaths, ta
|
|
|
20844
21921
|
} catch (error) {
|
|
20845
21922
|
if (isMissingFsError(error)) return;
|
|
20846
21923
|
if (isPermissionFsError(error)) {
|
|
20847
|
-
unreadablePrefixes.add(
|
|
21924
|
+
unreadablePrefixes.add(path28.resolve(directoryPath));
|
|
20848
21925
|
return;
|
|
20849
21926
|
}
|
|
20850
21927
|
throw error;
|
|
20851
21928
|
}
|
|
20852
21929
|
for (const entry of entries) {
|
|
20853
|
-
const fullPath =
|
|
20854
|
-
const relativePath =
|
|
21930
|
+
const fullPath = path28.join(directoryPath, entry.name);
|
|
21931
|
+
const relativePath = path28.relative(normalizedProjectRoot, fullPath);
|
|
20855
21932
|
if (entry.isDirectory()) {
|
|
20856
|
-
if (hasFilteredPathSegment(relativePath,
|
|
21933
|
+
if (hasFilteredPathSegment(relativePath, path28.sep) || isRestrictedDirectory(relativePath, path28.sep)) continue;
|
|
20857
21934
|
if (ignoreFilter.ignores(relativePath)) continue;
|
|
20858
21935
|
if (maxDepth === -1 || depth < maxDepth) await walk(fullPath, depth + 1);
|
|
20859
21936
|
} else if (entry.isFile()) {
|
|
@@ -20877,7 +21954,7 @@ function completeFileSnapshot(previous, scan) {
|
|
|
20877
21954
|
return completed;
|
|
20878
21955
|
}
|
|
20879
21956
|
async function includeExplicitConfigPaths(snapshot, unreadablePrefixes, configPaths) {
|
|
20880
|
-
for (const configPath of [...new Set(configPaths.map((value) =>
|
|
21957
|
+
for (const configPath of [...new Set(configPaths.map((value) => path28.resolve(value)))]) {
|
|
20881
21958
|
if (snapshot.has(configPath)) continue;
|
|
20882
21959
|
const stat5 = await readStatIfFile(configPath, unreadablePrefixes);
|
|
20883
21960
|
if (stat5) snapshot.set(configPath, { size: stat5.size, mtimeMs: stat5.mtimeMs });
|
|
@@ -20887,12 +21964,12 @@ async function includeExplicitConfigPathsInPath(snapshot, unreadablePrefixes, co
|
|
|
20887
21964
|
await includeExplicitConfigPaths(
|
|
20888
21965
|
snapshot,
|
|
20889
21966
|
unreadablePrefixes,
|
|
20890
|
-
configPaths.filter((configPath) => isWithinPath(targetPath,
|
|
21967
|
+
configPaths.filter((configPath) => isWithinPath(targetPath, path28.resolve(configPath)))
|
|
20891
21968
|
);
|
|
20892
21969
|
}
|
|
20893
21970
|
function isWithinPath(parentPath, childPath) {
|
|
20894
|
-
const relativePath =
|
|
20895
|
-
return relativePath === "" || !relativePath.startsWith(`..${
|
|
21971
|
+
const relativePath = path28.relative(parentPath, childPath);
|
|
21972
|
+
return relativePath === "" || !relativePath.startsWith(`..${path28.sep}`) && relativePath !== ".." && !path28.isAbsolute(relativePath);
|
|
20896
21973
|
}
|
|
20897
21974
|
async function readStatIfFile(filePath, unreadablePrefixes) {
|
|
20898
21975
|
try {
|
|
@@ -20901,7 +21978,7 @@ async function readStatIfFile(filePath, unreadablePrefixes) {
|
|
|
20901
21978
|
} catch (error) {
|
|
20902
21979
|
if (isMissingFsError(error)) return null;
|
|
20903
21980
|
if (isPermissionFsError(error)) {
|
|
20904
|
-
unreadablePrefixes.add(
|
|
21981
|
+
unreadablePrefixes.add(path28.resolve(filePath));
|
|
20905
21982
|
return null;
|
|
20906
21983
|
}
|
|
20907
21984
|
throw error;
|
|
@@ -21038,8 +22115,8 @@ var FileWatcher = class {
|
|
|
21038
22115
|
this.createWatcher();
|
|
21039
22116
|
}
|
|
21040
22117
|
resetReady() {
|
|
21041
|
-
this.readyPromise = new Promise((
|
|
21042
|
-
this.resolveReady =
|
|
22118
|
+
this.readyPromise = new Promise((resolve21) => {
|
|
22119
|
+
this.resolveReady = resolve21;
|
|
21043
22120
|
});
|
|
21044
22121
|
this.startupReadySignals = 1;
|
|
21045
22122
|
}
|
|
@@ -21070,7 +22147,7 @@ var FileWatcher = class {
|
|
|
21070
22147
|
const resolvedWatchTargets = watchTargets ?? this.getFullChokidarWatchTargets();
|
|
21071
22148
|
const watcherOptions = {
|
|
21072
22149
|
ignored: (filePath) => {
|
|
21073
|
-
const relativePath =
|
|
22150
|
+
const relativePath = path29.relative(this.projectRoot, filePath);
|
|
21074
22151
|
if (!relativePath) return false;
|
|
21075
22152
|
if (this.isProjectConfigPathOrAncestor(relativePath)) {
|
|
21076
22153
|
return false;
|
|
@@ -21078,10 +22155,10 @@ var FileWatcher = class {
|
|
|
21078
22155
|
if (this.isOutsideProjectPath(relativePath)) {
|
|
21079
22156
|
return true;
|
|
21080
22157
|
}
|
|
21081
|
-
if (hasFilteredPathSegment(relativePath,
|
|
22158
|
+
if (hasFilteredPathSegment(relativePath, path29.sep)) {
|
|
21082
22159
|
return true;
|
|
21083
22160
|
}
|
|
21084
|
-
if (isRestrictedDirectory(relativePath,
|
|
22161
|
+
if (isRestrictedDirectory(relativePath, path29.sep)) {
|
|
21085
22162
|
return true;
|
|
21086
22163
|
}
|
|
21087
22164
|
if (ignoreFilter.ignores(relativePath)) {
|
|
@@ -21172,13 +22249,13 @@ var FileWatcher = class {
|
|
|
21172
22249
|
getExternalConfigWatchTargets() {
|
|
21173
22250
|
return [...new Set(
|
|
21174
22251
|
this.projectConfigPaths.filter((projectConfigPath) => {
|
|
21175
|
-
const relativeConfigPath =
|
|
22252
|
+
const relativeConfigPath = path29.relative(this.projectRoot, projectConfigPath);
|
|
21176
22253
|
return this.isOutsideProjectPath(relativeConfigPath);
|
|
21177
22254
|
}).map((projectConfigPath) => {
|
|
21178
22255
|
if ((0, import_fs19.existsSync)(projectConfigPath)) {
|
|
21179
22256
|
return projectConfigPath;
|
|
21180
22257
|
}
|
|
21181
|
-
return this.getNearestExistingDirectory(
|
|
22258
|
+
return this.getNearestExistingDirectory(path29.dirname(projectConfigPath));
|
|
21182
22259
|
})
|
|
21183
22260
|
)];
|
|
21184
22261
|
}
|
|
@@ -21240,7 +22317,7 @@ var FileWatcher = class {
|
|
|
21240
22317
|
}
|
|
21241
22318
|
scheduleNativeReconciliation(generation, filePath) {
|
|
21242
22319
|
if (!this.isCurrentNativeSetup(generation)) return;
|
|
21243
|
-
const requiresFullReconciliation = filePath ===
|
|
22320
|
+
const requiresFullReconciliation = filePath === path29.join(this.projectRoot, ".gitignore");
|
|
21244
22321
|
const invalidatedPath = requiresFullReconciliation ? null : filePath;
|
|
21245
22322
|
this.nativeInvalidatedPaths.set(invalidatedPath, invalidatedPath !== null);
|
|
21246
22323
|
if (this.nativeReconcileTimer) {
|
|
@@ -21335,23 +22412,23 @@ var FileWatcher = class {
|
|
|
21335
22412
|
this.scheduleFlush();
|
|
21336
22413
|
}
|
|
21337
22414
|
isProjectConfigPath(filePath) {
|
|
21338
|
-
const relativePath =
|
|
21339
|
-
const normalizedRelativePath =
|
|
22415
|
+
const relativePath = path29.relative(this.projectRoot, filePath);
|
|
22416
|
+
const normalizedRelativePath = path29.normalize(relativePath);
|
|
21340
22417
|
return this.getProjectConfigRelativePaths().some((configPath) => configPath === normalizedRelativePath);
|
|
21341
22418
|
}
|
|
21342
22419
|
isProjectConfigPathOrAncestor(relativePath) {
|
|
21343
|
-
const normalizedRelativePath =
|
|
22420
|
+
const normalizedRelativePath = path29.normalize(relativePath);
|
|
21344
22421
|
return this.getProjectConfigRelativePaths().some(
|
|
21345
|
-
(configPath) => configPath === normalizedRelativePath || configPath.startsWith(`${normalizedRelativePath}${
|
|
22422
|
+
(configPath) => configPath === normalizedRelativePath || configPath.startsWith(`${normalizedRelativePath}${path29.sep}`)
|
|
21346
22423
|
);
|
|
21347
22424
|
}
|
|
21348
22425
|
isOutsideProjectPath(relativePath) {
|
|
21349
|
-
return relativePath === ".." || relativePath.startsWith(`..${
|
|
22426
|
+
return relativePath === ".." || relativePath.startsWith(`..${path29.sep}`) || path29.isAbsolute(relativePath);
|
|
21350
22427
|
}
|
|
21351
22428
|
getNearestExistingDirectory(directoryPath) {
|
|
21352
22429
|
let candidate = directoryPath;
|
|
21353
22430
|
while (!(0, import_fs19.existsSync)(candidate)) {
|
|
21354
|
-
const parent =
|
|
22431
|
+
const parent = path29.dirname(candidate);
|
|
21355
22432
|
if (parent === candidate) break;
|
|
21356
22433
|
candidate = parent;
|
|
21357
22434
|
}
|
|
@@ -21359,7 +22436,7 @@ var FileWatcher = class {
|
|
|
21359
22436
|
}
|
|
21360
22437
|
getProjectConfigRelativePaths() {
|
|
21361
22438
|
return this.projectConfigPaths.map(
|
|
21362
|
-
(configPath) =>
|
|
22439
|
+
(configPath) => path29.normalize(path29.relative(this.projectRoot, configPath))
|
|
21363
22440
|
);
|
|
21364
22441
|
}
|
|
21365
22442
|
getConfigPathStates() {
|
|
@@ -21417,7 +22494,7 @@ var FileWatcher = class {
|
|
|
21417
22494
|
return;
|
|
21418
22495
|
}
|
|
21419
22496
|
const changes = Array.from(this.pendingChanges.entries()).map(
|
|
21420
|
-
([
|
|
22497
|
+
([path34, type]) => ({ path: path34, type })
|
|
21421
22498
|
);
|
|
21422
22499
|
this.pendingChanges.clear();
|
|
21423
22500
|
try {
|
|
@@ -21463,7 +22540,7 @@ var FileWatcher = class {
|
|
|
21463
22540
|
};
|
|
21464
22541
|
|
|
21465
22542
|
// src/watcher/git-head-watcher.ts
|
|
21466
|
-
var
|
|
22543
|
+
var path30 = __toESM(require("path"), 1);
|
|
21467
22544
|
var GitHeadWatcher = class {
|
|
21468
22545
|
watcher = null;
|
|
21469
22546
|
projectRoot;
|
|
@@ -21485,13 +22562,13 @@ var GitHeadWatcher = class {
|
|
|
21485
22562
|
this.readyPromise = Promise.resolve();
|
|
21486
22563
|
return;
|
|
21487
22564
|
}
|
|
21488
|
-
this.readyPromise = new Promise((
|
|
21489
|
-
this.resolveReady =
|
|
22565
|
+
this.readyPromise = new Promise((resolve21) => {
|
|
22566
|
+
this.resolveReady = resolve21;
|
|
21490
22567
|
});
|
|
21491
22568
|
this.onBranchChange = handler;
|
|
21492
22569
|
this.currentBranch = getCurrentBranch(this.projectRoot);
|
|
21493
22570
|
const headPath = getHeadPath(this.projectRoot);
|
|
21494
|
-
const refsPath =
|
|
22571
|
+
const refsPath = path30.join(this.projectRoot, ".git", "refs", "heads");
|
|
21495
22572
|
this.watcher = chokidar_default.watch([headPath, refsPath], {
|
|
21496
22573
|
persistent: true,
|
|
21497
22574
|
ignoreInitial: true,
|
|
@@ -21559,7 +22636,9 @@ var GitHeadWatcher = class {
|
|
|
21559
22636
|
function createWatcherWithIndexer(getIndexer, projectRoot, config, host, options = {}) {
|
|
21560
22637
|
const fileWatcher = new FileWatcher(projectRoot, config, host, options);
|
|
21561
22638
|
const configPaths = getConfigPaths(projectRoot, host, options);
|
|
21562
|
-
configureAutoIndex(projectRoot, host, parseConfig(config), getIndexer
|
|
22639
|
+
configureAutoIndex(projectRoot, host, parseConfig(config), getIndexer, {
|
|
22640
|
+
synchronizeBackgroundWorker: false
|
|
22641
|
+
});
|
|
21563
22642
|
let stopped = false;
|
|
21564
22643
|
const requestReindex = () => {
|
|
21565
22644
|
if (stopped) return;
|
|
@@ -21579,7 +22658,9 @@ function createWatcherWithIndexer(getIndexer, projectRoot, config, host, options
|
|
|
21579
22658
|
const parsedConfig = options.configPath ? parseConfig(loadConfigFile(options.configPath)) : void 0;
|
|
21580
22659
|
const refreshedConfig = refreshIndexerForDirectory(projectRoot, host, parsedConfig);
|
|
21581
22660
|
if (refreshedConfig) {
|
|
21582
|
-
configureAutoIndex(projectRoot, host, refreshedConfig, getIndexer
|
|
22661
|
+
configureAutoIndex(projectRoot, host, refreshedConfig, getIndexer, {
|
|
22662
|
+
synchronizeBackgroundWorker: false
|
|
22663
|
+
});
|
|
21583
22664
|
}
|
|
21584
22665
|
}
|
|
21585
22666
|
requestReindex();
|
|
@@ -21627,7 +22708,7 @@ function getConfigPaths(projectRoot, host, options) {
|
|
|
21627
22708
|
|
|
21628
22709
|
// src/tools/visualize/activity.ts
|
|
21629
22710
|
var import_child_process5 = require("child_process");
|
|
21630
|
-
var
|
|
22711
|
+
var path31 = __toESM(require("path"), 1);
|
|
21631
22712
|
function attachRecentActivity(data, projectRoot) {
|
|
21632
22713
|
const activity = readGitActivity(projectRoot);
|
|
21633
22714
|
const changes = activity.size > 0 ? buildGitChanges(data, activity, projectRoot) : buildGraphChanges(data);
|
|
@@ -21789,7 +22870,7 @@ function normalizePath4(filePath) {
|
|
|
21789
22870
|
return filePath.replace(/\\/g, "/");
|
|
21790
22871
|
}
|
|
21791
22872
|
function toGitRelativePath(projectRoot, filePath) {
|
|
21792
|
-
const relativePath =
|
|
22873
|
+
const relativePath = path31.isAbsolute(filePath) ? path31.relative(projectRoot, filePath) : filePath;
|
|
21793
22874
|
return normalizePath4(relativePath);
|
|
21794
22875
|
}
|
|
21795
22876
|
|
|
@@ -22047,7 +23128,7 @@ render();
|
|
|
22047
23128
|
}
|
|
22048
23129
|
|
|
22049
23130
|
// src/tools/visualize/transform.ts
|
|
22050
|
-
var
|
|
23131
|
+
var path32 = __toESM(require("path"), 1);
|
|
22051
23132
|
|
|
22052
23133
|
// src/tools/visualize/modules.ts
|
|
22053
23134
|
var MAX_MODULES = 18;
|
|
@@ -22307,7 +23388,7 @@ function transformForVisualization(symbols, edges, options = {}) {
|
|
|
22307
23388
|
filePath: s.filePath,
|
|
22308
23389
|
kind: s.kind,
|
|
22309
23390
|
line: s.startLine,
|
|
22310
|
-
directory:
|
|
23391
|
+
directory: path32.dirname(s.filePath),
|
|
22311
23392
|
moduleId: "",
|
|
22312
23393
|
moduleLabel: ""
|
|
22313
23394
|
}));
|
|
@@ -22335,9 +23416,9 @@ function parseArgs(argv) {
|
|
|
22335
23416
|
let host = "opencode";
|
|
22336
23417
|
for (let i = 2; i < argv.length; i++) {
|
|
22337
23418
|
if (argv[i] === "--project" && argv[i + 1]) {
|
|
22338
|
-
project =
|
|
23419
|
+
project = path33.resolve(argv[++i]);
|
|
22339
23420
|
} else if (argv[i] === "--config" && argv[i + 1]) {
|
|
22340
|
-
config =
|
|
23421
|
+
config = path33.resolve(argv[++i]);
|
|
22341
23422
|
} else if (argv[i] === "--host" && argv[i + 1]) {
|
|
22342
23423
|
host = parseHostMode(argv[++i]);
|
|
22343
23424
|
} else if (argv[i] === "--host") {
|
|
@@ -22365,7 +23446,7 @@ function parseIndexArgs(argv, cwd) {
|
|
|
22365
23446
|
if (!arg.startsWith("--project=")) {
|
|
22366
23447
|
i += 1;
|
|
22367
23448
|
}
|
|
22368
|
-
project =
|
|
23449
|
+
project = path33.resolve(cwd, value);
|
|
22369
23450
|
continue;
|
|
22370
23451
|
}
|
|
22371
23452
|
if (arg === "--config" || arg.startsWith("--config=")) {
|
|
@@ -22376,7 +23457,7 @@ function parseIndexArgs(argv, cwd) {
|
|
|
22376
23457
|
if (!arg.startsWith("--config=")) {
|
|
22377
23458
|
i += 1;
|
|
22378
23459
|
}
|
|
22379
|
-
config =
|
|
23460
|
+
config = path33.resolve(cwd, value);
|
|
22380
23461
|
continue;
|
|
22381
23462
|
}
|
|
22382
23463
|
if (arg === "--host" || arg.startsWith("--host=")) {
|
|
@@ -22446,7 +23527,7 @@ function parseVisualizeArgs(argv, cwd) {
|
|
|
22446
23527
|
for (let i = 0; i < argv.length; i++) {
|
|
22447
23528
|
const arg = argv[i];
|
|
22448
23529
|
if (arg === "--project" && argv[i + 1]) {
|
|
22449
|
-
project =
|
|
23530
|
+
project = path33.resolve(argv[++i]);
|
|
22450
23531
|
} else if (arg === "--max" && argv[i + 1]) {
|
|
22451
23532
|
maxNodes = Number(argv[++i]);
|
|
22452
23533
|
} else if (arg.startsWith("--max=") || arg.startsWith("max=")) {
|
|
@@ -22483,7 +23564,7 @@ async function handleVisualizeCommand(argv, cwd) {
|
|
|
22483
23564
|
console.error("No connected symbols found. Retry with: npm run visualize -- orphans");
|
|
22484
23565
|
return 1;
|
|
22485
23566
|
}
|
|
22486
|
-
const outputPath =
|
|
23567
|
+
const outputPath = path33.join(os9.tmpdir(), `call-graph-${Date.now()}.html`);
|
|
22487
23568
|
(0, import_fs20.writeFileSync)(outputPath, generateVisualizationHtml(vizData), "utf-8");
|
|
22488
23569
|
console.log(`Temporal call graph visualization generated: ${outputPath}`);
|
|
22489
23570
|
console.log(`Nodes: ${vizData.nodes.length} | Edges: ${vizData.edges.length}`);
|
|
@@ -22515,7 +23596,6 @@ async function runMcpCli(argv) {
|
|
|
22515
23596
|
const config = parseConfig(rawConfig);
|
|
22516
23597
|
const server = createMcpServer(args.project, config, args.host);
|
|
22517
23598
|
const transport = new import_stdio.StdioServerTransport();
|
|
22518
|
-
let watcher = null;
|
|
22519
23599
|
let shutdownPromise;
|
|
22520
23600
|
const onServerClose = server.server.onclose;
|
|
22521
23601
|
const shutdown = () => {
|
|
@@ -22529,16 +23609,19 @@ async function runMcpCli(argv) {
|
|
|
22529
23609
|
shutdownPromise = (async () => {
|
|
22530
23610
|
let exitCode = 0;
|
|
22531
23611
|
try {
|
|
22532
|
-
await
|
|
22533
|
-
} catch (error) {
|
|
22534
|
-
exitCode = 1;
|
|
22535
|
-
console.error("Failed to stop MCP file watcher cleanly:", error);
|
|
22536
|
-
}
|
|
22537
|
-
try {
|
|
22538
|
-
await stopAutoIndex(args.project, args.host);
|
|
23612
|
+
await stopBackgroundWorker(args.project, args.host);
|
|
22539
23613
|
} catch (error) {
|
|
22540
23614
|
exitCode = 1;
|
|
22541
|
-
|
|
23615
|
+
if (error instanceof BackgroundWorkerStopError) {
|
|
23616
|
+
if (error.watcherError !== void 0) {
|
|
23617
|
+
console.error("Failed to stop MCP file watcher cleanly:", error.watcherError);
|
|
23618
|
+
}
|
|
23619
|
+
if (error.autoIndexError !== void 0) {
|
|
23620
|
+
console.error("Failed to stop automatic indexing cleanly:", error.autoIndexError);
|
|
23621
|
+
}
|
|
23622
|
+
} else {
|
|
23623
|
+
console.error("Failed to stop automatic indexing cleanly:", error);
|
|
23624
|
+
}
|
|
22542
23625
|
}
|
|
22543
23626
|
try {
|
|
22544
23627
|
await server.close();
|
|
@@ -22567,19 +23650,25 @@ async function runMcpCli(argv) {
|
|
|
22567
23650
|
process.once("SIGHUP", requestShutdown);
|
|
22568
23651
|
process.once("SIGTERM", requestShutdown);
|
|
22569
23652
|
}
|
|
22570
|
-
await server.connect(transport);
|
|
22571
|
-
if (shutdownPromise) return;
|
|
22572
23653
|
const isHomeDir = isHomeDirectory(args.project);
|
|
22573
23654
|
const isValidProject = !isHomeDir && (!config.indexing.requireProjectMarker || hasProjectMarker(args.project));
|
|
22574
|
-
|
|
22575
|
-
|
|
22576
|
-
|
|
22577
|
-
|
|
22578
|
-
|
|
22579
|
-
|
|
22580
|
-
|
|
22581
|
-
|
|
22582
|
-
|
|
23655
|
+
const watcherFactoryForConfig = (refreshedConfig) => refreshedConfig.indexing.watchFiles && !isHomeDirectory(args.project) && (!refreshedConfig.indexing.requireProjectMarker || hasProjectMarker(args.project)) ? () => createWatcherWithIndexer(
|
|
23656
|
+
() => getIndexerForProject(args.project, args.host),
|
|
23657
|
+
args.project,
|
|
23658
|
+
refreshedConfig,
|
|
23659
|
+
args.host,
|
|
23660
|
+
args.config ? { configPath: args.config } : {}
|
|
23661
|
+
) : null;
|
|
23662
|
+
await server.connect(transport);
|
|
23663
|
+
if (shutdownPromise) return;
|
|
23664
|
+
await attachMcpBackgroundWatcher(
|
|
23665
|
+
args.project,
|
|
23666
|
+
config,
|
|
23667
|
+
args.host,
|
|
23668
|
+
config.indexing.watchFiles && isValidProject ? watcherFactoryForConfig(config) : null,
|
|
23669
|
+
watcherFactoryForConfig
|
|
23670
|
+
);
|
|
23671
|
+
if (shutdownPromise) return;
|
|
22583
23672
|
}
|
|
22584
23673
|
function printIndexProgress(onProgress, title, metadata) {
|
|
22585
23674
|
const details = Object.entries(metadata).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${isSensitiveKey(key) ? "[REDACTED]" : String(value)}`).join(" ");
|