raggrep 0.6.1 → 0.7.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 +2 -0
- package/dist/cli/main.js +670 -123
- package/dist/cli/main.js.map +11 -7
- 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 +665 -118
- package/dist/index.js.map +11 -7
- package/dist/infrastructure/storage/index.d.ts +1 -0
- package/dist/infrastructure/storage/literalIndex.d.ts +103 -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,158 @@ var init_symbolicIndex = __esm(() => {
|
|
|
2889
3182
|
init_keywords();
|
|
2890
3183
|
});
|
|
2891
3184
|
|
|
3185
|
+
// src/infrastructure/storage/literalIndex.ts
|
|
3186
|
+
import * as fs4 from "fs/promises";
|
|
3187
|
+
import * as path9 from "path";
|
|
3188
|
+
|
|
3189
|
+
class LiteralIndex {
|
|
3190
|
+
indexPath;
|
|
3191
|
+
moduleId;
|
|
3192
|
+
entries = new Map;
|
|
3193
|
+
static VERSION = "1.0.0";
|
|
3194
|
+
constructor(indexDir, moduleId) {
|
|
3195
|
+
this.indexPath = path9.join(indexDir, "index", moduleId, "literals");
|
|
3196
|
+
this.moduleId = moduleId;
|
|
3197
|
+
}
|
|
3198
|
+
async initialize() {
|
|
3199
|
+
try {
|
|
3200
|
+
await this.load();
|
|
3201
|
+
} catch {
|
|
3202
|
+
this.entries = new Map;
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
addLiterals(chunkId, filepath, literals) {
|
|
3206
|
+
for (const literal of literals) {
|
|
3207
|
+
const key = literal.value.toLowerCase();
|
|
3208
|
+
const existingEntries = this.entries.get(key) || [];
|
|
3209
|
+
const existingIndex = existingEntries.findIndex((e) => e.chunkId === chunkId);
|
|
3210
|
+
const newEntry = {
|
|
3211
|
+
chunkId,
|
|
3212
|
+
filepath,
|
|
3213
|
+
originalCasing: literal.value,
|
|
3214
|
+
type: literal.type,
|
|
3215
|
+
matchType: literal.matchType
|
|
3216
|
+
};
|
|
3217
|
+
if (existingIndex >= 0) {
|
|
3218
|
+
const existing = existingEntries[existingIndex];
|
|
3219
|
+
if (shouldReplaceMatchType(existing.matchType, literal.matchType)) {
|
|
3220
|
+
existingEntries[existingIndex] = newEntry;
|
|
3221
|
+
}
|
|
3222
|
+
} else {
|
|
3223
|
+
existingEntries.push(newEntry);
|
|
3224
|
+
}
|
|
3225
|
+
this.entries.set(key, existingEntries);
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
removeChunk(chunkId) {
|
|
3229
|
+
for (const [key, entries] of this.entries) {
|
|
3230
|
+
const filtered = entries.filter((e) => e.chunkId !== chunkId);
|
|
3231
|
+
if (filtered.length === 0) {
|
|
3232
|
+
this.entries.delete(key);
|
|
3233
|
+
} else if (filtered.length !== entries.length) {
|
|
3234
|
+
this.entries.set(key, filtered);
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
findMatches(queryLiterals) {
|
|
3239
|
+
const matches = [];
|
|
3240
|
+
for (const queryLiteral of queryLiterals) {
|
|
3241
|
+
const key = queryLiteral.value.toLowerCase();
|
|
3242
|
+
const entries = this.entries.get(key);
|
|
3243
|
+
if (!entries) {
|
|
3244
|
+
continue;
|
|
3245
|
+
}
|
|
3246
|
+
for (const entry of entries) {
|
|
3247
|
+
const exactMatch = entry.originalCasing === queryLiteral.value;
|
|
3248
|
+
matches.push({
|
|
3249
|
+
queryLiteral,
|
|
3250
|
+
indexedLiteral: {
|
|
3251
|
+
value: entry.originalCasing,
|
|
3252
|
+
type: entry.type,
|
|
3253
|
+
matchType: entry.matchType
|
|
3254
|
+
},
|
|
3255
|
+
chunkId: entry.chunkId,
|
|
3256
|
+
filepath: entry.filepath,
|
|
3257
|
+
exactMatch
|
|
3258
|
+
});
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3261
|
+
return matches;
|
|
3262
|
+
}
|
|
3263
|
+
getChunksForLiteral(literal) {
|
|
3264
|
+
const key = literal.toLowerCase();
|
|
3265
|
+
const entries = this.entries.get(key);
|
|
3266
|
+
return entries ? entries.map((e) => e.chunkId) : [];
|
|
3267
|
+
}
|
|
3268
|
+
async save() {
|
|
3269
|
+
await fs4.mkdir(this.indexPath, { recursive: true });
|
|
3270
|
+
const data = {
|
|
3271
|
+
version: LiteralIndex.VERSION,
|
|
3272
|
+
entries: Object.fromEntries(this.entries)
|
|
3273
|
+
};
|
|
3274
|
+
const indexFile = path9.join(this.indexPath, "_index.json");
|
|
3275
|
+
await fs4.writeFile(indexFile, JSON.stringify(data, null, 2));
|
|
3276
|
+
}
|
|
3277
|
+
async load() {
|
|
3278
|
+
const indexFile = path9.join(this.indexPath, "_index.json");
|
|
3279
|
+
const content = await fs4.readFile(indexFile, "utf-8");
|
|
3280
|
+
const data = JSON.parse(content);
|
|
3281
|
+
if (data.version !== LiteralIndex.VERSION) {
|
|
3282
|
+
console.warn(`Literal index version mismatch: expected ${LiteralIndex.VERSION}, got ${data.version}`);
|
|
3283
|
+
}
|
|
3284
|
+
this.entries = new Map(Object.entries(data.entries));
|
|
3285
|
+
}
|
|
3286
|
+
async exists() {
|
|
3287
|
+
try {
|
|
3288
|
+
const indexFile = path9.join(this.indexPath, "_index.json");
|
|
3289
|
+
await fs4.access(indexFile);
|
|
3290
|
+
return true;
|
|
3291
|
+
} catch {
|
|
3292
|
+
return false;
|
|
3293
|
+
}
|
|
3294
|
+
}
|
|
3295
|
+
clear() {
|
|
3296
|
+
this.entries.clear();
|
|
3297
|
+
}
|
|
3298
|
+
get size() {
|
|
3299
|
+
return this.entries.size;
|
|
3300
|
+
}
|
|
3301
|
+
get totalMappings() {
|
|
3302
|
+
let count = 0;
|
|
3303
|
+
for (const entries of this.entries.values()) {
|
|
3304
|
+
count += entries.length;
|
|
3305
|
+
}
|
|
3306
|
+
return count;
|
|
3307
|
+
}
|
|
3308
|
+
getAllLiterals() {
|
|
3309
|
+
return Array.from(this.entries.keys());
|
|
3310
|
+
}
|
|
3311
|
+
buildMatchMap(queryLiterals) {
|
|
3312
|
+
const matches = this.findMatches(queryLiterals);
|
|
3313
|
+
const matchMap = new Map;
|
|
3314
|
+
for (const match of matches) {
|
|
3315
|
+
const existing = matchMap.get(match.chunkId) || [];
|
|
3316
|
+
existing.push(match);
|
|
3317
|
+
matchMap.set(match.chunkId, existing);
|
|
3318
|
+
}
|
|
3319
|
+
return matchMap;
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3322
|
+
function shouldReplaceMatchType(existing, incoming) {
|
|
3323
|
+
const priority = {
|
|
3324
|
+
definition: 3,
|
|
3325
|
+
reference: 2,
|
|
3326
|
+
import: 1
|
|
3327
|
+
};
|
|
3328
|
+
return priority[incoming] > priority[existing];
|
|
3329
|
+
}
|
|
3330
|
+
var init_literalIndex = () => {};
|
|
3331
|
+
|
|
2892
3332
|
// src/infrastructure/storage/index.ts
|
|
2893
3333
|
var init_storage = __esm(() => {
|
|
2894
3334
|
init_fileIndexStorage();
|
|
2895
3335
|
init_symbolicIndex();
|
|
3336
|
+
init_literalIndex();
|
|
2896
3337
|
});
|
|
2897
3338
|
|
|
2898
3339
|
// src/modules/language/typescript/index.ts
|
|
@@ -2905,9 +3346,9 @@ __export(exports_typescript, {
|
|
|
2905
3346
|
DEFAULT_TOP_K: () => DEFAULT_TOP_K2,
|
|
2906
3347
|
DEFAULT_MIN_SCORE: () => DEFAULT_MIN_SCORE2
|
|
2907
3348
|
});
|
|
2908
|
-
import * as
|
|
3349
|
+
import * as path10 from "path";
|
|
2909
3350
|
function isTypeScriptFile(filepath) {
|
|
2910
|
-
const ext =
|
|
3351
|
+
const ext = path10.extname(filepath).toLowerCase();
|
|
2911
3352
|
return TYPESCRIPT_EXTENSIONS.includes(ext);
|
|
2912
3353
|
}
|
|
2913
3354
|
function calculateChunkTypeBoost(chunk) {
|
|
@@ -2942,7 +3383,9 @@ class TypeScriptModule {
|
|
|
2942
3383
|
}
|
|
2943
3384
|
embeddingConfig = null;
|
|
2944
3385
|
symbolicIndex = null;
|
|
3386
|
+
literalIndex = null;
|
|
2945
3387
|
pendingSummaries = new Map;
|
|
3388
|
+
pendingLiterals = new Map;
|
|
2946
3389
|
rootDir = "";
|
|
2947
3390
|
logger = undefined;
|
|
2948
3391
|
async initialize(config) {
|
|
@@ -2956,6 +3399,7 @@ class TypeScriptModule {
|
|
|
2956
3399
|
}
|
|
2957
3400
|
configureEmbeddings(this.embeddingConfig);
|
|
2958
3401
|
this.pendingSummaries.clear();
|
|
3402
|
+
this.pendingLiterals.clear();
|
|
2959
3403
|
}
|
|
2960
3404
|
async indexFile(filepath, content, ctx) {
|
|
2961
3405
|
if (!isTypeScriptFile(filepath)) {
|
|
@@ -3015,6 +3459,17 @@ class TypeScriptModule {
|
|
|
3015
3459
|
}
|
|
3016
3460
|
};
|
|
3017
3461
|
this.pendingSummaries.set(filepath, fileSummary);
|
|
3462
|
+
for (const chunk of chunks) {
|
|
3463
|
+
const literals = extractLiterals(chunk);
|
|
3464
|
+
if (literals.length > 0) {
|
|
3465
|
+
const existing = this.pendingLiterals.get(chunk.id);
|
|
3466
|
+
if (existing) {
|
|
3467
|
+
existing.literals.push(...literals);
|
|
3468
|
+
} else {
|
|
3469
|
+
this.pendingLiterals.set(chunk.id, { filepath, literals });
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3018
3473
|
return {
|
|
3019
3474
|
filepath,
|
|
3020
3475
|
lastModified: stats.lastModified,
|
|
@@ -3032,7 +3487,14 @@ class TypeScriptModule {
|
|
|
3032
3487
|
}
|
|
3033
3488
|
this.symbolicIndex.buildBM25Index();
|
|
3034
3489
|
await this.symbolicIndex.save();
|
|
3490
|
+
this.literalIndex = new LiteralIndex(indexDir, this.id);
|
|
3491
|
+
await this.literalIndex.initialize();
|
|
3492
|
+
for (const [chunkId, { filepath, literals }] of this.pendingLiterals) {
|
|
3493
|
+
this.literalIndex.addLiterals(chunkId, filepath, literals);
|
|
3494
|
+
}
|
|
3495
|
+
await this.literalIndex.save();
|
|
3035
3496
|
this.pendingSummaries.clear();
|
|
3497
|
+
this.pendingLiterals.clear();
|
|
3036
3498
|
}
|
|
3037
3499
|
async search(query, ctx, options = {}) {
|
|
3038
3500
|
const {
|
|
@@ -3040,8 +3502,15 @@ class TypeScriptModule {
|
|
|
3040
3502
|
minScore = DEFAULT_MIN_SCORE2,
|
|
3041
3503
|
filePatterns
|
|
3042
3504
|
} = options;
|
|
3505
|
+
const { literals: queryLiterals, remainingQuery } = parseQueryLiterals(query);
|
|
3043
3506
|
const indexDir = getRaggrepDir(ctx.rootDir, ctx.config);
|
|
3044
3507
|
const symbolicIndex = new SymbolicIndex(indexDir, this.id);
|
|
3508
|
+
const literalIndex = new LiteralIndex(indexDir, this.id);
|
|
3509
|
+
let literalMatchMap = new Map;
|
|
3510
|
+
try {
|
|
3511
|
+
await literalIndex.initialize();
|
|
3512
|
+
literalMatchMap = literalIndex.buildMatchMap(queryLiterals);
|
|
3513
|
+
} catch {}
|
|
3045
3514
|
let allFiles;
|
|
3046
3515
|
try {
|
|
3047
3516
|
await symbolicIndex.initialize();
|
|
@@ -3061,7 +3530,8 @@ class TypeScriptModule {
|
|
|
3061
3530
|
});
|
|
3062
3531
|
});
|
|
3063
3532
|
}
|
|
3064
|
-
const
|
|
3533
|
+
const semanticQuery = remainingQuery.trim() || query;
|
|
3534
|
+
const queryEmbedding = await getEmbedding(semanticQuery);
|
|
3065
3535
|
const bm25Index = new BM25Index;
|
|
3066
3536
|
const allChunksData = [];
|
|
3067
3537
|
for (const filepath of filesToSearch) {
|
|
@@ -3095,14 +3565,14 @@ class TypeScriptModule {
|
|
|
3095
3565
|
const summary = symbolicIndex.getFileSummary(filepath);
|
|
3096
3566
|
if (summary?.pathContext) {
|
|
3097
3567
|
let boost = 0;
|
|
3098
|
-
const
|
|
3099
|
-
if (
|
|
3568
|
+
const pathCtx = summary.pathContext;
|
|
3569
|
+
if (pathCtx.domain && queryTerms.some((t) => pathCtx.domain.includes(t) || t.includes(pathCtx.domain))) {
|
|
3100
3570
|
boost += 0.1;
|
|
3101
3571
|
}
|
|
3102
|
-
if (
|
|
3572
|
+
if (pathCtx.layer && queryTerms.some((t) => pathCtx.layer.includes(t) || t.includes(pathCtx.layer))) {
|
|
3103
3573
|
boost += 0.05;
|
|
3104
3574
|
}
|
|
3105
|
-
const segmentMatch =
|
|
3575
|
+
const segmentMatch = pathCtx.segments.some((seg) => queryTerms.some((t) => seg.toLowerCase().includes(t) || t.includes(seg.toLowerCase())));
|
|
3106
3576
|
if (segmentMatch) {
|
|
3107
3577
|
boost += 0.05;
|
|
3108
3578
|
}
|
|
@@ -3110,6 +3580,7 @@ class TypeScriptModule {
|
|
|
3110
3580
|
}
|
|
3111
3581
|
}
|
|
3112
3582
|
const results = [];
|
|
3583
|
+
const processedChunkIds = new Set;
|
|
3113
3584
|
for (const { filepath, chunk, embedding } of allChunksData) {
|
|
3114
3585
|
const semanticScore = cosineSimilarity(queryEmbedding, embedding);
|
|
3115
3586
|
const bm25Score = bm25Scores.get(chunk.id) || 0;
|
|
@@ -3117,13 +3588,18 @@ class TypeScriptModule {
|
|
|
3117
3588
|
const fileTypeBoost = calculateFileTypeBoost(filepath, queryTerms);
|
|
3118
3589
|
const chunkTypeBoost = calculateChunkTypeBoost(chunk);
|
|
3119
3590
|
const exportBoost = calculateExportBoost(chunk);
|
|
3120
|
-
const
|
|
3121
|
-
const
|
|
3122
|
-
|
|
3591
|
+
const additiveBoost = pathBoost + fileTypeBoost + chunkTypeBoost + exportBoost;
|
|
3592
|
+
const baseScore = SEMANTIC_WEIGHT * semanticScore + BM25_WEIGHT * bm25Score;
|
|
3593
|
+
const literalMatches = literalMatchMap.get(chunk.id) || [];
|
|
3594
|
+
const literalContribution = calculateLiteralContribution(literalMatches, true);
|
|
3595
|
+
const boostedScore = applyLiteralBoost(baseScore, literalMatches, true);
|
|
3596
|
+
const finalScore = boostedScore + additiveBoost;
|
|
3597
|
+
processedChunkIds.add(chunk.id);
|
|
3598
|
+
if (finalScore >= minScore || bm25Score > 0.3 || literalMatches.length > 0) {
|
|
3123
3599
|
results.push({
|
|
3124
3600
|
filepath,
|
|
3125
3601
|
chunk,
|
|
3126
|
-
score:
|
|
3602
|
+
score: finalScore,
|
|
3127
3603
|
moduleId: this.id,
|
|
3128
3604
|
context: {
|
|
3129
3605
|
semanticScore,
|
|
@@ -3131,7 +3607,78 @@ class TypeScriptModule {
|
|
|
3131
3607
|
pathBoost,
|
|
3132
3608
|
fileTypeBoost,
|
|
3133
3609
|
chunkTypeBoost,
|
|
3134
|
-
exportBoost
|
|
3610
|
+
exportBoost,
|
|
3611
|
+
literalMultiplier: literalContribution.multiplier,
|
|
3612
|
+
literalMatchType: literalContribution.bestMatchType,
|
|
3613
|
+
literalConfidence: literalContribution.bestConfidence,
|
|
3614
|
+
literalMatchCount: literalContribution.matchCount
|
|
3615
|
+
}
|
|
3616
|
+
});
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
const literalOnlyFiles = new Map;
|
|
3620
|
+
for (const [chunkId, matches] of literalMatchMap) {
|
|
3621
|
+
if (processedChunkIds.has(chunkId)) {
|
|
3622
|
+
continue;
|
|
3623
|
+
}
|
|
3624
|
+
const filepath = matches[0]?.filepath;
|
|
3625
|
+
if (!filepath)
|
|
3626
|
+
continue;
|
|
3627
|
+
const existing = literalOnlyFiles.get(filepath) || [];
|
|
3628
|
+
existing.push(...matches);
|
|
3629
|
+
literalOnlyFiles.set(filepath, existing);
|
|
3630
|
+
}
|
|
3631
|
+
for (const [filepath, matches] of literalOnlyFiles) {
|
|
3632
|
+
const fileIndex = await ctx.loadFileIndex(filepath);
|
|
3633
|
+
if (!fileIndex)
|
|
3634
|
+
continue;
|
|
3635
|
+
const moduleData = fileIndex.moduleData;
|
|
3636
|
+
const chunkMatches = new Map;
|
|
3637
|
+
for (const match of matches) {
|
|
3638
|
+
const existing = chunkMatches.get(match.chunkId) || [];
|
|
3639
|
+
existing.push(match);
|
|
3640
|
+
chunkMatches.set(match.chunkId, existing);
|
|
3641
|
+
}
|
|
3642
|
+
for (const [chunkId, chunkLiteralMatches] of chunkMatches) {
|
|
3643
|
+
if (processedChunkIds.has(chunkId))
|
|
3644
|
+
continue;
|
|
3645
|
+
const chunkIndex = fileIndex.chunks.findIndex((c) => c.id === chunkId);
|
|
3646
|
+
if (chunkIndex === -1)
|
|
3647
|
+
continue;
|
|
3648
|
+
const chunk = fileIndex.chunks[chunkIndex];
|
|
3649
|
+
const embedding = moduleData?.embeddings?.[chunkIndex];
|
|
3650
|
+
let semanticScore = 0;
|
|
3651
|
+
if (embedding) {
|
|
3652
|
+
semanticScore = cosineSimilarity(queryEmbedding, embedding);
|
|
3653
|
+
}
|
|
3654
|
+
const bm25Score = bm25Scores.get(chunkId) || 0;
|
|
3655
|
+
const pathBoost = pathBoosts.get(filepath) || 0;
|
|
3656
|
+
const fileTypeBoost = calculateFileTypeBoost(filepath, queryTerms);
|
|
3657
|
+
const chunkTypeBoost = calculateChunkTypeBoost(chunk);
|
|
3658
|
+
const exportBoost = calculateExportBoost(chunk);
|
|
3659
|
+
const additiveBoost = pathBoost + fileTypeBoost + chunkTypeBoost + exportBoost;
|
|
3660
|
+
const literalContribution = calculateLiteralContribution(chunkLiteralMatches, false);
|
|
3661
|
+
const baseScore = semanticScore > 0 ? SEMANTIC_WEIGHT * semanticScore + BM25_WEIGHT * bm25Score : LITERAL_SCORING_CONSTANTS.BASE_SCORE;
|
|
3662
|
+
const boostedScore = applyLiteralBoost(baseScore, chunkLiteralMatches, semanticScore > 0);
|
|
3663
|
+
const finalScore = boostedScore + additiveBoost;
|
|
3664
|
+
processedChunkIds.add(chunkId);
|
|
3665
|
+
results.push({
|
|
3666
|
+
filepath,
|
|
3667
|
+
chunk,
|
|
3668
|
+
score: finalScore,
|
|
3669
|
+
moduleId: this.id,
|
|
3670
|
+
context: {
|
|
3671
|
+
semanticScore,
|
|
3672
|
+
bm25Score,
|
|
3673
|
+
pathBoost,
|
|
3674
|
+
fileTypeBoost,
|
|
3675
|
+
chunkTypeBoost,
|
|
3676
|
+
exportBoost,
|
|
3677
|
+
literalMultiplier: literalContribution.multiplier,
|
|
3678
|
+
literalMatchType: literalContribution.bestMatchType,
|
|
3679
|
+
literalConfidence: literalContribution.bestConfidence,
|
|
3680
|
+
literalMatchCount: literalContribution.matchCount,
|
|
3681
|
+
literalOnly: true
|
|
3135
3682
|
}
|
|
3136
3683
|
});
|
|
3137
3684
|
}
|
|
@@ -3147,16 +3694,16 @@ class TypeScriptModule {
|
|
|
3147
3694
|
while ((match = importRegex.exec(content)) !== null) {
|
|
3148
3695
|
const importPath = match[1];
|
|
3149
3696
|
if (importPath.startsWith(".")) {
|
|
3150
|
-
const dir =
|
|
3151
|
-
const resolved =
|
|
3697
|
+
const dir = path10.dirname(filepath);
|
|
3698
|
+
const resolved = path10.normalize(path10.join(dir, importPath));
|
|
3152
3699
|
references.push(resolved);
|
|
3153
3700
|
}
|
|
3154
3701
|
}
|
|
3155
3702
|
while ((match = requireRegex.exec(content)) !== null) {
|
|
3156
3703
|
const importPath = match[1];
|
|
3157
3704
|
if (importPath.startsWith(".")) {
|
|
3158
|
-
const dir =
|
|
3159
|
-
const resolved =
|
|
3705
|
+
const dir = path10.dirname(filepath);
|
|
3706
|
+
const resolved = path10.normalize(path10.join(dir, importPath));
|
|
3160
3707
|
references.push(resolved);
|
|
3161
3708
|
}
|
|
3162
3709
|
}
|
|
@@ -3193,9 +3740,9 @@ __export(exports_json, {
|
|
|
3193
3740
|
DEFAULT_TOP_K: () => DEFAULT_TOP_K3,
|
|
3194
3741
|
DEFAULT_MIN_SCORE: () => DEFAULT_MIN_SCORE3
|
|
3195
3742
|
});
|
|
3196
|
-
import * as
|
|
3743
|
+
import * as path11 from "path";
|
|
3197
3744
|
function isJsonFile(filepath) {
|
|
3198
|
-
const ext =
|
|
3745
|
+
const ext = path11.extname(filepath).toLowerCase();
|
|
3199
3746
|
return JSON_EXTENSIONS.includes(ext);
|
|
3200
3747
|
}
|
|
3201
3748
|
function extractJsonKeys(obj, prefix = "") {
|
|
@@ -3276,7 +3823,7 @@ class JsonModule {
|
|
|
3276
3823
|
return null;
|
|
3277
3824
|
}
|
|
3278
3825
|
const chunkContents = textChunks.map((c) => {
|
|
3279
|
-
const filename =
|
|
3826
|
+
const filename = path11.basename(filepath);
|
|
3280
3827
|
return `${filename}: ${c.content}`;
|
|
3281
3828
|
});
|
|
3282
3829
|
const embeddings = await getEmbeddings(chunkContents);
|
|
@@ -3427,9 +3974,9 @@ __export(exports_markdown, {
|
|
|
3427
3974
|
DEFAULT_TOP_K: () => DEFAULT_TOP_K4,
|
|
3428
3975
|
DEFAULT_MIN_SCORE: () => DEFAULT_MIN_SCORE4
|
|
3429
3976
|
});
|
|
3430
|
-
import * as
|
|
3977
|
+
import * as path12 from "path";
|
|
3431
3978
|
function isMarkdownFile(filepath) {
|
|
3432
|
-
const ext =
|
|
3979
|
+
const ext = path12.extname(filepath).toLowerCase();
|
|
3433
3980
|
return MARKDOWN_EXTENSIONS.includes(ext);
|
|
3434
3981
|
}
|
|
3435
3982
|
function parseMarkdownSections(content) {
|
|
@@ -3556,7 +4103,7 @@ class MarkdownModule {
|
|
|
3556
4103
|
return null;
|
|
3557
4104
|
}
|
|
3558
4105
|
const chunkContents = sections.map((s) => {
|
|
3559
|
-
const filename =
|
|
4106
|
+
const filename = path12.basename(filepath);
|
|
3560
4107
|
const headingContext = s.heading ? `${s.heading}: ` : "";
|
|
3561
4108
|
return `${filename} ${headingContext}${s.content}`;
|
|
3562
4109
|
});
|
|
@@ -3711,8 +4258,8 @@ var init_markdown = __esm(() => {
|
|
|
3711
4258
|
// src/app/indexer/index.ts
|
|
3712
4259
|
init_config2();
|
|
3713
4260
|
import { glob } from "glob";
|
|
3714
|
-
import * as
|
|
3715
|
-
import * as
|
|
4261
|
+
import * as fs7 from "fs/promises";
|
|
4262
|
+
import * as path15 from "path";
|
|
3716
4263
|
import * as os3 from "os";
|
|
3717
4264
|
|
|
3718
4265
|
// src/modules/registry.ts
|
|
@@ -3747,12 +4294,12 @@ async function registerBuiltInModules() {
|
|
|
3747
4294
|
}
|
|
3748
4295
|
|
|
3749
4296
|
// src/infrastructure/introspection/IntrospectionIndex.ts
|
|
3750
|
-
import * as
|
|
3751
|
-
import * as
|
|
4297
|
+
import * as path14 from "path";
|
|
4298
|
+
import * as fs6 from "fs/promises";
|
|
3752
4299
|
|
|
3753
4300
|
// src/infrastructure/introspection/projectDetector.ts
|
|
3754
|
-
import * as
|
|
3755
|
-
import * as
|
|
4301
|
+
import * as path13 from "path";
|
|
4302
|
+
import * as fs5 from "fs/promises";
|
|
3756
4303
|
var MAX_SCAN_DEPTH = 4;
|
|
3757
4304
|
var SKIP_DIRS = new Set([
|
|
3758
4305
|
"node_modules",
|
|
@@ -3768,9 +4315,9 @@ async function scanForPackageJsons(rootDir, currentDir = "", depth = 0) {
|
|
|
3768
4315
|
if (depth > MAX_SCAN_DEPTH)
|
|
3769
4316
|
return [];
|
|
3770
4317
|
const results = [];
|
|
3771
|
-
const fullDir = currentDir ?
|
|
4318
|
+
const fullDir = currentDir ? path13.join(rootDir, currentDir) : rootDir;
|
|
3772
4319
|
try {
|
|
3773
|
-
const entries = await
|
|
4320
|
+
const entries = await fs5.readdir(fullDir, { withFileTypes: true });
|
|
3774
4321
|
const hasPackageJson = entries.some((e) => e.isFile() && e.name === "package.json");
|
|
3775
4322
|
if (hasPackageJson && currentDir) {
|
|
3776
4323
|
const info = await parsePackageJson(rootDir, currentDir);
|
|
@@ -3791,10 +4338,10 @@ async function scanForPackageJsons(rootDir, currentDir = "", depth = 0) {
|
|
|
3791
4338
|
}
|
|
3792
4339
|
async function parsePackageJson(rootDir, relativePath) {
|
|
3793
4340
|
try {
|
|
3794
|
-
const packageJsonPath =
|
|
3795
|
-
const content = await
|
|
4341
|
+
const packageJsonPath = path13.join(rootDir, relativePath, "package.json");
|
|
4342
|
+
const content = await fs5.readFile(packageJsonPath, "utf-8");
|
|
3796
4343
|
const pkg = JSON.parse(content);
|
|
3797
|
-
const name = pkg.name ||
|
|
4344
|
+
const name = pkg.name || path13.basename(relativePath);
|
|
3798
4345
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
3799
4346
|
let type = "unknown";
|
|
3800
4347
|
if (deps["next"] || deps["react"] || deps["vue"] || deps["svelte"]) {
|
|
@@ -3830,7 +4377,7 @@ async function detectProjectStructure(rootDir) {
|
|
|
3830
4377
|
const projectMap = new Map;
|
|
3831
4378
|
let isMonorepo = false;
|
|
3832
4379
|
try {
|
|
3833
|
-
const entries = await
|
|
4380
|
+
const entries = await fs5.readdir(rootDir, { withFileTypes: true });
|
|
3834
4381
|
const dirNames = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
3835
4382
|
const monorepoPatterns = ["apps", "packages", "libs", "services"];
|
|
3836
4383
|
const hasMonorepoStructure = monorepoPatterns.some((p) => dirNames.includes(p));
|
|
@@ -3839,9 +4386,9 @@ async function detectProjectStructure(rootDir) {
|
|
|
3839
4386
|
for (const pattern of monorepoPatterns) {
|
|
3840
4387
|
if (!dirNames.includes(pattern))
|
|
3841
4388
|
continue;
|
|
3842
|
-
const patternDir =
|
|
4389
|
+
const patternDir = path13.join(rootDir, pattern);
|
|
3843
4390
|
try {
|
|
3844
|
-
const subDirs = await
|
|
4391
|
+
const subDirs = await fs5.readdir(patternDir, { withFileTypes: true });
|
|
3845
4392
|
for (const subDir of subDirs) {
|
|
3846
4393
|
if (!subDir.isDirectory())
|
|
3847
4394
|
continue;
|
|
@@ -3870,8 +4417,8 @@ async function detectProjectStructure(rootDir) {
|
|
|
3870
4417
|
}
|
|
3871
4418
|
let rootType = "unknown";
|
|
3872
4419
|
try {
|
|
3873
|
-
const rootPkgPath =
|
|
3874
|
-
const rootPkg = JSON.parse(await
|
|
4420
|
+
const rootPkgPath = path13.join(rootDir, "package.json");
|
|
4421
|
+
const rootPkg = JSON.parse(await fs5.readFile(rootPkgPath, "utf-8"));
|
|
3875
4422
|
if (rootPkg.workspaces)
|
|
3876
4423
|
isMonorepo = true;
|
|
3877
4424
|
const deps = { ...rootPkg.dependencies, ...rootPkg.devDependencies };
|
|
@@ -3911,8 +4458,8 @@ class IntrospectionIndex {
|
|
|
3911
4458
|
async initialize() {
|
|
3912
4459
|
this.structure = await detectProjectStructure(this.rootDir);
|
|
3913
4460
|
try {
|
|
3914
|
-
const configPath =
|
|
3915
|
-
const configContent = await
|
|
4461
|
+
const configPath = path14.join(this.rootDir, ".raggrep", "config.json");
|
|
4462
|
+
const configContent = await fs6.readFile(configPath, "utf-8");
|
|
3916
4463
|
const config = JSON.parse(configContent);
|
|
3917
4464
|
this.config = config.introspection || {};
|
|
3918
4465
|
} catch {}
|
|
@@ -3951,28 +4498,28 @@ class IntrospectionIndex {
|
|
|
3951
4498
|
}
|
|
3952
4499
|
}
|
|
3953
4500
|
async save(config) {
|
|
3954
|
-
const introDir =
|
|
3955
|
-
await
|
|
3956
|
-
const projectPath =
|
|
3957
|
-
await
|
|
4501
|
+
const introDir = path14.join(getRaggrepDir(this.rootDir, config), "introspection");
|
|
4502
|
+
await fs6.mkdir(introDir, { recursive: true });
|
|
4503
|
+
const projectPath = path14.join(introDir, "_project.json");
|
|
4504
|
+
await fs6.writeFile(projectPath, JSON.stringify({
|
|
3958
4505
|
version: "1.0.0",
|
|
3959
4506
|
lastUpdated: new Date().toISOString(),
|
|
3960
4507
|
structure: this.structure
|
|
3961
4508
|
}, null, 2));
|
|
3962
4509
|
for (const [filepath, intro] of this.files) {
|
|
3963
|
-
const introFilePath =
|
|
3964
|
-
await
|
|
3965
|
-
await
|
|
4510
|
+
const introFilePath = path14.join(introDir, "files", filepath.replace(/\.[^.]+$/, ".json"));
|
|
4511
|
+
await fs6.mkdir(path14.dirname(introFilePath), { recursive: true });
|
|
4512
|
+
await fs6.writeFile(introFilePath, JSON.stringify(intro, null, 2));
|
|
3966
4513
|
}
|
|
3967
4514
|
}
|
|
3968
4515
|
async load(config) {
|
|
3969
|
-
const introDir =
|
|
4516
|
+
const introDir = path14.join(getRaggrepDir(this.rootDir, config), "introspection");
|
|
3970
4517
|
try {
|
|
3971
|
-
const projectPath =
|
|
3972
|
-
const projectContent = await
|
|
4518
|
+
const projectPath = path14.join(introDir, "_project.json");
|
|
4519
|
+
const projectContent = await fs6.readFile(projectPath, "utf-8");
|
|
3973
4520
|
const projectData = JSON.parse(projectContent);
|
|
3974
4521
|
this.structure = projectData.structure;
|
|
3975
|
-
await this.loadFilesRecursive(
|
|
4522
|
+
await this.loadFilesRecursive(path14.join(introDir, "files"), "");
|
|
3976
4523
|
} catch {
|
|
3977
4524
|
this.structure = null;
|
|
3978
4525
|
this.files.clear();
|
|
@@ -3980,14 +4527,14 @@ class IntrospectionIndex {
|
|
|
3980
4527
|
}
|
|
3981
4528
|
async loadFilesRecursive(basePath, prefix) {
|
|
3982
4529
|
try {
|
|
3983
|
-
const entries = await
|
|
4530
|
+
const entries = await fs6.readdir(basePath, { withFileTypes: true });
|
|
3984
4531
|
for (const entry of entries) {
|
|
3985
|
-
const entryPath =
|
|
4532
|
+
const entryPath = path14.join(basePath, entry.name);
|
|
3986
4533
|
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
3987
4534
|
if (entry.isDirectory()) {
|
|
3988
4535
|
await this.loadFilesRecursive(entryPath, relativePath);
|
|
3989
4536
|
} else if (entry.name.endsWith(".json")) {
|
|
3990
|
-
const content = await
|
|
4537
|
+
const content = await fs6.readFile(entryPath, "utf-8");
|
|
3991
4538
|
const intro = JSON.parse(content);
|
|
3992
4539
|
this.files.set(intro.filepath, intro);
|
|
3993
4540
|
}
|
|
@@ -4133,7 +4680,7 @@ async function indexDirectory(rootDir, options = {}) {
|
|
|
4133
4680
|
const quiet = options.quiet ?? false;
|
|
4134
4681
|
const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
|
|
4135
4682
|
const logger = options.logger ? options.logger : quiet ? createSilentLogger() : createLogger({ verbose });
|
|
4136
|
-
rootDir =
|
|
4683
|
+
rootDir = path15.resolve(rootDir);
|
|
4137
4684
|
const location = getIndexLocation(rootDir);
|
|
4138
4685
|
logger.info(`Indexing directory: ${rootDir}`);
|
|
4139
4686
|
logger.info(`Index location: ${location.indexDir}`);
|
|
@@ -4185,12 +4732,12 @@ async function indexDirectory(rootDir, options = {}) {
|
|
|
4185
4732
|
rootDir,
|
|
4186
4733
|
config,
|
|
4187
4734
|
readFile: async (filepath) => {
|
|
4188
|
-
const fullPath =
|
|
4189
|
-
return
|
|
4735
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
4736
|
+
return fs7.readFile(fullPath, "utf-8");
|
|
4190
4737
|
},
|
|
4191
4738
|
getFileStats: async (filepath) => {
|
|
4192
|
-
const fullPath =
|
|
4193
|
-
const stats = await
|
|
4739
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
4740
|
+
const stats = await fs7.stat(fullPath);
|
|
4194
4741
|
return { lastModified: stats.mtime.toISOString() };
|
|
4195
4742
|
}
|
|
4196
4743
|
};
|
|
@@ -4215,7 +4762,7 @@ async function isIndexVersionCompatible(rootDir) {
|
|
|
4215
4762
|
const config = await loadConfig(rootDir);
|
|
4216
4763
|
const globalManifestPath = getGlobalManifestPath(rootDir, config);
|
|
4217
4764
|
try {
|
|
4218
|
-
const content = await
|
|
4765
|
+
const content = await fs7.readFile(globalManifestPath, "utf-8");
|
|
4219
4766
|
const manifest = JSON.parse(content);
|
|
4220
4767
|
return manifest.version === INDEX_SCHEMA_VERSION;
|
|
4221
4768
|
} catch {
|
|
@@ -4225,11 +4772,11 @@ async function isIndexVersionCompatible(rootDir) {
|
|
|
4225
4772
|
async function deleteIndex(rootDir) {
|
|
4226
4773
|
const indexDir = getRaggrepDir(rootDir);
|
|
4227
4774
|
try {
|
|
4228
|
-
await
|
|
4775
|
+
await fs7.rm(indexDir, { recursive: true, force: true });
|
|
4229
4776
|
} catch {}
|
|
4230
4777
|
}
|
|
4231
4778
|
async function resetIndex(rootDir) {
|
|
4232
|
-
rootDir =
|
|
4779
|
+
rootDir = path15.resolve(rootDir);
|
|
4233
4780
|
const status = await getIndexStatus(rootDir);
|
|
4234
4781
|
if (!status.exists) {
|
|
4235
4782
|
throw new Error(`No index found for ${rootDir}`);
|
|
@@ -4244,7 +4791,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4244
4791
|
const verbose = options.verbose ?? false;
|
|
4245
4792
|
const quiet = options.quiet ?? false;
|
|
4246
4793
|
const logger = options.logger ? options.logger : quiet ? createSilentLogger() : createLogger({ verbose });
|
|
4247
|
-
rootDir =
|
|
4794
|
+
rootDir = path15.resolve(rootDir);
|
|
4248
4795
|
const status = await getIndexStatus(rootDir);
|
|
4249
4796
|
if (!status.exists) {
|
|
4250
4797
|
logger.info(`No index found. Creating index...
|
|
@@ -4271,7 +4818,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4271
4818
|
const introspection = new IntrospectionIndex(rootDir);
|
|
4272
4819
|
await introspection.initialize();
|
|
4273
4820
|
const currentFiles = await findFiles(rootDir, config);
|
|
4274
|
-
const currentFileSet = new Set(currentFiles.map((f) =>
|
|
4821
|
+
const currentFileSet = new Set(currentFiles.map((f) => path15.relative(rootDir, f)));
|
|
4275
4822
|
let totalIndexed = 0;
|
|
4276
4823
|
let totalRemoved = 0;
|
|
4277
4824
|
let totalUnchanged = 0;
|
|
@@ -4301,13 +4848,13 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4301
4848
|
}
|
|
4302
4849
|
for (const filepath of filesToRemove) {
|
|
4303
4850
|
logger.debug(` Removing stale: ${filepath}`);
|
|
4304
|
-
const indexFilePath =
|
|
4851
|
+
const indexFilePath = path15.join(indexPath, filepath.replace(/\.[^.]+$/, ".json"));
|
|
4305
4852
|
try {
|
|
4306
|
-
await
|
|
4853
|
+
await fs7.unlink(indexFilePath);
|
|
4307
4854
|
} catch {}
|
|
4308
|
-
const symbolicFilePath =
|
|
4855
|
+
const symbolicFilePath = path15.join(indexPath, "symbolic", filepath.replace(/\.[^.]+$/, ".json"));
|
|
4309
4856
|
try {
|
|
4310
|
-
await
|
|
4857
|
+
await fs7.unlink(symbolicFilePath);
|
|
4311
4858
|
} catch {}
|
|
4312
4859
|
delete manifest.files[filepath];
|
|
4313
4860
|
totalRemoved++;
|
|
@@ -4316,12 +4863,12 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4316
4863
|
rootDir,
|
|
4317
4864
|
config,
|
|
4318
4865
|
readFile: async (filepath) => {
|
|
4319
|
-
const fullPath =
|
|
4320
|
-
return
|
|
4866
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
4867
|
+
return fs7.readFile(fullPath, "utf-8");
|
|
4321
4868
|
},
|
|
4322
4869
|
getFileStats: async (filepath) => {
|
|
4323
|
-
const fullPath =
|
|
4324
|
-
const stats = await
|
|
4870
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
4871
|
+
const stats = await fs7.stat(fullPath);
|
|
4325
4872
|
return { lastModified: stats.mtime.toISOString() };
|
|
4326
4873
|
},
|
|
4327
4874
|
getIntrospection: (filepath) => introspection.getFile(filepath)
|
|
@@ -4329,10 +4876,10 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4329
4876
|
const totalFiles = currentFiles.length;
|
|
4330
4877
|
for (let i = 0;i < currentFiles.length; i++) {
|
|
4331
4878
|
const filepath = currentFiles[i];
|
|
4332
|
-
const relativePath =
|
|
4879
|
+
const relativePath = path15.relative(rootDir, filepath);
|
|
4333
4880
|
const progress = `[${i + 1}/${totalFiles}]`;
|
|
4334
4881
|
try {
|
|
4335
|
-
const stats = await
|
|
4882
|
+
const stats = await fs7.stat(filepath);
|
|
4336
4883
|
const lastModified = stats.mtime.toISOString();
|
|
4337
4884
|
const existingEntry = manifest.files[relativePath];
|
|
4338
4885
|
if (existingEntry && existingEntry.lastModified === lastModified) {
|
|
@@ -4340,7 +4887,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
4340
4887
|
continue;
|
|
4341
4888
|
}
|
|
4342
4889
|
logger.progress(` ${progress} Indexing: ${relativePath}`);
|
|
4343
|
-
const content = await
|
|
4890
|
+
const content = await fs7.readFile(filepath, "utf-8");
|
|
4344
4891
|
introspection.addFile(relativePath, content);
|
|
4345
4892
|
const fileIndex = await module.indexFile(relativePath, content, ctx);
|
|
4346
4893
|
if (fileIndex) {
|
|
@@ -4389,7 +4936,7 @@ async function indexWithModule(rootDir, files, module, config, verbose, introspe
|
|
|
4389
4936
|
};
|
|
4390
4937
|
const manifest = await loadModuleManifest(rootDir, module.id, config);
|
|
4391
4938
|
const indexPath = getModuleIndexPath(rootDir, module.id, config);
|
|
4392
|
-
const currentFileSet = new Set(files.map((f) =>
|
|
4939
|
+
const currentFileSet = new Set(files.map((f) => path15.relative(rootDir, f)));
|
|
4393
4940
|
const filesToRemove = [];
|
|
4394
4941
|
for (const filepath of Object.keys(manifest.files)) {
|
|
4395
4942
|
if (!currentFileSet.has(filepath)) {
|
|
@@ -4400,13 +4947,13 @@ async function indexWithModule(rootDir, files, module, config, verbose, introspe
|
|
|
4400
4947
|
logger.info(` Removing ${filesToRemove.length} stale entries...`);
|
|
4401
4948
|
for (const filepath of filesToRemove) {
|
|
4402
4949
|
logger.debug(` Removing: ${filepath}`);
|
|
4403
|
-
const indexFilePath =
|
|
4950
|
+
const indexFilePath = path15.join(indexPath, filepath.replace(/\.[^.]+$/, ".json"));
|
|
4404
4951
|
try {
|
|
4405
|
-
await
|
|
4952
|
+
await fs7.unlink(indexFilePath);
|
|
4406
4953
|
} catch {}
|
|
4407
|
-
const symbolicFilePath =
|
|
4954
|
+
const symbolicFilePath = path15.join(indexPath, "symbolic", filepath.replace(/\.[^.]+$/, ".json"));
|
|
4408
4955
|
try {
|
|
4409
|
-
await
|
|
4956
|
+
await fs7.unlink(symbolicFilePath);
|
|
4410
4957
|
} catch {}
|
|
4411
4958
|
delete manifest.files[filepath];
|
|
4412
4959
|
}
|
|
@@ -4416,12 +4963,12 @@ async function indexWithModule(rootDir, files, module, config, verbose, introspe
|
|
|
4416
4963
|
rootDir,
|
|
4417
4964
|
config,
|
|
4418
4965
|
readFile: async (filepath) => {
|
|
4419
|
-
const fullPath =
|
|
4420
|
-
return
|
|
4966
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
4967
|
+
return fs7.readFile(fullPath, "utf-8");
|
|
4421
4968
|
},
|
|
4422
4969
|
getFileStats: async (filepath) => {
|
|
4423
|
-
const fullPath =
|
|
4424
|
-
const stats = await
|
|
4970
|
+
const fullPath = path15.isAbsolute(filepath) ? filepath : path15.join(rootDir, filepath);
|
|
4971
|
+
const stats = await fs7.stat(fullPath);
|
|
4425
4972
|
return { lastModified: stats.mtime.toISOString() };
|
|
4426
4973
|
},
|
|
4427
4974
|
getIntrospection: (filepath) => introspection.getFile(filepath)
|
|
@@ -4429,9 +4976,9 @@ async function indexWithModule(rootDir, files, module, config, verbose, introspe
|
|
|
4429
4976
|
const totalFiles = files.length;
|
|
4430
4977
|
let completedCount = 0;
|
|
4431
4978
|
const processFile = async (filepath, _index) => {
|
|
4432
|
-
const relativePath =
|
|
4979
|
+
const relativePath = path15.relative(rootDir, filepath);
|
|
4433
4980
|
try {
|
|
4434
|
-
const stats = await
|
|
4981
|
+
const stats = await fs7.stat(filepath);
|
|
4435
4982
|
const lastModified = stats.mtime.toISOString();
|
|
4436
4983
|
const existingEntry = manifest.files[relativePath];
|
|
4437
4984
|
if (existingEntry && existingEntry.lastModified === lastModified) {
|
|
@@ -4439,7 +4986,7 @@ async function indexWithModule(rootDir, files, module, config, verbose, introspe
|
|
|
4439
4986
|
logger.debug(` [${completedCount}/${totalFiles}] Skipped ${relativePath} (unchanged)`);
|
|
4440
4987
|
return { relativePath, status: "skipped" };
|
|
4441
4988
|
}
|
|
4442
|
-
const content = await
|
|
4989
|
+
const content = await fs7.readFile(filepath, "utf-8");
|
|
4443
4990
|
introspection.addFile(relativePath, content);
|
|
4444
4991
|
completedCount++;
|
|
4445
4992
|
logger.progress(` [${completedCount}/${totalFiles}] Processing: ${relativePath}`);
|
|
@@ -4507,7 +5054,7 @@ async function findFiles(rootDir, config) {
|
|
|
4507
5054
|
async function loadModuleManifest(rootDir, moduleId, config) {
|
|
4508
5055
|
const manifestPath = getModuleManifestPath(rootDir, moduleId, config);
|
|
4509
5056
|
try {
|
|
4510
|
-
const content = await
|
|
5057
|
+
const content = await fs7.readFile(manifestPath, "utf-8");
|
|
4511
5058
|
return JSON.parse(content);
|
|
4512
5059
|
} catch {
|
|
4513
5060
|
return {
|
|
@@ -4520,14 +5067,14 @@ async function loadModuleManifest(rootDir, moduleId, config) {
|
|
|
4520
5067
|
}
|
|
4521
5068
|
async function writeModuleManifest(rootDir, moduleId, manifest, config) {
|
|
4522
5069
|
const manifestPath = getModuleManifestPath(rootDir, moduleId, config);
|
|
4523
|
-
await
|
|
4524
|
-
await
|
|
5070
|
+
await fs7.mkdir(path15.dirname(manifestPath), { recursive: true });
|
|
5071
|
+
await fs7.writeFile(manifestPath, JSON.stringify(manifest, null, 2));
|
|
4525
5072
|
}
|
|
4526
5073
|
async function writeFileIndex(rootDir, moduleId, filepath, fileIndex, config) {
|
|
4527
5074
|
const indexPath = getModuleIndexPath(rootDir, moduleId, config);
|
|
4528
|
-
const indexFilePath =
|
|
4529
|
-
await
|
|
4530
|
-
await
|
|
5075
|
+
const indexFilePath = path15.join(indexPath, filepath.replace(/\.[^.]+$/, ".json"));
|
|
5076
|
+
await fs7.mkdir(path15.dirname(indexFilePath), { recursive: true });
|
|
5077
|
+
await fs7.writeFile(indexFilePath, JSON.stringify(fileIndex, null, 2));
|
|
4531
5078
|
}
|
|
4532
5079
|
async function updateGlobalManifest(rootDir, modules, config) {
|
|
4533
5080
|
const manifestPath = getGlobalManifestPath(rootDir, config);
|
|
@@ -4536,13 +5083,13 @@ async function updateGlobalManifest(rootDir, modules, config) {
|
|
|
4536
5083
|
lastUpdated: new Date().toISOString(),
|
|
4537
5084
|
modules: modules.map((m) => m.id)
|
|
4538
5085
|
};
|
|
4539
|
-
await
|
|
4540
|
-
await
|
|
5086
|
+
await fs7.mkdir(path15.dirname(manifestPath), { recursive: true });
|
|
5087
|
+
await fs7.writeFile(manifestPath, JSON.stringify(manifest, null, 2));
|
|
4541
5088
|
}
|
|
4542
5089
|
async function cleanupIndex(rootDir, options = {}) {
|
|
4543
5090
|
const verbose = options.verbose ?? false;
|
|
4544
5091
|
const logger = options.logger ?? createLogger({ verbose });
|
|
4545
|
-
rootDir =
|
|
5092
|
+
rootDir = path15.resolve(rootDir);
|
|
4546
5093
|
logger.info(`Cleaning up index in: ${rootDir}`);
|
|
4547
5094
|
const config = await loadConfig(rootDir);
|
|
4548
5095
|
await registerBuiltInModules();
|
|
@@ -4572,9 +5119,9 @@ async function cleanupModuleIndex(rootDir, moduleId, config, logger) {
|
|
|
4572
5119
|
const filesToRemove = [];
|
|
4573
5120
|
const updatedFiles = {};
|
|
4574
5121
|
for (const [filepath, entry] of Object.entries(manifest.files)) {
|
|
4575
|
-
const fullPath =
|
|
5122
|
+
const fullPath = path15.join(rootDir, filepath);
|
|
4576
5123
|
try {
|
|
4577
|
-
await
|
|
5124
|
+
await fs7.access(fullPath);
|
|
4578
5125
|
updatedFiles[filepath] = entry;
|
|
4579
5126
|
result.kept++;
|
|
4580
5127
|
} catch {
|
|
@@ -4584,9 +5131,9 @@ async function cleanupModuleIndex(rootDir, moduleId, config, logger) {
|
|
|
4584
5131
|
}
|
|
4585
5132
|
}
|
|
4586
5133
|
for (const filepath of filesToRemove) {
|
|
4587
|
-
const indexFilePath =
|
|
5134
|
+
const indexFilePath = path15.join(indexPath, filepath.replace(/\.[^.]+$/, ".json"));
|
|
4588
5135
|
try {
|
|
4589
|
-
await
|
|
5136
|
+
await fs7.unlink(indexFilePath);
|
|
4590
5137
|
} catch {}
|
|
4591
5138
|
}
|
|
4592
5139
|
manifest.files = updatedFiles;
|
|
@@ -4597,16 +5144,16 @@ async function cleanupModuleIndex(rootDir, moduleId, config, logger) {
|
|
|
4597
5144
|
}
|
|
4598
5145
|
async function cleanupEmptyDirectories(dir) {
|
|
4599
5146
|
try {
|
|
4600
|
-
const entries = await
|
|
5147
|
+
const entries = await fs7.readdir(dir, { withFileTypes: true });
|
|
4601
5148
|
for (const entry of entries) {
|
|
4602
5149
|
if (entry.isDirectory()) {
|
|
4603
|
-
const subDir =
|
|
5150
|
+
const subDir = path15.join(dir, entry.name);
|
|
4604
5151
|
await cleanupEmptyDirectories(subDir);
|
|
4605
5152
|
}
|
|
4606
5153
|
}
|
|
4607
|
-
const remainingEntries = await
|
|
5154
|
+
const remainingEntries = await fs7.readdir(dir);
|
|
4608
5155
|
if (remainingEntries.length === 0) {
|
|
4609
|
-
await
|
|
5156
|
+
await fs7.rmdir(dir);
|
|
4610
5157
|
return true;
|
|
4611
5158
|
}
|
|
4612
5159
|
return false;
|
|
@@ -4615,7 +5162,7 @@ async function cleanupEmptyDirectories(dir) {
|
|
|
4615
5162
|
}
|
|
4616
5163
|
}
|
|
4617
5164
|
async function getIndexStatus(rootDir) {
|
|
4618
|
-
rootDir =
|
|
5165
|
+
rootDir = path15.resolve(rootDir);
|
|
4619
5166
|
const config = await loadConfig(rootDir);
|
|
4620
5167
|
const location = getIndexLocation(rootDir);
|
|
4621
5168
|
const indexDir = location.indexDir;
|
|
@@ -4627,13 +5174,13 @@ async function getIndexStatus(rootDir) {
|
|
|
4627
5174
|
totalFiles: 0
|
|
4628
5175
|
};
|
|
4629
5176
|
try {
|
|
4630
|
-
await
|
|
5177
|
+
await fs7.access(indexDir);
|
|
4631
5178
|
} catch {
|
|
4632
5179
|
return status;
|
|
4633
5180
|
}
|
|
4634
5181
|
try {
|
|
4635
5182
|
const globalManifestPath = getGlobalManifestPath(rootDir, config);
|
|
4636
|
-
const content = await
|
|
5183
|
+
const content = await fs7.readFile(globalManifestPath, "utf-8");
|
|
4637
5184
|
const globalManifest = JSON.parse(content);
|
|
4638
5185
|
status.exists = true;
|
|
4639
5186
|
status.lastUpdated = globalManifest.lastUpdated;
|
|
@@ -4651,7 +5198,7 @@ async function getIndexStatus(rootDir) {
|
|
|
4651
5198
|
}
|
|
4652
5199
|
} catch {
|
|
4653
5200
|
try {
|
|
4654
|
-
const entries = await
|
|
5201
|
+
const entries = await fs7.readdir(path15.join(indexDir, "index"));
|
|
4655
5202
|
if (entries.length > 0) {
|
|
4656
5203
|
status.exists = true;
|
|
4657
5204
|
for (const entry of entries) {
|
|
@@ -4673,8 +5220,8 @@ async function getIndexStatus(rootDir) {
|
|
|
4673
5220
|
}
|
|
4674
5221
|
|
|
4675
5222
|
// src/app/search/index.ts
|
|
4676
|
-
import * as
|
|
4677
|
-
import * as
|
|
5223
|
+
import * as fs8 from "fs/promises";
|
|
5224
|
+
import * as path16 from "path";
|
|
4678
5225
|
|
|
4679
5226
|
// src/types.ts
|
|
4680
5227
|
init_entities();
|
|
@@ -4682,7 +5229,7 @@ init_entities();
|
|
|
4682
5229
|
// src/app/search/index.ts
|
|
4683
5230
|
init_config2();
|
|
4684
5231
|
async function search(rootDir, query, options = {}) {
|
|
4685
|
-
rootDir =
|
|
5232
|
+
rootDir = path16.resolve(rootDir);
|
|
4686
5233
|
const ensureFresh = options.ensureFresh ?? DEFAULT_SEARCH_OPTIONS.ensureFresh;
|
|
4687
5234
|
if (ensureFresh) {
|
|
4688
5235
|
await ensureIndexFresh(rootDir, { quiet: true });
|
|
@@ -4735,9 +5282,9 @@ function createSearchContext(rootDir, moduleId, config) {
|
|
|
4735
5282
|
config,
|
|
4736
5283
|
loadFileIndex: async (filepath) => {
|
|
4737
5284
|
const hasExtension = /\.[^./]+$/.test(filepath);
|
|
4738
|
-
const indexFilePath = hasExtension ?
|
|
5285
|
+
const indexFilePath = hasExtension ? path16.join(indexPath, filepath.replace(/\.[^.]+$/, ".json")) : path16.join(indexPath, filepath + ".json");
|
|
4739
5286
|
try {
|
|
4740
|
-
const content = await
|
|
5287
|
+
const content = await fs8.readFile(indexFilePath, "utf-8");
|
|
4741
5288
|
return JSON.parse(content);
|
|
4742
5289
|
} catch {
|
|
4743
5290
|
return null;
|
|
@@ -4747,7 +5294,7 @@ function createSearchContext(rootDir, moduleId, config) {
|
|
|
4747
5294
|
const files = [];
|
|
4748
5295
|
await traverseDirectory(indexPath, files, indexPath);
|
|
4749
5296
|
return files.filter((f) => f.endsWith(".json") && !f.endsWith("manifest.json")).map((f) => {
|
|
4750
|
-
const relative3 =
|
|
5297
|
+
const relative3 = path16.relative(indexPath, f);
|
|
4751
5298
|
return relative3.replace(/\.json$/, "");
|
|
4752
5299
|
});
|
|
4753
5300
|
}
|
|
@@ -4755,9 +5302,9 @@ function createSearchContext(rootDir, moduleId, config) {
|
|
|
4755
5302
|
}
|
|
4756
5303
|
async function traverseDirectory(dir, files, basePath) {
|
|
4757
5304
|
try {
|
|
4758
|
-
const entries = await
|
|
5305
|
+
const entries = await fs8.readdir(dir, { withFileTypes: true });
|
|
4759
5306
|
for (const entry of entries) {
|
|
4760
|
-
const fullPath =
|
|
5307
|
+
const fullPath = path16.join(dir, entry.name);
|
|
4761
5308
|
if (entry.isDirectory()) {
|
|
4762
5309
|
await traverseDirectory(fullPath, files, basePath);
|
|
4763
5310
|
} else if (entry.isFile()) {
|
|
@@ -4769,7 +5316,7 @@ async function traverseDirectory(dir, files, basePath) {
|
|
|
4769
5316
|
async function loadGlobalManifest(rootDir, config) {
|
|
4770
5317
|
const manifestPath = getGlobalManifestPath(rootDir, config);
|
|
4771
5318
|
try {
|
|
4772
|
-
const content = await
|
|
5319
|
+
const content = await fs8.readFile(manifestPath, "utf-8");
|
|
4773
5320
|
return JSON.parse(content);
|
|
4774
5321
|
} catch {
|
|
4775
5322
|
return null;
|
|
@@ -4859,4 +5406,4 @@ export {
|
|
|
4859
5406
|
ConsoleLogger
|
|
4860
5407
|
};
|
|
4861
5408
|
|
|
4862
|
-
//# debugId=
|
|
5409
|
+
//# debugId=8F3468BC25F1B30164756E2164756E21
|