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.js
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.
|
|
@@ -652,9 +652,10 @@ var require_ignore = __commonJS({
|
|
|
652
652
|
});
|
|
653
653
|
|
|
654
654
|
// src/index.ts
|
|
655
|
-
import { existsSync as
|
|
656
|
-
import * as
|
|
655
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
|
|
656
|
+
import * as path8 from "path";
|
|
657
657
|
import * as os3 from "os";
|
|
658
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
658
659
|
|
|
659
660
|
// src/config/schema.ts
|
|
660
661
|
var DEFAULT_INCLUDE = [
|
|
@@ -692,7 +693,10 @@ function getDefaultIndexingConfig() {
|
|
|
692
693
|
maxChunksPerFile: 100,
|
|
693
694
|
semanticOnly: false,
|
|
694
695
|
retries: 3,
|
|
695
|
-
retryDelayMs: 1e3
|
|
696
|
+
retryDelayMs: 1e3,
|
|
697
|
+
autoGc: true,
|
|
698
|
+
gcIntervalDays: 7,
|
|
699
|
+
gcOrphanThreshold: 100
|
|
696
700
|
};
|
|
697
701
|
}
|
|
698
702
|
function getDefaultSearchConfig() {
|
|
@@ -727,7 +731,10 @@ function parseConfig(raw) {
|
|
|
727
731
|
maxChunksPerFile: typeof rawIndexing.maxChunksPerFile === "number" ? Math.max(1, rawIndexing.maxChunksPerFile) : defaultIndexing.maxChunksPerFile,
|
|
728
732
|
semanticOnly: typeof rawIndexing.semanticOnly === "boolean" ? rawIndexing.semanticOnly : defaultIndexing.semanticOnly,
|
|
729
733
|
retries: typeof rawIndexing.retries === "number" ? rawIndexing.retries : defaultIndexing.retries,
|
|
730
|
-
retryDelayMs: typeof rawIndexing.retryDelayMs === "number" ? rawIndexing.retryDelayMs : defaultIndexing.retryDelayMs
|
|
734
|
+
retryDelayMs: typeof rawIndexing.retryDelayMs === "number" ? rawIndexing.retryDelayMs : defaultIndexing.retryDelayMs,
|
|
735
|
+
autoGc: typeof rawIndexing.autoGc === "boolean" ? rawIndexing.autoGc : defaultIndexing.autoGc,
|
|
736
|
+
gcIntervalDays: typeof rawIndexing.gcIntervalDays === "number" ? Math.max(1, rawIndexing.gcIntervalDays) : defaultIndexing.gcIntervalDays,
|
|
737
|
+
gcOrphanThreshold: typeof rawIndexing.gcOrphanThreshold === "number" ? Math.max(0, rawIndexing.gcOrphanThreshold) : defaultIndexing.gcOrphanThreshold
|
|
731
738
|
};
|
|
732
739
|
const rawSearch = input.search && typeof input.search === "object" ? input.search : {};
|
|
733
740
|
const search = {
|
|
@@ -2066,34 +2073,36 @@ var GoogleEmbeddingProvider = class {
|
|
|
2066
2073
|
};
|
|
2067
2074
|
}
|
|
2068
2075
|
async embedBatch(texts) {
|
|
2069
|
-
const
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
}
|
|
2083
|
-
}
|
|
2076
|
+
const results = await Promise.all(
|
|
2077
|
+
texts.map(async (text) => {
|
|
2078
|
+
const response = await fetch(
|
|
2079
|
+
`${this.credentials.baseUrl}/models/${this.modelInfo.model}:embedContent?key=${this.credentials.apiKey}`,
|
|
2080
|
+
{
|
|
2081
|
+
method: "POST",
|
|
2082
|
+
headers: {
|
|
2083
|
+
"Content-Type": "application/json"
|
|
2084
|
+
},
|
|
2085
|
+
body: JSON.stringify({
|
|
2086
|
+
content: {
|
|
2087
|
+
parts: [{ text }]
|
|
2088
|
+
}
|
|
2089
|
+
})
|
|
2090
|
+
}
|
|
2091
|
+
);
|
|
2092
|
+
if (!response.ok) {
|
|
2093
|
+
const error = await response.text();
|
|
2094
|
+
throw new Error(`Google embedding API error: ${response.status} - ${error}`);
|
|
2084
2095
|
}
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
totalTokens += Math.ceil(text.length / 4);
|
|
2093
|
-
}
|
|
2096
|
+
const data = await response.json();
|
|
2097
|
+
return {
|
|
2098
|
+
embedding: data.embedding.values,
|
|
2099
|
+
tokensUsed: Math.ceil(text.length / 4)
|
|
2100
|
+
};
|
|
2101
|
+
})
|
|
2102
|
+
);
|
|
2094
2103
|
return {
|
|
2095
|
-
embeddings,
|
|
2096
|
-
totalTokensUsed:
|
|
2104
|
+
embeddings: results.map((r) => r.embedding),
|
|
2105
|
+
totalTokensUsed: results.reduce((sum, r) => sum + r.tokensUsed, 0)
|
|
2097
2106
|
};
|
|
2098
2107
|
}
|
|
2099
2108
|
getModelInfo() {
|
|
@@ -2127,16 +2136,10 @@ var OllamaEmbeddingProvider = class {
|
|
|
2127
2136
|
};
|
|
2128
2137
|
}
|
|
2129
2138
|
async embedBatch(texts) {
|
|
2130
|
-
const
|
|
2131
|
-
let totalTokens = 0;
|
|
2132
|
-
for (const text of texts) {
|
|
2133
|
-
const result = await this.embed(text);
|
|
2134
|
-
embeddings.push(result.embedding);
|
|
2135
|
-
totalTokens += result.tokensUsed;
|
|
2136
|
-
}
|
|
2139
|
+
const results = await Promise.all(texts.map((text) => this.embed(text)));
|
|
2137
2140
|
return {
|
|
2138
|
-
embeddings,
|
|
2139
|
-
totalTokensUsed:
|
|
2141
|
+
embeddings: results.map((r) => r.embedding),
|
|
2142
|
+
totalTokensUsed: results.reduce((sum, r) => sum + r.tokensUsed, 0)
|
|
2140
2143
|
};
|
|
2141
2144
|
}
|
|
2142
2145
|
getModelInfo() {
|
|
@@ -2677,12 +2680,20 @@ var Database = class {
|
|
|
2677
2680
|
upsertEmbedding(contentHash, embedding, chunkText, model) {
|
|
2678
2681
|
this.inner.upsertEmbedding(contentHash, embedding, chunkText, model);
|
|
2679
2682
|
}
|
|
2683
|
+
upsertEmbeddingsBatch(items) {
|
|
2684
|
+
if (items.length === 0) return;
|
|
2685
|
+
this.inner.upsertEmbeddingsBatch(items);
|
|
2686
|
+
}
|
|
2680
2687
|
getMissingEmbeddings(contentHashes) {
|
|
2681
2688
|
return this.inner.getMissingEmbeddings(contentHashes);
|
|
2682
2689
|
}
|
|
2683
2690
|
upsertChunk(chunk) {
|
|
2684
2691
|
this.inner.upsertChunk(chunk);
|
|
2685
2692
|
}
|
|
2693
|
+
upsertChunksBatch(chunks) {
|
|
2694
|
+
if (chunks.length === 0) return;
|
|
2695
|
+
this.inner.upsertChunksBatch(chunks);
|
|
2696
|
+
}
|
|
2686
2697
|
getChunk(chunkId) {
|
|
2687
2698
|
return this.inner.getChunk(chunkId) ?? null;
|
|
2688
2699
|
}
|
|
@@ -2695,6 +2706,10 @@ var Database = class {
|
|
|
2695
2706
|
addChunksToBranch(branch, chunkIds) {
|
|
2696
2707
|
this.inner.addChunksToBranch(branch, chunkIds);
|
|
2697
2708
|
}
|
|
2709
|
+
addChunksToBranchBatch(branch, chunkIds) {
|
|
2710
|
+
if (chunkIds.length === 0) return;
|
|
2711
|
+
this.inner.addChunksToBranchBatch(branch, chunkIds);
|
|
2712
|
+
}
|
|
2698
2713
|
clearBranch(branch) {
|
|
2699
2714
|
return this.inner.clearBranch(branch);
|
|
2700
2715
|
}
|
|
@@ -2955,11 +2970,45 @@ var Indexer = class {
|
|
|
2955
2970
|
this.currentBranch = "default";
|
|
2956
2971
|
this.baseBranch = "default";
|
|
2957
2972
|
}
|
|
2973
|
+
if (this.config.indexing.autoGc) {
|
|
2974
|
+
await this.maybeRunAutoGc();
|
|
2975
|
+
}
|
|
2976
|
+
}
|
|
2977
|
+
async maybeRunAutoGc() {
|
|
2978
|
+
if (!this.database) return;
|
|
2979
|
+
const lastGcTimestamp = this.database.getMetadata("lastGcTimestamp");
|
|
2980
|
+
const now = Date.now();
|
|
2981
|
+
const intervalMs = this.config.indexing.gcIntervalDays * 24 * 60 * 60 * 1e3;
|
|
2982
|
+
let shouldRunGc = false;
|
|
2983
|
+
if (!lastGcTimestamp) {
|
|
2984
|
+
shouldRunGc = true;
|
|
2985
|
+
} else {
|
|
2986
|
+
const lastGcTime = parseInt(lastGcTimestamp, 10);
|
|
2987
|
+
if (!isNaN(lastGcTime) && now - lastGcTime > intervalMs) {
|
|
2988
|
+
shouldRunGc = true;
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
if (shouldRunGc) {
|
|
2992
|
+
await this.healthCheck();
|
|
2993
|
+
this.database.setMetadata("lastGcTimestamp", now.toString());
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
async maybeRunOrphanGc() {
|
|
2997
|
+
if (!this.database) return;
|
|
2998
|
+
const stats = this.database.getStats();
|
|
2999
|
+
if (!stats) return;
|
|
3000
|
+
const orphanCount = stats.embeddingCount - stats.chunkCount;
|
|
3001
|
+
if (orphanCount > this.config.indexing.gcOrphanThreshold) {
|
|
3002
|
+
this.database.gcOrphanEmbeddings();
|
|
3003
|
+
this.database.gcOrphanChunks();
|
|
3004
|
+
this.database.setMetadata("lastGcTimestamp", Date.now().toString());
|
|
3005
|
+
}
|
|
2958
3006
|
}
|
|
2959
3007
|
migrateFromLegacyIndex() {
|
|
2960
3008
|
if (!this.store || !this.database) return;
|
|
2961
3009
|
const allMetadata = this.store.getAllMetadata();
|
|
2962
3010
|
const chunkIds = [];
|
|
3011
|
+
const chunkDataBatch = [];
|
|
2963
3012
|
for (const { key, metadata } of allMetadata) {
|
|
2964
3013
|
const chunkData = {
|
|
2965
3014
|
chunkId: key,
|
|
@@ -2971,10 +3020,13 @@ var Indexer = class {
|
|
|
2971
3020
|
name: metadata.name,
|
|
2972
3021
|
language: metadata.language
|
|
2973
3022
|
};
|
|
2974
|
-
|
|
3023
|
+
chunkDataBatch.push(chunkData);
|
|
2975
3024
|
chunkIds.push(key);
|
|
2976
3025
|
}
|
|
2977
|
-
|
|
3026
|
+
if (chunkDataBatch.length > 0) {
|
|
3027
|
+
this.database.upsertChunksBatch(chunkDataBatch);
|
|
3028
|
+
}
|
|
3029
|
+
this.database.addChunksToBranchBatch(this.currentBranch || "default", chunkIds);
|
|
2978
3030
|
}
|
|
2979
3031
|
async ensureInitialized() {
|
|
2980
3032
|
if (!this.store || !this.provider || !this.invertedIndex || !this.detectedProvider || !this.database) {
|
|
@@ -3070,6 +3122,7 @@ var Indexer = class {
|
|
|
3070
3122
|
}
|
|
3071
3123
|
}
|
|
3072
3124
|
}
|
|
3125
|
+
const chunkDataBatch = [];
|
|
3073
3126
|
for (const parsed of parsedFiles) {
|
|
3074
3127
|
currentFilePaths.add(parsed.path);
|
|
3075
3128
|
if (parsed.chunks.length === 0) {
|
|
@@ -3097,7 +3150,7 @@ var Indexer = class {
|
|
|
3097
3150
|
name: chunk.name,
|
|
3098
3151
|
language: chunk.language
|
|
3099
3152
|
};
|
|
3100
|
-
|
|
3153
|
+
chunkDataBatch.push(chunkData);
|
|
3101
3154
|
if (existingChunks.get(id) === contentHash) {
|
|
3102
3155
|
fileChunkCount++;
|
|
3103
3156
|
continue;
|
|
@@ -3116,6 +3169,9 @@ var Indexer = class {
|
|
|
3116
3169
|
fileChunkCount++;
|
|
3117
3170
|
}
|
|
3118
3171
|
}
|
|
3172
|
+
if (chunkDataBatch.length > 0) {
|
|
3173
|
+
database.upsertChunksBatch(chunkDataBatch);
|
|
3174
|
+
}
|
|
3119
3175
|
let removedCount = 0;
|
|
3120
3176
|
for (const [chunkId] of existingChunks) {
|
|
3121
3177
|
if (!currentChunkIds.has(chunkId)) {
|
|
@@ -3129,7 +3185,7 @@ var Indexer = class {
|
|
|
3129
3185
|
stats.removedChunks = removedCount;
|
|
3130
3186
|
if (pendingChunks.length === 0 && removedCount === 0) {
|
|
3131
3187
|
database.clearBranch(this.currentBranch);
|
|
3132
|
-
database.
|
|
3188
|
+
database.addChunksToBranchBatch(this.currentBranch, Array.from(currentChunkIds));
|
|
3133
3189
|
this.fileHashCache = currentFileHashes;
|
|
3134
3190
|
this.saveFileHashCache();
|
|
3135
3191
|
stats.durationMs = Date.now() - startTime;
|
|
@@ -3144,7 +3200,7 @@ var Indexer = class {
|
|
|
3144
3200
|
}
|
|
3145
3201
|
if (pendingChunks.length === 0) {
|
|
3146
3202
|
database.clearBranch(this.currentBranch);
|
|
3147
|
-
database.
|
|
3203
|
+
database.addChunksToBranchBatch(this.currentBranch, Array.from(currentChunkIds));
|
|
3148
3204
|
store.save();
|
|
3149
3205
|
invertedIndex.save();
|
|
3150
3206
|
this.fileHashCache = currentFileHashes;
|
|
@@ -3228,15 +3284,14 @@ var Indexer = class {
|
|
|
3228
3284
|
metadata: chunk.metadata
|
|
3229
3285
|
}));
|
|
3230
3286
|
store.addBatch(items);
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
);
|
|
3287
|
+
const embeddingBatchItems = batch.map((chunk, i) => ({
|
|
3288
|
+
contentHash: chunk.contentHash,
|
|
3289
|
+
embedding: float32ArrayToBuffer(result.embeddings[i]),
|
|
3290
|
+
chunkText: chunk.text,
|
|
3291
|
+
model: detectedProvider.modelInfo.model
|
|
3292
|
+
}));
|
|
3293
|
+
database.upsertEmbeddingsBatch(embeddingBatchItems);
|
|
3294
|
+
for (const chunk of batch) {
|
|
3240
3295
|
invertedIndex.removeChunk(chunk.id);
|
|
3241
3296
|
invertedIndex.addChunk(chunk.id, chunk.content);
|
|
3242
3297
|
}
|
|
@@ -3265,11 +3320,14 @@ var Indexer = class {
|
|
|
3265
3320
|
totalChunks: pendingChunks.length
|
|
3266
3321
|
});
|
|
3267
3322
|
database.clearBranch(this.currentBranch);
|
|
3268
|
-
database.
|
|
3323
|
+
database.addChunksToBranchBatch(this.currentBranch, Array.from(currentChunkIds));
|
|
3269
3324
|
store.save();
|
|
3270
3325
|
invertedIndex.save();
|
|
3271
3326
|
this.fileHashCache = currentFileHashes;
|
|
3272
3327
|
this.saveFileHashCache();
|
|
3328
|
+
if (this.config.indexing.autoGc && stats.removedChunks > 0) {
|
|
3329
|
+
await this.maybeRunOrphanGc();
|
|
3330
|
+
}
|
|
3273
3331
|
stats.durationMs = Date.now() - startTime;
|
|
3274
3332
|
if (stats.failedChunks > 0) {
|
|
3275
3333
|
stats.failedBatchesPath = this.failedBatchesPath;
|
|
@@ -3409,11 +3467,14 @@ var Indexer = class {
|
|
|
3409
3467
|
};
|
|
3410
3468
|
}
|
|
3411
3469
|
async clearIndex() {
|
|
3412
|
-
const { store, invertedIndex } = await this.ensureInitialized();
|
|
3470
|
+
const { store, invertedIndex, database } = await this.ensureInitialized();
|
|
3413
3471
|
store.clear();
|
|
3414
3472
|
store.save();
|
|
3415
3473
|
invertedIndex.clear();
|
|
3416
3474
|
invertedIndex.save();
|
|
3475
|
+
this.fileHashCache.clear();
|
|
3476
|
+
this.saveFileHashCache();
|
|
3477
|
+
database.clearBranch(this.currentBranch);
|
|
3417
3478
|
}
|
|
3418
3479
|
async healthCheck() {
|
|
3419
3480
|
const { store, invertedIndex, database } = await this.ensureInitialized();
|
|
@@ -3605,7 +3666,7 @@ var ReaddirpStream = class extends Readable {
|
|
|
3605
3666
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
3606
3667
|
const statMethod = opts.lstat ? lstat : stat;
|
|
3607
3668
|
if (wantBigintFsStats) {
|
|
3608
|
-
this._stat = (
|
|
3669
|
+
this._stat = (path9) => statMethod(path9, { bigint: true });
|
|
3609
3670
|
} else {
|
|
3610
3671
|
this._stat = statMethod;
|
|
3611
3672
|
}
|
|
@@ -3630,8 +3691,8 @@ var ReaddirpStream = class extends Readable {
|
|
|
3630
3691
|
const par = this.parent;
|
|
3631
3692
|
const fil = par && par.files;
|
|
3632
3693
|
if (fil && fil.length > 0) {
|
|
3633
|
-
const { path:
|
|
3634
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
3694
|
+
const { path: path9, depth } = par;
|
|
3695
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path9));
|
|
3635
3696
|
const awaited = await Promise.all(slice);
|
|
3636
3697
|
for (const entry of awaited) {
|
|
3637
3698
|
if (!entry)
|
|
@@ -3671,21 +3732,21 @@ var ReaddirpStream = class extends Readable {
|
|
|
3671
3732
|
this.reading = false;
|
|
3672
3733
|
}
|
|
3673
3734
|
}
|
|
3674
|
-
async _exploreDir(
|
|
3735
|
+
async _exploreDir(path9, depth) {
|
|
3675
3736
|
let files;
|
|
3676
3737
|
try {
|
|
3677
|
-
files = await readdir(
|
|
3738
|
+
files = await readdir(path9, this._rdOptions);
|
|
3678
3739
|
} catch (error) {
|
|
3679
3740
|
this._onError(error);
|
|
3680
3741
|
}
|
|
3681
|
-
return { files, depth, path:
|
|
3742
|
+
return { files, depth, path: path9 };
|
|
3682
3743
|
}
|
|
3683
|
-
async _formatEntry(dirent,
|
|
3744
|
+
async _formatEntry(dirent, path9) {
|
|
3684
3745
|
let entry;
|
|
3685
|
-
const
|
|
3746
|
+
const basename4 = this._isDirent ? dirent.name : dirent;
|
|
3686
3747
|
try {
|
|
3687
|
-
const fullPath = presolve(pjoin(
|
|
3688
|
-
entry = { path: prelative(this._root, fullPath), fullPath, basename:
|
|
3748
|
+
const fullPath = presolve(pjoin(path9, basename4));
|
|
3749
|
+
entry = { path: prelative(this._root, fullPath), fullPath, basename: basename4 };
|
|
3689
3750
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
3690
3751
|
} catch (err) {
|
|
3691
3752
|
this._onError(err);
|
|
@@ -4084,16 +4145,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
4084
4145
|
};
|
|
4085
4146
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
4086
4147
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
4087
|
-
function createFsWatchInstance(
|
|
4148
|
+
function createFsWatchInstance(path9, options, listener, errHandler, emitRaw) {
|
|
4088
4149
|
const handleEvent = (rawEvent, evPath) => {
|
|
4089
|
-
listener(
|
|
4090
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
4091
|
-
if (evPath &&
|
|
4092
|
-
fsWatchBroadcast(sp.resolve(
|
|
4150
|
+
listener(path9);
|
|
4151
|
+
emitRaw(rawEvent, evPath, { watchedPath: path9 });
|
|
4152
|
+
if (evPath && path9 !== evPath) {
|
|
4153
|
+
fsWatchBroadcast(sp.resolve(path9, evPath), KEY_LISTENERS, sp.join(path9, evPath));
|
|
4093
4154
|
}
|
|
4094
4155
|
};
|
|
4095
4156
|
try {
|
|
4096
|
-
return fs_watch(
|
|
4157
|
+
return fs_watch(path9, {
|
|
4097
4158
|
persistent: options.persistent
|
|
4098
4159
|
}, handleEvent);
|
|
4099
4160
|
} catch (error) {
|
|
@@ -4109,12 +4170,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
4109
4170
|
listener(val1, val2, val3);
|
|
4110
4171
|
});
|
|
4111
4172
|
};
|
|
4112
|
-
var setFsWatchListener = (
|
|
4173
|
+
var setFsWatchListener = (path9, fullPath, options, handlers) => {
|
|
4113
4174
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
4114
4175
|
let cont = FsWatchInstances.get(fullPath);
|
|
4115
4176
|
let watcher;
|
|
4116
4177
|
if (!options.persistent) {
|
|
4117
|
-
watcher = createFsWatchInstance(
|
|
4178
|
+
watcher = createFsWatchInstance(path9, options, listener, errHandler, rawEmitter);
|
|
4118
4179
|
if (!watcher)
|
|
4119
4180
|
return;
|
|
4120
4181
|
return watcher.close.bind(watcher);
|
|
@@ -4125,7 +4186,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
4125
4186
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
4126
4187
|
} else {
|
|
4127
4188
|
watcher = createFsWatchInstance(
|
|
4128
|
-
|
|
4189
|
+
path9,
|
|
4129
4190
|
options,
|
|
4130
4191
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
4131
4192
|
errHandler,
|
|
@@ -4140,7 +4201,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
4140
4201
|
cont.watcherUnusable = true;
|
|
4141
4202
|
if (isWindows && error.code === "EPERM") {
|
|
4142
4203
|
try {
|
|
4143
|
-
const fd = await open(
|
|
4204
|
+
const fd = await open(path9, "r");
|
|
4144
4205
|
await fd.close();
|
|
4145
4206
|
broadcastErr(error);
|
|
4146
4207
|
} catch (err) {
|
|
@@ -4171,7 +4232,7 @@ var setFsWatchListener = (path8, fullPath, options, handlers) => {
|
|
|
4171
4232
|
};
|
|
4172
4233
|
};
|
|
4173
4234
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
4174
|
-
var setFsWatchFileListener = (
|
|
4235
|
+
var setFsWatchFileListener = (path9, fullPath, options, handlers) => {
|
|
4175
4236
|
const { listener, rawEmitter } = handlers;
|
|
4176
4237
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
4177
4238
|
const copts = cont && cont.options;
|
|
@@ -4193,7 +4254,7 @@ var setFsWatchFileListener = (path8, fullPath, options, handlers) => {
|
|
|
4193
4254
|
});
|
|
4194
4255
|
const currmtime = curr.mtimeMs;
|
|
4195
4256
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
4196
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
4257
|
+
foreach(cont.listeners, (listener2) => listener2(path9, curr));
|
|
4197
4258
|
}
|
|
4198
4259
|
})
|
|
4199
4260
|
};
|
|
@@ -4223,13 +4284,13 @@ var NodeFsHandler = class {
|
|
|
4223
4284
|
* @param listener on fs change
|
|
4224
4285
|
* @returns closer for the watcher instance
|
|
4225
4286
|
*/
|
|
4226
|
-
_watchWithNodeFs(
|
|
4287
|
+
_watchWithNodeFs(path9, listener) {
|
|
4227
4288
|
const opts = this.fsw.options;
|
|
4228
|
-
const directory = sp.dirname(
|
|
4229
|
-
const
|
|
4289
|
+
const directory = sp.dirname(path9);
|
|
4290
|
+
const basename4 = sp.basename(path9);
|
|
4230
4291
|
const parent = this.fsw._getWatchedDir(directory);
|
|
4231
|
-
parent.add(
|
|
4232
|
-
const absolutePath = sp.resolve(
|
|
4292
|
+
parent.add(basename4);
|
|
4293
|
+
const absolutePath = sp.resolve(path9);
|
|
4233
4294
|
const options = {
|
|
4234
4295
|
persistent: opts.persistent
|
|
4235
4296
|
};
|
|
@@ -4238,13 +4299,13 @@ var NodeFsHandler = class {
|
|
|
4238
4299
|
let closer;
|
|
4239
4300
|
if (opts.usePolling) {
|
|
4240
4301
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
4241
|
-
options.interval = enableBin && isBinaryPath(
|
|
4242
|
-
closer = setFsWatchFileListener(
|
|
4302
|
+
options.interval = enableBin && isBinaryPath(basename4) ? opts.binaryInterval : opts.interval;
|
|
4303
|
+
closer = setFsWatchFileListener(path9, absolutePath, options, {
|
|
4243
4304
|
listener,
|
|
4244
4305
|
rawEmitter: this.fsw._emitRaw
|
|
4245
4306
|
});
|
|
4246
4307
|
} else {
|
|
4247
|
-
closer = setFsWatchListener(
|
|
4308
|
+
closer = setFsWatchListener(path9, absolutePath, options, {
|
|
4248
4309
|
listener,
|
|
4249
4310
|
errHandler: this._boundHandleError,
|
|
4250
4311
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -4260,13 +4321,13 @@ var NodeFsHandler = class {
|
|
|
4260
4321
|
if (this.fsw.closed) {
|
|
4261
4322
|
return;
|
|
4262
4323
|
}
|
|
4263
|
-
const
|
|
4264
|
-
const
|
|
4265
|
-
const parent = this.fsw._getWatchedDir(
|
|
4324
|
+
const dirname5 = sp.dirname(file);
|
|
4325
|
+
const basename4 = sp.basename(file);
|
|
4326
|
+
const parent = this.fsw._getWatchedDir(dirname5);
|
|
4266
4327
|
let prevStats = stats;
|
|
4267
|
-
if (parent.has(
|
|
4328
|
+
if (parent.has(basename4))
|
|
4268
4329
|
return;
|
|
4269
|
-
const listener = async (
|
|
4330
|
+
const listener = async (path9, newStats) => {
|
|
4270
4331
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
4271
4332
|
return;
|
|
4272
4333
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -4280,18 +4341,18 @@ var NodeFsHandler = class {
|
|
|
4280
4341
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
4281
4342
|
}
|
|
4282
4343
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
4283
|
-
this.fsw._closeFile(
|
|
4344
|
+
this.fsw._closeFile(path9);
|
|
4284
4345
|
prevStats = newStats2;
|
|
4285
4346
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
4286
4347
|
if (closer2)
|
|
4287
|
-
this.fsw._addPathCloser(
|
|
4348
|
+
this.fsw._addPathCloser(path9, closer2);
|
|
4288
4349
|
} else {
|
|
4289
4350
|
prevStats = newStats2;
|
|
4290
4351
|
}
|
|
4291
4352
|
} catch (error) {
|
|
4292
|
-
this.fsw._remove(
|
|
4353
|
+
this.fsw._remove(dirname5, basename4);
|
|
4293
4354
|
}
|
|
4294
|
-
} else if (parent.has(
|
|
4355
|
+
} else if (parent.has(basename4)) {
|
|
4295
4356
|
const at = newStats.atimeMs;
|
|
4296
4357
|
const mt = newStats.mtimeMs;
|
|
4297
4358
|
if (!at || at <= mt || mt !== prevStats.mtimeMs) {
|
|
@@ -4316,7 +4377,7 @@ var NodeFsHandler = class {
|
|
|
4316
4377
|
* @param item basename of this item
|
|
4317
4378
|
* @returns true if no more processing is needed for this entry.
|
|
4318
4379
|
*/
|
|
4319
|
-
async _handleSymlink(entry, directory,
|
|
4380
|
+
async _handleSymlink(entry, directory, path9, item) {
|
|
4320
4381
|
if (this.fsw.closed) {
|
|
4321
4382
|
return;
|
|
4322
4383
|
}
|
|
@@ -4326,7 +4387,7 @@ var NodeFsHandler = class {
|
|
|
4326
4387
|
this.fsw._incrReadyCount();
|
|
4327
4388
|
let linkPath;
|
|
4328
4389
|
try {
|
|
4329
|
-
linkPath = await fsrealpath(
|
|
4390
|
+
linkPath = await fsrealpath(path9);
|
|
4330
4391
|
} catch (e) {
|
|
4331
4392
|
this.fsw._emitReady();
|
|
4332
4393
|
return true;
|
|
@@ -4336,12 +4397,12 @@ var NodeFsHandler = class {
|
|
|
4336
4397
|
if (dir.has(item)) {
|
|
4337
4398
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
4338
4399
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
4339
|
-
this.fsw._emit(EV.CHANGE,
|
|
4400
|
+
this.fsw._emit(EV.CHANGE, path9, entry.stats);
|
|
4340
4401
|
}
|
|
4341
4402
|
} else {
|
|
4342
4403
|
dir.add(item);
|
|
4343
4404
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
4344
|
-
this.fsw._emit(EV.ADD,
|
|
4405
|
+
this.fsw._emit(EV.ADD, path9, entry.stats);
|
|
4345
4406
|
}
|
|
4346
4407
|
this.fsw._emitReady();
|
|
4347
4408
|
return true;
|
|
@@ -4371,9 +4432,9 @@ var NodeFsHandler = class {
|
|
|
4371
4432
|
return;
|
|
4372
4433
|
}
|
|
4373
4434
|
const item = entry.path;
|
|
4374
|
-
let
|
|
4435
|
+
let path9 = sp.join(directory, item);
|
|
4375
4436
|
current.add(item);
|
|
4376
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
4437
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path9, item)) {
|
|
4377
4438
|
return;
|
|
4378
4439
|
}
|
|
4379
4440
|
if (this.fsw.closed) {
|
|
@@ -4382,8 +4443,8 @@ var NodeFsHandler = class {
|
|
|
4382
4443
|
}
|
|
4383
4444
|
if (item === target || !target && !previous.has(item)) {
|
|
4384
4445
|
this.fsw._incrReadyCount();
|
|
4385
|
-
|
|
4386
|
-
this._addToNodeFs(
|
|
4446
|
+
path9 = sp.join(dir, sp.relative(dir, path9));
|
|
4447
|
+
this._addToNodeFs(path9, initialAdd, wh, depth + 1);
|
|
4387
4448
|
}
|
|
4388
4449
|
}).on(EV.ERROR, this._boundHandleError);
|
|
4389
4450
|
return new Promise((resolve4, reject) => {
|
|
@@ -4452,13 +4513,13 @@ var NodeFsHandler = class {
|
|
|
4452
4513
|
* @param depth Child path actually targeted for watch
|
|
4453
4514
|
* @param target Child path actually targeted for watch
|
|
4454
4515
|
*/
|
|
4455
|
-
async _addToNodeFs(
|
|
4516
|
+
async _addToNodeFs(path9, initialAdd, priorWh, depth, target) {
|
|
4456
4517
|
const ready = this.fsw._emitReady;
|
|
4457
|
-
if (this.fsw._isIgnored(
|
|
4518
|
+
if (this.fsw._isIgnored(path9) || this.fsw.closed) {
|
|
4458
4519
|
ready();
|
|
4459
4520
|
return false;
|
|
4460
4521
|
}
|
|
4461
|
-
const wh = this.fsw._getWatchHelpers(
|
|
4522
|
+
const wh = this.fsw._getWatchHelpers(path9);
|
|
4462
4523
|
if (priorWh) {
|
|
4463
4524
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
4464
4525
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -4474,8 +4535,8 @@ var NodeFsHandler = class {
|
|
|
4474
4535
|
const follow = this.fsw.options.followSymlinks;
|
|
4475
4536
|
let closer;
|
|
4476
4537
|
if (stats.isDirectory()) {
|
|
4477
|
-
const absPath = sp.resolve(
|
|
4478
|
-
const targetPath = follow ? await fsrealpath(
|
|
4538
|
+
const absPath = sp.resolve(path9);
|
|
4539
|
+
const targetPath = follow ? await fsrealpath(path9) : path9;
|
|
4479
4540
|
if (this.fsw.closed)
|
|
4480
4541
|
return;
|
|
4481
4542
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -4485,29 +4546,29 @@ var NodeFsHandler = class {
|
|
|
4485
4546
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
4486
4547
|
}
|
|
4487
4548
|
} else if (stats.isSymbolicLink()) {
|
|
4488
|
-
const targetPath = follow ? await fsrealpath(
|
|
4549
|
+
const targetPath = follow ? await fsrealpath(path9) : path9;
|
|
4489
4550
|
if (this.fsw.closed)
|
|
4490
4551
|
return;
|
|
4491
4552
|
const parent = sp.dirname(wh.watchPath);
|
|
4492
4553
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
4493
4554
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
4494
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
4555
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path9, wh, targetPath);
|
|
4495
4556
|
if (this.fsw.closed)
|
|
4496
4557
|
return;
|
|
4497
4558
|
if (targetPath !== void 0) {
|
|
4498
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
4559
|
+
this.fsw._symlinkPaths.set(sp.resolve(path9), targetPath);
|
|
4499
4560
|
}
|
|
4500
4561
|
} else {
|
|
4501
4562
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
4502
4563
|
}
|
|
4503
4564
|
ready();
|
|
4504
4565
|
if (closer)
|
|
4505
|
-
this.fsw._addPathCloser(
|
|
4566
|
+
this.fsw._addPathCloser(path9, closer);
|
|
4506
4567
|
return false;
|
|
4507
4568
|
} catch (error) {
|
|
4508
4569
|
if (this.fsw._handleError(error)) {
|
|
4509
4570
|
ready();
|
|
4510
|
-
return
|
|
4571
|
+
return path9;
|
|
4511
4572
|
}
|
|
4512
4573
|
}
|
|
4513
4574
|
}
|
|
@@ -4550,24 +4611,24 @@ function createPattern(matcher) {
|
|
|
4550
4611
|
}
|
|
4551
4612
|
return () => false;
|
|
4552
4613
|
}
|
|
4553
|
-
function normalizePath(
|
|
4554
|
-
if (typeof
|
|
4614
|
+
function normalizePath(path9) {
|
|
4615
|
+
if (typeof path9 !== "string")
|
|
4555
4616
|
throw new Error("string expected");
|
|
4556
|
-
|
|
4557
|
-
|
|
4617
|
+
path9 = sp2.normalize(path9);
|
|
4618
|
+
path9 = path9.replace(/\\/g, "/");
|
|
4558
4619
|
let prepend = false;
|
|
4559
|
-
if (
|
|
4620
|
+
if (path9.startsWith("//"))
|
|
4560
4621
|
prepend = true;
|
|
4561
|
-
|
|
4622
|
+
path9 = path9.replace(DOUBLE_SLASH_RE, "/");
|
|
4562
4623
|
if (prepend)
|
|
4563
|
-
|
|
4564
|
-
return
|
|
4624
|
+
path9 = "/" + path9;
|
|
4625
|
+
return path9;
|
|
4565
4626
|
}
|
|
4566
4627
|
function matchPatterns(patterns, testString, stats) {
|
|
4567
|
-
const
|
|
4628
|
+
const path9 = normalizePath(testString);
|
|
4568
4629
|
for (let index = 0; index < patterns.length; index++) {
|
|
4569
4630
|
const pattern = patterns[index];
|
|
4570
|
-
if (pattern(
|
|
4631
|
+
if (pattern(path9, stats)) {
|
|
4571
4632
|
return true;
|
|
4572
4633
|
}
|
|
4573
4634
|
}
|
|
@@ -4605,19 +4666,19 @@ var toUnix = (string) => {
|
|
|
4605
4666
|
}
|
|
4606
4667
|
return str;
|
|
4607
4668
|
};
|
|
4608
|
-
var normalizePathToUnix = (
|
|
4609
|
-
var normalizeIgnored = (cwd = "") => (
|
|
4610
|
-
if (typeof
|
|
4611
|
-
return normalizePathToUnix(sp2.isAbsolute(
|
|
4669
|
+
var normalizePathToUnix = (path9) => toUnix(sp2.normalize(toUnix(path9)));
|
|
4670
|
+
var normalizeIgnored = (cwd = "") => (path9) => {
|
|
4671
|
+
if (typeof path9 === "string") {
|
|
4672
|
+
return normalizePathToUnix(sp2.isAbsolute(path9) ? path9 : sp2.join(cwd, path9));
|
|
4612
4673
|
} else {
|
|
4613
|
-
return
|
|
4674
|
+
return path9;
|
|
4614
4675
|
}
|
|
4615
4676
|
};
|
|
4616
|
-
var getAbsolutePath = (
|
|
4617
|
-
if (sp2.isAbsolute(
|
|
4618
|
-
return
|
|
4677
|
+
var getAbsolutePath = (path9, cwd) => {
|
|
4678
|
+
if (sp2.isAbsolute(path9)) {
|
|
4679
|
+
return path9;
|
|
4619
4680
|
}
|
|
4620
|
-
return sp2.join(cwd,
|
|
4681
|
+
return sp2.join(cwd, path9);
|
|
4621
4682
|
};
|
|
4622
4683
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
4623
4684
|
var DirEntry = class {
|
|
@@ -4682,10 +4743,10 @@ var WatchHelper = class {
|
|
|
4682
4743
|
dirParts;
|
|
4683
4744
|
followSymlinks;
|
|
4684
4745
|
statMethod;
|
|
4685
|
-
constructor(
|
|
4746
|
+
constructor(path9, follow, fsw) {
|
|
4686
4747
|
this.fsw = fsw;
|
|
4687
|
-
const watchPath =
|
|
4688
|
-
this.path =
|
|
4748
|
+
const watchPath = path9;
|
|
4749
|
+
this.path = path9 = path9.replace(REPLACER_RE, "");
|
|
4689
4750
|
this.watchPath = watchPath;
|
|
4690
4751
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
4691
4752
|
this.dirParts = [];
|
|
@@ -4825,20 +4886,20 @@ var FSWatcher = class extends EventEmitter2 {
|
|
|
4825
4886
|
this._closePromise = void 0;
|
|
4826
4887
|
let paths = unifyPaths(paths_);
|
|
4827
4888
|
if (cwd) {
|
|
4828
|
-
paths = paths.map((
|
|
4829
|
-
const absPath = getAbsolutePath(
|
|
4889
|
+
paths = paths.map((path9) => {
|
|
4890
|
+
const absPath = getAbsolutePath(path9, cwd);
|
|
4830
4891
|
return absPath;
|
|
4831
4892
|
});
|
|
4832
4893
|
}
|
|
4833
|
-
paths.forEach((
|
|
4834
|
-
this._removeIgnoredPath(
|
|
4894
|
+
paths.forEach((path9) => {
|
|
4895
|
+
this._removeIgnoredPath(path9);
|
|
4835
4896
|
});
|
|
4836
4897
|
this._userIgnored = void 0;
|
|
4837
4898
|
if (!this._readyCount)
|
|
4838
4899
|
this._readyCount = 0;
|
|
4839
4900
|
this._readyCount += paths.length;
|
|
4840
|
-
Promise.all(paths.map(async (
|
|
4841
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
4901
|
+
Promise.all(paths.map(async (path9) => {
|
|
4902
|
+
const res = await this._nodeFsHandler._addToNodeFs(path9, !_internal, void 0, 0, _origAdd);
|
|
4842
4903
|
if (res)
|
|
4843
4904
|
this._emitReady();
|
|
4844
4905
|
return res;
|
|
@@ -4860,17 +4921,17 @@ var FSWatcher = class extends EventEmitter2 {
|
|
|
4860
4921
|
return this;
|
|
4861
4922
|
const paths = unifyPaths(paths_);
|
|
4862
4923
|
const { cwd } = this.options;
|
|
4863
|
-
paths.forEach((
|
|
4864
|
-
if (!sp2.isAbsolute(
|
|
4924
|
+
paths.forEach((path9) => {
|
|
4925
|
+
if (!sp2.isAbsolute(path9) && !this._closers.has(path9)) {
|
|
4865
4926
|
if (cwd)
|
|
4866
|
-
|
|
4867
|
-
|
|
4927
|
+
path9 = sp2.join(cwd, path9);
|
|
4928
|
+
path9 = sp2.resolve(path9);
|
|
4868
4929
|
}
|
|
4869
|
-
this._closePath(
|
|
4870
|
-
this._addIgnoredPath(
|
|
4871
|
-
if (this._watched.has(
|
|
4930
|
+
this._closePath(path9);
|
|
4931
|
+
this._addIgnoredPath(path9);
|
|
4932
|
+
if (this._watched.has(path9)) {
|
|
4872
4933
|
this._addIgnoredPath({
|
|
4873
|
-
path:
|
|
4934
|
+
path: path9,
|
|
4874
4935
|
recursive: true
|
|
4875
4936
|
});
|
|
4876
4937
|
}
|
|
@@ -4934,38 +4995,38 @@ var FSWatcher = class extends EventEmitter2 {
|
|
|
4934
4995
|
* @param stats arguments to be passed with event
|
|
4935
4996
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
4936
4997
|
*/
|
|
4937
|
-
async _emit(event,
|
|
4998
|
+
async _emit(event, path9, stats) {
|
|
4938
4999
|
if (this.closed)
|
|
4939
5000
|
return;
|
|
4940
5001
|
const opts = this.options;
|
|
4941
5002
|
if (isWindows)
|
|
4942
|
-
|
|
5003
|
+
path9 = sp2.normalize(path9);
|
|
4943
5004
|
if (opts.cwd)
|
|
4944
|
-
|
|
4945
|
-
const args = [
|
|
5005
|
+
path9 = sp2.relative(opts.cwd, path9);
|
|
5006
|
+
const args = [path9];
|
|
4946
5007
|
if (stats != null)
|
|
4947
5008
|
args.push(stats);
|
|
4948
5009
|
const awf = opts.awaitWriteFinish;
|
|
4949
5010
|
let pw;
|
|
4950
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
5011
|
+
if (awf && (pw = this._pendingWrites.get(path9))) {
|
|
4951
5012
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
4952
5013
|
return this;
|
|
4953
5014
|
}
|
|
4954
5015
|
if (opts.atomic) {
|
|
4955
5016
|
if (event === EVENTS.UNLINK) {
|
|
4956
|
-
this._pendingUnlinks.set(
|
|
5017
|
+
this._pendingUnlinks.set(path9, [event, ...args]);
|
|
4957
5018
|
setTimeout(() => {
|
|
4958
|
-
this._pendingUnlinks.forEach((entry,
|
|
5019
|
+
this._pendingUnlinks.forEach((entry, path10) => {
|
|
4959
5020
|
this.emit(...entry);
|
|
4960
5021
|
this.emit(EVENTS.ALL, ...entry);
|
|
4961
|
-
this._pendingUnlinks.delete(
|
|
5022
|
+
this._pendingUnlinks.delete(path10);
|
|
4962
5023
|
});
|
|
4963
5024
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
4964
5025
|
return this;
|
|
4965
5026
|
}
|
|
4966
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
5027
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path9)) {
|
|
4967
5028
|
event = EVENTS.CHANGE;
|
|
4968
|
-
this._pendingUnlinks.delete(
|
|
5029
|
+
this._pendingUnlinks.delete(path9);
|
|
4969
5030
|
}
|
|
4970
5031
|
}
|
|
4971
5032
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -4983,16 +5044,16 @@ var FSWatcher = class extends EventEmitter2 {
|
|
|
4983
5044
|
this.emitWithAll(event, args);
|
|
4984
5045
|
}
|
|
4985
5046
|
};
|
|
4986
|
-
this._awaitWriteFinish(
|
|
5047
|
+
this._awaitWriteFinish(path9, awf.stabilityThreshold, event, awfEmit);
|
|
4987
5048
|
return this;
|
|
4988
5049
|
}
|
|
4989
5050
|
if (event === EVENTS.CHANGE) {
|
|
4990
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
5051
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path9, 50);
|
|
4991
5052
|
if (isThrottled)
|
|
4992
5053
|
return this;
|
|
4993
5054
|
}
|
|
4994
5055
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
4995
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
5056
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path9) : path9;
|
|
4996
5057
|
let stats2;
|
|
4997
5058
|
try {
|
|
4998
5059
|
stats2 = await stat3(fullPath);
|
|
@@ -5023,23 +5084,23 @@ var FSWatcher = class extends EventEmitter2 {
|
|
|
5023
5084
|
* @param timeout duration of time to suppress duplicate actions
|
|
5024
5085
|
* @returns tracking object or false if action should be suppressed
|
|
5025
5086
|
*/
|
|
5026
|
-
_throttle(actionType,
|
|
5087
|
+
_throttle(actionType, path9, timeout) {
|
|
5027
5088
|
if (!this._throttled.has(actionType)) {
|
|
5028
5089
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
5029
5090
|
}
|
|
5030
5091
|
const action = this._throttled.get(actionType);
|
|
5031
5092
|
if (!action)
|
|
5032
5093
|
throw new Error("invalid throttle");
|
|
5033
|
-
const actionPath = action.get(
|
|
5094
|
+
const actionPath = action.get(path9);
|
|
5034
5095
|
if (actionPath) {
|
|
5035
5096
|
actionPath.count++;
|
|
5036
5097
|
return false;
|
|
5037
5098
|
}
|
|
5038
5099
|
let timeoutObject;
|
|
5039
5100
|
const clear = () => {
|
|
5040
|
-
const item = action.get(
|
|
5101
|
+
const item = action.get(path9);
|
|
5041
5102
|
const count = item ? item.count : 0;
|
|
5042
|
-
action.delete(
|
|
5103
|
+
action.delete(path9);
|
|
5043
5104
|
clearTimeout(timeoutObject);
|
|
5044
5105
|
if (item)
|
|
5045
5106
|
clearTimeout(item.timeoutObject);
|
|
@@ -5047,7 +5108,7 @@ var FSWatcher = class extends EventEmitter2 {
|
|
|
5047
5108
|
};
|
|
5048
5109
|
timeoutObject = setTimeout(clear, timeout);
|
|
5049
5110
|
const thr = { timeoutObject, clear, count: 0 };
|
|
5050
|
-
action.set(
|
|
5111
|
+
action.set(path9, thr);
|
|
5051
5112
|
return thr;
|
|
5052
5113
|
}
|
|
5053
5114
|
_incrReadyCount() {
|
|
@@ -5061,44 +5122,44 @@ var FSWatcher = class extends EventEmitter2 {
|
|
|
5061
5122
|
* @param event
|
|
5062
5123
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
5063
5124
|
*/
|
|
5064
|
-
_awaitWriteFinish(
|
|
5125
|
+
_awaitWriteFinish(path9, threshold, event, awfEmit) {
|
|
5065
5126
|
const awf = this.options.awaitWriteFinish;
|
|
5066
5127
|
if (typeof awf !== "object")
|
|
5067
5128
|
return;
|
|
5068
5129
|
const pollInterval = awf.pollInterval;
|
|
5069
5130
|
let timeoutHandler;
|
|
5070
|
-
let fullPath =
|
|
5071
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
5072
|
-
fullPath = sp2.join(this.options.cwd,
|
|
5131
|
+
let fullPath = path9;
|
|
5132
|
+
if (this.options.cwd && !sp2.isAbsolute(path9)) {
|
|
5133
|
+
fullPath = sp2.join(this.options.cwd, path9);
|
|
5073
5134
|
}
|
|
5074
5135
|
const now = /* @__PURE__ */ new Date();
|
|
5075
5136
|
const writes = this._pendingWrites;
|
|
5076
5137
|
function awaitWriteFinishFn(prevStat) {
|
|
5077
5138
|
statcb(fullPath, (err, curStat) => {
|
|
5078
|
-
if (err || !writes.has(
|
|
5139
|
+
if (err || !writes.has(path9)) {
|
|
5079
5140
|
if (err && err.code !== "ENOENT")
|
|
5080
5141
|
awfEmit(err);
|
|
5081
5142
|
return;
|
|
5082
5143
|
}
|
|
5083
5144
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
5084
5145
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
5085
|
-
writes.get(
|
|
5146
|
+
writes.get(path9).lastChange = now2;
|
|
5086
5147
|
}
|
|
5087
|
-
const pw = writes.get(
|
|
5148
|
+
const pw = writes.get(path9);
|
|
5088
5149
|
const df = now2 - pw.lastChange;
|
|
5089
5150
|
if (df >= threshold) {
|
|
5090
|
-
writes.delete(
|
|
5151
|
+
writes.delete(path9);
|
|
5091
5152
|
awfEmit(void 0, curStat);
|
|
5092
5153
|
} else {
|
|
5093
5154
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
5094
5155
|
}
|
|
5095
5156
|
});
|
|
5096
5157
|
}
|
|
5097
|
-
if (!writes.has(
|
|
5098
|
-
writes.set(
|
|
5158
|
+
if (!writes.has(path9)) {
|
|
5159
|
+
writes.set(path9, {
|
|
5099
5160
|
lastChange: now,
|
|
5100
5161
|
cancelWait: () => {
|
|
5101
|
-
writes.delete(
|
|
5162
|
+
writes.delete(path9);
|
|
5102
5163
|
clearTimeout(timeoutHandler);
|
|
5103
5164
|
return event;
|
|
5104
5165
|
}
|
|
@@ -5109,8 +5170,8 @@ var FSWatcher = class extends EventEmitter2 {
|
|
|
5109
5170
|
/**
|
|
5110
5171
|
* Determines whether user has asked to ignore this path.
|
|
5111
5172
|
*/
|
|
5112
|
-
_isIgnored(
|
|
5113
|
-
if (this.options.atomic && DOT_RE.test(
|
|
5173
|
+
_isIgnored(path9, stats) {
|
|
5174
|
+
if (this.options.atomic && DOT_RE.test(path9))
|
|
5114
5175
|
return true;
|
|
5115
5176
|
if (!this._userIgnored) {
|
|
5116
5177
|
const { cwd } = this.options;
|
|
@@ -5120,17 +5181,17 @@ var FSWatcher = class extends EventEmitter2 {
|
|
|
5120
5181
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
5121
5182
|
this._userIgnored = anymatch(list, void 0);
|
|
5122
5183
|
}
|
|
5123
|
-
return this._userIgnored(
|
|
5184
|
+
return this._userIgnored(path9, stats);
|
|
5124
5185
|
}
|
|
5125
|
-
_isntIgnored(
|
|
5126
|
-
return !this._isIgnored(
|
|
5186
|
+
_isntIgnored(path9, stat4) {
|
|
5187
|
+
return !this._isIgnored(path9, stat4);
|
|
5127
5188
|
}
|
|
5128
5189
|
/**
|
|
5129
5190
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
5130
5191
|
* @param path file or directory pattern being watched
|
|
5131
5192
|
*/
|
|
5132
|
-
_getWatchHelpers(
|
|
5133
|
-
return new WatchHelper(
|
|
5193
|
+
_getWatchHelpers(path9) {
|
|
5194
|
+
return new WatchHelper(path9, this.options.followSymlinks, this);
|
|
5134
5195
|
}
|
|
5135
5196
|
// Directory helpers
|
|
5136
5197
|
// -----------------
|
|
@@ -5162,63 +5223,63 @@ var FSWatcher = class extends EventEmitter2 {
|
|
|
5162
5223
|
* @param item base path of item/directory
|
|
5163
5224
|
*/
|
|
5164
5225
|
_remove(directory, item, isDirectory) {
|
|
5165
|
-
const
|
|
5166
|
-
const fullPath = sp2.resolve(
|
|
5167
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
5168
|
-
if (!this._throttle("remove",
|
|
5226
|
+
const path9 = sp2.join(directory, item);
|
|
5227
|
+
const fullPath = sp2.resolve(path9);
|
|
5228
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path9) || this._watched.has(fullPath);
|
|
5229
|
+
if (!this._throttle("remove", path9, 100))
|
|
5169
5230
|
return;
|
|
5170
5231
|
if (!isDirectory && this._watched.size === 1) {
|
|
5171
5232
|
this.add(directory, item, true);
|
|
5172
5233
|
}
|
|
5173
|
-
const wp = this._getWatchedDir(
|
|
5234
|
+
const wp = this._getWatchedDir(path9);
|
|
5174
5235
|
const nestedDirectoryChildren = wp.getChildren();
|
|
5175
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
5236
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path9, nested));
|
|
5176
5237
|
const parent = this._getWatchedDir(directory);
|
|
5177
5238
|
const wasTracked = parent.has(item);
|
|
5178
5239
|
parent.remove(item);
|
|
5179
5240
|
if (this._symlinkPaths.has(fullPath)) {
|
|
5180
5241
|
this._symlinkPaths.delete(fullPath);
|
|
5181
5242
|
}
|
|
5182
|
-
let relPath =
|
|
5243
|
+
let relPath = path9;
|
|
5183
5244
|
if (this.options.cwd)
|
|
5184
|
-
relPath = sp2.relative(this.options.cwd,
|
|
5245
|
+
relPath = sp2.relative(this.options.cwd, path9);
|
|
5185
5246
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
5186
5247
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
5187
5248
|
if (event === EVENTS.ADD)
|
|
5188
5249
|
return;
|
|
5189
5250
|
}
|
|
5190
|
-
this._watched.delete(
|
|
5251
|
+
this._watched.delete(path9);
|
|
5191
5252
|
this._watched.delete(fullPath);
|
|
5192
5253
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
5193
|
-
if (wasTracked && !this._isIgnored(
|
|
5194
|
-
this._emit(eventName,
|
|
5195
|
-
this._closePath(
|
|
5254
|
+
if (wasTracked && !this._isIgnored(path9))
|
|
5255
|
+
this._emit(eventName, path9);
|
|
5256
|
+
this._closePath(path9);
|
|
5196
5257
|
}
|
|
5197
5258
|
/**
|
|
5198
5259
|
* Closes all watchers for a path
|
|
5199
5260
|
*/
|
|
5200
|
-
_closePath(
|
|
5201
|
-
this._closeFile(
|
|
5202
|
-
const dir = sp2.dirname(
|
|
5203
|
-
this._getWatchedDir(dir).remove(sp2.basename(
|
|
5261
|
+
_closePath(path9) {
|
|
5262
|
+
this._closeFile(path9);
|
|
5263
|
+
const dir = sp2.dirname(path9);
|
|
5264
|
+
this._getWatchedDir(dir).remove(sp2.basename(path9));
|
|
5204
5265
|
}
|
|
5205
5266
|
/**
|
|
5206
5267
|
* Closes only file-specific watchers
|
|
5207
5268
|
*/
|
|
5208
|
-
_closeFile(
|
|
5209
|
-
const closers = this._closers.get(
|
|
5269
|
+
_closeFile(path9) {
|
|
5270
|
+
const closers = this._closers.get(path9);
|
|
5210
5271
|
if (!closers)
|
|
5211
5272
|
return;
|
|
5212
5273
|
closers.forEach((closer) => closer());
|
|
5213
|
-
this._closers.delete(
|
|
5274
|
+
this._closers.delete(path9);
|
|
5214
5275
|
}
|
|
5215
|
-
_addPathCloser(
|
|
5276
|
+
_addPathCloser(path9, closer) {
|
|
5216
5277
|
if (!closer)
|
|
5217
5278
|
return;
|
|
5218
|
-
let list = this._closers.get(
|
|
5279
|
+
let list = this._closers.get(path9);
|
|
5219
5280
|
if (!list) {
|
|
5220
5281
|
list = [];
|
|
5221
|
-
this._closers.set(
|
|
5282
|
+
this._closers.set(path9, list);
|
|
5222
5283
|
}
|
|
5223
5284
|
list.push(closer);
|
|
5224
5285
|
}
|
|
@@ -5313,7 +5374,7 @@ var FileWatcher = class {
|
|
|
5313
5374
|
return;
|
|
5314
5375
|
}
|
|
5315
5376
|
const changes = Array.from(this.pendingChanges.entries()).map(
|
|
5316
|
-
([
|
|
5377
|
+
([path9, type]) => ({ path: path9, type })
|
|
5317
5378
|
);
|
|
5318
5379
|
this.pendingChanges.clear();
|
|
5319
5380
|
try {
|
|
@@ -5493,7 +5554,7 @@ var index_codebase = tool({
|
|
|
5493
5554
|
estimateOnly: z.boolean().optional().default(false).describe("Only show cost estimate without indexing"),
|
|
5494
5555
|
verbose: z.boolean().optional().default(false).describe("Show detailed info about skipped files and parsing failures")
|
|
5495
5556
|
},
|
|
5496
|
-
async execute(args) {
|
|
5557
|
+
async execute(args, context) {
|
|
5497
5558
|
const indexer = getIndexer();
|
|
5498
5559
|
if (args.estimateOnly) {
|
|
5499
5560
|
const estimate = await indexer.estimateCost();
|
|
@@ -5502,7 +5563,19 @@ var index_codebase = tool({
|
|
|
5502
5563
|
if (args.force) {
|
|
5503
5564
|
await indexer.clearIndex();
|
|
5504
5565
|
}
|
|
5505
|
-
const stats = await indexer.index()
|
|
5566
|
+
const stats = await indexer.index((progress) => {
|
|
5567
|
+
context.metadata({
|
|
5568
|
+
title: formatProgressTitle(progress),
|
|
5569
|
+
metadata: {
|
|
5570
|
+
phase: progress.phase,
|
|
5571
|
+
filesProcessed: progress.filesProcessed,
|
|
5572
|
+
totalFiles: progress.totalFiles,
|
|
5573
|
+
chunksProcessed: progress.chunksProcessed,
|
|
5574
|
+
totalChunks: progress.totalChunks,
|
|
5575
|
+
percentage: calculatePercentage(progress)
|
|
5576
|
+
}
|
|
5577
|
+
});
|
|
5578
|
+
});
|
|
5506
5579
|
return formatIndexStats(stats, args.verbose ?? false);
|
|
5507
5580
|
}
|
|
5508
5581
|
});
|
|
@@ -5601,12 +5674,90 @@ function formatStatus(status) {
|
|
|
5601
5674
|
}
|
|
5602
5675
|
return lines.join("\n");
|
|
5603
5676
|
}
|
|
5677
|
+
function formatProgressTitle(progress) {
|
|
5678
|
+
switch (progress.phase) {
|
|
5679
|
+
case "scanning":
|
|
5680
|
+
return "Scanning files...";
|
|
5681
|
+
case "parsing":
|
|
5682
|
+
return `Parsing: ${progress.filesProcessed}/${progress.totalFiles} files`;
|
|
5683
|
+
case "embedding":
|
|
5684
|
+
return `Embedding: ${progress.chunksProcessed}/${progress.totalChunks} chunks`;
|
|
5685
|
+
case "storing":
|
|
5686
|
+
return "Storing index...";
|
|
5687
|
+
case "complete":
|
|
5688
|
+
return "Indexing complete";
|
|
5689
|
+
default:
|
|
5690
|
+
return "Indexing...";
|
|
5691
|
+
}
|
|
5692
|
+
}
|
|
5693
|
+
function calculatePercentage(progress) {
|
|
5694
|
+
if (progress.phase === "scanning") return 0;
|
|
5695
|
+
if (progress.phase === "complete") return 100;
|
|
5696
|
+
if (progress.phase === "parsing") {
|
|
5697
|
+
if (progress.totalFiles === 0) return 5;
|
|
5698
|
+
return Math.round(5 + progress.filesProcessed / progress.totalFiles * 15);
|
|
5699
|
+
}
|
|
5700
|
+
if (progress.phase === "embedding") {
|
|
5701
|
+
if (progress.totalChunks === 0) return 20;
|
|
5702
|
+
return Math.round(20 + progress.chunksProcessed / progress.totalChunks * 70);
|
|
5703
|
+
}
|
|
5704
|
+
if (progress.phase === "storing") return 95;
|
|
5705
|
+
return 0;
|
|
5706
|
+
}
|
|
5707
|
+
|
|
5708
|
+
// src/commands/loader.ts
|
|
5709
|
+
import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync5 } from "fs";
|
|
5710
|
+
import * as path7 from "path";
|
|
5711
|
+
function parseFrontmatter(content) {
|
|
5712
|
+
const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
|
|
5713
|
+
const match = content.match(frontmatterRegex);
|
|
5714
|
+
if (!match) {
|
|
5715
|
+
return { frontmatter: {}, body: content.trim() };
|
|
5716
|
+
}
|
|
5717
|
+
const frontmatterLines = match[1].split("\n");
|
|
5718
|
+
const frontmatter = {};
|
|
5719
|
+
for (const line of frontmatterLines) {
|
|
5720
|
+
const colonIndex = line.indexOf(":");
|
|
5721
|
+
if (colonIndex > 0) {
|
|
5722
|
+
const key = line.slice(0, colonIndex).trim();
|
|
5723
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
5724
|
+
frontmatter[key] = value;
|
|
5725
|
+
}
|
|
5726
|
+
}
|
|
5727
|
+
return { frontmatter, body: match[2].trim() };
|
|
5728
|
+
}
|
|
5729
|
+
function loadCommandsFromDirectory(commandsDir) {
|
|
5730
|
+
const commands = /* @__PURE__ */ new Map();
|
|
5731
|
+
if (!existsSync5(commandsDir)) {
|
|
5732
|
+
return commands;
|
|
5733
|
+
}
|
|
5734
|
+
const files = readdirSync2(commandsDir).filter((f) => f.endsWith(".md"));
|
|
5735
|
+
for (const file of files) {
|
|
5736
|
+
const filePath = path7.join(commandsDir, file);
|
|
5737
|
+
const content = readFileSync5(filePath, "utf-8");
|
|
5738
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
5739
|
+
const name = path7.basename(file, ".md");
|
|
5740
|
+
const description = frontmatter.description || `Run the ${name} command`;
|
|
5741
|
+
commands.set(name, {
|
|
5742
|
+
description,
|
|
5743
|
+
template: body
|
|
5744
|
+
});
|
|
5745
|
+
}
|
|
5746
|
+
return commands;
|
|
5747
|
+
}
|
|
5604
5748
|
|
|
5605
5749
|
// src/index.ts
|
|
5750
|
+
function getCommandsDir() {
|
|
5751
|
+
let currentDir = process.cwd();
|
|
5752
|
+
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
5753
|
+
currentDir = path8.dirname(fileURLToPath2(import.meta.url));
|
|
5754
|
+
}
|
|
5755
|
+
return path8.join(currentDir, "..", "commands");
|
|
5756
|
+
}
|
|
5606
5757
|
function loadJsonFile(filePath) {
|
|
5607
5758
|
try {
|
|
5608
|
-
if (
|
|
5609
|
-
const content =
|
|
5759
|
+
if (existsSync6(filePath)) {
|
|
5760
|
+
const content = readFileSync6(filePath, "utf-8");
|
|
5610
5761
|
return JSON.parse(content);
|
|
5611
5762
|
}
|
|
5612
5763
|
} catch {
|
|
@@ -5614,11 +5765,11 @@ function loadJsonFile(filePath) {
|
|
|
5614
5765
|
return null;
|
|
5615
5766
|
}
|
|
5616
5767
|
function loadPluginConfig(projectRoot) {
|
|
5617
|
-
const projectConfig = loadJsonFile(
|
|
5768
|
+
const projectConfig = loadJsonFile(path8.join(projectRoot, ".opencode", "codebase-index.json"));
|
|
5618
5769
|
if (projectConfig) {
|
|
5619
5770
|
return projectConfig;
|
|
5620
5771
|
}
|
|
5621
|
-
const globalConfigPath =
|
|
5772
|
+
const globalConfigPath = path8.join(os3.homedir(), ".config", "opencode", "codebase-index.json");
|
|
5622
5773
|
const globalConfig = loadJsonFile(globalConfigPath);
|
|
5623
5774
|
if (globalConfig) {
|
|
5624
5775
|
return globalConfig;
|
|
@@ -5650,36 +5801,11 @@ var plugin = async ({ directory }) => {
|
|
|
5650
5801
|
},
|
|
5651
5802
|
async config(cfg) {
|
|
5652
5803
|
cfg.command = cfg.command ?? {};
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
Return the most relevant results with file paths and line numbers.`
|
|
5660
|
-
};
|
|
5661
|
-
cfg.command["find"] = {
|
|
5662
|
-
description: "Find code using hybrid approach (semantic + grep)",
|
|
5663
|
-
template: `Find code related to: $ARGUMENTS
|
|
5664
|
-
|
|
5665
|
-
Strategy:
|
|
5666
|
-
1. First use \`codebase_search\` to find semantically related code
|
|
5667
|
-
2. From the results, identify specific function/class names
|
|
5668
|
-
3. Use grep to find all occurrences of those identifiers
|
|
5669
|
-
4. Combine findings into a comprehensive answer
|
|
5670
|
-
|
|
5671
|
-
If the semantic index doesn't exist, run \`index_codebase\` first.`
|
|
5672
|
-
};
|
|
5673
|
-
cfg.command["index"] = {
|
|
5674
|
-
description: "Index the codebase for semantic search",
|
|
5675
|
-
template: `Run the \`index_codebase\` tool to create or update the semantic search index.
|
|
5676
|
-
|
|
5677
|
-
Show progress and final statistics including:
|
|
5678
|
-
- Number of files processed
|
|
5679
|
-
- Number of chunks indexed
|
|
5680
|
-
- Tokens used
|
|
5681
|
-
- Duration`
|
|
5682
|
-
};
|
|
5804
|
+
const commandsDir = getCommandsDir();
|
|
5805
|
+
const commands = loadCommandsFromDirectory(commandsDir);
|
|
5806
|
+
for (const [name, definition] of commands) {
|
|
5807
|
+
cfg.command[name] = definition;
|
|
5808
|
+
}
|
|
5683
5809
|
}
|
|
5684
5810
|
};
|
|
5685
5811
|
};
|