open-codebase-index 0.22.5 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/dist/cli.cjs +949 -479
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +950 -480
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +854 -395
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +855 -396
- package/dist/index.js.map +1 -1
- package/dist/pi-extension.cjs +6 -95
- package/dist/pi-extension.cjs.map +1 -1
- package/dist/pi-extension.js +6 -95
- 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 +3 -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(path33, 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(path33);
|
|
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 = (path33, originalPath, doThrow) => {
|
|
530
|
+
if (!isString(path33)) {
|
|
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 (!path33) {
|
|
537
537
|
return doThrow(`path must not be empty`, TypeError);
|
|
538
538
|
}
|
|
539
|
-
if (checkPath.isNotRelative(
|
|
539
|
+
if (checkPath.isNotRelative(path33)) {
|
|
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 = (path33) => REGEX_TEST_INVALID_PATH.test(path33);
|
|
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 path33 = originalPath && checkPath.convert(originalPath);
|
|
579
579
|
checkPath(
|
|
580
|
-
|
|
580
|
+
path33,
|
|
581
581
|
originalPath,
|
|
582
582
|
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
583
583
|
);
|
|
584
|
-
return this._t(
|
|
584
|
+
return this._t(path33, cache, checkUnignored, slices);
|
|
585
585
|
}
|
|
586
|
-
checkIgnore(
|
|
587
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
588
|
-
return this.test(
|
|
586
|
+
checkIgnore(path33) {
|
|
587
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path33)) {
|
|
588
|
+
return this.test(path33);
|
|
589
589
|
}
|
|
590
|
-
const slices =
|
|
590
|
+
const slices = path33.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(path33, false, MODE_CHECK_IGNORE);
|
|
604
604
|
}
|
|
605
|
-
_t(
|
|
606
|
-
if (
|
|
607
|
-
return cache[
|
|
605
|
+
_t(path33, cache, checkUnignored, slices) {
|
|
606
|
+
if (path33 in cache) {
|
|
607
|
+
return cache[path33];
|
|
608
608
|
}
|
|
609
609
|
if (!slices) {
|
|
610
|
-
slices =
|
|
610
|
+
slices = path33.split(SLASH2).filter(Boolean);
|
|
611
611
|
}
|
|
612
612
|
slices.pop();
|
|
613
613
|
if (!slices.length) {
|
|
614
|
-
return cache[
|
|
614
|
+
return cache[path33] = this._rules.test(path33, 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[path33] = parent.ignored ? parent : this._rules.test(path33, checkUnignored, MODE_IGNORE);
|
|
623
623
|
}
|
|
624
|
-
ignores(
|
|
625
|
-
return this._test(
|
|
624
|
+
ignores(path33) {
|
|
625
|
+
return this._test(path33, this._ignoreCache, false).ignored;
|
|
626
626
|
}
|
|
627
627
|
createFilter() {
|
|
628
|
-
return (
|
|
628
|
+
return (path33) => !this.ignores(path33);
|
|
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(path33) {
|
|
635
|
+
return this._test(path33, this._testCache, true);
|
|
636
636
|
}
|
|
637
637
|
};
|
|
638
638
|
var factory = (options) => new Ignore2(options);
|
|
639
|
-
var isPathValid = (
|
|
639
|
+
var isPathValid = (path33) => checkPath(path33 && checkPath.convert(path33), path33, 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 = (path33) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path33) || isNotRelative(path33);
|
|
645
645
|
};
|
|
646
646
|
if (
|
|
647
647
|
// Detect `process` so that it can run in browsers.
|
|
@@ -669,7 +669,7 @@ module.exports = __toCommonJS(cli_exports);
|
|
|
669
669
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
670
670
|
var import_fs20 = require("fs");
|
|
671
671
|
var os8 = __toESM(require("os"), 1);
|
|
672
|
-
var
|
|
672
|
+
var path32 = __toESM(require("path"), 1);
|
|
673
673
|
var import_url = require("url");
|
|
674
674
|
|
|
675
675
|
// src/config/constants.ts
|
|
@@ -1179,9 +1179,9 @@ var import_fs = require("fs");
|
|
|
1179
1179
|
var path = __toESM(require("path"), 1);
|
|
1180
1180
|
|
|
1181
1181
|
// src/eval/report-formatters.ts
|
|
1182
|
-
function assertFiniteNumber(value,
|
|
1182
|
+
function assertFiniteNumber(value, path33) {
|
|
1183
1183
|
if (typeof value !== "number" || Number.isNaN(value) || !Number.isFinite(value)) {
|
|
1184
|
-
throw new Error(`${
|
|
1184
|
+
throw new Error(`${path33} must be a finite number`);
|
|
1185
1185
|
}
|
|
1186
1186
|
return value;
|
|
1187
1187
|
}
|
|
@@ -1453,7 +1453,7 @@ function pTimeout(promise, options) {
|
|
|
1453
1453
|
} = options;
|
|
1454
1454
|
let timer;
|
|
1455
1455
|
let abortHandler;
|
|
1456
|
-
const wrappedPromise = new Promise((
|
|
1456
|
+
const wrappedPromise = new Promise((resolve20, reject) => {
|
|
1457
1457
|
if (typeof milliseconds !== "number" || Math.sign(milliseconds) !== 1) {
|
|
1458
1458
|
throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${milliseconds}\``);
|
|
1459
1459
|
}
|
|
@@ -1467,7 +1467,7 @@ function pTimeout(promise, options) {
|
|
|
1467
1467
|
};
|
|
1468
1468
|
signal.addEventListener("abort", abortHandler, { once: true });
|
|
1469
1469
|
}
|
|
1470
|
-
promise.then(
|
|
1470
|
+
promise.then(resolve20, reject);
|
|
1471
1471
|
if (milliseconds === Number.POSITIVE_INFINITY) {
|
|
1472
1472
|
return;
|
|
1473
1473
|
}
|
|
@@ -1475,7 +1475,7 @@ function pTimeout(promise, options) {
|
|
|
1475
1475
|
timer = customTimers.setTimeout.call(void 0, () => {
|
|
1476
1476
|
if (fallback) {
|
|
1477
1477
|
try {
|
|
1478
|
-
|
|
1478
|
+
resolve20(fallback());
|
|
1479
1479
|
} catch (error) {
|
|
1480
1480
|
reject(error);
|
|
1481
1481
|
}
|
|
@@ -1485,7 +1485,7 @@ function pTimeout(promise, options) {
|
|
|
1485
1485
|
promise.cancel();
|
|
1486
1486
|
}
|
|
1487
1487
|
if (message === false) {
|
|
1488
|
-
|
|
1488
|
+
resolve20();
|
|
1489
1489
|
} else if (message instanceof Error) {
|
|
1490
1490
|
reject(message);
|
|
1491
1491
|
} else {
|
|
@@ -1887,7 +1887,7 @@ var PQueue = class extends import_index.default {
|
|
|
1887
1887
|
// Assign unique ID if not provided
|
|
1888
1888
|
id: options.id ?? (this.#idAssigner++).toString()
|
|
1889
1889
|
};
|
|
1890
|
-
return new Promise((
|
|
1890
|
+
return new Promise((resolve20, reject) => {
|
|
1891
1891
|
const taskSymbol = /* @__PURE__ */ Symbol(`task-${options.id}`);
|
|
1892
1892
|
let cleanupQueueAbortHandler = () => void 0;
|
|
1893
1893
|
const run = async () => {
|
|
@@ -1927,7 +1927,7 @@ var PQueue = class extends import_index.default {
|
|
|
1927
1927
|
})]);
|
|
1928
1928
|
}
|
|
1929
1929
|
const result = await operation;
|
|
1930
|
-
|
|
1930
|
+
resolve20(result);
|
|
1931
1931
|
this.emit("completed", result);
|
|
1932
1932
|
} catch (error) {
|
|
1933
1933
|
reject(error);
|
|
@@ -2115,13 +2115,13 @@ var PQueue = class extends import_index.default {
|
|
|
2115
2115
|
});
|
|
2116
2116
|
}
|
|
2117
2117
|
async #onEvent(event, filter) {
|
|
2118
|
-
return new Promise((
|
|
2118
|
+
return new Promise((resolve20) => {
|
|
2119
2119
|
const listener = () => {
|
|
2120
2120
|
if (filter && !filter()) {
|
|
2121
2121
|
return;
|
|
2122
2122
|
}
|
|
2123
2123
|
this.off(event, listener);
|
|
2124
|
-
|
|
2124
|
+
resolve20();
|
|
2125
2125
|
};
|
|
2126
2126
|
this.on(event, listener);
|
|
2127
2127
|
});
|
|
@@ -2407,7 +2407,7 @@ async function onAttemptFailure({ error, attemptNumber, retriesConsumed, startTi
|
|
|
2407
2407
|
const finalDelay = Math.min(delayTime, remainingTime);
|
|
2408
2408
|
options.signal?.throwIfAborted();
|
|
2409
2409
|
if (finalDelay > 0) {
|
|
2410
|
-
await new Promise((
|
|
2410
|
+
await new Promise((resolve20, reject) => {
|
|
2411
2411
|
const onAbort = () => {
|
|
2412
2412
|
clearTimeout(timeoutToken);
|
|
2413
2413
|
options.signal?.removeEventListener("abort", onAbort);
|
|
@@ -2415,7 +2415,7 @@ async function onAttemptFailure({ error, attemptNumber, retriesConsumed, startTi
|
|
|
2415
2415
|
};
|
|
2416
2416
|
const timeoutToken = setTimeout(() => {
|
|
2417
2417
|
options.signal?.removeEventListener("abort", onAbort);
|
|
2418
|
-
|
|
2418
|
+
resolve20();
|
|
2419
2419
|
}, finalDelay);
|
|
2420
2420
|
if (options.unref) {
|
|
2421
2421
|
timeoutToken.unref?.();
|
|
@@ -3221,85 +3221,6 @@ function createEmbeddingProvider(configuredProviderInfo) {
|
|
|
3221
3221
|
}
|
|
3222
3222
|
}
|
|
3223
3223
|
|
|
3224
|
-
// src/rerank/index.ts
|
|
3225
|
-
function createReranker(config) {
|
|
3226
|
-
if (!config.enabled) {
|
|
3227
|
-
return new NoOpReranker();
|
|
3228
|
-
}
|
|
3229
|
-
return new SiliconFlowReranker(config);
|
|
3230
|
-
}
|
|
3231
|
-
var NoOpReranker = class {
|
|
3232
|
-
isAvailable() {
|
|
3233
|
-
return false;
|
|
3234
|
-
}
|
|
3235
|
-
async rerank(_query, documents, _topN) {
|
|
3236
|
-
return {
|
|
3237
|
-
results: documents.map((_, index) => ({ index, relevanceScore: 0 }))
|
|
3238
|
-
};
|
|
3239
|
-
}
|
|
3240
|
-
};
|
|
3241
|
-
var SiliconFlowReranker = class {
|
|
3242
|
-
config;
|
|
3243
|
-
constructor(config) {
|
|
3244
|
-
this.config = config;
|
|
3245
|
-
}
|
|
3246
|
-
isAvailable() {
|
|
3247
|
-
return this.config.enabled && !!this.config.baseUrl && !!this.config.model;
|
|
3248
|
-
}
|
|
3249
|
-
async rerank(query, documents, topN) {
|
|
3250
|
-
if (documents.length === 0) {
|
|
3251
|
-
return { results: [] };
|
|
3252
|
-
}
|
|
3253
|
-
const headers = {
|
|
3254
|
-
"Content-Type": "application/json"
|
|
3255
|
-
};
|
|
3256
|
-
if (this.config.apiKey) {
|
|
3257
|
-
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
3258
|
-
}
|
|
3259
|
-
const baseUrl = this.config.baseUrl;
|
|
3260
|
-
if (!baseUrl) {
|
|
3261
|
-
throw new Error("Reranker baseUrl is required. Configure reranker.baseUrl in your codebase-index.json.");
|
|
3262
|
-
}
|
|
3263
|
-
const timeoutMs = this.config.timeoutMs ?? 3e4;
|
|
3264
|
-
const controller = new AbortController();
|
|
3265
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
3266
|
-
try {
|
|
3267
|
-
const response = await fetch(`${baseUrl}/rerank`, {
|
|
3268
|
-
method: "POST",
|
|
3269
|
-
headers,
|
|
3270
|
-
body: JSON.stringify({
|
|
3271
|
-
model: this.config.model,
|
|
3272
|
-
query,
|
|
3273
|
-
documents,
|
|
3274
|
-
top_n: topN ?? this.config.topN ?? 20,
|
|
3275
|
-
return_documents: false
|
|
3276
|
-
}),
|
|
3277
|
-
signal: controller.signal
|
|
3278
|
-
});
|
|
3279
|
-
clearTimeout(timeout);
|
|
3280
|
-
if (!response.ok) {
|
|
3281
|
-
const errorText = await response.text();
|
|
3282
|
-
throw new Error(`Rerank API error: ${response.status} - ${errorText}`);
|
|
3283
|
-
}
|
|
3284
|
-
const data = await response.json();
|
|
3285
|
-
return {
|
|
3286
|
-
results: data.results.map((r) => ({
|
|
3287
|
-
index: r.index,
|
|
3288
|
-
relevanceScore: r.relevance_score,
|
|
3289
|
-
document: r.document?.text
|
|
3290
|
-
})),
|
|
3291
|
-
tokensUsed: data.meta?.tokens?.input_tokens
|
|
3292
|
-
};
|
|
3293
|
-
} catch (error) {
|
|
3294
|
-
clearTimeout(timeout);
|
|
3295
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
3296
|
-
throw new Error(`Rerank API request timed out after ${timeoutMs}ms`);
|
|
3297
|
-
}
|
|
3298
|
-
throw error;
|
|
3299
|
-
}
|
|
3300
|
-
}
|
|
3301
|
-
};
|
|
3302
|
-
|
|
3303
3224
|
// src/utils/files.ts
|
|
3304
3225
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
3305
3226
|
var import_fs3 = require("fs");
|
|
@@ -3461,8 +3382,8 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
|
|
|
3461
3382
|
if (entry.isDirectory()) {
|
|
3462
3383
|
subdirs.push({ fullPath, relativePath });
|
|
3463
3384
|
} else if (entry.isFile()) {
|
|
3464
|
-
const
|
|
3465
|
-
if (
|
|
3385
|
+
const stat5 = await import_fs3.promises.stat(fullPath);
|
|
3386
|
+
if (stat5.size > maxFileSize) {
|
|
3466
3387
|
skipped.push({ path: relativePath, reason: "too_large" });
|
|
3467
3388
|
continue;
|
|
3468
3389
|
}
|
|
@@ -3480,7 +3401,7 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
|
|
|
3480
3401
|
}
|
|
3481
3402
|
}
|
|
3482
3403
|
if (matched) {
|
|
3483
|
-
filesInDir.push({ path: fullPath, size:
|
|
3404
|
+
filesInDir.push({ path: fullPath, size: stat5.size });
|
|
3484
3405
|
}
|
|
3485
3406
|
}
|
|
3486
3407
|
}
|
|
@@ -3537,8 +3458,8 @@ async function collectFiles(projectRoot, includePatterns, excludePatterns, maxFi
|
|
|
3537
3458
|
}
|
|
3538
3459
|
for (const resolvedKbRoot of normalizedRoots) {
|
|
3539
3460
|
try {
|
|
3540
|
-
const
|
|
3541
|
-
if (!
|
|
3461
|
+
const stat5 = await import_fs3.promises.stat(resolvedKbRoot);
|
|
3462
|
+
if (!stat5.isDirectory()) {
|
|
3542
3463
|
skipped.push({ path: resolvedKbRoot, reason: "excluded" });
|
|
3543
3464
|
continue;
|
|
3544
3465
|
}
|
|
@@ -4865,11 +4786,11 @@ function resolveGitDir(repoRoot) {
|
|
|
4865
4786
|
return null;
|
|
4866
4787
|
}
|
|
4867
4788
|
try {
|
|
4868
|
-
const
|
|
4869
|
-
if (
|
|
4789
|
+
const stat5 = (0, import_fs5.statSync)(gitPath);
|
|
4790
|
+
if (stat5.isDirectory()) {
|
|
4870
4791
|
return gitPath;
|
|
4871
4792
|
}
|
|
4872
|
-
if (
|
|
4793
|
+
if (stat5.isFile()) {
|
|
4873
4794
|
const content = (0, import_fs5.readFileSync)(gitPath, "utf-8").trim();
|
|
4874
4795
|
const match = content.match(/^gitdir:\s*(.+)$/);
|
|
4875
4796
|
if (match) {
|
|
@@ -5374,8 +5295,8 @@ async function isWorktreeRegistered(projectRoot, worktreePath) {
|
|
|
5374
5295
|
return false;
|
|
5375
5296
|
}
|
|
5376
5297
|
function isPathWithinRoot(filePath, rootPath) {
|
|
5377
|
-
const
|
|
5378
|
-
return
|
|
5298
|
+
const relative14 = path9.relative(path9.resolve(rootPath), path9.resolve(filePath));
|
|
5299
|
+
return relative14 === "" || !relative14.startsWith(`..${path9.sep}`) && relative14 !== ".." && !path9.isAbsolute(relative14);
|
|
5379
5300
|
}
|
|
5380
5301
|
async function pruneExactMissingWorktreeRegistration(projectRoot, worktreePath) {
|
|
5381
5302
|
if (await pathExists(worktreePath)) return false;
|
|
@@ -5933,11 +5854,11 @@ function normalizeFiles(rawFiles, projectRoot) {
|
|
|
5933
5854
|
for (const raw of rawFiles) {
|
|
5934
5855
|
if (raw.length === 0) continue;
|
|
5935
5856
|
const absolute = path11.resolve(root, raw);
|
|
5936
|
-
const
|
|
5937
|
-
if (path11.isAbsolute(raw) ||
|
|
5857
|
+
const relative14 = path11.relative(root, absolute);
|
|
5858
|
+
if (path11.isAbsolute(raw) || relative14 === ".." || relative14.startsWith(`..${path11.sep}`) || path11.isAbsolute(relative14)) {
|
|
5938
5859
|
throw new Error(`Changed file escapes the project root: ${JSON.stringify(raw)}`);
|
|
5939
5860
|
}
|
|
5940
|
-
const cleaned =
|
|
5861
|
+
const cleaned = relative14.startsWith(`.${path11.sep}`) ? relative14.slice(2) : relative14;
|
|
5941
5862
|
if (!seen.has(cleaned)) {
|
|
5942
5863
|
seen.add(cleaned);
|
|
5943
5864
|
result.push(cleaned);
|
|
@@ -6274,7 +6195,7 @@ function analyzeQueryIntent(query) {
|
|
|
6274
6195
|
}
|
|
6275
6196
|
function isTestPath(filePath) {
|
|
6276
6197
|
const normalized = normalizePath(filePath);
|
|
6277
|
-
return /(?:^|\/)(?:test|tests|__tests__|spec|specs)(?:\/|$)/u.test(normalized) ||
|
|
6198
|
+
return /(?:^|\/)(?:test|tests|__tests__|spec|specs)(?:\/|$)/u.test(normalized) || /(?:\.(?:test|spec)|_(?:test|spec))\.[^/]+$/u.test(normalized) || /(?:^|\/)(?:test|spec)_[^/]+\.[^/]+$/u.test(normalized);
|
|
6278
6199
|
}
|
|
6279
6200
|
function isFixturePath(filePath) {
|
|
6280
6201
|
const normalized = normalizePath(filePath);
|
|
@@ -6681,7 +6602,8 @@ function rankHybridResults(query, semanticResults, keywordResults, options) {
|
|
|
6681
6602
|
return cached;
|
|
6682
6603
|
}
|
|
6683
6604
|
}
|
|
6684
|
-
const
|
|
6605
|
+
const overfetchFactor = prioritizeSourcePaths ? 12 : 4;
|
|
6606
|
+
const overfetchLimit = Math.max(options.limit * overfetchFactor, options.limit);
|
|
6685
6607
|
const fused = options.fusionStrategy === "rrf" ? fuseResultsRrf(semanticResults, keywordResults, options.rrfK, overfetchLimit) : fuseResultsWeighted(semanticResults, keywordResults, options.hybridWeight, overfetchLimit);
|
|
6686
6608
|
const rerankPoolLimit = Math.max(overfetchLimit, options.rerankTopN * 3, options.limit * 6);
|
|
6687
6609
|
const rerankPool = fused.slice(0, rerankPoolLimit);
|
|
@@ -8583,7 +8505,6 @@ var Indexer = class _Indexer {
|
|
|
8583
8505
|
database = null;
|
|
8584
8506
|
provider = null;
|
|
8585
8507
|
configuredProviderInfo = null;
|
|
8586
|
-
reranker = null;
|
|
8587
8508
|
fileHashCache = /* @__PURE__ */ new Map();
|
|
8588
8509
|
fileHashCachePath = "";
|
|
8589
8510
|
failedBatchesPath = "";
|
|
@@ -8743,7 +8664,6 @@ var Indexer = class _Indexer {
|
|
|
8743
8664
|
this.database = null;
|
|
8744
8665
|
this.provider = null;
|
|
8745
8666
|
this.configuredProviderInfo = null;
|
|
8746
|
-
this.reranker = null;
|
|
8747
8667
|
this.indexCompatibility = null;
|
|
8748
8668
|
this.initializationMode = "none";
|
|
8749
8669
|
this.readIssues = [];
|
|
@@ -9473,7 +9393,7 @@ var Indexer = class _Indexer {
|
|
|
9473
9393
|
await options.queue.onSizeLessThan(Math.max(1, options.providerRateLimits.concurrency));
|
|
9474
9394
|
const task = options.queue.add(async () => {
|
|
9475
9395
|
if (options.rateLimitState.backoffMs > 0) {
|
|
9476
|
-
await new Promise((
|
|
9396
|
+
await new Promise((resolve20) => setTimeout(resolve20, options.rateLimitState.backoffMs));
|
|
9477
9397
|
}
|
|
9478
9398
|
try {
|
|
9479
9399
|
const embeddingResult = await pRetry(
|
|
@@ -10040,15 +9960,6 @@ var Indexer = class _Indexer {
|
|
|
10040
9960
|
rerankerEnabled: this.config.reranker?.enabled ?? false
|
|
10041
9961
|
});
|
|
10042
9962
|
this.provider = createEmbeddingProvider(this.configuredProviderInfo);
|
|
10043
|
-
if (this.config.reranker?.enabled) {
|
|
10044
|
-
this.reranker = createReranker(this.config.reranker);
|
|
10045
|
-
if (this.reranker.isAvailable()) {
|
|
10046
|
-
this.logger.info("Reranker initialized", {
|
|
10047
|
-
model: this.config.reranker.model,
|
|
10048
|
-
baseUrl: this.config.reranker.baseUrl
|
|
10049
|
-
});
|
|
10050
|
-
}
|
|
10051
|
-
}
|
|
10052
9963
|
const dimensions = this.configuredProviderInfo.modelInfo.dimensions;
|
|
10053
9964
|
const storePath = path15.join(this.indexPath, "vectors");
|
|
10054
9965
|
const vectorMetadataPath = `${storePath}.meta.json`;
|
|
@@ -11453,6 +11364,7 @@ var Indexer = class _Indexer {
|
|
|
11453
11364
|
const filterByBranch = options?.filterByBranch ?? true;
|
|
11454
11365
|
const sourceIntent = options?.definitionIntent === true || classifyQueryIntentRaw(query) === "source";
|
|
11455
11366
|
const identifierHints = extractIdentifierHints(query);
|
|
11367
|
+
const candidateLimit = maxResults * (sourceIntent ? 12 : 4);
|
|
11456
11368
|
this.logger.search("debug", "Starting search", {
|
|
11457
11369
|
query,
|
|
11458
11370
|
maxResults,
|
|
@@ -11489,7 +11401,7 @@ var Indexer = class _Indexer {
|
|
|
11489
11401
|
const semanticCandidates = embedding ? this.searchSemanticCandidates(
|
|
11490
11402
|
store,
|
|
11491
11403
|
embedding,
|
|
11492
|
-
|
|
11404
|
+
candidateLimit,
|
|
11493
11405
|
branchChunkIds,
|
|
11494
11406
|
shouldPrefilterByBranch
|
|
11495
11407
|
) : [];
|
|
@@ -11497,7 +11409,7 @@ var Indexer = class _Indexer {
|
|
|
11497
11409
|
const keywordStartTime = import_perf_hooks.performance.now();
|
|
11498
11410
|
const keywordCandidates = await this.keywordSearch(
|
|
11499
11411
|
query,
|
|
11500
|
-
|
|
11412
|
+
candidateLimit,
|
|
11501
11413
|
store,
|
|
11502
11414
|
invertedIndex,
|
|
11503
11415
|
branchChunkIds,
|
|
@@ -12255,9 +12167,9 @@ var Indexer = class _Indexer {
|
|
|
12255
12167
|
this.requireReadableComponents(readIssues, "database");
|
|
12256
12168
|
let shortest = [];
|
|
12257
12169
|
for (const branchKey of this.getBranchCatalogKeys()) {
|
|
12258
|
-
const
|
|
12259
|
-
if (
|
|
12260
|
-
shortest =
|
|
12170
|
+
const path33 = database.findShortestPath(fromName, toName, branchKey, maxDepth);
|
|
12171
|
+
if (path33.length > 0 && (shortest.length === 0 || path33.length < shortest.length)) {
|
|
12172
|
+
shortest = path33;
|
|
12261
12173
|
}
|
|
12262
12174
|
}
|
|
12263
12175
|
return shortest.map((hop) => this.resolveFilePathRecord(hop));
|
|
@@ -12305,13 +12217,13 @@ var Indexer = class _Indexer {
|
|
|
12305
12217
|
}
|
|
12306
12218
|
}
|
|
12307
12219
|
if (!found) continue;
|
|
12308
|
-
const
|
|
12220
|
+
const path33 = [];
|
|
12309
12221
|
let currentSymbolId = toSymbolId;
|
|
12310
12222
|
while (true) {
|
|
12311
12223
|
const symbol = symbolsById.get(currentSymbolId);
|
|
12312
12224
|
if (!symbol) break;
|
|
12313
12225
|
const parent = parentBySymbolId.get(currentSymbolId);
|
|
12314
|
-
|
|
12226
|
+
path33.push({
|
|
12315
12227
|
symbolId: symbol.id,
|
|
12316
12228
|
symbolName: symbol.name,
|
|
12317
12229
|
filePath: symbol.filePath,
|
|
@@ -12321,9 +12233,9 @@ var Indexer = class _Indexer {
|
|
|
12321
12233
|
if (!parent) break;
|
|
12322
12234
|
currentSymbolId = parent.parentId;
|
|
12323
12235
|
}
|
|
12324
|
-
|
|
12325
|
-
if (
|
|
12326
|
-
shortest =
|
|
12236
|
+
path33.reverse();
|
|
12237
|
+
if (path33.length > 0 && (shortest.length === 0 || path33.length < shortest.length)) {
|
|
12238
|
+
shortest = path33;
|
|
12327
12239
|
}
|
|
12328
12240
|
}
|
|
12329
12241
|
return shortest.map((hop) => this.resolveFilePathRecord(hop));
|
|
@@ -12659,7 +12571,6 @@ var Indexer = class _Indexer {
|
|
|
12659
12571
|
this.store = null;
|
|
12660
12572
|
this.invertedIndex = null;
|
|
12661
12573
|
this.provider = null;
|
|
12662
|
-
this.reranker = null;
|
|
12663
12574
|
this.configuredProviderInfo = null;
|
|
12664
12575
|
this.indexCompatibility = null;
|
|
12665
12576
|
this.initializationMode = "none";
|
|
@@ -12973,8 +12884,8 @@ function formatExactSearchHandoff(results) {
|
|
|
12973
12884
|
}
|
|
12974
12885
|
function formatContextEvidence(result, index) {
|
|
12975
12886
|
const symbol = result.name ? ` ${JSON.stringify(compactEvidenceValue(result.name, 80))}` : "";
|
|
12976
|
-
const
|
|
12977
|
-
return `[${index}] ${result.chunkType}${symbol} in ${
|
|
12887
|
+
const path33 = compactEvidenceValue(result.filePath, 120);
|
|
12888
|
+
return `[${index}] ${result.chunkType}${symbol} in ${path33}:${result.startLine}-${result.endLine} (score ${result.score.toFixed(2)})`;
|
|
12978
12889
|
}
|
|
12979
12890
|
function formatContextPack(heading, selected, candidateCount, duplicateCount, limitOmittedCount, budgetOmittedCount, includeExactSearchHandoff) {
|
|
12980
12891
|
const lines = selected.map((result, index) => formatContextEvidence(result, index + 1));
|
|
@@ -13628,7 +13539,7 @@ function getErrorMessage4(error) {
|
|
|
13628
13539
|
return error instanceof Error ? error.message : String(error);
|
|
13629
13540
|
}
|
|
13630
13541
|
function runCommand(file, args, options) {
|
|
13631
|
-
return new Promise((
|
|
13542
|
+
return new Promise((resolve20, reject) => {
|
|
13632
13543
|
childProcess.execFile(
|
|
13633
13544
|
file,
|
|
13634
13545
|
args,
|
|
@@ -13638,7 +13549,7 @@ function runCommand(file, args, options) {
|
|
|
13638
13549
|
reject(error);
|
|
13639
13550
|
return;
|
|
13640
13551
|
}
|
|
13641
|
-
|
|
13552
|
+
resolve20(stdout);
|
|
13642
13553
|
}
|
|
13643
13554
|
);
|
|
13644
13555
|
});
|
|
@@ -13783,10 +13694,10 @@ function safeFailureMessage(error) {
|
|
|
13783
13694
|
}
|
|
13784
13695
|
function cancellableDelay(delayMs, signal) {
|
|
13785
13696
|
if (signal.aborted) return Promise.reject(new AutoIndexCancelledError());
|
|
13786
|
-
return new Promise((
|
|
13697
|
+
return new Promise((resolve20, reject) => {
|
|
13787
13698
|
const timer = setTimeout(() => {
|
|
13788
13699
|
signal.removeEventListener("abort", onAbort);
|
|
13789
|
-
|
|
13700
|
+
resolve20();
|
|
13790
13701
|
}, delayMs);
|
|
13791
13702
|
timer.unref?.();
|
|
13792
13703
|
const onAbort = () => {
|
|
@@ -13798,15 +13709,15 @@ function cancellableDelay(delayMs, signal) {
|
|
|
13798
13709
|
}
|
|
13799
13710
|
function withTimeout(promise, timeoutMs) {
|
|
13800
13711
|
if (timeoutMs <= 0) return Promise.resolve(void 0);
|
|
13801
|
-
return new Promise((
|
|
13802
|
-
const timer = setTimeout(() =>
|
|
13712
|
+
return new Promise((resolve20) => {
|
|
13713
|
+
const timer = setTimeout(() => resolve20(void 0), timeoutMs);
|
|
13803
13714
|
timer.unref?.();
|
|
13804
13715
|
void promise.then((value) => {
|
|
13805
13716
|
clearTimeout(timer);
|
|
13806
|
-
|
|
13717
|
+
resolve20(value);
|
|
13807
13718
|
}, () => {
|
|
13808
13719
|
clearTimeout(timer);
|
|
13809
|
-
|
|
13720
|
+
resolve20(void 0);
|
|
13810
13721
|
});
|
|
13811
13722
|
});
|
|
13812
13723
|
}
|
|
@@ -14188,17 +14099,17 @@ var AutoIndexCoordinator = class {
|
|
|
14188
14099
|
}
|
|
14189
14100
|
}
|
|
14190
14101
|
waitForBatteryRetry(delayMs) {
|
|
14191
|
-
return new Promise((
|
|
14102
|
+
return new Promise((resolve20) => {
|
|
14192
14103
|
const timer = setTimeout(() => {
|
|
14193
14104
|
if (this.batteryRetryTimer === timer) {
|
|
14194
14105
|
this.batteryRetryTimer = null;
|
|
14195
14106
|
this.resolveBatteryRetry = null;
|
|
14196
14107
|
}
|
|
14197
|
-
|
|
14108
|
+
resolve20();
|
|
14198
14109
|
}, delayMs);
|
|
14199
14110
|
timer.unref?.();
|
|
14200
14111
|
this.batteryRetryTimer = timer;
|
|
14201
|
-
this.resolveBatteryRetry =
|
|
14112
|
+
this.resolveBatteryRetry = resolve20;
|
|
14202
14113
|
});
|
|
14203
14114
|
}
|
|
14204
14115
|
cancelBatteryRetry() {
|
|
@@ -14206,9 +14117,9 @@ var AutoIndexCoordinator = class {
|
|
|
14206
14117
|
clearTimeout(this.batteryRetryTimer);
|
|
14207
14118
|
this.batteryRetryTimer = null;
|
|
14208
14119
|
}
|
|
14209
|
-
const
|
|
14120
|
+
const resolve20 = this.resolveBatteryRetry;
|
|
14210
14121
|
this.resolveBatteryRetry = null;
|
|
14211
|
-
|
|
14122
|
+
resolve20?.();
|
|
14212
14123
|
}
|
|
14213
14124
|
finishBatteryCheck(batteryCheck) {
|
|
14214
14125
|
if (this.batteryCheck !== batteryCheck) return;
|
|
@@ -14883,12 +14794,12 @@ async function getCallGraphPath(projectRoot, host, from, to, maxDepth, fromFileP
|
|
|
14883
14794
|
if (fromResolution.status !== "resolved" || toResolution.status !== "resolved") {
|
|
14884
14795
|
return { from: fromResolution, to: toResolution, path: [] };
|
|
14885
14796
|
}
|
|
14886
|
-
const
|
|
14797
|
+
const path33 = await indexer.findCallPathBySymbolIds(
|
|
14887
14798
|
fromResolution.symbolId,
|
|
14888
14799
|
toResolution.symbolId,
|
|
14889
14800
|
maxDepth
|
|
14890
14801
|
);
|
|
14891
|
-
return { from: fromResolution, to: toResolution, path:
|
|
14802
|
+
return { from: fromResolution, to: toResolution, path: path33 };
|
|
14892
14803
|
}
|
|
14893
14804
|
async function runIndexCodebase(projectRoot, host, args, onProgress) {
|
|
14894
14805
|
const root = getProjectRoot(projectRoot, host);
|
|
@@ -15513,7 +15424,7 @@ async function resolveCodebaseContextUnmeasured(projectRoot, host, input) {
|
|
|
15513
15424
|
const directory = input.directory ?? void 0;
|
|
15514
15425
|
const tokenBudget = input.tokenBudget ?? void 0;
|
|
15515
15426
|
if (from && to) {
|
|
15516
|
-
const
|
|
15427
|
+
const path33 = await getCallGraphPath(
|
|
15517
15428
|
projectRoot,
|
|
15518
15429
|
host,
|
|
15519
15430
|
from,
|
|
@@ -15522,25 +15433,25 @@ async function resolveCodebaseContextUnmeasured(projectRoot, host, input) {
|
|
|
15522
15433
|
fromFilePath,
|
|
15523
15434
|
toFilePath
|
|
15524
15435
|
);
|
|
15525
|
-
const pathText = formatCallGraphPathResult(
|
|
15526
|
-
if (
|
|
15436
|
+
const pathText = formatCallGraphPathResult(path33);
|
|
15437
|
+
if (path33.path.length > 0) {
|
|
15527
15438
|
const fitted2 = fitTextToContextBudget(
|
|
15528
15439
|
pathText,
|
|
15529
15440
|
tokenBudget
|
|
15530
15441
|
);
|
|
15531
15442
|
return {
|
|
15532
15443
|
text: fitted2.text,
|
|
15533
|
-
details: fittedDetails("path", fitted2,
|
|
15444
|
+
details: fittedDetails("path", fitted2, path33.path.length)
|
|
15534
15445
|
};
|
|
15535
15446
|
}
|
|
15536
|
-
if (
|
|
15447
|
+
if (path33.from.status !== "resolved" || path33.to.status !== "resolved") {
|
|
15537
15448
|
const fitted2 = fitTextToContextBudget(pathText, tokenBudget);
|
|
15538
15449
|
return {
|
|
15539
15450
|
text: fitted2.text,
|
|
15540
15451
|
details: fittedDetails("path", fitted2, 0)
|
|
15541
15452
|
};
|
|
15542
15453
|
}
|
|
15543
|
-
const resolvedFrom =
|
|
15454
|
+
const resolvedFrom = path33.from;
|
|
15544
15455
|
const { callers } = await getCallGraphData(projectRoot, host, {
|
|
15545
15456
|
name: to,
|
|
15546
15457
|
direction: "callers",
|
|
@@ -16017,9 +15928,9 @@ function getRelevantEvidence(query) {
|
|
|
16017
15928
|
});
|
|
16018
15929
|
}
|
|
16019
15930
|
if (query.expected.acceptableFiles) {
|
|
16020
|
-
for (const
|
|
15931
|
+
for (const path33 of query.expected.acceptableFiles) {
|
|
16021
15932
|
legacyEvidence.push({
|
|
16022
|
-
path:
|
|
15933
|
+
path: path33,
|
|
16023
15934
|
...query.expected.symbol !== void 0 ? { symbol: query.expected.symbol } : {},
|
|
16024
15935
|
relevance: 1
|
|
16025
15936
|
});
|
|
@@ -16516,68 +16427,68 @@ function isStringArray4(value) {
|
|
|
16516
16427
|
function isNonEmptyString(value) {
|
|
16517
16428
|
return typeof value === "string" && value.trim().length > 0;
|
|
16518
16429
|
}
|
|
16519
|
-
function asPositiveNumber(value,
|
|
16430
|
+
function asPositiveNumber(value, path33) {
|
|
16520
16431
|
if (typeof value !== "number" || Number.isNaN(value) || value < 0) {
|
|
16521
|
-
throw new Error(`${
|
|
16432
|
+
throw new Error(`${path33} must be a non-negative number`);
|
|
16522
16433
|
}
|
|
16523
16434
|
return value;
|
|
16524
16435
|
}
|
|
16525
|
-
function parseQueryType(value,
|
|
16436
|
+
function parseQueryType(value, path33) {
|
|
16526
16437
|
if (value === "definition" || value === "implementation-intent" || value === "similarity" || value === "keyword-heavy" || value === "conceptual") {
|
|
16527
16438
|
return value;
|
|
16528
16439
|
}
|
|
16529
16440
|
throw new Error(
|
|
16530
|
-
`${
|
|
16441
|
+
`${path33} must be one of: definition, implementation-intent, similarity, keyword-heavy, conceptual`
|
|
16531
16442
|
);
|
|
16532
16443
|
}
|
|
16533
|
-
function parseExpectedRoute(value,
|
|
16444
|
+
function parseExpectedRoute(value, path33) {
|
|
16534
16445
|
if (value === void 0) return void 0;
|
|
16535
16446
|
if (value === "search" || value === "definition") return value;
|
|
16536
|
-
throw new Error(`${
|
|
16447
|
+
throw new Error(`${path33} must be one of: search, definition`);
|
|
16537
16448
|
}
|
|
16538
|
-
function parseExpectedOutcome(value,
|
|
16449
|
+
function parseExpectedOutcome(value, path33) {
|
|
16539
16450
|
if (value === void 0) return void 0;
|
|
16540
16451
|
if (value === "results" || value === "no-results") {
|
|
16541
16452
|
return value;
|
|
16542
16453
|
}
|
|
16543
|
-
throw new Error(`${
|
|
16454
|
+
throw new Error(`${path33} must be one of: results, no-results`);
|
|
16544
16455
|
}
|
|
16545
|
-
function parseRecoveryExpectation(value,
|
|
16456
|
+
function parseRecoveryExpectation(value, path33) {
|
|
16546
16457
|
if (value === void 0) return void 0;
|
|
16547
16458
|
if (value === "none" || value === "filter-relaxed") {
|
|
16548
16459
|
return value;
|
|
16549
16460
|
}
|
|
16550
|
-
throw new Error(`${
|
|
16461
|
+
throw new Error(`${path33} must be one of: none, filter-relaxed`);
|
|
16551
16462
|
}
|
|
16552
|
-
function parseQueryDifficulty(value,
|
|
16463
|
+
function parseQueryDifficulty(value, path33) {
|
|
16553
16464
|
if (value === void 0) return void 0;
|
|
16554
16465
|
if (value === "easy" || value === "medium" || value === "hard") {
|
|
16555
16466
|
return value;
|
|
16556
16467
|
}
|
|
16557
|
-
throw new Error(`${
|
|
16468
|
+
throw new Error(`${path33} must be one of: easy, medium, hard`);
|
|
16558
16469
|
}
|
|
16559
|
-
function parseQueryTags(value,
|
|
16470
|
+
function parseQueryTags(value, path33) {
|
|
16560
16471
|
if (value === void 0) return void 0;
|
|
16561
16472
|
if (!isStringArray4(value) || value.some((tag) => tag.trim().length === 0)) {
|
|
16562
|
-
throw new Error(`${
|
|
16473
|
+
throw new Error(`${path33} must be an array of non-empty strings`);
|
|
16563
16474
|
}
|
|
16564
16475
|
if (value.length > 16) {
|
|
16565
|
-
throw new Error(`${
|
|
16476
|
+
throw new Error(`${path33} must contain at most 16 tags`);
|
|
16566
16477
|
}
|
|
16567
16478
|
return value;
|
|
16568
16479
|
}
|
|
16569
|
-
function parseQueryArgs(value,
|
|
16480
|
+
function parseQueryArgs(value, path33) {
|
|
16570
16481
|
if (value === void 0) return void 0;
|
|
16571
16482
|
if (!isRecord3(value)) {
|
|
16572
|
-
throw new Error(`${
|
|
16573
|
-
}
|
|
16574
|
-
const symbol = parseStringOrUndefined(value.symbol, `${
|
|
16575
|
-
const filePath = parseStringOrUndefined(value.filePath, `${
|
|
16576
|
-
const fileType = parseStringOrUndefined(value.fileType, `${
|
|
16577
|
-
const directory = parseStringOrUndefined(value.directory, `${
|
|
16578
|
-
const callerLimit = parsePositiveIntegerOrUndefined(value.callerLimit, `${
|
|
16579
|
-
const calleeLimit = parsePositiveIntegerOrUndefined(value.calleeLimit, `${
|
|
16580
|
-
const tokenBudget = parsePositiveIntegerOrUndefined(value.tokenBudget, `${
|
|
16483
|
+
throw new Error(`${path33} must be an object`);
|
|
16484
|
+
}
|
|
16485
|
+
const symbol = parseStringOrUndefined(value.symbol, `${path33}.symbol`);
|
|
16486
|
+
const filePath = parseStringOrUndefined(value.filePath, `${path33}.filePath`);
|
|
16487
|
+
const fileType = parseStringOrUndefined(value.fileType, `${path33}.fileType`);
|
|
16488
|
+
const directory = parseStringOrUndefined(value.directory, `${path33}.directory`);
|
|
16489
|
+
const callerLimit = parsePositiveIntegerOrUndefined(value.callerLimit, `${path33}.callerLimit`);
|
|
16490
|
+
const calleeLimit = parsePositiveIntegerOrUndefined(value.calleeLimit, `${path33}.calleeLimit`);
|
|
16491
|
+
const tokenBudget = parsePositiveIntegerOrUndefined(value.tokenBudget, `${path33}.tokenBudget`);
|
|
16581
16492
|
return {
|
|
16582
16493
|
...symbol !== void 0 ? { symbol } : {},
|
|
16583
16494
|
...filePath !== void 0 ? { filePath } : {},
|
|
@@ -16588,50 +16499,50 @@ function parseQueryArgs(value, path31) {
|
|
|
16588
16499
|
...tokenBudget !== void 0 ? { tokenBudget } : {}
|
|
16589
16500
|
};
|
|
16590
16501
|
}
|
|
16591
|
-
function parsePositiveIntegerOrUndefined(value,
|
|
16502
|
+
function parsePositiveIntegerOrUndefined(value, path33) {
|
|
16592
16503
|
if (value === void 0 || value === null) return void 0;
|
|
16593
16504
|
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
16594
|
-
throw new Error(`${
|
|
16505
|
+
throw new Error(`${path33} must be a positive integer`);
|
|
16595
16506
|
}
|
|
16596
16507
|
return value;
|
|
16597
16508
|
}
|
|
16598
16509
|
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-]+)*)?$/;
|
|
16599
|
-
function parseSemanticVersion(value,
|
|
16510
|
+
function parseSemanticVersion(value, path33) {
|
|
16600
16511
|
if (!isNonEmptyString(value)) {
|
|
16601
|
-
throw new Error(`${
|
|
16512
|
+
throw new Error(`${path33} must be a non-empty string`);
|
|
16602
16513
|
}
|
|
16603
16514
|
if (!SEMVER_VERSION_PATTERN.test(value)) {
|
|
16604
|
-
throw new Error(`${
|
|
16515
|
+
throw new Error(`${path33} must be a valid semantic version (MAJOR.MINOR.PATCH)`);
|
|
16605
16516
|
}
|
|
16606
16517
|
return value;
|
|
16607
16518
|
}
|
|
16608
|
-
function parseRetrievalMode(value,
|
|
16519
|
+
function parseRetrievalMode(value, path33) {
|
|
16609
16520
|
if (value === void 0 || value === "search") return "search";
|
|
16610
16521
|
if (value === "context" || value === "edit-context") return value;
|
|
16611
|
-
throw new Error(`${
|
|
16522
|
+
throw new Error(`${path33} must be one of: search, context, edit-context`);
|
|
16612
16523
|
}
|
|
16613
|
-
function parseStringOrUndefined(value,
|
|
16524
|
+
function parseStringOrUndefined(value, path33) {
|
|
16614
16525
|
if (value === void 0 || value === null) return void 0;
|
|
16615
16526
|
if (!isNonEmptyString(value)) {
|
|
16616
|
-
throw new Error(`${
|
|
16527
|
+
throw new Error(`${path33} must be a non-empty string`);
|
|
16617
16528
|
}
|
|
16618
16529
|
return value;
|
|
16619
16530
|
}
|
|
16620
|
-
function parseGradedEvidence(value,
|
|
16531
|
+
function parseGradedEvidence(value, path33) {
|
|
16621
16532
|
if (value === void 0) return [];
|
|
16622
16533
|
if (!Array.isArray(value)) {
|
|
16623
|
-
throw new Error(`${
|
|
16534
|
+
throw new Error(`${path33} must be an array`);
|
|
16624
16535
|
}
|
|
16625
16536
|
return value.map((entry, index) => {
|
|
16626
16537
|
if (!isRecord3(entry)) {
|
|
16627
|
-
throw new Error(`${
|
|
16538
|
+
throw new Error(`${path33}[${index}] must be an object`);
|
|
16628
16539
|
}
|
|
16629
|
-
const evidencePath = parseStringOrUndefined(entry.path, `${
|
|
16540
|
+
const evidencePath = parseStringOrUndefined(entry.path, `${path33}[${index}].path`);
|
|
16630
16541
|
if (evidencePath === void 0) {
|
|
16631
|
-
throw new Error(`${
|
|
16542
|
+
throw new Error(`${path33}[${index}].path is required`);
|
|
16632
16543
|
}
|
|
16633
|
-
const symbol = parseStringOrUndefined(entry.symbol, `${
|
|
16634
|
-
const relevance = parseEvidenceRelevance(entry.relevance, `${
|
|
16544
|
+
const symbol = parseStringOrUndefined(entry.symbol, `${path33}[${index}].symbol`);
|
|
16545
|
+
const relevance = parseEvidenceRelevance(entry.relevance, `${path33}[${index}].relevance`);
|
|
16635
16546
|
return {
|
|
16636
16547
|
path: evidencePath,
|
|
16637
16548
|
...symbol !== void 0 ? { symbol } : {},
|
|
@@ -16639,27 +16550,27 @@ function parseGradedEvidence(value, path31) {
|
|
|
16639
16550
|
};
|
|
16640
16551
|
});
|
|
16641
16552
|
}
|
|
16642
|
-
function parseEvidenceRelevance(value,
|
|
16553
|
+
function parseEvidenceRelevance(value, path33) {
|
|
16643
16554
|
if (value === void 0) {
|
|
16644
|
-
throw new Error(`${
|
|
16555
|
+
throw new Error(`${path33} is required`);
|
|
16645
16556
|
}
|
|
16646
16557
|
if (value !== 1 && value !== 2 && value !== 3) {
|
|
16647
|
-
throw new Error(`${
|
|
16558
|
+
throw new Error(`${path33} must be 1, 2, or 3`);
|
|
16648
16559
|
}
|
|
16649
16560
|
return value;
|
|
16650
16561
|
}
|
|
16651
|
-
function parseExpectedGraphNeighbor(value,
|
|
16562
|
+
function parseExpectedGraphNeighbor(value, path33) {
|
|
16652
16563
|
if (value === void 0) return void 0;
|
|
16653
16564
|
if (!isRecord3(value)) {
|
|
16654
|
-
throw new Error(`${
|
|
16565
|
+
throw new Error(`${path33} must be an object`);
|
|
16655
16566
|
}
|
|
16656
16567
|
if (value.direction !== "caller" && value.direction !== "callee") {
|
|
16657
|
-
throw new Error(`${
|
|
16568
|
+
throw new Error(`${path33}.direction must be one of: caller, callee`);
|
|
16658
16569
|
}
|
|
16659
|
-
const filePath = parseStringOrUndefined(value.filePath, `${
|
|
16660
|
-
const symbol = parseStringOrUndefined(value.symbol, `${
|
|
16570
|
+
const filePath = parseStringOrUndefined(value.filePath, `${path33}.filePath`);
|
|
16571
|
+
const symbol = parseStringOrUndefined(value.symbol, `${path33}.symbol`);
|
|
16661
16572
|
if (filePath === void 0 && symbol === void 0) {
|
|
16662
|
-
throw new Error(`${
|
|
16573
|
+
throw new Error(`${path33} must include filePath or symbol`);
|
|
16663
16574
|
}
|
|
16664
16575
|
return {
|
|
16665
16576
|
direction: value.direction,
|
|
@@ -16667,9 +16578,9 @@ function parseExpectedGraphNeighbor(value, path31) {
|
|
|
16667
16578
|
...symbol !== void 0 ? { symbol } : {}
|
|
16668
16579
|
};
|
|
16669
16580
|
}
|
|
16670
|
-
function parseExpected(input,
|
|
16581
|
+
function parseExpected(input, path33) {
|
|
16671
16582
|
if (!isRecord3(input)) {
|
|
16672
|
-
throw new Error(`${
|
|
16583
|
+
throw new Error(`${path33} must be an object`);
|
|
16673
16584
|
}
|
|
16674
16585
|
const filePathRaw = input.filePath;
|
|
16675
16586
|
const acceptableFilesRaw = input.acceptableFiles;
|
|
@@ -16680,29 +16591,29 @@ function parseExpected(input, path31) {
|
|
|
16680
16591
|
const recoveryExpectationRaw = input.recoveryExpectation;
|
|
16681
16592
|
const gradedEvidenceRaw = input.gradedEvidence;
|
|
16682
16593
|
const graphNeighborRaw = input.graphNeighbor;
|
|
16683
|
-
const filePath = parseStringOrUndefined(filePathRaw, `${
|
|
16594
|
+
const filePath = parseStringOrUndefined(filePathRaw, `${path33}.filePath`);
|
|
16684
16595
|
const acceptableFiles = isStringArray4(acceptableFilesRaw) ? acceptableFilesRaw : void 0;
|
|
16685
|
-
const gradedEvidence = parseGradedEvidence(gradedEvidenceRaw, `${
|
|
16686
|
-
const graphNeighbor = parseExpectedGraphNeighbor(graphNeighborRaw, `${
|
|
16687
|
-
const expectedOutcome = parseExpectedOutcome(expectedOutcomeRaw, `${
|
|
16596
|
+
const gradedEvidence = parseGradedEvidence(gradedEvidenceRaw, `${path33}.gradedEvidence`);
|
|
16597
|
+
const graphNeighbor = parseExpectedGraphNeighbor(graphNeighborRaw, `${path33}.graphNeighbor`);
|
|
16598
|
+
const expectedOutcome = parseExpectedOutcome(expectedOutcomeRaw, `${path33}.expectedOutcome`);
|
|
16688
16599
|
if (expectedOutcome !== "no-results" && !filePath && (!acceptableFiles || acceptableFiles.length === 0) && gradedEvidence.length === 0) {
|
|
16689
16600
|
throw new Error(
|
|
16690
|
-
`${
|
|
16601
|
+
`${path33} must include expected.filePath, expected.acceptableFiles, or expected.gradedEvidence`
|
|
16691
16602
|
);
|
|
16692
16603
|
}
|
|
16693
16604
|
if (acceptableFilesRaw !== void 0 && !isStringArray4(acceptableFilesRaw)) {
|
|
16694
|
-
throw new Error(`${
|
|
16605
|
+
throw new Error(`${path33}.acceptableFiles must be an array of strings`);
|
|
16695
16606
|
}
|
|
16696
16607
|
if (symbolRaw !== void 0 && typeof symbolRaw !== "string") {
|
|
16697
|
-
throw new Error(`${
|
|
16608
|
+
throw new Error(`${path33}.symbol must be a string when provided`);
|
|
16698
16609
|
}
|
|
16699
16610
|
if (branchRaw !== void 0 && typeof branchRaw !== "string") {
|
|
16700
|
-
throw new Error(`${
|
|
16611
|
+
throw new Error(`${path33}.branch must be a string when provided`);
|
|
16701
16612
|
}
|
|
16702
|
-
const expectedRoute = parseExpectedRoute(expectedRouteRaw, `${
|
|
16613
|
+
const expectedRoute = parseExpectedRoute(expectedRouteRaw, `${path33}.expectedRoute`);
|
|
16703
16614
|
const recoveryExpectation = parseRecoveryExpectation(
|
|
16704
16615
|
recoveryExpectationRaw,
|
|
16705
|
-
`${
|
|
16616
|
+
`${path33}.recoveryExpectation`
|
|
16706
16617
|
);
|
|
16707
16618
|
return {
|
|
16708
16619
|
filePath,
|
|
@@ -16716,13 +16627,13 @@ function parseExpected(input, path31) {
|
|
|
16716
16627
|
...graphNeighbor !== void 0 ? { graphNeighbor } : {}
|
|
16717
16628
|
};
|
|
16718
16629
|
}
|
|
16719
|
-
function parseQueryLanguage(value,
|
|
16720
|
-
return parseStringOrUndefined(value,
|
|
16630
|
+
function parseQueryLanguage(value, path33) {
|
|
16631
|
+
return parseStringOrUndefined(value, path33);
|
|
16721
16632
|
}
|
|
16722
16633
|
function parseQuery(input, index) {
|
|
16723
|
-
const
|
|
16634
|
+
const path33 = `queries[${index}]`;
|
|
16724
16635
|
if (!isRecord3(input)) {
|
|
16725
|
-
throw new Error(`${
|
|
16636
|
+
throw new Error(`${path33} must be an object`);
|
|
16726
16637
|
}
|
|
16727
16638
|
const id = input.id;
|
|
16728
16639
|
const query = input.query;
|
|
@@ -16734,21 +16645,21 @@ function parseQuery(input, index) {
|
|
|
16734
16645
|
const tags = input.tags;
|
|
16735
16646
|
const args = input.args;
|
|
16736
16647
|
if (typeof id !== "string" || id.trim().length === 0) {
|
|
16737
|
-
throw new Error(`${
|
|
16648
|
+
throw new Error(`${path33}.id must be a non-empty string`);
|
|
16738
16649
|
}
|
|
16739
16650
|
if (typeof query !== "string" || query.trim().length === 0) {
|
|
16740
|
-
throw new Error(`${
|
|
16651
|
+
throw new Error(`${path33}.query must be a non-empty string`);
|
|
16741
16652
|
}
|
|
16742
16653
|
return {
|
|
16743
16654
|
id,
|
|
16744
16655
|
query,
|
|
16745
|
-
queryType: parseQueryType(queryType, `${
|
|
16746
|
-
retrievalMode: parseRetrievalMode(retrievalMode, `${
|
|
16747
|
-
language: parseQueryLanguage(language, `${
|
|
16748
|
-
difficulty: parseQueryDifficulty(difficulty, `${
|
|
16749
|
-
args: parseQueryArgs(args, `${
|
|
16750
|
-
tags: parseQueryTags(tags, `${
|
|
16751
|
-
expected: parseExpected(expected, `${
|
|
16656
|
+
queryType: parseQueryType(queryType, `${path33}.queryType`),
|
|
16657
|
+
retrievalMode: parseRetrievalMode(retrievalMode, `${path33}.retrievalMode`),
|
|
16658
|
+
language: parseQueryLanguage(language, `${path33}.language`),
|
|
16659
|
+
difficulty: parseQueryDifficulty(difficulty, `${path33}.difficulty`),
|
|
16660
|
+
args: parseQueryArgs(args, `${path33}.args`),
|
|
16661
|
+
tags: parseQueryTags(tags, `${path33}.tags`),
|
|
16662
|
+
expected: parseExpected(expected, `${path33}.expected`)
|
|
16752
16663
|
};
|
|
16753
16664
|
}
|
|
16754
16665
|
function parseGoldenDataset(raw, sourceLabel) {
|
|
@@ -17715,7 +17626,7 @@ async function executeCallGraph(projectRoot, host, args) {
|
|
|
17715
17626
|
return { text: formatCallGraphResult(await getCallGraphData(projectRoot, host, args)) };
|
|
17716
17627
|
}
|
|
17717
17628
|
async function executeCallGraphPath(projectRoot, host, args) {
|
|
17718
|
-
const
|
|
17629
|
+
const path33 = await getCallGraphPath(
|
|
17719
17630
|
projectRoot,
|
|
17720
17631
|
host,
|
|
17721
17632
|
args.from,
|
|
@@ -17724,7 +17635,7 @@ async function executeCallGraphPath(projectRoot, host, args) {
|
|
|
17724
17635
|
args.fromFilePath,
|
|
17725
17636
|
args.toFilePath
|
|
17726
17637
|
);
|
|
17727
|
-
return { text: formatCallGraphPathResult(
|
|
17638
|
+
return { text: formatCallGraphPathResult(path33) };
|
|
17728
17639
|
}
|
|
17729
17640
|
async function executeCodeCommunities(projectRoot, host, args) {
|
|
17730
17641
|
const result = await getCodeCommunities(projectRoot, host, args);
|
|
@@ -18303,7 +18214,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
18303
18214
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
18304
18215
|
const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
|
|
18305
18216
|
if (wantBigintFsStats) {
|
|
18306
|
-
this._stat = (
|
|
18217
|
+
this._stat = (path33) => statMethod(path33, { bigint: true });
|
|
18307
18218
|
} else {
|
|
18308
18219
|
this._stat = statMethod;
|
|
18309
18220
|
}
|
|
@@ -18328,8 +18239,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
18328
18239
|
const par = this.parent;
|
|
18329
18240
|
const fil = par && par.files;
|
|
18330
18241
|
if (fil && fil.length > 0) {
|
|
18331
|
-
const { path:
|
|
18332
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
18242
|
+
const { path: path33, depth } = par;
|
|
18243
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path33));
|
|
18333
18244
|
const awaited = await Promise.all(slice);
|
|
18334
18245
|
for (const entry of awaited) {
|
|
18335
18246
|
if (!entry)
|
|
@@ -18369,20 +18280,20 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
18369
18280
|
this.reading = false;
|
|
18370
18281
|
}
|
|
18371
18282
|
}
|
|
18372
|
-
async _exploreDir(
|
|
18283
|
+
async _exploreDir(path33, depth) {
|
|
18373
18284
|
let files;
|
|
18374
18285
|
try {
|
|
18375
|
-
files = await (0, import_promises.readdir)(
|
|
18286
|
+
files = await (0, import_promises.readdir)(path33, this._rdOptions);
|
|
18376
18287
|
} catch (error) {
|
|
18377
18288
|
this._onError(error);
|
|
18378
18289
|
}
|
|
18379
|
-
return { files, depth, path:
|
|
18290
|
+
return { files, depth, path: path33 };
|
|
18380
18291
|
}
|
|
18381
|
-
async _formatEntry(dirent,
|
|
18292
|
+
async _formatEntry(dirent, path33) {
|
|
18382
18293
|
let entry;
|
|
18383
18294
|
const basename8 = this._isDirent ? dirent.name : dirent;
|
|
18384
18295
|
try {
|
|
18385
|
-
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(
|
|
18296
|
+
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path33, basename8));
|
|
18386
18297
|
entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename8 };
|
|
18387
18298
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
18388
18299
|
} catch (err) {
|
|
@@ -18782,16 +18693,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
18782
18693
|
};
|
|
18783
18694
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
18784
18695
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
18785
|
-
function createFsWatchInstance(
|
|
18696
|
+
function createFsWatchInstance(path33, options, listener, errHandler, emitRaw) {
|
|
18786
18697
|
const handleEvent = (rawEvent, evPath) => {
|
|
18787
|
-
listener(
|
|
18788
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
18789
|
-
if (evPath &&
|
|
18790
|
-
fsWatchBroadcast(sp.resolve(
|
|
18698
|
+
listener(path33);
|
|
18699
|
+
emitRaw(rawEvent, evPath, { watchedPath: path33 });
|
|
18700
|
+
if (evPath && path33 !== evPath) {
|
|
18701
|
+
fsWatchBroadcast(sp.resolve(path33, evPath), KEY_LISTENERS, sp.join(path33, evPath));
|
|
18791
18702
|
}
|
|
18792
18703
|
};
|
|
18793
18704
|
try {
|
|
18794
|
-
return (0, import_node_fs.watch)(
|
|
18705
|
+
return (0, import_node_fs.watch)(path33, {
|
|
18795
18706
|
persistent: options.persistent
|
|
18796
18707
|
}, handleEvent);
|
|
18797
18708
|
} catch (error) {
|
|
@@ -18807,12 +18718,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
18807
18718
|
listener(val1, val2, val3);
|
|
18808
18719
|
});
|
|
18809
18720
|
};
|
|
18810
|
-
var setFsWatchListener = (
|
|
18721
|
+
var setFsWatchListener = (path33, fullPath, options, handlers) => {
|
|
18811
18722
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
18812
18723
|
let cont = FsWatchInstances.get(fullPath);
|
|
18813
18724
|
let watcher;
|
|
18814
18725
|
if (!options.persistent) {
|
|
18815
|
-
watcher = createFsWatchInstance(
|
|
18726
|
+
watcher = createFsWatchInstance(path33, options, listener, errHandler, rawEmitter);
|
|
18816
18727
|
if (!watcher)
|
|
18817
18728
|
return;
|
|
18818
18729
|
return watcher.close.bind(watcher);
|
|
@@ -18823,7 +18734,7 @@ var setFsWatchListener = (path31, fullPath, options, handlers) => {
|
|
|
18823
18734
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
18824
18735
|
} else {
|
|
18825
18736
|
watcher = createFsWatchInstance(
|
|
18826
|
-
|
|
18737
|
+
path33,
|
|
18827
18738
|
options,
|
|
18828
18739
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
18829
18740
|
errHandler,
|
|
@@ -18838,7 +18749,7 @@ var setFsWatchListener = (path31, fullPath, options, handlers) => {
|
|
|
18838
18749
|
cont.watcherUnusable = true;
|
|
18839
18750
|
if (isWindows && error.code === "EPERM") {
|
|
18840
18751
|
try {
|
|
18841
|
-
const fd = await (0, import_promises2.open)(
|
|
18752
|
+
const fd = await (0, import_promises2.open)(path33, "r");
|
|
18842
18753
|
await fd.close();
|
|
18843
18754
|
broadcastErr(error);
|
|
18844
18755
|
} catch (err) {
|
|
@@ -18869,7 +18780,7 @@ var setFsWatchListener = (path31, fullPath, options, handlers) => {
|
|
|
18869
18780
|
};
|
|
18870
18781
|
};
|
|
18871
18782
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
18872
|
-
var setFsWatchFileListener = (
|
|
18783
|
+
var setFsWatchFileListener = (path33, fullPath, options, handlers) => {
|
|
18873
18784
|
const { listener, rawEmitter } = handlers;
|
|
18874
18785
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
18875
18786
|
const copts = cont && cont.options;
|
|
@@ -18891,7 +18802,7 @@ var setFsWatchFileListener = (path31, fullPath, options, handlers) => {
|
|
|
18891
18802
|
});
|
|
18892
18803
|
const currmtime = curr.mtimeMs;
|
|
18893
18804
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
18894
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
18805
|
+
foreach(cont.listeners, (listener2) => listener2(path33, curr));
|
|
18895
18806
|
}
|
|
18896
18807
|
})
|
|
18897
18808
|
};
|
|
@@ -18921,13 +18832,13 @@ var NodeFsHandler = class {
|
|
|
18921
18832
|
* @param listener on fs change
|
|
18922
18833
|
* @returns closer for the watcher instance
|
|
18923
18834
|
*/
|
|
18924
|
-
_watchWithNodeFs(
|
|
18835
|
+
_watchWithNodeFs(path33, listener) {
|
|
18925
18836
|
const opts = this.fsw.options;
|
|
18926
|
-
const directory = sp.dirname(
|
|
18927
|
-
const basename8 = sp.basename(
|
|
18837
|
+
const directory = sp.dirname(path33);
|
|
18838
|
+
const basename8 = sp.basename(path33);
|
|
18928
18839
|
const parent = this.fsw._getWatchedDir(directory);
|
|
18929
18840
|
parent.add(basename8);
|
|
18930
|
-
const absolutePath = sp.resolve(
|
|
18841
|
+
const absolutePath = sp.resolve(path33);
|
|
18931
18842
|
const options = {
|
|
18932
18843
|
persistent: opts.persistent
|
|
18933
18844
|
};
|
|
@@ -18937,12 +18848,12 @@ var NodeFsHandler = class {
|
|
|
18937
18848
|
if (opts.usePolling) {
|
|
18938
18849
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
18939
18850
|
options.interval = enableBin && isBinaryPath(basename8) ? opts.binaryInterval : opts.interval;
|
|
18940
|
-
closer = setFsWatchFileListener(
|
|
18851
|
+
closer = setFsWatchFileListener(path33, absolutePath, options, {
|
|
18941
18852
|
listener,
|
|
18942
18853
|
rawEmitter: this.fsw._emitRaw
|
|
18943
18854
|
});
|
|
18944
18855
|
} else {
|
|
18945
|
-
closer = setFsWatchListener(
|
|
18856
|
+
closer = setFsWatchListener(path33, absolutePath, options, {
|
|
18946
18857
|
listener,
|
|
18947
18858
|
errHandler: this._boundHandleError,
|
|
18948
18859
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -18964,7 +18875,7 @@ var NodeFsHandler = class {
|
|
|
18964
18875
|
let prevStats = stats;
|
|
18965
18876
|
if (parent.has(basename8))
|
|
18966
18877
|
return;
|
|
18967
|
-
const listener = async (
|
|
18878
|
+
const listener = async (path33, newStats) => {
|
|
18968
18879
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
18969
18880
|
return;
|
|
18970
18881
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -18978,11 +18889,11 @@ var NodeFsHandler = class {
|
|
|
18978
18889
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
18979
18890
|
}
|
|
18980
18891
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
18981
|
-
this.fsw._closeFile(
|
|
18892
|
+
this.fsw._closeFile(path33);
|
|
18982
18893
|
prevStats = newStats2;
|
|
18983
18894
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
18984
18895
|
if (closer2)
|
|
18985
|
-
this.fsw._addPathCloser(
|
|
18896
|
+
this.fsw._addPathCloser(path33, closer2);
|
|
18986
18897
|
} else {
|
|
18987
18898
|
prevStats = newStats2;
|
|
18988
18899
|
}
|
|
@@ -19014,7 +18925,7 @@ var NodeFsHandler = class {
|
|
|
19014
18925
|
* @param item basename of this item
|
|
19015
18926
|
* @returns true if no more processing is needed for this entry.
|
|
19016
18927
|
*/
|
|
19017
|
-
async _handleSymlink(entry, directory,
|
|
18928
|
+
async _handleSymlink(entry, directory, path33, item) {
|
|
19018
18929
|
if (this.fsw.closed) {
|
|
19019
18930
|
return;
|
|
19020
18931
|
}
|
|
@@ -19024,7 +18935,7 @@ var NodeFsHandler = class {
|
|
|
19024
18935
|
this.fsw._incrReadyCount();
|
|
19025
18936
|
let linkPath;
|
|
19026
18937
|
try {
|
|
19027
|
-
linkPath = await (0, import_promises2.realpath)(
|
|
18938
|
+
linkPath = await (0, import_promises2.realpath)(path33);
|
|
19028
18939
|
} catch (e) {
|
|
19029
18940
|
this.fsw._emitReady();
|
|
19030
18941
|
return true;
|
|
@@ -19034,12 +18945,12 @@ var NodeFsHandler = class {
|
|
|
19034
18945
|
if (dir.has(item)) {
|
|
19035
18946
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
19036
18947
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
19037
|
-
this.fsw._emit(EV.CHANGE,
|
|
18948
|
+
this.fsw._emit(EV.CHANGE, path33, entry.stats);
|
|
19038
18949
|
}
|
|
19039
18950
|
} else {
|
|
19040
18951
|
dir.add(item);
|
|
19041
18952
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
19042
|
-
this.fsw._emit(EV.ADD,
|
|
18953
|
+
this.fsw._emit(EV.ADD, path33, entry.stats);
|
|
19043
18954
|
}
|
|
19044
18955
|
this.fsw._emitReady();
|
|
19045
18956
|
return true;
|
|
@@ -19069,9 +18980,9 @@ var NodeFsHandler = class {
|
|
|
19069
18980
|
return;
|
|
19070
18981
|
}
|
|
19071
18982
|
const item = entry.path;
|
|
19072
|
-
let
|
|
18983
|
+
let path33 = sp.join(directory, item);
|
|
19073
18984
|
current.add(item);
|
|
19074
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
18985
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path33, item)) {
|
|
19075
18986
|
return;
|
|
19076
18987
|
}
|
|
19077
18988
|
if (this.fsw.closed) {
|
|
@@ -19080,11 +18991,11 @@ var NodeFsHandler = class {
|
|
|
19080
18991
|
}
|
|
19081
18992
|
if (item === target || !target && !previous.has(item)) {
|
|
19082
18993
|
this.fsw._incrReadyCount();
|
|
19083
|
-
|
|
19084
|
-
this._addToNodeFs(
|
|
18994
|
+
path33 = sp.join(dir, sp.relative(dir, path33));
|
|
18995
|
+
this._addToNodeFs(path33, initialAdd, wh, depth + 1);
|
|
19085
18996
|
}
|
|
19086
18997
|
}).on(EV.ERROR, this._boundHandleError);
|
|
19087
|
-
return new Promise((
|
|
18998
|
+
return new Promise((resolve20, reject) => {
|
|
19088
18999
|
if (!stream)
|
|
19089
19000
|
return reject();
|
|
19090
19001
|
stream.once(STR_END, () => {
|
|
@@ -19093,7 +19004,7 @@ var NodeFsHandler = class {
|
|
|
19093
19004
|
return;
|
|
19094
19005
|
}
|
|
19095
19006
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
19096
|
-
|
|
19007
|
+
resolve20(void 0);
|
|
19097
19008
|
previous.getChildren().filter((item) => {
|
|
19098
19009
|
return item !== directory && !current.has(item);
|
|
19099
19010
|
}).forEach((item) => {
|
|
@@ -19150,13 +19061,13 @@ var NodeFsHandler = class {
|
|
|
19150
19061
|
* @param depth Child path actually targeted for watch
|
|
19151
19062
|
* @param target Child path actually targeted for watch
|
|
19152
19063
|
*/
|
|
19153
|
-
async _addToNodeFs(
|
|
19064
|
+
async _addToNodeFs(path33, initialAdd, priorWh, depth, target) {
|
|
19154
19065
|
const ready = this.fsw._emitReady;
|
|
19155
|
-
if (this.fsw._isIgnored(
|
|
19066
|
+
if (this.fsw._isIgnored(path33) || this.fsw.closed) {
|
|
19156
19067
|
ready();
|
|
19157
19068
|
return false;
|
|
19158
19069
|
}
|
|
19159
|
-
const wh = this.fsw._getWatchHelpers(
|
|
19070
|
+
const wh = this.fsw._getWatchHelpers(path33);
|
|
19160
19071
|
if (priorWh) {
|
|
19161
19072
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
19162
19073
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -19172,8 +19083,8 @@ var NodeFsHandler = class {
|
|
|
19172
19083
|
const follow = this.fsw.options.followSymlinks;
|
|
19173
19084
|
let closer;
|
|
19174
19085
|
if (stats.isDirectory()) {
|
|
19175
|
-
const absPath = sp.resolve(
|
|
19176
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
19086
|
+
const absPath = sp.resolve(path33);
|
|
19087
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path33) : path33;
|
|
19177
19088
|
if (this.fsw.closed)
|
|
19178
19089
|
return;
|
|
19179
19090
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -19183,29 +19094,29 @@ var NodeFsHandler = class {
|
|
|
19183
19094
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
19184
19095
|
}
|
|
19185
19096
|
} else if (stats.isSymbolicLink()) {
|
|
19186
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
19097
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path33) : path33;
|
|
19187
19098
|
if (this.fsw.closed)
|
|
19188
19099
|
return;
|
|
19189
19100
|
const parent = sp.dirname(wh.watchPath);
|
|
19190
19101
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
19191
19102
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
19192
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
19103
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path33, wh, targetPath);
|
|
19193
19104
|
if (this.fsw.closed)
|
|
19194
19105
|
return;
|
|
19195
19106
|
if (targetPath !== void 0) {
|
|
19196
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
19107
|
+
this.fsw._symlinkPaths.set(sp.resolve(path33), targetPath);
|
|
19197
19108
|
}
|
|
19198
19109
|
} else {
|
|
19199
19110
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
19200
19111
|
}
|
|
19201
19112
|
ready();
|
|
19202
19113
|
if (closer)
|
|
19203
|
-
this.fsw._addPathCloser(
|
|
19114
|
+
this.fsw._addPathCloser(path33, closer);
|
|
19204
19115
|
return false;
|
|
19205
19116
|
} catch (error) {
|
|
19206
19117
|
if (this.fsw._handleError(error)) {
|
|
19207
19118
|
ready();
|
|
19208
|
-
return
|
|
19119
|
+
return path33;
|
|
19209
19120
|
}
|
|
19210
19121
|
}
|
|
19211
19122
|
}
|
|
@@ -19237,35 +19148,35 @@ function createPattern(matcher) {
|
|
|
19237
19148
|
if (matcher.path === string)
|
|
19238
19149
|
return true;
|
|
19239
19150
|
if (matcher.recursive) {
|
|
19240
|
-
const
|
|
19241
|
-
if (!
|
|
19151
|
+
const relative14 = sp2.relative(matcher.path, string);
|
|
19152
|
+
if (!relative14) {
|
|
19242
19153
|
return false;
|
|
19243
19154
|
}
|
|
19244
|
-
return !
|
|
19155
|
+
return !relative14.startsWith("..") && !sp2.isAbsolute(relative14);
|
|
19245
19156
|
}
|
|
19246
19157
|
return false;
|
|
19247
19158
|
};
|
|
19248
19159
|
}
|
|
19249
19160
|
return () => false;
|
|
19250
19161
|
}
|
|
19251
|
-
function normalizePath3(
|
|
19252
|
-
if (typeof
|
|
19162
|
+
function normalizePath3(path33) {
|
|
19163
|
+
if (typeof path33 !== "string")
|
|
19253
19164
|
throw new Error("string expected");
|
|
19254
|
-
|
|
19255
|
-
|
|
19165
|
+
path33 = sp2.normalize(path33);
|
|
19166
|
+
path33 = path33.replace(/\\/g, "/");
|
|
19256
19167
|
let prepend = false;
|
|
19257
|
-
if (
|
|
19168
|
+
if (path33.startsWith("//"))
|
|
19258
19169
|
prepend = true;
|
|
19259
|
-
|
|
19170
|
+
path33 = path33.replace(DOUBLE_SLASH_RE, "/");
|
|
19260
19171
|
if (prepend)
|
|
19261
|
-
|
|
19262
|
-
return
|
|
19172
|
+
path33 = "/" + path33;
|
|
19173
|
+
return path33;
|
|
19263
19174
|
}
|
|
19264
19175
|
function matchPatterns(patterns, testString, stats) {
|
|
19265
|
-
const
|
|
19176
|
+
const path33 = normalizePath3(testString);
|
|
19266
19177
|
for (let index = 0; index < patterns.length; index++) {
|
|
19267
19178
|
const pattern = patterns[index];
|
|
19268
|
-
if (pattern(
|
|
19179
|
+
if (pattern(path33, stats)) {
|
|
19269
19180
|
return true;
|
|
19270
19181
|
}
|
|
19271
19182
|
}
|
|
@@ -19303,19 +19214,19 @@ var toUnix = (string) => {
|
|
|
19303
19214
|
}
|
|
19304
19215
|
return str;
|
|
19305
19216
|
};
|
|
19306
|
-
var normalizePathToUnix = (
|
|
19307
|
-
var normalizeIgnored = (cwd = "") => (
|
|
19308
|
-
if (typeof
|
|
19309
|
-
return normalizePathToUnix(sp2.isAbsolute(
|
|
19217
|
+
var normalizePathToUnix = (path33) => toUnix(sp2.normalize(toUnix(path33)));
|
|
19218
|
+
var normalizeIgnored = (cwd = "") => (path33) => {
|
|
19219
|
+
if (typeof path33 === "string") {
|
|
19220
|
+
return normalizePathToUnix(sp2.isAbsolute(path33) ? path33 : sp2.join(cwd, path33));
|
|
19310
19221
|
} else {
|
|
19311
|
-
return
|
|
19222
|
+
return path33;
|
|
19312
19223
|
}
|
|
19313
19224
|
};
|
|
19314
|
-
var getAbsolutePath = (
|
|
19315
|
-
if (sp2.isAbsolute(
|
|
19316
|
-
return
|
|
19225
|
+
var getAbsolutePath = (path33, cwd) => {
|
|
19226
|
+
if (sp2.isAbsolute(path33)) {
|
|
19227
|
+
return path33;
|
|
19317
19228
|
}
|
|
19318
|
-
return sp2.join(cwd,
|
|
19229
|
+
return sp2.join(cwd, path33);
|
|
19319
19230
|
};
|
|
19320
19231
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
19321
19232
|
var DirEntry = class {
|
|
@@ -19380,10 +19291,10 @@ var WatchHelper = class {
|
|
|
19380
19291
|
dirParts;
|
|
19381
19292
|
followSymlinks;
|
|
19382
19293
|
statMethod;
|
|
19383
|
-
constructor(
|
|
19294
|
+
constructor(path33, follow, fsw) {
|
|
19384
19295
|
this.fsw = fsw;
|
|
19385
|
-
const watchPath =
|
|
19386
|
-
this.path =
|
|
19296
|
+
const watchPath = path33;
|
|
19297
|
+
this.path = path33 = path33.replace(REPLACER_RE, "");
|
|
19387
19298
|
this.watchPath = watchPath;
|
|
19388
19299
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
19389
19300
|
this.dirParts = [];
|
|
@@ -19523,20 +19434,20 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
19523
19434
|
this._closePromise = void 0;
|
|
19524
19435
|
let paths = unifyPaths(paths_);
|
|
19525
19436
|
if (cwd) {
|
|
19526
|
-
paths = paths.map((
|
|
19527
|
-
const absPath = getAbsolutePath(
|
|
19437
|
+
paths = paths.map((path33) => {
|
|
19438
|
+
const absPath = getAbsolutePath(path33, cwd);
|
|
19528
19439
|
return absPath;
|
|
19529
19440
|
});
|
|
19530
19441
|
}
|
|
19531
|
-
paths.forEach((
|
|
19532
|
-
this._removeIgnoredPath(
|
|
19442
|
+
paths.forEach((path33) => {
|
|
19443
|
+
this._removeIgnoredPath(path33);
|
|
19533
19444
|
});
|
|
19534
19445
|
this._userIgnored = void 0;
|
|
19535
19446
|
if (!this._readyCount)
|
|
19536
19447
|
this._readyCount = 0;
|
|
19537
19448
|
this._readyCount += paths.length;
|
|
19538
|
-
Promise.all(paths.map(async (
|
|
19539
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
19449
|
+
Promise.all(paths.map(async (path33) => {
|
|
19450
|
+
const res = await this._nodeFsHandler._addToNodeFs(path33, !_internal, void 0, 0, _origAdd);
|
|
19540
19451
|
if (res)
|
|
19541
19452
|
this._emitReady();
|
|
19542
19453
|
return res;
|
|
@@ -19558,17 +19469,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
19558
19469
|
return this;
|
|
19559
19470
|
const paths = unifyPaths(paths_);
|
|
19560
19471
|
const { cwd } = this.options;
|
|
19561
|
-
paths.forEach((
|
|
19562
|
-
if (!sp2.isAbsolute(
|
|
19472
|
+
paths.forEach((path33) => {
|
|
19473
|
+
if (!sp2.isAbsolute(path33) && !this._closers.has(path33)) {
|
|
19563
19474
|
if (cwd)
|
|
19564
|
-
|
|
19565
|
-
|
|
19475
|
+
path33 = sp2.join(cwd, path33);
|
|
19476
|
+
path33 = sp2.resolve(path33);
|
|
19566
19477
|
}
|
|
19567
|
-
this._closePath(
|
|
19568
|
-
this._addIgnoredPath(
|
|
19569
|
-
if (this._watched.has(
|
|
19478
|
+
this._closePath(path33);
|
|
19479
|
+
this._addIgnoredPath(path33);
|
|
19480
|
+
if (this._watched.has(path33)) {
|
|
19570
19481
|
this._addIgnoredPath({
|
|
19571
|
-
path:
|
|
19482
|
+
path: path33,
|
|
19572
19483
|
recursive: true
|
|
19573
19484
|
});
|
|
19574
19485
|
}
|
|
@@ -19632,38 +19543,38 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
19632
19543
|
* @param stats arguments to be passed with event
|
|
19633
19544
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
19634
19545
|
*/
|
|
19635
|
-
async _emit(event,
|
|
19546
|
+
async _emit(event, path33, stats) {
|
|
19636
19547
|
if (this.closed)
|
|
19637
19548
|
return;
|
|
19638
19549
|
const opts = this.options;
|
|
19639
19550
|
if (isWindows)
|
|
19640
|
-
|
|
19551
|
+
path33 = sp2.normalize(path33);
|
|
19641
19552
|
if (opts.cwd)
|
|
19642
|
-
|
|
19643
|
-
const args = [
|
|
19553
|
+
path33 = sp2.relative(opts.cwd, path33);
|
|
19554
|
+
const args = [path33];
|
|
19644
19555
|
if (stats != null)
|
|
19645
19556
|
args.push(stats);
|
|
19646
19557
|
const awf = opts.awaitWriteFinish;
|
|
19647
19558
|
let pw;
|
|
19648
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
19559
|
+
if (awf && (pw = this._pendingWrites.get(path33))) {
|
|
19649
19560
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
19650
19561
|
return this;
|
|
19651
19562
|
}
|
|
19652
19563
|
if (opts.atomic) {
|
|
19653
19564
|
if (event === EVENTS.UNLINK) {
|
|
19654
|
-
this._pendingUnlinks.set(
|
|
19565
|
+
this._pendingUnlinks.set(path33, [event, ...args]);
|
|
19655
19566
|
setTimeout(() => {
|
|
19656
|
-
this._pendingUnlinks.forEach((entry,
|
|
19567
|
+
this._pendingUnlinks.forEach((entry, path34) => {
|
|
19657
19568
|
this.emit(...entry);
|
|
19658
19569
|
this.emit(EVENTS.ALL, ...entry);
|
|
19659
|
-
this._pendingUnlinks.delete(
|
|
19570
|
+
this._pendingUnlinks.delete(path34);
|
|
19660
19571
|
});
|
|
19661
19572
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
19662
19573
|
return this;
|
|
19663
19574
|
}
|
|
19664
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
19575
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path33)) {
|
|
19665
19576
|
event = EVENTS.CHANGE;
|
|
19666
|
-
this._pendingUnlinks.delete(
|
|
19577
|
+
this._pendingUnlinks.delete(path33);
|
|
19667
19578
|
}
|
|
19668
19579
|
}
|
|
19669
19580
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -19681,16 +19592,16 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
19681
19592
|
this.emitWithAll(event, args);
|
|
19682
19593
|
}
|
|
19683
19594
|
};
|
|
19684
|
-
this._awaitWriteFinish(
|
|
19595
|
+
this._awaitWriteFinish(path33, awf.stabilityThreshold, event, awfEmit);
|
|
19685
19596
|
return this;
|
|
19686
19597
|
}
|
|
19687
19598
|
if (event === EVENTS.CHANGE) {
|
|
19688
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
19599
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path33, 50);
|
|
19689
19600
|
if (isThrottled)
|
|
19690
19601
|
return this;
|
|
19691
19602
|
}
|
|
19692
19603
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
19693
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
19604
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path33) : path33;
|
|
19694
19605
|
let stats2;
|
|
19695
19606
|
try {
|
|
19696
19607
|
stats2 = await (0, import_promises3.stat)(fullPath);
|
|
@@ -19721,23 +19632,23 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
19721
19632
|
* @param timeout duration of time to suppress duplicate actions
|
|
19722
19633
|
* @returns tracking object or false if action should be suppressed
|
|
19723
19634
|
*/
|
|
19724
|
-
_throttle(actionType,
|
|
19635
|
+
_throttle(actionType, path33, timeout) {
|
|
19725
19636
|
if (!this._throttled.has(actionType)) {
|
|
19726
19637
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
19727
19638
|
}
|
|
19728
19639
|
const action = this._throttled.get(actionType);
|
|
19729
19640
|
if (!action)
|
|
19730
19641
|
throw new Error("invalid throttle");
|
|
19731
|
-
const actionPath = action.get(
|
|
19642
|
+
const actionPath = action.get(path33);
|
|
19732
19643
|
if (actionPath) {
|
|
19733
19644
|
actionPath.count++;
|
|
19734
19645
|
return false;
|
|
19735
19646
|
}
|
|
19736
19647
|
let timeoutObject;
|
|
19737
19648
|
const clear = () => {
|
|
19738
|
-
const item = action.get(
|
|
19649
|
+
const item = action.get(path33);
|
|
19739
19650
|
const count = item ? item.count : 0;
|
|
19740
|
-
action.delete(
|
|
19651
|
+
action.delete(path33);
|
|
19741
19652
|
clearTimeout(timeoutObject);
|
|
19742
19653
|
if (item)
|
|
19743
19654
|
clearTimeout(item.timeoutObject);
|
|
@@ -19745,7 +19656,7 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
19745
19656
|
};
|
|
19746
19657
|
timeoutObject = setTimeout(clear, timeout);
|
|
19747
19658
|
const thr = { timeoutObject, clear, count: 0 };
|
|
19748
|
-
action.set(
|
|
19659
|
+
action.set(path33, thr);
|
|
19749
19660
|
return thr;
|
|
19750
19661
|
}
|
|
19751
19662
|
_incrReadyCount() {
|
|
@@ -19759,44 +19670,44 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
19759
19670
|
* @param event
|
|
19760
19671
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
19761
19672
|
*/
|
|
19762
|
-
_awaitWriteFinish(
|
|
19673
|
+
_awaitWriteFinish(path33, threshold, event, awfEmit) {
|
|
19763
19674
|
const awf = this.options.awaitWriteFinish;
|
|
19764
19675
|
if (typeof awf !== "object")
|
|
19765
19676
|
return;
|
|
19766
19677
|
const pollInterval = awf.pollInterval;
|
|
19767
19678
|
let timeoutHandler;
|
|
19768
|
-
let fullPath =
|
|
19769
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
19770
|
-
fullPath = sp2.join(this.options.cwd,
|
|
19679
|
+
let fullPath = path33;
|
|
19680
|
+
if (this.options.cwd && !sp2.isAbsolute(path33)) {
|
|
19681
|
+
fullPath = sp2.join(this.options.cwd, path33);
|
|
19771
19682
|
}
|
|
19772
19683
|
const now2 = /* @__PURE__ */ new Date();
|
|
19773
19684
|
const writes = this._pendingWrites;
|
|
19774
19685
|
function awaitWriteFinishFn(prevStat) {
|
|
19775
19686
|
(0, import_node_fs2.stat)(fullPath, (err, curStat) => {
|
|
19776
|
-
if (err || !writes.has(
|
|
19687
|
+
if (err || !writes.has(path33)) {
|
|
19777
19688
|
if (err && err.code !== "ENOENT")
|
|
19778
19689
|
awfEmit(err);
|
|
19779
19690
|
return;
|
|
19780
19691
|
}
|
|
19781
19692
|
const now3 = Number(/* @__PURE__ */ new Date());
|
|
19782
19693
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
19783
|
-
writes.get(
|
|
19694
|
+
writes.get(path33).lastChange = now3;
|
|
19784
19695
|
}
|
|
19785
|
-
const pw = writes.get(
|
|
19696
|
+
const pw = writes.get(path33);
|
|
19786
19697
|
const df = now3 - pw.lastChange;
|
|
19787
19698
|
if (df >= threshold) {
|
|
19788
|
-
writes.delete(
|
|
19699
|
+
writes.delete(path33);
|
|
19789
19700
|
awfEmit(void 0, curStat);
|
|
19790
19701
|
} else {
|
|
19791
19702
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
19792
19703
|
}
|
|
19793
19704
|
});
|
|
19794
19705
|
}
|
|
19795
|
-
if (!writes.has(
|
|
19796
|
-
writes.set(
|
|
19706
|
+
if (!writes.has(path33)) {
|
|
19707
|
+
writes.set(path33, {
|
|
19797
19708
|
lastChange: now2,
|
|
19798
19709
|
cancelWait: () => {
|
|
19799
|
-
writes.delete(
|
|
19710
|
+
writes.delete(path33);
|
|
19800
19711
|
clearTimeout(timeoutHandler);
|
|
19801
19712
|
return event;
|
|
19802
19713
|
}
|
|
@@ -19807,8 +19718,8 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
19807
19718
|
/**
|
|
19808
19719
|
* Determines whether user has asked to ignore this path.
|
|
19809
19720
|
*/
|
|
19810
|
-
_isIgnored(
|
|
19811
|
-
if (this.options.atomic && DOT_RE.test(
|
|
19721
|
+
_isIgnored(path33, stats) {
|
|
19722
|
+
if (this.options.atomic && DOT_RE.test(path33))
|
|
19812
19723
|
return true;
|
|
19813
19724
|
if (!this._userIgnored) {
|
|
19814
19725
|
const { cwd } = this.options;
|
|
@@ -19818,17 +19729,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
19818
19729
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
19819
19730
|
this._userIgnored = anymatch(list, void 0);
|
|
19820
19731
|
}
|
|
19821
|
-
return this._userIgnored(
|
|
19732
|
+
return this._userIgnored(path33, stats);
|
|
19822
19733
|
}
|
|
19823
|
-
_isntIgnored(
|
|
19824
|
-
return !this._isIgnored(
|
|
19734
|
+
_isntIgnored(path33, stat5) {
|
|
19735
|
+
return !this._isIgnored(path33, stat5);
|
|
19825
19736
|
}
|
|
19826
19737
|
/**
|
|
19827
19738
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
19828
19739
|
* @param path file or directory pattern being watched
|
|
19829
19740
|
*/
|
|
19830
|
-
_getWatchHelpers(
|
|
19831
|
-
return new WatchHelper(
|
|
19741
|
+
_getWatchHelpers(path33) {
|
|
19742
|
+
return new WatchHelper(path33, this.options.followSymlinks, this);
|
|
19832
19743
|
}
|
|
19833
19744
|
// Directory helpers
|
|
19834
19745
|
// -----------------
|
|
@@ -19860,63 +19771,63 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
19860
19771
|
* @param item base path of item/directory
|
|
19861
19772
|
*/
|
|
19862
19773
|
_remove(directory, item, isDirectory) {
|
|
19863
|
-
const
|
|
19864
|
-
const fullPath = sp2.resolve(
|
|
19865
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
19866
|
-
if (!this._throttle("remove",
|
|
19774
|
+
const path33 = sp2.join(directory, item);
|
|
19775
|
+
const fullPath = sp2.resolve(path33);
|
|
19776
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path33) || this._watched.has(fullPath);
|
|
19777
|
+
if (!this._throttle("remove", path33, 100))
|
|
19867
19778
|
return;
|
|
19868
19779
|
if (!isDirectory && this._watched.size === 1) {
|
|
19869
19780
|
this.add(directory, item, true);
|
|
19870
19781
|
}
|
|
19871
|
-
const wp = this._getWatchedDir(
|
|
19782
|
+
const wp = this._getWatchedDir(path33);
|
|
19872
19783
|
const nestedDirectoryChildren = wp.getChildren();
|
|
19873
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
19784
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path33, nested));
|
|
19874
19785
|
const parent = this._getWatchedDir(directory);
|
|
19875
19786
|
const wasTracked = parent.has(item);
|
|
19876
19787
|
parent.remove(item);
|
|
19877
19788
|
if (this._symlinkPaths.has(fullPath)) {
|
|
19878
19789
|
this._symlinkPaths.delete(fullPath);
|
|
19879
19790
|
}
|
|
19880
|
-
let relPath =
|
|
19791
|
+
let relPath = path33;
|
|
19881
19792
|
if (this.options.cwd)
|
|
19882
|
-
relPath = sp2.relative(this.options.cwd,
|
|
19793
|
+
relPath = sp2.relative(this.options.cwd, path33);
|
|
19883
19794
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
19884
19795
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
19885
19796
|
if (event === EVENTS.ADD)
|
|
19886
19797
|
return;
|
|
19887
19798
|
}
|
|
19888
|
-
this._watched.delete(
|
|
19799
|
+
this._watched.delete(path33);
|
|
19889
19800
|
this._watched.delete(fullPath);
|
|
19890
19801
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
19891
|
-
if (wasTracked && !this._isIgnored(
|
|
19892
|
-
this._emit(eventName,
|
|
19893
|
-
this._closePath(
|
|
19802
|
+
if (wasTracked && !this._isIgnored(path33))
|
|
19803
|
+
this._emit(eventName, path33);
|
|
19804
|
+
this._closePath(path33);
|
|
19894
19805
|
}
|
|
19895
19806
|
/**
|
|
19896
19807
|
* Closes all watchers for a path
|
|
19897
19808
|
*/
|
|
19898
|
-
_closePath(
|
|
19899
|
-
this._closeFile(
|
|
19900
|
-
const dir = sp2.dirname(
|
|
19901
|
-
this._getWatchedDir(dir).remove(sp2.basename(
|
|
19809
|
+
_closePath(path33) {
|
|
19810
|
+
this._closeFile(path33);
|
|
19811
|
+
const dir = sp2.dirname(path33);
|
|
19812
|
+
this._getWatchedDir(dir).remove(sp2.basename(path33));
|
|
19902
19813
|
}
|
|
19903
19814
|
/**
|
|
19904
19815
|
* Closes only file-specific watchers
|
|
19905
19816
|
*/
|
|
19906
|
-
_closeFile(
|
|
19907
|
-
const closers = this._closers.get(
|
|
19817
|
+
_closeFile(path33) {
|
|
19818
|
+
const closers = this._closers.get(path33);
|
|
19908
19819
|
if (!closers)
|
|
19909
19820
|
return;
|
|
19910
19821
|
closers.forEach((closer) => closer());
|
|
19911
|
-
this._closers.delete(
|
|
19822
|
+
this._closers.delete(path33);
|
|
19912
19823
|
}
|
|
19913
|
-
_addPathCloser(
|
|
19824
|
+
_addPathCloser(path33, closer) {
|
|
19914
19825
|
if (!closer)
|
|
19915
19826
|
return;
|
|
19916
|
-
let list = this._closers.get(
|
|
19827
|
+
let list = this._closers.get(path33);
|
|
19917
19828
|
if (!list) {
|
|
19918
19829
|
list = [];
|
|
19919
|
-
this._closers.set(
|
|
19830
|
+
this._closers.set(path33, list);
|
|
19920
19831
|
}
|
|
19921
19832
|
list.push(closer);
|
|
19922
19833
|
}
|
|
@@ -19946,12 +19857,291 @@ function watch(paths, options = {}) {
|
|
|
19946
19857
|
var chokidar_default = { watch, FSWatcher };
|
|
19947
19858
|
|
|
19948
19859
|
// src/watcher/file-watcher.ts
|
|
19860
|
+
var path28 = __toESM(require("path"), 1);
|
|
19861
|
+
|
|
19862
|
+
// src/watcher/native-recursive-watcher.ts
|
|
19863
|
+
var import_node_fs3 = require("fs");
|
|
19949
19864
|
var path26 = __toESM(require("path"), 1);
|
|
19865
|
+
var NativeRecursiveWatcher = class {
|
|
19866
|
+
constructor(root, onChange, options = {}) {
|
|
19867
|
+
this.root = root;
|
|
19868
|
+
this.onChange = onChange;
|
|
19869
|
+
this.watchFactory = options.watchFactory ?? this.defaultWatchFactory;
|
|
19870
|
+
this.onError = options.onError;
|
|
19871
|
+
}
|
|
19872
|
+
root;
|
|
19873
|
+
onChange;
|
|
19874
|
+
watcher = null;
|
|
19875
|
+
listenerToken = 0;
|
|
19876
|
+
watchFactory;
|
|
19877
|
+
onError;
|
|
19878
|
+
start() {
|
|
19879
|
+
if (this.watcher) return;
|
|
19880
|
+
const token = ++this.listenerToken;
|
|
19881
|
+
const listener = (_eventType, filename) => {
|
|
19882
|
+
if (this.watcher === null || this.listenerToken !== token) return;
|
|
19883
|
+
const absolutePath = this.toAbsolutePath(filename);
|
|
19884
|
+
const nextResult = this.onChange(absolutePath);
|
|
19885
|
+
if (nextResult instanceof Promise) {
|
|
19886
|
+
void nextResult.catch((error) => {
|
|
19887
|
+
console.error("[codebase-index] Error handling native watcher event:", error);
|
|
19888
|
+
});
|
|
19889
|
+
}
|
|
19890
|
+
};
|
|
19891
|
+
const watcher = this.watchFactory(this.root, listener, {
|
|
19892
|
+
persistent: true,
|
|
19893
|
+
recursive: true
|
|
19894
|
+
});
|
|
19895
|
+
watcher.on?.("error", (error) => {
|
|
19896
|
+
if (this.watcher === watcher && this.listenerToken === token) {
|
|
19897
|
+
this.onError?.(error);
|
|
19898
|
+
}
|
|
19899
|
+
});
|
|
19900
|
+
this.watcher = watcher;
|
|
19901
|
+
}
|
|
19902
|
+
async stop() {
|
|
19903
|
+
const watcher = this.watcher;
|
|
19904
|
+
this.watcher = null;
|
|
19905
|
+
this.listenerToken += 1;
|
|
19906
|
+
if (!watcher) return;
|
|
19907
|
+
await watcher.close();
|
|
19908
|
+
}
|
|
19909
|
+
toAbsolutePath(filename) {
|
|
19910
|
+
if (filename == null) return null;
|
|
19911
|
+
const normalizedFilename = typeof filename === "string" ? filename : filename.toString();
|
|
19912
|
+
const absolutePath = path26.resolve(this.root, normalizedFilename);
|
|
19913
|
+
const relativePath = path26.relative(this.root, absolutePath);
|
|
19914
|
+
const outsideRoot = relativePath === ".." || relativePath.startsWith(`..${path26.sep}`) || path26.isAbsolute(relativePath);
|
|
19915
|
+
return outsideRoot ? null : absolutePath;
|
|
19916
|
+
}
|
|
19917
|
+
defaultWatchFactory = (root, listener, options) => (0, import_node_fs3.watch)(root, options, listener);
|
|
19918
|
+
};
|
|
19919
|
+
|
|
19920
|
+
// src/watcher/snapshot.ts
|
|
19921
|
+
var fsPromises4 = __toESM(require("fs/promises"), 1);
|
|
19922
|
+
var path27 = __toESM(require("path"), 1);
|
|
19923
|
+
async function buildFileSnapshotScan(projectRoot, config, configPaths = []) {
|
|
19924
|
+
const normalizedProjectRoot = path27.resolve(projectRoot);
|
|
19925
|
+
const ignoreFilter = createIgnoreFilter(normalizedProjectRoot);
|
|
19926
|
+
const includePatterns = [...config.include, ...config.additionalInclude ?? []];
|
|
19927
|
+
const maxDepth = config.indexing?.maxDepth ?? -1;
|
|
19928
|
+
const snapshot = /* @__PURE__ */ new Map();
|
|
19929
|
+
const unreadablePrefixes = /* @__PURE__ */ new Set();
|
|
19930
|
+
const includeFile = async (filePath) => {
|
|
19931
|
+
const normalizedPath3 = path27.resolve(filePath);
|
|
19932
|
+
if (!shouldIncludeFile(normalizedPath3, normalizedProjectRoot, includePatterns, config.exclude, ignoreFilter)) return;
|
|
19933
|
+
const stat5 = await readStatIfFile(normalizedPath3, unreadablePrefixes);
|
|
19934
|
+
if (stat5) snapshot.set(normalizedPath3, { size: stat5.size, mtimeMs: stat5.mtimeMs });
|
|
19935
|
+
};
|
|
19936
|
+
const walk = async (directoryPath, depth) => {
|
|
19937
|
+
let entries;
|
|
19938
|
+
try {
|
|
19939
|
+
entries = await fsPromises4.readdir(directoryPath, { withFileTypes: true });
|
|
19940
|
+
} catch (error) {
|
|
19941
|
+
if (isMissingFsError(error)) return;
|
|
19942
|
+
if (isPermissionFsError(error)) {
|
|
19943
|
+
unreadablePrefixes.add(path27.resolve(directoryPath));
|
|
19944
|
+
return;
|
|
19945
|
+
}
|
|
19946
|
+
throw error;
|
|
19947
|
+
}
|
|
19948
|
+
for (const entry of entries) {
|
|
19949
|
+
const fullPath = path27.join(directoryPath, entry.name);
|
|
19950
|
+
const relativePath = path27.relative(normalizedProjectRoot, fullPath);
|
|
19951
|
+
if (entry.isDirectory()) {
|
|
19952
|
+
if (hasFilteredPathSegment(relativePath, path27.sep) || isRestrictedDirectory(relativePath, path27.sep)) continue;
|
|
19953
|
+
if (ignoreFilter.ignores(relativePath)) continue;
|
|
19954
|
+
if (maxDepth === -1 || depth < maxDepth) await walk(fullPath, depth + 1);
|
|
19955
|
+
} else if (entry.isFile()) {
|
|
19956
|
+
await includeFile(fullPath);
|
|
19957
|
+
}
|
|
19958
|
+
}
|
|
19959
|
+
};
|
|
19960
|
+
await walk(normalizedProjectRoot, 0);
|
|
19961
|
+
await includeExplicitConfigPaths(snapshot, unreadablePrefixes, configPaths);
|
|
19962
|
+
return { entries: snapshot, unreadablePrefixes };
|
|
19963
|
+
}
|
|
19964
|
+
async function buildFileSnapshotForPathScan(projectRoot, config, configPaths, targetPath) {
|
|
19965
|
+
const normalizedProjectRoot = path27.resolve(projectRoot);
|
|
19966
|
+
const normalizedTargetPath = path27.resolve(targetPath);
|
|
19967
|
+
if (!isWithinPath(normalizedProjectRoot, normalizedTargetPath)) {
|
|
19968
|
+
return { entries: /* @__PURE__ */ new Map(), unreadablePrefixes: /* @__PURE__ */ new Set() };
|
|
19969
|
+
}
|
|
19970
|
+
const ignoreFilter = createIgnoreFilter(normalizedProjectRoot);
|
|
19971
|
+
const includePatterns = [...config.include, ...config.additionalInclude ?? []];
|
|
19972
|
+
const maxDepth = config.indexing?.maxDepth ?? -1;
|
|
19973
|
+
const explicitConfigPaths = new Set(configPaths.map((configPath) => path27.resolve(configPath)));
|
|
19974
|
+
const snapshot = /* @__PURE__ */ new Map();
|
|
19975
|
+
const unreadablePrefixes = /* @__PURE__ */ new Set();
|
|
19976
|
+
const includeFile = async (filePath) => {
|
|
19977
|
+
const normalizedPath3 = path27.resolve(filePath);
|
|
19978
|
+
if (!explicitConfigPaths.has(normalizedPath3) && !shouldIncludeFile(
|
|
19979
|
+
normalizedPath3,
|
|
19980
|
+
normalizedProjectRoot,
|
|
19981
|
+
includePatterns,
|
|
19982
|
+
config.exclude,
|
|
19983
|
+
ignoreFilter
|
|
19984
|
+
)) return;
|
|
19985
|
+
const stat5 = await readStatIfFile(normalizedPath3, unreadablePrefixes);
|
|
19986
|
+
if (stat5) snapshot.set(normalizedPath3, { size: stat5.size, mtimeMs: stat5.mtimeMs });
|
|
19987
|
+
};
|
|
19988
|
+
const walk = async (directoryPath, depth) => {
|
|
19989
|
+
let entries;
|
|
19990
|
+
try {
|
|
19991
|
+
entries = await fsPromises4.readdir(directoryPath, { withFileTypes: true });
|
|
19992
|
+
} catch (error) {
|
|
19993
|
+
if (isMissingFsError(error)) return;
|
|
19994
|
+
if (isPermissionFsError(error)) {
|
|
19995
|
+
unreadablePrefixes.add(path27.resolve(directoryPath));
|
|
19996
|
+
return;
|
|
19997
|
+
}
|
|
19998
|
+
throw error;
|
|
19999
|
+
}
|
|
20000
|
+
for (const entry of entries) {
|
|
20001
|
+
const fullPath = path27.join(directoryPath, entry.name);
|
|
20002
|
+
const relativePath = path27.relative(normalizedProjectRoot, fullPath);
|
|
20003
|
+
if (entry.isDirectory()) {
|
|
20004
|
+
if (hasFilteredPathSegment(relativePath, path27.sep) || isRestrictedDirectory(relativePath, path27.sep)) continue;
|
|
20005
|
+
if (ignoreFilter.ignores(relativePath)) continue;
|
|
20006
|
+
if (maxDepth === -1 || depth < maxDepth) await walk(fullPath, depth + 1);
|
|
20007
|
+
} else if (entry.isFile()) {
|
|
20008
|
+
await includeFile(fullPath);
|
|
20009
|
+
}
|
|
20010
|
+
}
|
|
20011
|
+
};
|
|
20012
|
+
const targetStat = await readStatIfFile(normalizedTargetPath, unreadablePrefixes);
|
|
20013
|
+
if (targetStat) await includeFile(normalizedTargetPath);
|
|
20014
|
+
else await walk(normalizedTargetPath, 0);
|
|
20015
|
+
await includeExplicitConfigPathsInPath(snapshot, unreadablePrefixes, configPaths, normalizedTargetPath);
|
|
20016
|
+
return { entries: snapshot, unreadablePrefixes };
|
|
20017
|
+
}
|
|
20018
|
+
function completeFileSnapshot(previous, scan) {
|
|
20019
|
+
const completed = new Map(scan.entries);
|
|
20020
|
+
for (const unreadablePrefix of scan.unreadablePrefixes) {
|
|
20021
|
+
for (const [entryPath, entry] of previous) {
|
|
20022
|
+
if (isWithinPath(unreadablePrefix, entryPath) && !completed.has(entryPath)) completed.set(entryPath, entry);
|
|
20023
|
+
}
|
|
20024
|
+
}
|
|
20025
|
+
return completed;
|
|
20026
|
+
}
|
|
20027
|
+
async function includeExplicitConfigPaths(snapshot, unreadablePrefixes, configPaths) {
|
|
20028
|
+
for (const configPath of [...new Set(configPaths.map((value) => path27.resolve(value)))]) {
|
|
20029
|
+
if (snapshot.has(configPath)) continue;
|
|
20030
|
+
const stat5 = await readStatIfFile(configPath, unreadablePrefixes);
|
|
20031
|
+
if (stat5) snapshot.set(configPath, { size: stat5.size, mtimeMs: stat5.mtimeMs });
|
|
20032
|
+
}
|
|
20033
|
+
}
|
|
20034
|
+
async function includeExplicitConfigPathsInPath(snapshot, unreadablePrefixes, configPaths, targetPath) {
|
|
20035
|
+
await includeExplicitConfigPaths(
|
|
20036
|
+
snapshot,
|
|
20037
|
+
unreadablePrefixes,
|
|
20038
|
+
configPaths.filter((configPath) => isWithinPath(targetPath, path27.resolve(configPath)))
|
|
20039
|
+
);
|
|
20040
|
+
}
|
|
20041
|
+
function isWithinPath(parentPath, childPath) {
|
|
20042
|
+
const relativePath = path27.relative(parentPath, childPath);
|
|
20043
|
+
return relativePath === "" || !relativePath.startsWith(`..${path27.sep}`) && relativePath !== ".." && !path27.isAbsolute(relativePath);
|
|
20044
|
+
}
|
|
20045
|
+
async function readStatIfFile(filePath, unreadablePrefixes) {
|
|
20046
|
+
try {
|
|
20047
|
+
const stat5 = await fsPromises4.stat(filePath);
|
|
20048
|
+
return stat5.isFile() ? stat5 : null;
|
|
20049
|
+
} catch (error) {
|
|
20050
|
+
if (isMissingFsError(error)) return null;
|
|
20051
|
+
if (isPermissionFsError(error)) {
|
|
20052
|
+
unreadablePrefixes.add(path27.resolve(filePath));
|
|
20053
|
+
return null;
|
|
20054
|
+
}
|
|
20055
|
+
throw error;
|
|
20056
|
+
}
|
|
20057
|
+
}
|
|
20058
|
+
function isMissingFsError(error) {
|
|
20059
|
+
return error instanceof Error && ["ENOENT", "ENOTDIR"].includes(error.code ?? "");
|
|
20060
|
+
}
|
|
20061
|
+
function isPermissionFsError(error) {
|
|
20062
|
+
return error instanceof Error && ["EACCES", "EPERM"].includes(error.code ?? "");
|
|
20063
|
+
}
|
|
20064
|
+
var diffTypeOrder = { add: 0, change: 1, unlink: 2 };
|
|
20065
|
+
function diffFileSnapshots(previous, current, forcedChanges = /* @__PURE__ */ new Set()) {
|
|
20066
|
+
const changes = [];
|
|
20067
|
+
for (const [filePath, previousEntry] of previous) {
|
|
20068
|
+
const currentEntry = current.get(filePath);
|
|
20069
|
+
if (!currentEntry) changes.push({ type: "unlink", path: filePath });
|
|
20070
|
+
else if (forcedChanges.has(filePath) || currentEntry.size !== previousEntry.size || currentEntry.mtimeMs !== previousEntry.mtimeMs) {
|
|
20071
|
+
changes.push({ type: "change", path: filePath });
|
|
20072
|
+
}
|
|
20073
|
+
}
|
|
20074
|
+
for (const [filePath] of current) {
|
|
20075
|
+
if (!previous.has(filePath)) changes.push({ type: "add", path: filePath });
|
|
20076
|
+
}
|
|
20077
|
+
return changes.sort((left, right) => left.path.localeCompare(right.path) || diffTypeOrder[left.type] - diffTypeOrder[right.type]);
|
|
20078
|
+
}
|
|
20079
|
+
|
|
20080
|
+
// src/watcher/snapshot-reconciler.ts
|
|
20081
|
+
var FileSnapshotReconciler = class {
|
|
20082
|
+
constructor(projectRoot, config, configPaths) {
|
|
20083
|
+
this.projectRoot = projectRoot;
|
|
20084
|
+
this.config = config;
|
|
20085
|
+
this.configPaths = configPaths;
|
|
20086
|
+
}
|
|
20087
|
+
projectRoot;
|
|
20088
|
+
config;
|
|
20089
|
+
configPaths;
|
|
20090
|
+
snapshot = null;
|
|
20091
|
+
reconciliationTail = Promise.resolve();
|
|
20092
|
+
async initialize() {
|
|
20093
|
+
this.snapshot = (await buildFileSnapshotScan(this.projectRoot, this.config, this.configPaths)).entries;
|
|
20094
|
+
}
|
|
20095
|
+
async reconcile(invalidations = []) {
|
|
20096
|
+
if (this.snapshot === null) {
|
|
20097
|
+
throw new Error("FileSnapshotReconciler is not initialized. Call initialize() before reconcile().");
|
|
20098
|
+
}
|
|
20099
|
+
const reconciliation = this.reconciliationTail.then(async () => {
|
|
20100
|
+
const previousSnapshot = this.snapshot;
|
|
20101
|
+
if (previousSnapshot === null) {
|
|
20102
|
+
throw new Error("FileSnapshotReconciler is not initialized. Call initialize() before reconcile().");
|
|
20103
|
+
}
|
|
20104
|
+
const normalizedInvalidations = invalidations.map((invalidation) => typeof invalidation === "string" || invalidation === null ? { path: invalidation, forceChange: false } : { path: invalidation.path, forceChange: invalidation.forceChange === true });
|
|
20105
|
+
const scopedPaths = normalizedInvalidations.map((invalidation) => invalidation.path).filter((filePath) => filePath !== null);
|
|
20106
|
+
const scan = scopedPaths.length === 0 || scopedPaths.length !== normalizedInvalidations.length ? await buildFileSnapshotScan(this.projectRoot, this.config, this.configPaths) : await this.reconcilePaths(previousSnapshot, scopedPaths);
|
|
20107
|
+
const nextSnapshot = completeFileSnapshot(previousSnapshot, scan);
|
|
20108
|
+
const forcedChanges = new Set(normalizedInvalidations.filter((invalidation) => invalidation.path !== null && invalidation.forceChange).map((invalidation) => invalidation.path));
|
|
20109
|
+
const changes = diffFileSnapshots(previousSnapshot, nextSnapshot, forcedChanges);
|
|
20110
|
+
this.snapshot = nextSnapshot;
|
|
20111
|
+
return changes;
|
|
20112
|
+
});
|
|
20113
|
+
this.reconciliationTail = reconciliation.then(() => void 0, () => void 0);
|
|
20114
|
+
return reconciliation;
|
|
20115
|
+
}
|
|
20116
|
+
async reconcilePaths(previousSnapshot, invalidatedPaths) {
|
|
20117
|
+
const scopes = this.getScopes(invalidatedPaths);
|
|
20118
|
+
const entries = new Map(previousSnapshot);
|
|
20119
|
+
const unreadablePrefixes = /* @__PURE__ */ new Set();
|
|
20120
|
+
for (const scope of scopes) {
|
|
20121
|
+
for (const previousPath of entries.keys()) {
|
|
20122
|
+
if (isWithinPath(scope, previousPath)) entries.delete(previousPath);
|
|
20123
|
+
}
|
|
20124
|
+
const scopedScan = await buildFileSnapshotForPathScan(this.projectRoot, this.config, this.configPaths, scope);
|
|
20125
|
+
for (const [filePath, entry] of scopedScan.entries) entries.set(filePath, entry);
|
|
20126
|
+
for (const unreadablePrefix of scopedScan.unreadablePrefixes) unreadablePrefixes.add(unreadablePrefix);
|
|
20127
|
+
}
|
|
20128
|
+
return { entries, unreadablePrefixes };
|
|
20129
|
+
}
|
|
20130
|
+
getScopes(invalidatedPaths) {
|
|
20131
|
+
const uniquePaths = [...new Set(invalidatedPaths)].sort((left, right) => left.length - right.length);
|
|
20132
|
+
return uniquePaths.filter((candidate, index) => !uniquePaths.slice(0, index).some(
|
|
20133
|
+
(ancestor) => isWithinPath(ancestor, candidate)
|
|
20134
|
+
));
|
|
20135
|
+
}
|
|
20136
|
+
};
|
|
20137
|
+
|
|
20138
|
+
// src/watcher/file-watcher.ts
|
|
19950
20139
|
var FileWatcher = class {
|
|
19951
20140
|
watcher = null;
|
|
19952
20141
|
projectRoot;
|
|
19953
20142
|
config;
|
|
19954
20143
|
configPath;
|
|
20144
|
+
backend;
|
|
19955
20145
|
projectConfigPaths;
|
|
19956
20146
|
pendingChanges = /* @__PURE__ */ new Map();
|
|
19957
20147
|
debounceTimer = null;
|
|
@@ -19961,44 +20151,74 @@ var FileWatcher = class {
|
|
|
19961
20151
|
resolveReady = null;
|
|
19962
20152
|
pollingFallbackAttempted = false;
|
|
19963
20153
|
pendingClose = null;
|
|
20154
|
+
startupReadySignals = 1;
|
|
20155
|
+
nativeWatcher = null;
|
|
20156
|
+
nativeReconciler = null;
|
|
20157
|
+
nativeSetupGeneration = 0;
|
|
20158
|
+
nativeStarting = false;
|
|
20159
|
+
nativeInitializing = false;
|
|
20160
|
+
nativeReconcileTimer = null;
|
|
20161
|
+
nativeInvalidatedPaths = /* @__PURE__ */ new Map();
|
|
20162
|
+
configPathStates = /* @__PURE__ */ new Map();
|
|
19964
20163
|
constructor(projectRoot, config, host, options = {}) {
|
|
19965
20164
|
this.projectRoot = projectRoot;
|
|
19966
20165
|
this.config = config;
|
|
20166
|
+
this.backend = options.backend ?? "auto";
|
|
19967
20167
|
this.configPath = options.configPath;
|
|
19968
20168
|
this.projectConfigPaths = options.configPath ? [options.configPath] : getProjectConfigCandidatePaths(projectRoot, host);
|
|
19969
20169
|
}
|
|
19970
20170
|
start(handler) {
|
|
19971
|
-
if (this.watcher) {
|
|
20171
|
+
if (this.watcher || this.nativeWatcher || this.nativeStarting) {
|
|
19972
20172
|
return;
|
|
19973
20173
|
}
|
|
19974
20174
|
this.onChanges = handler;
|
|
19975
20175
|
this.pollingFallbackAttempted = false;
|
|
19976
20176
|
this.resetReady();
|
|
20177
|
+
if (this.shouldUseNativeWatcher()) {
|
|
20178
|
+
if (this.hasExternalConfigWatchTarget()) {
|
|
20179
|
+
this.setStartupReadySignals(2);
|
|
20180
|
+
this.startExternalConfigWatcher();
|
|
20181
|
+
}
|
|
20182
|
+
this.nativeStarting = true;
|
|
20183
|
+
void this.createNativeWatcher();
|
|
20184
|
+
return;
|
|
20185
|
+
}
|
|
19977
20186
|
this.createWatcher();
|
|
19978
20187
|
}
|
|
19979
20188
|
resetReady() {
|
|
19980
|
-
this.readyPromise = new Promise((
|
|
19981
|
-
this.resolveReady =
|
|
20189
|
+
this.readyPromise = new Promise((resolve20) => {
|
|
20190
|
+
this.resolveReady = resolve20;
|
|
19982
20191
|
});
|
|
20192
|
+
this.startupReadySignals = 1;
|
|
19983
20193
|
}
|
|
19984
|
-
|
|
19985
|
-
|
|
19986
|
-
|
|
19987
|
-
|
|
19988
|
-
|
|
19989
|
-
|
|
19990
|
-
|
|
19991
|
-
|
|
19992
|
-
|
|
19993
|
-
|
|
19994
|
-
|
|
19995
|
-
|
|
19996
|
-
watchTargets = [this.projectRoot, ...uniqueExternalConfigTargets];
|
|
19997
|
-
}
|
|
20194
|
+
setStartupReadySignals(expectedSignals) {
|
|
20195
|
+
if (!this.readyPromise) {
|
|
20196
|
+
return;
|
|
20197
|
+
}
|
|
20198
|
+
this.startupReadySignals = Math.max(0, expectedSignals);
|
|
20199
|
+
}
|
|
20200
|
+
reportStartupReadySignal() {
|
|
20201
|
+
if (!this.readyPromise || !this.resolveReady) {
|
|
20202
|
+
return;
|
|
20203
|
+
}
|
|
20204
|
+
if (this.startupReadySignals <= 0) {
|
|
20205
|
+
return;
|
|
19998
20206
|
}
|
|
20207
|
+
this.startupReadySignals -= 1;
|
|
20208
|
+
if (this.startupReadySignals !== 0) {
|
|
20209
|
+
return;
|
|
20210
|
+
}
|
|
20211
|
+
this.resolveReady();
|
|
20212
|
+
this.resolveReady = null;
|
|
20213
|
+
}
|
|
20214
|
+
createWatcher(watchTargets, usePolling = false, reportsStartupReady = true) {
|
|
20215
|
+
let reportedStartupReady = false;
|
|
20216
|
+
this.configPathStates = this.getConfigPathStates();
|
|
20217
|
+
const ignoreFilter = createIgnoreFilter(this.projectRoot);
|
|
20218
|
+
const resolvedWatchTargets = watchTargets ?? this.getFullChokidarWatchTargets();
|
|
19999
20219
|
const watcherOptions = {
|
|
20000
20220
|
ignored: (filePath) => {
|
|
20001
|
-
const relativePath =
|
|
20221
|
+
const relativePath = path28.relative(this.projectRoot, filePath);
|
|
20002
20222
|
if (!relativePath) return false;
|
|
20003
20223
|
if (this.isProjectConfigPathOrAncestor(relativePath)) {
|
|
20004
20224
|
return false;
|
|
@@ -20006,10 +20226,10 @@ var FileWatcher = class {
|
|
|
20006
20226
|
if (this.isOutsideProjectPath(relativePath)) {
|
|
20007
20227
|
return true;
|
|
20008
20228
|
}
|
|
20009
|
-
if (hasFilteredPathSegment(relativePath,
|
|
20229
|
+
if (hasFilteredPathSegment(relativePath, path28.sep)) {
|
|
20010
20230
|
return true;
|
|
20011
20231
|
}
|
|
20012
|
-
if (isRestrictedDirectory(relativePath,
|
|
20232
|
+
if (isRestrictedDirectory(relativePath, path28.sep)) {
|
|
20013
20233
|
return true;
|
|
20014
20234
|
}
|
|
20015
20235
|
if (ignoreFilter.ignores(relativePath)) {
|
|
@@ -20042,10 +20262,13 @@ var FileWatcher = class {
|
|
|
20042
20262
|
watcher = new FSWatcher(watcherOptions);
|
|
20043
20263
|
}
|
|
20044
20264
|
this.watcher = watcher;
|
|
20045
|
-
watcher.
|
|
20265
|
+
watcher.on("ready", () => {
|
|
20046
20266
|
if (this.watcher !== watcher) return;
|
|
20047
|
-
this.
|
|
20048
|
-
|
|
20267
|
+
this.reconcileConfigPathStates();
|
|
20268
|
+
if (reportsStartupReady) {
|
|
20269
|
+
this.reportStartupReadySignal();
|
|
20270
|
+
reportedStartupReady = true;
|
|
20271
|
+
}
|
|
20049
20272
|
});
|
|
20050
20273
|
watcher.on("error", (error) => {
|
|
20051
20274
|
const err = error instanceof Error ? error : null;
|
|
@@ -20059,10 +20282,13 @@ var FileWatcher = class {
|
|
|
20059
20282
|
console.error("[codebase-index] Failed to close exhausted file watcher:", closeError);
|
|
20060
20283
|
});
|
|
20061
20284
|
if (this.onChanges) {
|
|
20285
|
+
const replacementReportsStartupReady = reportsStartupReady || reportedStartupReady;
|
|
20062
20286
|
if (!this.resolveReady) {
|
|
20063
20287
|
this.resetReady();
|
|
20288
|
+
} else if (reportedStartupReady) {
|
|
20289
|
+
this.startupReadySignals += 1;
|
|
20064
20290
|
}
|
|
20065
|
-
this.createWatcher(true);
|
|
20291
|
+
this.createWatcher(resolvedWatchTargets, true, replacementReportsStartupReady);
|
|
20066
20292
|
} else {
|
|
20067
20293
|
this.watcher = null;
|
|
20068
20294
|
}
|
|
@@ -20073,13 +20299,166 @@ var FileWatcher = class {
|
|
|
20073
20299
|
watcher.on("add", (filePath) => this.handleChange(watcher, "add", filePath));
|
|
20074
20300
|
watcher.on("change", (filePath) => this.handleChange(watcher, "change", filePath));
|
|
20075
20301
|
watcher.on("unlink", (filePath) => this.handleChange(watcher, "unlink", filePath));
|
|
20076
|
-
watcher.add(
|
|
20302
|
+
watcher.add(resolvedWatchTargets);
|
|
20303
|
+
}
|
|
20304
|
+
shouldUseNativeWatcher() {
|
|
20305
|
+
if (this.backend === "chokidar") {
|
|
20306
|
+
return false;
|
|
20307
|
+
}
|
|
20308
|
+
return true;
|
|
20309
|
+
}
|
|
20310
|
+
getFullChokidarWatchTargets() {
|
|
20311
|
+
if (this.configPath) {
|
|
20312
|
+
return [this.projectRoot, this.configPath];
|
|
20313
|
+
}
|
|
20314
|
+
const externalConfigTargets = this.getExternalConfigWatchTargets();
|
|
20315
|
+
if (externalConfigTargets.length === 0) {
|
|
20316
|
+
return this.projectRoot;
|
|
20317
|
+
}
|
|
20318
|
+
return [this.projectRoot, ...externalConfigTargets];
|
|
20319
|
+
}
|
|
20320
|
+
getExternalConfigWatchTargets() {
|
|
20321
|
+
return [...new Set(
|
|
20322
|
+
this.projectConfigPaths.filter((projectConfigPath) => {
|
|
20323
|
+
const relativeConfigPath = path28.relative(this.projectRoot, projectConfigPath);
|
|
20324
|
+
return this.isOutsideProjectPath(relativeConfigPath);
|
|
20325
|
+
}).map((projectConfigPath) => {
|
|
20326
|
+
if ((0, import_fs19.existsSync)(projectConfigPath)) {
|
|
20327
|
+
return projectConfigPath;
|
|
20328
|
+
}
|
|
20329
|
+
return this.getNearestExistingDirectory(path28.dirname(projectConfigPath));
|
|
20330
|
+
})
|
|
20331
|
+
)];
|
|
20332
|
+
}
|
|
20333
|
+
hasExternalConfigWatchTarget() {
|
|
20334
|
+
return this.getExternalConfigWatchTargets().length > 0;
|
|
20335
|
+
}
|
|
20336
|
+
startExternalConfigWatcher(usePolling = false) {
|
|
20337
|
+
const externalTargets = this.getExternalConfigWatchTargets();
|
|
20338
|
+
if (externalTargets.length === 0) {
|
|
20339
|
+
return;
|
|
20340
|
+
}
|
|
20341
|
+
this.createWatcher(externalTargets, usePolling);
|
|
20342
|
+
}
|
|
20343
|
+
async createNativeWatcher() {
|
|
20344
|
+
const generation = ++this.nativeSetupGeneration;
|
|
20345
|
+
const reconciler = new FileSnapshotReconciler(this.projectRoot, this.config, this.projectConfigPaths);
|
|
20346
|
+
const watcher = new NativeRecursiveWatcher(
|
|
20347
|
+
this.projectRoot,
|
|
20348
|
+
(filePath) => this.scheduleNativeReconciliation(generation, filePath),
|
|
20349
|
+
{ onError: (error) => void this.fallbackFromNativeWatcher(generation, error) }
|
|
20350
|
+
);
|
|
20351
|
+
this.nativeReconciler = reconciler;
|
|
20352
|
+
this.nativeWatcher = watcher;
|
|
20353
|
+
this.nativeInitializing = true;
|
|
20354
|
+
try {
|
|
20355
|
+
watcher.start();
|
|
20356
|
+
if (!this.isCurrentNativeSetup(generation)) {
|
|
20357
|
+
await watcher.stop();
|
|
20358
|
+
return;
|
|
20359
|
+
}
|
|
20360
|
+
await reconciler.initialize();
|
|
20361
|
+
if (!this.isCurrentNativeSetup(generation) || this.nativeWatcher !== watcher) {
|
|
20362
|
+
await watcher.stop();
|
|
20363
|
+
return;
|
|
20364
|
+
}
|
|
20365
|
+
this.nativeStarting = false;
|
|
20366
|
+
this.nativeInitializing = false;
|
|
20367
|
+
await this.reconcileNativeWatcherWithPendingInvalidations(generation);
|
|
20368
|
+
this.reportStartupReadySignal();
|
|
20369
|
+
} catch (error) {
|
|
20370
|
+
if (!this.isCurrentNativeSetup(generation)) return;
|
|
20371
|
+
this.nativeInitializing = false;
|
|
20372
|
+
if (this.nativeWatcher) {
|
|
20373
|
+
await this.fallbackFromNativeWatcher(generation, error);
|
|
20374
|
+
return;
|
|
20375
|
+
}
|
|
20376
|
+
this.nativeStarting = false;
|
|
20377
|
+
const externalWatcher = this.watcher;
|
|
20378
|
+
this.watcher = null;
|
|
20379
|
+
this.nativeReconciler = null;
|
|
20380
|
+
await externalWatcher?.close();
|
|
20381
|
+
console.warn("[codebase-index] Native recursive watcher unavailable; using Chokidar fallback.", error);
|
|
20382
|
+
this.setStartupReadySignals(1);
|
|
20383
|
+
this.createWatcher();
|
|
20384
|
+
}
|
|
20385
|
+
}
|
|
20386
|
+
isCurrentNativeSetup(generation) {
|
|
20387
|
+
return this.nativeSetupGeneration === generation && this.onChanges !== null;
|
|
20388
|
+
}
|
|
20389
|
+
scheduleNativeReconciliation(generation, filePath) {
|
|
20390
|
+
if (!this.isCurrentNativeSetup(generation)) return;
|
|
20391
|
+
const requiresFullReconciliation = filePath === path28.join(this.projectRoot, ".gitignore");
|
|
20392
|
+
const invalidatedPath = requiresFullReconciliation ? null : filePath;
|
|
20393
|
+
this.nativeInvalidatedPaths.set(invalidatedPath, invalidatedPath !== null);
|
|
20394
|
+
if (this.nativeReconcileTimer) {
|
|
20395
|
+
clearTimeout(this.nativeReconcileTimer);
|
|
20396
|
+
}
|
|
20397
|
+
this.nativeReconcileTimer = setTimeout(() => {
|
|
20398
|
+
this.nativeReconcileTimer = null;
|
|
20399
|
+
void this.reconcileNativeWatcherFromQueue(generation);
|
|
20400
|
+
}, 100);
|
|
20401
|
+
}
|
|
20402
|
+
reconcileNativeWatcherFromQueue(generation) {
|
|
20403
|
+
if (!this.isCurrentNativeSetup(generation) || this.nativeInitializing) return;
|
|
20404
|
+
const invalidatedPaths = this.popNativeInvalidations();
|
|
20405
|
+
if (invalidatedPaths.length === 0) return;
|
|
20406
|
+
void this.reconcileNativeWatcher(generation, invalidatedPaths);
|
|
20407
|
+
}
|
|
20408
|
+
async reconcileNativeWatcher(generation, invalidatedPaths) {
|
|
20409
|
+
if (!this.isCurrentNativeSetup(generation) || !this.nativeReconciler) return;
|
|
20410
|
+
try {
|
|
20411
|
+
const reconciler = this.nativeReconciler;
|
|
20412
|
+
const changes = await reconciler.reconcile(invalidatedPaths);
|
|
20413
|
+
if (!this.isCurrentNativeSetup(generation) || this.nativeReconciler !== reconciler) return;
|
|
20414
|
+
this.recordChanges(changes);
|
|
20415
|
+
} catch (error) {
|
|
20416
|
+
await this.fallbackFromNativeWatcher(generation, error);
|
|
20417
|
+
}
|
|
20418
|
+
}
|
|
20419
|
+
async reconcileNativeWatcherWithPendingInvalidations(generation) {
|
|
20420
|
+
const invalidatedPaths = this.popNativeInvalidations();
|
|
20421
|
+
if (invalidatedPaths.length === 0) return;
|
|
20422
|
+
await this.reconcileNativeWatcher(generation, invalidatedPaths);
|
|
20423
|
+
}
|
|
20424
|
+
popNativeInvalidations() {
|
|
20425
|
+
if (this.nativeInvalidatedPaths.size === 0) return [];
|
|
20426
|
+
const invalidations = [...this.nativeInvalidatedPaths].map(([invalidatedPath, forceChange]) => ({
|
|
20427
|
+
path: invalidatedPath,
|
|
20428
|
+
forceChange
|
|
20429
|
+
}));
|
|
20430
|
+
this.nativeInvalidatedPaths.clear();
|
|
20431
|
+
return invalidations;
|
|
20432
|
+
}
|
|
20433
|
+
async fallbackFromNativeWatcher(generation, error) {
|
|
20434
|
+
if (!this.isCurrentNativeSetup(generation)) return;
|
|
20435
|
+
const watcher = this.nativeWatcher;
|
|
20436
|
+
const externalWatcher = this.watcher;
|
|
20437
|
+
this.nativeWatcher = null;
|
|
20438
|
+
this.watcher = null;
|
|
20439
|
+
this.nativeReconciler = null;
|
|
20440
|
+
this.nativeStarting = false;
|
|
20441
|
+
this.nativeInitializing = false;
|
|
20442
|
+
this.nativeSetupGeneration += 1;
|
|
20443
|
+
if (this.nativeReconcileTimer) {
|
|
20444
|
+
clearTimeout(this.nativeReconcileTimer);
|
|
20445
|
+
this.nativeReconcileTimer = null;
|
|
20446
|
+
}
|
|
20447
|
+
this.nativeInvalidatedPaths.clear();
|
|
20448
|
+
this.setStartupReadySignals(1);
|
|
20449
|
+
console.warn("[codebase-index] Native recursive watcher failed; using Chokidar fallback.", error);
|
|
20450
|
+
await watcher?.stop();
|
|
20451
|
+
await externalWatcher?.close();
|
|
20452
|
+
if (this.onChanges) {
|
|
20453
|
+
this.createWatcher();
|
|
20454
|
+
}
|
|
20077
20455
|
}
|
|
20078
20456
|
handleChange(watcher, type, filePath) {
|
|
20079
20457
|
if (this.watcher !== watcher) {
|
|
20080
20458
|
return;
|
|
20081
20459
|
}
|
|
20082
20460
|
if (this.isProjectConfigPath(filePath)) {
|
|
20461
|
+
this.updateConfigPathState(filePath);
|
|
20083
20462
|
this.pendingChanges.set(filePath, type);
|
|
20084
20463
|
this.scheduleFlush();
|
|
20085
20464
|
return;
|
|
@@ -20094,27 +20473,33 @@ var FileWatcher = class {
|
|
|
20094
20473
|
)) {
|
|
20095
20474
|
return;
|
|
20096
20475
|
}
|
|
20097
|
-
this.
|
|
20476
|
+
this.recordChanges([{ path: filePath, type }]);
|
|
20477
|
+
}
|
|
20478
|
+
recordChanges(changes) {
|
|
20479
|
+
if (changes.length === 0) return;
|
|
20480
|
+
for (const change of changes) {
|
|
20481
|
+
this.pendingChanges.set(change.path, change.type);
|
|
20482
|
+
}
|
|
20098
20483
|
this.scheduleFlush();
|
|
20099
20484
|
}
|
|
20100
20485
|
isProjectConfigPath(filePath) {
|
|
20101
|
-
const relativePath =
|
|
20102
|
-
const normalizedRelativePath =
|
|
20486
|
+
const relativePath = path28.relative(this.projectRoot, filePath);
|
|
20487
|
+
const normalizedRelativePath = path28.normalize(relativePath);
|
|
20103
20488
|
return this.getProjectConfigRelativePaths().some((configPath) => configPath === normalizedRelativePath);
|
|
20104
20489
|
}
|
|
20105
20490
|
isProjectConfigPathOrAncestor(relativePath) {
|
|
20106
|
-
const normalizedRelativePath =
|
|
20491
|
+
const normalizedRelativePath = path28.normalize(relativePath);
|
|
20107
20492
|
return this.getProjectConfigRelativePaths().some(
|
|
20108
|
-
(configPath) => configPath === normalizedRelativePath || configPath.startsWith(`${normalizedRelativePath}${
|
|
20493
|
+
(configPath) => configPath === normalizedRelativePath || configPath.startsWith(`${normalizedRelativePath}${path28.sep}`)
|
|
20109
20494
|
);
|
|
20110
20495
|
}
|
|
20111
20496
|
isOutsideProjectPath(relativePath) {
|
|
20112
|
-
return relativePath === ".." || relativePath.startsWith(`..${
|
|
20497
|
+
return relativePath === ".." || relativePath.startsWith(`..${path28.sep}`) || path28.isAbsolute(relativePath);
|
|
20113
20498
|
}
|
|
20114
20499
|
getNearestExistingDirectory(directoryPath) {
|
|
20115
20500
|
let candidate = directoryPath;
|
|
20116
20501
|
while (!(0, import_fs19.existsSync)(candidate)) {
|
|
20117
|
-
const parent =
|
|
20502
|
+
const parent = path28.dirname(candidate);
|
|
20118
20503
|
if (parent === candidate) break;
|
|
20119
20504
|
candidate = parent;
|
|
20120
20505
|
}
|
|
@@ -20122,9 +20507,51 @@ var FileWatcher = class {
|
|
|
20122
20507
|
}
|
|
20123
20508
|
getProjectConfigRelativePaths() {
|
|
20124
20509
|
return this.projectConfigPaths.map(
|
|
20125
|
-
(configPath) =>
|
|
20510
|
+
(configPath) => path28.normalize(path28.relative(this.projectRoot, configPath))
|
|
20126
20511
|
);
|
|
20127
20512
|
}
|
|
20513
|
+
getConfigPathStates() {
|
|
20514
|
+
const states = /* @__PURE__ */ new Map();
|
|
20515
|
+
for (const configPath of this.projectConfigPaths) {
|
|
20516
|
+
const state = this.getConfigPathState(configPath);
|
|
20517
|
+
if (state) states.set(configPath, state);
|
|
20518
|
+
}
|
|
20519
|
+
return states;
|
|
20520
|
+
}
|
|
20521
|
+
getConfigPathState(configPath) {
|
|
20522
|
+
try {
|
|
20523
|
+
const stats = (0, import_fs19.statSync)(configPath);
|
|
20524
|
+
return stats.isFile() ? { mtimeMs: stats.mtimeMs, size: stats.size } : void 0;
|
|
20525
|
+
} catch (error) {
|
|
20526
|
+
void error;
|
|
20527
|
+
return void 0;
|
|
20528
|
+
}
|
|
20529
|
+
}
|
|
20530
|
+
updateConfigPathState(configPath) {
|
|
20531
|
+
const state = this.getConfigPathState(configPath);
|
|
20532
|
+
if (state) {
|
|
20533
|
+
this.configPathStates.set(configPath, state);
|
|
20534
|
+
} else {
|
|
20535
|
+
this.configPathStates.delete(configPath);
|
|
20536
|
+
}
|
|
20537
|
+
}
|
|
20538
|
+
reconcileConfigPathStates() {
|
|
20539
|
+
const nextStates = this.getConfigPathStates();
|
|
20540
|
+
const changes = [];
|
|
20541
|
+
for (const configPath of this.projectConfigPaths) {
|
|
20542
|
+
const previous = this.configPathStates.get(configPath);
|
|
20543
|
+
const next = nextStates.get(configPath);
|
|
20544
|
+
if (!previous && next) {
|
|
20545
|
+
changes.push({ path: configPath, type: "add" });
|
|
20546
|
+
} else if (previous && !next) {
|
|
20547
|
+
changes.push({ path: configPath, type: "unlink" });
|
|
20548
|
+
} else if (previous && next && (previous.size !== next.size || previous.mtimeMs !== next.mtimeMs)) {
|
|
20549
|
+
changes.push({ path: configPath, type: "change" });
|
|
20550
|
+
}
|
|
20551
|
+
}
|
|
20552
|
+
this.configPathStates = nextStates;
|
|
20553
|
+
this.recordChanges(changes);
|
|
20554
|
+
}
|
|
20128
20555
|
scheduleFlush() {
|
|
20129
20556
|
if (this.debounceTimer) {
|
|
20130
20557
|
clearTimeout(this.debounceTimer);
|
|
@@ -20138,7 +20565,7 @@ var FileWatcher = class {
|
|
|
20138
20565
|
return;
|
|
20139
20566
|
}
|
|
20140
20567
|
const changes = Array.from(this.pendingChanges.entries()).map(
|
|
20141
|
-
([
|
|
20568
|
+
([path33, type]) => ({ path: path33, type })
|
|
20142
20569
|
);
|
|
20143
20570
|
this.pendingChanges.clear();
|
|
20144
20571
|
try {
|
|
@@ -20152,20 +20579,31 @@ var FileWatcher = class {
|
|
|
20152
20579
|
clearTimeout(this.debounceTimer);
|
|
20153
20580
|
this.debounceTimer = null;
|
|
20154
20581
|
}
|
|
20582
|
+
if (this.nativeReconcileTimer) {
|
|
20583
|
+
clearTimeout(this.nativeReconcileTimer);
|
|
20584
|
+
this.nativeReconcileTimer = null;
|
|
20585
|
+
}
|
|
20586
|
+
this.nativeInvalidatedPaths.clear();
|
|
20155
20587
|
const watcher = this.watcher;
|
|
20588
|
+
const nativeWatcher = this.nativeWatcher;
|
|
20156
20589
|
const pendingClose = this.pendingClose;
|
|
20157
20590
|
const resolveReady = this.resolveReady;
|
|
20158
20591
|
this.watcher = null;
|
|
20592
|
+
this.nativeWatcher = null;
|
|
20593
|
+
this.nativeReconciler = null;
|
|
20594
|
+
this.nativeStarting = false;
|
|
20595
|
+
this.nativeInitializing = false;
|
|
20596
|
+
this.nativeSetupGeneration += 1;
|
|
20159
20597
|
this.pendingClose = null;
|
|
20160
20598
|
this.resolveReady = null;
|
|
20161
20599
|
this.readyPromise = null;
|
|
20162
20600
|
this.pendingChanges.clear();
|
|
20163
20601
|
this.onChanges = null;
|
|
20164
|
-
await Promise.all([watcher?.close(), pendingClose]);
|
|
20602
|
+
await Promise.all([watcher?.close(), nativeWatcher?.stop(), pendingClose]);
|
|
20165
20603
|
resolveReady?.();
|
|
20166
20604
|
}
|
|
20167
20605
|
isRunning() {
|
|
20168
|
-
return this.watcher !== null;
|
|
20606
|
+
return this.watcher !== null || this.nativeWatcher !== null || this.nativeStarting;
|
|
20169
20607
|
}
|
|
20170
20608
|
async waitUntilReady() {
|
|
20171
20609
|
await (this.readyPromise ?? Promise.resolve());
|
|
@@ -20173,7 +20611,7 @@ var FileWatcher = class {
|
|
|
20173
20611
|
};
|
|
20174
20612
|
|
|
20175
20613
|
// src/watcher/git-head-watcher.ts
|
|
20176
|
-
var
|
|
20614
|
+
var path29 = __toESM(require("path"), 1);
|
|
20177
20615
|
var GitHeadWatcher = class {
|
|
20178
20616
|
watcher = null;
|
|
20179
20617
|
projectRoot;
|
|
@@ -20195,13 +20633,13 @@ var GitHeadWatcher = class {
|
|
|
20195
20633
|
this.readyPromise = Promise.resolve();
|
|
20196
20634
|
return;
|
|
20197
20635
|
}
|
|
20198
|
-
this.readyPromise = new Promise((
|
|
20199
|
-
this.resolveReady =
|
|
20636
|
+
this.readyPromise = new Promise((resolve20) => {
|
|
20637
|
+
this.resolveReady = resolve20;
|
|
20200
20638
|
});
|
|
20201
20639
|
this.onBranchChange = handler;
|
|
20202
20640
|
this.currentBranch = getCurrentBranch(this.projectRoot);
|
|
20203
20641
|
const headPath = getHeadPath(this.projectRoot);
|
|
20204
|
-
const refsPath =
|
|
20642
|
+
const refsPath = path29.join(this.projectRoot, ".git", "refs", "heads");
|
|
20205
20643
|
this.watcher = chokidar_default.watch([headPath, refsPath], {
|
|
20206
20644
|
persistent: true,
|
|
20207
20645
|
ignoreInitial: true,
|
|
@@ -20337,7 +20775,7 @@ function getConfigPaths(projectRoot, host, options) {
|
|
|
20337
20775
|
|
|
20338
20776
|
// src/tools/visualize/activity.ts
|
|
20339
20777
|
var import_child_process5 = require("child_process");
|
|
20340
|
-
var
|
|
20778
|
+
var path30 = __toESM(require("path"), 1);
|
|
20341
20779
|
function attachRecentActivity(data, projectRoot) {
|
|
20342
20780
|
const activity = readGitActivity(projectRoot);
|
|
20343
20781
|
const changes = activity.size > 0 ? buildGitChanges(data, activity, projectRoot) : buildGraphChanges(data);
|
|
@@ -20499,7 +20937,7 @@ function normalizePath4(filePath) {
|
|
|
20499
20937
|
return filePath.replace(/\\/g, "/");
|
|
20500
20938
|
}
|
|
20501
20939
|
function toGitRelativePath(projectRoot, filePath) {
|
|
20502
|
-
const relativePath =
|
|
20940
|
+
const relativePath = path30.isAbsolute(filePath) ? path30.relative(projectRoot, filePath) : filePath;
|
|
20503
20941
|
return normalizePath4(relativePath);
|
|
20504
20942
|
}
|
|
20505
20943
|
|
|
@@ -20757,7 +21195,7 @@ render();
|
|
|
20757
21195
|
}
|
|
20758
21196
|
|
|
20759
21197
|
// src/tools/visualize/transform.ts
|
|
20760
|
-
var
|
|
21198
|
+
var path31 = __toESM(require("path"), 1);
|
|
20761
21199
|
|
|
20762
21200
|
// src/tools/visualize/modules.ts
|
|
20763
21201
|
var MAX_MODULES = 18;
|
|
@@ -20890,8 +21328,8 @@ function compactModules(prefixToNodes) {
|
|
|
20890
21328
|
function deriveModules(nodes) {
|
|
20891
21329
|
const initial = /* @__PURE__ */ new Map();
|
|
20892
21330
|
for (const node of nodes) {
|
|
20893
|
-
const
|
|
20894
|
-
const prefix = modulePrefixFromRelativePath(
|
|
21331
|
+
const relative14 = stripToProjectRelative(node.filePath);
|
|
21332
|
+
const prefix = modulePrefixFromRelativePath(relative14);
|
|
20895
21333
|
if (!initial.has(prefix)) initial.set(prefix, []);
|
|
20896
21334
|
initial.get(prefix)?.push(node);
|
|
20897
21335
|
}
|
|
@@ -21017,7 +21455,7 @@ function transformForVisualization(symbols, edges, options = {}) {
|
|
|
21017
21455
|
filePath: s.filePath,
|
|
21018
21456
|
kind: s.kind,
|
|
21019
21457
|
line: s.startLine,
|
|
21020
|
-
directory:
|
|
21458
|
+
directory: path31.dirname(s.filePath),
|
|
21021
21459
|
moduleId: "",
|
|
21022
21460
|
moduleLabel: ""
|
|
21023
21461
|
}));
|
|
@@ -21045,9 +21483,9 @@ function parseArgs(argv) {
|
|
|
21045
21483
|
let host = "opencode";
|
|
21046
21484
|
for (let i = 2; i < argv.length; i++) {
|
|
21047
21485
|
if (argv[i] === "--project" && argv[i + 1]) {
|
|
21048
|
-
project =
|
|
21486
|
+
project = path32.resolve(argv[++i]);
|
|
21049
21487
|
} else if (argv[i] === "--config" && argv[i + 1]) {
|
|
21050
|
-
config =
|
|
21488
|
+
config = path32.resolve(argv[++i]);
|
|
21051
21489
|
} else if (argv[i] === "--host" && argv[i + 1]) {
|
|
21052
21490
|
host = parseHostMode(argv[++i]);
|
|
21053
21491
|
} else if (argv[i] === "--host") {
|
|
@@ -21074,7 +21512,7 @@ function parseIndexArgs(argv, cwd) {
|
|
|
21074
21512
|
if (!arg.startsWith("--project=")) {
|
|
21075
21513
|
i += 1;
|
|
21076
21514
|
}
|
|
21077
|
-
project =
|
|
21515
|
+
project = path32.resolve(cwd, value);
|
|
21078
21516
|
continue;
|
|
21079
21517
|
}
|
|
21080
21518
|
if (arg === "--config" || arg.startsWith("--config=")) {
|
|
@@ -21085,7 +21523,7 @@ function parseIndexArgs(argv, cwd) {
|
|
|
21085
21523
|
if (!arg.startsWith("--config=")) {
|
|
21086
21524
|
i += 1;
|
|
21087
21525
|
}
|
|
21088
|
-
config =
|
|
21526
|
+
config = path32.resolve(cwd, value);
|
|
21089
21527
|
continue;
|
|
21090
21528
|
}
|
|
21091
21529
|
if (arg === "--host" || arg.startsWith("--host=")) {
|
|
@@ -21151,7 +21589,7 @@ function parseVisualizeArgs(argv, cwd) {
|
|
|
21151
21589
|
for (let i = 0; i < argv.length; i++) {
|
|
21152
21590
|
const arg = argv[i];
|
|
21153
21591
|
if (arg === "--project" && argv[i + 1]) {
|
|
21154
|
-
project =
|
|
21592
|
+
project = path32.resolve(argv[++i]);
|
|
21155
21593
|
} else if (arg === "--max" && argv[i + 1]) {
|
|
21156
21594
|
maxNodes = Number(argv[++i]);
|
|
21157
21595
|
} else if (arg.startsWith("--max=") || arg.startsWith("max=")) {
|
|
@@ -21188,7 +21626,7 @@ async function handleVisualizeCommand(argv, cwd) {
|
|
|
21188
21626
|
console.error("No connected symbols found. Retry with: npm run visualize -- orphans");
|
|
21189
21627
|
return 1;
|
|
21190
21628
|
}
|
|
21191
|
-
const outputPath =
|
|
21629
|
+
const outputPath = path32.join(os8.tmpdir(), `call-graph-${Date.now()}.html`);
|
|
21192
21630
|
(0, import_fs20.writeFileSync)(outputPath, generateVisualizationHtml(vizData), "utf-8");
|
|
21193
21631
|
console.log(`Temporal call graph visualization generated: ${outputPath}`);
|
|
21194
21632
|
console.log(`Nodes: ${vizData.nodes.length} | Edges: ${vizData.edges.length}`);
|
|
@@ -21220,8 +21658,60 @@ async function runMcpCli(argv) {
|
|
|
21220
21658
|
const config = parseConfig(rawConfig);
|
|
21221
21659
|
const server = createMcpServer(args.project, config, args.host);
|
|
21222
21660
|
const transport = new import_stdio.StdioServerTransport();
|
|
21223
|
-
await server.connect(transport);
|
|
21224
21661
|
let watcher = null;
|
|
21662
|
+
let shutdownPromise;
|
|
21663
|
+
const onServerClose = server.server.onclose;
|
|
21664
|
+
const shutdown = () => {
|
|
21665
|
+
if (shutdownPromise) return shutdownPromise;
|
|
21666
|
+
process.stdin.removeListener("end", requestShutdown);
|
|
21667
|
+
process.stdin.removeListener("close", requestShutdown);
|
|
21668
|
+
process.removeListener("SIGHUP", requestShutdown);
|
|
21669
|
+
process.removeListener("SIGINT", requestShutdown);
|
|
21670
|
+
process.removeListener("SIGTERM", requestShutdown);
|
|
21671
|
+
server.server.onclose = onServerClose;
|
|
21672
|
+
shutdownPromise = (async () => {
|
|
21673
|
+
let exitCode = 0;
|
|
21674
|
+
try {
|
|
21675
|
+
await watcher?.stop();
|
|
21676
|
+
} catch (error) {
|
|
21677
|
+
exitCode = 1;
|
|
21678
|
+
console.error("Failed to stop MCP file watcher cleanly:", error);
|
|
21679
|
+
}
|
|
21680
|
+
try {
|
|
21681
|
+
await stopAutoIndex(args.project, args.host);
|
|
21682
|
+
} catch (error) {
|
|
21683
|
+
exitCode = 1;
|
|
21684
|
+
console.error("Failed to stop automatic indexing cleanly:", error);
|
|
21685
|
+
}
|
|
21686
|
+
try {
|
|
21687
|
+
await server.close();
|
|
21688
|
+
} catch (error) {
|
|
21689
|
+
exitCode = 1;
|
|
21690
|
+
console.error("Failed to close MCP server cleanly:", error);
|
|
21691
|
+
}
|
|
21692
|
+
process.exit(exitCode);
|
|
21693
|
+
})();
|
|
21694
|
+
return shutdownPromise;
|
|
21695
|
+
};
|
|
21696
|
+
const requestShutdown = () => {
|
|
21697
|
+
void shutdown();
|
|
21698
|
+
};
|
|
21699
|
+
server.server.onclose = () => {
|
|
21700
|
+
try {
|
|
21701
|
+
onServerClose?.();
|
|
21702
|
+
} finally {
|
|
21703
|
+
requestShutdown();
|
|
21704
|
+
}
|
|
21705
|
+
};
|
|
21706
|
+
process.stdin.once("end", requestShutdown);
|
|
21707
|
+
process.stdin.once("close", requestShutdown);
|
|
21708
|
+
process.once("SIGINT", requestShutdown);
|
|
21709
|
+
if (process.platform !== "win32") {
|
|
21710
|
+
process.once("SIGHUP", requestShutdown);
|
|
21711
|
+
process.once("SIGTERM", requestShutdown);
|
|
21712
|
+
}
|
|
21713
|
+
await server.connect(transport);
|
|
21714
|
+
if (shutdownPromise) return;
|
|
21225
21715
|
const isHomeDir = isHomeDirectory(args.project);
|
|
21226
21716
|
const isValidProject = !isHomeDir && (!config.indexing.requireProjectMarker || hasProjectMarker(args.project));
|
|
21227
21717
|
if (config.indexing.watchFiles && isValidProject) {
|
|
@@ -21233,26 +21723,6 @@ async function runMcpCli(argv) {
|
|
|
21233
21723
|
args.config ? { configPath: args.config } : {}
|
|
21234
21724
|
);
|
|
21235
21725
|
}
|
|
21236
|
-
let shuttingDown = false;
|
|
21237
|
-
const shutdown = async () => {
|
|
21238
|
-
if (shuttingDown) return;
|
|
21239
|
-
shuttingDown = true;
|
|
21240
|
-
try {
|
|
21241
|
-
await watcher?.stop();
|
|
21242
|
-
await stopAutoIndex(args.project, args.host);
|
|
21243
|
-
await server.close();
|
|
21244
|
-
process.exit(0);
|
|
21245
|
-
} catch (error) {
|
|
21246
|
-
console.error("Failed to stop MCP server cleanly:", error);
|
|
21247
|
-
process.exit(1);
|
|
21248
|
-
}
|
|
21249
|
-
};
|
|
21250
|
-
process.on("SIGINT", () => {
|
|
21251
|
-
void shutdown();
|
|
21252
|
-
});
|
|
21253
|
-
process.on("SIGTERM", () => {
|
|
21254
|
-
void shutdown();
|
|
21255
|
-
});
|
|
21256
21726
|
}
|
|
21257
21727
|
function printIndexProgress(onProgress, title, metadata) {
|
|
21258
21728
|
const details = Object.entries(metadata).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${isSensitiveKey(key) ? "[REDACTED]" : String(value)}`).join(" ");
|