opencode-codebase-index 0.2.5 → 0.3.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/README.md +152 -1
- package/commands/find.md +17 -5
- package/commands/index.md +16 -6
- package/commands/search.md +18 -3
- package/commands/status.md +15 -0
- package/dist/index.cjs +398 -271
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +397 -271
- 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/skill/SKILL.md +101 -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(path9, 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(path9);
|
|
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 = (path9, originalPath, doThrow) => {
|
|
525
|
+
if (!isString(path9)) {
|
|
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 (!path9) {
|
|
532
532
|
return doThrow(`path must not be empty`, TypeError);
|
|
533
533
|
}
|
|
534
|
-
if (checkPath.isNotRelative(
|
|
534
|
+
if (checkPath.isNotRelative(path9)) {
|
|
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 = (path9) => REGEX_TEST_INVALID_PATH.test(path9);
|
|
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 path9 = originalPath && checkPath.convert(originalPath);
|
|
574
574
|
checkPath(
|
|
575
|
-
|
|
575
|
+
path9,
|
|
576
576
|
originalPath,
|
|
577
577
|
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
578
578
|
);
|
|
579
|
-
return this._t(
|
|
579
|
+
return this._t(path9, cache, checkUnignored, slices);
|
|
580
580
|
}
|
|
581
|
-
checkIgnore(
|
|
582
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
583
|
-
return this.test(
|
|
581
|
+
checkIgnore(path9) {
|
|
582
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path9)) {
|
|
583
|
+
return this.test(path9);
|
|
584
584
|
}
|
|
585
|
-
const slices =
|
|
585
|
+
const slices = path9.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(path9, false, MODE_CHECK_IGNORE);
|
|
599
599
|
}
|
|
600
|
-
_t(
|
|
601
|
-
if (
|
|
602
|
-
return cache[
|
|
600
|
+
_t(path9, cache, checkUnignored, slices) {
|
|
601
|
+
if (path9 in cache) {
|
|
602
|
+
return cache[path9];
|
|
603
603
|
}
|
|
604
604
|
if (!slices) {
|
|
605
|
-
slices =
|
|
605
|
+
slices = path9.split(SLASH2).filter(Boolean);
|
|
606
606
|
}
|
|
607
607
|
slices.pop();
|
|
608
608
|
if (!slices.length) {
|
|
609
|
-
return cache[
|
|
609
|
+
return cache[path9] = this._rules.test(path9, 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[path9] = parent.ignored ? parent : this._rules.test(path9, checkUnignored, MODE_IGNORE);
|
|
618
618
|
}
|
|
619
|
-
ignores(
|
|
620
|
-
return this._test(
|
|
619
|
+
ignores(path9) {
|
|
620
|
+
return this._test(path9, this._ignoreCache, false).ignored;
|
|
621
621
|
}
|
|
622
622
|
createFilter() {
|
|
623
|
-
return (
|
|
623
|
+
return (path9) => !this.ignores(path9);
|
|
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(path9) {
|
|
630
|
+
return this._test(path9, this._testCache, true);
|
|
631
631
|
}
|
|
632
632
|
};
|
|
633
633
|
var factory = (options) => new Ignore2(options);
|
|
634
|
-
var isPathValid = (
|
|
634
|
+
var isPathValid = (path9) => checkPath(path9 && checkPath.convert(path9), path9, 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 = (path9) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path9) || isNotRelative(path9);
|
|
640
640
|
};
|
|
641
641
|
if (
|
|
642
642
|
// Detect `process` so that it can run in browsers.
|
|
@@ -657,9 +657,10 @@ __export(index_exports, {
|
|
|
657
657
|
default: () => index_default
|
|
658
658
|
});
|
|
659
659
|
module.exports = __toCommonJS(index_exports);
|
|
660
|
-
var
|
|
661
|
-
var
|
|
660
|
+
var import_fs6 = require("fs");
|
|
661
|
+
var path8 = __toESM(require("path"), 1);
|
|
662
662
|
var os3 = __toESM(require("os"), 1);
|
|
663
|
+
var import_url2 = require("url");
|
|
663
664
|
|
|
664
665
|
// src/config/schema.ts
|
|
665
666
|
var DEFAULT_INCLUDE = [
|
|
@@ -697,7 +698,10 @@ function getDefaultIndexingConfig() {
|
|
|
697
698
|
maxChunksPerFile: 100,
|
|
698
699
|
semanticOnly: false,
|
|
699
700
|
retries: 3,
|
|
700
|
-
retryDelayMs: 1e3
|
|
701
|
+
retryDelayMs: 1e3,
|
|
702
|
+
autoGc: true,
|
|
703
|
+
gcIntervalDays: 7,
|
|
704
|
+
gcOrphanThreshold: 100
|
|
701
705
|
};
|
|
702
706
|
}
|
|
703
707
|
function getDefaultSearchConfig() {
|
|
@@ -732,7 +736,10 @@ function parseConfig(raw) {
|
|
|
732
736
|
maxChunksPerFile: typeof rawIndexing.maxChunksPerFile === "number" ? Math.max(1, rawIndexing.maxChunksPerFile) : defaultIndexing.maxChunksPerFile,
|
|
733
737
|
semanticOnly: typeof rawIndexing.semanticOnly === "boolean" ? rawIndexing.semanticOnly : defaultIndexing.semanticOnly,
|
|
734
738
|
retries: typeof rawIndexing.retries === "number" ? rawIndexing.retries : defaultIndexing.retries,
|
|
735
|
-
retryDelayMs: typeof rawIndexing.retryDelayMs === "number" ? rawIndexing.retryDelayMs : defaultIndexing.retryDelayMs
|
|
739
|
+
retryDelayMs: typeof rawIndexing.retryDelayMs === "number" ? rawIndexing.retryDelayMs : defaultIndexing.retryDelayMs,
|
|
740
|
+
autoGc: typeof rawIndexing.autoGc === "boolean" ? rawIndexing.autoGc : defaultIndexing.autoGc,
|
|
741
|
+
gcIntervalDays: typeof rawIndexing.gcIntervalDays === "number" ? Math.max(1, rawIndexing.gcIntervalDays) : defaultIndexing.gcIntervalDays,
|
|
742
|
+
gcOrphanThreshold: typeof rawIndexing.gcOrphanThreshold === "number" ? Math.max(0, rawIndexing.gcOrphanThreshold) : defaultIndexing.gcOrphanThreshold
|
|
736
743
|
};
|
|
737
744
|
const rawSearch = input.search && typeof input.search === "object" ? input.search : {};
|
|
738
745
|
const search = {
|
|
@@ -2071,34 +2078,36 @@ var GoogleEmbeddingProvider = class {
|
|
|
2071
2078
|
};
|
|
2072
2079
|
}
|
|
2073
2080
|
async embedBatch(texts) {
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
}
|
|
2088
|
-
}
|
|
2081
|
+
const results = await Promise.all(
|
|
2082
|
+
texts.map(async (text) => {
|
|
2083
|
+
const response = await fetch(
|
|
2084
|
+
`${this.credentials.baseUrl}/models/${this.modelInfo.model}:embedContent?key=${this.credentials.apiKey}`,
|
|
2085
|
+
{
|
|
2086
|
+
method: "POST",
|
|
2087
|
+
headers: {
|
|
2088
|
+
"Content-Type": "application/json"
|
|
2089
|
+
},
|
|
2090
|
+
body: JSON.stringify({
|
|
2091
|
+
content: {
|
|
2092
|
+
parts: [{ text }]
|
|
2093
|
+
}
|
|
2094
|
+
})
|
|
2095
|
+
}
|
|
2096
|
+
);
|
|
2097
|
+
if (!response.ok) {
|
|
2098
|
+
const error = await response.text();
|
|
2099
|
+
throw new Error(`Google embedding API error: ${response.status} - ${error}`);
|
|
2089
2100
|
}
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
totalTokens += Math.ceil(text.length / 4);
|
|
2098
|
-
}
|
|
2101
|
+
const data = await response.json();
|
|
2102
|
+
return {
|
|
2103
|
+
embedding: data.embedding.values,
|
|
2104
|
+
tokensUsed: Math.ceil(text.length / 4)
|
|
2105
|
+
};
|
|
2106
|
+
})
|
|
2107
|
+
);
|
|
2099
2108
|
return {
|
|
2100
|
-
embeddings,
|
|
2101
|
-
totalTokensUsed:
|
|
2109
|
+
embeddings: results.map((r) => r.embedding),
|
|
2110
|
+
totalTokensUsed: results.reduce((sum, r) => sum + r.tokensUsed, 0)
|
|
2102
2111
|
};
|
|
2103
2112
|
}
|
|
2104
2113
|
getModelInfo() {
|
|
@@ -2132,16 +2141,10 @@ var OllamaEmbeddingProvider = class {
|
|
|
2132
2141
|
};
|
|
2133
2142
|
}
|
|
2134
2143
|
async embedBatch(texts) {
|
|
2135
|
-
const
|
|
2136
|
-
let totalTokens = 0;
|
|
2137
|
-
for (const text of texts) {
|
|
2138
|
-
const result = await this.embed(text);
|
|
2139
|
-
embeddings.push(result.embedding);
|
|
2140
|
-
totalTokens += result.tokensUsed;
|
|
2141
|
-
}
|
|
2144
|
+
const results = await Promise.all(texts.map((text) => this.embed(text)));
|
|
2142
2145
|
return {
|
|
2143
|
-
embeddings,
|
|
2144
|
-
totalTokensUsed:
|
|
2146
|
+
embeddings: results.map((r) => r.embedding),
|
|
2147
|
+
totalTokensUsed: results.reduce((sum, r) => sum + r.tokensUsed, 0)
|
|
2145
2148
|
};
|
|
2146
2149
|
}
|
|
2147
2150
|
getModelInfo() {
|
|
@@ -2683,12 +2686,20 @@ var Database = class {
|
|
|
2683
2686
|
upsertEmbedding(contentHash, embedding, chunkText, model) {
|
|
2684
2687
|
this.inner.upsertEmbedding(contentHash, embedding, chunkText, model);
|
|
2685
2688
|
}
|
|
2689
|
+
upsertEmbeddingsBatch(items) {
|
|
2690
|
+
if (items.length === 0) return;
|
|
2691
|
+
this.inner.upsertEmbeddingsBatch(items);
|
|
2692
|
+
}
|
|
2686
2693
|
getMissingEmbeddings(contentHashes) {
|
|
2687
2694
|
return this.inner.getMissingEmbeddings(contentHashes);
|
|
2688
2695
|
}
|
|
2689
2696
|
upsertChunk(chunk) {
|
|
2690
2697
|
this.inner.upsertChunk(chunk);
|
|
2691
2698
|
}
|
|
2699
|
+
upsertChunksBatch(chunks) {
|
|
2700
|
+
if (chunks.length === 0) return;
|
|
2701
|
+
this.inner.upsertChunksBatch(chunks);
|
|
2702
|
+
}
|
|
2692
2703
|
getChunk(chunkId) {
|
|
2693
2704
|
return this.inner.getChunk(chunkId) ?? null;
|
|
2694
2705
|
}
|
|
@@ -2701,6 +2712,10 @@ var Database = class {
|
|
|
2701
2712
|
addChunksToBranch(branch, chunkIds) {
|
|
2702
2713
|
this.inner.addChunksToBranch(branch, chunkIds);
|
|
2703
2714
|
}
|
|
2715
|
+
addChunksToBranchBatch(branch, chunkIds) {
|
|
2716
|
+
if (chunkIds.length === 0) return;
|
|
2717
|
+
this.inner.addChunksToBranchBatch(branch, chunkIds);
|
|
2718
|
+
}
|
|
2704
2719
|
clearBranch(branch) {
|
|
2705
2720
|
return this.inner.clearBranch(branch);
|
|
2706
2721
|
}
|
|
@@ -2961,11 +2976,45 @@ var Indexer = class {
|
|
|
2961
2976
|
this.currentBranch = "default";
|
|
2962
2977
|
this.baseBranch = "default";
|
|
2963
2978
|
}
|
|
2979
|
+
if (this.config.indexing.autoGc) {
|
|
2980
|
+
await this.maybeRunAutoGc();
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
async maybeRunAutoGc() {
|
|
2984
|
+
if (!this.database) return;
|
|
2985
|
+
const lastGcTimestamp = this.database.getMetadata("lastGcTimestamp");
|
|
2986
|
+
const now = Date.now();
|
|
2987
|
+
const intervalMs = this.config.indexing.gcIntervalDays * 24 * 60 * 60 * 1e3;
|
|
2988
|
+
let shouldRunGc = false;
|
|
2989
|
+
if (!lastGcTimestamp) {
|
|
2990
|
+
shouldRunGc = true;
|
|
2991
|
+
} else {
|
|
2992
|
+
const lastGcTime = parseInt(lastGcTimestamp, 10);
|
|
2993
|
+
if (!isNaN(lastGcTime) && now - lastGcTime > intervalMs) {
|
|
2994
|
+
shouldRunGc = true;
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
if (shouldRunGc) {
|
|
2998
|
+
await this.healthCheck();
|
|
2999
|
+
this.database.setMetadata("lastGcTimestamp", now.toString());
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
async maybeRunOrphanGc() {
|
|
3003
|
+
if (!this.database) return;
|
|
3004
|
+
const stats = this.database.getStats();
|
|
3005
|
+
if (!stats) return;
|
|
3006
|
+
const orphanCount = stats.embeddingCount - stats.chunkCount;
|
|
3007
|
+
if (orphanCount > this.config.indexing.gcOrphanThreshold) {
|
|
3008
|
+
this.database.gcOrphanEmbeddings();
|
|
3009
|
+
this.database.gcOrphanChunks();
|
|
3010
|
+
this.database.setMetadata("lastGcTimestamp", Date.now().toString());
|
|
3011
|
+
}
|
|
2964
3012
|
}
|
|
2965
3013
|
migrateFromLegacyIndex() {
|
|
2966
3014
|
if (!this.store || !this.database) return;
|
|
2967
3015
|
const allMetadata = this.store.getAllMetadata();
|
|
2968
3016
|
const chunkIds = [];
|
|
3017
|
+
const chunkDataBatch = [];
|
|
2969
3018
|
for (const { key, metadata } of allMetadata) {
|
|
2970
3019
|
const chunkData = {
|
|
2971
3020
|
chunkId: key,
|
|
@@ -2977,10 +3026,13 @@ var Indexer = class {
|
|
|
2977
3026
|
name: metadata.name,
|
|
2978
3027
|
language: metadata.language
|
|
2979
3028
|
};
|
|
2980
|
-
|
|
3029
|
+
chunkDataBatch.push(chunkData);
|
|
2981
3030
|
chunkIds.push(key);
|
|
2982
3031
|
}
|
|
2983
|
-
|
|
3032
|
+
if (chunkDataBatch.length > 0) {
|
|
3033
|
+
this.database.upsertChunksBatch(chunkDataBatch);
|
|
3034
|
+
}
|
|
3035
|
+
this.database.addChunksToBranchBatch(this.currentBranch || "default", chunkIds);
|
|
2984
3036
|
}
|
|
2985
3037
|
async ensureInitialized() {
|
|
2986
3038
|
if (!this.store || !this.provider || !this.invertedIndex || !this.detectedProvider || !this.database) {
|
|
@@ -3076,6 +3128,7 @@ var Indexer = class {
|
|
|
3076
3128
|
}
|
|
3077
3129
|
}
|
|
3078
3130
|
}
|
|
3131
|
+
const chunkDataBatch = [];
|
|
3079
3132
|
for (const parsed of parsedFiles) {
|
|
3080
3133
|
currentFilePaths.add(parsed.path);
|
|
3081
3134
|
if (parsed.chunks.length === 0) {
|
|
@@ -3103,7 +3156,7 @@ var Indexer = class {
|
|
|
3103
3156
|
name: chunk.name,
|
|
3104
3157
|
language: chunk.language
|
|
3105
3158
|
};
|
|
3106
|
-
|
|
3159
|
+
chunkDataBatch.push(chunkData);
|
|
3107
3160
|
if (existingChunks.get(id) === contentHash) {
|
|
3108
3161
|
fileChunkCount++;
|
|
3109
3162
|
continue;
|
|
@@ -3122,6 +3175,9 @@ var Indexer = class {
|
|
|
3122
3175
|
fileChunkCount++;
|
|
3123
3176
|
}
|
|
3124
3177
|
}
|
|
3178
|
+
if (chunkDataBatch.length > 0) {
|
|
3179
|
+
database.upsertChunksBatch(chunkDataBatch);
|
|
3180
|
+
}
|
|
3125
3181
|
let removedCount = 0;
|
|
3126
3182
|
for (const [chunkId] of existingChunks) {
|
|
3127
3183
|
if (!currentChunkIds.has(chunkId)) {
|
|
@@ -3135,7 +3191,7 @@ var Indexer = class {
|
|
|
3135
3191
|
stats.removedChunks = removedCount;
|
|
3136
3192
|
if (pendingChunks.length === 0 && removedCount === 0) {
|
|
3137
3193
|
database.clearBranch(this.currentBranch);
|
|
3138
|
-
database.
|
|
3194
|
+
database.addChunksToBranchBatch(this.currentBranch, Array.from(currentChunkIds));
|
|
3139
3195
|
this.fileHashCache = currentFileHashes;
|
|
3140
3196
|
this.saveFileHashCache();
|
|
3141
3197
|
stats.durationMs = Date.now() - startTime;
|
|
@@ -3150,7 +3206,7 @@ var Indexer = class {
|
|
|
3150
3206
|
}
|
|
3151
3207
|
if (pendingChunks.length === 0) {
|
|
3152
3208
|
database.clearBranch(this.currentBranch);
|
|
3153
|
-
database.
|
|
3209
|
+
database.addChunksToBranchBatch(this.currentBranch, Array.from(currentChunkIds));
|
|
3154
3210
|
store.save();
|
|
3155
3211
|
invertedIndex.save();
|
|
3156
3212
|
this.fileHashCache = currentFileHashes;
|
|
@@ -3234,15 +3290,14 @@ var Indexer = class {
|
|
|
3234
3290
|
metadata: chunk.metadata
|
|
3235
3291
|
}));
|
|
3236
3292
|
store.addBatch(items);
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
);
|
|
3293
|
+
const embeddingBatchItems = batch.map((chunk, i) => ({
|
|
3294
|
+
contentHash: chunk.contentHash,
|
|
3295
|
+
embedding: float32ArrayToBuffer(result.embeddings[i]),
|
|
3296
|
+
chunkText: chunk.text,
|
|
3297
|
+
model: detectedProvider.modelInfo.model
|
|
3298
|
+
}));
|
|
3299
|
+
database.upsertEmbeddingsBatch(embeddingBatchItems);
|
|
3300
|
+
for (const chunk of batch) {
|
|
3246
3301
|
invertedIndex.removeChunk(chunk.id);
|
|
3247
3302
|
invertedIndex.addChunk(chunk.id, chunk.content);
|
|
3248
3303
|
}
|
|
@@ -3271,11 +3326,14 @@ var Indexer = class {
|
|
|
3271
3326
|
totalChunks: pendingChunks.length
|
|
3272
3327
|
});
|
|
3273
3328
|
database.clearBranch(this.currentBranch);
|
|
3274
|
-
database.
|
|
3329
|
+
database.addChunksToBranchBatch(this.currentBranch, Array.from(currentChunkIds));
|
|
3275
3330
|
store.save();
|
|
3276
3331
|
invertedIndex.save();
|
|
3277
3332
|
this.fileHashCache = currentFileHashes;
|
|
3278
3333
|
this.saveFileHashCache();
|
|
3334
|
+
if (this.config.indexing.autoGc && stats.removedChunks > 0) {
|
|
3335
|
+
await this.maybeRunOrphanGc();
|
|
3336
|
+
}
|
|
3279
3337
|
stats.durationMs = Date.now() - startTime;
|
|
3280
3338
|
if (stats.failedChunks > 0) {
|
|
3281
3339
|
stats.failedBatchesPath = this.failedBatchesPath;
|
|
@@ -3415,11 +3473,14 @@ var Indexer = class {
|
|
|
3415
3473
|
};
|
|
3416
3474
|
}
|
|
3417
3475
|
async clearIndex() {
|
|
3418
|
-
const { store, invertedIndex } = await this.ensureInitialized();
|
|
3476
|
+
const { store, invertedIndex, database } = await this.ensureInitialized();
|
|
3419
3477
|
store.clear();
|
|
3420
3478
|
store.save();
|
|
3421
3479
|
invertedIndex.clear();
|
|
3422
3480
|
invertedIndex.save();
|
|
3481
|
+
this.fileHashCache.clear();
|
|
3482
|
+
this.saveFileHashCache();
|
|
3483
|
+
database.clearBranch(this.currentBranch);
|
|
3423
3484
|
}
|
|
3424
3485
|
async healthCheck() {
|
|
3425
3486
|
const { store, invertedIndex, database } = await this.ensureInitialized();
|
|
@@ -3611,7 +3672,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
3611
3672
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
3612
3673
|
const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
|
|
3613
3674
|
if (wantBigintFsStats) {
|
|
3614
|
-
this._stat = (
|
|
3675
|
+
this._stat = (path9) => statMethod(path9, { bigint: true });
|
|
3615
3676
|
} else {
|
|
3616
3677
|
this._stat = statMethod;
|
|
3617
3678
|
}
|
|
@@ -3636,8 +3697,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
3636
3697
|
const par = this.parent;
|
|
3637
3698
|
const fil = par && par.files;
|
|
3638
3699
|
if (fil && fil.length > 0) {
|
|
3639
|
-
const { path:
|
|
3640
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
3700
|
+
const { path: path9, depth } = par;
|
|
3701
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path9));
|
|
3641
3702
|
const awaited = await Promise.all(slice);
|
|
3642
3703
|
for (const entry of awaited) {
|
|
3643
3704
|
if (!entry)
|
|
@@ -3677,21 +3738,21 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
3677
3738
|
this.reading = false;
|
|
3678
3739
|
}
|
|
3679
3740
|
}
|
|
3680
|
-
async _exploreDir(
|
|
3741
|
+
async _exploreDir(path9, depth) {
|
|
3681
3742
|
let files;
|
|
3682
3743
|
try {
|
|
3683
|
-
files = await (0, import_promises.readdir)(
|
|
3744
|
+
files = await (0, import_promises.readdir)(path9, this._rdOptions);
|
|
3684
3745
|
} catch (error) {
|
|
3685
3746
|
this._onError(error);
|
|
3686
3747
|
}
|
|
3687
|
-
return { files, depth, path:
|
|
3748
|
+
return { files, depth, path: path9 };
|
|
3688
3749
|
}
|
|
3689
|
-
async _formatEntry(dirent,
|
|
3750
|
+
async _formatEntry(dirent, path9) {
|
|
3690
3751
|
let entry;
|
|
3691
|
-
const
|
|
3752
|
+
const basename4 = this._isDirent ? dirent.name : dirent;
|
|
3692
3753
|
try {
|
|
3693
|
-
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(
|
|
3694
|
-
entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename:
|
|
3754
|
+
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path9, basename4));
|
|
3755
|
+
entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename4 };
|
|
3695
3756
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
3696
3757
|
} catch (err) {
|
|
3697
3758
|
this._onError(err);
|
|
@@ -4090,16 +4151,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
4090
4151
|
};
|
|
4091
4152
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
4092
4153
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
4093
|
-
function createFsWatchInstance(
|
|
4154
|
+
function createFsWatchInstance(path9, options, listener, errHandler, emitRaw) {
|
|
4094
4155
|
const handleEvent = (rawEvent, evPath) => {
|
|
4095
|
-
listener(
|
|
4096
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
4097
|
-
if (evPath &&
|
|
4098
|
-
fsWatchBroadcast(sp.resolve(
|
|
4156
|
+
listener(path9);
|
|
4157
|
+
emitRaw(rawEvent, evPath, { watchedPath: path9 });
|
|
4158
|
+
if (evPath && path9 !== evPath) {
|
|
4159
|
+
fsWatchBroadcast(sp.resolve(path9, evPath), KEY_LISTENERS, sp.join(path9, evPath));
|
|
4099
4160
|
}
|
|
4100
4161
|
};
|
|
4101
4162
|
try {
|
|
4102
|
-
return (0, import_node_fs.watch)(
|
|
4163
|
+
return (0, import_node_fs.watch)(path9, {
|
|
4103
4164
|
persistent: options.persistent
|
|
4104
4165
|
}, handleEvent);
|
|
4105
4166
|
} catch (error) {
|
|
@@ -4115,12 +4176,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
4115
4176
|
listener(val1, val2, val3);
|
|
4116
4177
|
});
|
|
4117
4178
|
};
|
|
4118
|
-
var setFsWatchListener = (
|
|
4179
|
+
var setFsWatchListener = (path9, fullPath, options, handlers) => {
|
|
4119
4180
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
4120
4181
|
let cont = FsWatchInstances.get(fullPath);
|
|
4121
4182
|
let watcher;
|
|
4122
4183
|
if (!options.persistent) {
|
|
4123
|
-
watcher = createFsWatchInstance(
|
|
4184
|
+
watcher = createFsWatchInstance(path9, options, listener, errHandler, rawEmitter);
|
|
4124
4185
|
if (!watcher)
|
|
4125
4186
|
return;
|
|
4126
4187
|
return watcher.close.bind(watcher);
|
|
@@ -4131,7 +4192,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
4131
4192
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
4132
4193
|
} else {
|
|
4133
4194
|
watcher = createFsWatchInstance(
|
|
4134
|
-
|
|
4195
|
+
path9,
|
|
4135
4196
|
options,
|
|
4136
4197
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
4137
4198
|
errHandler,
|
|
@@ -4146,7 +4207,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
4146
4207
|
cont.watcherUnusable = true;
|
|
4147
4208
|
if (isWindows && error.code === "EPERM") {
|
|
4148
4209
|
try {
|
|
4149
|
-
const fd = await (0, import_promises2.open)(
|
|
4210
|
+
const fd = await (0, import_promises2.open)(path9, "r");
|
|
4150
4211
|
await fd.close();
|
|
4151
4212
|
broadcastErr(error);
|
|
4152
4213
|
} catch (err) {
|
|
@@ -4177,7 +4238,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
4177
4238
|
};
|
|
4178
4239
|
};
|
|
4179
4240
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
4180
|
-
var setFsWatchFileListener = (
|
|
4241
|
+
var setFsWatchFileListener = (path9, fullPath, options, handlers) => {
|
|
4181
4242
|
const { listener, rawEmitter } = handlers;
|
|
4182
4243
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
4183
4244
|
const copts = cont && cont.options;
|
|
@@ -4199,7 +4260,7 @@ var setFsWatchFileListener = (path8, fullPath, options, handlers) => {
|
|
|
4199
4260
|
});
|
|
4200
4261
|
const currmtime = curr.mtimeMs;
|
|
4201
4262
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
4202
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
4263
|
+
foreach(cont.listeners, (listener2) => listener2(path9, curr));
|
|
4203
4264
|
}
|
|
4204
4265
|
})
|
|
4205
4266
|
};
|
|
@@ -4229,13 +4290,13 @@ var NodeFsHandler = class {
|
|
|
4229
4290
|
* @param listener on fs change
|
|
4230
4291
|
* @returns closer for the watcher instance
|
|
4231
4292
|
*/
|
|
4232
|
-
_watchWithNodeFs(
|
|
4293
|
+
_watchWithNodeFs(path9, listener) {
|
|
4233
4294
|
const opts = this.fsw.options;
|
|
4234
|
-
const directory = sp.dirname(
|
|
4235
|
-
const
|
|
4295
|
+
const directory = sp.dirname(path9);
|
|
4296
|
+
const basename4 = sp.basename(path9);
|
|
4236
4297
|
const parent = this.fsw._getWatchedDir(directory);
|
|
4237
|
-
parent.add(
|
|
4238
|
-
const absolutePath = sp.resolve(
|
|
4298
|
+
parent.add(basename4);
|
|
4299
|
+
const absolutePath = sp.resolve(path9);
|
|
4239
4300
|
const options = {
|
|
4240
4301
|
persistent: opts.persistent
|
|
4241
4302
|
};
|
|
@@ -4244,13 +4305,13 @@ var NodeFsHandler = class {
|
|
|
4244
4305
|
let closer;
|
|
4245
4306
|
if (opts.usePolling) {
|
|
4246
4307
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
4247
|
-
options.interval = enableBin && isBinaryPath(
|
|
4248
|
-
closer = setFsWatchFileListener(
|
|
4308
|
+
options.interval = enableBin && isBinaryPath(basename4) ? opts.binaryInterval : opts.interval;
|
|
4309
|
+
closer = setFsWatchFileListener(path9, absolutePath, options, {
|
|
4249
4310
|
listener,
|
|
4250
4311
|
rawEmitter: this.fsw._emitRaw
|
|
4251
4312
|
});
|
|
4252
4313
|
} else {
|
|
4253
|
-
closer = setFsWatchListener(
|
|
4314
|
+
closer = setFsWatchListener(path9, absolutePath, options, {
|
|
4254
4315
|
listener,
|
|
4255
4316
|
errHandler: this._boundHandleError,
|
|
4256
4317
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -4266,13 +4327,13 @@ var NodeFsHandler = class {
|
|
|
4266
4327
|
if (this.fsw.closed) {
|
|
4267
4328
|
return;
|
|
4268
4329
|
}
|
|
4269
|
-
const
|
|
4270
|
-
const
|
|
4271
|
-
const parent = this.fsw._getWatchedDir(
|
|
4330
|
+
const dirname5 = sp.dirname(file);
|
|
4331
|
+
const basename4 = sp.basename(file);
|
|
4332
|
+
const parent = this.fsw._getWatchedDir(dirname5);
|
|
4272
4333
|
let prevStats = stats;
|
|
4273
|
-
if (parent.has(
|
|
4334
|
+
if (parent.has(basename4))
|
|
4274
4335
|
return;
|
|
4275
|
-
const listener = async (
|
|
4336
|
+
const listener = async (path9, newStats) => {
|
|
4276
4337
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
4277
4338
|
return;
|
|
4278
4339
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -4286,18 +4347,18 @@ var NodeFsHandler = class {
|
|
|
4286
4347
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
4287
4348
|
}
|
|
4288
4349
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
4289
|
-
this.fsw._closeFile(
|
|
4350
|
+
this.fsw._closeFile(path9);
|
|
4290
4351
|
prevStats = newStats2;
|
|
4291
4352
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
4292
4353
|
if (closer2)
|
|
4293
|
-
this.fsw._addPathCloser(
|
|
4354
|
+
this.fsw._addPathCloser(path9, closer2);
|
|
4294
4355
|
} else {
|
|
4295
4356
|
prevStats = newStats2;
|
|
4296
4357
|
}
|
|
4297
4358
|
} catch (error) {
|
|
4298
|
-
this.fsw._remove(
|
|
4359
|
+
this.fsw._remove(dirname5, basename4);
|
|
4299
4360
|
}
|
|
4300
|
-
} else if (parent.has(
|
|
4361
|
+
} else if (parent.has(basename4)) {
|
|
4301
4362
|
const at = newStats.atimeMs;
|
|
4302
4363
|
const mt = newStats.mtimeMs;
|
|
4303
4364
|
if (!at || at <= mt || mt !== prevStats.mtimeMs) {
|
|
@@ -4322,7 +4383,7 @@ var NodeFsHandler = class {
|
|
|
4322
4383
|
* @param item basename of this item
|
|
4323
4384
|
* @returns true if no more processing is needed for this entry.
|
|
4324
4385
|
*/
|
|
4325
|
-
async _handleSymlink(entry, directory,
|
|
4386
|
+
async _handleSymlink(entry, directory, path9, item) {
|
|
4326
4387
|
if (this.fsw.closed) {
|
|
4327
4388
|
return;
|
|
4328
4389
|
}
|
|
@@ -4332,7 +4393,7 @@ var NodeFsHandler = class {
|
|
|
4332
4393
|
this.fsw._incrReadyCount();
|
|
4333
4394
|
let linkPath;
|
|
4334
4395
|
try {
|
|
4335
|
-
linkPath = await (0, import_promises2.realpath)(
|
|
4396
|
+
linkPath = await (0, import_promises2.realpath)(path9);
|
|
4336
4397
|
} catch (e) {
|
|
4337
4398
|
this.fsw._emitReady();
|
|
4338
4399
|
return true;
|
|
@@ -4342,12 +4403,12 @@ var NodeFsHandler = class {
|
|
|
4342
4403
|
if (dir.has(item)) {
|
|
4343
4404
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
4344
4405
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
4345
|
-
this.fsw._emit(EV.CHANGE,
|
|
4406
|
+
this.fsw._emit(EV.CHANGE, path9, entry.stats);
|
|
4346
4407
|
}
|
|
4347
4408
|
} else {
|
|
4348
4409
|
dir.add(item);
|
|
4349
4410
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
4350
|
-
this.fsw._emit(EV.ADD,
|
|
4411
|
+
this.fsw._emit(EV.ADD, path9, entry.stats);
|
|
4351
4412
|
}
|
|
4352
4413
|
this.fsw._emitReady();
|
|
4353
4414
|
return true;
|
|
@@ -4377,9 +4438,9 @@ var NodeFsHandler = class {
|
|
|
4377
4438
|
return;
|
|
4378
4439
|
}
|
|
4379
4440
|
const item = entry.path;
|
|
4380
|
-
let
|
|
4441
|
+
let path9 = sp.join(directory, item);
|
|
4381
4442
|
current.add(item);
|
|
4382
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
4443
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path9, item)) {
|
|
4383
4444
|
return;
|
|
4384
4445
|
}
|
|
4385
4446
|
if (this.fsw.closed) {
|
|
@@ -4388,8 +4449,8 @@ var NodeFsHandler = class {
|
|
|
4388
4449
|
}
|
|
4389
4450
|
if (item === target || !target && !previous.has(item)) {
|
|
4390
4451
|
this.fsw._incrReadyCount();
|
|
4391
|
-
|
|
4392
|
-
this._addToNodeFs(
|
|
4452
|
+
path9 = sp.join(dir, sp.relative(dir, path9));
|
|
4453
|
+
this._addToNodeFs(path9, initialAdd, wh, depth + 1);
|
|
4393
4454
|
}
|
|
4394
4455
|
}).on(EV.ERROR, this._boundHandleError);
|
|
4395
4456
|
return new Promise((resolve4, reject) => {
|
|
@@ -4458,13 +4519,13 @@ var NodeFsHandler = class {
|
|
|
4458
4519
|
* @param depth Child path actually targeted for watch
|
|
4459
4520
|
* @param target Child path actually targeted for watch
|
|
4460
4521
|
*/
|
|
4461
|
-
async _addToNodeFs(
|
|
4522
|
+
async _addToNodeFs(path9, initialAdd, priorWh, depth, target) {
|
|
4462
4523
|
const ready = this.fsw._emitReady;
|
|
4463
|
-
if (this.fsw._isIgnored(
|
|
4524
|
+
if (this.fsw._isIgnored(path9) || this.fsw.closed) {
|
|
4464
4525
|
ready();
|
|
4465
4526
|
return false;
|
|
4466
4527
|
}
|
|
4467
|
-
const wh = this.fsw._getWatchHelpers(
|
|
4528
|
+
const wh = this.fsw._getWatchHelpers(path9);
|
|
4468
4529
|
if (priorWh) {
|
|
4469
4530
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
4470
4531
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -4480,8 +4541,8 @@ var NodeFsHandler = class {
|
|
|
4480
4541
|
const follow = this.fsw.options.followSymlinks;
|
|
4481
4542
|
let closer;
|
|
4482
4543
|
if (stats.isDirectory()) {
|
|
4483
|
-
const absPath = sp.resolve(
|
|
4484
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
4544
|
+
const absPath = sp.resolve(path9);
|
|
4545
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path9) : path9;
|
|
4485
4546
|
if (this.fsw.closed)
|
|
4486
4547
|
return;
|
|
4487
4548
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -4491,29 +4552,29 @@ var NodeFsHandler = class {
|
|
|
4491
4552
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
4492
4553
|
}
|
|
4493
4554
|
} else if (stats.isSymbolicLink()) {
|
|
4494
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
4555
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path9) : path9;
|
|
4495
4556
|
if (this.fsw.closed)
|
|
4496
4557
|
return;
|
|
4497
4558
|
const parent = sp.dirname(wh.watchPath);
|
|
4498
4559
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
4499
4560
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
4500
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
4561
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path9, wh, targetPath);
|
|
4501
4562
|
if (this.fsw.closed)
|
|
4502
4563
|
return;
|
|
4503
4564
|
if (targetPath !== void 0) {
|
|
4504
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
4565
|
+
this.fsw._symlinkPaths.set(sp.resolve(path9), targetPath);
|
|
4505
4566
|
}
|
|
4506
4567
|
} else {
|
|
4507
4568
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
4508
4569
|
}
|
|
4509
4570
|
ready();
|
|
4510
4571
|
if (closer)
|
|
4511
|
-
this.fsw._addPathCloser(
|
|
4572
|
+
this.fsw._addPathCloser(path9, closer);
|
|
4512
4573
|
return false;
|
|
4513
4574
|
} catch (error) {
|
|
4514
4575
|
if (this.fsw._handleError(error)) {
|
|
4515
4576
|
ready();
|
|
4516
|
-
return
|
|
4577
|
+
return path9;
|
|
4517
4578
|
}
|
|
4518
4579
|
}
|
|
4519
4580
|
}
|
|
@@ -4556,24 +4617,24 @@ function createPattern(matcher) {
|
|
|
4556
4617
|
}
|
|
4557
4618
|
return () => false;
|
|
4558
4619
|
}
|
|
4559
|
-
function normalizePath(
|
|
4560
|
-
if (typeof
|
|
4620
|
+
function normalizePath(path9) {
|
|
4621
|
+
if (typeof path9 !== "string")
|
|
4561
4622
|
throw new Error("string expected");
|
|
4562
|
-
|
|
4563
|
-
|
|
4623
|
+
path9 = sp2.normalize(path9);
|
|
4624
|
+
path9 = path9.replace(/\\/g, "/");
|
|
4564
4625
|
let prepend = false;
|
|
4565
|
-
if (
|
|
4626
|
+
if (path9.startsWith("//"))
|
|
4566
4627
|
prepend = true;
|
|
4567
|
-
|
|
4628
|
+
path9 = path9.replace(DOUBLE_SLASH_RE, "/");
|
|
4568
4629
|
if (prepend)
|
|
4569
|
-
|
|
4570
|
-
return
|
|
4630
|
+
path9 = "/" + path9;
|
|
4631
|
+
return path9;
|
|
4571
4632
|
}
|
|
4572
4633
|
function matchPatterns(patterns, testString, stats) {
|
|
4573
|
-
const
|
|
4634
|
+
const path9 = normalizePath(testString);
|
|
4574
4635
|
for (let index = 0; index < patterns.length; index++) {
|
|
4575
4636
|
const pattern = patterns[index];
|
|
4576
|
-
if (pattern(
|
|
4637
|
+
if (pattern(path9, stats)) {
|
|
4577
4638
|
return true;
|
|
4578
4639
|
}
|
|
4579
4640
|
}
|
|
@@ -4611,19 +4672,19 @@ var toUnix = (string) => {
|
|
|
4611
4672
|
}
|
|
4612
4673
|
return str;
|
|
4613
4674
|
};
|
|
4614
|
-
var normalizePathToUnix = (
|
|
4615
|
-
var normalizeIgnored = (cwd = "") => (
|
|
4616
|
-
if (typeof
|
|
4617
|
-
return normalizePathToUnix(sp2.isAbsolute(
|
|
4675
|
+
var normalizePathToUnix = (path9) => toUnix(sp2.normalize(toUnix(path9)));
|
|
4676
|
+
var normalizeIgnored = (cwd = "") => (path9) => {
|
|
4677
|
+
if (typeof path9 === "string") {
|
|
4678
|
+
return normalizePathToUnix(sp2.isAbsolute(path9) ? path9 : sp2.join(cwd, path9));
|
|
4618
4679
|
} else {
|
|
4619
|
-
return
|
|
4680
|
+
return path9;
|
|
4620
4681
|
}
|
|
4621
4682
|
};
|
|
4622
|
-
var getAbsolutePath = (
|
|
4623
|
-
if (sp2.isAbsolute(
|
|
4624
|
-
return
|
|
4683
|
+
var getAbsolutePath = (path9, cwd) => {
|
|
4684
|
+
if (sp2.isAbsolute(path9)) {
|
|
4685
|
+
return path9;
|
|
4625
4686
|
}
|
|
4626
|
-
return sp2.join(cwd,
|
|
4687
|
+
return sp2.join(cwd, path9);
|
|
4627
4688
|
};
|
|
4628
4689
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
4629
4690
|
var DirEntry = class {
|
|
@@ -4688,10 +4749,10 @@ var WatchHelper = class {
|
|
|
4688
4749
|
dirParts;
|
|
4689
4750
|
followSymlinks;
|
|
4690
4751
|
statMethod;
|
|
4691
|
-
constructor(
|
|
4752
|
+
constructor(path9, follow, fsw) {
|
|
4692
4753
|
this.fsw = fsw;
|
|
4693
|
-
const watchPath =
|
|
4694
|
-
this.path =
|
|
4754
|
+
const watchPath = path9;
|
|
4755
|
+
this.path = path9 = path9.replace(REPLACER_RE, "");
|
|
4695
4756
|
this.watchPath = watchPath;
|
|
4696
4757
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
4697
4758
|
this.dirParts = [];
|
|
@@ -4831,20 +4892,20 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4831
4892
|
this._closePromise = void 0;
|
|
4832
4893
|
let paths = unifyPaths(paths_);
|
|
4833
4894
|
if (cwd) {
|
|
4834
|
-
paths = paths.map((
|
|
4835
|
-
const absPath = getAbsolutePath(
|
|
4895
|
+
paths = paths.map((path9) => {
|
|
4896
|
+
const absPath = getAbsolutePath(path9, cwd);
|
|
4836
4897
|
return absPath;
|
|
4837
4898
|
});
|
|
4838
4899
|
}
|
|
4839
|
-
paths.forEach((
|
|
4840
|
-
this._removeIgnoredPath(
|
|
4900
|
+
paths.forEach((path9) => {
|
|
4901
|
+
this._removeIgnoredPath(path9);
|
|
4841
4902
|
});
|
|
4842
4903
|
this._userIgnored = void 0;
|
|
4843
4904
|
if (!this._readyCount)
|
|
4844
4905
|
this._readyCount = 0;
|
|
4845
4906
|
this._readyCount += paths.length;
|
|
4846
|
-
Promise.all(paths.map(async (
|
|
4847
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
4907
|
+
Promise.all(paths.map(async (path9) => {
|
|
4908
|
+
const res = await this._nodeFsHandler._addToNodeFs(path9, !_internal, void 0, 0, _origAdd);
|
|
4848
4909
|
if (res)
|
|
4849
4910
|
this._emitReady();
|
|
4850
4911
|
return res;
|
|
@@ -4866,17 +4927,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4866
4927
|
return this;
|
|
4867
4928
|
const paths = unifyPaths(paths_);
|
|
4868
4929
|
const { cwd } = this.options;
|
|
4869
|
-
paths.forEach((
|
|
4870
|
-
if (!sp2.isAbsolute(
|
|
4930
|
+
paths.forEach((path9) => {
|
|
4931
|
+
if (!sp2.isAbsolute(path9) && !this._closers.has(path9)) {
|
|
4871
4932
|
if (cwd)
|
|
4872
|
-
|
|
4873
|
-
|
|
4933
|
+
path9 = sp2.join(cwd, path9);
|
|
4934
|
+
path9 = sp2.resolve(path9);
|
|
4874
4935
|
}
|
|
4875
|
-
this._closePath(
|
|
4876
|
-
this._addIgnoredPath(
|
|
4877
|
-
if (this._watched.has(
|
|
4936
|
+
this._closePath(path9);
|
|
4937
|
+
this._addIgnoredPath(path9);
|
|
4938
|
+
if (this._watched.has(path9)) {
|
|
4878
4939
|
this._addIgnoredPath({
|
|
4879
|
-
path:
|
|
4940
|
+
path: path9,
|
|
4880
4941
|
recursive: true
|
|
4881
4942
|
});
|
|
4882
4943
|
}
|
|
@@ -4940,38 +5001,38 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4940
5001
|
* @param stats arguments to be passed with event
|
|
4941
5002
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
4942
5003
|
*/
|
|
4943
|
-
async _emit(event,
|
|
5004
|
+
async _emit(event, path9, stats) {
|
|
4944
5005
|
if (this.closed)
|
|
4945
5006
|
return;
|
|
4946
5007
|
const opts = this.options;
|
|
4947
5008
|
if (isWindows)
|
|
4948
|
-
|
|
5009
|
+
path9 = sp2.normalize(path9);
|
|
4949
5010
|
if (opts.cwd)
|
|
4950
|
-
|
|
4951
|
-
const args = [
|
|
5011
|
+
path9 = sp2.relative(opts.cwd, path9);
|
|
5012
|
+
const args = [path9];
|
|
4952
5013
|
if (stats != null)
|
|
4953
5014
|
args.push(stats);
|
|
4954
5015
|
const awf = opts.awaitWriteFinish;
|
|
4955
5016
|
let pw;
|
|
4956
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
5017
|
+
if (awf && (pw = this._pendingWrites.get(path9))) {
|
|
4957
5018
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
4958
5019
|
return this;
|
|
4959
5020
|
}
|
|
4960
5021
|
if (opts.atomic) {
|
|
4961
5022
|
if (event === EVENTS.UNLINK) {
|
|
4962
|
-
this._pendingUnlinks.set(
|
|
5023
|
+
this._pendingUnlinks.set(path9, [event, ...args]);
|
|
4963
5024
|
setTimeout(() => {
|
|
4964
|
-
this._pendingUnlinks.forEach((entry,
|
|
5025
|
+
this._pendingUnlinks.forEach((entry, path10) => {
|
|
4965
5026
|
this.emit(...entry);
|
|
4966
5027
|
this.emit(EVENTS.ALL, ...entry);
|
|
4967
|
-
this._pendingUnlinks.delete(
|
|
5028
|
+
this._pendingUnlinks.delete(path10);
|
|
4968
5029
|
});
|
|
4969
5030
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
4970
5031
|
return this;
|
|
4971
5032
|
}
|
|
4972
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
5033
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path9)) {
|
|
4973
5034
|
event = EVENTS.CHANGE;
|
|
4974
|
-
this._pendingUnlinks.delete(
|
|
5035
|
+
this._pendingUnlinks.delete(path9);
|
|
4975
5036
|
}
|
|
4976
5037
|
}
|
|
4977
5038
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -4989,16 +5050,16 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
4989
5050
|
this.emitWithAll(event, args);
|
|
4990
5051
|
}
|
|
4991
5052
|
};
|
|
4992
|
-
this._awaitWriteFinish(
|
|
5053
|
+
this._awaitWriteFinish(path9, awf.stabilityThreshold, event, awfEmit);
|
|
4993
5054
|
return this;
|
|
4994
5055
|
}
|
|
4995
5056
|
if (event === EVENTS.CHANGE) {
|
|
4996
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
5057
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path9, 50);
|
|
4997
5058
|
if (isThrottled)
|
|
4998
5059
|
return this;
|
|
4999
5060
|
}
|
|
5000
5061
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
5001
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
5062
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path9) : path9;
|
|
5002
5063
|
let stats2;
|
|
5003
5064
|
try {
|
|
5004
5065
|
stats2 = await (0, import_promises3.stat)(fullPath);
|
|
@@ -5029,23 +5090,23 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
5029
5090
|
* @param timeout duration of time to suppress duplicate actions
|
|
5030
5091
|
* @returns tracking object or false if action should be suppressed
|
|
5031
5092
|
*/
|
|
5032
|
-
_throttle(actionType,
|
|
5093
|
+
_throttle(actionType, path9, timeout) {
|
|
5033
5094
|
if (!this._throttled.has(actionType)) {
|
|
5034
5095
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
5035
5096
|
}
|
|
5036
5097
|
const action = this._throttled.get(actionType);
|
|
5037
5098
|
if (!action)
|
|
5038
5099
|
throw new Error("invalid throttle");
|
|
5039
|
-
const actionPath = action.get(
|
|
5100
|
+
const actionPath = action.get(path9);
|
|
5040
5101
|
if (actionPath) {
|
|
5041
5102
|
actionPath.count++;
|
|
5042
5103
|
return false;
|
|
5043
5104
|
}
|
|
5044
5105
|
let timeoutObject;
|
|
5045
5106
|
const clear = () => {
|
|
5046
|
-
const item = action.get(
|
|
5107
|
+
const item = action.get(path9);
|
|
5047
5108
|
const count = item ? item.count : 0;
|
|
5048
|
-
action.delete(
|
|
5109
|
+
action.delete(path9);
|
|
5049
5110
|
clearTimeout(timeoutObject);
|
|
5050
5111
|
if (item)
|
|
5051
5112
|
clearTimeout(item.timeoutObject);
|
|
@@ -5053,7 +5114,7 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
5053
5114
|
};
|
|
5054
5115
|
timeoutObject = setTimeout(clear, timeout);
|
|
5055
5116
|
const thr = { timeoutObject, clear, count: 0 };
|
|
5056
|
-
action.set(
|
|
5117
|
+
action.set(path9, thr);
|
|
5057
5118
|
return thr;
|
|
5058
5119
|
}
|
|
5059
5120
|
_incrReadyCount() {
|
|
@@ -5067,44 +5128,44 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
5067
5128
|
* @param event
|
|
5068
5129
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
5069
5130
|
*/
|
|
5070
|
-
_awaitWriteFinish(
|
|
5131
|
+
_awaitWriteFinish(path9, threshold, event, awfEmit) {
|
|
5071
5132
|
const awf = this.options.awaitWriteFinish;
|
|
5072
5133
|
if (typeof awf !== "object")
|
|
5073
5134
|
return;
|
|
5074
5135
|
const pollInterval = awf.pollInterval;
|
|
5075
5136
|
let timeoutHandler;
|
|
5076
|
-
let fullPath =
|
|
5077
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
5078
|
-
fullPath = sp2.join(this.options.cwd,
|
|
5137
|
+
let fullPath = path9;
|
|
5138
|
+
if (this.options.cwd && !sp2.isAbsolute(path9)) {
|
|
5139
|
+
fullPath = sp2.join(this.options.cwd, path9);
|
|
5079
5140
|
}
|
|
5080
5141
|
const now = /* @__PURE__ */ new Date();
|
|
5081
5142
|
const writes = this._pendingWrites;
|
|
5082
5143
|
function awaitWriteFinishFn(prevStat) {
|
|
5083
5144
|
(0, import_node_fs2.stat)(fullPath, (err, curStat) => {
|
|
5084
|
-
if (err || !writes.has(
|
|
5145
|
+
if (err || !writes.has(path9)) {
|
|
5085
5146
|
if (err && err.code !== "ENOENT")
|
|
5086
5147
|
awfEmit(err);
|
|
5087
5148
|
return;
|
|
5088
5149
|
}
|
|
5089
5150
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
5090
5151
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
5091
|
-
writes.get(
|
|
5152
|
+
writes.get(path9).lastChange = now2;
|
|
5092
5153
|
}
|
|
5093
|
-
const pw = writes.get(
|
|
5154
|
+
const pw = writes.get(path9);
|
|
5094
5155
|
const df = now2 - pw.lastChange;
|
|
5095
5156
|
if (df >= threshold) {
|
|
5096
|
-
writes.delete(
|
|
5157
|
+
writes.delete(path9);
|
|
5097
5158
|
awfEmit(void 0, curStat);
|
|
5098
5159
|
} else {
|
|
5099
5160
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
5100
5161
|
}
|
|
5101
5162
|
});
|
|
5102
5163
|
}
|
|
5103
|
-
if (!writes.has(
|
|
5104
|
-
writes.set(
|
|
5164
|
+
if (!writes.has(path9)) {
|
|
5165
|
+
writes.set(path9, {
|
|
5105
5166
|
lastChange: now,
|
|
5106
5167
|
cancelWait: () => {
|
|
5107
|
-
writes.delete(
|
|
5168
|
+
writes.delete(path9);
|
|
5108
5169
|
clearTimeout(timeoutHandler);
|
|
5109
5170
|
return event;
|
|
5110
5171
|
}
|
|
@@ -5115,8 +5176,8 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
5115
5176
|
/**
|
|
5116
5177
|
* Determines whether user has asked to ignore this path.
|
|
5117
5178
|
*/
|
|
5118
|
-
_isIgnored(
|
|
5119
|
-
if (this.options.atomic && DOT_RE.test(
|
|
5179
|
+
_isIgnored(path9, stats) {
|
|
5180
|
+
if (this.options.atomic && DOT_RE.test(path9))
|
|
5120
5181
|
return true;
|
|
5121
5182
|
if (!this._userIgnored) {
|
|
5122
5183
|
const { cwd } = this.options;
|
|
@@ -5126,17 +5187,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
5126
5187
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
5127
5188
|
this._userIgnored = anymatch(list, void 0);
|
|
5128
5189
|
}
|
|
5129
|
-
return this._userIgnored(
|
|
5190
|
+
return this._userIgnored(path9, stats);
|
|
5130
5191
|
}
|
|
5131
|
-
_isntIgnored(
|
|
5132
|
-
return !this._isIgnored(
|
|
5192
|
+
_isntIgnored(path9, stat4) {
|
|
5193
|
+
return !this._isIgnored(path9, stat4);
|
|
5133
5194
|
}
|
|
5134
5195
|
/**
|
|
5135
5196
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
5136
5197
|
* @param path file or directory pattern being watched
|
|
5137
5198
|
*/
|
|
5138
|
-
_getWatchHelpers(
|
|
5139
|
-
return new WatchHelper(
|
|
5199
|
+
_getWatchHelpers(path9) {
|
|
5200
|
+
return new WatchHelper(path9, this.options.followSymlinks, this);
|
|
5140
5201
|
}
|
|
5141
5202
|
// Directory helpers
|
|
5142
5203
|
// -----------------
|
|
@@ -5168,63 +5229,63 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
5168
5229
|
* @param item base path of item/directory
|
|
5169
5230
|
*/
|
|
5170
5231
|
_remove(directory, item, isDirectory) {
|
|
5171
|
-
const
|
|
5172
|
-
const fullPath = sp2.resolve(
|
|
5173
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
5174
|
-
if (!this._throttle("remove",
|
|
5232
|
+
const path9 = sp2.join(directory, item);
|
|
5233
|
+
const fullPath = sp2.resolve(path9);
|
|
5234
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path9) || this._watched.has(fullPath);
|
|
5235
|
+
if (!this._throttle("remove", path9, 100))
|
|
5175
5236
|
return;
|
|
5176
5237
|
if (!isDirectory && this._watched.size === 1) {
|
|
5177
5238
|
this.add(directory, item, true);
|
|
5178
5239
|
}
|
|
5179
|
-
const wp = this._getWatchedDir(
|
|
5240
|
+
const wp = this._getWatchedDir(path9);
|
|
5180
5241
|
const nestedDirectoryChildren = wp.getChildren();
|
|
5181
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
5242
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path9, nested));
|
|
5182
5243
|
const parent = this._getWatchedDir(directory);
|
|
5183
5244
|
const wasTracked = parent.has(item);
|
|
5184
5245
|
parent.remove(item);
|
|
5185
5246
|
if (this._symlinkPaths.has(fullPath)) {
|
|
5186
5247
|
this._symlinkPaths.delete(fullPath);
|
|
5187
5248
|
}
|
|
5188
|
-
let relPath =
|
|
5249
|
+
let relPath = path9;
|
|
5189
5250
|
if (this.options.cwd)
|
|
5190
|
-
relPath = sp2.relative(this.options.cwd,
|
|
5251
|
+
relPath = sp2.relative(this.options.cwd, path9);
|
|
5191
5252
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
5192
5253
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
5193
5254
|
if (event === EVENTS.ADD)
|
|
5194
5255
|
return;
|
|
5195
5256
|
}
|
|
5196
|
-
this._watched.delete(
|
|
5257
|
+
this._watched.delete(path9);
|
|
5197
5258
|
this._watched.delete(fullPath);
|
|
5198
5259
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
5199
|
-
if (wasTracked && !this._isIgnored(
|
|
5200
|
-
this._emit(eventName,
|
|
5201
|
-
this._closePath(
|
|
5260
|
+
if (wasTracked && !this._isIgnored(path9))
|
|
5261
|
+
this._emit(eventName, path9);
|
|
5262
|
+
this._closePath(path9);
|
|
5202
5263
|
}
|
|
5203
5264
|
/**
|
|
5204
5265
|
* Closes all watchers for a path
|
|
5205
5266
|
*/
|
|
5206
|
-
_closePath(
|
|
5207
|
-
this._closeFile(
|
|
5208
|
-
const dir = sp2.dirname(
|
|
5209
|
-
this._getWatchedDir(dir).remove(sp2.basename(
|
|
5267
|
+
_closePath(path9) {
|
|
5268
|
+
this._closeFile(path9);
|
|
5269
|
+
const dir = sp2.dirname(path9);
|
|
5270
|
+
this._getWatchedDir(dir).remove(sp2.basename(path9));
|
|
5210
5271
|
}
|
|
5211
5272
|
/**
|
|
5212
5273
|
* Closes only file-specific watchers
|
|
5213
5274
|
*/
|
|
5214
|
-
_closeFile(
|
|
5215
|
-
const closers = this._closers.get(
|
|
5275
|
+
_closeFile(path9) {
|
|
5276
|
+
const closers = this._closers.get(path9);
|
|
5216
5277
|
if (!closers)
|
|
5217
5278
|
return;
|
|
5218
5279
|
closers.forEach((closer) => closer());
|
|
5219
|
-
this._closers.delete(
|
|
5280
|
+
this._closers.delete(path9);
|
|
5220
5281
|
}
|
|
5221
|
-
_addPathCloser(
|
|
5282
|
+
_addPathCloser(path9, closer) {
|
|
5222
5283
|
if (!closer)
|
|
5223
5284
|
return;
|
|
5224
|
-
let list = this._closers.get(
|
|
5285
|
+
let list = this._closers.get(path9);
|
|
5225
5286
|
if (!list) {
|
|
5226
5287
|
list = [];
|
|
5227
|
-
this._closers.set(
|
|
5288
|
+
this._closers.set(path9, list);
|
|
5228
5289
|
}
|
|
5229
5290
|
list.push(closer);
|
|
5230
5291
|
}
|
|
@@ -5319,7 +5380,7 @@ var FileWatcher = class {
|
|
|
5319
5380
|
return;
|
|
5320
5381
|
}
|
|
5321
5382
|
const changes = Array.from(this.pendingChanges.entries()).map(
|
|
5322
|
-
([
|
|
5383
|
+
([path9, type]) => ({ path: path9, type })
|
|
5323
5384
|
);
|
|
5324
5385
|
this.pendingChanges.clear();
|
|
5325
5386
|
try {
|
|
@@ -5499,7 +5560,7 @@ var index_codebase = (0, import_plugin.tool)({
|
|
|
5499
5560
|
estimateOnly: z.boolean().optional().default(false).describe("Only show cost estimate without indexing"),
|
|
5500
5561
|
verbose: z.boolean().optional().default(false).describe("Show detailed info about skipped files and parsing failures")
|
|
5501
5562
|
},
|
|
5502
|
-
async execute(args) {
|
|
5563
|
+
async execute(args, context) {
|
|
5503
5564
|
const indexer = getIndexer();
|
|
5504
5565
|
if (args.estimateOnly) {
|
|
5505
5566
|
const estimate = await indexer.estimateCost();
|
|
@@ -5508,7 +5569,19 @@ var index_codebase = (0, import_plugin.tool)({
|
|
|
5508
5569
|
if (args.force) {
|
|
5509
5570
|
await indexer.clearIndex();
|
|
5510
5571
|
}
|
|
5511
|
-
const stats = await indexer.index()
|
|
5572
|
+
const stats = await indexer.index((progress) => {
|
|
5573
|
+
context.metadata({
|
|
5574
|
+
title: formatProgressTitle(progress),
|
|
5575
|
+
metadata: {
|
|
5576
|
+
phase: progress.phase,
|
|
5577
|
+
filesProcessed: progress.filesProcessed,
|
|
5578
|
+
totalFiles: progress.totalFiles,
|
|
5579
|
+
chunksProcessed: progress.chunksProcessed,
|
|
5580
|
+
totalChunks: progress.totalChunks,
|
|
5581
|
+
percentage: calculatePercentage(progress)
|
|
5582
|
+
}
|
|
5583
|
+
});
|
|
5584
|
+
});
|
|
5512
5585
|
return formatIndexStats(stats, args.verbose ?? false);
|
|
5513
5586
|
}
|
|
5514
5587
|
});
|
|
@@ -5607,12 +5680,91 @@ function formatStatus(status) {
|
|
|
5607
5680
|
}
|
|
5608
5681
|
return lines.join("\n");
|
|
5609
5682
|
}
|
|
5683
|
+
function formatProgressTitle(progress) {
|
|
5684
|
+
switch (progress.phase) {
|
|
5685
|
+
case "scanning":
|
|
5686
|
+
return "Scanning files...";
|
|
5687
|
+
case "parsing":
|
|
5688
|
+
return `Parsing: ${progress.filesProcessed}/${progress.totalFiles} files`;
|
|
5689
|
+
case "embedding":
|
|
5690
|
+
return `Embedding: ${progress.chunksProcessed}/${progress.totalChunks} chunks`;
|
|
5691
|
+
case "storing":
|
|
5692
|
+
return "Storing index...";
|
|
5693
|
+
case "complete":
|
|
5694
|
+
return "Indexing complete";
|
|
5695
|
+
default:
|
|
5696
|
+
return "Indexing...";
|
|
5697
|
+
}
|
|
5698
|
+
}
|
|
5699
|
+
function calculatePercentage(progress) {
|
|
5700
|
+
if (progress.phase === "scanning") return 0;
|
|
5701
|
+
if (progress.phase === "complete") return 100;
|
|
5702
|
+
if (progress.phase === "parsing") {
|
|
5703
|
+
if (progress.totalFiles === 0) return 5;
|
|
5704
|
+
return Math.round(5 + progress.filesProcessed / progress.totalFiles * 15);
|
|
5705
|
+
}
|
|
5706
|
+
if (progress.phase === "embedding") {
|
|
5707
|
+
if (progress.totalChunks === 0) return 20;
|
|
5708
|
+
return Math.round(20 + progress.chunksProcessed / progress.totalChunks * 70);
|
|
5709
|
+
}
|
|
5710
|
+
if (progress.phase === "storing") return 95;
|
|
5711
|
+
return 0;
|
|
5712
|
+
}
|
|
5713
|
+
|
|
5714
|
+
// src/commands/loader.ts
|
|
5715
|
+
var import_fs5 = require("fs");
|
|
5716
|
+
var path7 = __toESM(require("path"), 1);
|
|
5717
|
+
function parseFrontmatter(content) {
|
|
5718
|
+
const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
|
|
5719
|
+
const match = content.match(frontmatterRegex);
|
|
5720
|
+
if (!match) {
|
|
5721
|
+
return { frontmatter: {}, body: content.trim() };
|
|
5722
|
+
}
|
|
5723
|
+
const frontmatterLines = match[1].split("\n");
|
|
5724
|
+
const frontmatter = {};
|
|
5725
|
+
for (const line of frontmatterLines) {
|
|
5726
|
+
const colonIndex = line.indexOf(":");
|
|
5727
|
+
if (colonIndex > 0) {
|
|
5728
|
+
const key = line.slice(0, colonIndex).trim();
|
|
5729
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
5730
|
+
frontmatter[key] = value;
|
|
5731
|
+
}
|
|
5732
|
+
}
|
|
5733
|
+
return { frontmatter, body: match[2].trim() };
|
|
5734
|
+
}
|
|
5735
|
+
function loadCommandsFromDirectory(commandsDir) {
|
|
5736
|
+
const commands = /* @__PURE__ */ new Map();
|
|
5737
|
+
if (!(0, import_fs5.existsSync)(commandsDir)) {
|
|
5738
|
+
return commands;
|
|
5739
|
+
}
|
|
5740
|
+
const files = (0, import_fs5.readdirSync)(commandsDir).filter((f) => f.endsWith(".md"));
|
|
5741
|
+
for (const file of files) {
|
|
5742
|
+
const filePath = path7.join(commandsDir, file);
|
|
5743
|
+
const content = (0, import_fs5.readFileSync)(filePath, "utf-8");
|
|
5744
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
5745
|
+
const name = path7.basename(file, ".md");
|
|
5746
|
+
const description = frontmatter.description || `Run the ${name} command`;
|
|
5747
|
+
commands.set(name, {
|
|
5748
|
+
description,
|
|
5749
|
+
template: body
|
|
5750
|
+
});
|
|
5751
|
+
}
|
|
5752
|
+
return commands;
|
|
5753
|
+
}
|
|
5610
5754
|
|
|
5611
5755
|
// src/index.ts
|
|
5756
|
+
var import_meta2 = {};
|
|
5757
|
+
function getCommandsDir() {
|
|
5758
|
+
let currentDir = process.cwd();
|
|
5759
|
+
if (typeof import_meta2 !== "undefined" && import_meta2.url) {
|
|
5760
|
+
currentDir = path8.dirname((0, import_url2.fileURLToPath)(import_meta2.url));
|
|
5761
|
+
}
|
|
5762
|
+
return path8.join(currentDir, "..", "commands");
|
|
5763
|
+
}
|
|
5612
5764
|
function loadJsonFile(filePath) {
|
|
5613
5765
|
try {
|
|
5614
|
-
if ((0,
|
|
5615
|
-
const content = (0,
|
|
5766
|
+
if ((0, import_fs6.existsSync)(filePath)) {
|
|
5767
|
+
const content = (0, import_fs6.readFileSync)(filePath, "utf-8");
|
|
5616
5768
|
return JSON.parse(content);
|
|
5617
5769
|
}
|
|
5618
5770
|
} catch {
|
|
@@ -5620,11 +5772,11 @@ function loadJsonFile(filePath) {
|
|
|
5620
5772
|
return null;
|
|
5621
5773
|
}
|
|
5622
5774
|
function loadPluginConfig(projectRoot) {
|
|
5623
|
-
const projectConfig = loadJsonFile(
|
|
5775
|
+
const projectConfig = loadJsonFile(path8.join(projectRoot, ".opencode", "codebase-index.json"));
|
|
5624
5776
|
if (projectConfig) {
|
|
5625
5777
|
return projectConfig;
|
|
5626
5778
|
}
|
|
5627
|
-
const globalConfigPath =
|
|
5779
|
+
const globalConfigPath = path8.join(os3.homedir(), ".config", "opencode", "codebase-index.json");
|
|
5628
5780
|
const globalConfig = loadJsonFile(globalConfigPath);
|
|
5629
5781
|
if (globalConfig) {
|
|
5630
5782
|
return globalConfig;
|
|
@@ -5656,36 +5808,11 @@ var plugin = async ({ directory }) => {
|
|
|
5656
5808
|
},
|
|
5657
5809
|
async config(cfg) {
|
|
5658
5810
|
cfg.command = cfg.command ?? {};
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
Return the most relevant results with file paths and line numbers.`
|
|
5666
|
-
};
|
|
5667
|
-
cfg.command["find"] = {
|
|
5668
|
-
description: "Find code using hybrid approach (semantic + grep)",
|
|
5669
|
-
template: `Find code related to: $ARGUMENTS
|
|
5670
|
-
|
|
5671
|
-
Strategy:
|
|
5672
|
-
1. First use \`codebase_search\` to find semantically related code
|
|
5673
|
-
2. From the results, identify specific function/class names
|
|
5674
|
-
3. Use grep to find all occurrences of those identifiers
|
|
5675
|
-
4. Combine findings into a comprehensive answer
|
|
5676
|
-
|
|
5677
|
-
If the semantic index doesn't exist, run \`index_codebase\` first.`
|
|
5678
|
-
};
|
|
5679
|
-
cfg.command["index"] = {
|
|
5680
|
-
description: "Index the codebase for semantic search",
|
|
5681
|
-
template: `Run the \`index_codebase\` tool to create or update the semantic search index.
|
|
5682
|
-
|
|
5683
|
-
Show progress and final statistics including:
|
|
5684
|
-
- Number of files processed
|
|
5685
|
-
- Number of chunks indexed
|
|
5686
|
-
- Tokens used
|
|
5687
|
-
- Duration`
|
|
5688
|
-
};
|
|
5811
|
+
const commandsDir = getCommandsDir();
|
|
5812
|
+
const commands = loadCommandsFromDirectory(commandsDir);
|
|
5813
|
+
for (const [name, definition] of commands) {
|
|
5814
|
+
cfg.command[name] = definition;
|
|
5815
|
+
}
|
|
5689
5816
|
}
|
|
5690
5817
|
};
|
|
5691
5818
|
};
|