mindlore 0.4.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/scripts/lib/constants.d.ts +4 -0
- package/dist/scripts/lib/constants.d.ts.map +1 -1
- package/dist/scripts/lib/constants.js +5 -1
- package/dist/scripts/lib/constants.js.map +1 -1
- package/dist/scripts/lib/db-helpers.d.ts +15 -0
- package/dist/scripts/lib/db-helpers.d.ts.map +1 -1
- package/dist/scripts/lib/db-helpers.js +51 -0
- package/dist/scripts/lib/db-helpers.js.map +1 -1
- package/dist/scripts/lib/embedding.d.ts +5 -0
- package/dist/scripts/lib/embedding.d.ts.map +1 -0
- package/dist/scripts/lib/embedding.js +44 -0
- package/dist/scripts/lib/embedding.js.map +1 -0
- package/dist/scripts/lib/hybrid-search.d.ts +62 -0
- package/dist/scripts/lib/hybrid-search.d.ts.map +1 -0
- package/dist/scripts/lib/hybrid-search.js +150 -0
- package/dist/scripts/lib/hybrid-search.js.map +1 -0
- package/dist/scripts/lib/migrations.d.ts +3 -0
- package/dist/scripts/lib/migrations.d.ts.map +1 -0
- package/dist/scripts/lib/migrations.js +38 -0
- package/dist/scripts/lib/migrations.js.map +1 -0
- package/dist/scripts/lib/schema-version.d.ts +13 -0
- package/dist/scripts/lib/schema-version.d.ts.map +1 -0
- package/dist/scripts/lib/schema-version.js +37 -0
- package/dist/scripts/lib/schema-version.js.map +1 -0
- package/dist/scripts/lib/synonym.d.ts +4 -0
- package/dist/scripts/lib/synonym.d.ts.map +1 -0
- package/dist/scripts/lib/synonym.js +37 -0
- package/dist/scripts/lib/synonym.js.map +1 -0
- package/dist/scripts/mindlore-fts5-index.d.ts +2 -1
- package/dist/scripts/mindlore-fts5-index.d.ts.map +1 -1
- package/dist/scripts/mindlore-fts5-index.js +57 -5
- package/dist/scripts/mindlore-fts5-index.js.map +1 -1
- package/dist/scripts/mindlore-fts5-search.d.ts +3 -2
- package/dist/scripts/mindlore-fts5-search.d.ts.map +1 -1
- package/dist/scripts/mindlore-fts5-search.js +89 -35
- package/dist/scripts/mindlore-fts5-search.js.map +1 -1
- package/dist/scripts/mindlore-health-check.js +52 -0
- package/dist/scripts/mindlore-health-check.js.map +1 -1
- package/dist/tests/embedding.test.d.ts +6 -0
- package/dist/tests/embedding.test.d.ts.map +1 -0
- package/dist/tests/embedding.test.js +71 -0
- package/dist/tests/embedding.test.js.map +1 -0
- package/dist/tests/fts5.test.js +82 -0
- package/dist/tests/fts5.test.js.map +1 -1
- package/dist/tests/helpers/db.d.ts +5 -0
- package/dist/tests/helpers/db.d.ts.map +1 -1
- package/dist/tests/helpers/db.js +19 -0
- package/dist/tests/helpers/db.js.map +1 -1
- package/dist/tests/hybrid-search.test.d.ts +2 -0
- package/dist/tests/hybrid-search.test.d.ts.map +1 -0
- package/dist/tests/hybrid-search.test.js +114 -0
- package/dist/tests/hybrid-search.test.js.map +1 -0
- package/dist/tests/schema-version.test.d.ts +2 -0
- package/dist/tests/schema-version.test.d.ts.map +1 -0
- package/dist/tests/schema-version.test.js +99 -0
- package/dist/tests/schema-version.test.js.map +1 -0
- package/dist/tests/search-hook.test.js +11 -0
- package/dist/tests/search-hook.test.js.map +1 -1
- package/dist/tests/synonym.test.d.ts +2 -0
- package/dist/tests/synonym.test.d.ts.map +1 -0
- package/dist/tests/synonym.test.js +47 -0
- package/dist/tests/synonym.test.js.map +1 -0
- package/hooks/lib/mindlore-common.cjs +32 -0
- package/hooks/mindlore-search.cjs +58 -1
- package/package.json +3 -1
- package/plugin.json +1 -1
- package/templates/config.json +15 -1
package/README.md
CHANGED
|
@@ -163,6 +163,7 @@ SESSION START DURING SESSION SESSIO
|
|
|
163
163
|
- **Project-scoped search** — results filtered by current project, falls back to all projects if none found
|
|
164
164
|
- **No `.mindlore/`?** — hooks silently skip, zero overhead
|
|
165
165
|
- **FTS5 search** — SQLite full-text search with BM25 ranking, no external services
|
|
166
|
+
- **Hybrid search** — RRF fusion combining FTS5 keyword + sqlite-vec vector results with synonym expansion
|
|
166
167
|
- **Content-hash dedup** — SHA256 prevents re-indexing unchanged files
|
|
167
168
|
|
|
168
169
|
## Configuration
|
|
@@ -184,7 +185,7 @@ Skills spawn subagents with `[mindlore:SKILL]` markers — the model-router hook
|
|
|
184
185
|
|
|
185
186
|
## Hooks
|
|
186
187
|
|
|
187
|
-
14 Claude Code lifecycle hooks (v0.
|
|
188
|
+
14 Claude Code lifecycle hooks (v0.5.0):
|
|
188
189
|
|
|
189
190
|
| Event | Hook | What it does |
|
|
190
191
|
|-------|------|-------------|
|
|
@@ -5,6 +5,10 @@ export declare const DIRECTORIES: readonly ["raw", "sources", "domains", "analys
|
|
|
5
5
|
export declare const SKIP_FILES: Set<string>;
|
|
6
6
|
export declare const CONFIG_FILE = "config.json";
|
|
7
7
|
export declare const DEFAULT_MODELS: Record<string, string>;
|
|
8
|
+
export declare const VEC_TABLE_NAME = "documents_vec";
|
|
9
|
+
export declare const SCHEMA_VERSION = 1;
|
|
10
|
+
export declare const EMBEDDING_MODEL_NAME = "Xenova/multilingual-e5-small";
|
|
11
|
+
export declare const EMBEDDING_DIM_CONST = 384;
|
|
8
12
|
export declare const FTS5_COLUMNS: readonly ["path", "slug", "description", "type", "category", "title", "content", "tags", "quality", "date_captured", "project"];
|
|
9
13
|
export type FtsColumn = typeof FTS5_COLUMNS[number];
|
|
10
14
|
export declare const FRONTMATTER_TYPES: readonly ["raw", "source", "domain", "analysis", "diary", "decision", "insight", "connection", "learning"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../scripts/lib/constants.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,cAAc,CAAC;AACxC,eAAO,MAAM,mBAAmB,QAAqE,CAAC;AACtG,eAAO,MAAM,OAAO,gBAAgB,CAAC;AAErC,eAAO,MAAM,WAAW,kHAUd,CAAC;AAEX,eAAO,MAAM,UAAU,aAA+C,CAAC;AAEvE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKxC,CAAC;AAEX,eAAO,MAAM,YAAY,iIAAkI,CAAC;AAC5J,MAAM,MAAM,SAAS,GAAG,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;AAEpD,eAAO,MAAM,iBAAiB,4GAA6G,CAAC;AAC5I,MAAM,MAAM,eAAe,GAAG,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAE/D,eAAO,MAAM,cAAc,oCAAqC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAS3D,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAU9C,CAAC;AAEF,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,EAAE,CAIpC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAErC;AAID,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI3D;AAOD,wBAAgB,aAAa,IAAI,OAAO,CAWvC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAO9C"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../scripts/lib/constants.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,cAAc,CAAC;AACxC,eAAO,MAAM,mBAAmB,QAAqE,CAAC;AACtG,eAAO,MAAM,OAAO,gBAAgB,CAAC;AAErC,eAAO,MAAM,WAAW,kHAUd,CAAC;AAEX,eAAO,MAAM,UAAU,aAA+C,CAAC;AAEvE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKxC,CAAC;AAEX,eAAO,MAAM,cAAc,kBAAkB,CAAC;AAC9C,eAAO,MAAM,cAAc,IAAI,CAAC;AAChC,eAAO,MAAM,oBAAoB,iCAAiC,CAAC;AACnE,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,eAAO,MAAM,YAAY,iIAAkI,CAAC;AAC5J,MAAM,MAAM,SAAS,GAAG,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;AAEpD,eAAO,MAAM,iBAAiB,4GAA6G,CAAC;AAC5I,MAAM,MAAM,eAAe,GAAG,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAE/D,eAAO,MAAM,cAAc,oCAAqC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAS3D,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAU9C,CAAC;AAEF,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,EAAE,CAIpC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAErC;AAID,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI3D;AAOD,wBAAgB,aAAa,IAAI,OAAO,CAWvC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAO9C"}
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.TYPE_TO_DIR = exports.QUALITY_HEURISTICS = exports.QUALITY_VALUES = exports.FRONTMATTER_TYPES = exports.FTS5_COLUMNS = exports.DEFAULT_MODELS = exports.CONFIG_FILE = exports.SKIP_FILES = exports.DIRECTORIES = exports.DB_NAME = exports.GLOBAL_MINDLORE_DIR = exports.MINDLORE_DIR = void 0;
|
|
6
|
+
exports.TYPE_TO_DIR = exports.QUALITY_HEURISTICS = exports.QUALITY_VALUES = exports.FRONTMATTER_TYPES = exports.FTS5_COLUMNS = exports.EMBEDDING_DIM_CONST = exports.EMBEDDING_MODEL_NAME = exports.SCHEMA_VERSION = exports.VEC_TABLE_NAME = exports.DEFAULT_MODELS = exports.CONFIG_FILE = exports.SKIP_FILES = exports.DIRECTORIES = exports.DB_NAME = exports.GLOBAL_MINDLORE_DIR = exports.MINDLORE_DIR = void 0;
|
|
7
7
|
exports.homedir = homedir;
|
|
8
8
|
exports.getActiveMindloreDir = getActiveMindloreDir;
|
|
9
9
|
exports.getAllDbs = getAllDbs;
|
|
@@ -38,6 +38,10 @@ exports.DEFAULT_MODELS = {
|
|
|
38
38
|
explore: 'sonnet',
|
|
39
39
|
default: 'haiku',
|
|
40
40
|
};
|
|
41
|
+
exports.VEC_TABLE_NAME = 'documents_vec';
|
|
42
|
+
exports.SCHEMA_VERSION = 1;
|
|
43
|
+
exports.EMBEDDING_MODEL_NAME = 'Xenova/multilingual-e5-small';
|
|
44
|
+
exports.EMBEDDING_DIM_CONST = 384;
|
|
41
45
|
exports.FTS5_COLUMNS = ['path', 'slug', 'description', 'type', 'category', 'title', 'content', 'tags', 'quality', 'date_captured', 'project'];
|
|
42
46
|
exports.FRONTMATTER_TYPES = ['raw', 'source', 'domain', 'analysis', 'diary', 'decision', 'insight', 'connection', 'learning'];
|
|
43
47
|
exports.QUALITY_VALUES = ['high', 'medium', 'low'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../scripts/lib/constants.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../scripts/lib/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,5 +18,20 @@ export declare function dbAll<T extends Record<string, unknown>>(db: Database, s
|
|
|
18
18
|
* Typed wrapper for Database.pragma().
|
|
19
19
|
*/
|
|
20
20
|
export declare function dbPragma<T>(db: Database, pragma: string): T[];
|
|
21
|
+
/**
|
|
22
|
+
* Load sqlite-vec extension into the database.
|
|
23
|
+
* Returns true if loaded, false if sqlite-vec is not available.
|
|
24
|
+
*/
|
|
25
|
+
export declare function loadSqliteVec(db: Database): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Create documents_vec virtual table if it doesn't exist.
|
|
28
|
+
* Requires sqlite-vec to be loaded first.
|
|
29
|
+
* Silently does nothing if vec0 is not available.
|
|
30
|
+
*/
|
|
31
|
+
export declare function ensureVecTable(db: Database): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Check if documents_vec table exists and is functional.
|
|
34
|
+
*/
|
|
35
|
+
export declare function hasVecTable(db: Database): boolean;
|
|
21
36
|
export {};
|
|
22
37
|
//# sourceMappingURL=db-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-helpers.d.ts","sourceRoot":"","sources":["../../../scripts/lib/db-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAChD,KAAK,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"db-helpers.d.ts","sourceRoot":"","sources":["../../../scripts/lib/db-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAChD,KAAK,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AAIvC;;;GAGG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrD,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,MAAM,EAAE,OAAO,EAAE,GACnB,CAAC,GAAG,SAAS,CAQf;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrD,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,MAAM,EAAE,OAAO,EAAE,GACnB,CAAC,EAAE,CAIL;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,CAI7D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAQnD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAcpD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAOjD"}
|
|
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.dbGet = dbGet;
|
|
4
4
|
exports.dbAll = dbAll;
|
|
5
5
|
exports.dbPragma = dbPragma;
|
|
6
|
+
exports.loadSqliteVec = loadSqliteVec;
|
|
7
|
+
exports.ensureVecTable = ensureVecTable;
|
|
8
|
+
exports.hasVecTable = hasVecTable;
|
|
9
|
+
const constants_js_1 = require("./constants.js");
|
|
6
10
|
/**
|
|
7
11
|
* Typed wrapper for Statement.get().
|
|
8
12
|
* Returns undefined if no row matches.
|
|
@@ -33,4 +37,51 @@ function dbPragma(db, pragma) {
|
|
|
33
37
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- centralized cast: pragma returns array of objects
|
|
34
38
|
return result;
|
|
35
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Load sqlite-vec extension into the database.
|
|
42
|
+
* Returns true if loaded, false if sqlite-vec is not available.
|
|
43
|
+
*/
|
|
44
|
+
function loadSqliteVec(db) {
|
|
45
|
+
try {
|
|
46
|
+
const sqliteVec = require('sqlite-vec');
|
|
47
|
+
sqliteVec.load(db);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
catch (_err) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Create documents_vec virtual table if it doesn't exist.
|
|
56
|
+
* Requires sqlite-vec to be loaded first.
|
|
57
|
+
* Silently does nothing if vec0 is not available.
|
|
58
|
+
*/
|
|
59
|
+
function ensureVecTable(db) {
|
|
60
|
+
try {
|
|
61
|
+
db.exec(`
|
|
62
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS ${constants_js_1.VEC_TABLE_NAME} USING vec0(
|
|
63
|
+
embedding float[${constants_js_1.EMBEDDING_DIM_CONST}],
|
|
64
|
+
slug text,
|
|
65
|
+
+created_at text,
|
|
66
|
+
+model_name text
|
|
67
|
+
)
|
|
68
|
+
`);
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
catch (_err) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if documents_vec table exists and is functional.
|
|
77
|
+
*/
|
|
78
|
+
function hasVecTable(db) {
|
|
79
|
+
try {
|
|
80
|
+
db.prepare(`SELECT slug FROM ${constants_js_1.VEC_TABLE_NAME} LIMIT 0`).run();
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
catch (_err) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
36
87
|
//# sourceMappingURL=db-helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-helpers.js","sourceRoot":"","sources":["../../../scripts/lib/db-helpers.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"db-helpers.js","sourceRoot":"","sources":["../../../scripts/lib/db-helpers.ts"],"names":[],"mappings":";;AAcA,sBAYC;AAKD,sBAQC;AAKD,4BAIC;AAMD,sCAQC;AAOD,wCAcC;AAKD,kCAOC;AAvFD,iDAAqE;AAErE;;;GAGG;AACH,SAAgB,KAAK,CACnB,EAAY,EACZ,GAAW,EACX,GAAG,MAAiB;IAEpB,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAC9C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,SAAS,CAAC,mCAAmC,OAAO,MAAM,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,qHAAqH;IACrH,OAAO,MAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAgB,KAAK,CACnB,EAAY,EACZ,GAAW,EACX,GAAG,MAAiB;IAEpB,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAC/C,mIAAmI;IACnI,OAAO,OAAc,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,SAAgB,QAAQ,CAAI,EAAY,EAAE,MAAc;IACtD,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,4HAA4H;IAC5H,OAAO,MAAa,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,SAAgB,aAAa,CAAC,EAAY;IACxC,IAAI,CAAC;QACH,MAAM,SAAS,GAAoC,OAAO,CAAC,YAAY,CAAC,CAAC;QACzE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,IAAI,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAAC,EAAY;IACzC,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC;2CAC+B,6BAAc;0BAC/B,kCAAmB;;;;;KAKxC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,IAAI,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,EAAY;IACtC,IAAI,CAAC;QACH,EAAE,CAAC,OAAO,CAAC,oBAAoB,6BAAc,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,IAAI,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const EMBEDDING_MODEL = "Xenova/multilingual-e5-small";
|
|
2
|
+
export declare const EMBEDDING_DIM = 384;
|
|
3
|
+
export declare function generateEmbedding(text: string): Promise<number[]>;
|
|
4
|
+
export declare function batchEmbed(texts: string[]): Promise<number[][]>;
|
|
5
|
+
//# sourceMappingURL=embedding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["../../../scripts/lib/embedding.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,iCAAiC,CAAC;AAC9D,eAAO,MAAM,aAAa,MAAM,CAAC;AAgBjC,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAevE;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAMrE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EMBEDDING_DIM = exports.EMBEDDING_MODEL = void 0;
|
|
4
|
+
exports.generateEmbedding = generateEmbedding;
|
|
5
|
+
exports.batchEmbed = batchEmbed;
|
|
6
|
+
exports.EMBEDDING_MODEL = 'Xenova/multilingual-e5-small';
|
|
7
|
+
exports.EMBEDDING_DIM = 384;
|
|
8
|
+
// Pipeline instance — cached after first load (~16s)
|
|
9
|
+
let cachedPipeline = null;
|
|
10
|
+
async function getEmbedder() {
|
|
11
|
+
if (cachedPipeline)
|
|
12
|
+
return cachedPipeline;
|
|
13
|
+
// Dynamic import — @xenova/transformers is ESM
|
|
14
|
+
const { pipeline: createPipeline } = await import('@xenova/transformers');
|
|
15
|
+
cachedPipeline = await createPipeline('feature-extraction', exports.EMBEDDING_MODEL, {
|
|
16
|
+
quantized: true, // int8 quantization — smaller, faster
|
|
17
|
+
});
|
|
18
|
+
return cachedPipeline;
|
|
19
|
+
}
|
|
20
|
+
async function generateEmbedding(text) {
|
|
21
|
+
const embedder = await getEmbedder();
|
|
22
|
+
// multilingual-e5-small expects "query: " or "passage: " prefix
|
|
23
|
+
const prefixed = text.startsWith('query:') || text.startsWith('passage:')
|
|
24
|
+
? text
|
|
25
|
+
: `passage: ${text}`;
|
|
26
|
+
// Pipeline is callable — returns Tensor with tolist()
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- @xenova/transformers pipeline is callable but untyped
|
|
28
|
+
const run = embedder;
|
|
29
|
+
// normalize: true in pipeline options already returns L2-normalized vectors
|
|
30
|
+
const result = await run([prefixed], { pooling: 'mean', normalize: true });
|
|
31
|
+
const list = result.tolist();
|
|
32
|
+
const raw = list[0];
|
|
33
|
+
if (!raw)
|
|
34
|
+
throw new Error('Embedding pipeline returned empty result');
|
|
35
|
+
return raw;
|
|
36
|
+
}
|
|
37
|
+
async function batchEmbed(texts) {
|
|
38
|
+
const results = [];
|
|
39
|
+
for (const text of texts) {
|
|
40
|
+
results.push(await generateEmbedding(text));
|
|
41
|
+
}
|
|
42
|
+
return results;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=embedding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding.js","sourceRoot":"","sources":["../../../scripts/lib/embedding.ts"],"names":[],"mappings":";;;AAiBA,8CAeC;AAED,gCAMC;AAxCY,QAAA,eAAe,GAAG,8BAA8B,CAAC;AACjD,QAAA,aAAa,GAAG,GAAG,CAAC;AAEjC,qDAAqD;AACrD,IAAI,cAAc,GAAY,IAAI,CAAC;AAEnC,KAAK,UAAU,WAAW;IACxB,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAE1C,+CAA+C;IAC/C,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAC1E,cAAc,GAAG,MAAM,cAAc,CAAC,oBAAoB,EAAE,uBAAe,EAAE;QAC3E,SAAS,EAAE,IAAI,EAAE,sCAAsC;KACxD,CAAC,CAAC;IACH,OAAO,cAAc,CAAC;AACxB,CAAC;AAEM,KAAK,UAAU,iBAAiB,CAAC,IAAY;IAClD,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAC;IACrC,gEAAgE;IAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QACvE,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC;IACvB,sDAAsD;IACtD,gIAAgI;IAChI,MAAM,GAAG,GAAG,QAAqG,CAAC;IAClH,4EAA4E;IAC5E,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IACtE,OAAO,GAAG,CAAC;AACb,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,KAAe;IAC9C,MAAM,OAAO,GAAe,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
type Database = BetterSqlite3.Database;
|
|
3
|
+
export interface FtsResult {
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
slug: string;
|
|
6
|
+
rank: number;
|
|
7
|
+
path?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
category?: string;
|
|
11
|
+
tags?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface VecResult {
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
slug: string;
|
|
16
|
+
distance: number;
|
|
17
|
+
}
|
|
18
|
+
export interface FusedResult {
|
|
19
|
+
slug: string;
|
|
20
|
+
score: number;
|
|
21
|
+
ftsRank?: number;
|
|
22
|
+
vecDistance?: number;
|
|
23
|
+
path?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
title?: string;
|
|
26
|
+
category?: string;
|
|
27
|
+
tags?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface RRFOptions {
|
|
30
|
+
k?: number;
|
|
31
|
+
ftsWeight?: number;
|
|
32
|
+
vecWeight?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface HybridSearchOptions {
|
|
35
|
+
maxResults?: number;
|
|
36
|
+
k?: number;
|
|
37
|
+
ftsWeight?: number;
|
|
38
|
+
vecWeight?: number;
|
|
39
|
+
synonyms?: Record<string, string[]>;
|
|
40
|
+
project?: string;
|
|
41
|
+
queryEmbedding?: number[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Convert L2 distance to cosine similarity.
|
|
45
|
+
* For normalized vectors: cosine_sim = 1.0 - (l2_dist² / 2.0)
|
|
46
|
+
*/
|
|
47
|
+
export declare function l2ToCosine(l2Distance: number): number;
|
|
48
|
+
/**
|
|
49
|
+
* Normalize FTS5 BM25 rank to 0-1 range.
|
|
50
|
+
* FTS5 returns negative rank — more negative = better match.
|
|
51
|
+
*/
|
|
52
|
+
export declare function normalizeBM25(rank: number): number;
|
|
53
|
+
export declare function computeRRF(ftsResults: FtsResult[], vecResults: VecResult[], options?: RRFOptions): FusedResult[];
|
|
54
|
+
export declare function searchFts5(db: Database, query: string, limit?: number, project?: string): FtsResult[];
|
|
55
|
+
export declare function searchVec(db: Database, queryEmbedding: number[], limit?: number): VecResult[];
|
|
56
|
+
/**
|
|
57
|
+
* Main hybrid search entry point.
|
|
58
|
+
* Falls back to pure FTS5 when vec table or embedding is not available.
|
|
59
|
+
*/
|
|
60
|
+
export declare function hybridSearch(db: Database, query: string, options?: HybridSearchOptions): FusedResult[];
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=hybrid-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../../../scripts/lib/hybrid-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAGhD,KAAK,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AAEvC,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,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,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,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;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,CAiDf;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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.l2ToCosine = l2ToCosine;
|
|
4
|
+
exports.normalizeBM25 = normalizeBM25;
|
|
5
|
+
exports.computeRRF = computeRRF;
|
|
6
|
+
exports.searchFts5 = searchFts5;
|
|
7
|
+
exports.searchVec = searchVec;
|
|
8
|
+
exports.hybridSearch = hybridSearch;
|
|
9
|
+
const db_helpers_js_1 = require("./db-helpers.js");
|
|
10
|
+
// ── Utility Functions ──────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Convert L2 distance to cosine similarity.
|
|
13
|
+
* For normalized vectors: cosine_sim = 1.0 - (l2_dist² / 2.0)
|
|
14
|
+
*/
|
|
15
|
+
function l2ToCosine(l2Distance) {
|
|
16
|
+
const cosine = 1.0 - (l2Distance * l2Distance / 2.0);
|
|
17
|
+
return Math.max(0.0, Math.min(1.0, cosine));
|
|
18
|
+
}
|
|
19
|
+
// Empirical upper bound for BM25 absolute rank in Mindlore corpus (~150 docs)
|
|
20
|
+
const BM25_MAX_RANK = 25.0;
|
|
21
|
+
/**
|
|
22
|
+
* Normalize FTS5 BM25 rank to 0-1 range.
|
|
23
|
+
* FTS5 returns negative rank — more negative = better match.
|
|
24
|
+
*/
|
|
25
|
+
function normalizeBM25(rank) {
|
|
26
|
+
return Math.abs(rank) / BM25_MAX_RANK;
|
|
27
|
+
}
|
|
28
|
+
// ── RRF Fusion ─────────────────────────────────────────────────────
|
|
29
|
+
function computeRRF(ftsResults, vecResults, options = {}) {
|
|
30
|
+
const k = options.k ?? 60;
|
|
31
|
+
const ftsWeight = options.ftsWeight ?? 0.4;
|
|
32
|
+
const vecWeight = options.vecWeight ?? 0.6;
|
|
33
|
+
const scores = new Map();
|
|
34
|
+
// FTS5 results — already sorted by rank (most negative first = best)
|
|
35
|
+
for (let i = 0; i < ftsResults.length; i++) {
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- loop guard: i < length
|
|
37
|
+
const r = ftsResults[i];
|
|
38
|
+
const rrfScore = ftsWeight * (1.0 / (k + i + 1));
|
|
39
|
+
const existing = scores.get(r.slug);
|
|
40
|
+
if (existing) {
|
|
41
|
+
existing.score += rrfScore;
|
|
42
|
+
existing.ftsRank = r.rank;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
scores.set(r.slug, {
|
|
46
|
+
slug: r.slug,
|
|
47
|
+
score: rrfScore,
|
|
48
|
+
ftsRank: r.rank,
|
|
49
|
+
path: r.path,
|
|
50
|
+
description: r.description,
|
|
51
|
+
title: r.title,
|
|
52
|
+
category: r.category,
|
|
53
|
+
tags: r.tags,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Vec results — already sorted by distance (lowest first = most similar)
|
|
58
|
+
for (let i = 0; i < vecResults.length; i++) {
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- loop guard: i < length
|
|
60
|
+
const r = vecResults[i];
|
|
61
|
+
const rrfScore = vecWeight * (1.0 / (k + i + 1));
|
|
62
|
+
const existing = scores.get(r.slug);
|
|
63
|
+
if (existing) {
|
|
64
|
+
existing.score += rrfScore;
|
|
65
|
+
existing.vecDistance = r.distance;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
scores.set(r.slug, {
|
|
69
|
+
slug: r.slug,
|
|
70
|
+
score: rrfScore,
|
|
71
|
+
vecDistance: r.distance,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return Array.from(scores.values()).sort((a, b) => b.score - a.score);
|
|
76
|
+
}
|
|
77
|
+
// ── Search Functions ───────────────────────────────────────────────
|
|
78
|
+
function searchFts5(db, query, limit = 20, project) {
|
|
79
|
+
const sanitized = query.replace(/["*(){}[\]^~:]/g, '').trim();
|
|
80
|
+
if (!sanitized)
|
|
81
|
+
return [];
|
|
82
|
+
const terms = sanitized.split(/\s+/).map(t => `"${t}"`).join(' OR ');
|
|
83
|
+
try {
|
|
84
|
+
if (project) {
|
|
85
|
+
return (0, db_helpers_js_1.dbAll)(db, `SELECT slug, path, description, title, category, tags, rank
|
|
86
|
+
FROM mindlore_fts
|
|
87
|
+
WHERE mindlore_fts MATCH ? AND project = ?
|
|
88
|
+
ORDER BY rank
|
|
89
|
+
LIMIT ?`, terms, project, limit);
|
|
90
|
+
}
|
|
91
|
+
return (0, db_helpers_js_1.dbAll)(db, `SELECT slug, path, description, title, category, tags, rank
|
|
92
|
+
FROM mindlore_fts
|
|
93
|
+
WHERE mindlore_fts MATCH ?
|
|
94
|
+
ORDER BY rank
|
|
95
|
+
LIMIT ?`, terms, limit);
|
|
96
|
+
}
|
|
97
|
+
catch (_err) {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function searchVec(db, queryEmbedding, limit = 20) {
|
|
102
|
+
try {
|
|
103
|
+
const buf = Buffer.from(new Float32Array(queryEmbedding).buffer);
|
|
104
|
+
return (0, db_helpers_js_1.dbAll)(db, `SELECT slug, distance
|
|
105
|
+
FROM documents_vec
|
|
106
|
+
WHERE embedding MATCH ?
|
|
107
|
+
ORDER BY distance
|
|
108
|
+
LIMIT ?`, buf, limit);
|
|
109
|
+
}
|
|
110
|
+
catch (_err) {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Main hybrid search entry point.
|
|
116
|
+
* Falls back to pure FTS5 when vec table or embedding is not available.
|
|
117
|
+
*/
|
|
118
|
+
function hybridSearch(db, query, options = {}) {
|
|
119
|
+
const maxResults = options.maxResults ?? 5;
|
|
120
|
+
const ftsLimit = 20;
|
|
121
|
+
const vecLimit = 20;
|
|
122
|
+
// Always search FTS5
|
|
123
|
+
const ftsResults = searchFts5(db, query, ftsLimit, options.project);
|
|
124
|
+
// Try vec search if embedding is provided and vec table exists
|
|
125
|
+
let vecResults = [];
|
|
126
|
+
if (options.queryEmbedding && (0, db_helpers_js_1.hasVecTable)(db)) {
|
|
127
|
+
vecResults = searchVec(db, options.queryEmbedding, vecLimit);
|
|
128
|
+
}
|
|
129
|
+
// If no vec results, return FTS5 results directly
|
|
130
|
+
if (vecResults.length === 0) {
|
|
131
|
+
return ftsResults.slice(0, maxResults).map(r => ({
|
|
132
|
+
slug: r.slug,
|
|
133
|
+
score: normalizeBM25(r.rank),
|
|
134
|
+
ftsRank: r.rank,
|
|
135
|
+
path: r.path,
|
|
136
|
+
description: r.description,
|
|
137
|
+
title: r.title,
|
|
138
|
+
category: r.category,
|
|
139
|
+
tags: r.tags,
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
// Fuse results with RRF
|
|
143
|
+
const fused = computeRRF(ftsResults, vecResults, {
|
|
144
|
+
k: options.k,
|
|
145
|
+
ftsWeight: options.ftsWeight,
|
|
146
|
+
vecWeight: options.vecWeight,
|
|
147
|
+
});
|
|
148
|
+
return fused.slice(0, maxResults);
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=hybrid-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hybrid-search.js","sourceRoot":"","sources":["../../../scripts/lib/hybrid-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../scripts/lib/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAKrD,eAAO,MAAM,eAAe,EAAE,SAAS,EAiCtC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.V050_MIGRATIONS = void 0;
|
|
4
|
+
const constants_js_1 = require("./constants.js");
|
|
5
|
+
exports.V050_MIGRATIONS = [
|
|
6
|
+
{
|
|
7
|
+
version: 1,
|
|
8
|
+
name: 'add_vec_table_and_timestamps',
|
|
9
|
+
up: (db) => {
|
|
10
|
+
// 1. Create vec table (requires sqlite-vec loaded — skip gracefully if not)
|
|
11
|
+
try {
|
|
12
|
+
db.exec(`
|
|
13
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS ${constants_js_1.VEC_TABLE_NAME} USING vec0(
|
|
14
|
+
embedding float[${constants_js_1.EMBEDDING_DIM_CONST}],
|
|
15
|
+
slug text,
|
|
16
|
+
+created_at text,
|
|
17
|
+
+model_name text
|
|
18
|
+
)
|
|
19
|
+
`);
|
|
20
|
+
}
|
|
21
|
+
catch (_err) {
|
|
22
|
+
// sqlite-vec not loaded — vec table will be created when extension is available
|
|
23
|
+
}
|
|
24
|
+
// 2. Add timestamp columns to file_hashes
|
|
25
|
+
// (FTS5 virtual tables can't be altered — timestamps go in file_hashes)
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- pragma returns array of objects
|
|
27
|
+
const cols = db.pragma('table_info(file_hashes)');
|
|
28
|
+
const colNames = new Set(cols.map(c => c.name));
|
|
29
|
+
if (!colNames.has('created_at')) {
|
|
30
|
+
db.exec('ALTER TABLE file_hashes ADD COLUMN created_at TEXT');
|
|
31
|
+
}
|
|
32
|
+
if (!colNames.has('updated_at')) {
|
|
33
|
+
db.exec('ALTER TABLE file_hashes ADD COLUMN updated_at TEXT');
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../scripts/lib/migrations.ts"],"names":[],"mappings":";;;AACA,iDAAqE;AAIxD,QAAA,eAAe,GAAgB;IAC1C;QACE,OAAO,EAAE,CAAC;QACV,IAAI,EAAE,8BAA8B;QACpC,EAAE,EAAE,CAAC,EAAY,EAAE,EAAE;YACnB,4EAA4E;YAC5E,IAAI,CAAC;gBACH,EAAE,CAAC,IAAI,CAAC;+CAC+B,6BAAc;8BAC/B,kCAAmB;;;;;SAKxC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC;gBACd,gFAAgF;YAClF,CAAC;YAED,0CAA0C;YAC1C,wEAAwE;YACxE,0GAA0G;YAC1G,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAA4B,CAAC;YAC7E,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAEhD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBAChC,EAAE,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;YAChE,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBAChC,EAAE,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
type Database = BetterSqlite3.Database;
|
|
3
|
+
export interface Migration {
|
|
4
|
+
version: number;
|
|
5
|
+
name: string;
|
|
6
|
+
up: (db: Database) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function ensureSchemaTable(db: Database): void;
|
|
9
|
+
export declare function getSchemaVersion(db: Database): number;
|
|
10
|
+
export declare function setSchemaVersion(db: Database, version: number, name?: string): void;
|
|
11
|
+
export declare function runMigrations(db: Database, migrations: Migration[]): void;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=schema-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-version.d.ts","sourceRoot":"","sources":["../../../scripts/lib/schema-version.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAChD,KAAK,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AAEvC,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC5B;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAQpD;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAKrD;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAKnF;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,CAYzE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureSchemaTable = ensureSchemaTable;
|
|
4
|
+
exports.getSchemaVersion = getSchemaVersion;
|
|
5
|
+
exports.setSchemaVersion = setSchemaVersion;
|
|
6
|
+
exports.runMigrations = runMigrations;
|
|
7
|
+
function ensureSchemaTable(db) {
|
|
8
|
+
db.exec(`
|
|
9
|
+
CREATE TABLE IF NOT EXISTS schema_versions (
|
|
10
|
+
version INTEGER PRIMARY KEY,
|
|
11
|
+
name TEXT NOT NULL,
|
|
12
|
+
applied_at TEXT NOT NULL
|
|
13
|
+
)
|
|
14
|
+
`);
|
|
15
|
+
}
|
|
16
|
+
function getSchemaVersion(db) {
|
|
17
|
+
ensureSchemaTable(db);
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown
|
|
19
|
+
const row = db.prepare('SELECT MAX(version) as v FROM schema_versions').get();
|
|
20
|
+
return row?.v ?? 0;
|
|
21
|
+
}
|
|
22
|
+
function setSchemaVersion(db, version, name) {
|
|
23
|
+
ensureSchemaTable(db);
|
|
24
|
+
db.prepare('INSERT OR REPLACE INTO schema_versions (version, name, applied_at) VALUES (?, ?, ?)').run(version, name ?? `migration_${version}`, new Date().toISOString());
|
|
25
|
+
}
|
|
26
|
+
function runMigrations(db, migrations) {
|
|
27
|
+
ensureSchemaTable(db);
|
|
28
|
+
const current = getSchemaVersion(db);
|
|
29
|
+
const pending = migrations
|
|
30
|
+
.filter(m => m.version > current)
|
|
31
|
+
.sort((a, b) => a.version - b.version);
|
|
32
|
+
for (const migration of pending) {
|
|
33
|
+
migration.up(db);
|
|
34
|
+
setSchemaVersion(db, migration.version, migration.name);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=schema-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-version.js","sourceRoot":"","sources":["../../../scripts/lib/schema-version.ts"],"names":[],"mappings":";;AASA,8CAQC;AAED,4CAKC;AAED,4CAKC;AAED,sCAYC;AApCD,SAAgB,iBAAiB,CAAC,EAAY;IAC5C,EAAE,CAAC,IAAI,CAAC;;;;;;GAMP,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,gBAAgB,CAAC,EAAY;IAC3C,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACtB,gHAAgH;IAChH,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,+CAA+C,CAAC,CAAC,GAAG,EAAsC,CAAC;IAClH,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED,SAAgB,gBAAgB,CAAC,EAAY,EAAE,OAAe,EAAE,IAAa;IAC3E,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACtB,EAAE,CAAC,OAAO,CACR,qFAAqF,CACtF,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,aAAa,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,SAAgB,aAAa,CAAC,EAAY,EAAE,UAAuB;IACjE,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACtB,MAAM,OAAO,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAErC,MAAM,OAAO,GAAG,UAAU;SACvB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC;SAChC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAEzC,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;QAChC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACjB,gBAAgB,CAAC,EAAE,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synonym.d.ts","sourceRoot":"","sources":["../../../scripts/lib/synonym.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAElD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAMxE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,MAAM,EAAE,CA2BzE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadSynonyms = loadSynonyms;
|
|
4
|
+
exports.expandQuery = expandQuery;
|
|
5
|
+
function loadSynonyms(config) {
|
|
6
|
+
if (!config || typeof config.synonyms !== 'object' || config.synonyms === null) {
|
|
7
|
+
return {};
|
|
8
|
+
}
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- runtime-validated object shape
|
|
10
|
+
return config.synonyms;
|
|
11
|
+
}
|
|
12
|
+
function expandQuery(query, synonyms) {
|
|
13
|
+
const terms = query.trim().split(/\s+/).filter(Boolean);
|
|
14
|
+
if (terms.length === 0)
|
|
15
|
+
return [];
|
|
16
|
+
const expanded = [];
|
|
17
|
+
const seen = new Set();
|
|
18
|
+
for (const term of terms) {
|
|
19
|
+
const lower = term.toLowerCase();
|
|
20
|
+
if (!seen.has(lower)) {
|
|
21
|
+
seen.add(lower);
|
|
22
|
+
expanded.push(term);
|
|
23
|
+
}
|
|
24
|
+
const syns = synonyms[lower];
|
|
25
|
+
if (syns) {
|
|
26
|
+
for (const syn of syns) {
|
|
27
|
+
const synLower = syn.toLowerCase();
|
|
28
|
+
if (!seen.has(synLower)) {
|
|
29
|
+
seen.add(synLower);
|
|
30
|
+
expanded.push(syn);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return expanded;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=synonym.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synonym.js","sourceRoot":"","sources":["../../../scripts/lib/synonym.ts"],"names":[],"mappings":";;AAEA,oCAMC;AAED,kCA2BC;AAnCD,SAAgB,YAAY,CAAC,MAA+B;IAC1D,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC/E,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,yGAAyG;IACzG,OAAO,MAAM,CAAC,QAAsB,CAAC;AACvC,CAAC;AAED,SAAgB,WAAW,CAAC,KAAa,EAAE,QAAoB;IAC7D,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAChB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;gBACnC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACxB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;oBACnB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|