opencode-codebase-index 0.1.10 → 0.1.11
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/LICENSE +21 -0
- package/README.md +56 -29
- package/dist/index.cjs +345 -309
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +342 -306
- package/dist/index.js.map +1 -1
- package/native/codebase-index-native.darwin-arm64.node +0 -0
- package/native/codebase-index-native.darwin-x64.node +0 -0
- package/native/codebase-index-native.linux-arm64-gnu.node +0 -0
- package/native/codebase-index-native.linux-x64-gnu.node +0 -0
- package/native/codebase-index-native.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -491,7 +491,7 @@ var require_ignore = __commonJS({
|
|
|
491
491
|
// path matching.
|
|
492
492
|
// - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
|
|
493
493
|
// @returns {TestResult} true if a file is ignored
|
|
494
|
-
test(
|
|
494
|
+
test(path7, checkUnignored, mode) {
|
|
495
495
|
let ignored = false;
|
|
496
496
|
let unignored = false;
|
|
497
497
|
let matchedRule;
|
|
@@ -500,7 +500,7 @@ var require_ignore = __commonJS({
|
|
|
500
500
|
if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
|
|
501
501
|
return;
|
|
502
502
|
}
|
|
503
|
-
const matched = rule[mode].test(
|
|
503
|
+
const matched = rule[mode].test(path7);
|
|
504
504
|
if (!matched) {
|
|
505
505
|
return;
|
|
506
506
|
}
|
|
@@ -521,17 +521,17 @@ var require_ignore = __commonJS({
|
|
|
521
521
|
var throwError = (message, Ctor) => {
|
|
522
522
|
throw new Ctor(message);
|
|
523
523
|
};
|
|
524
|
-
var checkPath = (
|
|
525
|
-
if (!isString(
|
|
524
|
+
var checkPath = (path7, originalPath, doThrow) => {
|
|
525
|
+
if (!isString(path7)) {
|
|
526
526
|
return doThrow(
|
|
527
527
|
`path must be a string, but got \`${originalPath}\``,
|
|
528
528
|
TypeError
|
|
529
529
|
);
|
|
530
530
|
}
|
|
531
|
-
if (!
|
|
531
|
+
if (!path7) {
|
|
532
532
|
return doThrow(`path must not be empty`, TypeError);
|
|
533
533
|
}
|
|
534
|
-
if (checkPath.isNotRelative(
|
|
534
|
+
if (checkPath.isNotRelative(path7)) {
|
|
535
535
|
const r = "`path.relative()`d";
|
|
536
536
|
return doThrow(
|
|
537
537
|
`path should be a ${r} string, but got "${originalPath}"`,
|
|
@@ -540,7 +540,7 @@ var require_ignore = __commonJS({
|
|
|
540
540
|
}
|
|
541
541
|
return true;
|
|
542
542
|
};
|
|
543
|
-
var isNotRelative = (
|
|
543
|
+
var isNotRelative = (path7) => REGEX_TEST_INVALID_PATH.test(path7);
|
|
544
544
|
checkPath.isNotRelative = isNotRelative;
|
|
545
545
|
checkPath.convert = (p) => p;
|
|
546
546
|
var Ignore2 = class {
|
|
@@ -570,19 +570,19 @@ var require_ignore = __commonJS({
|
|
|
570
570
|
}
|
|
571
571
|
// @returns {TestResult}
|
|
572
572
|
_test(originalPath, cache, checkUnignored, slices) {
|
|
573
|
-
const
|
|
573
|
+
const path7 = originalPath && checkPath.convert(originalPath);
|
|
574
574
|
checkPath(
|
|
575
|
-
|
|
575
|
+
path7,
|
|
576
576
|
originalPath,
|
|
577
577
|
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
578
578
|
);
|
|
579
|
-
return this._t(
|
|
579
|
+
return this._t(path7, cache, checkUnignored, slices);
|
|
580
580
|
}
|
|
581
|
-
checkIgnore(
|
|
582
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
583
|
-
return this.test(
|
|
581
|
+
checkIgnore(path7) {
|
|
582
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path7)) {
|
|
583
|
+
return this.test(path7);
|
|
584
584
|
}
|
|
585
|
-
const slices =
|
|
585
|
+
const slices = path7.split(SLASH2).filter(Boolean);
|
|
586
586
|
slices.pop();
|
|
587
587
|
if (slices.length) {
|
|
588
588
|
const parent = this._t(
|
|
@@ -595,18 +595,18 @@ var require_ignore = __commonJS({
|
|
|
595
595
|
return parent;
|
|
596
596
|
}
|
|
597
597
|
}
|
|
598
|
-
return this._rules.test(
|
|
598
|
+
return this._rules.test(path7, false, MODE_CHECK_IGNORE);
|
|
599
599
|
}
|
|
600
|
-
_t(
|
|
601
|
-
if (
|
|
602
|
-
return cache[
|
|
600
|
+
_t(path7, cache, checkUnignored, slices) {
|
|
601
|
+
if (path7 in cache) {
|
|
602
|
+
return cache[path7];
|
|
603
603
|
}
|
|
604
604
|
if (!slices) {
|
|
605
|
-
slices =
|
|
605
|
+
slices = path7.split(SLASH2).filter(Boolean);
|
|
606
606
|
}
|
|
607
607
|
slices.pop();
|
|
608
608
|
if (!slices.length) {
|
|
609
|
-
return cache[
|
|
609
|
+
return cache[path7] = this._rules.test(path7, checkUnignored, MODE_IGNORE);
|
|
610
610
|
}
|
|
611
611
|
const parent = this._t(
|
|
612
612
|
slices.join(SLASH2) + SLASH2,
|
|
@@ -614,29 +614,29 @@ var require_ignore = __commonJS({
|
|
|
614
614
|
checkUnignored,
|
|
615
615
|
slices
|
|
616
616
|
);
|
|
617
|
-
return cache[
|
|
617
|
+
return cache[path7] = parent.ignored ? parent : this._rules.test(path7, checkUnignored, MODE_IGNORE);
|
|
618
618
|
}
|
|
619
|
-
ignores(
|
|
620
|
-
return this._test(
|
|
619
|
+
ignores(path7) {
|
|
620
|
+
return this._test(path7, this._ignoreCache, false).ignored;
|
|
621
621
|
}
|
|
622
622
|
createFilter() {
|
|
623
|
-
return (
|
|
623
|
+
return (path7) => !this.ignores(path7);
|
|
624
624
|
}
|
|
625
625
|
filter(paths) {
|
|
626
626
|
return makeArray(paths).filter(this.createFilter());
|
|
627
627
|
}
|
|
628
628
|
// @returns {TestResult}
|
|
629
|
-
test(
|
|
630
|
-
return this._test(
|
|
629
|
+
test(path7) {
|
|
630
|
+
return this._test(path7, this._testCache, true);
|
|
631
631
|
}
|
|
632
632
|
};
|
|
633
633
|
var factory = (options) => new Ignore2(options);
|
|
634
|
-
var isPathValid = (
|
|
634
|
+
var isPathValid = (path7) => checkPath(path7 && checkPath.convert(path7), path7, RETURN_FALSE);
|
|
635
635
|
var setupWindows = () => {
|
|
636
636
|
const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
|
|
637
637
|
checkPath.convert = makePosix;
|
|
638
638
|
const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
|
|
639
|
-
checkPath.isNotRelative = (
|
|
639
|
+
checkPath.isNotRelative = (path7) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path7) || isNotRelative(path7);
|
|
640
640
|
};
|
|
641
641
|
if (
|
|
642
642
|
// Detect `process` so that it can run in browsers.
|
|
@@ -657,8 +657,8 @@ __export(index_exports, {
|
|
|
657
657
|
default: () => index_default
|
|
658
658
|
});
|
|
659
659
|
module.exports = __toCommonJS(index_exports);
|
|
660
|
-
var
|
|
661
|
-
var
|
|
660
|
+
var import_fs4 = require("fs");
|
|
661
|
+
var path6 = __toESM(require("path"), 1);
|
|
662
662
|
|
|
663
663
|
// src/config/schema.ts
|
|
664
664
|
var DEFAULT_INCLUDE = [
|
|
@@ -693,6 +693,8 @@ function getDefaultIndexingConfig() {
|
|
|
693
693
|
autoIndex: false,
|
|
694
694
|
watchFiles: true,
|
|
695
695
|
maxFileSize: 1048576,
|
|
696
|
+
maxChunksPerFile: 100,
|
|
697
|
+
semanticOnly: false,
|
|
696
698
|
retries: 3,
|
|
697
699
|
retryDelayMs: 1e3
|
|
698
700
|
};
|
|
@@ -726,6 +728,8 @@ function parseConfig(raw) {
|
|
|
726
728
|
autoIndex: typeof rawIndexing.autoIndex === "boolean" ? rawIndexing.autoIndex : defaultIndexing.autoIndex,
|
|
727
729
|
watchFiles: typeof rawIndexing.watchFiles === "boolean" ? rawIndexing.watchFiles : defaultIndexing.watchFiles,
|
|
728
730
|
maxFileSize: typeof rawIndexing.maxFileSize === "number" ? rawIndexing.maxFileSize : defaultIndexing.maxFileSize,
|
|
731
|
+
maxChunksPerFile: typeof rawIndexing.maxChunksPerFile === "number" ? Math.max(1, rawIndexing.maxChunksPerFile) : defaultIndexing.maxChunksPerFile,
|
|
732
|
+
semanticOnly: typeof rawIndexing.semanticOnly === "boolean" ? rawIndexing.semanticOnly : defaultIndexing.semanticOnly,
|
|
729
733
|
retries: typeof rawIndexing.retries === "number" ? rawIndexing.retries : defaultIndexing.retries,
|
|
730
734
|
retryDelayMs: typeof rawIndexing.retryDelayMs === "number" ? rawIndexing.retryDelayMs : defaultIndexing.retryDelayMs
|
|
731
735
|
};
|
|
@@ -807,8 +811,8 @@ function getDefaultModelForProvider(provider) {
|
|
|
807
811
|
}
|
|
808
812
|
|
|
809
813
|
// src/indexer/index.ts
|
|
810
|
-
var
|
|
811
|
-
var
|
|
814
|
+
var import_fs3 = require("fs");
|
|
815
|
+
var path4 = __toESM(require("path"), 1);
|
|
812
816
|
|
|
813
817
|
// node_modules/eventemitter3/index.mjs
|
|
814
818
|
var import_index = __toESM(require_eventemitter3(), 1);
|
|
@@ -2626,139 +2630,39 @@ function generateChunkId(filePath, chunk) {
|
|
|
2626
2630
|
function generateChunkHash(chunk) {
|
|
2627
2631
|
return hashContent(chunk.content);
|
|
2628
2632
|
}
|
|
2629
|
-
|
|
2630
|
-
// src/indexer/inverted-index.ts
|
|
2631
|
-
var import_fs3 = require("fs");
|
|
2632
|
-
var path4 = __toESM(require("path"), 1);
|
|
2633
2633
|
var InvertedIndex = class {
|
|
2634
|
-
|
|
2635
|
-
termToChunks = /* @__PURE__ */ new Map();
|
|
2636
|
-
chunkTokens = /* @__PURE__ */ new Map();
|
|
2637
|
-
totalTokenCount = 0;
|
|
2634
|
+
inner;
|
|
2638
2635
|
constructor(indexPath) {
|
|
2639
|
-
this.
|
|
2636
|
+
this.inner = new native.InvertedIndex(indexPath);
|
|
2640
2637
|
}
|
|
2641
2638
|
load() {
|
|
2642
|
-
|
|
2643
|
-
return;
|
|
2644
|
-
}
|
|
2645
|
-
try {
|
|
2646
|
-
const content = (0, import_fs3.readFileSync)(this.indexPath, "utf-8");
|
|
2647
|
-
const data = JSON.parse(content);
|
|
2648
|
-
for (const [term, chunkIds] of Object.entries(data.termToChunks)) {
|
|
2649
|
-
this.termToChunks.set(term, new Set(chunkIds));
|
|
2650
|
-
}
|
|
2651
|
-
for (const [chunkId, tokens] of Object.entries(data.chunkTokens)) {
|
|
2652
|
-
const tokenMap = new Map(Object.entries(tokens).map(([k, v]) => [k, v]));
|
|
2653
|
-
this.chunkTokens.set(chunkId, tokenMap);
|
|
2654
|
-
for (const count of tokenMap.values()) {
|
|
2655
|
-
this.totalTokenCount += count;
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
} catch {
|
|
2659
|
-
this.termToChunks.clear();
|
|
2660
|
-
this.chunkTokens.clear();
|
|
2661
|
-
this.totalTokenCount = 0;
|
|
2662
|
-
}
|
|
2639
|
+
this.inner.load();
|
|
2663
2640
|
}
|
|
2664
2641
|
save() {
|
|
2665
|
-
|
|
2666
|
-
termToChunks: {},
|
|
2667
|
-
chunkTokens: {},
|
|
2668
|
-
avgDocLength: this.getAvgDocLength()
|
|
2669
|
-
};
|
|
2670
|
-
for (const [term, chunkIds] of this.termToChunks) {
|
|
2671
|
-
data.termToChunks[term] = Array.from(chunkIds);
|
|
2672
|
-
}
|
|
2673
|
-
for (const [chunkId, tokens] of this.chunkTokens) {
|
|
2674
|
-
data.chunkTokens[chunkId] = Object.fromEntries(tokens);
|
|
2675
|
-
}
|
|
2676
|
-
(0, import_fs3.writeFileSync)(this.indexPath, JSON.stringify(data));
|
|
2642
|
+
this.inner.save();
|
|
2677
2643
|
}
|
|
2678
2644
|
addChunk(chunkId, content) {
|
|
2679
|
-
|
|
2680
|
-
const termFreq = /* @__PURE__ */ new Map();
|
|
2681
|
-
for (const token of tokens) {
|
|
2682
|
-
termFreq.set(token, (termFreq.get(token) || 0) + 1);
|
|
2683
|
-
const chunks = this.termToChunks.get(token) || /* @__PURE__ */ new Set();
|
|
2684
|
-
chunks.add(chunkId);
|
|
2685
|
-
this.termToChunks.set(token, chunks);
|
|
2686
|
-
}
|
|
2687
|
-
this.chunkTokens.set(chunkId, termFreq);
|
|
2688
|
-
this.totalTokenCount += tokens.length;
|
|
2645
|
+
this.inner.addChunk(chunkId, content);
|
|
2689
2646
|
}
|
|
2690
2647
|
removeChunk(chunkId) {
|
|
2691
|
-
|
|
2692
|
-
if (!tokens) return;
|
|
2693
|
-
for (const [token, count] of tokens) {
|
|
2694
|
-
this.totalTokenCount -= count;
|
|
2695
|
-
const chunks = this.termToChunks.get(token);
|
|
2696
|
-
if (chunks) {
|
|
2697
|
-
chunks.delete(chunkId);
|
|
2698
|
-
if (chunks.size === 0) {
|
|
2699
|
-
this.termToChunks.delete(token);
|
|
2700
|
-
}
|
|
2701
|
-
}
|
|
2702
|
-
}
|
|
2703
|
-
this.chunkTokens.delete(chunkId);
|
|
2648
|
+
return this.inner.removeChunk(chunkId);
|
|
2704
2649
|
}
|
|
2705
|
-
search(query) {
|
|
2706
|
-
const
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
const candidateChunks = /* @__PURE__ */ new Set();
|
|
2711
|
-
for (const token of queryTokens) {
|
|
2712
|
-
const chunks = this.termToChunks.get(token);
|
|
2713
|
-
if (chunks) {
|
|
2714
|
-
for (const chunkId of chunks) {
|
|
2715
|
-
candidateChunks.add(chunkId);
|
|
2716
|
-
}
|
|
2717
|
-
}
|
|
2650
|
+
search(query, limit) {
|
|
2651
|
+
const results = this.inner.search(query, limit ?? 100);
|
|
2652
|
+
const map = /* @__PURE__ */ new Map();
|
|
2653
|
+
for (const r of results) {
|
|
2654
|
+
map.set(r.chunkId, r.score);
|
|
2718
2655
|
}
|
|
2719
|
-
|
|
2720
|
-
const k1 = 1.2;
|
|
2721
|
-
const b = 0.75;
|
|
2722
|
-
const N = this.chunkTokens.size;
|
|
2723
|
-
const avgDocLength = this.getAvgDocLength();
|
|
2724
|
-
for (const chunkId of candidateChunks) {
|
|
2725
|
-
const termFreq = this.chunkTokens.get(chunkId);
|
|
2726
|
-
if (!termFreq) continue;
|
|
2727
|
-
const docLength = Array.from(termFreq.values()).reduce((a, b2) => a + b2, 0);
|
|
2728
|
-
let score = 0;
|
|
2729
|
-
for (const term of queryTokens) {
|
|
2730
|
-
const tf = termFreq.get(term) || 0;
|
|
2731
|
-
if (tf === 0) continue;
|
|
2732
|
-
const df = this.termToChunks.get(term)?.size || 0;
|
|
2733
|
-
const idf = Math.log((N - df + 0.5) / (df + 0.5) + 1);
|
|
2734
|
-
const tfNorm = tf * (k1 + 1) / (tf + k1 * (1 - b + b * (docLength / avgDocLength)));
|
|
2735
|
-
score += idf * tfNorm;
|
|
2736
|
-
}
|
|
2737
|
-
scores.set(chunkId, score);
|
|
2738
|
-
}
|
|
2739
|
-
const maxScore = Math.max(...scores.values(), 1);
|
|
2740
|
-
for (const [chunkId, score] of scores) {
|
|
2741
|
-
scores.set(chunkId, score / maxScore);
|
|
2742
|
-
}
|
|
2743
|
-
return scores;
|
|
2656
|
+
return map;
|
|
2744
2657
|
}
|
|
2745
2658
|
hasChunk(chunkId) {
|
|
2746
|
-
return this.
|
|
2659
|
+
return this.inner.hasChunk(chunkId);
|
|
2747
2660
|
}
|
|
2748
2661
|
clear() {
|
|
2749
|
-
this.
|
|
2750
|
-
this.chunkTokens.clear();
|
|
2751
|
-
this.totalTokenCount = 0;
|
|
2662
|
+
this.inner.clear();
|
|
2752
2663
|
}
|
|
2753
2664
|
getDocumentCount() {
|
|
2754
|
-
return this.
|
|
2755
|
-
}
|
|
2756
|
-
getAvgDocLength() {
|
|
2757
|
-
const count = this.chunkTokens.size;
|
|
2758
|
-
return count > 0 ? this.totalTokenCount / count : 100;
|
|
2759
|
-
}
|
|
2760
|
-
tokenize(text) {
|
|
2761
|
-
return text.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((t) => t.length > 2);
|
|
2665
|
+
return this.inner.documentCount();
|
|
2762
2666
|
}
|
|
2763
2667
|
};
|
|
2764
2668
|
|
|
@@ -2773,23 +2677,25 @@ var Indexer = class {
|
|
|
2773
2677
|
detectedProvider = null;
|
|
2774
2678
|
fileHashCache = /* @__PURE__ */ new Map();
|
|
2775
2679
|
fileHashCachePath = "";
|
|
2680
|
+
failedBatchesPath = "";
|
|
2776
2681
|
constructor(projectRoot, config) {
|
|
2777
2682
|
this.projectRoot = projectRoot;
|
|
2778
2683
|
this.config = config;
|
|
2779
2684
|
this.indexPath = this.getIndexPath();
|
|
2780
|
-
this.fileHashCachePath =
|
|
2685
|
+
this.fileHashCachePath = path4.join(this.indexPath, "file-hashes.json");
|
|
2686
|
+
this.failedBatchesPath = path4.join(this.indexPath, "failed-batches.json");
|
|
2781
2687
|
}
|
|
2782
2688
|
getIndexPath() {
|
|
2783
2689
|
if (this.config.scope === "global") {
|
|
2784
2690
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
2785
|
-
return
|
|
2691
|
+
return path4.join(homeDir, ".opencode", "global-index");
|
|
2786
2692
|
}
|
|
2787
|
-
return
|
|
2693
|
+
return path4.join(this.projectRoot, ".opencode", "index");
|
|
2788
2694
|
}
|
|
2789
2695
|
loadFileHashCache() {
|
|
2790
2696
|
try {
|
|
2791
|
-
if ((0,
|
|
2792
|
-
const data = (0,
|
|
2697
|
+
if ((0, import_fs3.existsSync)(this.fileHashCachePath)) {
|
|
2698
|
+
const data = (0, import_fs3.readFileSync)(this.fileHashCachePath, "utf-8");
|
|
2793
2699
|
const parsed = JSON.parse(data);
|
|
2794
2700
|
this.fileHashCache = new Map(Object.entries(parsed));
|
|
2795
2701
|
}
|
|
@@ -2802,7 +2708,38 @@ var Indexer = class {
|
|
|
2802
2708
|
for (const [k, v] of this.fileHashCache) {
|
|
2803
2709
|
obj[k] = v;
|
|
2804
2710
|
}
|
|
2805
|
-
(0,
|
|
2711
|
+
(0, import_fs3.writeFileSync)(this.fileHashCachePath, JSON.stringify(obj));
|
|
2712
|
+
}
|
|
2713
|
+
loadFailedBatches() {
|
|
2714
|
+
try {
|
|
2715
|
+
if ((0, import_fs3.existsSync)(this.failedBatchesPath)) {
|
|
2716
|
+
const data = (0, import_fs3.readFileSync)(this.failedBatchesPath, "utf-8");
|
|
2717
|
+
return JSON.parse(data);
|
|
2718
|
+
}
|
|
2719
|
+
} catch {
|
|
2720
|
+
return [];
|
|
2721
|
+
}
|
|
2722
|
+
return [];
|
|
2723
|
+
}
|
|
2724
|
+
saveFailedBatches(batches) {
|
|
2725
|
+
if (batches.length === 0) {
|
|
2726
|
+
if ((0, import_fs3.existsSync)(this.failedBatchesPath)) {
|
|
2727
|
+
import_fs3.promises.unlink(this.failedBatchesPath).catch(() => {
|
|
2728
|
+
});
|
|
2729
|
+
}
|
|
2730
|
+
return;
|
|
2731
|
+
}
|
|
2732
|
+
(0, import_fs3.writeFileSync)(this.failedBatchesPath, JSON.stringify(batches, null, 2));
|
|
2733
|
+
}
|
|
2734
|
+
addFailedBatch(batch, error) {
|
|
2735
|
+
const existing = this.loadFailedBatches();
|
|
2736
|
+
existing.push({
|
|
2737
|
+
chunks: batch,
|
|
2738
|
+
error,
|
|
2739
|
+
attemptCount: 1,
|
|
2740
|
+
lastAttempt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2741
|
+
});
|
|
2742
|
+
this.saveFailedBatches(existing);
|
|
2806
2743
|
}
|
|
2807
2744
|
async initialize() {
|
|
2808
2745
|
this.detectedProvider = await detectEmbeddingProvider(this.config.embeddingProvider);
|
|
@@ -2815,15 +2752,16 @@ var Indexer = class {
|
|
|
2815
2752
|
this.detectedProvider.credentials,
|
|
2816
2753
|
this.detectedProvider.modelInfo
|
|
2817
2754
|
);
|
|
2818
|
-
await
|
|
2755
|
+
await import_fs3.promises.mkdir(this.indexPath, { recursive: true });
|
|
2819
2756
|
const dimensions = this.detectedProvider.modelInfo.dimensions;
|
|
2820
|
-
const storePath =
|
|
2757
|
+
const storePath = path4.join(this.indexPath, "vectors");
|
|
2821
2758
|
this.store = new VectorStore(storePath, dimensions);
|
|
2822
|
-
const indexFilePath =
|
|
2823
|
-
if ((0,
|
|
2759
|
+
const indexFilePath = path4.join(this.indexPath, "vectors.usearch");
|
|
2760
|
+
if ((0, import_fs3.existsSync)(indexFilePath)) {
|
|
2824
2761
|
this.store.load();
|
|
2825
2762
|
}
|
|
2826
|
-
|
|
2763
|
+
const invertedIndexPath = path4.join(this.indexPath, "inverted-index.json");
|
|
2764
|
+
this.invertedIndex = new InvertedIndex(invertedIndexPath);
|
|
2827
2765
|
this.invertedIndex.load();
|
|
2828
2766
|
}
|
|
2829
2767
|
async ensureInitialized() {
|
|
@@ -2887,7 +2825,7 @@ var Indexer = class {
|
|
|
2887
2825
|
if (this.fileHashCache.get(f.path) === currentHash) {
|
|
2888
2826
|
unchangedFilePaths.add(f.path);
|
|
2889
2827
|
} else {
|
|
2890
|
-
const content = await
|
|
2828
|
+
const content = await import_fs3.promises.readFile(f.path, "utf-8");
|
|
2891
2829
|
changedFiles.push({ path: f.path, content, hash: currentHash });
|
|
2892
2830
|
}
|
|
2893
2831
|
}
|
|
@@ -2922,14 +2860,22 @@ var Indexer = class {
|
|
|
2922
2860
|
for (const parsed of parsedFiles) {
|
|
2923
2861
|
currentFilePaths.add(parsed.path);
|
|
2924
2862
|
if (parsed.chunks.length === 0) {
|
|
2925
|
-
const relativePath =
|
|
2863
|
+
const relativePath = path4.relative(this.projectRoot, parsed.path);
|
|
2926
2864
|
stats.parseFailures.push(relativePath);
|
|
2927
2865
|
}
|
|
2866
|
+
let fileChunkCount = 0;
|
|
2928
2867
|
for (const chunk of parsed.chunks) {
|
|
2868
|
+
if (fileChunkCount >= this.config.indexing.maxChunksPerFile) {
|
|
2869
|
+
break;
|
|
2870
|
+
}
|
|
2871
|
+
if (this.config.indexing.semanticOnly && chunk.chunkType === "other") {
|
|
2872
|
+
continue;
|
|
2873
|
+
}
|
|
2929
2874
|
const id = generateChunkId(parsed.path, chunk);
|
|
2930
2875
|
const contentHash = generateChunkHash(chunk);
|
|
2931
2876
|
currentChunkIds.add(id);
|
|
2932
2877
|
if (existingChunks.get(id) === contentHash) {
|
|
2878
|
+
fileChunkCount++;
|
|
2933
2879
|
continue;
|
|
2934
2880
|
}
|
|
2935
2881
|
const text = createEmbeddingText(chunk, parsed.path);
|
|
@@ -2943,6 +2889,7 @@ var Indexer = class {
|
|
|
2943
2889
|
hash: contentHash
|
|
2944
2890
|
};
|
|
2945
2891
|
pendingChunks.push({ id, text, content: chunk.content, metadata });
|
|
2892
|
+
fileChunkCount++;
|
|
2946
2893
|
}
|
|
2947
2894
|
}
|
|
2948
2895
|
let removedCount = 0;
|
|
@@ -3032,6 +2979,7 @@ var Indexer = class {
|
|
|
3032
2979
|
});
|
|
3033
2980
|
} catch (error) {
|
|
3034
2981
|
stats.failedChunks += batch.length;
|
|
2982
|
+
this.addFailedBatch(batch, String(error));
|
|
3035
2983
|
console.error(`Failed to embed batch after retries: ${error}`);
|
|
3036
2984
|
}
|
|
3037
2985
|
});
|
|
@@ -3049,6 +2997,9 @@ var Indexer = class {
|
|
|
3049
2997
|
this.fileHashCache = currentFileHashes;
|
|
3050
2998
|
this.saveFileHashCache();
|
|
3051
2999
|
stats.durationMs = Date.now() - startTime;
|
|
3000
|
+
if (stats.failedChunks > 0) {
|
|
3001
|
+
stats.failedBatchesPath = this.failedBatchesPath;
|
|
3002
|
+
}
|
|
3052
3003
|
onProgress?.({
|
|
3053
3004
|
phase: "complete",
|
|
3054
3005
|
filesProcessed: files.length,
|
|
@@ -3091,7 +3042,7 @@ var Indexer = class {
|
|
|
3091
3042
|
let contextEndLine = r.metadata.endLine;
|
|
3092
3043
|
if (this.config.search.includeContext) {
|
|
3093
3044
|
try {
|
|
3094
|
-
const fileContent = await
|
|
3045
|
+
const fileContent = await import_fs3.promises.readFile(
|
|
3095
3046
|
r.metadata.filePath,
|
|
3096
3047
|
"utf-8"
|
|
3097
3048
|
);
|
|
@@ -3194,7 +3145,7 @@ var Indexer = class {
|
|
|
3194
3145
|
const removedFilePaths = [];
|
|
3195
3146
|
let removedCount = 0;
|
|
3196
3147
|
for (const [filePath, chunkKeys] of filePathsToChunkKeys) {
|
|
3197
|
-
if (!(0,
|
|
3148
|
+
if (!(0, import_fs3.existsSync)(filePath)) {
|
|
3198
3149
|
for (const key of chunkKeys) {
|
|
3199
3150
|
store.remove(key);
|
|
3200
3151
|
invertedIndex.removeChunk(key);
|
|
@@ -3209,6 +3160,58 @@ var Indexer = class {
|
|
|
3209
3160
|
}
|
|
3210
3161
|
return { removed: removedCount, filePaths: removedFilePaths };
|
|
3211
3162
|
}
|
|
3163
|
+
async retryFailedBatches() {
|
|
3164
|
+
const { store, provider, invertedIndex } = await this.ensureInitialized();
|
|
3165
|
+
const failedBatches = this.loadFailedBatches();
|
|
3166
|
+
if (failedBatches.length === 0) {
|
|
3167
|
+
return { succeeded: 0, failed: 0, remaining: 0 };
|
|
3168
|
+
}
|
|
3169
|
+
let succeeded = 0;
|
|
3170
|
+
let failed = 0;
|
|
3171
|
+
const stillFailing = [];
|
|
3172
|
+
for (const batch of failedBatches) {
|
|
3173
|
+
try {
|
|
3174
|
+
const result = await pRetry(
|
|
3175
|
+
async () => {
|
|
3176
|
+
const texts = batch.chunks.map((c) => c.text);
|
|
3177
|
+
return provider.embedBatch(texts);
|
|
3178
|
+
},
|
|
3179
|
+
{
|
|
3180
|
+
retries: this.config.indexing.retries,
|
|
3181
|
+
minTimeout: this.config.indexing.retryDelayMs
|
|
3182
|
+
}
|
|
3183
|
+
);
|
|
3184
|
+
const items = batch.chunks.map((chunk, idx) => ({
|
|
3185
|
+
id: chunk.id,
|
|
3186
|
+
vector: result.embeddings[idx],
|
|
3187
|
+
metadata: chunk.metadata
|
|
3188
|
+
}));
|
|
3189
|
+
store.addBatch(items);
|
|
3190
|
+
for (const chunk of batch.chunks) {
|
|
3191
|
+
invertedIndex.removeChunk(chunk.id);
|
|
3192
|
+
invertedIndex.addChunk(chunk.id, chunk.content);
|
|
3193
|
+
}
|
|
3194
|
+
succeeded += batch.chunks.length;
|
|
3195
|
+
} catch (error) {
|
|
3196
|
+
failed += batch.chunks.length;
|
|
3197
|
+
stillFailing.push({
|
|
3198
|
+
...batch,
|
|
3199
|
+
attemptCount: batch.attemptCount + 1,
|
|
3200
|
+
lastAttempt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3201
|
+
error: String(error)
|
|
3202
|
+
});
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
this.saveFailedBatches(stillFailing);
|
|
3206
|
+
if (succeeded > 0) {
|
|
3207
|
+
store.save();
|
|
3208
|
+
invertedIndex.save();
|
|
3209
|
+
}
|
|
3210
|
+
return { succeeded, failed, remaining: stillFailing.length };
|
|
3211
|
+
}
|
|
3212
|
+
getFailedBatchesCount() {
|
|
3213
|
+
return this.loadFailedBatches().length;
|
|
3214
|
+
}
|
|
3212
3215
|
};
|
|
3213
3216
|
|
|
3214
3217
|
// node_modules/chokidar/index.js
|
|
@@ -3301,7 +3304,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
3301
3304
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
3302
3305
|
const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
|
|
3303
3306
|
if (wantBigintFsStats) {
|
|
3304
|
-
this._stat = (
|
|
3307
|
+
this._stat = (path7) => statMethod(path7, { bigint: true });
|
|
3305
3308
|
} else {
|
|
3306
3309
|
this._stat = statMethod;
|
|
3307
3310
|
}
|
|
@@ -3326,8 +3329,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
3326
3329
|
const par = this.parent;
|
|
3327
3330
|
const fil = par && par.files;
|
|
3328
3331
|
if (fil && fil.length > 0) {
|
|
3329
|
-
const { path:
|
|
3330
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
3332
|
+
const { path: path7, depth } = par;
|
|
3333
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path7));
|
|
3331
3334
|
const awaited = await Promise.all(slice);
|
|
3332
3335
|
for (const entry of awaited) {
|
|
3333
3336
|
if (!entry)
|
|
@@ -3367,20 +3370,20 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
3367
3370
|
this.reading = false;
|
|
3368
3371
|
}
|
|
3369
3372
|
}
|
|
3370
|
-
async _exploreDir(
|
|
3373
|
+
async _exploreDir(path7, depth) {
|
|
3371
3374
|
let files;
|
|
3372
3375
|
try {
|
|
3373
|
-
files = await (0, import_promises.readdir)(
|
|
3376
|
+
files = await (0, import_promises.readdir)(path7, this._rdOptions);
|
|
3374
3377
|
} catch (error) {
|
|
3375
3378
|
this._onError(error);
|
|
3376
3379
|
}
|
|
3377
|
-
return { files, depth, path:
|
|
3380
|
+
return { files, depth, path: path7 };
|
|
3378
3381
|
}
|
|
3379
|
-
async _formatEntry(dirent,
|
|
3382
|
+
async _formatEntry(dirent, path7) {
|
|
3380
3383
|
let entry;
|
|
3381
3384
|
const basename3 = this._isDirent ? dirent.name : dirent;
|
|
3382
3385
|
try {
|
|
3383
|
-
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(
|
|
3386
|
+
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path7, basename3));
|
|
3384
3387
|
entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename3 };
|
|
3385
3388
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
3386
3389
|
} catch (err) {
|
|
@@ -3780,16 +3783,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
3780
3783
|
};
|
|
3781
3784
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
3782
3785
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
3783
|
-
function createFsWatchInstance(
|
|
3786
|
+
function createFsWatchInstance(path7, options, listener, errHandler, emitRaw) {
|
|
3784
3787
|
const handleEvent = (rawEvent, evPath) => {
|
|
3785
|
-
listener(
|
|
3786
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
3787
|
-
if (evPath &&
|
|
3788
|
-
fsWatchBroadcast(sp.resolve(
|
|
3788
|
+
listener(path7);
|
|
3789
|
+
emitRaw(rawEvent, evPath, { watchedPath: path7 });
|
|
3790
|
+
if (evPath && path7 !== evPath) {
|
|
3791
|
+
fsWatchBroadcast(sp.resolve(path7, evPath), KEY_LISTENERS, sp.join(path7, evPath));
|
|
3789
3792
|
}
|
|
3790
3793
|
};
|
|
3791
3794
|
try {
|
|
3792
|
-
return (0, import_node_fs.watch)(
|
|
3795
|
+
return (0, import_node_fs.watch)(path7, {
|
|
3793
3796
|
persistent: options.persistent
|
|
3794
3797
|
}, handleEvent);
|
|
3795
3798
|
} catch (error) {
|
|
@@ -3805,12 +3808,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
3805
3808
|
listener(val1, val2, val3);
|
|
3806
3809
|
});
|
|
3807
3810
|
};
|
|
3808
|
-
var setFsWatchListener = (
|
|
3811
|
+
var setFsWatchListener = (path7, fullPath, options, handlers) => {
|
|
3809
3812
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
3810
3813
|
let cont = FsWatchInstances.get(fullPath);
|
|
3811
3814
|
let watcher;
|
|
3812
3815
|
if (!options.persistent) {
|
|
3813
|
-
watcher = createFsWatchInstance(
|
|
3816
|
+
watcher = createFsWatchInstance(path7, options, listener, errHandler, rawEmitter);
|
|
3814
3817
|
if (!watcher)
|
|
3815
3818
|
return;
|
|
3816
3819
|
return watcher.close.bind(watcher);
|
|
@@ -3821,7 +3824,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
3821
3824
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
3822
3825
|
} else {
|
|
3823
3826
|
watcher = createFsWatchInstance(
|
|
3824
|
-
|
|
3827
|
+
path7,
|
|
3825
3828
|
options,
|
|
3826
3829
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
3827
3830
|
errHandler,
|
|
@@ -3836,7 +3839,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
3836
3839
|
cont.watcherUnusable = true;
|
|
3837
3840
|
if (isWindows && error.code === "EPERM") {
|
|
3838
3841
|
try {
|
|
3839
|
-
const fd = await (0, import_promises2.open)(
|
|
3842
|
+
const fd = await (0, import_promises2.open)(path7, "r");
|
|
3840
3843
|
await fd.close();
|
|
3841
3844
|
broadcastErr(error);
|
|
3842
3845
|
} catch (err) {
|
|
@@ -3867,7 +3870,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
3867
3870
|
};
|
|
3868
3871
|
};
|
|
3869
3872
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
3870
|
-
var setFsWatchFileListener = (
|
|
3873
|
+
var setFsWatchFileListener = (path7, fullPath, options, handlers) => {
|
|
3871
3874
|
const { listener, rawEmitter } = handlers;
|
|
3872
3875
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
3873
3876
|
const copts = cont && cont.options;
|
|
@@ -3889,7 +3892,7 @@ var setFsWatchFileListener = (path8, fullPath, options, handlers) => {
|
|
|
3889
3892
|
});
|
|
3890
3893
|
const currmtime = curr.mtimeMs;
|
|
3891
3894
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
3892
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
3895
|
+
foreach(cont.listeners, (listener2) => listener2(path7, curr));
|
|
3893
3896
|
}
|
|
3894
3897
|
})
|
|
3895
3898
|
};
|
|
@@ -3919,13 +3922,13 @@ var NodeFsHandler = class {
|
|
|
3919
3922
|
* @param listener on fs change
|
|
3920
3923
|
* @returns closer for the watcher instance
|
|
3921
3924
|
*/
|
|
3922
|
-
_watchWithNodeFs(
|
|
3925
|
+
_watchWithNodeFs(path7, listener) {
|
|
3923
3926
|
const opts = this.fsw.options;
|
|
3924
|
-
const directory = sp.dirname(
|
|
3925
|
-
const basename3 = sp.basename(
|
|
3927
|
+
const directory = sp.dirname(path7);
|
|
3928
|
+
const basename3 = sp.basename(path7);
|
|
3926
3929
|
const parent = this.fsw._getWatchedDir(directory);
|
|
3927
3930
|
parent.add(basename3);
|
|
3928
|
-
const absolutePath = sp.resolve(
|
|
3931
|
+
const absolutePath = sp.resolve(path7);
|
|
3929
3932
|
const options = {
|
|
3930
3933
|
persistent: opts.persistent
|
|
3931
3934
|
};
|
|
@@ -3935,12 +3938,12 @@ var NodeFsHandler = class {
|
|
|
3935
3938
|
if (opts.usePolling) {
|
|
3936
3939
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
3937
3940
|
options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
|
|
3938
|
-
closer = setFsWatchFileListener(
|
|
3941
|
+
closer = setFsWatchFileListener(path7, absolutePath, options, {
|
|
3939
3942
|
listener,
|
|
3940
3943
|
rawEmitter: this.fsw._emitRaw
|
|
3941
3944
|
});
|
|
3942
3945
|
} else {
|
|
3943
|
-
closer = setFsWatchListener(
|
|
3946
|
+
closer = setFsWatchListener(path7, absolutePath, options, {
|
|
3944
3947
|
listener,
|
|
3945
3948
|
errHandler: this._boundHandleError,
|
|
3946
3949
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -3962,7 +3965,7 @@ var NodeFsHandler = class {
|
|
|
3962
3965
|
let prevStats = stats;
|
|
3963
3966
|
if (parent.has(basename3))
|
|
3964
3967
|
return;
|
|
3965
|
-
const listener = async (
|
|
3968
|
+
const listener = async (path7, newStats) => {
|
|
3966
3969
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
3967
3970
|
return;
|
|
3968
3971
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -3976,11 +3979,11 @@ var NodeFsHandler = class {
|
|
|
3976
3979
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
3977
3980
|
}
|
|
3978
3981
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
3979
|
-
this.fsw._closeFile(
|
|
3982
|
+
this.fsw._closeFile(path7);
|
|
3980
3983
|
prevStats = newStats2;
|
|
3981
3984
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
3982
3985
|
if (closer2)
|
|
3983
|
-
this.fsw._addPathCloser(
|
|
3986
|
+
this.fsw._addPathCloser(path7, closer2);
|
|
3984
3987
|
} else {
|
|
3985
3988
|
prevStats = newStats2;
|
|
3986
3989
|
}
|
|
@@ -4012,7 +4015,7 @@ var NodeFsHandler = class {
|
|
|
4012
4015
|
* @param item basename of this item
|
|
4013
4016
|
* @returns true if no more processing is needed for this entry.
|
|
4014
4017
|
*/
|
|
4015
|
-
async _handleSymlink(entry, directory,
|
|
4018
|
+
async _handleSymlink(entry, directory, path7, item) {
|
|
4016
4019
|
if (this.fsw.closed) {
|
|
4017
4020
|
return;
|
|
4018
4021
|
}
|
|
@@ -4022,7 +4025,7 @@ var NodeFsHandler = class {
|
|
|
4022
4025
|
this.fsw._incrReadyCount();
|
|
4023
4026
|
let linkPath;
|
|
4024
4027
|
try {
|
|
4025
|
-
linkPath = await (0, import_promises2.realpath)(
|
|
4028
|
+
linkPath = await (0, import_promises2.realpath)(path7);
|
|
4026
4029
|
} catch (e) {
|
|
4027
4030
|
this.fsw._emitReady();
|
|
4028
4031
|
return true;
|
|
@@ -4032,12 +4035,12 @@ var NodeFsHandler = class {
|
|
|
4032
4035
|
if (dir.has(item)) {
|
|
4033
4036
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
4034
4037
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
4035
|
-
this.fsw._emit(EV.CHANGE,
|
|
4038
|
+
this.fsw._emit(EV.CHANGE, path7, entry.stats);
|
|
4036
4039
|
}
|
|
4037
4040
|
} else {
|
|
4038
4041
|
dir.add(item);
|
|
4039
4042
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
4040
|
-
this.fsw._emit(EV.ADD,
|
|
4043
|
+
this.fsw._emit(EV.ADD, path7, entry.stats);
|
|
4041
4044
|
}
|
|
4042
4045
|
this.fsw._emitReady();
|
|
4043
4046
|
return true;
|
|
@@ -4067,9 +4070,9 @@ var NodeFsHandler = class {
|
|
|
4067
4070
|
return;
|
|
4068
4071
|
}
|
|
4069
4072
|
const item = entry.path;
|
|
4070
|
-
let
|
|
4073
|
+
let path7 = sp.join(directory, item);
|
|
4071
4074
|
current.add(item);
|
|
4072
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
4075
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path7, item)) {
|
|
4073
4076
|
return;
|
|
4074
4077
|
}
|
|
4075
4078
|
if (this.fsw.closed) {
|
|
@@ -4078,8 +4081,8 @@ var NodeFsHandler = class {
|
|
|
4078
4081
|
}
|
|
4079
4082
|
if (item === target || !target && !previous.has(item)) {
|
|
4080
4083
|
this.fsw._incrReadyCount();
|
|
4081
|
-
|
|
4082
|
-
this._addToNodeFs(
|
|
4084
|
+
path7 = sp.join(dir, sp.relative(dir, path7));
|
|
4085
|
+
this._addToNodeFs(path7, initialAdd, wh, depth + 1);
|
|
4083
4086
|
}
|
|
4084
4087
|
}).on(EV.ERROR, this._boundHandleError);
|
|
4085
4088
|
return new Promise((resolve4, reject) => {
|
|
@@ -4148,13 +4151,13 @@ var NodeFsHandler = class {
|
|
|
4148
4151
|
* @param depth Child path actually targeted for watch
|
|
4149
4152
|
* @param target Child path actually targeted for watch
|
|
4150
4153
|
*/
|
|
4151
|
-
async _addToNodeFs(
|
|
4154
|
+
async _addToNodeFs(path7, initialAdd, priorWh, depth, target) {
|
|
4152
4155
|
const ready = this.fsw._emitReady;
|
|
4153
|
-
if (this.fsw._isIgnored(
|
|
4156
|
+
if (this.fsw._isIgnored(path7) || this.fsw.closed) {
|
|
4154
4157
|
ready();
|
|
4155
4158
|
return false;
|
|
4156
4159
|
}
|
|
4157
|
-
const wh = this.fsw._getWatchHelpers(
|
|
4160
|
+
const wh = this.fsw._getWatchHelpers(path7);
|
|
4158
4161
|
if (priorWh) {
|
|
4159
4162
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
4160
4163
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -4170,8 +4173,8 @@ var NodeFsHandler = class {
|
|
|
4170
4173
|
const follow = this.fsw.options.followSymlinks;
|
|
4171
4174
|
let closer;
|
|
4172
4175
|
if (stats.isDirectory()) {
|
|
4173
|
-
const absPath = sp.resolve(
|
|
4174
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
4176
|
+
const absPath = sp.resolve(path7);
|
|
4177
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path7) : path7;
|
|
4175
4178
|
if (this.fsw.closed)
|
|
4176
4179
|
return;
|
|
4177
4180
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -4181,29 +4184,29 @@ var NodeFsHandler = class {
|
|
|
4181
4184
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
4182
4185
|
}
|
|
4183
4186
|
} else if (stats.isSymbolicLink()) {
|
|
4184
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
4187
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path7) : path7;
|
|
4185
4188
|
if (this.fsw.closed)
|
|
4186
4189
|
return;
|
|
4187
4190
|
const parent = sp.dirname(wh.watchPath);
|
|
4188
4191
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
4189
4192
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
4190
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
4193
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path7, wh, targetPath);
|
|
4191
4194
|
if (this.fsw.closed)
|
|
4192
4195
|
return;
|
|
4193
4196
|
if (targetPath !== void 0) {
|
|
4194
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
4197
|
+
this.fsw._symlinkPaths.set(sp.resolve(path7), targetPath);
|
|
4195
4198
|
}
|
|
4196
4199
|
} else {
|
|
4197
4200
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
4198
4201
|
}
|
|
4199
4202
|
ready();
|
|
4200
4203
|
if (closer)
|
|
4201
|
-
this.fsw._addPathCloser(
|
|
4204
|
+
this.fsw._addPathCloser(path7, closer);
|
|
4202
4205
|
return false;
|
|
4203
4206
|
} catch (error) {
|
|
4204
4207
|
if (this.fsw._handleError(error)) {
|
|
4205
4208
|
ready();
|
|
4206
|
-
return
|
|
4209
|
+
return path7;
|
|
4207
4210
|
}
|
|
4208
4211
|
}
|
|
4209
4212
|
}
|
|
@@ -4246,24 +4249,24 @@ function createPattern(matcher) {
|
|
|
4246
4249
|
}
|
|
4247
4250
|
return () => false;
|
|
4248
4251
|
}
|
|
4249
|
-
function normalizePath(
|
|
4250
|
-
if (typeof
|
|
4252
|
+
function normalizePath(path7) {
|
|
4253
|
+
if (typeof path7 !== "string")
|
|
4251
4254
|
throw new Error("string expected");
|
|
4252
|
-
|
|
4253
|
-
|
|
4255
|
+
path7 = sp2.normalize(path7);
|
|
4256
|
+
path7 = path7.replace(/\\/g, "/");
|
|
4254
4257
|
let prepend = false;
|
|
4255
|
-
if (
|
|
4258
|
+
if (path7.startsWith("//"))
|
|
4256
4259
|
prepend = true;
|
|
4257
|
-
|
|
4260
|
+
path7 = path7.replace(DOUBLE_SLASH_RE, "/");
|
|
4258
4261
|
if (prepend)
|
|
4259
|
-
|
|
4260
|
-
return
|
|
4262
|
+
path7 = "/" + path7;
|
|
4263
|
+
return path7;
|
|
4261
4264
|
}
|
|
4262
4265
|
function matchPatterns(patterns, testString, stats) {
|
|
4263
|
-
const
|
|
4266
|
+
const path7 = normalizePath(testString);
|
|
4264
4267
|
for (let index = 0; index < patterns.length; index++) {
|
|
4265
4268
|
const pattern = patterns[index];
|
|
4266
|
-
if (pattern(
|
|
4269
|
+
if (pattern(path7, stats)) {
|
|
4267
4270
|
return true;
|
|
4268
4271
|
}
|
|
4269
4272
|
}
|
|
@@ -4301,19 +4304,19 @@ var toUnix = (string) => {
|
|
|
4301
4304
|
}
|
|
4302
4305
|
return str;
|
|
4303
4306
|
};
|
|
4304
|
-
var normalizePathToUnix = (
|
|
4305
|
-
var normalizeIgnored = (cwd = "") => (
|
|
4306
|
-
if (typeof
|
|
4307
|
-
return normalizePathToUnix(sp2.isAbsolute(
|
|
4307
|
+
var normalizePathToUnix = (path7) => toUnix(sp2.normalize(toUnix(path7)));
|
|
4308
|
+
var normalizeIgnored = (cwd = "") => (path7) => {
|
|
4309
|
+
if (typeof path7 === "string") {
|
|
4310
|
+
return normalizePathToUnix(sp2.isAbsolute(path7) ? path7 : sp2.join(cwd, path7));
|
|
4308
4311
|
} else {
|
|
4309
|
-
return
|
|
4312
|
+
return path7;
|
|
4310
4313
|
}
|
|
4311
4314
|
};
|
|
4312
|
-
var getAbsolutePath = (
|
|
4313
|
-
if (sp2.isAbsolute(
|
|
4314
|
-
return
|
|
4315
|
+
var getAbsolutePath = (path7, cwd) => {
|
|
4316
|
+
if (sp2.isAbsolute(path7)) {
|
|
4317
|
+
return path7;
|
|
4315
4318
|
}
|
|
4316
|
-
return sp2.join(cwd,
|
|
4319
|
+
return sp2.join(cwd, path7);
|
|
4317
4320
|
};
|
|
4318
4321
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
4319
4322
|
var DirEntry = class {
|
|
@@ -4378,10 +4381,10 @@ var WatchHelper = class {
|
|
|
4378
4381
|
dirParts;
|
|
4379
4382
|
followSymlinks;
|
|
4380
4383
|
statMethod;
|
|
4381
|
-
constructor(
|
|
4384
|
+
constructor(path7, follow, fsw) {
|
|
4382
4385
|
this.fsw = fsw;
|
|
4383
|
-
const watchPath =
|
|
4384
|
-
this.path =
|
|
4386
|
+
const watchPath = path7;
|
|
4387
|
+
this.path = path7 = path7.replace(REPLACER_RE, "");
|
|
4385
4388
|
this.watchPath = watchPath;
|
|
4386
4389
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
4387
4390
|
this.dirParts = [];
|
|
@@ -4521,20 +4524,20 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4521
4524
|
this._closePromise = void 0;
|
|
4522
4525
|
let paths = unifyPaths(paths_);
|
|
4523
4526
|
if (cwd) {
|
|
4524
|
-
paths = paths.map((
|
|
4525
|
-
const absPath = getAbsolutePath(
|
|
4527
|
+
paths = paths.map((path7) => {
|
|
4528
|
+
const absPath = getAbsolutePath(path7, cwd);
|
|
4526
4529
|
return absPath;
|
|
4527
4530
|
});
|
|
4528
4531
|
}
|
|
4529
|
-
paths.forEach((
|
|
4530
|
-
this._removeIgnoredPath(
|
|
4532
|
+
paths.forEach((path7) => {
|
|
4533
|
+
this._removeIgnoredPath(path7);
|
|
4531
4534
|
});
|
|
4532
4535
|
this._userIgnored = void 0;
|
|
4533
4536
|
if (!this._readyCount)
|
|
4534
4537
|
this._readyCount = 0;
|
|
4535
4538
|
this._readyCount += paths.length;
|
|
4536
|
-
Promise.all(paths.map(async (
|
|
4537
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
4539
|
+
Promise.all(paths.map(async (path7) => {
|
|
4540
|
+
const res = await this._nodeFsHandler._addToNodeFs(path7, !_internal, void 0, 0, _origAdd);
|
|
4538
4541
|
if (res)
|
|
4539
4542
|
this._emitReady();
|
|
4540
4543
|
return res;
|
|
@@ -4556,17 +4559,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4556
4559
|
return this;
|
|
4557
4560
|
const paths = unifyPaths(paths_);
|
|
4558
4561
|
const { cwd } = this.options;
|
|
4559
|
-
paths.forEach((
|
|
4560
|
-
if (!sp2.isAbsolute(
|
|
4562
|
+
paths.forEach((path7) => {
|
|
4563
|
+
if (!sp2.isAbsolute(path7) && !this._closers.has(path7)) {
|
|
4561
4564
|
if (cwd)
|
|
4562
|
-
|
|
4563
|
-
|
|
4565
|
+
path7 = sp2.join(cwd, path7);
|
|
4566
|
+
path7 = sp2.resolve(path7);
|
|
4564
4567
|
}
|
|
4565
|
-
this._closePath(
|
|
4566
|
-
this._addIgnoredPath(
|
|
4567
|
-
if (this._watched.has(
|
|
4568
|
+
this._closePath(path7);
|
|
4569
|
+
this._addIgnoredPath(path7);
|
|
4570
|
+
if (this._watched.has(path7)) {
|
|
4568
4571
|
this._addIgnoredPath({
|
|
4569
|
-
path:
|
|
4572
|
+
path: path7,
|
|
4570
4573
|
recursive: true
|
|
4571
4574
|
});
|
|
4572
4575
|
}
|
|
@@ -4630,38 +4633,38 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4630
4633
|
* @param stats arguments to be passed with event
|
|
4631
4634
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
4632
4635
|
*/
|
|
4633
|
-
async _emit(event,
|
|
4636
|
+
async _emit(event, path7, stats) {
|
|
4634
4637
|
if (this.closed)
|
|
4635
4638
|
return;
|
|
4636
4639
|
const opts = this.options;
|
|
4637
4640
|
if (isWindows)
|
|
4638
|
-
|
|
4641
|
+
path7 = sp2.normalize(path7);
|
|
4639
4642
|
if (opts.cwd)
|
|
4640
|
-
|
|
4641
|
-
const args = [
|
|
4643
|
+
path7 = sp2.relative(opts.cwd, path7);
|
|
4644
|
+
const args = [path7];
|
|
4642
4645
|
if (stats != null)
|
|
4643
4646
|
args.push(stats);
|
|
4644
4647
|
const awf = opts.awaitWriteFinish;
|
|
4645
4648
|
let pw;
|
|
4646
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
4649
|
+
if (awf && (pw = this._pendingWrites.get(path7))) {
|
|
4647
4650
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
4648
4651
|
return this;
|
|
4649
4652
|
}
|
|
4650
4653
|
if (opts.atomic) {
|
|
4651
4654
|
if (event === EVENTS.UNLINK) {
|
|
4652
|
-
this._pendingUnlinks.set(
|
|
4655
|
+
this._pendingUnlinks.set(path7, [event, ...args]);
|
|
4653
4656
|
setTimeout(() => {
|
|
4654
|
-
this._pendingUnlinks.forEach((entry,
|
|
4657
|
+
this._pendingUnlinks.forEach((entry, path8) => {
|
|
4655
4658
|
this.emit(...entry);
|
|
4656
4659
|
this.emit(EVENTS.ALL, ...entry);
|
|
4657
|
-
this._pendingUnlinks.delete(
|
|
4660
|
+
this._pendingUnlinks.delete(path8);
|
|
4658
4661
|
});
|
|
4659
4662
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
4660
4663
|
return this;
|
|
4661
4664
|
}
|
|
4662
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
4665
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path7)) {
|
|
4663
4666
|
event = EVENTS.CHANGE;
|
|
4664
|
-
this._pendingUnlinks.delete(
|
|
4667
|
+
this._pendingUnlinks.delete(path7);
|
|
4665
4668
|
}
|
|
4666
4669
|
}
|
|
4667
4670
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -4679,16 +4682,16 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4679
4682
|
this.emitWithAll(event, args);
|
|
4680
4683
|
}
|
|
4681
4684
|
};
|
|
4682
|
-
this._awaitWriteFinish(
|
|
4685
|
+
this._awaitWriteFinish(path7, awf.stabilityThreshold, event, awfEmit);
|
|
4683
4686
|
return this;
|
|
4684
4687
|
}
|
|
4685
4688
|
if (event === EVENTS.CHANGE) {
|
|
4686
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
4689
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path7, 50);
|
|
4687
4690
|
if (isThrottled)
|
|
4688
4691
|
return this;
|
|
4689
4692
|
}
|
|
4690
4693
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
4691
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
4694
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path7) : path7;
|
|
4692
4695
|
let stats2;
|
|
4693
4696
|
try {
|
|
4694
4697
|
stats2 = await (0, import_promises3.stat)(fullPath);
|
|
@@ -4719,23 +4722,23 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4719
4722
|
* @param timeout duration of time to suppress duplicate actions
|
|
4720
4723
|
* @returns tracking object or false if action should be suppressed
|
|
4721
4724
|
*/
|
|
4722
|
-
_throttle(actionType,
|
|
4725
|
+
_throttle(actionType, path7, timeout) {
|
|
4723
4726
|
if (!this._throttled.has(actionType)) {
|
|
4724
4727
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
4725
4728
|
}
|
|
4726
4729
|
const action = this._throttled.get(actionType);
|
|
4727
4730
|
if (!action)
|
|
4728
4731
|
throw new Error("invalid throttle");
|
|
4729
|
-
const actionPath = action.get(
|
|
4732
|
+
const actionPath = action.get(path7);
|
|
4730
4733
|
if (actionPath) {
|
|
4731
4734
|
actionPath.count++;
|
|
4732
4735
|
return false;
|
|
4733
4736
|
}
|
|
4734
4737
|
let timeoutObject;
|
|
4735
4738
|
const clear = () => {
|
|
4736
|
-
const item = action.get(
|
|
4739
|
+
const item = action.get(path7);
|
|
4737
4740
|
const count = item ? item.count : 0;
|
|
4738
|
-
action.delete(
|
|
4741
|
+
action.delete(path7);
|
|
4739
4742
|
clearTimeout(timeoutObject);
|
|
4740
4743
|
if (item)
|
|
4741
4744
|
clearTimeout(item.timeoutObject);
|
|
@@ -4743,7 +4746,7 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4743
4746
|
};
|
|
4744
4747
|
timeoutObject = setTimeout(clear, timeout);
|
|
4745
4748
|
const thr = { timeoutObject, clear, count: 0 };
|
|
4746
|
-
action.set(
|
|
4749
|
+
action.set(path7, thr);
|
|
4747
4750
|
return thr;
|
|
4748
4751
|
}
|
|
4749
4752
|
_incrReadyCount() {
|
|
@@ -4757,44 +4760,44 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4757
4760
|
* @param event
|
|
4758
4761
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
4759
4762
|
*/
|
|
4760
|
-
_awaitWriteFinish(
|
|
4763
|
+
_awaitWriteFinish(path7, threshold, event, awfEmit) {
|
|
4761
4764
|
const awf = this.options.awaitWriteFinish;
|
|
4762
4765
|
if (typeof awf !== "object")
|
|
4763
4766
|
return;
|
|
4764
4767
|
const pollInterval = awf.pollInterval;
|
|
4765
4768
|
let timeoutHandler;
|
|
4766
|
-
let fullPath =
|
|
4767
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
4768
|
-
fullPath = sp2.join(this.options.cwd,
|
|
4769
|
+
let fullPath = path7;
|
|
4770
|
+
if (this.options.cwd && !sp2.isAbsolute(path7)) {
|
|
4771
|
+
fullPath = sp2.join(this.options.cwd, path7);
|
|
4769
4772
|
}
|
|
4770
4773
|
const now = /* @__PURE__ */ new Date();
|
|
4771
4774
|
const writes = this._pendingWrites;
|
|
4772
4775
|
function awaitWriteFinishFn(prevStat) {
|
|
4773
4776
|
(0, import_node_fs2.stat)(fullPath, (err, curStat) => {
|
|
4774
|
-
if (err || !writes.has(
|
|
4777
|
+
if (err || !writes.has(path7)) {
|
|
4775
4778
|
if (err && err.code !== "ENOENT")
|
|
4776
4779
|
awfEmit(err);
|
|
4777
4780
|
return;
|
|
4778
4781
|
}
|
|
4779
4782
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
4780
4783
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
4781
|
-
writes.get(
|
|
4784
|
+
writes.get(path7).lastChange = now2;
|
|
4782
4785
|
}
|
|
4783
|
-
const pw = writes.get(
|
|
4786
|
+
const pw = writes.get(path7);
|
|
4784
4787
|
const df = now2 - pw.lastChange;
|
|
4785
4788
|
if (df >= threshold) {
|
|
4786
|
-
writes.delete(
|
|
4789
|
+
writes.delete(path7);
|
|
4787
4790
|
awfEmit(void 0, curStat);
|
|
4788
4791
|
} else {
|
|
4789
4792
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
4790
4793
|
}
|
|
4791
4794
|
});
|
|
4792
4795
|
}
|
|
4793
|
-
if (!writes.has(
|
|
4794
|
-
writes.set(
|
|
4796
|
+
if (!writes.has(path7)) {
|
|
4797
|
+
writes.set(path7, {
|
|
4795
4798
|
lastChange: now,
|
|
4796
4799
|
cancelWait: () => {
|
|
4797
|
-
writes.delete(
|
|
4800
|
+
writes.delete(path7);
|
|
4798
4801
|
clearTimeout(timeoutHandler);
|
|
4799
4802
|
return event;
|
|
4800
4803
|
}
|
|
@@ -4805,8 +4808,8 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4805
4808
|
/**
|
|
4806
4809
|
* Determines whether user has asked to ignore this path.
|
|
4807
4810
|
*/
|
|
4808
|
-
_isIgnored(
|
|
4809
|
-
if (this.options.atomic && DOT_RE.test(
|
|
4811
|
+
_isIgnored(path7, stats) {
|
|
4812
|
+
if (this.options.atomic && DOT_RE.test(path7))
|
|
4810
4813
|
return true;
|
|
4811
4814
|
if (!this._userIgnored) {
|
|
4812
4815
|
const { cwd } = this.options;
|
|
@@ -4816,17 +4819,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4816
4819
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
4817
4820
|
this._userIgnored = anymatch(list, void 0);
|
|
4818
4821
|
}
|
|
4819
|
-
return this._userIgnored(
|
|
4822
|
+
return this._userIgnored(path7, stats);
|
|
4820
4823
|
}
|
|
4821
|
-
_isntIgnored(
|
|
4822
|
-
return !this._isIgnored(
|
|
4824
|
+
_isntIgnored(path7, stat4) {
|
|
4825
|
+
return !this._isIgnored(path7, stat4);
|
|
4823
4826
|
}
|
|
4824
4827
|
/**
|
|
4825
4828
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
4826
4829
|
* @param path file or directory pattern being watched
|
|
4827
4830
|
*/
|
|
4828
|
-
_getWatchHelpers(
|
|
4829
|
-
return new WatchHelper(
|
|
4831
|
+
_getWatchHelpers(path7) {
|
|
4832
|
+
return new WatchHelper(path7, this.options.followSymlinks, this);
|
|
4830
4833
|
}
|
|
4831
4834
|
// Directory helpers
|
|
4832
4835
|
// -----------------
|
|
@@ -4858,63 +4861,63 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4858
4861
|
* @param item base path of item/directory
|
|
4859
4862
|
*/
|
|
4860
4863
|
_remove(directory, item, isDirectory) {
|
|
4861
|
-
const
|
|
4862
|
-
const fullPath = sp2.resolve(
|
|
4863
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
4864
|
-
if (!this._throttle("remove",
|
|
4864
|
+
const path7 = sp2.join(directory, item);
|
|
4865
|
+
const fullPath = sp2.resolve(path7);
|
|
4866
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path7) || this._watched.has(fullPath);
|
|
4867
|
+
if (!this._throttle("remove", path7, 100))
|
|
4865
4868
|
return;
|
|
4866
4869
|
if (!isDirectory && this._watched.size === 1) {
|
|
4867
4870
|
this.add(directory, item, true);
|
|
4868
4871
|
}
|
|
4869
|
-
const wp = this._getWatchedDir(
|
|
4872
|
+
const wp = this._getWatchedDir(path7);
|
|
4870
4873
|
const nestedDirectoryChildren = wp.getChildren();
|
|
4871
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
4874
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path7, nested));
|
|
4872
4875
|
const parent = this._getWatchedDir(directory);
|
|
4873
4876
|
const wasTracked = parent.has(item);
|
|
4874
4877
|
parent.remove(item);
|
|
4875
4878
|
if (this._symlinkPaths.has(fullPath)) {
|
|
4876
4879
|
this._symlinkPaths.delete(fullPath);
|
|
4877
4880
|
}
|
|
4878
|
-
let relPath =
|
|
4881
|
+
let relPath = path7;
|
|
4879
4882
|
if (this.options.cwd)
|
|
4880
|
-
relPath = sp2.relative(this.options.cwd,
|
|
4883
|
+
relPath = sp2.relative(this.options.cwd, path7);
|
|
4881
4884
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
4882
4885
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
4883
4886
|
if (event === EVENTS.ADD)
|
|
4884
4887
|
return;
|
|
4885
4888
|
}
|
|
4886
|
-
this._watched.delete(
|
|
4889
|
+
this._watched.delete(path7);
|
|
4887
4890
|
this._watched.delete(fullPath);
|
|
4888
4891
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
4889
|
-
if (wasTracked && !this._isIgnored(
|
|
4890
|
-
this._emit(eventName,
|
|
4891
|
-
this._closePath(
|
|
4892
|
+
if (wasTracked && !this._isIgnored(path7))
|
|
4893
|
+
this._emit(eventName, path7);
|
|
4894
|
+
this._closePath(path7);
|
|
4892
4895
|
}
|
|
4893
4896
|
/**
|
|
4894
4897
|
* Closes all watchers for a path
|
|
4895
4898
|
*/
|
|
4896
|
-
_closePath(
|
|
4897
|
-
this._closeFile(
|
|
4898
|
-
const dir = sp2.dirname(
|
|
4899
|
-
this._getWatchedDir(dir).remove(sp2.basename(
|
|
4899
|
+
_closePath(path7) {
|
|
4900
|
+
this._closeFile(path7);
|
|
4901
|
+
const dir = sp2.dirname(path7);
|
|
4902
|
+
this._getWatchedDir(dir).remove(sp2.basename(path7));
|
|
4900
4903
|
}
|
|
4901
4904
|
/**
|
|
4902
4905
|
* Closes only file-specific watchers
|
|
4903
4906
|
*/
|
|
4904
|
-
_closeFile(
|
|
4905
|
-
const closers = this._closers.get(
|
|
4907
|
+
_closeFile(path7) {
|
|
4908
|
+
const closers = this._closers.get(path7);
|
|
4906
4909
|
if (!closers)
|
|
4907
4910
|
return;
|
|
4908
4911
|
closers.forEach((closer) => closer());
|
|
4909
|
-
this._closers.delete(
|
|
4912
|
+
this._closers.delete(path7);
|
|
4910
4913
|
}
|
|
4911
|
-
_addPathCloser(
|
|
4914
|
+
_addPathCloser(path7, closer) {
|
|
4912
4915
|
if (!closer)
|
|
4913
4916
|
return;
|
|
4914
|
-
let list = this._closers.get(
|
|
4917
|
+
let list = this._closers.get(path7);
|
|
4915
4918
|
if (!list) {
|
|
4916
4919
|
list = [];
|
|
4917
|
-
this._closers.set(
|
|
4920
|
+
this._closers.set(path7, list);
|
|
4918
4921
|
}
|
|
4919
4922
|
list.push(closer);
|
|
4920
4923
|
}
|
|
@@ -4944,7 +4947,7 @@ function watch(paths, options = {}) {
|
|
|
4944
4947
|
var chokidar_default = { watch, FSWatcher };
|
|
4945
4948
|
|
|
4946
4949
|
// src/watcher/index.ts
|
|
4947
|
-
var
|
|
4950
|
+
var path5 = __toESM(require("path"), 1);
|
|
4948
4951
|
var FileWatcher = class {
|
|
4949
4952
|
watcher = null;
|
|
4950
4953
|
projectRoot;
|
|
@@ -4965,7 +4968,7 @@ var FileWatcher = class {
|
|
|
4965
4968
|
const ignoreFilter = createIgnoreFilter(this.projectRoot);
|
|
4966
4969
|
this.watcher = chokidar_default.watch(this.projectRoot, {
|
|
4967
4970
|
ignored: (filePath) => {
|
|
4968
|
-
const relativePath =
|
|
4971
|
+
const relativePath = path5.relative(this.projectRoot, filePath);
|
|
4969
4972
|
if (!relativePath) return false;
|
|
4970
4973
|
if (ignoreFilter.ignores(relativePath)) {
|
|
4971
4974
|
return true;
|
|
@@ -5009,7 +5012,7 @@ var FileWatcher = class {
|
|
|
5009
5012
|
return;
|
|
5010
5013
|
}
|
|
5011
5014
|
const changes = Array.from(this.pendingChanges.entries()).map(
|
|
5012
|
-
([
|
|
5015
|
+
([path7, type]) => ({ path: path7, type })
|
|
5013
5016
|
);
|
|
5014
5017
|
this.pendingChanges.clear();
|
|
5015
5018
|
try {
|
|
@@ -5201,10 +5204,10 @@ function formatStatus(status) {
|
|
|
5201
5204
|
|
|
5202
5205
|
// src/index.ts
|
|
5203
5206
|
function loadPluginConfig(projectRoot) {
|
|
5204
|
-
const configPath =
|
|
5207
|
+
const configPath = path6.join(projectRoot, ".opencode", "codebase-index.json");
|
|
5205
5208
|
try {
|
|
5206
|
-
if ((0,
|
|
5207
|
-
const content = (0,
|
|
5209
|
+
if ((0, import_fs4.existsSync)(configPath)) {
|
|
5210
|
+
const content = (0, import_fs4.readFileSync)(configPath, "utf-8");
|
|
5208
5211
|
return JSON.parse(content);
|
|
5209
5212
|
}
|
|
5210
5213
|
} catch {
|
|
@@ -5233,6 +5236,39 @@ var plugin = async ({ directory }) => {
|
|
|
5233
5236
|
index_codebase,
|
|
5234
5237
|
index_status,
|
|
5235
5238
|
index_health_check
|
|
5239
|
+
},
|
|
5240
|
+
async config(cfg) {
|
|
5241
|
+
cfg.command = cfg.command ?? {};
|
|
5242
|
+
cfg.command["search"] = {
|
|
5243
|
+
description: "Search codebase by meaning using semantic search",
|
|
5244
|
+
template: `Use the \`codebase_search\` tool to find code related to: $ARGUMENTS
|
|
5245
|
+
|
|
5246
|
+
If the index doesn't exist yet, run \`index_codebase\` first.
|
|
5247
|
+
|
|
5248
|
+
Return the most relevant results with file paths and line numbers.`
|
|
5249
|
+
};
|
|
5250
|
+
cfg.command["find"] = {
|
|
5251
|
+
description: "Find code using hybrid approach (semantic + grep)",
|
|
5252
|
+
template: `Find code related to: $ARGUMENTS
|
|
5253
|
+
|
|
5254
|
+
Strategy:
|
|
5255
|
+
1. First use \`codebase_search\` to find semantically related code
|
|
5256
|
+
2. From the results, identify specific function/class names
|
|
5257
|
+
3. Use grep to find all occurrences of those identifiers
|
|
5258
|
+
4. Combine findings into a comprehensive answer
|
|
5259
|
+
|
|
5260
|
+
If the semantic index doesn't exist, run \`index_codebase\` first.`
|
|
5261
|
+
};
|
|
5262
|
+
cfg.command["index"] = {
|
|
5263
|
+
description: "Index the codebase for semantic search",
|
|
5264
|
+
template: `Run the \`index_codebase\` tool to create or update the semantic search index.
|
|
5265
|
+
|
|
5266
|
+
Show progress and final statistics including:
|
|
5267
|
+
- Number of files processed
|
|
5268
|
+
- Number of chunks indexed
|
|
5269
|
+
- Tokens used
|
|
5270
|
+
- Duration`
|
|
5271
|
+
};
|
|
5236
5272
|
}
|
|
5237
5273
|
};
|
|
5238
5274
|
};
|