@monoes/monograph 1.6.11 → 1.6.12
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/dist/src/pipeline/phases/orm-helpers.d.ts +11 -0
- package/dist/src/pipeline/phases/orm-helpers.d.ts.map +1 -0
- package/dist/src/pipeline/phases/orm-helpers.js +72 -0
- package/dist/src/pipeline/phases/orm-helpers.js.map +1 -0
- package/dist/src/pipeline/phases/orm-mongoose.d.ts +8 -0
- package/dist/src/pipeline/phases/orm-mongoose.d.ts.map +1 -0
- package/dist/src/pipeline/phases/orm-mongoose.js +51 -0
- package/dist/src/pipeline/phases/orm-mongoose.js.map +1 -0
- package/dist/src/pipeline/phases/orm-prisma.d.ts +8 -0
- package/dist/src/pipeline/phases/orm-prisma.d.ts.map +1 -0
- package/dist/src/pipeline/phases/orm-prisma.js +41 -0
- package/dist/src/pipeline/phases/orm-prisma.js.map +1 -0
- package/dist/src/pipeline/phases/orm-sequelize.d.ts +12 -0
- package/dist/src/pipeline/phases/orm-sequelize.d.ts.map +1 -0
- package/dist/src/pipeline/phases/orm-sequelize.js +97 -0
- package/dist/src/pipeline/phases/orm-sequelize.js.map +1 -0
- package/dist/src/pipeline/phases/orm-sqlalchemy.d.ts +8 -0
- package/dist/src/pipeline/phases/orm-sqlalchemy.d.ts.map +1 -0
- package/dist/src/pipeline/phases/orm-sqlalchemy.js +42 -0
- package/dist/src/pipeline/phases/orm-sqlalchemy.js.map +1 -0
- package/dist/src/pipeline/phases/orm-typeorm.d.ts +10 -0
- package/dist/src/pipeline/phases/orm-typeorm.d.ts.map +1 -0
- package/dist/src/pipeline/phases/orm-typeorm.js +52 -0
- package/dist/src/pipeline/phases/orm-typeorm.js.map +1 -0
- package/dist/src/pipeline/phases/orm.d.ts.map +1 -1
- package/dist/src/pipeline/phases/orm.js +6 -336
- package/dist/src/pipeline/phases/orm.js.map +1 -1
- package/dist/src/pipeline/phases/scope-resolution-edges.d.ts +9 -0
- package/dist/src/pipeline/phases/scope-resolution-edges.d.ts.map +1 -0
- package/dist/src/pipeline/phases/scope-resolution-edges.js +30 -0
- package/dist/src/pipeline/phases/scope-resolution-edges.js.map +1 -0
- package/dist/src/pipeline/phases/scope-resolution-function-index.d.ts +31 -0
- package/dist/src/pipeline/phases/scope-resolution-function-index.d.ts.map +1 -0
- package/dist/src/pipeline/phases/scope-resolution-function-index.js +96 -0
- package/dist/src/pipeline/phases/scope-resolution-function-index.js.map +1 -0
- package/dist/src/pipeline/phases/scope-resolution-target.d.ts +6 -0
- package/dist/src/pipeline/phases/scope-resolution-target.d.ts.map +1 -0
- package/dist/src/pipeline/phases/scope-resolution-target.js +69 -0
- package/dist/src/pipeline/phases/scope-resolution-target.js.map +1 -0
- package/dist/src/pipeline/phases/scope-resolution.d.ts.map +1 -1
- package/dist/src/pipeline/phases/scope-resolution.js +3 -189
- package/dist/src/pipeline/phases/scope-resolution.js.map +1 -1
- package/dist/src/storage/fts-store-hybrid.d.ts +17 -0
- package/dist/src/storage/fts-store-hybrid.d.ts.map +1 -0
- package/dist/src/storage/fts-store-hybrid.js +119 -0
- package/dist/src/storage/fts-store-hybrid.js.map +1 -0
- package/dist/src/storage/fts-store-search.d.ts +29 -0
- package/dist/src/storage/fts-store-search.d.ts.map +1 -0
- package/dist/src/storage/fts-store-search.js +177 -0
- package/dist/src/storage/fts-store-search.js.map +1 -0
- package/dist/src/storage/fts-store-terms.d.ts +8 -0
- package/dist/src/storage/fts-store-terms.d.ts.map +1 -0
- package/dist/src/storage/fts-store-terms.js +174 -0
- package/dist/src/storage/fts-store-terms.js.map +1 -0
- package/dist/src/storage/fts-store.d.ts +12 -46
- package/dist/src/storage/fts-store.d.ts.map +1 -1
- package/dist/src/storage/fts-store.js +11 -459
- package/dist/src/storage/fts-store.js.map +1 -1
- package/dist/src/web/api-queries.d.ts +89 -0
- package/dist/src/web/api-queries.d.ts.map +1 -0
- package/dist/src/web/api-queries.js +245 -0
- package/dist/src/web/api-queries.js.map +1 -0
- package/dist/src/web/api.d.ts +2 -87
- package/dist/src/web/api.d.ts.map +1 -1
- package/dist/src/web/api.js +3 -244
- package/dist/src/web/api.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,462 +1,14 @@
|
|
|
1
|
-
// ── Intent-to-identifier extraction ──────────────────────────────────────────
|
|
2
|
-
const STOPWORDS = new Set([
|
|
3
|
-
'a',
|
|
4
|
-
'an',
|
|
5
|
-
'the',
|
|
6
|
-
'is',
|
|
7
|
-
'are',
|
|
8
|
-
'was',
|
|
9
|
-
'were',
|
|
10
|
-
'be',
|
|
11
|
-
'been',
|
|
12
|
-
'being',
|
|
13
|
-
'have',
|
|
14
|
-
'has',
|
|
15
|
-
'had',
|
|
16
|
-
'do',
|
|
17
|
-
'does',
|
|
18
|
-
'did',
|
|
19
|
-
'will',
|
|
20
|
-
'would',
|
|
21
|
-
'shall',
|
|
22
|
-
'should',
|
|
23
|
-
'may',
|
|
24
|
-
'might',
|
|
25
|
-
'must',
|
|
26
|
-
'can',
|
|
27
|
-
'could',
|
|
28
|
-
'am',
|
|
29
|
-
'it',
|
|
30
|
-
'its',
|
|
31
|
-
'i',
|
|
32
|
-
'me',
|
|
33
|
-
'my',
|
|
34
|
-
'we',
|
|
35
|
-
'our',
|
|
36
|
-
'you',
|
|
37
|
-
'your',
|
|
38
|
-
'he',
|
|
39
|
-
'she',
|
|
40
|
-
'they',
|
|
41
|
-
'them',
|
|
42
|
-
'their',
|
|
43
|
-
'this',
|
|
44
|
-
'that',
|
|
45
|
-
'these',
|
|
46
|
-
'those',
|
|
47
|
-
'of',
|
|
48
|
-
'in',
|
|
49
|
-
'to',
|
|
50
|
-
'for',
|
|
51
|
-
'with',
|
|
52
|
-
'on',
|
|
53
|
-
'at',
|
|
54
|
-
'from',
|
|
55
|
-
'by',
|
|
56
|
-
'about',
|
|
57
|
-
'as',
|
|
58
|
-
'into',
|
|
59
|
-
'through',
|
|
60
|
-
'during',
|
|
61
|
-
'before',
|
|
62
|
-
'after',
|
|
63
|
-
'above',
|
|
64
|
-
'below',
|
|
65
|
-
'between',
|
|
66
|
-
'out',
|
|
67
|
-
'off',
|
|
68
|
-
'over',
|
|
69
|
-
'under',
|
|
70
|
-
'again',
|
|
71
|
-
'then',
|
|
72
|
-
'once',
|
|
73
|
-
'here',
|
|
74
|
-
'there',
|
|
75
|
-
'when',
|
|
76
|
-
'where',
|
|
77
|
-
'why',
|
|
78
|
-
'how',
|
|
79
|
-
'all',
|
|
80
|
-
'both',
|
|
81
|
-
'each',
|
|
82
|
-
'every',
|
|
83
|
-
'few',
|
|
84
|
-
'more',
|
|
85
|
-
'most',
|
|
86
|
-
'other',
|
|
87
|
-
'some',
|
|
88
|
-
'such',
|
|
89
|
-
'no',
|
|
90
|
-
'nor',
|
|
91
|
-
'not',
|
|
92
|
-
'only',
|
|
93
|
-
'own',
|
|
94
|
-
'same',
|
|
95
|
-
'so',
|
|
96
|
-
'than',
|
|
97
|
-
'too',
|
|
98
|
-
'very',
|
|
99
|
-
'just',
|
|
100
|
-
'because',
|
|
101
|
-
'but',
|
|
102
|
-
'and',
|
|
103
|
-
'or',
|
|
104
|
-
'if',
|
|
105
|
-
'while',
|
|
106
|
-
'what',
|
|
107
|
-
'which',
|
|
108
|
-
'who',
|
|
109
|
-
'whom',
|
|
110
|
-
'up',
|
|
111
|
-
'down',
|
|
112
|
-
'get',
|
|
113
|
-
'set',
|
|
114
|
-
'add',
|
|
115
|
-
'use',
|
|
116
|
-
'find',
|
|
117
|
-
'show',
|
|
118
|
-
'make',
|
|
119
|
-
'let',
|
|
120
|
-
'want',
|
|
121
|
-
'need',
|
|
122
|
-
'like',
|
|
123
|
-
'look',
|
|
124
|
-
'also',
|
|
125
|
-
'new',
|
|
126
|
-
'old',
|
|
127
|
-
]);
|
|
128
1
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* file extensions (so "CLAUDE.md" also tries "CLAUDE").
|
|
132
|
-
* Returns an empty array when the query is already a bare identifier.
|
|
133
|
-
*/
|
|
134
|
-
export function extractSearchTerms(query) {
|
|
135
|
-
const words = query.split(/[\s,;:!?()[\]{}'"]+/).filter(Boolean);
|
|
136
|
-
// If query is a single token, it's already a bare identifier query — nothing to extract.
|
|
137
|
-
// (We used to also bail out for short, stopword-free multi-token queries under the
|
|
138
|
-
// assumption they were "already an identifier query", but that misfires for queries
|
|
139
|
-
// like "ExtensionBridge keepalive reconnect" — three distinct identifier-ish tokens
|
|
140
|
-
// that FTS5 MATCH ANDs together and fails to find as a single row. Since this function
|
|
141
|
-
// only runs as a fallback after the raw MATCH already returned zero rows, there's no
|
|
142
|
-
// extra cost to always extracting terms for multi-token queries.)
|
|
143
|
-
if (words.length <= 1)
|
|
144
|
-
return [];
|
|
145
|
-
const terms = new Set();
|
|
146
|
-
for (const word of words) {
|
|
147
|
-
const lower = word.toLowerCase();
|
|
148
|
-
if (STOPWORDS.has(lower))
|
|
149
|
-
continue;
|
|
150
|
-
if (word.length < 3)
|
|
151
|
-
continue;
|
|
152
|
-
// Strip file extensions: "CLAUDE.md" → also add "CLAUDE"
|
|
153
|
-
const dotIdx = word.lastIndexOf('.');
|
|
154
|
-
if (dotIdx > 0 && dotIdx < word.length - 1) {
|
|
155
|
-
terms.add(word.slice(0, dotIdx));
|
|
156
|
-
terms.add(word);
|
|
157
|
-
}
|
|
158
|
-
// Split camelCase/PascalCase: "ExtensionBridge" → "Extension", "Bridge"
|
|
159
|
-
const camelParts = word
|
|
160
|
-
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
161
|
-
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
|
|
162
|
-
.split(/[\s_-]+/)
|
|
163
|
-
.filter((p) => p.length >= 3 && !STOPWORDS.has(p.toLowerCase()));
|
|
164
|
-
if (camelParts.length > 1) {
|
|
165
|
-
for (const part of camelParts)
|
|
166
|
-
terms.add(part);
|
|
167
|
-
}
|
|
168
|
-
// Keep the original word
|
|
169
|
-
terms.add(word);
|
|
170
|
-
}
|
|
171
|
-
return Array.from(terms);
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* THE single conversion from FTS5's `rank` to monograph's score convention.
|
|
175
|
-
*
|
|
176
|
-
* SCORE CONVENTION: every score that leaves the search layer is
|
|
177
|
-
* **higher-is-better and non-negative**. SQLite FTS5's `rank` is the opposite
|
|
178
|
-
* (negative, and *more* negative means a *better* match), so a raw rank must
|
|
179
|
-
* never escape this module — forwarding one into a ranker that takes maxima
|
|
180
|
-
* lets an unrelated node sitting at 0 outrank a genuine match at -0.656.
|
|
2
|
+
* FTS5 search, intent-extraction, and hybrid search over the monograph nodes
|
|
3
|
+
* table.
|
|
181
4
|
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
* Quote a single FTS5 search term as a string literal when it contains characters
|
|
192
|
-
* that would otherwise be parsed as FTS5 syntax (quotes, parens, boolean keywords
|
|
193
|
-
* like AND/OR/NOT, colons, hyphens, etc). Wrapping in double-quotes forces FTS5 to
|
|
194
|
-
* treat the term as a literal string; any literal `"` inside the term is escaped by
|
|
195
|
-
* doubling it, per FTS5's own string-literal quoting rules.
|
|
196
|
-
*/
|
|
197
|
-
function quoteFtsTerm(term) {
|
|
198
|
-
// Bare alphanumeric/underscore terms need no quoting and are the common case.
|
|
199
|
-
if (/^[A-Za-z0-9_]+$/.test(term))
|
|
200
|
-
return term;
|
|
201
|
-
const escaped = term.replace(/"/g, '""');
|
|
202
|
-
return `"${escaped}"`;
|
|
203
|
-
}
|
|
204
|
-
export function ftsSearch(db, query, limit, label) {
|
|
205
|
-
// Sanitize: strip only characters that break FTS5 MATCH syntax (* still stripped,
|
|
206
|
-
// trigram handles substring natively; " is now preserved since trigram doesn't need it removed)
|
|
207
|
-
const safeQuery = query.replace(/[*]/g, ' ').trim();
|
|
208
|
-
if (!safeQuery)
|
|
209
|
-
return [];
|
|
210
|
-
// Trigram handles substring matching natively — no need to append * to each term.
|
|
211
|
-
// Quote each term individually so characters like `"`, `(`, `)`, or bare boolean
|
|
212
|
-
// keywords (AND/OR/NOT) don't get parsed as FTS5 query syntax.
|
|
213
|
-
const ftsQuery = safeQuery.split(/\s+/).map(quoteFtsTerm).join(' ');
|
|
214
|
-
let matchSql = `
|
|
215
|
-
SELECT n.id, n.name, n.norm_label, n.file_path, n.label,
|
|
216
|
-
n.start_line, n.end_line, nodes_fts.rank
|
|
217
|
-
FROM nodes_fts
|
|
218
|
-
JOIN nodes n ON n.rowid = nodes_fts.rowid
|
|
219
|
-
WHERE nodes_fts MATCH ?
|
|
220
|
-
`;
|
|
221
|
-
const matchParams = [ftsQuery];
|
|
222
|
-
if (label) {
|
|
223
|
-
matchSql += ' AND n.label = ?';
|
|
224
|
-
matchParams.push(label);
|
|
225
|
-
}
|
|
226
|
-
matchSql += ' ORDER BY nodes_fts.rank LIMIT ?';
|
|
227
|
-
matchParams.push(limit);
|
|
228
|
-
let matchRows = [];
|
|
229
|
-
try {
|
|
230
|
-
matchRows = db.prepare(matchSql).all(...matchParams);
|
|
231
|
-
}
|
|
232
|
-
catch {
|
|
233
|
-
// FTS MATCH can throw on malformed queries; fall through to LIKE path
|
|
234
|
-
}
|
|
235
|
-
// ── Intent-extraction fallback: when the raw query looks like natural language
|
|
236
|
-
// and FTS returned nothing, extract code-relevant tokens and retry FTS. ──────
|
|
237
|
-
if (matchRows.length === 0) {
|
|
238
|
-
const extracted = extractSearchTerms(safeQuery);
|
|
239
|
-
if (extracted.length > 0) {
|
|
240
|
-
// Try each extracted term individually via FTS, then merge by best rank
|
|
241
|
-
const termFtsQuery = extracted.map(quoteFtsTerm).join(' OR ');
|
|
242
|
-
let termSql = `
|
|
243
|
-
SELECT n.id, n.name, n.norm_label, n.file_path, n.label,
|
|
244
|
-
n.start_line, n.end_line, nodes_fts.rank
|
|
245
|
-
FROM nodes_fts
|
|
246
|
-
JOIN nodes n ON n.rowid = nodes_fts.rowid
|
|
247
|
-
WHERE nodes_fts MATCH ?
|
|
248
|
-
`;
|
|
249
|
-
const termParams = [termFtsQuery];
|
|
250
|
-
if (label) {
|
|
251
|
-
termSql += ' AND n.label = ?';
|
|
252
|
-
termParams.push(label);
|
|
253
|
-
}
|
|
254
|
-
termSql += ' ORDER BY nodes_fts.rank LIMIT ?';
|
|
255
|
-
termParams.push(limit * 2);
|
|
256
|
-
try {
|
|
257
|
-
matchRows = db.prepare(termSql).all(...termParams);
|
|
258
|
-
}
|
|
259
|
-
catch {
|
|
260
|
-
/* FTS MATCH can throw on malformed queries */
|
|
261
|
-
}
|
|
262
|
-
// Also try individual LIKE for each extracted term to catch camelCase substrings
|
|
263
|
-
if (matchRows.length < limit) {
|
|
264
|
-
const seenIds = new Set(matchRows.map((r) => r.id));
|
|
265
|
-
for (const term of extracted) {
|
|
266
|
-
if (matchRows.length >= limit)
|
|
267
|
-
break;
|
|
268
|
-
const escapedTerm = term.replace(/\\/g, '\\\\').replace(/%/g, '\\%').replace(/_/g, '\\_');
|
|
269
|
-
const pat = `%${escapedTerm}%`;
|
|
270
|
-
let termLikeSql = `
|
|
271
|
-
SELECT n.id, n.name, n.norm_label, n.file_path, n.label,
|
|
272
|
-
n.start_line, n.end_line, 0 AS rank
|
|
273
|
-
FROM nodes n
|
|
274
|
-
WHERE (n.name LIKE ? ESCAPE '\\' OR n.norm_label LIKE ? ESCAPE '\\')
|
|
275
|
-
`;
|
|
276
|
-
const termLikeParams = [pat, pat];
|
|
277
|
-
if (label) {
|
|
278
|
-
termLikeSql += ' AND n.label = ?';
|
|
279
|
-
termLikeParams.push(label);
|
|
280
|
-
}
|
|
281
|
-
termLikeSql += ' LIMIT ?';
|
|
282
|
-
termLikeParams.push(limit);
|
|
283
|
-
const likeRows = db
|
|
284
|
-
.prepare(termLikeSql)
|
|
285
|
-
.all(...termLikeParams);
|
|
286
|
-
for (const r of likeRows) {
|
|
287
|
-
if (!seenIds.has(r.id)) {
|
|
288
|
-
matchRows.push(r);
|
|
289
|
-
seenIds.add(r.id);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
// Run the LIKE fallback whenever MATCH threw (malformed/boolean-keyword query) or
|
|
297
|
-
// returned zero rows — not just for short (≤2 char) queries. Short queries need it
|
|
298
|
-
// because trigram requires ≥3 characters to fire; longer queries need it whenever
|
|
299
|
-
// MATCH couldn't handle the syntax, so a query-syntax failure doesn't silently read
|
|
300
|
-
// as "no results".
|
|
301
|
-
if (safeQuery.length <= 2 || matchRows.length === 0) {
|
|
302
|
-
const escapedQuery = safeQuery.replace(/\\/g, '\\\\').replace(/%/g, '\\%').replace(/_/g, '\\_');
|
|
303
|
-
const likePattern = `%${escapedQuery}%`;
|
|
304
|
-
// Also try without file extension: "CLAUDE.md" → "CLAUDE"
|
|
305
|
-
const dotIdx = safeQuery.lastIndexOf('.');
|
|
306
|
-
const strippedLikePattern = dotIdx > 0 && dotIdx < safeQuery.length - 1
|
|
307
|
-
? `%${safeQuery.slice(0, dotIdx).replace(/\\/g, '\\\\').replace(/%/g, '\\%').replace(/_/g, '\\_')}%`
|
|
308
|
-
: null;
|
|
309
|
-
let likeSql = `
|
|
310
|
-
SELECT n.id, n.name, n.norm_label, n.file_path, n.label,
|
|
311
|
-
n.start_line, n.end_line, 0 AS rank
|
|
312
|
-
FROM nodes n
|
|
313
|
-
WHERE (n.name LIKE ? ESCAPE '\\' OR n.norm_label LIKE ? ESCAPE '\\' OR n.file_path LIKE ? ESCAPE '\\'`;
|
|
314
|
-
const likeParams = [likePattern, likePattern, likePattern];
|
|
315
|
-
if (strippedLikePattern) {
|
|
316
|
-
likeSql += ` OR n.name LIKE ? ESCAPE '\\'`;
|
|
317
|
-
likeParams.push(strippedLikePattern);
|
|
318
|
-
}
|
|
319
|
-
likeSql += ')';
|
|
320
|
-
if (label) {
|
|
321
|
-
likeSql += ' AND n.label = ?';
|
|
322
|
-
likeParams.push(label);
|
|
323
|
-
}
|
|
324
|
-
likeSql += ' LIMIT ?';
|
|
325
|
-
likeParams.push(limit);
|
|
326
|
-
const likeRows = db.prepare(likeSql).all(...likeParams);
|
|
327
|
-
// Merge: MATCH results first, append LIKE results not already present
|
|
328
|
-
const seenIds = new Set(matchRows.map((r) => r.id));
|
|
329
|
-
for (const r of likeRows) {
|
|
330
|
-
if (!seenIds.has(r.id)) {
|
|
331
|
-
matchRows.push(r);
|
|
332
|
-
seenIds.add(r.id);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
return matchRows.slice(0, limit).map((r) => ({
|
|
337
|
-
id: r.id,
|
|
338
|
-
name: r.name,
|
|
339
|
-
normLabel: r.norm_label,
|
|
340
|
-
filePath: r.file_path ?? null,
|
|
341
|
-
label: r.label,
|
|
342
|
-
rank: r.rank,
|
|
343
|
-
startLine: r.start_line ?? null,
|
|
344
|
-
endLine: r.end_line ?? null,
|
|
345
|
-
}));
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Computes an in-memory fuzzy sequence score for `query` against `name`.
|
|
349
|
-
* Walks through query chars left-to-right, finding each in `name` sequentially.
|
|
350
|
-
* Returns a score in [0, 1]: higher means a tighter match.
|
|
351
|
-
*/
|
|
352
|
-
function computeFuzzyScore(name, query) {
|
|
353
|
-
if (!query.length)
|
|
354
|
-
return 0;
|
|
355
|
-
const lname = name.toLowerCase();
|
|
356
|
-
const lquery = query.toLowerCase();
|
|
357
|
-
let nameIdx = 0;
|
|
358
|
-
let matched = 0;
|
|
359
|
-
let gapPenalty = 0;
|
|
360
|
-
let lastMatchPos = -1;
|
|
361
|
-
for (let qi = 0; qi < lquery.length; qi++) {
|
|
362
|
-
const ch = lquery[qi];
|
|
363
|
-
const pos = lname.indexOf(ch, nameIdx);
|
|
364
|
-
if (pos === -1)
|
|
365
|
-
break;
|
|
366
|
-
matched++;
|
|
367
|
-
if (lastMatchPos !== -1) {
|
|
368
|
-
gapPenalty += pos - lastMatchPos - 1;
|
|
369
|
-
}
|
|
370
|
-
lastMatchPos = pos;
|
|
371
|
-
nameIdx = pos + 1;
|
|
372
|
-
}
|
|
373
|
-
if (matched === 0)
|
|
374
|
-
return 0;
|
|
375
|
-
const matchRatio = matched / lquery.length;
|
|
376
|
-
const normalizedGap = gapPenalty / (lname.length || 1);
|
|
377
|
-
return matchRatio * (1 / (1 + normalizedGap));
|
|
378
|
-
}
|
|
379
|
-
/** Returns a small bonus based on node label to favour structural node types. */
|
|
380
|
-
function computeNodeTypeBonus(label) {
|
|
381
|
-
if (label === 'File' || label === 'Module')
|
|
382
|
-
return 0.02;
|
|
383
|
-
if (label === 'Class')
|
|
384
|
-
return 0.01;
|
|
385
|
-
return 0;
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Hybrid search combining three strategies:
|
|
389
|
-
* 1. FTS5 (trigram) BM25 match via `ftsSearch`
|
|
390
|
-
* 2. LIKE fallback for short queries (≤3 chars) or when FTS returns 0 results
|
|
391
|
-
* 3. In-memory fuzzy character-sequence scoring applied to all candidates
|
|
392
|
-
*
|
|
393
|
-
* Results are deduped by id (highest combinedScore wins), re-ranked, and
|
|
394
|
-
* trimmed to `limit`. The existing `ftsSearch` is left unchanged.
|
|
395
|
-
*/
|
|
396
|
-
export function hybridSearch(db, query, limit, label) {
|
|
397
|
-
const safeQuery = query.replace(/[*]/g, ' ').trim();
|
|
398
|
-
if (!safeQuery)
|
|
399
|
-
return [];
|
|
400
|
-
// id → best result so far
|
|
401
|
-
const best = new Map();
|
|
402
|
-
const upsert = (result) => {
|
|
403
|
-
const existing = best.get(result.id);
|
|
404
|
-
if (!existing || result.combinedScore > existing.combinedScore) {
|
|
405
|
-
best.set(result.id, result);
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
// ── Strategy 1: FTS5 BM25 ──────────────────────────────────────────────────
|
|
409
|
-
const ftsRows = ftsSearch(db, safeQuery, limit * 2, label);
|
|
410
|
-
for (const row of ftsRows) {
|
|
411
|
-
const ftsScore = relevanceFromFtsRank(row.rank);
|
|
412
|
-
const fuzz = computeFuzzyScore(row.name, safeQuery);
|
|
413
|
-
const combined = ftsScore + fuzz + computeNodeTypeBonus(row.label);
|
|
414
|
-
upsert({ ...row, combinedScore: combined, matchStrategy: 'fts' });
|
|
415
|
-
}
|
|
416
|
-
// ── Strategy 2: LIKE fallback ──────────────────────────────────────────────
|
|
417
|
-
// Always run for short queries (≤3 chars) or when FTS returned nothing.
|
|
418
|
-
if (safeQuery.length <= 3 || ftsRows.length === 0) {
|
|
419
|
-
const escapedSafeQuery = safeQuery
|
|
420
|
-
.replace(/\\/g, '\\\\')
|
|
421
|
-
.replace(/%/g, '\\%')
|
|
422
|
-
.replace(/_/g, '\\_');
|
|
423
|
-
const likePattern = `%${escapedSafeQuery}%`;
|
|
424
|
-
let likeSql = `
|
|
425
|
-
SELECT n.id, n.name, n.norm_label, n.file_path, n.label,
|
|
426
|
-
n.start_line, n.end_line
|
|
427
|
-
FROM nodes n
|
|
428
|
-
WHERE (n.name LIKE ? ESCAPE '\\' OR n.norm_label LIKE ? ESCAPE '\\')
|
|
429
|
-
`;
|
|
430
|
-
const likeParams = [likePattern, likePattern];
|
|
431
|
-
if (label) {
|
|
432
|
-
likeSql += ' AND n.label = ?';
|
|
433
|
-
likeParams.push(label);
|
|
434
|
-
}
|
|
435
|
-
likeSql += ' LIMIT ?';
|
|
436
|
-
likeParams.push(limit * 2);
|
|
437
|
-
const likeRows = db.prepare(likeSql).all(...likeParams);
|
|
438
|
-
for (const r of likeRows) {
|
|
439
|
-
const name = r.name;
|
|
440
|
-
const lbl = r.label;
|
|
441
|
-
const fuzz = computeFuzzyScore(name, safeQuery);
|
|
442
|
-
const combined = 0.3 + fuzz + computeNodeTypeBonus(lbl);
|
|
443
|
-
upsert({
|
|
444
|
-
id: r.id,
|
|
445
|
-
name,
|
|
446
|
-
normLabel: r.norm_label,
|
|
447
|
-
filePath: r.file_path ?? null,
|
|
448
|
-
label: lbl,
|
|
449
|
-
rank: 0,
|
|
450
|
-
startLine: r.start_line ?? null,
|
|
451
|
-
endLine: r.end_line ?? null,
|
|
452
|
-
combinedScore: combined,
|
|
453
|
-
matchStrategy: 'like',
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
// ── Sort, dedupe (handled by Map), slice ───────────────────────────────────
|
|
458
|
-
return Array.from(best.values())
|
|
459
|
-
.sort((a, b) => b.combinedScore - a.combinedScore)
|
|
460
|
-
.slice(0, limit);
|
|
461
|
-
}
|
|
5
|
+
* File-size sweep: split into sibling modules — stopwords + intent-to-
|
|
6
|
+
* identifier extraction in fts-store-terms.ts, the FTS5/LIKE search path in
|
|
7
|
+
* fts-store-search.ts, and hybrid (FTS + LIKE + fuzzy) search in
|
|
8
|
+
* fts-store-hybrid.ts. Re-exported here so every existing import path
|
|
9
|
+
* (`./fts-store.js`) keeps working unchanged.
|
|
10
|
+
*/
|
|
11
|
+
export { hybridSearch } from './fts-store-hybrid.js';
|
|
12
|
+
export { ftsSearch, relevanceFromFtsRank } from './fts-store-search.js';
|
|
13
|
+
export { extractSearchTerms } from './fts-store-terms.js';
|
|
462
14
|
//# sourceMappingURL=fts-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fts-store.js","sourceRoot":"","sources":["../../../src/storage/fts-store.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fts-store.js","sourceRoot":"","sources":["../../../src/storage/fts-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
import { type IndexScope } from '../pipeline/index-scope.js';
|
|
3
|
+
export interface ApiNode {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
label: string;
|
|
7
|
+
filePath: string | null;
|
|
8
|
+
startLine: number | null;
|
|
9
|
+
endLine: number | null;
|
|
10
|
+
communityId: number | null;
|
|
11
|
+
}
|
|
12
|
+
export interface ApiEdge {
|
|
13
|
+
sourceId: string;
|
|
14
|
+
targetId: string;
|
|
15
|
+
relation: string;
|
|
16
|
+
confidenceScore: number;
|
|
17
|
+
}
|
|
18
|
+
export interface GraphData {
|
|
19
|
+
nodes: ApiNode[];
|
|
20
|
+
edges: ApiEdge[];
|
|
21
|
+
communities: Record<string, string[]>;
|
|
22
|
+
totalNodeCount: number;
|
|
23
|
+
totalEdgeCount: number;
|
|
24
|
+
truncated: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface NodeDetail {
|
|
27
|
+
node: ApiNode | null;
|
|
28
|
+
callers: ApiNode[];
|
|
29
|
+
callees: ApiNode[];
|
|
30
|
+
}
|
|
31
|
+
export interface StatsData {
|
|
32
|
+
nodeCount: number;
|
|
33
|
+
edgeCount: number;
|
|
34
|
+
communityCount: number;
|
|
35
|
+
buildAt: string | null;
|
|
36
|
+
/** Source-selection domain the index was built with; null for indexes built before it was recorded. */
|
|
37
|
+
scope: IndexScope | null;
|
|
38
|
+
}
|
|
39
|
+
export declare function rowToApiNode(row: Record<string, unknown>): ApiNode;
|
|
40
|
+
export declare function queryGraphData(db: Database.Database): GraphData;
|
|
41
|
+
export declare function queryNode(db: Database.Database, id: string): NodeDetail;
|
|
42
|
+
export declare function querySearch(db: Database.Database, q: string): ApiNode[];
|
|
43
|
+
export declare function queryStats(db: Database.Database): StatsData;
|
|
44
|
+
export interface GrepResult {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
label: string;
|
|
48
|
+
filePath: string | null;
|
|
49
|
+
startLine: number | null;
|
|
50
|
+
}
|
|
51
|
+
export declare function queryGrep(db: Database.Database, pattern: string, caseSensitive: boolean): GrepResult[];
|
|
52
|
+
export interface FileLine {
|
|
53
|
+
number: number;
|
|
54
|
+
content: string;
|
|
55
|
+
}
|
|
56
|
+
export interface FileContent {
|
|
57
|
+
path: string;
|
|
58
|
+
totalLines: number;
|
|
59
|
+
lines: FileLine[];
|
|
60
|
+
}
|
|
61
|
+
export declare function readFileContent(filePath: string, startLine?: number, endLine?: number): FileContent;
|
|
62
|
+
export interface ClusterSummary {
|
|
63
|
+
id: number;
|
|
64
|
+
label: string | null;
|
|
65
|
+
memberCount: number;
|
|
66
|
+
}
|
|
67
|
+
export interface ClusterDetail {
|
|
68
|
+
id: number;
|
|
69
|
+
label: string | null;
|
|
70
|
+
members: unknown[];
|
|
71
|
+
}
|
|
72
|
+
export declare function queryClusters(db: Database.Database): ClusterSummary[];
|
|
73
|
+
export declare function queryCluster(db: Database.Database, name: string): ClusterDetail | null;
|
|
74
|
+
export interface ProcessSummary {
|
|
75
|
+
id: string;
|
|
76
|
+
name: string;
|
|
77
|
+
filePath: string | null;
|
|
78
|
+
}
|
|
79
|
+
export declare function queryProcessesList(db: Database.Database): ProcessSummary[];
|
|
80
|
+
export declare function queryProcess(db: Database.Database, name: string): Record<string, unknown> | null;
|
|
81
|
+
export interface ServerInfo {
|
|
82
|
+
name: string;
|
|
83
|
+
version: string;
|
|
84
|
+
nodeVersion: string;
|
|
85
|
+
uptimeSeconds: number;
|
|
86
|
+
}
|
|
87
|
+
export declare function getServerInfo(): ServerInfo;
|
|
88
|
+
export declare function streamGraph(db: Database.Database, onRecord: (record: unknown) => void): Promise<void>;
|
|
89
|
+
//# sourceMappingURL=api-queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-queries.d.ts","sourceRoot":"","sources":["../../../src/web/api-queries.ts"],"names":[],"mappings":"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"}
|