aidex-graphra 1.0.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/LICENSE +21 -0
- package/README.md +463 -0
- package/dist/chunker.d.ts +3 -0
- package/dist/chunker.d.ts.map +1 -0
- package/dist/chunker.js +116 -0
- package/dist/chunker.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +821 -0
- package/dist/cli.js.map +1 -0
- package/dist/graph.d.ts +9 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +97 -0
- package/dist/graph.js.map +1 -0
- package/dist/init.d.ts +27 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +306 -0
- package/dist/init.js.map +1 -0
- package/dist/mcp.d.ts +13 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +19 -0
- package/dist/mcp.js.map +1 -0
- package/dist/mcpServer.d.ts +14 -0
- package/dist/mcpServer.d.ts.map +1 -0
- package/dist/mcpServer.js +373 -0
- package/dist/mcpServer.js.map +1 -0
- package/dist/neuralEmbedder.d.ts +21 -0
- package/dist/neuralEmbedder.d.ts.map +1 -0
- package/dist/neuralEmbedder.js +98 -0
- package/dist/neuralEmbedder.js.map +1 -0
- package/dist/scanner.d.ts +3 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +43 -0
- package/dist/scanner.js.map +1 -0
- package/dist/search.d.ts +37 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +252 -0
- package/dist/search.js.map +1 -0
- package/dist/signatureExtractor.d.ts +25 -0
- package/dist/signatureExtractor.d.ts.map +1 -0
- package/dist/signatureExtractor.js +173 -0
- package/dist/signatureExtractor.js.map +1 -0
- package/dist/storage.d.ts +59 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +322 -0
- package/dist/storage.js.map +1 -0
- package/dist/tokenBudget.d.ts +52 -0
- package/dist/tokenBudget.d.ts.map +1 -0
- package/dist/tokenBudget.js +175 -0
- package/dist/tokenBudget.js.map +1 -0
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/hash.d.ts +6 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +45 -0
- package/dist/utils/hash.js.map +1 -0
- package/package.json +69 -0
package/dist/search.js
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hybrid Search Engine — combines:
|
|
4
|
+
* 1. Neural embeddings (TransformersJS all-MiniLM-L6-v2) for semantic search
|
|
5
|
+
* 2. BM25 full-text search for exact keyword matching
|
|
6
|
+
* 3. PageRank importance scores from the dependency graph
|
|
7
|
+
*
|
|
8
|
+
* All 100% local, zero API keys.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.computePageRank = computePageRank;
|
|
12
|
+
exports.getGitRecencyScores = getGitRecencyScores;
|
|
13
|
+
exports.hybridSearch = hybridSearch;
|
|
14
|
+
const storage_1 = require("./storage");
|
|
15
|
+
// ============================================
|
|
16
|
+
// BM25 Full-Text Search
|
|
17
|
+
// ============================================
|
|
18
|
+
const STOP_WORDS = new Set([
|
|
19
|
+
"a", "an", "the", "is", "are", "was", "were", "be", "been", "being",
|
|
20
|
+
"have", "has", "had", "do", "does", "did", "will", "would", "could",
|
|
21
|
+
"should", "may", "might", "shall", "can", "need", "to", "of", "in",
|
|
22
|
+
"for", "on", "with", "at", "by", "from", "as", "into", "through",
|
|
23
|
+
"during", "before", "after", "between", "out", "off", "over", "under",
|
|
24
|
+
"again", "then", "once", "here", "there", "when", "where", "why", "how",
|
|
25
|
+
"all", "each", "every", "both", "few", "more", "most", "other", "some",
|
|
26
|
+
"no", "nor", "not", "only", "so", "than", "too", "very", "just",
|
|
27
|
+
"because", "but", "and", "or", "if", "while", "that", "this", "it",
|
|
28
|
+
"its", "which", "what", "who", "whom", "these", "those",
|
|
29
|
+
]);
|
|
30
|
+
/** Tokenize text for BM25 — split camelCase, lowercase, remove stopwords */
|
|
31
|
+
function tokenize(text) {
|
|
32
|
+
return text
|
|
33
|
+
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
34
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2")
|
|
35
|
+
.toLowerCase()
|
|
36
|
+
.replace(/[^a-z0-9]/g, " ")
|
|
37
|
+
.split(/\s+/)
|
|
38
|
+
.filter((t) => t.length > 1 && !STOP_WORDS.has(t));
|
|
39
|
+
}
|
|
40
|
+
/** BM25 scoring parameters */
|
|
41
|
+
const BM25_K1 = 1.2;
|
|
42
|
+
const BM25_B = 0.75;
|
|
43
|
+
/** Compute BM25 scores for a query against a set of documents */
|
|
44
|
+
function bm25Search(queryTokens, docs, topK) {
|
|
45
|
+
const N = docs.length;
|
|
46
|
+
const avgDl = docs.reduce((sum, d) => sum + d.length, 0) / (N || 1);
|
|
47
|
+
// Document frequency for each term
|
|
48
|
+
const df = new Map();
|
|
49
|
+
for (const doc of docs) {
|
|
50
|
+
const uniqueTerms = new Set(doc.tokens);
|
|
51
|
+
for (const term of uniqueTerms) {
|
|
52
|
+
df.set(term, (df.get(term) ?? 0) + 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Score each document
|
|
56
|
+
const scores = new Map();
|
|
57
|
+
for (const doc of docs) {
|
|
58
|
+
let score = 0;
|
|
59
|
+
const termFreq = new Map();
|
|
60
|
+
for (const t of doc.tokens) {
|
|
61
|
+
termFreq.set(t, (termFreq.get(t) ?? 0) + 1);
|
|
62
|
+
}
|
|
63
|
+
for (const qt of queryTokens) {
|
|
64
|
+
const tf = termFreq.get(qt) ?? 0;
|
|
65
|
+
if (tf === 0)
|
|
66
|
+
continue;
|
|
67
|
+
const docFreq = df.get(qt) ?? 0;
|
|
68
|
+
const idf = Math.log((N - docFreq + 0.5) / (docFreq + 0.5) + 1);
|
|
69
|
+
const tfNorm = (tf * (BM25_K1 + 1)) / (tf + BM25_K1 * (1 - BM25_B + BM25_B * (doc.length / avgDl)));
|
|
70
|
+
score += idf * tfNorm;
|
|
71
|
+
}
|
|
72
|
+
if (score > 0) {
|
|
73
|
+
scores.set(doc.id, score);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return scores;
|
|
77
|
+
}
|
|
78
|
+
// ============================================
|
|
79
|
+
// PageRank Importance
|
|
80
|
+
// ============================================
|
|
81
|
+
/**
|
|
82
|
+
* Compute PageRank scores for files in the dependency graph.
|
|
83
|
+
* Files that are imported by many other files get higher scores.
|
|
84
|
+
*/
|
|
85
|
+
function computePageRank(graph, damping = 0.85, iterations = 20) {
|
|
86
|
+
const files = new Set();
|
|
87
|
+
for (const [src, targets] of Object.entries(graph)) {
|
|
88
|
+
files.add(src);
|
|
89
|
+
for (const t of targets)
|
|
90
|
+
files.add(t);
|
|
91
|
+
}
|
|
92
|
+
const N = files.size;
|
|
93
|
+
if (N === 0)
|
|
94
|
+
return new Map();
|
|
95
|
+
// Initialize scores
|
|
96
|
+
const scores = new Map();
|
|
97
|
+
for (const f of files)
|
|
98
|
+
scores.set(f, 1 / N);
|
|
99
|
+
// Build reverse graph (who imports this file?)
|
|
100
|
+
const reverseGraph = new Map();
|
|
101
|
+
for (const f of files)
|
|
102
|
+
reverseGraph.set(f, []);
|
|
103
|
+
for (const [src, targets] of Object.entries(graph)) {
|
|
104
|
+
for (const t of targets) {
|
|
105
|
+
reverseGraph.get(t)?.push(src);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Outgoing link count
|
|
109
|
+
const outCount = new Map();
|
|
110
|
+
for (const [src, targets] of Object.entries(graph)) {
|
|
111
|
+
outCount.set(src, targets.length);
|
|
112
|
+
}
|
|
113
|
+
// Iterate
|
|
114
|
+
for (let i = 0; i < iterations; i++) {
|
|
115
|
+
const newScores = new Map();
|
|
116
|
+
for (const f of files) {
|
|
117
|
+
let sum = 0;
|
|
118
|
+
for (const src of reverseGraph.get(f) ?? []) {
|
|
119
|
+
sum += (scores.get(src) ?? 0) / (outCount.get(src) ?? 1);
|
|
120
|
+
}
|
|
121
|
+
newScores.set(f, (1 - damping) / N + damping * sum);
|
|
122
|
+
}
|
|
123
|
+
for (const [f, s] of newScores)
|
|
124
|
+
scores.set(f, s);
|
|
125
|
+
}
|
|
126
|
+
return scores;
|
|
127
|
+
}
|
|
128
|
+
// ============================================
|
|
129
|
+
// Cosine Similarity
|
|
130
|
+
// ============================================
|
|
131
|
+
function cosineSimilarity(a, b) {
|
|
132
|
+
if (a.length !== b.length || a.length === 0)
|
|
133
|
+
return 0;
|
|
134
|
+
let dot = 0, normA = 0, normB = 0;
|
|
135
|
+
for (let i = 0; i < a.length; i++) {
|
|
136
|
+
dot += a[i] * b[i];
|
|
137
|
+
normA += a[i] * a[i];
|
|
138
|
+
normB += b[i] * b[i];
|
|
139
|
+
}
|
|
140
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
141
|
+
return denom === 0 ? 0 : dot / denom;
|
|
142
|
+
}
|
|
143
|
+
// ============================================
|
|
144
|
+
// Git Recency Scoring
|
|
145
|
+
// ============================================
|
|
146
|
+
/**
|
|
147
|
+
* Get git recency scores for files — recently modified files rank higher.
|
|
148
|
+
* Uses `git log` to get last commit timestamp per file.
|
|
149
|
+
*/
|
|
150
|
+
function getGitRecencyScores(files) {
|
|
151
|
+
const scores = new Map();
|
|
152
|
+
try {
|
|
153
|
+
const { execSync } = require("child_process");
|
|
154
|
+
// Get last commit time for each tracked file
|
|
155
|
+
const output = execSync('git log --format="%at %H" --name-only --diff-filter=ACMR -n 200', { encoding: "utf-8", timeout: 5000, stdio: ["pipe", "pipe", "pipe"] });
|
|
156
|
+
const now = Date.now() / 1000;
|
|
157
|
+
const lines = output.split("\n");
|
|
158
|
+
let currentTimestamp = 0;
|
|
159
|
+
for (const line of lines) {
|
|
160
|
+
const tsMatch = line.match(/^(\d+)\s+[a-f0-9]+$/);
|
|
161
|
+
if (tsMatch) {
|
|
162
|
+
currentTimestamp = parseInt(tsMatch[1]);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const filePath = line.trim();
|
|
166
|
+
if (filePath && currentTimestamp && !scores.has(filePath)) {
|
|
167
|
+
// Decay: files modified recently get higher scores
|
|
168
|
+
// Score = 1.0 for today, ~0.5 for 7 days ago, ~0.1 for 30 days ago
|
|
169
|
+
const ageInDays = (now - currentTimestamp) / 86400;
|
|
170
|
+
const recency = Math.exp(-ageInDays / 10); // exponential decay, half-life ~7 days
|
|
171
|
+
scores.set(filePath, recency);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// Git not available or not a git repo — skip recency
|
|
177
|
+
}
|
|
178
|
+
return scores;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Hybrid search combining BM25 + neural embeddings + PageRank.
|
|
182
|
+
*
|
|
183
|
+
* @param query - The search query
|
|
184
|
+
* @param queryEmbedding - Pre-computed embedding for the query (or null to skip)
|
|
185
|
+
* @param graph - Dependency graph for PageRank
|
|
186
|
+
* @param options - Tuning parameters
|
|
187
|
+
*/
|
|
188
|
+
function hybridSearch(query, queryEmbedding, graph, options = {}) {
|
|
189
|
+
const { topK = 10, bm25Weight = 0.30, embeddingWeight = 0.40, pageRankWeight = 0.10, nameBoost = 0.10, gitRecencyWeight = 0.10, } = options;
|
|
190
|
+
const chunks = (0, storage_1.getAllChunks)();
|
|
191
|
+
if (chunks.length === 0)
|
|
192
|
+
return [];
|
|
193
|
+
const embeddings = (0, storage_1.getAllEmbeddings)();
|
|
194
|
+
const pageRankScores = computePageRank(graph);
|
|
195
|
+
const gitScores = getGitRecencyScores(chunks.map((c) => c.file));
|
|
196
|
+
// --- BM25 ---
|
|
197
|
+
const queryTokens = tokenize(query);
|
|
198
|
+
const bm25Docs = chunks.map((c) => {
|
|
199
|
+
const text = `${c.name} ${c.signature} ${c.summary}`;
|
|
200
|
+
const tokens = tokenize(text);
|
|
201
|
+
return { id: c.id, tokens, length: tokens.length };
|
|
202
|
+
});
|
|
203
|
+
const bm25Scores = bm25Search(queryTokens, bm25Docs, topK * 3);
|
|
204
|
+
// Normalize BM25 scores to 0-1
|
|
205
|
+
const maxBm25 = Math.max(...Array.from(bm25Scores.values()), 0.001);
|
|
206
|
+
// --- Combine scores ---
|
|
207
|
+
const finalScores = [];
|
|
208
|
+
for (const chunk of chunks) {
|
|
209
|
+
let score = 0;
|
|
210
|
+
// BM25 component
|
|
211
|
+
const bm25 = (bm25Scores.get(chunk.id) ?? 0) / maxBm25;
|
|
212
|
+
score += bm25 * bm25Weight;
|
|
213
|
+
// Embedding component
|
|
214
|
+
if (queryEmbedding && embeddings.has(chunk.id)) {
|
|
215
|
+
const chunkEmb = embeddings.get(chunk.id);
|
|
216
|
+
const sim = cosineSimilarity(queryEmbedding, chunkEmb);
|
|
217
|
+
score += sim * embeddingWeight;
|
|
218
|
+
}
|
|
219
|
+
// PageRank component (file-level importance)
|
|
220
|
+
const fileRank = pageRankScores.get(chunk.file) ?? 0;
|
|
221
|
+
const maxRank = Math.max(...Array.from(pageRankScores.values()), 0.001);
|
|
222
|
+
score += (fileRank / maxRank) * pageRankWeight;
|
|
223
|
+
// Git recency component
|
|
224
|
+
// Try matching by relative path fragments
|
|
225
|
+
const fileShort = chunk.file.replace(/\\/g, "/");
|
|
226
|
+
let gitRecency = 0;
|
|
227
|
+
for (const [gitFile, recency] of gitScores) {
|
|
228
|
+
if (fileShort.endsWith(gitFile) || gitFile.endsWith(fileShort.split("/").slice(-2).join("/"))) {
|
|
229
|
+
gitRecency = recency;
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
score += gitRecency * gitRecencyWeight;
|
|
234
|
+
// Name match boost
|
|
235
|
+
const nameParts = chunk.name
|
|
236
|
+
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
237
|
+
.replace(/\./g, " ")
|
|
238
|
+
.toLowerCase()
|
|
239
|
+
.split(/\s+/);
|
|
240
|
+
for (const qt of queryTokens) {
|
|
241
|
+
if (nameParts.some((np) => np === qt || np.includes(qt))) {
|
|
242
|
+
score += nameBoost;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (score > 0) {
|
|
246
|
+
finalScores.push({ chunk: chunk, score });
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
finalScores.sort((a, b) => b.score - a.score);
|
|
250
|
+
return finalScores.slice(0, topK);
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAiGH,0CA+CC;AAuCD,kDAiCC;AAUD,oCAuFC;AAtTD,uCAAkE;AAElE,+CAA+C;AAC/C,wBAAwB;AACxB,+CAA+C;AAE/C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO;IACnE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACnE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS;IAChE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO;IACrE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK;IACvE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IACtE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM;IAC/D,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI;IAClE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;CACxD,CAAC,CAAC;AAEH,4EAA4E;AAC5E,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI;SACR,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC;SACzC,WAAW,EAAE;SACb,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC;SAC1B,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,8BAA8B;AAC9B,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,MAAM,MAAM,GAAG,IAAI,CAAC;AAQpB,iEAAiE;AACjE,SAAS,UAAU,CACjB,WAAqB,EACrB,IAAe,EACf,IAAY;IAEZ,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACtB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpE,mCAAmC;IACnC,MAAM,EAAE,GAAG,IAAI,GAAG,EAAkB,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC3B,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;YAC7B,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,EAAE,KAAK,CAAC;gBAAE,SAAS;YAEvB,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAChE,MAAM,MAAM,GAAG,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAEpG,KAAK,IAAI,GAAG,GAAG,MAAM,CAAC;QACxB,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+CAA+C;AAC/C,sBAAsB;AACtB,+CAA+C;AAE/C;;;GAGG;AACH,SAAgB,eAAe,CAC7B,KAAsB,EACtB,UAAkB,IAAI,EACtB,aAAqB,EAAE;IAEvB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACf,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;IACrB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAE9B,oBAAoB;IACpB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAE5C,+CAA+C;IAC/C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAoB,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/C,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,UAAU;IACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC5C,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3D,CAAC;YACD,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,GAAG,GAAG,CAAC,CAAC;QACtD,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,SAAS;YAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+CAA+C;AAC/C,oBAAoB;AACpB,+CAA+C;AAE/C,SAAS,gBAAgB,CAAC,CAAW,EAAE,CAAW;IAChD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtD,IAAI,GAAG,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC;AACvC,CAAC;AAeD,+CAA+C;AAC/C,sBAAsB;AACtB,+CAA+C;AAE/C;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,KAAe;IACjD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;QAC9C,6CAA6C;QAC7C,MAAM,MAAM,GAAG,QAAQ,CACrB,iEAAiE,EACjE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CACtE,CAAC;QAEF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,gBAAgB,GAAG,CAAC,CAAC;QAEzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YAClD,IAAI,OAAO,EAAE,CAAC;gBACZ,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxC,SAAS;YACX,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,QAAQ,IAAI,gBAAgB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1D,mDAAmD;gBACnD,mEAAmE;gBACnE,MAAM,SAAS,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,GAAG,KAAK,CAAC;gBACnD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,uCAAuC;gBAClF,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,YAAY,CAC1B,KAAa,EACb,cAA+B,EAC/B,KAAsB,EACtB,UAA+B,EAAE;IAEjC,MAAM,EACJ,IAAI,GAAG,EAAE,EACT,UAAU,GAAG,IAAI,EACjB,eAAe,GAAG,IAAI,EACtB,cAAc,GAAG,IAAI,EACrB,SAAS,GAAG,IAAI,EAChB,gBAAgB,GAAG,IAAI,GACxB,GAAG,OAAO,CAAC;IAEZ,MAAM,MAAM,GAAG,IAAA,sBAAY,GAAE,CAAC;IAC9B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,UAAU,GAAG,IAAA,0BAAgB,GAAE,CAAC;IACtC,MAAM,cAAc,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjE,eAAe;IACf,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAc,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACrD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC9B,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;IAE/D,+BAA+B;IAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;IAEpE,yBAAyB;IACzB,MAAM,WAAW,GAAsC,EAAE,CAAC;IAE1D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,iBAAiB;QACjB,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC;QACvD,KAAK,IAAI,IAAI,GAAG,UAAU,CAAC;QAE3B,sBAAsB;QACtB,IAAI,cAAc,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/C,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAE,CAAC;YAC3C,MAAM,GAAG,GAAG,gBAAgB,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;YACvD,KAAK,IAAI,GAAG,GAAG,eAAe,CAAC;QACjC,CAAC;QAED,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QACxE,KAAK,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,cAAc,CAAC;QAE/C,wBAAwB;QACxB,0CAA0C;QAC1C,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACjD,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC;YAC3C,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC9F,UAAU,GAAG,OAAO,CAAC;gBACrB,MAAM;YACR,CAAC;QACH,CAAC;QACD,KAAK,IAAI,UAAU,GAAG,gBAAgB,CAAC;QAEvC,mBAAmB;QACnB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI;aACzB,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;aACnC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;aACnB,WAAW,EAAE;aACb,KAAK,CAAC,KAAK,CAAC,CAAC;QAChB,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;YAC7B,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBACzD,KAAK,IAAI,SAAS,CAAC;YACrB,CAAC;QACH,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAc,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signature Extractor — Aider-style approach.
|
|
3
|
+
*
|
|
4
|
+
* Instead of generating text summaries, we extract the ACTUAL code signature
|
|
5
|
+
* (function declaration line, class declaration, interface shape, etc.)
|
|
6
|
+
* This is what gets stored and shown to the AI — real code, not lossy summaries.
|
|
7
|
+
*/
|
|
8
|
+
import { Chunk } from "./types";
|
|
9
|
+
/**
|
|
10
|
+
* Extract the signature (declaration line) from a chunk's code.
|
|
11
|
+
* Returns the actual code line(s) that define the function/class/interface.
|
|
12
|
+
*
|
|
13
|
+
* Examples:
|
|
14
|
+
* "export async function ssoLogin(accessToken, newUser, session, sessionDetails, keepSessionActive) {"
|
|
15
|
+
* "class CronJobScheduler {"
|
|
16
|
+
* "interface ScanConfig { include: string[]; ignore: string[]; }"
|
|
17
|
+
*/
|
|
18
|
+
export declare function extractSignature(chunk: Chunk): string;
|
|
19
|
+
/**
|
|
20
|
+
* Build a compact text representation for embedding/search.
|
|
21
|
+
* Combines: file path + name + signature + JSDoc (if any) + body keywords.
|
|
22
|
+
* This is what gets embedded — NOT the full code.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildSearchableText(chunk: Chunk, signature: string): string;
|
|
25
|
+
//# sourceMappingURL=signatureExtractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signatureExtractor.d.ts","sourceRoot":"","sources":["../src/signatureExtractor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAuBrD;AAmID;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CA8B3E"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Signature Extractor — Aider-style approach.
|
|
4
|
+
*
|
|
5
|
+
* Instead of generating text summaries, we extract the ACTUAL code signature
|
|
6
|
+
* (function declaration line, class declaration, interface shape, etc.)
|
|
7
|
+
* This is what gets stored and shown to the AI — real code, not lossy summaries.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.extractSignature = extractSignature;
|
|
11
|
+
exports.buildSearchableText = buildSearchableText;
|
|
12
|
+
/**
|
|
13
|
+
* Extract the signature (declaration line) from a chunk's code.
|
|
14
|
+
* Returns the actual code line(s) that define the function/class/interface.
|
|
15
|
+
*
|
|
16
|
+
* Examples:
|
|
17
|
+
* "export async function ssoLogin(accessToken, newUser, session, sessionDetails, keepSessionActive) {"
|
|
18
|
+
* "class CronJobScheduler {"
|
|
19
|
+
* "interface ScanConfig { include: string[]; ignore: string[]; }"
|
|
20
|
+
*/
|
|
21
|
+
function extractSignature(chunk) {
|
|
22
|
+
const code = chunk.code;
|
|
23
|
+
const lines = code.split("\n");
|
|
24
|
+
switch (chunk.type) {
|
|
25
|
+
case "interface":
|
|
26
|
+
case "type-alias":
|
|
27
|
+
return extractInterfaceSignature(lines, chunk.name);
|
|
28
|
+
case "class":
|
|
29
|
+
return extractClassSignature(lines, chunk.name);
|
|
30
|
+
case "function":
|
|
31
|
+
case "method":
|
|
32
|
+
case "arrow-function":
|
|
33
|
+
return extractFunctionSignature(lines, chunk.name);
|
|
34
|
+
case "constant":
|
|
35
|
+
return extractConstantSignature(lines, chunk.name);
|
|
36
|
+
default:
|
|
37
|
+
return lines[0]?.trim() ?? chunk.name;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Extract function/method signature up to the opening brace */
|
|
41
|
+
function extractFunctionSignature(lines, name) {
|
|
42
|
+
// Skip JSDoc/comments
|
|
43
|
+
let start = 0;
|
|
44
|
+
while (start < lines.length &&
|
|
45
|
+
(lines[start].trim().startsWith("*") ||
|
|
46
|
+
lines[start].trim().startsWith("/**") ||
|
|
47
|
+
lines[start].trim().startsWith("//") ||
|
|
48
|
+
lines[start].trim().startsWith("/*") ||
|
|
49
|
+
lines[start].trim() === "")) {
|
|
50
|
+
start++;
|
|
51
|
+
}
|
|
52
|
+
// Collect lines until we hit the opening brace
|
|
53
|
+
let sig = "";
|
|
54
|
+
for (let i = start; i < lines.length && i < start + 10; i++) {
|
|
55
|
+
const line = lines[i].trim();
|
|
56
|
+
sig += (sig ? " " : "") + line;
|
|
57
|
+
if (line.includes("{")) {
|
|
58
|
+
// Remove everything after the opening brace
|
|
59
|
+
sig = sig.replace(/\s*\{[\s\S]*$/, "").trim();
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
if (line.includes("=>")) {
|
|
63
|
+
// Arrow function — keep up to =>
|
|
64
|
+
sig = sig.replace(/\s*=>[\s\S]*$/, " =>").trim();
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return sig || name;
|
|
69
|
+
}
|
|
70
|
+
/** Extract class signature (class name + constructor params if present) */
|
|
71
|
+
function extractClassSignature(lines, name) {
|
|
72
|
+
// Get the class declaration line
|
|
73
|
+
const classLine = lines.find((l) => /^\s*(?:export\s+)?class\s/.test(l));
|
|
74
|
+
if (!classLine)
|
|
75
|
+
return `class ${name}`;
|
|
76
|
+
let sig = classLine.trim();
|
|
77
|
+
if (sig.includes("{")) {
|
|
78
|
+
sig = sig.replace(/\s*\{.*$/, "").trim();
|
|
79
|
+
}
|
|
80
|
+
// Also extract method names for a compact overview
|
|
81
|
+
const methods = [];
|
|
82
|
+
for (const line of lines) {
|
|
83
|
+
// Match method declarations: " methodName(" or " async methodName("
|
|
84
|
+
const methodMatch = line.match(/^\s+(?:async\s+)?(\w+)\s*\(/);
|
|
85
|
+
if (methodMatch && methodMatch[1] !== "constructor") {
|
|
86
|
+
methods.push(methodMatch[1]);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (methods.length > 0) {
|
|
90
|
+
sig += ` { ${methods.join(", ")} }`;
|
|
91
|
+
}
|
|
92
|
+
return sig;
|
|
93
|
+
}
|
|
94
|
+
/** Extract interface/type signature with member names */
|
|
95
|
+
function extractInterfaceSignature(lines, name) {
|
|
96
|
+
// Get the declaration line
|
|
97
|
+
const declLine = lines.find((l) => /^\s*(?:export\s+)?(?:interface|type)\s/.test(l));
|
|
98
|
+
if (!declLine)
|
|
99
|
+
return `interface ${name}`;
|
|
100
|
+
// For short interfaces, return the whole thing (up to 200 chars)
|
|
101
|
+
const fullCode = lines.join("\n").trim();
|
|
102
|
+
if (fullCode.length <= 200) {
|
|
103
|
+
return fullCode;
|
|
104
|
+
}
|
|
105
|
+
// For longer ones, extract member names
|
|
106
|
+
const members = [];
|
|
107
|
+
for (const line of lines) {
|
|
108
|
+
const memberMatch = line.match(/^\s+(\w+)\s*[?]?\s*:/);
|
|
109
|
+
if (memberMatch) {
|
|
110
|
+
members.push(memberMatch[1]);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
let sig = declLine.trim();
|
|
114
|
+
if (sig.includes("{")) {
|
|
115
|
+
sig = sig.replace(/\s*\{.*$/, "").trim();
|
|
116
|
+
}
|
|
117
|
+
if (members.length > 0) {
|
|
118
|
+
sig += ` { ${members.join(", ")} }`;
|
|
119
|
+
}
|
|
120
|
+
return sig;
|
|
121
|
+
}
|
|
122
|
+
/** Extract constant signature */
|
|
123
|
+
function extractConstantSignature(lines, name) {
|
|
124
|
+
// Skip comments
|
|
125
|
+
let start = 0;
|
|
126
|
+
while (start < lines.length &&
|
|
127
|
+
(lines[start].trim().startsWith("*") ||
|
|
128
|
+
lines[start].trim().startsWith("/**") ||
|
|
129
|
+
lines[start].trim().startsWith("//") ||
|
|
130
|
+
lines[start].trim().startsWith("/*") ||
|
|
131
|
+
lines[start].trim() === "")) {
|
|
132
|
+
start++;
|
|
133
|
+
}
|
|
134
|
+
const line = lines[start]?.trim() ?? `const ${name}`;
|
|
135
|
+
// If it's a short one-liner, return it
|
|
136
|
+
if (line.length <= 150)
|
|
137
|
+
return line;
|
|
138
|
+
// Otherwise truncate
|
|
139
|
+
return line.slice(0, 150) + "...";
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Build a compact text representation for embedding/search.
|
|
143
|
+
* Combines: file path + name + signature + JSDoc (if any) + body keywords.
|
|
144
|
+
* This is what gets embedded — NOT the full code.
|
|
145
|
+
*/
|
|
146
|
+
function buildSearchableText(chunk, signature) {
|
|
147
|
+
const parts = [];
|
|
148
|
+
// File context (just the filename, not full path)
|
|
149
|
+
const fileName = chunk.file.split(/[/\\]/).pop() ?? "";
|
|
150
|
+
parts.push(fileName);
|
|
151
|
+
// Humanized name
|
|
152
|
+
const humanName = chunk.name
|
|
153
|
+
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
154
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2")
|
|
155
|
+
.replace(/\./g, " ")
|
|
156
|
+
.toLowerCase();
|
|
157
|
+
parts.push(humanName);
|
|
158
|
+
// Signature
|
|
159
|
+
parts.push(signature);
|
|
160
|
+
// JSDoc if present
|
|
161
|
+
const jsdocMatch = chunk.code.match(/\/\*\*([\s\S]*?)\*\//);
|
|
162
|
+
if (jsdocMatch) {
|
|
163
|
+
const jsdocText = jsdocMatch[1]
|
|
164
|
+
.split("\n")
|
|
165
|
+
.map((l) => l.replace(/^\s*\*\s?/, "").trim())
|
|
166
|
+
.filter((l) => l && !l.startsWith("@"))
|
|
167
|
+
.join(" ");
|
|
168
|
+
if (jsdocText)
|
|
169
|
+
parts.push(jsdocText);
|
|
170
|
+
}
|
|
171
|
+
return parts.join(" ");
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=signatureExtractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signatureExtractor.js","sourceRoot":"","sources":["../src/signatureExtractor.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAaH,4CAuBC;AAwID,kDA8BC;AAtMD;;;;;;;;GAQG;AACH,SAAgB,gBAAgB,CAAC,KAAY;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE/B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,WAAW,CAAC;QACjB,KAAK,YAAY;YACf,OAAO,yBAAyB,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAEtD,KAAK,OAAO;YACV,OAAO,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAElD,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ,CAAC;QACd,KAAK,gBAAgB;YACnB,OAAO,wBAAwB,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAErD,KAAK,UAAU;YACb,OAAO,wBAAwB,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAErD;YACE,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,gEAAgE;AAChE,SAAS,wBAAwB,CAAC,KAAe,EAAE,IAAY;IAC7D,sBAAsB;IACtB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OACE,KAAK,GAAG,KAAK,CAAC,MAAM;QACpB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAClC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;YACrC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YACpC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YACpC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAC7B,CAAC;QACD,KAAK,EAAE,CAAC;IACV,CAAC;IAED,+CAA+C;IAC/C,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,KAAK,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QAE/B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,4CAA4C;YAC5C,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9C,MAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,iCAAiC;YACjC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;YACjD,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,GAAG,IAAI,IAAI,CAAC;AACrB,CAAC;AAED,2EAA2E;AAC3E,SAAS,qBAAqB,CAAC,KAAe,EAAE,IAAY;IAC1D,iCAAiC;IACjC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACjC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC,CACpC,CAAC;IAEF,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,IAAI,EAAE,CAAC;IAEvC,IAAI,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,CAAC;IAED,mDAAmD;IACnD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,sEAAsE;QACtE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,6BAA6B,CAC9B,CAAC;QACF,IAAI,WAAW,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,aAAa,EAAE,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,GAAG,IAAI,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACtC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,yDAAyD;AACzD,SAAS,yBAAyB,CAAC,KAAe,EAAE,IAAY;IAC9D,2BAA2B;IAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAChC,wCAAwC,CAAC,IAAI,CAAC,CAAC,CAAC,CACjD,CAAC;IAEF,IAAI,CAAC,QAAQ;QAAE,OAAO,aAAa,IAAI,EAAE,CAAC;IAE1C,iEAAiE;IACjE,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,wCAAwC;IACxC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACvD,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,IAAI,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC1B,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,GAAG,IAAI,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACtC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iCAAiC;AACjC,SAAS,wBAAwB,CAAC,KAAe,EAAE,IAAY;IAC7D,gBAAgB;IAChB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OACE,KAAK,GAAG,KAAK,CAAC,MAAM;QACpB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAClC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;YACrC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YACpC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YACpC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAC7B,CAAC;QACD,KAAK,EAAE,CAAC;IACV,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,IAAI,EAAE,CAAC;IAErD,uCAAuC;IACvC,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IAEpC,qBAAqB;IACrB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,SAAgB,mBAAmB,CAAC,KAAY,EAAE,SAAiB;IACjE,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,kDAAkD;IAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAErB,iBAAiB;IACjB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI;SACzB,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC;SACzC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,WAAW,EAAE,CAAC;IACjB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEtB,YAAY;IACZ,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEtB,mBAAmB;IACnB,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC5D,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC;aAC5B,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;aAC7C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;aACtC,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,IAAI,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import { Chunk, DependencyGraph } from "./types";
|
|
3
|
+
/** Get or create the database connection */
|
|
4
|
+
export declare function getDb(): Database.Database;
|
|
5
|
+
/** Close the database */
|
|
6
|
+
export declare function closeDb(): void;
|
|
7
|
+
/** Upsert a chunk into the database */
|
|
8
|
+
export declare function upsertChunk(chunk: Chunk & {
|
|
9
|
+
signature: string;
|
|
10
|
+
}): void;
|
|
11
|
+
/** Batch upsert chunks (much faster) */
|
|
12
|
+
export declare function upsertChunks(chunks: (Chunk & {
|
|
13
|
+
signature: string;
|
|
14
|
+
})[]): void;
|
|
15
|
+
/** Get a chunk by ID */
|
|
16
|
+
export declare function getChunk(id: string): (Chunk & {
|
|
17
|
+
signature: string;
|
|
18
|
+
}) | null;
|
|
19
|
+
/** Get all chunks */
|
|
20
|
+
export declare function getAllChunks(): (Chunk & {
|
|
21
|
+
signature: string;
|
|
22
|
+
})[];
|
|
23
|
+
/** Get chunk hash for cache checking */
|
|
24
|
+
export declare function getChunkHash(id: string): string | null;
|
|
25
|
+
/** Get chunk count */
|
|
26
|
+
export declare function getChunkCount(): number;
|
|
27
|
+
/** Store an embedding vector as a binary blob */
|
|
28
|
+
export declare function upsertEmbedding(chunkId: string, vector: number[]): void;
|
|
29
|
+
/** Batch upsert embeddings */
|
|
30
|
+
export declare function upsertEmbeddings(items: {
|
|
31
|
+
chunkId: string;
|
|
32
|
+
vector: number[];
|
|
33
|
+
}[]): void;
|
|
34
|
+
/** Get an embedding vector */
|
|
35
|
+
export declare function getEmbedding(chunkId: string): number[] | null;
|
|
36
|
+
/** Get all embeddings as a map */
|
|
37
|
+
export declare function getAllEmbeddings(): Map<string, number[]>;
|
|
38
|
+
/** Save the dependency graph */
|
|
39
|
+
export declare function saveGraph(graph: DependencyGraph): void;
|
|
40
|
+
/** Load the dependency graph */
|
|
41
|
+
export declare function loadGraph(): DependencyGraph;
|
|
42
|
+
export declare function setMeta(key: string, value: string): void;
|
|
43
|
+
export declare function getMeta(key: string): string | null;
|
|
44
|
+
/** Get stored mtime for a file */
|
|
45
|
+
export declare function getFileMtime(filePath: string): number | null;
|
|
46
|
+
/** Upsert file tracking info */
|
|
47
|
+
export declare function upsertFile(filePath: string, mtime: number, hash: string): void;
|
|
48
|
+
/** Get all tracked file paths */
|
|
49
|
+
export declare function getTrackedFiles(): string[];
|
|
50
|
+
/** Remove a file and all its chunks/embeddings */
|
|
51
|
+
export declare function removeFile(filePath: string): void;
|
|
52
|
+
/** Remove chunks for a file (before re-inserting updated ones).
|
|
53
|
+
* Uses LIKE matching to handle both relative and absolute paths. */
|
|
54
|
+
export declare function removeChunksForFile(filePath: string): void;
|
|
55
|
+
/** Get chunk IDs that have no embedding yet */
|
|
56
|
+
export declare function getChunksWithoutEmbeddings(): string[];
|
|
57
|
+
/** Clear all data (for full regeneration) */
|
|
58
|
+
export declare function clearAll(): void;
|
|
59
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAGtC,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAkBjD,4CAA4C;AAC5C,wBAAgB,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAsDzC;AAED,yBAAyB;AACzB,wBAAgB,OAAO,IAAI,IAAI,CAK9B;AAMD,uCAAuC;AACvC,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAetE;AAED,wCAAwC;AACxC,wBAAgB,YAAY,CAAC,MAAM,EAAE,CAAC,KAAK,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,GAAG,IAAI,CAc5E;AAED,wBAAwB;AACxB,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,KAAK,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAG3E;AAED,qBAAqB;AACrB,wBAAgB,YAAY,IAAI,CAAC,KAAK,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,CAGhE;AAED,wCAAwC;AACxC,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAItD;AAED,sBAAsB;AACtB,wBAAgB,aAAa,IAAI,MAAM,CAGtC;AAMD,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAIvE;AAED,8BAA8B;AAC9B,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,GAAG,IAAI,CAYrF;AAED,8BAA8B;AAC9B,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAK7D;AAED,kCAAkC;AAClC,wBAAgB,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAUxD;AAMD,gCAAgC;AAChC,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CActD;AAED,gCAAgC;AAChC,wBAAgB,SAAS,IAAI,eAAe,CAS3C;AAMD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGxD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIlD;AAMD,kCAAkC;AAClC,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI5D;AAED,gCAAgC;AAChC,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAG9E;AAED,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAG1C;AAED,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAajD;AAED;qEACqE;AACrE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAW1D;AAED,+CAA+C;AAC/C,wBAAgB,0BAA0B,IAAI,MAAM,EAAE,CAKrD;AAED,6CAA6C;AAC7C,wBAAgB,QAAQ,IAAI,IAAI,CAG/B"}
|