raggrep 0.6.1 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/cli/main.js +718 -123
- package/dist/cli/main.js.map +12 -8
- package/dist/domain/entities/index.d.ts +2 -0
- package/dist/domain/entities/literal.d.ts +101 -0
- package/dist/domain/services/index.d.ts +3 -0
- package/dist/domain/services/literalExtractor.d.ts +35 -0
- package/dist/domain/services/literalScorer.d.ts +93 -0
- package/dist/domain/services/queryLiteralParser.d.ts +20 -0
- package/dist/domain/services/queryLiteralParser.test.d.ts +7 -0
- package/dist/index.js +713 -118
- package/dist/index.js.map +12 -8
- package/dist/infrastructure/storage/index.d.ts +1 -0
- package/dist/infrastructure/storage/literalIndex.d.ts +111 -0
- package/dist/modules/language/typescript/index.d.ts +8 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -130,10 +130,14 @@ var init_config = __esm(() => {
|
|
|
130
130
|
];
|
|
131
131
|
});
|
|
132
132
|
|
|
133
|
+
// src/domain/entities/literal.ts
|
|
134
|
+
var init_literal = () => {};
|
|
135
|
+
|
|
133
136
|
// src/domain/entities/index.ts
|
|
134
137
|
var init_entities = __esm(() => {
|
|
135
138
|
init_searchResult();
|
|
136
139
|
init_config();
|
|
140
|
+
init_literal();
|
|
137
141
|
});
|
|
138
142
|
|
|
139
143
|
// src/infrastructure/config/configLoader.ts
|
|
@@ -2566,10 +2570,299 @@ function generateChunkId(filepath, startLine, endLine) {
|
|
|
2566
2570
|
}
|
|
2567
2571
|
var DEFAULT_CHUNK_SIZE = 30, DEFAULT_OVERLAP = 5;
|
|
2568
2572
|
|
|
2573
|
+
// src/domain/services/queryLiteralParser.ts
|
|
2574
|
+
function parseQueryLiterals(query) {
|
|
2575
|
+
if (!query || query.trim() === "") {
|
|
2576
|
+
return { literals: [], remainingQuery: "" };
|
|
2577
|
+
}
|
|
2578
|
+
const literals = [];
|
|
2579
|
+
let remainingQuery = query;
|
|
2580
|
+
const matchedPositions = new Set;
|
|
2581
|
+
const backtickResult = extractExplicitLiterals(remainingQuery, /`([^`]+)`/g, "explicit-backtick", matchedPositions);
|
|
2582
|
+
literals.push(...backtickResult.literals);
|
|
2583
|
+
remainingQuery = backtickResult.remainingQuery;
|
|
2584
|
+
const quoteResult = extractExplicitLiterals(remainingQuery, /"([^"]+)"/g, "explicit-quote", matchedPositions);
|
|
2585
|
+
literals.push(...quoteResult.literals);
|
|
2586
|
+
remainingQuery = quoteResult.remainingQuery;
|
|
2587
|
+
const implicitLiterals = extractImplicitLiterals(query, matchedPositions);
|
|
2588
|
+
literals.push(...implicitLiterals);
|
|
2589
|
+
return {
|
|
2590
|
+
literals,
|
|
2591
|
+
remainingQuery: remainingQuery.trim()
|
|
2592
|
+
};
|
|
2593
|
+
}
|
|
2594
|
+
function extractExplicitLiterals(query, pattern, method, matchedPositions) {
|
|
2595
|
+
const literals = [];
|
|
2596
|
+
let remainingQuery = query;
|
|
2597
|
+
pattern.lastIndex = 0;
|
|
2598
|
+
let match;
|
|
2599
|
+
const replacements = [];
|
|
2600
|
+
while ((match = pattern.exec(query)) !== null) {
|
|
2601
|
+
const value = match[1];
|
|
2602
|
+
const rawValue = match[0];
|
|
2603
|
+
if (!value || value.trim() === "") {
|
|
2604
|
+
continue;
|
|
2605
|
+
}
|
|
2606
|
+
const posKey = `${match.index}:${match.index + rawValue.length}`;
|
|
2607
|
+
matchedPositions.add(posKey);
|
|
2608
|
+
matchedPositions.add(`value:${value.toLowerCase()}`);
|
|
2609
|
+
literals.push({
|
|
2610
|
+
value,
|
|
2611
|
+
rawValue,
|
|
2612
|
+
confidence: "high",
|
|
2613
|
+
detectionMethod: method,
|
|
2614
|
+
inferredType: inferTypeFromValue(value)
|
|
2615
|
+
});
|
|
2616
|
+
replacements.push({
|
|
2617
|
+
start: match.index,
|
|
2618
|
+
end: match.index + rawValue.length,
|
|
2619
|
+
text: ""
|
|
2620
|
+
});
|
|
2621
|
+
}
|
|
2622
|
+
replacements.sort((a, b) => b.start - a.start).forEach((r) => {
|
|
2623
|
+
remainingQuery = remainingQuery.slice(0, r.start) + r.text + remainingQuery.slice(r.end);
|
|
2624
|
+
});
|
|
2625
|
+
return { literals, remainingQuery };
|
|
2626
|
+
}
|
|
2627
|
+
function extractImplicitLiterals(query, matchedPositions) {
|
|
2628
|
+
const literals = [];
|
|
2629
|
+
const seenValues = new Set;
|
|
2630
|
+
for (const patternDef of IMPLICIT_PATTERNS) {
|
|
2631
|
+
patternDef.pattern.lastIndex = 0;
|
|
2632
|
+
let match;
|
|
2633
|
+
while ((match = patternDef.pattern.exec(query)) !== null) {
|
|
2634
|
+
const value = match[1];
|
|
2635
|
+
if (patternDef.minLength && value.length < patternDef.minLength) {
|
|
2636
|
+
continue;
|
|
2637
|
+
}
|
|
2638
|
+
const posKey = `${match.index}:${match.index + value.length}`;
|
|
2639
|
+
if (matchedPositions.has(posKey)) {
|
|
2640
|
+
continue;
|
|
2641
|
+
}
|
|
2642
|
+
if (matchedPositions.has(`value:${value.toLowerCase()}`)) {
|
|
2643
|
+
continue;
|
|
2644
|
+
}
|
|
2645
|
+
const lowerValue = value.toLowerCase();
|
|
2646
|
+
if (seenValues.has(lowerValue)) {
|
|
2647
|
+
continue;
|
|
2648
|
+
}
|
|
2649
|
+
seenValues.add(lowerValue);
|
|
2650
|
+
if (isCommonWord(value)) {
|
|
2651
|
+
continue;
|
|
2652
|
+
}
|
|
2653
|
+
literals.push({
|
|
2654
|
+
value,
|
|
2655
|
+
rawValue: value,
|
|
2656
|
+
confidence: patternDef.confidence,
|
|
2657
|
+
detectionMethod: "implicit-casing",
|
|
2658
|
+
inferredType: patternDef.inferredType
|
|
2659
|
+
});
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
return literals;
|
|
2663
|
+
}
|
|
2664
|
+
function inferTypeFromValue(value) {
|
|
2665
|
+
if (/^[A-Z][a-z]+(?:[A-Z][a-z0-9]*)+$/.test(value)) {
|
|
2666
|
+
return "className";
|
|
2667
|
+
}
|
|
2668
|
+
if (/^[a-z][a-z0-9]*(?:[A-Z][a-zA-Z0-9]*)+$/.test(value)) {
|
|
2669
|
+
return "functionName";
|
|
2670
|
+
}
|
|
2671
|
+
if (/^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$/.test(value)) {
|
|
2672
|
+
return "variableName";
|
|
2673
|
+
}
|
|
2674
|
+
if (/^[a-z][a-z0-9]*(?:_[a-z0-9]+)+$/.test(value)) {
|
|
2675
|
+
return "identifier";
|
|
2676
|
+
}
|
|
2677
|
+
if (/^[a-z][a-z0-9]*(?:-[a-z0-9]+)+$/.test(value)) {
|
|
2678
|
+
return "packageName";
|
|
2679
|
+
}
|
|
2680
|
+
return;
|
|
2681
|
+
}
|
|
2682
|
+
function isCommonWord(word) {
|
|
2683
|
+
const commonWords = new Set([
|
|
2684
|
+
"find",
|
|
2685
|
+
"the",
|
|
2686
|
+
"a",
|
|
2687
|
+
"an",
|
|
2688
|
+
"is",
|
|
2689
|
+
"are",
|
|
2690
|
+
"was",
|
|
2691
|
+
"were",
|
|
2692
|
+
"what",
|
|
2693
|
+
"where",
|
|
2694
|
+
"when",
|
|
2695
|
+
"how",
|
|
2696
|
+
"why",
|
|
2697
|
+
"which",
|
|
2698
|
+
"who",
|
|
2699
|
+
"this",
|
|
2700
|
+
"that",
|
|
2701
|
+
"these",
|
|
2702
|
+
"those",
|
|
2703
|
+
"and",
|
|
2704
|
+
"or",
|
|
2705
|
+
"but",
|
|
2706
|
+
"for",
|
|
2707
|
+
"with",
|
|
2708
|
+
"from",
|
|
2709
|
+
"to",
|
|
2710
|
+
"in",
|
|
2711
|
+
"on",
|
|
2712
|
+
"at",
|
|
2713
|
+
"by",
|
|
2714
|
+
"of",
|
|
2715
|
+
"all",
|
|
2716
|
+
"any",
|
|
2717
|
+
"some",
|
|
2718
|
+
"get",
|
|
2719
|
+
"set",
|
|
2720
|
+
"new",
|
|
2721
|
+
"class",
|
|
2722
|
+
"function",
|
|
2723
|
+
"const",
|
|
2724
|
+
"let",
|
|
2725
|
+
"var",
|
|
2726
|
+
"type",
|
|
2727
|
+
"interface",
|
|
2728
|
+
"import",
|
|
2729
|
+
"export",
|
|
2730
|
+
"default",
|
|
2731
|
+
"return",
|
|
2732
|
+
"async",
|
|
2733
|
+
"await",
|
|
2734
|
+
"null",
|
|
2735
|
+
"undefined",
|
|
2736
|
+
"true",
|
|
2737
|
+
"false"
|
|
2738
|
+
]);
|
|
2739
|
+
return commonWords.has(word.toLowerCase());
|
|
2740
|
+
}
|
|
2741
|
+
var IMPLICIT_PATTERNS;
|
|
2742
|
+
var init_queryLiteralParser = __esm(() => {
|
|
2743
|
+
IMPLICIT_PATTERNS = [
|
|
2744
|
+
{
|
|
2745
|
+
pattern: /\b([A-Z][a-z]+(?:[A-Z][a-z0-9]*)+)\b/g,
|
|
2746
|
+
confidence: "medium",
|
|
2747
|
+
inferredType: "className",
|
|
2748
|
+
minLength: 3
|
|
2749
|
+
},
|
|
2750
|
+
{
|
|
2751
|
+
pattern: /\b([a-z][a-z0-9]*(?:[A-Z][a-zA-Z0-9]*)+)\b/g,
|
|
2752
|
+
confidence: "medium",
|
|
2753
|
+
inferredType: "functionName",
|
|
2754
|
+
minLength: 3
|
|
2755
|
+
},
|
|
2756
|
+
{
|
|
2757
|
+
pattern: /\b([A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+)\b/g,
|
|
2758
|
+
confidence: "medium",
|
|
2759
|
+
inferredType: "variableName",
|
|
2760
|
+
minLength: 3
|
|
2761
|
+
},
|
|
2762
|
+
{
|
|
2763
|
+
pattern: /\b([a-z][a-z0-9]*(?:_[a-z0-9]+)+)\b/g,
|
|
2764
|
+
confidence: "low",
|
|
2765
|
+
inferredType: "identifier",
|
|
2766
|
+
minLength: 3
|
|
2767
|
+
},
|
|
2768
|
+
{
|
|
2769
|
+
pattern: /(?<![/:.])\b([a-z][a-z0-9]*(?:-[a-z0-9]+)+)\b(?![/:])/g,
|
|
2770
|
+
confidence: "low",
|
|
2771
|
+
inferredType: "packageName",
|
|
2772
|
+
minLength: 3
|
|
2773
|
+
}
|
|
2774
|
+
];
|
|
2775
|
+
});
|
|
2776
|
+
|
|
2777
|
+
// src/domain/services/literalExtractor.ts
|
|
2778
|
+
function extractLiterals(chunk) {
|
|
2779
|
+
const literals = [];
|
|
2780
|
+
if (chunk.name) {
|
|
2781
|
+
const literalType = CHUNK_TYPE_TO_LITERAL_TYPE[chunk.type] || "identifier";
|
|
2782
|
+
literals.push({
|
|
2783
|
+
value: chunk.name,
|
|
2784
|
+
type: literalType,
|
|
2785
|
+
matchType: "definition"
|
|
2786
|
+
});
|
|
2787
|
+
}
|
|
2788
|
+
return literals;
|
|
2789
|
+
}
|
|
2790
|
+
var CHUNK_TYPE_TO_LITERAL_TYPE;
|
|
2791
|
+
var init_literalExtractor = __esm(() => {
|
|
2792
|
+
CHUNK_TYPE_TO_LITERAL_TYPE = {
|
|
2793
|
+
class: "className",
|
|
2794
|
+
function: "functionName",
|
|
2795
|
+
interface: "interfaceName",
|
|
2796
|
+
type: "typeName",
|
|
2797
|
+
enum: "enumName",
|
|
2798
|
+
variable: "variableName"
|
|
2799
|
+
};
|
|
2800
|
+
});
|
|
2801
|
+
|
|
2802
|
+
// src/domain/services/literalScorer.ts
|
|
2803
|
+
function calculateLiteralMultiplier(matchType, confidence) {
|
|
2804
|
+
return LITERAL_SCORING_CONSTANTS.MULTIPLIERS[matchType][confidence];
|
|
2805
|
+
}
|
|
2806
|
+
function calculateMaxMultiplier(matches) {
|
|
2807
|
+
if (!matches || matches.length === 0) {
|
|
2808
|
+
return 1;
|
|
2809
|
+
}
|
|
2810
|
+
return Math.max(...matches.map((m) => calculateLiteralMultiplier(m.indexedLiteral.matchType, m.queryLiteral.confidence)));
|
|
2811
|
+
}
|
|
2812
|
+
function calculateLiteralContribution(matches, hasSemanticOrBm25) {
|
|
2813
|
+
if (!matches || matches.length === 0) {
|
|
2814
|
+
return {
|
|
2815
|
+
multiplier: 1,
|
|
2816
|
+
literalOnly: false,
|
|
2817
|
+
matchCount: 0
|
|
2818
|
+
};
|
|
2819
|
+
}
|
|
2820
|
+
let bestMatch = null;
|
|
2821
|
+
let bestMultiplier = 0;
|
|
2822
|
+
for (const match of matches) {
|
|
2823
|
+
const mult = calculateLiteralMultiplier(match.indexedLiteral.matchType, match.queryLiteral.confidence);
|
|
2824
|
+
if (mult > bestMultiplier) {
|
|
2825
|
+
bestMultiplier = mult;
|
|
2826
|
+
bestMatch = match;
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
return {
|
|
2830
|
+
multiplier: bestMultiplier,
|
|
2831
|
+
literalOnly: !hasSemanticOrBm25,
|
|
2832
|
+
bestMatchType: bestMatch?.indexedLiteral.matchType,
|
|
2833
|
+
bestConfidence: bestMatch?.queryLiteral.confidence,
|
|
2834
|
+
matchCount: matches.length
|
|
2835
|
+
};
|
|
2836
|
+
}
|
|
2837
|
+
function applyLiteralBoost(baseScore, matches, hasSemanticOrBm25) {
|
|
2838
|
+
if (!matches || matches.length === 0) {
|
|
2839
|
+
return baseScore;
|
|
2840
|
+
}
|
|
2841
|
+
const multiplier = calculateMaxMultiplier(matches);
|
|
2842
|
+
if (!hasSemanticOrBm25) {
|
|
2843
|
+
return LITERAL_SCORING_CONSTANTS.BASE_SCORE * multiplier;
|
|
2844
|
+
}
|
|
2845
|
+
return baseScore * multiplier;
|
|
2846
|
+
}
|
|
2847
|
+
var LITERAL_SCORING_CONSTANTS;
|
|
2848
|
+
var init_literalScorer = __esm(() => {
|
|
2849
|
+
LITERAL_SCORING_CONSTANTS = {
|
|
2850
|
+
BASE_SCORE: 0.5,
|
|
2851
|
+
MULTIPLIERS: {
|
|
2852
|
+
definition: { high: 2.5, medium: 2, low: 1.5 },
|
|
2853
|
+
reference: { high: 2, medium: 1.5, low: 1.3 },
|
|
2854
|
+
import: { high: 1.5, medium: 1.3, low: 1.1 }
|
|
2855
|
+
}
|
|
2856
|
+
};
|
|
2857
|
+
});
|
|
2858
|
+
|
|
2569
2859
|
// src/domain/services/index.ts
|
|
2570
2860
|
var init_services = __esm(() => {
|
|
2571
2861
|
init_keywords();
|
|
2572
2862
|
init_queryIntent();
|
|
2863
|
+
init_queryLiteralParser();
|
|
2864
|
+
init_literalExtractor();
|
|
2865
|
+
init_literalScorer();
|
|
2573
2866
|
});
|
|
2574
2867
|
|
|
2575
2868
|
// src/modules/language/typescript/parseCode.ts
|
|
@@ -2889,10 +3182,182 @@ var init_symbolicIndex = __esm(() => {
|
|
|
2889
3182
|
init_keywords();
|
|
2890
3183
|
});
|
|
2891
3184
|
|
|
3185
|
+
// src/infrastructure/storage/literalIndex.ts
|
|
3186
|
+
var exports_literalIndex = {};
|
|
3187
|
+
__export(exports_literalIndex, {
|
|
3188
|
+
getLiteralIndexPath: () => getLiteralIndexPath,
|
|
3189
|
+
LiteralIndex: () => LiteralIndex
|
|
3190
|
+
});
|
|
3191
|
+
import * as fs4 from "fs/promises";
|
|
3192
|
+
import * as path9 from "path";
|
|
3193
|
+
|
|
3194
|
+
class LiteralIndex {
|
|
3195
|
+
indexPath;
|
|
3196
|
+
moduleId;
|
|
3197
|
+
entries = new Map;
|
|
3198
|
+
static VERSION = "1.0.0";
|
|
3199
|
+
constructor(indexDir, moduleId) {
|
|
3200
|
+
this.indexPath = path9.join(indexDir, "index", moduleId, "literals");
|
|
3201
|
+
this.moduleId = moduleId;
|
|
3202
|
+
}
|
|
3203
|
+
async initialize() {
|
|
3204
|
+
try {
|
|
3205
|
+
await this.load();
|
|
3206
|
+
} catch {
|
|
3207
|
+
this.entries = new Map;
|
|
3208
|
+
}
|
|
3209
|
+
}
|
|
3210
|
+
addLiterals(chunkId, filepath, literals) {
|
|
3211
|
+
for (const literal of literals) {
|
|
3212
|
+
const key = literal.value.toLowerCase();
|
|
3213
|
+
const existingEntries = this.entries.get(key) || [];
|
|
3214
|
+
const existingIndex = existingEntries.findIndex((e) => e.chunkId === chunkId);
|
|
3215
|
+
const newEntry = {
|
|
3216
|
+
chunkId,
|
|
3217
|
+
filepath,
|
|
3218
|
+
originalCasing: literal.value,
|
|
3219
|
+
type: literal.type,
|
|
3220
|
+
matchType: literal.matchType
|
|
3221
|
+
};
|
|
3222
|
+
if (existingIndex >= 0) {
|
|
3223
|
+
const existing = existingEntries[existingIndex];
|
|
3224
|
+
if (shouldReplaceMatchType(existing.matchType, literal.matchType)) {
|
|
3225
|
+
existingEntries[existingIndex] = newEntry;
|
|
3226
|
+
}
|
|
3227
|
+
} else {
|
|
3228
|
+
existingEntries.push(newEntry);
|
|
3229
|
+
}
|
|
3230
|
+
this.entries.set(key, existingEntries);
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
removeChunk(chunkId) {
|
|
3234
|
+
for (const [key, entries] of this.entries) {
|
|
3235
|
+
const filtered = entries.filter((e) => e.chunkId !== chunkId);
|
|
3236
|
+
if (filtered.length === 0) {
|
|
3237
|
+
this.entries.delete(key);
|
|
3238
|
+
} else if (filtered.length !== entries.length) {
|
|
3239
|
+
this.entries.set(key, filtered);
|
|
3240
|
+
}
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
removeFile(filepath) {
|
|
3244
|
+
let removed = 0;
|
|
3245
|
+
for (const [key, entries] of this.entries) {
|
|
3246
|
+
const filtered = entries.filter((e) => e.filepath !== filepath);
|
|
3247
|
+
const removedCount = entries.length - filtered.length;
|
|
3248
|
+
if (removedCount > 0) {
|
|
3249
|
+
removed += removedCount;
|
|
3250
|
+
if (filtered.length === 0) {
|
|
3251
|
+
this.entries.delete(key);
|
|
3252
|
+
} else {
|
|
3253
|
+
this.entries.set(key, filtered);
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
}
|
|
3257
|
+
return removed;
|
|
3258
|
+
}
|
|
3259
|
+
findMatches(queryLiterals) {
|
|
3260
|
+
const matches = [];
|
|
3261
|
+
for (const queryLiteral of queryLiterals) {
|
|
3262
|
+
const key = queryLiteral.value.toLowerCase();
|
|
3263
|
+
const entries = this.entries.get(key);
|
|
3264
|
+
if (!entries) {
|
|
3265
|
+
continue;
|
|
3266
|
+
}
|
|
3267
|
+
for (const entry of entries) {
|
|
3268
|
+
const exactMatch = entry.originalCasing === queryLiteral.value;
|
|
3269
|
+
matches.push({
|
|
3270
|
+
queryLiteral,
|
|
3271
|
+
indexedLiteral: {
|
|
3272
|
+
value: entry.originalCasing,
|
|
3273
|
+
type: entry.type,
|
|
3274
|
+
matchType: entry.matchType
|
|
3275
|
+
},
|
|
3276
|
+
chunkId: entry.chunkId,
|
|
3277
|
+
filepath: entry.filepath,
|
|
3278
|
+
exactMatch
|
|
3279
|
+
});
|
|
3280
|
+
}
|
|
3281
|
+
}
|
|
3282
|
+
return matches;
|
|
3283
|
+
}
|
|
3284
|
+
getChunksForLiteral(literal) {
|
|
3285
|
+
const key = literal.toLowerCase();
|
|
3286
|
+
const entries = this.entries.get(key);
|
|
3287
|
+
return entries ? entries.map((e) => e.chunkId) : [];
|
|
3288
|
+
}
|
|
3289
|
+
async save() {
|
|
3290
|
+
await fs4.mkdir(this.indexPath, { recursive: true });
|
|
3291
|
+
const data = {
|
|
3292
|
+
version: LiteralIndex.VERSION,
|
|
3293
|
+
entries: Object.fromEntries(this.entries)
|
|
3294
|
+
};
|
|
3295
|
+
const indexFile = path9.join(this.indexPath, "_index.json");
|
|
3296
|
+
await fs4.writeFile(indexFile, JSON.stringify(data, null, 2));
|
|
3297
|
+
}
|
|
3298
|
+
async load() {
|
|
3299
|
+
const indexFile = path9.join(this.indexPath, "_index.json");
|
|
3300
|
+
const content = await fs4.readFile(indexFile, "utf-8");
|
|
3301
|
+
const data = JSON.parse(content);
|
|
3302
|
+
if (data.version !== LiteralIndex.VERSION) {
|
|
3303
|
+
console.warn(`Literal index version mismatch: expected ${LiteralIndex.VERSION}, got ${data.version}`);
|
|
3304
|
+
}
|
|
3305
|
+
this.entries = new Map(Object.entries(data.entries));
|
|
3306
|
+
}
|
|
3307
|
+
async exists() {
|
|
3308
|
+
try {
|
|
3309
|
+
const indexFile = path9.join(this.indexPath, "_index.json");
|
|
3310
|
+
await fs4.access(indexFile);
|
|
3311
|
+
return true;
|
|
3312
|
+
} catch {
|
|
3313
|
+
return false;
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
clear() {
|
|
3317
|
+
this.entries.clear();
|
|
3318
|
+
}
|
|
3319
|
+
get size() {
|
|
3320
|
+
return this.entries.size;
|
|
3321
|
+
}
|
|
3322
|
+
get totalMappings() {
|
|
3323
|
+
let count = 0;
|
|
3324
|
+
for (const entries of this.entries.values()) {
|
|
3325
|
+
count += entries.length;
|
|
3326
|
+
}
|
|
3327
|
+
return count;
|
|
3328
|
+
}
|
|
3329
|
+
getAllLiterals() {
|
|
3330
|
+
return Array.from(this.entries.keys());
|
|
3331
|
+
}
|
|
3332
|
+
buildMatchMap(queryLiterals) {
|
|
3333
|
+
const matches = this.findMatches(queryLiterals);
|
|
3334
|
+
const matchMap = new Map;
|
|
3335
|
+
for (const match of matches) {
|
|
3336
|
+
const existing = matchMap.get(match.chunkId) || [];
|
|
3337
|
+
existing.push(match);
|
|
3338
|
+
matchMap.set(match.chunkId, existing);
|
|
3339
|
+
}
|
|
3340
|
+
return matchMap;
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
function shouldReplaceMatchType(existing, incoming) {
|
|
3344
|
+
const priority = {
|
|
3345
|
+
definition: 3,
|
|
3346
|
+
reference: 2,
|
|
3347
|
+
import: 1
|
|
3348
|
+
};
|
|
3349
|
+
return priority[incoming] > priority[existing];
|
|
3350
|
+
}
|
|
3351
|
+
function getLiteralIndexPath(rootDir, moduleId, indexDir = ".raggrep") {
|
|
3352
|
+
return path9.join(rootDir, indexDir, "index", moduleId, "literals");
|
|
3353
|
+
}
|
|
3354
|
+
var init_literalIndex = () => {};
|
|
3355
|
+
|
|
2892
3356
|
// src/infrastructure/storage/index.ts
|
|
2893
3357
|
var init_storage = __esm(() => {
|
|
2894
3358
|
init_fileIndexStorage();
|
|
2895
3359
|
init_symbolicIndex();
|
|
3360
|
+
init_literalIndex();
|
|
2896
3361
|
});
|
|
2897
3362
|
|
|
2898
3363
|
// src/modules/language/typescript/index.ts
|
|
@@ -2905,9 +3370,9 @@ __export(exports_typescript, {
|
|
|
2905
3370
|
DEFAULT_TOP_K: () => DEFAULT_TOP_K2,
|
|
2906
3371
|
DEFAULT_MIN_SCORE: () => DEFAULT_MIN_SCORE2
|
|
2907
3372
|
});
|
|
2908
|
-
import * as
|
|
3373
|
+
import * as path10 from "path";
|
|
2909
3374
|
function isTypeScriptFile(filepath) {
|
|
2910
|
-
const ext =
|
|
3375
|
+
const ext = path10.extname(filepath).toLowerCase();
|
|
2911
3376
|
return TYPESCRIPT_EXTENSIONS.includes(ext);
|
|
2912
3377
|
}
|
|
2913
3378
|
function calculateChunkTypeBoost(chunk) {
|
|
@@ -2942,7 +3407,9 @@ class TypeScriptModule {
|
|
|
2942
3407
|
}
|
|
2943
3408
|
embeddingConfig = null;
|
|
2944
3409
|
symbolicIndex = null;
|
|
3410
|
+
literalIndex = null;
|
|
2945
3411
|
pendingSummaries = new Map;
|
|
3412
|
+
pendingLiterals = new Map;
|
|
2946
3413
|
rootDir = "";
|
|
2947
3414
|
logger = undefined;
|
|
2948
3415
|
async initialize(config) {
|
|
@@ -2956,6 +3423,7 @@ class TypeScriptModule {
|
|
|
2956
3423
|
}
|
|
2957
3424
|
configureEmbeddings(this.embeddingConfig);
|
|
2958
3425
|
this.pendingSummaries.clear();
|
|
3426
|
+
this.pendingLiterals.clear();
|
|
2959
3427
|
}
|
|
2960
3428
|
async indexFile(filepath, content, ctx) {
|
|
2961
3429
|
if (!isTypeScriptFile(filepath)) {
|
|
@@ -3015,6 +3483,17 @@ class TypeScriptModule {
|
|
|
3015
3483
|
}
|
|
3016
3484
|
};
|
|
3017
3485
|
this.pendingSummaries.set(filepath, fileSummary);
|
|
3486
|
+
for (const chunk of chunks) {
|
|
3487
|
+
const literals = extractLiterals(chunk);
|
|
3488
|
+
if (literals.length > 0) {
|
|
3489
|
+
const existing = this.pendingLiterals.get(chunk.id);
|
|
3490
|
+
if (existing) {
|
|
3491
|
+
existing.literals.push(...literals);
|
|
3492
|
+
} else {
|
|
3493
|
+
this.pendingLiterals.set(chunk.id, { filepath, literals });
|
|
3494
|
+
}
|
|
3495
|
+
}
|
|
3496
|
+
}
|
|
3018
3497
|
return {
|
|
3019
3498
|
filepath,
|
|
3020
3499
|
lastModified: stats.lastModified,
|
|
@@ -3032,7 +3511,24 @@ class TypeScriptModule {
|
|
|
3032
3511
|
}
|
|
3033
3512
|
this.symbolicIndex.buildBM25Index();
|
|
3034
3513
|
await this.symbolicIndex.save();
|
|
3514
|
+
this.literalIndex = new LiteralIndex(indexDir, this.id);
|
|
3515
|
+
await this.literalIndex.initialize();
|
|
3516
|
+
const indexedFilepaths = new Set;
|
|
3517
|
+
for (const filepath of this.pendingSummaries.keys()) {
|
|
3518
|
+
indexedFilepaths.add(filepath);
|
|
3519
|
+
}
|
|
3520
|
+
for (const { filepath } of this.pendingLiterals.values()) {
|
|
3521
|
+
indexedFilepaths.add(filepath);
|
|
3522
|
+
}
|
|
3523
|
+
for (const filepath of indexedFilepaths) {
|
|
3524
|
+
this.literalIndex.removeFile(filepath);
|
|
3525
|
+
}
|
|
3526
|
+
for (const [chunkId, { filepath, literals }] of this.pendingLiterals) {
|
|
3527
|
+
this.literalIndex.addLiterals(chunkId, filepath, literals);
|
|
3528
|
+
}
|
|
3529
|
+
await this.literalIndex.save();
|
|
3035
3530
|
this.pendingSummaries.clear();
|
|
3531
|
+
this.pendingLiterals.clear();
|
|
3036
3532
|
}
|
|
3037
3533
|
async search(query, ctx, options = {}) {
|
|
3038
3534
|
const {
|
|
@@ -3040,8 +3536,15 @@ class TypeScriptModule {
|
|
|
3040
3536
|
minScore = DEFAULT_MIN_SCORE2,
|
|
3041
3537
|
filePatterns
|
|
3042
3538
|
} = options;
|
|
3539
|
+
const { literals: queryLiterals, remainingQuery } = parseQueryLiterals(query);
|
|
3043
3540
|
const indexDir = getRaggrepDir(ctx.rootDir, ctx.config);
|
|
3044
3541
|
const symbolicIndex = new SymbolicIndex(indexDir, this.id);
|
|
3542
|
+
const literalIndex = new LiteralIndex(indexDir, this.id);
|
|
3543
|
+
let literalMatchMap = new Map;
|
|
3544
|
+
try {
|
|
3545
|
+
await literalIndex.initialize();
|
|
3546
|
+
literalMatchMap = literalIndex.buildMatchMap(queryLiterals);
|
|
3547
|
+
} catch {}
|
|
3045
3548
|
let allFiles;
|
|
3046
3549
|
try {
|
|
3047
3550
|
await symbolicIndex.initialize();
|
|
@@ -3061,7 +3564,8 @@ class TypeScriptModule {
|
|
|
3061
3564
|
});
|
|
3062
3565
|
});
|
|
3063
3566
|
}
|
|
3064
|
-
const
|
|
3567
|
+
const semanticQuery = remainingQuery.trim() || query;
|
|
3568
|
+
const queryEmbedding = await getEmbedding(semanticQuery);
|
|
3065
3569
|
const bm25Index = new BM25Index;
|
|
3066
3570
|
const allChunksData = [];
|
|
3067
3571
|
for (const filepath of filesToSearch) {
|
|
@@ -3095,14 +3599,14 @@ class TypeScriptModule {
|
|
|
3095
3599
|
const summary = symbolicIndex.getFileSummary(filepath);
|
|
3096
3600
|
if (summary?.pathContext) {
|
|
3097
3601
|
let boost = 0;
|
|
3098
|
-
const
|
|
3099
|
-
if (
|
|
3602
|
+
const pathCtx = summary.pathContext;
|
|
3603
|
+
if (pathCtx.domain && queryTerms.some((t) => pathCtx.domain.includes(t) || t.includes(pathCtx.domain))) {
|
|
3100
3604
|
boost += 0.1;
|
|
3101
3605
|
}
|
|
3102
|
-
if (
|
|
3606
|
+
if (pathCtx.layer && queryTerms.some((t) => pathCtx.layer.includes(t) || t.includes(pathCtx.layer))) {
|
|
3103
3607
|
boost += 0.05;
|
|
3104
3608
|
}
|
|
3105
|
-
const segmentMatch =
|
|
3609
|
+
const segmentMatch = pathCtx.segments.some((seg) => queryTerms.some((t) => seg.toLowerCase().includes(t) || t.includes(seg.toLowerCase())));
|
|
3106
3610
|
if (segmentMatch) {
|
|
3107
3611
|
boost += 0.05;
|
|
3108
3612
|
}
|
|
@@ -3110,6 +3614,7 @@ class TypeScriptModule {
|
|
|
3110
3614
|
}
|
|
3111
3615
|
}
|
|
3112
3616
|
const results = [];
|
|
3617
|
+
const processedChunkIds = new Set;
|
|
3113
3618
|
for (const { filepath, chunk, embedding } of allChunksData) {
|
|
3114
3619
|
const semanticScore = cosineSimilarity(queryEmbedding, embedding);
|
|
3115
3620
|
const bm25Score = bm25Scores.get(chunk.id) || 0;
|
|
@@ -3117,13 +3622,84 @@ class TypeScriptModule {
|
|
|
3117
3622
|
const fileTypeBoost = calculateFileTypeBoost(filepath, queryTerms);
|
|
3118
3623
|
const chunkTypeBoost = calculateChunkTypeBoost(chunk);
|
|
3119
3624
|
const exportBoost = calculateExportBoost(chunk);
|
|
3120
|
-
const
|
|
3121
|
-
const
|
|
3122
|
-
|
|
3625
|
+
const additiveBoost = pathBoost + fileTypeBoost + chunkTypeBoost + exportBoost;
|
|
3626
|
+
const baseScore = SEMANTIC_WEIGHT * semanticScore + BM25_WEIGHT * bm25Score;
|
|
3627
|
+
const literalMatches = literalMatchMap.get(chunk.id) || [];
|
|
3628
|
+
const literalContribution = calculateLiteralContribution(literalMatches, true);
|
|
3629
|
+
const boostedScore = applyLiteralBoost(baseScore, literalMatches, true);
|
|
3630
|
+
const finalScore = boostedScore + additiveBoost;
|
|
3631
|
+
processedChunkIds.add(chunk.id);
|
|
3632
|
+
if (finalScore >= minScore || bm25Score > 0.3 || literalMatches.length > 0) {
|
|
3123
3633
|
results.push({
|
|
3124
3634
|
filepath,
|
|
3125
3635
|
chunk,
|
|
3126
|
-
score:
|
|
3636
|
+
score: finalScore,
|
|
3637
|
+
moduleId: this.id,
|
|
3638
|
+
context: {
|
|
3639
|
+
semanticScore,
|
|
3640
|
+
bm25Score,
|
|
3641
|
+
pathBoost,
|
|
3642
|
+
fileTypeBoost,
|
|
3643
|
+
chunkTypeBoost,
|
|
3644
|
+
exportBoost,
|
|
3645
|
+
literalMultiplier: literalContribution.multiplier,
|
|
3646
|
+
literalMatchType: literalContribution.bestMatchType,
|
|
3647
|
+
literalConfidence: literalContribution.bestConfidence,
|
|
3648
|
+
literalMatchCount: literalContribution.matchCount
|
|
3649
|
+
}
|
|
3650
|
+
});
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
const literalOnlyFiles = new Map;
|
|
3654
|
+
for (const [chunkId, matches] of literalMatchMap) {
|
|
3655
|
+
if (processedChunkIds.has(chunkId)) {
|
|
3656
|
+
continue;
|
|
3657
|
+
}
|
|
3658
|
+
const filepath = matches[0]?.filepath;
|
|
3659
|
+
if (!filepath)
|
|
3660
|
+
continue;
|
|
3661
|
+
const existing = literalOnlyFiles.get(filepath) || [];
|
|
3662
|
+
existing.push(...matches);
|
|
3663
|
+
literalOnlyFiles.set(filepath, existing);
|
|
3664
|
+
}
|
|
3665
|
+
for (const [filepath, matches] of literalOnlyFiles) {
|
|
3666
|
+
const fileIndex = await ctx.loadFileIndex(filepath);
|
|
3667
|
+
if (!fileIndex)
|
|
3668
|
+
continue;
|
|
3669
|
+
const moduleData = fileIndex.moduleData;
|
|
3670
|
+
const chunkMatches = new Map;
|
|
3671
|
+
for (const match of matches) {
|
|
3672
|
+
const existing = chunkMatches.get(match.chunkId) || [];
|
|
3673
|
+
existing.push(match);
|
|
3674
|
+
chunkMatches.set(match.chunkId, existing);
|
|
3675
|
+
}
|
|
3676
|
+
for (const [chunkId, chunkLiteralMatches] of chunkMatches) {
|
|
3677
|
+
if (processedChunkIds.has(chunkId))
|
|
3678
|
+
continue;
|
|
3679
|
+
const chunkIndex = fileIndex.chunks.findIndex((c) => c.id === chunkId);
|
|
3680
|
+
if (chunkIndex === -1)
|
|
3681
|
+
continue;
|
|
3682
|
+
const chunk = fileIndex.chunks[chunkIndex];
|
|
3683
|
+
const embedding = moduleData?.embeddings?.[chunkIndex];
|
|
3684
|
+
let semanticScore = 0;
|
|
3685
|
+
if (embedding) {
|
|
3686
|
+
semanticScore = cosineSimilarity(queryEmbedding, embedding);
|
|
3687
|
+
}
|
|
3688
|
+
const bm25Score = bm25Scores.get(chunkId) || 0;
|
|
3689
|
+
const pathBoost = pathBoosts.get(filepath) || 0;
|
|
3690
|
+
const fileTypeBoost = calculateFileTypeBoost(filepath, queryTerms);
|
|
3691
|
+
const chunkTypeBoost = calculateChunkTypeBoost(chunk);
|
|
3692
|
+
const exportBoost = calculateExportBoost(chunk);
|
|
3693
|
+
const additiveBoost = pathBoost + fileTypeBoost + chunkTypeBoost + exportBoost;
|
|
3694
|
+
const literalContribution = calculateLiteralContribution(chunkLiteralMatches, false);
|
|
3695
|
+
const baseScore = semanticScore > 0 ? SEMANTIC_WEIGHT * semanticScore + BM25_WEIGHT * bm25Score : LITERAL_SCORING_CONSTANTS.BASE_SCORE;
|
|
3696
|
+
const boostedScore = applyLiteralBoost(baseScore, chunkLiteralMatches, semanticScore > 0);
|
|
3697
|
+
const finalScore = boostedScore + additiveBoost;
|
|
3698
|
+
processedChunkIds.add(chunkId);
|
|
3699
|
+
results.push({
|
|
3700
|
+
filepath,
|
|
3701
|
+
chunk,
|
|
3702
|
+
score: finalScore,
|
|
3127
3703
|
moduleId: this.id,
|
|
3128
3704
|
context: {
|
|
3129
3705
|
semanticScore,
|
|
@@ -3131,7 +3707,12 @@ class TypeScriptModule {
|
|
|
3131
3707
|
pathBoost,
|
|
3132
3708
|
fileTypeBoost,
|
|
3133
3709
|
chunkTypeBoost,
|
|
3134
|
-
exportBoost
|
|
3710
|
+
exportBoost,
|
|
3711
|
+
literalMultiplier: literalContribution.multiplier,
|
|
3712
|
+
literalMatchType: literalContribution.bestMatchType,
|
|
3713
|
+
literalConfidence: literalContribution.bestConfidence,
|
|
3714
|
+
literalMatchCount: literalContribution.matchCount,
|
|
3715
|
+
literalOnly: true
|
|
3135
3716
|
}
|
|
3136
3717
|
});
|
|
3137
3718
|
}
|
|
@@ -3147,16 +3728,16 @@ class TypeScriptModule {
|
|
|
3147
3728
|
while ((match = importRegex.exec(content)) !== null) {
|
|
3148
3729
|
const importPath = match[1];
|
|
3149
3730
|
if (importPath.startsWith(".")) {
|
|
3150
|
-
const dir =
|
|
3151
|
-
const resolved =
|
|
3731
|
+
const dir = path10.dirname(filepath);
|
|
3732
|
+
const resolved = path10.normalize(path10.join(dir, importPath));
|
|
3152
3733
|
references.push(resolved);
|
|
3153
3734
|
}
|
|
3154
3735
|
}
|
|
3155
3736
|
while ((match = requireRegex.exec(content)) !== null) {
|
|
3156
3737
|
const importPath = match[1];
|
|
3157
3738
|
if (importPath.startsWith(".")) {
|
|
3158
|
-
const dir =
|
|
3159
|
-
const resolved =
|
|
3739
|
+
const dir = path10.dirname(filepath);
|
|
3740
|
+
const resolved = path10.normalize(path10.join(dir, importPath));
|
|
3160
3741
|
references.push(resolved);
|
|
3161
3742
|
}
|
|
3162
3743
|
}
|
|
@@ -3193,9 +3774,9 @@ __export(exports_json, {
|
|
|
3193
3774
|
DEFAULT_TOP_K: () => DEFAULT_TOP_K3,
|
|
3194
3775
|
DEFAULT_MIN_SCORE: () => DEFAULT_MIN_SCORE3
|
|
3195
3776
|
});
|
|
3196
|
-
import * as
|
|
3777
|
+
import * as path11 from "path";
|
|
3197
3778
|
function isJsonFile(filepath) {
|
|
3198
|
-
const ext =
|
|
3779
|
+
const ext = path11.extname(filepath).toLowerCase();
|
|
3199
3780
|
return JSON_EXTENSIONS.includes(ext);
|
|
3200
3781
|
}
|
|
3201
3782
|
function extractJsonKeys(obj, prefix = "") {
|
|
@@ -3276,7 +3857,7 @@ class JsonModule {
|
|
|
3276
3857
|
return null;
|
|
3277
3858
|
}
|
|
3278
3859
|
const chunkContents = textChunks.map((c) => {
|
|
3279
|
-
const filename =
|
|
3860
|
+
const filename = path11.basename(filepath);
|
|
3280
3861
|
return `${filename}: ${c.content}`;
|
|
3281
3862
|
});
|
|
3282
3863
|
const embeddings = await getEmbeddings(chunkContents);
|
|
@@ -3427,9 +4008,9 @@ __export(exports_markdown, {
|
|
|
3427
4008
|
DEFAULT_TOP_K: () => DEFAULT_TOP_K4,
|
|
3428
4009
|
DEFAULT_MIN_SCORE: () => DEFAULT_MIN_SCORE4
|
|
3429
4010
|
});
|
|
3430
|
-
import * as
|
|
4011
|
+
import * as path12 from "path";
|
|
3431
4012
|
function isMarkdownFile(filepath) {
|
|
3432
|
-
const ext =
|
|
4013
|
+
const ext = path12.extname(filepath).toLowerCase();
|
|
3433
4014
|
return MARKDOWN_EXTENSIONS.includes(ext);
|
|
3434
4015
|
}
|
|
3435
4016
|
function parseMarkdownSections(content) {
|
|
@@ -3556,7 +4137,7 @@ class MarkdownModule {
|
|
|
3556
4137
|
return null;
|
|
3557
4138
|
}
|
|
3558
4139
|
const chunkContents = sections.map((s) => {
|
|
3559
|
-
const filename =
|
|
4140
|
+
const filename = path12.basename(filepath);
|
|
3560
4141
|
const headingContext = s.heading ? `${s.heading}: ` : "";
|
|
3561
4142
|
return `${filename} ${headingContext}${s.content}`;
|
|
3562
4143
|
});
|
|
@@ -3711,8 +4292,8 @@ var init_markdown = __esm(() => {
|
|
|
3711
4292
|
// src/app/indexer/index.ts
|
|
3712
4293
|
init_config2();
|
|
3713
4294
|
import { glob } from "glob";
|
|
3714
|
-
import * as
|
|
3715
|
-
import * as
|
|
4295
|
+
import * as fs7 from "fs/promises";
|
|
4296
|
+
import * as path15 from "path";
|
|
3716
4297
|
import * as os3 from "os";
|
|
3717
4298
|
|
|
3718
4299
|
// src/modules/registry.ts
|
|
@@ -3747,12 +4328,12 @@ async function registerBuiltInModules() {
|
|
|
3747
4328
|
}
|
|
3748
4329
|
|
|
3749
4330
|
// src/infrastructure/introspection/IntrospectionIndex.ts
|
|
3750
|
-
import * as
|
|
3751
|
-
import * as
|
|
4331
|
+
import * as path14 from "path";
|
|
4332
|
+
import * as fs6 from "fs/promises";
|
|
3752
4333
|
|
|
3753
4334
|
// src/infrastructure/introspection/projectDetector.ts
|
|
3754
|
-
import * as
|
|
3755
|
-
import * as
|
|
4335
|
+
import * as path13 from "path";
|
|
4336
|
+
import * as fs5 from "fs/promises";
|
|
3756
4337
|
var MAX_SCAN_DEPTH = 4;
|
|
3757
4338
|
var SKIP_DIRS = new Set([
|
|
3758
4339
|
"node_modules",
|
|
@@ -3768,9 +4349,9 @@ async function scanForPackageJsons(rootDir, currentDir = "", depth = 0) {
|
|
|
3768
4349
|
if (depth > MAX_SCAN_DEPTH)
|
|
3769
4350
|
return [];
|
|
3770
4351
|
const results = [];
|
|
3771
|
-
const fullDir = currentDir ?
|
|
4352
|
+
const fullDir = currentDir ? path13.join(rootDir, currentDir) : rootDir;
|
|
3772
4353
|
try {
|
|
3773
|
-
const entries = await
|
|
4354
|
+
const entries = await fs5.readdir(fullDir, { withFileTypes: true });
|
|
3774
4355
|
const hasPackageJson = entries.some((e) => e.isFile() && e.name === "package.json");
|
|
3775
4356
|
if (hasPackageJson && currentDir) {
|
|
3776
4357
|
const info = await parsePackageJson(rootDir, currentDir);
|
|
@@ -3791,10 +4372,10 @@ async function scanForPackageJsons(rootDir, currentDir = "", depth = 0) {
|
|
|
3791
4372
|
}
|
|
3792
4373
|
async function parsePackageJson(rootDir, relativePath) {
|
|
3793
4374
|
try {
|
|
3794
|
-
const packageJsonPath =
|
|
3795
|
-
const content = await
|
|
4375
|
+
const packageJsonPath = path13.join(rootDir, relativePath, "package.json");
|
|
4376
|
+
const content = await fs5.readFile(packageJsonPath, "utf-8");
|
|
3796
4377
|
const pkg = JSON.parse(content);
|
|
3797
|
-
const name = pkg.name ||
|
|
4378
|
+
const name = pkg.name || path13.basename(relativePath);
|
|
3798
4379
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
3799
4380
|
let type = "unknown";
|
|
3800
4381
|
if (deps["next"] || deps["react"] || deps["vue"] || deps["svelte"]) {
|
|
@@ -3830,7 +4411,7 @@ async function detectProjectStructure(rootDir) {
|
|
|
3830
4411
|
const projectMap = new Map;
|
|
3831
4412
|
let isMonorepo = false;
|
|
3832
4413
|
try {
|
|
3833
|
-
const entries = await
|
|
4414
|
+
const entries = await fs5.readdir(rootDir, { withFileTypes: true });
|
|
3834
4415
|
const dirNames = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
3835
4416
|
const monorepoPatterns = ["apps", "packages", "libs", "services"];
|
|
3836
4417
|
const hasMonorepoStructure = monorepoPatterns.some((p) => dirNames.includes(p));
|
|
@@ -3839,9 +4420,9 @@ async function detectProjectStructure(rootDir) {
|
|
|
3839
4420
|
for (const pattern of monorepoPatterns) {
|
|
3840
4421
|
if (!dirNames.includes(pattern))
|
|
3841
4422
|
continue;
|
|
3842
|
-
const patternDir =
|
|
4423
|
+
const patternDir = path13.join(rootDir, pattern);
|
|
3843
4424
|
try {
|
|
3844
|
-
const subDirs = await
|
|
4425
|
+
const subDirs = await fs5.readdir(patternDir, { withFileTypes: true });
|
|
3845
4426
|
for (const subDir of subDirs) {
|
|
3846
4427
|
if (!subDir.isDirectory())
|
|
3847
4428
|
continue;
|
|
@@ -3870,8 +4451,8 @@ async function detectProjectStructure(rootDir) {
|
|
|
3870
4451
|
}
|
|
3871
4452
|
let rootType = "unknown";
|
|
3872
4453
|
try {
|
|
3873
|
-
const rootPkgPath =
|
|
3874
|
-
const rootPkg = JSON.parse(await
|
|
4454
|
+
const rootPkgPath = path13.join(rootDir, "package.json");
|
|
4455
|
+
const rootPkg = JSON.parse(await fs5.readFile(rootPkgPath, "utf-8"));
|
|
3875
4456
|
if (rootPkg.workspaces)
|
|
3876
4457
|
isMonorepo = true;
|
|
3877
4458
|
const deps = { ...rootPkg.dependencies, ...rootPkg.devDependencies };
|
|
@@ -3911,8 +4492,8 @@ class IntrospectionIndex {
|
|
|
3911
4492
|
async initialize() {
|
|
3912
4493
|
this.structure = await detectProjectStructure(this.rootDir);
|
|
3913
4494
|
try {
|
|
3914
|
-
const configPath =
|
|
3915
|
-
const configContent = await
|
|
4495
|
+
const configPath = path14.join(this.rootDir, ".raggrep", "config.json");
|
|
4496
|
+
const configContent = await fs6.readFile(configPath, "utf-8");
|
|
3916
4497
|
const config = JSON.parse(configContent);
|
|
3917
4498
|
this.config = config.introspection || {};
|
|
3918
4499
|
} catch {}
|
|
@@ -3951,28 +4532,28 @@ class IntrospectionIndex {
|
|
|
3951
4532
|
}
|
|
3952
4533
|
}
|
|
3953
4534
|
async save(config) {
|
|
3954
|
-
const introDir =
|
|
3955
|
-
await
|
|
3956
|
-
const projectPath =
|
|
3957
|
-
await
|
|
4535
|
+
const introDir = path14.join(getRaggrepDir(this.rootDir, config), "introspection");
|
|
4536
|
+
await fs6.mkdir(introDir, { recursive: true });
|
|
4537
|
+
const projectPath = path14.join(introDir, "_project.json");
|
|
4538
|
+
await fs6.writeFile(projectPath, JSON.stringify({
|
|
3958
4539
|
version: "1.0.0",
|
|
3959
4540
|
lastUpdated: new Date().toISOString(),
|
|
3960
4541
|
structure: this.structure
|
|
3961
4542
|
}, null, 2));
|
|
3962
4543
|
for (const [filepath, intro] of this.files) {
|
|
3963
|
-
const introFilePath =
|
|
3964
|
-
await
|
|
3965
|
-
await
|
|
4544
|
+
const introFilePath = path14.join(introDir, "files", filepath.replace(/\.[^.]+$/, ".json"));
|
|
4545
|
+
await fs6.mkdir(path14.dirname(introFilePath), { recursive: true });
|
|
4546
|
+
await fs6.writeFile(introFilePath, JSON.stringify(intro, null, 2));
|
|
3966
4547
|
}
|
|
3967
4548
|
}
|
|
3968
4549
|
async load(config) {
|
|
3969
|
-
const introDir =
|
|
4550
|
+
const introDir = path14.join(getRaggrepDir(this.rootDir, config), "introspection");
|
|
3970
4551
|
try {
|
|
3971
|
-
const projectPath =
|
|
3972
|
-
const projectContent = await
|
|
4552
|
+
const projectPath = path14.join(introDir, "_project.json");
|
|
4553
|
+
const projectContent = await fs6.readFile(projectPath, "utf-8");
|
|
3973
4554
|
const projectData = JSON.parse(projectContent);
|
|
3974
4555
|
this.structure = projectData.structure;
|
|
3975
|
-
await this.loadFilesRecursive(
|
|
4556
|
+
await this.loadFilesRecursive(path14.join(introDir, "files"), "");
|
|
3976
4557
|
} catch {
|
|
3977
4558
|
this.structure = null;
|
|
3978
4559
|
this.files.clear();
|
|
@@ -3980,14 +4561,14 @@ class IntrospectionIndex {
|
|
|
3980
4561
|
}
|
|
3981
4562
|
async loadFilesRecursive(basePath, prefix) {
|
|
3982
4563
|
try {
|
|
3983
|
-
const entries = await
|
|
4564
|
+
const entries = await fs6.readdir(basePath, { withFileTypes: true });
|
|
3984
4565
|
for (const entry of entries) {
|
|
3985
|
-
const entryPath =
|
|
4566
|
+
const entryPath = path14.join(basePath, entry.name);
|
|
3986
4567
|
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
3987
4568
|
if (entry.isDirectory()) {
|
|
3988
4569
|
await this.loadFilesRecursive(entryPath, relativePath);
|
|
3989
4570
|
} else if (entry.name.endsWith(".json")) {
|
|
3990
|
-
const content = await
|
|
4571
|
+
const content = await fs6.readFile(entryPath, "utf-8");
|
|
3991
4572
|
const intro = JSON.parse(content);
|
|
3992
4573
|
this.files.set(intro.filepath, intro);
|
|
3993
4574
|
}
|
|
@@ -4133,7 +4714,7 @@ async function indexDirectory(rootDir, options = {}) {
|
|
|
4133
4714
|
const quiet = options.quiet ?? false;
|
|
4134
4715
|
const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
|
|
4135
4716
|
const logger = options.logger ? options.logger : quiet ? createSilentLogger() : createLogger({ verbose });
|
|
4136
|
-
rootDir =
|
|
4717
|
+
rootDir = path15.resolve(rootDir);
|
|
4137
4718
|
const location = getIndexLocation(rootDir);
|
|
4138
4719
|
logger.info(`Indexing directory: ${rootDir}`);
|
|
4139
4720
|
logger.info(`Index location: ${location.indexDir}`);
|
|
@@ -4185,12 +4766,12 @@ async function indexDirectory(rootDir, options = {}) {
|
|
|
4185
4766
|
rootDir,
|
|
4186
4767
|
config,
|
|
4187
4768
|
readFile: async (filepath) => {
|
|
4188
|
-
const fullPath =
|
|
4189
|
-
return
|
|
4769
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
4770
|
+
return fs7.readFile(fullPath, "utf-8");
|
|
4190
4771
|
},
|
|
4191
4772
|
getFileStats: async (filepath) => {
|
|
4192
|
-
const fullPath =
|
|
4193
|
-
const stats = await
|
|
4773
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
4774
|
+
const stats = await fs7.stat(fullPath);
|
|
4194
4775
|
return { lastModified: stats.mtime.toISOString() };
|
|
4195
4776
|
}
|
|
4196
4777
|
};
|
|
@@ -4215,7 +4796,7 @@ async function isIndexVersionCompatible(rootDir) {
|
|
|
4215
4796
|
const config = await loadConfig(rootDir);
|
|
4216
4797
|
const globalManifestPath = getGlobalManifestPath(rootDir, config);
|
|
4217
4798
|
try {
|
|
4218
|
-
const content = await
|
|
4799
|
+
const content = await fs7.readFile(globalManifestPath, "utf-8");
|
|
4219
4800
|
const manifest = JSON.parse(content);
|
|
4220
4801
|
return manifest.version === INDEX_SCHEMA_VERSION;
|
|
4221
4802
|
} catch {
|
|
@@ -4225,11 +4806,11 @@ async function isIndexVersionCompatible(rootDir) {
|
|
|
4225
4806
|
async function deleteIndex(rootDir) {
|
|
4226
4807
|
const indexDir = getRaggrepDir(rootDir);
|
|
4227
4808
|
try {
|
|
4228
|
-
await
|
|
4809
|
+
await fs7.rm(indexDir, { recursive: true, force: true });
|
|
4229
4810
|
} catch {}
|
|
4230
4811
|
}
|
|
4231
4812
|
async function resetIndex(rootDir) {
|
|
4232
|
-
rootDir =
|
|
4813
|
+
rootDir = path15.resolve(rootDir);
|
|
4233
4814
|
const status = await getIndexStatus(rootDir);
|
|
4234
4815
|
if (!status.exists) {
|
|
4235
4816
|
throw new Error(`No index found for ${rootDir}`);
|
|
@@ -4244,7 +4825,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4244
4825
|
const verbose = options.verbose ?? false;
|
|
4245
4826
|
const quiet = options.quiet ?? false;
|
|
4246
4827
|
const logger = options.logger ? options.logger : quiet ? createSilentLogger() : createLogger({ verbose });
|
|
4247
|
-
rootDir =
|
|
4828
|
+
rootDir = path15.resolve(rootDir);
|
|
4248
4829
|
const status = await getIndexStatus(rootDir);
|
|
4249
4830
|
if (!status.exists) {
|
|
4250
4831
|
logger.info(`No index found. Creating index...
|
|
@@ -4271,7 +4852,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4271
4852
|
const introspection = new IntrospectionIndex(rootDir);
|
|
4272
4853
|
await introspection.initialize();
|
|
4273
4854
|
const currentFiles = await findFiles(rootDir, config);
|
|
4274
|
-
const currentFileSet = new Set(currentFiles.map((f) =>
|
|
4855
|
+
const currentFileSet = new Set(currentFiles.map((f) => path15.relative(rootDir, f)));
|
|
4275
4856
|
let totalIndexed = 0;
|
|
4276
4857
|
let totalRemoved = 0;
|
|
4277
4858
|
let totalUnchanged = 0;
|
|
@@ -4299,29 +4880,43 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4299
4880
|
filesToRemove.push(filepath);
|
|
4300
4881
|
}
|
|
4301
4882
|
}
|
|
4883
|
+
const removedFilepaths = [];
|
|
4302
4884
|
for (const filepath of filesToRemove) {
|
|
4303
4885
|
logger.debug(` Removing stale: ${filepath}`);
|
|
4304
|
-
const indexFilePath =
|
|
4886
|
+
const indexFilePath = path15.join(indexPath, filepath.replace(/\.[^.]+$/, ".json"));
|
|
4305
4887
|
try {
|
|
4306
|
-
await
|
|
4888
|
+
await fs7.unlink(indexFilePath);
|
|
4307
4889
|
} catch {}
|
|
4308
|
-
const symbolicFilePath =
|
|
4890
|
+
const symbolicFilePath = path15.join(indexPath, "symbolic", filepath.replace(/\.[^.]+$/, ".json"));
|
|
4309
4891
|
try {
|
|
4310
|
-
await
|
|
4892
|
+
await fs7.unlink(symbolicFilePath);
|
|
4311
4893
|
} catch {}
|
|
4312
4894
|
delete manifest.files[filepath];
|
|
4895
|
+
removedFilepaths.push(filepath);
|
|
4313
4896
|
totalRemoved++;
|
|
4314
4897
|
}
|
|
4898
|
+
if (removedFilepaths.length > 0) {
|
|
4899
|
+
try {
|
|
4900
|
+
const { LiteralIndex: LiteralIndex2 } = await Promise.resolve().then(() => (init_literalIndex(), exports_literalIndex));
|
|
4901
|
+
const raggrepDir = getRaggrepDir(rootDir, config);
|
|
4902
|
+
const literalIndex = new LiteralIndex2(raggrepDir, module.id);
|
|
4903
|
+
await literalIndex.initialize();
|
|
4904
|
+
for (const filepath of removedFilepaths) {
|
|
4905
|
+
literalIndex.removeFile(filepath);
|
|
4906
|
+
}
|
|
4907
|
+
await literalIndex.save();
|
|
4908
|
+
} catch {}
|
|
4909
|
+
}
|
|
4315
4910
|
const ctx = {
|
|
4316
4911
|
rootDir,
|
|
4317
4912
|
config,
|
|
4318
4913
|
readFile: async (filepath) => {
|
|
4319
|
-
const fullPath =
|
|
4320
|
-
return
|
|
4914
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
4915
|
+
return fs7.readFile(fullPath, "utf-8");
|
|
4321
4916
|
},
|
|
4322
4917
|
getFileStats: async (filepath) => {
|
|
4323
|
-
const fullPath =
|
|
4324
|
-
const stats = await
|
|
4918
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
4919
|
+
const stats = await fs7.stat(fullPath);
|
|
4325
4920
|
return { lastModified: stats.mtime.toISOString() };
|
|
4326
4921
|
},
|
|
4327
4922
|
getIntrospection: (filepath) => introspection.getFile(filepath)
|
|
@@ -4329,10 +4924,10 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4329
4924
|
const totalFiles = currentFiles.length;
|
|
4330
4925
|
for (let i = 0;i < currentFiles.length; i++) {
|
|
4331
4926
|
const filepath = currentFiles[i];
|
|
4332
|
-
const relativePath =
|
|
4927
|
+
const relativePath = path15.relative(rootDir, filepath);
|
|
4333
4928
|
const progress = `[${i + 1}/${totalFiles}]`;
|
|
4334
4929
|
try {
|
|
4335
|
-
const stats = await
|
|
4930
|
+
const stats = await fs7.stat(filepath);
|
|
4336
4931
|
const lastModified = stats.mtime.toISOString();
|
|
4337
4932
|
const existingEntry = manifest.files[relativePath];
|
|
4338
4933
|
if (existingEntry && existingEntry.lastModified === lastModified) {
|
|
@@ -4340,7 +4935,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4340
4935
|
continue;
|
|
4341
4936
|
}
|
|
4342
4937
|
logger.progress(` ${progress} Indexing: ${relativePath}`);
|
|
4343
|
-
const content = await
|
|
4938
|
+
const content = await fs7.readFile(filepath, "utf-8");
|
|
4344
4939
|
introspection.addFile(relativePath, content);
|
|
4345
4940
|
const fileIndex = await module.indexFile(relativePath, content, ctx);
|
|
4346
4941
|
if (fileIndex) {
|
|
@@ -4389,7 +4984,7 @@ async function indexWithModule(rootDir, files, module, config, verbose, introspe
|
|
|
4389
4984
|
};
|
|
4390
4985
|
const manifest = await loadModuleManifest(rootDir, module.id, config);
|
|
4391
4986
|
const indexPath = getModuleIndexPath(rootDir, module.id, config);
|
|
4392
|
-
const currentFileSet = new Set(files.map((f) =>
|
|
4987
|
+
const currentFileSet = new Set(files.map((f) => path15.relative(rootDir, f)));
|
|
4393
4988
|
const filesToRemove = [];
|
|
4394
4989
|
for (const filepath of Object.keys(manifest.files)) {
|
|
4395
4990
|
if (!currentFileSet.has(filepath)) {
|
|
@@ -4400,13 +4995,13 @@ async function indexWithModule(rootDir, files, module, config, verbose, introspe
|
|
|
4400
4995
|
logger.info(` Removing ${filesToRemove.length} stale entries...`);
|
|
4401
4996
|
for (const filepath of filesToRemove) {
|
|
4402
4997
|
logger.debug(` Removing: ${filepath}`);
|
|
4403
|
-
const indexFilePath =
|
|
4998
|
+
const indexFilePath = path15.join(indexPath, filepath.replace(/\.[^.]+$/, ".json"));
|
|
4404
4999
|
try {
|
|
4405
|
-
await
|
|
5000
|
+
await fs7.unlink(indexFilePath);
|
|
4406
5001
|
} catch {}
|
|
4407
|
-
const symbolicFilePath =
|
|
5002
|
+
const symbolicFilePath = path15.join(indexPath, "symbolic", filepath.replace(/\.[^.]+$/, ".json"));
|
|
4408
5003
|
try {
|
|
4409
|
-
await
|
|
5004
|
+
await fs7.unlink(symbolicFilePath);
|
|
4410
5005
|
} catch {}
|
|
4411
5006
|
delete manifest.files[filepath];
|
|
4412
5007
|
}
|
|
@@ -4416,12 +5011,12 @@ async function indexWithModule(rootDir, files, module, config, verbose, introspe
|
|
|
4416
5011
|
rootDir,
|
|
4417
5012
|
config,
|
|
4418
5013
|
readFile: async (filepath) => {
|
|
4419
|
-
const fullPath =
|
|
4420
|
-
return
|
|
5014
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
5015
|
+
return fs7.readFile(fullPath, "utf-8");
|
|
4421
5016
|
},
|
|
4422
5017
|
getFileStats: async (filepath) => {
|
|
4423
|
-
const fullPath =
|
|
4424
|
-
const stats = await
|
|
5018
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
5019
|
+
const stats = await fs7.stat(fullPath);
|
|
4425
5020
|
return { lastModified: stats.mtime.toISOString() };
|
|
4426
5021
|
},
|
|
4427
5022
|
getIntrospection: (filepath) => introspection.getFile(filepath)
|
|
@@ -4429,9 +5024,9 @@ async function indexWithModule(rootDir, files, module, config, verbose, introspe
|
|
|
4429
5024
|
const totalFiles = files.length;
|
|
4430
5025
|
let completedCount = 0;
|
|
4431
5026
|
const processFile = async (filepath, _index) => {
|
|
4432
|
-
const relativePath =
|
|
5027
|
+
const relativePath = path15.relative(rootDir, filepath);
|
|
4433
5028
|
try {
|
|
4434
|
-
const stats = await
|
|
5029
|
+
const stats = await fs7.stat(filepath);
|
|
4435
5030
|
const lastModified = stats.mtime.toISOString();
|
|
4436
5031
|
const existingEntry = manifest.files[relativePath];
|
|
4437
5032
|
if (existingEntry && existingEntry.lastModified === lastModified) {
|
|
@@ -4439,7 +5034,7 @@ async function indexWithModule(rootDir, files, module, config, verbose, introspe
|
|
|
4439
5034
|
logger.debug(` [${completedCount}/${totalFiles}] Skipped ${relativePath} (unchanged)`);
|
|
4440
5035
|
return { relativePath, status: "skipped" };
|
|
4441
5036
|
}
|
|
4442
|
-
const content = await
|
|
5037
|
+
const content = await fs7.readFile(filepath, "utf-8");
|
|
4443
5038
|
introspection.addFile(relativePath, content);
|
|
4444
5039
|
completedCount++;
|
|
4445
5040
|
logger.progress(` [${completedCount}/${totalFiles}] Processing: ${relativePath}`);
|
|
@@ -4507,7 +5102,7 @@ async function findFiles(rootDir, config) {
|
|
|
4507
5102
|
async function loadModuleManifest(rootDir, moduleId, config) {
|
|
4508
5103
|
const manifestPath = getModuleManifestPath(rootDir, moduleId, config);
|
|
4509
5104
|
try {
|
|
4510
|
-
const content = await
|
|
5105
|
+
const content = await fs7.readFile(manifestPath, "utf-8");
|
|
4511
5106
|
return JSON.parse(content);
|
|
4512
5107
|
} catch {
|
|
4513
5108
|
return {
|
|
@@ -4520,14 +5115,14 @@ async function loadModuleManifest(rootDir, moduleId, config) {
|
|
|
4520
5115
|
}
|
|
4521
5116
|
async function writeModuleManifest(rootDir, moduleId, manifest, config) {
|
|
4522
5117
|
const manifestPath = getModuleManifestPath(rootDir, moduleId, config);
|
|
4523
|
-
await
|
|
4524
|
-
await
|
|
5118
|
+
await fs7.mkdir(path15.dirname(manifestPath), { recursive: true });
|
|
5119
|
+
await fs7.writeFile(manifestPath, JSON.stringify(manifest, null, 2));
|
|
4525
5120
|
}
|
|
4526
5121
|
async function writeFileIndex(rootDir, moduleId, filepath, fileIndex, config) {
|
|
4527
5122
|
const indexPath = getModuleIndexPath(rootDir, moduleId, config);
|
|
4528
|
-
const indexFilePath =
|
|
4529
|
-
await
|
|
4530
|
-
await
|
|
5123
|
+
const indexFilePath = path15.join(indexPath, filepath.replace(/\.[^.]+$/, ".json"));
|
|
5124
|
+
await fs7.mkdir(path15.dirname(indexFilePath), { recursive: true });
|
|
5125
|
+
await fs7.writeFile(indexFilePath, JSON.stringify(fileIndex, null, 2));
|
|
4531
5126
|
}
|
|
4532
5127
|
async function updateGlobalManifest(rootDir, modules, config) {
|
|
4533
5128
|
const manifestPath = getGlobalManifestPath(rootDir, config);
|
|
@@ -4536,13 +5131,13 @@ async function updateGlobalManifest(rootDir, modules, config) {
|
|
|
4536
5131
|
lastUpdated: new Date().toISOString(),
|
|
4537
5132
|
modules: modules.map((m) => m.id)
|
|
4538
5133
|
};
|
|
4539
|
-
await
|
|
4540
|
-
await
|
|
5134
|
+
await fs7.mkdir(path15.dirname(manifestPath), { recursive: true });
|
|
5135
|
+
await fs7.writeFile(manifestPath, JSON.stringify(manifest, null, 2));
|
|
4541
5136
|
}
|
|
4542
5137
|
async function cleanupIndex(rootDir, options = {}) {
|
|
4543
5138
|
const verbose = options.verbose ?? false;
|
|
4544
5139
|
const logger = options.logger ?? createLogger({ verbose });
|
|
4545
|
-
rootDir =
|
|
5140
|
+
rootDir = path15.resolve(rootDir);
|
|
4546
5141
|
logger.info(`Cleaning up index in: ${rootDir}`);
|
|
4547
5142
|
const config = await loadConfig(rootDir);
|
|
4548
5143
|
await registerBuiltInModules();
|
|
@@ -4572,9 +5167,9 @@ async function cleanupModuleIndex(rootDir, moduleId, config, logger) {
|
|
|
4572
5167
|
const filesToRemove = [];
|
|
4573
5168
|
const updatedFiles = {};
|
|
4574
5169
|
for (const [filepath, entry] of Object.entries(manifest.files)) {
|
|
4575
|
-
const fullPath =
|
|
5170
|
+
const fullPath = path15.join(rootDir, filepath);
|
|
4576
5171
|
try {
|
|
4577
|
-
await
|
|
5172
|
+
await fs7.access(fullPath);
|
|
4578
5173
|
updatedFiles[filepath] = entry;
|
|
4579
5174
|
result.kept++;
|
|
4580
5175
|
} catch {
|
|
@@ -4584,9 +5179,9 @@ async function cleanupModuleIndex(rootDir, moduleId, config, logger) {
|
|
|
4584
5179
|
}
|
|
4585
5180
|
}
|
|
4586
5181
|
for (const filepath of filesToRemove) {
|
|
4587
|
-
const indexFilePath =
|
|
5182
|
+
const indexFilePath = path15.join(indexPath, filepath.replace(/\.[^.]+$/, ".json"));
|
|
4588
5183
|
try {
|
|
4589
|
-
await
|
|
5184
|
+
await fs7.unlink(indexFilePath);
|
|
4590
5185
|
} catch {}
|
|
4591
5186
|
}
|
|
4592
5187
|
manifest.files = updatedFiles;
|
|
@@ -4597,16 +5192,16 @@ async function cleanupModuleIndex(rootDir, moduleId, config, logger) {
|
|
|
4597
5192
|
}
|
|
4598
5193
|
async function cleanupEmptyDirectories(dir) {
|
|
4599
5194
|
try {
|
|
4600
|
-
const entries = await
|
|
5195
|
+
const entries = await fs7.readdir(dir, { withFileTypes: true });
|
|
4601
5196
|
for (const entry of entries) {
|
|
4602
5197
|
if (entry.isDirectory()) {
|
|
4603
|
-
const subDir =
|
|
5198
|
+
const subDir = path15.join(dir, entry.name);
|
|
4604
5199
|
await cleanupEmptyDirectories(subDir);
|
|
4605
5200
|
}
|
|
4606
5201
|
}
|
|
4607
|
-
const remainingEntries = await
|
|
5202
|
+
const remainingEntries = await fs7.readdir(dir);
|
|
4608
5203
|
if (remainingEntries.length === 0) {
|
|
4609
|
-
await
|
|
5204
|
+
await fs7.rmdir(dir);
|
|
4610
5205
|
return true;
|
|
4611
5206
|
}
|
|
4612
5207
|
return false;
|
|
@@ -4615,7 +5210,7 @@ async function cleanupEmptyDirectories(dir) {
|
|
|
4615
5210
|
}
|
|
4616
5211
|
}
|
|
4617
5212
|
async function getIndexStatus(rootDir) {
|
|
4618
|
-
rootDir =
|
|
5213
|
+
rootDir = path15.resolve(rootDir);
|
|
4619
5214
|
const config = await loadConfig(rootDir);
|
|
4620
5215
|
const location = getIndexLocation(rootDir);
|
|
4621
5216
|
const indexDir = location.indexDir;
|
|
@@ -4627,13 +5222,13 @@ async function getIndexStatus(rootDir) {
|
|
|
4627
5222
|
totalFiles: 0
|
|
4628
5223
|
};
|
|
4629
5224
|
try {
|
|
4630
|
-
await
|
|
5225
|
+
await fs7.access(indexDir);
|
|
4631
5226
|
} catch {
|
|
4632
5227
|
return status;
|
|
4633
5228
|
}
|
|
4634
5229
|
try {
|
|
4635
5230
|
const globalManifestPath = getGlobalManifestPath(rootDir, config);
|
|
4636
|
-
const content = await
|
|
5231
|
+
const content = await fs7.readFile(globalManifestPath, "utf-8");
|
|
4637
5232
|
const globalManifest = JSON.parse(content);
|
|
4638
5233
|
status.exists = true;
|
|
4639
5234
|
status.lastUpdated = globalManifest.lastUpdated;
|
|
@@ -4651,7 +5246,7 @@ async function getIndexStatus(rootDir) {
|
|
|
4651
5246
|
}
|
|
4652
5247
|
} catch {
|
|
4653
5248
|
try {
|
|
4654
|
-
const entries = await
|
|
5249
|
+
const entries = await fs7.readdir(path15.join(indexDir, "index"));
|
|
4655
5250
|
if (entries.length > 0) {
|
|
4656
5251
|
status.exists = true;
|
|
4657
5252
|
for (const entry of entries) {
|
|
@@ -4673,8 +5268,8 @@ async function getIndexStatus(rootDir) {
|
|
|
4673
5268
|
}
|
|
4674
5269
|
|
|
4675
5270
|
// src/app/search/index.ts
|
|
4676
|
-
import * as
|
|
4677
|
-
import * as
|
|
5271
|
+
import * as fs8 from "fs/promises";
|
|
5272
|
+
import * as path16 from "path";
|
|
4678
5273
|
|
|
4679
5274
|
// src/types.ts
|
|
4680
5275
|
init_entities();
|
|
@@ -4682,7 +5277,7 @@ init_entities();
|
|
|
4682
5277
|
// src/app/search/index.ts
|
|
4683
5278
|
init_config2();
|
|
4684
5279
|
async function search(rootDir, query, options = {}) {
|
|
4685
|
-
rootDir =
|
|
5280
|
+
rootDir = path16.resolve(rootDir);
|
|
4686
5281
|
const ensureFresh = options.ensureFresh ?? DEFAULT_SEARCH_OPTIONS.ensureFresh;
|
|
4687
5282
|
if (ensureFresh) {
|
|
4688
5283
|
await ensureIndexFresh(rootDir, { quiet: true });
|
|
@@ -4735,9 +5330,9 @@ function createSearchContext(rootDir, moduleId, config) {
|
|
|
4735
5330
|
config,
|
|
4736
5331
|
loadFileIndex: async (filepath) => {
|
|
4737
5332
|
const hasExtension = /\.[^./]+$/.test(filepath);
|
|
4738
|
-
const indexFilePath = hasExtension ?
|
|
5333
|
+
const indexFilePath = hasExtension ? path16.join(indexPath, filepath.replace(/\.[^.]+$/, ".json")) : path16.join(indexPath, filepath + ".json");
|
|
4739
5334
|
try {
|
|
4740
|
-
const content = await
|
|
5335
|
+
const content = await fs8.readFile(indexFilePath, "utf-8");
|
|
4741
5336
|
return JSON.parse(content);
|
|
4742
5337
|
} catch {
|
|
4743
5338
|
return null;
|
|
@@ -4747,7 +5342,7 @@ function createSearchContext(rootDir, moduleId, config) {
|
|
|
4747
5342
|
const files = [];
|
|
4748
5343
|
await traverseDirectory(indexPath, files, indexPath);
|
|
4749
5344
|
return files.filter((f) => f.endsWith(".json") && !f.endsWith("manifest.json")).map((f) => {
|
|
4750
|
-
const relative3 =
|
|
5345
|
+
const relative3 = path16.relative(indexPath, f);
|
|
4751
5346
|
return relative3.replace(/\.json$/, "");
|
|
4752
5347
|
});
|
|
4753
5348
|
}
|
|
@@ -4755,9 +5350,9 @@ function createSearchContext(rootDir, moduleId, config) {
|
|
|
4755
5350
|
}
|
|
4756
5351
|
async function traverseDirectory(dir, files, basePath) {
|
|
4757
5352
|
try {
|
|
4758
|
-
const entries = await
|
|
5353
|
+
const entries = await fs8.readdir(dir, { withFileTypes: true });
|
|
4759
5354
|
for (const entry of entries) {
|
|
4760
|
-
const fullPath =
|
|
5355
|
+
const fullPath = path16.join(dir, entry.name);
|
|
4761
5356
|
if (entry.isDirectory()) {
|
|
4762
5357
|
await traverseDirectory(fullPath, files, basePath);
|
|
4763
5358
|
} else if (entry.isFile()) {
|
|
@@ -4769,7 +5364,7 @@ async function traverseDirectory(dir, files, basePath) {
|
|
|
4769
5364
|
async function loadGlobalManifest(rootDir, config) {
|
|
4770
5365
|
const manifestPath = getGlobalManifestPath(rootDir, config);
|
|
4771
5366
|
try {
|
|
4772
|
-
const content = await
|
|
5367
|
+
const content = await fs8.readFile(manifestPath, "utf-8");
|
|
4773
5368
|
return JSON.parse(content);
|
|
4774
5369
|
} catch {
|
|
4775
5370
|
return null;
|
|
@@ -4859,4 +5454,4 @@ export {
|
|
|
4859
5454
|
ConsoleLogger
|
|
4860
5455
|
};
|
|
4861
5456
|
|
|
4862
|
-
//# debugId=
|
|
5457
|
+
//# debugId=F5160C7762E8AC7864756E2164756E21
|