mindlore 0.6.3 → 0.6.5

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.
Files changed (107) hide show
  1. package/README.md +1 -1
  2. package/dist/scripts/cc-memory-bulk-sync.js +1 -1
  3. package/dist/scripts/cc-memory-bulk-sync.js.map +1 -1
  4. package/dist/scripts/cc-session-sync.js +2 -2
  5. package/dist/scripts/cc-session-sync.js.map +1 -1
  6. package/dist/scripts/fetch-raw.js +17 -8
  7. package/dist/scripts/fetch-raw.js.map +1 -1
  8. package/dist/scripts/init.js +8 -8
  9. package/dist/scripts/init.js.map +1 -1
  10. package/dist/scripts/lib/chunker.d.ts.map +1 -1
  11. package/dist/scripts/lib/chunker.js +3 -0
  12. package/dist/scripts/lib/chunker.js.map +1 -1
  13. package/dist/scripts/lib/constants.d.ts +5 -0
  14. package/dist/scripts/lib/constants.d.ts.map +1 -1
  15. package/dist/scripts/lib/constants.js +35 -1
  16. package/dist/scripts/lib/constants.js.map +1 -1
  17. package/dist/scripts/lib/daemon.d.ts.map +1 -1
  18. package/dist/scripts/lib/daemon.js +3 -0
  19. package/dist/scripts/lib/daemon.js.map +1 -1
  20. package/dist/scripts/lib/fuzzy.d.ts.map +1 -1
  21. package/dist/scripts/lib/fuzzy.js +6 -4
  22. package/dist/scripts/lib/fuzzy.js.map +1 -1
  23. package/dist/scripts/lib/input-validation.d.ts +5 -0
  24. package/dist/scripts/lib/input-validation.d.ts.map +1 -0
  25. package/dist/scripts/lib/input-validation.js +48 -0
  26. package/dist/scripts/lib/input-validation.js.map +1 -0
  27. package/dist/scripts/lib/privacy-filter.d.ts.map +1 -1
  28. package/dist/scripts/lib/privacy-filter.js +3 -0
  29. package/dist/scripts/lib/privacy-filter.js.map +1 -1
  30. package/dist/scripts/lib/proximity.d.ts.map +1 -1
  31. package/dist/scripts/lib/proximity.js +6 -0
  32. package/dist/scripts/lib/proximity.js.map +1 -1
  33. package/dist/scripts/lib/rrf.d.ts +7 -2
  34. package/dist/scripts/lib/rrf.d.ts.map +1 -1
  35. package/dist/scripts/lib/rrf.js +20 -16
  36. package/dist/scripts/lib/rrf.js.map +1 -1
  37. package/dist/scripts/lib/search-cache.d.ts +15 -0
  38. package/dist/scripts/lib/search-cache.d.ts.map +1 -1
  39. package/dist/scripts/lib/search-cache.js +50 -2
  40. package/dist/scripts/lib/search-cache.js.map +1 -1
  41. package/dist/scripts/lib/search-engine.d.ts +1 -1
  42. package/dist/scripts/lib/search-engine.d.ts.map +1 -1
  43. package/dist/scripts/lib/search-engine.js +31 -31
  44. package/dist/scripts/lib/search-engine.js.map +1 -1
  45. package/dist/scripts/mindlore-daemon.js +1 -3
  46. package/dist/scripts/mindlore-daemon.js.map +1 -1
  47. package/dist/scripts/mindlore-obsidian.js +4 -0
  48. package/dist/scripts/mindlore-obsidian.js.map +1 -1
  49. package/dist/scripts/mindlore-rrf-bench.d.ts +2 -0
  50. package/dist/scripts/mindlore-rrf-bench.d.ts.map +1 -0
  51. package/dist/scripts/mindlore-rrf-bench.js +30 -0
  52. package/dist/scripts/mindlore-rrf-bench.js.map +1 -0
  53. package/dist/tests/fetch-raw-security.test.d.ts +2 -0
  54. package/dist/tests/fetch-raw-security.test.d.ts.map +1 -0
  55. package/dist/tests/fetch-raw-security.test.js +72 -0
  56. package/dist/tests/fetch-raw-security.test.js.map +1 -0
  57. package/dist/tests/fetch-raw.test.js +4 -4
  58. package/dist/tests/fetch-raw.test.js.map +1 -1
  59. package/dist/tests/fts5.test.js +0 -22
  60. package/dist/tests/fts5.test.js.map +1 -1
  61. package/dist/tests/input-validation.test.d.ts +2 -0
  62. package/dist/tests/input-validation.test.d.ts.map +1 -0
  63. package/dist/tests/input-validation.test.js +113 -0
  64. package/dist/tests/input-validation.test.js.map +1 -0
  65. package/dist/tests/privacy-filter.test.js +25 -50
  66. package/dist/tests/privacy-filter.test.js.map +1 -1
  67. package/dist/tests/rrf.test.js +42 -3
  68. package/dist/tests/rrf.test.js.map +1 -1
  69. package/dist/tests/search-cache.test.js +44 -12
  70. package/dist/tests/search-cache.test.js.map +1 -1
  71. package/dist/tests/search-hook.test.js +0 -44
  72. package/dist/tests/search-hook.test.js.map +1 -1
  73. package/dist/tests/sec-regression.test.d.ts +2 -0
  74. package/dist/tests/sec-regression.test.d.ts.map +1 -0
  75. package/dist/tests/sec-regression.test.js +174 -0
  76. package/dist/tests/sec-regression.test.js.map +1 -0
  77. package/dist/tests/stop-words.test.d.ts +2 -0
  78. package/dist/tests/stop-words.test.d.ts.map +1 -0
  79. package/dist/tests/stop-words.test.js +47 -0
  80. package/dist/tests/stop-words.test.js.map +1 -0
  81. package/hooks/lib/mindlore-common.cjs +39 -36
  82. package/hooks/mindlore-fts5-sync.cjs +4 -3
  83. package/hooks/mindlore-index.cjs +6 -7
  84. package/hooks/mindlore-pre-compact.cjs +5 -4
  85. package/hooks/mindlore-search.cjs +3 -2
  86. package/hooks/mindlore-session-end.cjs +10 -10
  87. package/hooks/mindlore-session-focus.cjs +11 -1
  88. package/package.json +1 -1
  89. package/plugin.json +1 -1
  90. package/templates/SCHEMA.md +10 -108
  91. package/templates/config.json +1 -1
  92. package/dist/scripts/lib/hybrid-search.d.ts +0 -62
  93. package/dist/scripts/lib/hybrid-search.d.ts.map +0 -1
  94. package/dist/scripts/lib/hybrid-search.js +0 -171
  95. package/dist/scripts/lib/hybrid-search.js.map +0 -1
  96. package/dist/tests/hybrid-search.test.d.ts +0 -2
  97. package/dist/tests/hybrid-search.test.d.ts.map +0 -1
  98. package/dist/tests/hybrid-search.test.js +0 -139
  99. package/dist/tests/hybrid-search.test.js.map +0 -1
  100. package/dist/tests/index-cli-embed.test.d.ts +0 -7
  101. package/dist/tests/index-cli-embed.test.d.ts.map +0 -1
  102. package/dist/tests/index-cli-embed.test.js +0 -128
  103. package/dist/tests/index-cli-embed.test.js.map +0 -1
  104. package/dist/tests/search-cli-hybrid.test.d.ts +0 -6
  105. package/dist/tests/search-cli-hybrid.test.d.ts.map +0 -1
  106. package/dist/tests/search-cli-hybrid.test.js +0 -103
  107. package/dist/tests/search-cli-hybrid.test.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../../../scripts/lib/hybrid-search.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAIhD,KAAK,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AAEvC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAcD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGrD;AAKD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAID,wBAAgB,UAAU,CACxB,UAAU,EAAE,SAAS,EAAE,EACvB,UAAU,EAAE,SAAS,EAAE,EACvB,OAAO,GAAE,UAAe,GACvB,WAAW,EAAE,CAsDf;AAID,wBAAgB,UAAU,CACxB,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAW,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,SAAS,EAAE,CA8Bb;AAED,wBAAgB,SAAS,CACvB,EAAE,EAAE,QAAQ,EACZ,cAAc,EAAE,MAAM,EAAE,EACxB,KAAK,GAAE,MAAW,GACjB,SAAS,EAAE,CAeb;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAChC,WAAW,EAAE,CAoCf"}
@@ -1,171 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCategoryWeight = getCategoryWeight;
4
- exports.l2ToCosine = l2ToCosine;
5
- exports.normalizeBM25 = normalizeBM25;
6
- exports.computeRRF = computeRRF;
7
- exports.searchFts5 = searchFts5;
8
- exports.searchVec = searchVec;
9
- exports.hybridSearch = hybridSearch;
10
- const db_helpers_js_1 = require("./db-helpers.js");
11
- const constants_js_1 = require("./constants.js");
12
- // ── Category Weights (v0.6.1) ─────────────────────────────────────
13
- const CATEGORY_WEIGHTS = {
14
- sources: 2.0,
15
- domains: 1.8,
16
- analyses: 1.6,
17
- decisions: 1.5,
18
- diary: 1.0,
19
- 'cc-session': 0.8,
20
- 'cc-subagent': 0.5,
21
- };
22
- function getCategoryWeight(category) {
23
- return CATEGORY_WEIGHTS[category] ?? 1.0;
24
- }
25
- // ── Utility Functions ──────────────────────────────────────────────
26
- /**
27
- * Convert L2 distance to cosine similarity.
28
- * For normalized vectors: cosine_sim = 1.0 - (l2_dist² / 2.0)
29
- */
30
- function l2ToCosine(l2Distance) {
31
- const cosine = 1.0 - (l2Distance * l2Distance / 2.0);
32
- return Math.max(0.0, Math.min(1.0, cosine));
33
- }
34
- // Empirical upper bound for BM25 absolute rank in Mindlore corpus (~150 docs)
35
- const BM25_MAX_RANK = 25.0;
36
- /**
37
- * Normalize FTS5 BM25 rank to 0-1 range.
38
- * FTS5 returns negative rank — more negative = better match.
39
- */
40
- function normalizeBM25(rank) {
41
- return Math.abs(rank) / BM25_MAX_RANK;
42
- }
43
- // ── RRF Fusion ─────────────────────────────────────────────────────
44
- function computeRRF(ftsResults, vecResults, options = {}) {
45
- const k = options.k ?? 60;
46
- const ftsWeight = options.ftsWeight ?? 0.4;
47
- const vecWeight = options.vecWeight ?? 0.6;
48
- const scores = new Map();
49
- // FTS5 results — already sorted by rank (most negative first = best)
50
- for (let i = 0; i < ftsResults.length; i++) {
51
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- loop guard: i < length
52
- const r = ftsResults[i];
53
- const rrfScore = ftsWeight * (1.0 / (k + i + 1));
54
- const existing = scores.get(r.slug);
55
- if (existing) {
56
- existing.score += rrfScore;
57
- existing.ftsRank = r.rank;
58
- }
59
- else {
60
- scores.set(r.slug, {
61
- slug: r.slug,
62
- score: rrfScore,
63
- ftsRank: r.rank,
64
- path: r.path,
65
- description: r.description,
66
- title: r.title,
67
- category: r.category,
68
- tags: r.tags,
69
- });
70
- }
71
- }
72
- // Vec results — already sorted by distance (lowest first = most similar)
73
- for (let i = 0; i < vecResults.length; i++) {
74
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- loop guard: i < length
75
- const r = vecResults[i];
76
- const rrfScore = vecWeight * (1.0 / (k + i + 1));
77
- const existing = scores.get(r.slug);
78
- if (existing) {
79
- existing.score += rrfScore;
80
- existing.vecDistance = r.distance;
81
- }
82
- else {
83
- scores.set(r.slug, {
84
- slug: r.slug,
85
- score: rrfScore,
86
- vecDistance: r.distance,
87
- });
88
- }
89
- }
90
- const results = Array.from(scores.values());
91
- for (const r of results) {
92
- if (r.category === constants_js_1.CC_MEMORY_CATEGORY)
93
- r.score *= constants_js_1.CC_MEMORY_BOOST;
94
- r.score *= getCategoryWeight(r.category ?? '');
95
- }
96
- return results.sort((a, b) => b.score - a.score);
97
- }
98
- // ── Search Functions ───────────────────────────────────────────────
99
- function searchFts5(db, query, limit = 20, project) {
100
- const sanitized = query.replace(/["*(){}[\]^~:]/g, '').trim();
101
- if (!sanitized)
102
- return [];
103
- const terms = sanitized.split(/\s+/).map(t => `"${t}"`).join(' OR ');
104
- try {
105
- if (project) {
106
- return (0, db_helpers_js_1.dbAll)(db, `SELECT slug, path, description, title, category, tags, rank
107
- FROM mindlore_fts
108
- WHERE mindlore_fts MATCH ? AND project = ?
109
- ORDER BY rank
110
- LIMIT ?`, terms, project, limit);
111
- }
112
- return (0, db_helpers_js_1.dbAll)(db, `SELECT slug, path, description, title, category, tags, rank
113
- FROM mindlore_fts
114
- WHERE mindlore_fts MATCH ?
115
- ORDER BY rank
116
- LIMIT ?`, terms, limit);
117
- }
118
- catch (_err) {
119
- return [];
120
- }
121
- }
122
- function searchVec(db, queryEmbedding, limit = 20) {
123
- try {
124
- const buf = Buffer.from(new Float32Array(queryEmbedding).buffer);
125
- return (0, db_helpers_js_1.dbAll)(db, `SELECT slug, distance
126
- FROM documents_vec
127
- WHERE embedding MATCH ?
128
- ORDER BY distance
129
- LIMIT ?`, buf, limit);
130
- }
131
- catch (_err) {
132
- return [];
133
- }
134
- }
135
- /**
136
- * Main hybrid search entry point.
137
- * Falls back to pure FTS5 when vec table or embedding is not available.
138
- */
139
- function hybridSearch(db, query, options = {}) {
140
- const maxResults = options.maxResults ?? 5;
141
- const ftsLimit = 20;
142
- const vecLimit = 20;
143
- // Always search FTS5
144
- const ftsResults = searchFts5(db, query, ftsLimit, options.project);
145
- // Try vec search if embedding is provided and vec table exists
146
- let vecResults = [];
147
- if (options.queryEmbedding && (0, db_helpers_js_1.hasVecTable)(db)) {
148
- vecResults = searchVec(db, options.queryEmbedding, vecLimit);
149
- }
150
- // If no vec results, return FTS5 results directly
151
- if (vecResults.length === 0) {
152
- return ftsResults.slice(0, maxResults).map(r => ({
153
- slug: r.slug,
154
- score: normalizeBM25(r.rank) * getCategoryWeight(r.category ?? ''),
155
- ftsRank: r.rank,
156
- path: r.path,
157
- description: r.description,
158
- title: r.title,
159
- category: r.category,
160
- tags: r.tags,
161
- }));
162
- }
163
- // Fuse results with RRF
164
- const fused = computeRRF(ftsResults, vecResults, {
165
- k: options.k,
166
- ftsWeight: options.ftsWeight,
167
- vecWeight: options.vecWeight,
168
- });
169
- return fused.slice(0, maxResults);
170
- }
171
- //# sourceMappingURL=hybrid-search.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hybrid-search.js","sourceRoot":"","sources":["../../../scripts/lib/hybrid-search.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=hybrid-search.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hybrid-search.test.d.ts","sourceRoot":"","sources":["../../tests/hybrid-search.test.ts"],"names":[],"mappings":""}
@@ -1,139 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const path_1 = __importDefault(require("path"));
7
- const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
8
- const db_js_1 = require("./helpers/db.js");
9
- const hybrid_search_js_1 = require("../scripts/lib/hybrid-search.js");
10
- const TEST_DIR = path_1.default.join(__dirname, '..', '.test-hybrid-search');
11
- const DB_PATH = path_1.default.join(TEST_DIR, 'mindlore.db');
12
- beforeEach(() => {
13
- (0, db_js_1.setupTestDir)(TEST_DIR, ['sources']);
14
- const db = (0, db_js_1.createTestDb)(DB_PATH);
15
- db.close();
16
- });
17
- afterEach(() => {
18
- (0, db_js_1.teardownTestDir)(TEST_DIR);
19
- });
20
- describe('RRF Fusion', () => {
21
- test('should compute RRF scores correctly', () => {
22
- const { computeRRF } = require('../scripts/lib/hybrid-search.js');
23
- const ftsResults = [
24
- { slug: 'a', rank: -10 },
25
- { slug: 'b', rank: -5 },
26
- ];
27
- const vecResults = [
28
- { slug: 'b', distance: 0.5 },
29
- { slug: 'c', distance: 0.8 },
30
- ];
31
- const fused = computeRRF(ftsResults, vecResults, { k: 60, ftsWeight: 0.4, vecWeight: 0.6 });
32
- // 'b' appears in both — should have highest score
33
- expect(fused[0].slug).toBe('b');
34
- expect(fused.length).toBe(3); // a, b, c
35
- // All scores should be positive
36
- fused.forEach((r) => expect(r.score).toBeGreaterThan(0));
37
- });
38
- test('should handle FTS-only results (vec empty)', () => {
39
- const { computeRRF } = require('../scripts/lib/hybrid-search.js');
40
- const ftsResults = [
41
- { slug: 'a', rank: -10 },
42
- { slug: 'b', rank: -5 },
43
- ];
44
- const fused = computeRRF(ftsResults, [], { k: 60, ftsWeight: 0.4, vecWeight: 0.6 });
45
- expect(fused.length).toBe(2);
46
- expect(fused[0].slug).toBe('a');
47
- });
48
- test('should handle vec-only results (FTS empty)', () => {
49
- const { computeRRF } = require('../scripts/lib/hybrid-search.js');
50
- const vecResults = [
51
- { slug: 'a', distance: 0.3 },
52
- { slug: 'b', distance: 0.9 },
53
- ];
54
- const fused = computeRRF([], vecResults, { k: 60, ftsWeight: 0.4, vecWeight: 0.6 });
55
- expect(fused.length).toBe(2);
56
- expect(fused[0].slug).toBe('a'); // lower distance = more similar
57
- });
58
- test('should convert L2 distance to cosine similarity', () => {
59
- const { l2ToCosine } = require('../scripts/lib/hybrid-search.js');
60
- // L2 distance 0 = identical = cosine 1.0
61
- expect(l2ToCosine(0)).toBeCloseTo(1.0, 5);
62
- // L2 distance 2 = opposite = cosine 0.0 (for normalized vectors)
63
- expect(l2ToCosine(2)).toBeCloseTo(0.0, 5);
64
- // L2 distance 1 (90 degrees for normalized) = cosine 0.5
65
- expect(l2ToCosine(1)).toBeCloseTo(0.5, 5);
66
- });
67
- test('should normalize BM25 scores', () => {
68
- const { normalizeBM25 } = require('../scripts/lib/hybrid-search.js');
69
- // FTS5 returns negative ranks — more negative = better match
70
- expect(normalizeBM25(-25)).toBeCloseTo(1.0, 5);
71
- expect(normalizeBM25(-12.5)).toBeCloseTo(0.5, 5);
72
- expect(normalizeBM25(0)).toBeCloseTo(0.0, 5);
73
- });
74
- });
75
- describe('Hybrid Search Integration', () => {
76
- test('should search FTS5 and return results with path and score', () => {
77
- const { searchFts5 } = require('../scripts/lib/hybrid-search.js');
78
- const db = new better_sqlite3_1.default(DB_PATH);
79
- (0, db_js_1.insertFts)(db, {
80
- path: path_1.default.join(TEST_DIR, 'sources', 'test.md'),
81
- slug: 'test-doc',
82
- description: 'TypeScript guide for beginners',
83
- type: 'source',
84
- category: 'sources',
85
- title: 'Test Doc',
86
- content: 'TypeScript is a typed superset of JavaScript',
87
- tags: 'typescript,javascript',
88
- });
89
- const results = searchFts5(db, 'TypeScript', 10);
90
- expect(results.length).toBe(1);
91
- expect(results[0].slug).toBe('test-doc');
92
- expect(results[0].rank).toBeDefined();
93
- db.close();
94
- });
95
- test('should fall back to pure FTS5 when vec table is missing', () => {
96
- const { hybridSearch } = require('../scripts/lib/hybrid-search.js');
97
- const db = new better_sqlite3_1.default(DB_PATH);
98
- (0, db_js_1.insertFts)(db, {
99
- path: path_1.default.join(TEST_DIR, 'sources', 'fallback.md'),
100
- slug: 'fallback-doc',
101
- description: 'Fallback test document',
102
- type: 'source',
103
- category: 'sources',
104
- title: 'Fallback Doc',
105
- content: 'This tests the graceful fallback to pure FTS5',
106
- tags: 'test',
107
- });
108
- // No vec table loaded — should still work via FTS5 fallback
109
- const results = hybridSearch(db, 'fallback', { maxResults: 5 });
110
- expect(results.length).toBe(1);
111
- expect(results[0].slug).toBe('fallback-doc');
112
- db.close();
113
- });
114
- });
115
- describe('category boost (v0.6.1)', () => {
116
- test('sources weight is higher than cc-session', () => {
117
- expect((0, hybrid_search_js_1.getCategoryWeight)('sources')).toBeGreaterThan((0, hybrid_search_js_1.getCategoryWeight)('cc-session'));
118
- });
119
- test('domains weight is higher than cc-subagent', () => {
120
- expect((0, hybrid_search_js_1.getCategoryWeight)('domains')).toBeGreaterThan((0, hybrid_search_js_1.getCategoryWeight)('cc-subagent'));
121
- });
122
- test('unknown category returns 1.0', () => {
123
- expect((0, hybrid_search_js_1.getCategoryWeight)('unknown-category')).toBe(1.0);
124
- });
125
- test('category boost affects FTS-only hybrid results', () => {
126
- const dbPath = path_1.default.join(TEST_DIR, 'boost.db');
127
- (0, db_js_1.setupTestDir)(TEST_DIR, ['sources']);
128
- const db = (0, db_js_1.createTestDb)(dbPath);
129
- (0, db_js_1.insertFts)(db, { path: '/src.md', slug: 'src', content: 'karar alindi mimari', category: 'sources' });
130
- (0, db_js_1.insertFts)(db, { path: '/sess.md', slug: 'sess', content: 'karar alindi mimari', category: 'cc-session' });
131
- const { hybridSearch } = require('../scripts/lib/hybrid-search.js');
132
- const results = hybridSearch(db, 'karar', { maxResults: 5 });
133
- expect(results.length).toBe(2);
134
- expect(results[0].category).toBe('sources');
135
- db.close();
136
- (0, db_js_1.teardownTestDir)(TEST_DIR);
137
- });
138
- });
139
- //# sourceMappingURL=hybrid-search.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hybrid-search.test.js","sourceRoot":"","sources":["../../tests/hybrid-search.test.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AACxB,oEAAsC;AACtC,2CAAyF;AACzF,sEAAoE;AAEpE,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC;AACnE,MAAM,OAAO,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AAEnD,UAAU,CAAC,GAAG,EAAE;IACd,IAAA,oBAAY,EAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,IAAA,oBAAY,EAAC,OAAO,CAAC,CAAC;IACjC,EAAE,CAAC,KAAK,EAAE,CAAC;AACb,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,IAAA,uBAAe,EAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAI,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC/C,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;QAElE,MAAM,UAAU,GAAG;YACjB,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE;YACxB,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;SACxB,CAAC;QACF,MAAM,UAAU,GAAG;YACjB,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;YAC5B,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;SAC7B,CAAC;QAEF,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QAE5F,kDAAkD;QAClD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU;QACxC,gCAAgC;QAChC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACtD,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;QAElE,MAAM,UAAU,GAAG;YACjB,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE;YACxB,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;SACxB,CAAC;QAEF,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACtD,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;QAElE,MAAM,UAAU,GAAG;YACjB,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;YAC5B,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;SAC7B,CAAC;QAEF,MAAM,KAAK,GAAG,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,gCAAgC;IACnE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,iDAAiD,EAAE,GAAG,EAAE;QAC3D,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;QAElE,yCAAyC;QACzC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAE1C,iEAAiE;QACjE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAE1C,yDAAyD;QACzD,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACxC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;QAErE,6DAA6D;QAC7D,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,IAAI,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACrE,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;QAClE,MAAM,EAAE,GAAG,IAAI,wBAAQ,CAAC,OAAO,CAAC,CAAC;QAEjC,IAAA,iBAAS,EAAC,EAAE,EAAE;YACZ,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC;YAC/C,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,gCAAgC;YAC7C,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,8CAA8C;YACvD,IAAI,EAAE,uBAAuB;SAC9B,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,UAAU,CAAC,EAAE,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;QACjD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAEtC,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACnE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;QACpE,MAAM,EAAE,GAAG,IAAI,wBAAQ,CAAC,OAAO,CAAC,CAAC;QAEjC,IAAA,iBAAS,EAAC,EAAE,EAAE;YACZ,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,aAAa,CAAC;YACnD,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,wBAAwB;YACrC,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,cAAc;YACrB,OAAO,EAAE,+CAA+C;YACxD,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;QAEH,4DAA4D;QAC5D,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QAChE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE7C,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,IAAI,CAAC,0CAA0C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,IAAA,oCAAiB,EAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,IAAA,oCAAiB,EAAC,YAAY,CAAC,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,IAAA,oCAAiB,EAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,IAAA,oCAAiB,EAAC,aAAa,CAAC,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACxC,MAAM,CAAC,IAAA,oCAAiB,EAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,gDAAgD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC/C,IAAA,oBAAY,EAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QACpC,MAAM,EAAE,GAAG,IAAA,oBAAY,EAAC,MAAM,CAAC,CAAC;QAEhC,IAAA,iBAAS,EAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;QACrG,IAAA,iBAAS,EAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;QAE1G,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QAE7D,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE5C,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,IAAA,uBAAe,EAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Tests for embedding pipeline used by --embed flag in index script.
3
- * Tests the library functions (embedding.ts, db-helpers.ts vec functions)
4
- * rather than the CLI subprocess.
5
- */
6
- export {};
7
- //# sourceMappingURL=index-cli-embed.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-cli-embed.test.d.ts","sourceRoot":"","sources":["../../tests/index-cli-embed.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -1,128 +0,0 @@
1
- "use strict";
2
- /**
3
- * Tests for embedding pipeline used by --embed flag in index script.
4
- * Tests the library functions (embedding.ts, db-helpers.ts vec functions)
5
- * rather than the CLI subprocess.
6
- */
7
- var __importDefault = (this && this.__importDefault) || function (mod) {
8
- return (mod && mod.__esModule) ? mod : { "default": mod };
9
- };
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- const path_1 = __importDefault(require("path"));
12
- const db_js_1 = require("./helpers/db.js");
13
- const { hasVecTable, dbAll: dbAllFn } = require('../scripts/lib/db-helpers.js');
14
- const { searchFts5, searchVec, hybridSearch } = require('../scripts/lib/hybrid-search.js');
15
- const TEST_DIR = path_1.default.join(__dirname, '..', '.test-index-cli-embed');
16
- const DB_PATH = path_1.default.join(TEST_DIR, 'mindlore.db');
17
- beforeEach(() => {
18
- (0, db_js_1.setupTestDir)(TEST_DIR, ['sources']);
19
- });
20
- afterEach(() => {
21
- (0, db_js_1.teardownTestDir)(TEST_DIR);
22
- });
23
- describe('Embedding Pipeline — vec table management', () => {
24
- test('should create vec table when sqlite-vec is available', () => {
25
- const { db, vecLoaded } = (0, db_js_1.createTestDbWithVec)(DB_PATH);
26
- if (vecLoaded) {
27
- expect(hasVecTable(db)).toBe(true);
28
- }
29
- else {
30
- expect(hasVecTable(db)).toBe(false);
31
- }
32
- db.close();
33
- });
34
- test('should handle missing sqlite-vec gracefully', () => {
35
- const db = (0, db_js_1.createTestDb)(DB_PATH);
36
- expect(hasVecTable(db)).toBe(false);
37
- db.close();
38
- });
39
- test('should insert and query vec embeddings when vec is available', () => {
40
- const { db, vecLoaded } = (0, db_js_1.createTestDbWithVec)(DB_PATH);
41
- if (!vecLoaded) {
42
- db.close();
43
- return;
44
- }
45
- const testEmbedding = new Float32Array(384);
46
- testEmbedding[0] = 1.0;
47
- (0, db_js_1.insertVec)(db, 'test-doc', testEmbedding, 'test-model');
48
- const rows = dbAllFn(db, 'SELECT slug FROM documents_vec WHERE slug = ?', 'test-doc');
49
- expect(rows).toHaveLength(1);
50
- expect(rows[0]?.slug).toBe('test-doc');
51
- db.close();
52
- });
53
- test('should search vec table with embedding match when available', () => {
54
- const { db, vecLoaded } = (0, db_js_1.createTestDbWithVec)(DB_PATH);
55
- if (!vecLoaded) {
56
- db.close();
57
- return;
58
- }
59
- const embed1 = new Float32Array(384);
60
- embed1[0] = 1.0;
61
- (0, db_js_1.insertVec)(db, 'doc-a', embed1, 'test-model');
62
- const embed2 = new Float32Array(384);
63
- embed2[1] = 1.0;
64
- (0, db_js_1.insertVec)(db, 'doc-b', embed2, 'test-model');
65
- const queryEmbed = new Float32Array(384);
66
- queryEmbed[0] = 0.9;
67
- const results = searchVec(db, Array.from(queryEmbed), 5);
68
- expect(results.length).toBe(2);
69
- expect(results[0].slug).toBe('doc-a');
70
- db.close();
71
- });
72
- });
73
- describe('Embedding Pipeline — FTS5 + vec coexistence', () => {
74
- test('should allow FTS5 and vec tables in same database', () => {
75
- const { db, vecLoaded } = (0, db_js_1.createTestDbWithVec)(DB_PATH);
76
- (0, db_js_1.insertFts)(db, {
77
- path: path_1.default.join(TEST_DIR, 'sources', 'coexist.md'),
78
- slug: 'coexist-doc',
79
- description: 'Test coexistence of FTS5 and vec tables',
80
- type: 'source',
81
- category: 'sources',
82
- title: 'Coexist Doc',
83
- content: 'Testing that both FTS5 and vec work together',
84
- tags: 'test',
85
- });
86
- const ftsResults = searchFts5(db, 'coexistence', 5);
87
- expect(ftsResults.length).toBeGreaterThan(0);
88
- if (vecLoaded) {
89
- const testEmbed = new Float32Array(384);
90
- testEmbed[0] = 1.0;
91
- (0, db_js_1.insertVec)(db, 'coexist-doc', testEmbed, 'test-model');
92
- expect(hasVecTable(db)).toBe(true);
93
- }
94
- db.close();
95
- });
96
- test('should run hybridSearch with both FTS5 data and vec embeddings', () => {
97
- const { db, vecLoaded } = (0, db_js_1.createTestDbWithVec)(DB_PATH);
98
- (0, db_js_1.insertFts)(db, {
99
- path: path_1.default.join(TEST_DIR, 'sources', 'hybrid-test.md'),
100
- slug: 'hybrid-test',
101
- description: 'Document for hybrid search integration test',
102
- type: 'source',
103
- category: 'sources',
104
- title: 'Hybrid Test',
105
- content: 'Hybrid search combines FTS5 keyword and vector semantic results',
106
- tags: 'hybrid,search',
107
- });
108
- if (vecLoaded) {
109
- const testEmbed = new Float32Array(384);
110
- testEmbed[0] = 1.0;
111
- (0, db_js_1.insertVec)(db, 'hybrid-test', testEmbed, 'test-model');
112
- }
113
- let queryEmbed;
114
- if (vecLoaded) {
115
- const q = new Float32Array(384);
116
- q[0] = 0.9;
117
- queryEmbed = Array.from(q);
118
- }
119
- const results = hybridSearch(db, 'hybrid search', {
120
- maxResults: 5,
121
- queryEmbedding: queryEmbed,
122
- });
123
- expect(results.length).toBeGreaterThan(0);
124
- expect(results[0].slug).toBe('hybrid-test');
125
- db.close();
126
- });
127
- });
128
- //# sourceMappingURL=index-cli-embed.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-cli-embed.test.js","sourceRoot":"","sources":["../../tests/index-cli-embed.test.ts"],"names":[],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- /**
2
- * Tests for hybrid search CLI path — tests the library functions
3
- * that --hybrid flag invokes (synonym expansion + hybridSearch integration).
4
- */
5
- export {};
6
- //# sourceMappingURL=search-cli-hybrid.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-cli-hybrid.test.d.ts","sourceRoot":"","sources":["../../tests/search-cli-hybrid.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -1,103 +0,0 @@
1
- "use strict";
2
- /**
3
- * Tests for hybrid search CLI path — tests the library functions
4
- * that --hybrid flag invokes (synonym expansion + hybridSearch integration).
5
- */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- const path_1 = __importDefault(require("path"));
11
- const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
12
- const db_js_1 = require("./helpers/db.js");
13
- const { hybridSearch } = require('../scripts/lib/hybrid-search.js');
14
- const { expandQuery, loadSynonyms } = require('../scripts/lib/synonym.js');
15
- const TEST_DIR = path_1.default.join(__dirname, '..', '.test-search-cli-hybrid');
16
- const DB_PATH = path_1.default.join(TEST_DIR, 'mindlore.db');
17
- beforeEach(() => {
18
- (0, db_js_1.setupTestDir)(TEST_DIR, ['sources', 'domains']);
19
- const db = (0, db_js_1.createTestDb)(DB_PATH);
20
- (0, db_js_1.insertFts)(db, {
21
- path: path_1.default.join(TEST_DIR, 'sources', 'auth-guide.md'),
22
- slug: 'auth-guide',
23
- description: 'Authentication patterns and JWT token management',
24
- type: 'source',
25
- category: 'sources',
26
- title: 'Auth Guide',
27
- content: 'Authentication login patterns for secure applications with JWT tokens',
28
- tags: 'auth,security',
29
- });
30
- (0, db_js_1.insertFts)(db, {
31
- path: path_1.default.join(TEST_DIR, 'domains', 'database.md'),
32
- slug: 'database',
33
- description: 'SQLite and database optimization techniques',
34
- type: 'domain',
35
- category: 'domains',
36
- title: 'Database',
37
- content: 'SQLite FTS5 database optimization and indexing strategies',
38
- tags: 'sqlite,database',
39
- });
40
- db.close();
41
- });
42
- afterEach(() => {
43
- (0, db_js_1.teardownTestDir)(TEST_DIR);
44
- });
45
- describe('Hybrid Search CLI Path — synonym expansion + hybridSearch', () => {
46
- test('should find results via synonym expansion through hybridSearch', () => {
47
- const synonyms = loadSynonyms({
48
- synonyms: {
49
- auth: ['authentication', 'login', 'kimlik doğrulama'],
50
- db: ['database', 'veritabanı', 'sqlite'],
51
- },
52
- });
53
- const query = expandQuery('auth', synonyms).join(' ');
54
- const db = new better_sqlite3_1.default(DB_PATH, { readonly: true });
55
- const results = hybridSearch(db, query, { maxResults: 3 });
56
- expect(results.length).toBeGreaterThan(0);
57
- expect(results[0].slug).toBe('auth-guide');
58
- expect(results[0].score).toBeGreaterThan(0);
59
- db.close();
60
- });
61
- test('should boost results when synonym matches additional terms', () => {
62
- const synonyms = { db: ['database', 'sqlite'] };
63
- const expandedQuery = expandQuery('db', synonyms).join(' ');
64
- const db = new better_sqlite3_1.default(DB_PATH, { readonly: true });
65
- const results = hybridSearch(db, expandedQuery, { maxResults: 3 });
66
- expect(results.length).toBeGreaterThan(0);
67
- expect(results[0].slug).toBe('database');
68
- db.close();
69
- });
70
- test('should return FusedResult format with all expected fields', () => {
71
- const db = new better_sqlite3_1.default(DB_PATH, { readonly: true });
72
- const results = hybridSearch(db, 'authentication', { maxResults: 3 });
73
- expect(results.length).toBeGreaterThan(0);
74
- expect(results[0]).toMatchObject({
75
- slug: expect.any(String),
76
- score: expect.any(Number),
77
- ftsRank: expect.any(Number),
78
- });
79
- db.close();
80
- });
81
- test('should respect maxResults option', () => {
82
- const db = new better_sqlite3_1.default(DB_PATH, { readonly: true });
83
- const results = hybridSearch(db, 'authentication OR database', { maxResults: 1 });
84
- expect(results.length).toBe(1);
85
- db.close();
86
- });
87
- test('should return empty array for unmatched query', () => {
88
- const db = new better_sqlite3_1.default(DB_PATH, { readonly: true });
89
- const results = hybridSearch(db, 'kubernetes docker', { maxResults: 3 });
90
- expect(results).toHaveLength(0);
91
- db.close();
92
- });
93
- test('should handle empty synonyms gracefully', () => {
94
- const synonyms = loadSynonyms({});
95
- const query = expandQuery('database', synonyms).join(' ');
96
- expect(query).toBe('database');
97
- const db = new better_sqlite3_1.default(DB_PATH, { readonly: true });
98
- const results = hybridSearch(db, query, { maxResults: 3 });
99
- expect(results.length).toBeGreaterThan(0);
100
- db.close();
101
- });
102
- });
103
- //# sourceMappingURL=search-cli-hybrid.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-cli-hybrid.test.js","sourceRoot":"","sources":["../../tests/search-cli-hybrid.test.ts"],"names":[],"mappings":"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"}