brainbank 0.8.5 → 0.9.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 +9 -0
- package/dist/{chunk-IB3X5D5Y.js → chunk-Z54MHEYW.js} +70 -15
- package/dist/chunk-Z54MHEYW.js.map +1 -0
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/src/cli/commands/context.ts +4 -1
- package/src/cli/utils.ts +16 -0
- package/src/db/adapter.ts +3 -3
- package/src/db/sqlite-adapter.ts +32 -22
- package/src/engine/reembed.ts +2 -2
- package/src/providers/vector/hnsw-loader.ts +2 -2
- package/src/search/bm25-boost.ts +6 -0
- package/src/search/context-builder.ts +4 -2
- package/src/types.ts +2 -0
- package/dist/chunk-IB3X5D5Y.js.map +0 -1
package/README.md
CHANGED
|
@@ -24,6 +24,15 @@ BrainBank gives LLMs a long-term memory that persists between sessions.
|
|
|
24
24
|
npm i -g brainbank @brainbank/code @brainbank/git @brainbank/docs
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
> [!IMPORTANT]
|
|
28
|
+
> **Node 23+ users:** `@brainbank/code` uses [tree-sitter](https://github.com/tree-sitter/node-tree-sitter) native bindings for AST parsing. On **Node 23 and 24**, V8 headers require C++20 but tree-sitter's `binding.gyp` defaults to C++17, causing the install to fail with `"C++20 or later required."`. Fix it by setting the C++ standard before install:
|
|
29
|
+
>
|
|
30
|
+
> ```bash
|
|
31
|
+
> CXXFLAGS="-std=c++20" npm i -g brainbank
|
|
32
|
+
> ```
|
|
33
|
+
>
|
|
34
|
+
> Node ≤22 is unaffected — prebuilt binaries are available and no compilation is needed.
|
|
35
|
+
|
|
27
36
|
> If you get `ERESOLVE` errors, use `npm i --legacy-peer-deps` — tree-sitter grammars have overlapping peer dep ranges.
|
|
28
37
|
|
|
29
38
|
### CLI — zero code
|
|
@@ -65,7 +65,7 @@ var HNSW = {
|
|
|
65
65
|
};
|
|
66
66
|
|
|
67
67
|
// src/db/sqlite-adapter.ts
|
|
68
|
-
import
|
|
68
|
+
import { DatabaseSync } from "node:sqlite";
|
|
69
69
|
import * as fs from "fs";
|
|
70
70
|
import * as path2 from "path";
|
|
71
71
|
var SCHEMA_VERSION = 9;
|
|
@@ -158,7 +158,7 @@ function wrapStatement(stmt) {
|
|
|
158
158
|
const info = stmt.run(...params);
|
|
159
159
|
return {
|
|
160
160
|
lastInsertRowid: info.lastInsertRowid,
|
|
161
|
-
changes: info.changes
|
|
161
|
+
changes: Number(info.changes)
|
|
162
162
|
};
|
|
163
163
|
},
|
|
164
164
|
iterate(...params) {
|
|
@@ -183,11 +183,11 @@ var SQLiteAdapter = class {
|
|
|
183
183
|
if (!fs.existsSync(dir)) {
|
|
184
184
|
fs.mkdirSync(dir, { recursive: true });
|
|
185
185
|
}
|
|
186
|
-
this._db = new
|
|
187
|
-
this._db.
|
|
188
|
-
this._db.
|
|
189
|
-
this._db.
|
|
190
|
-
this._db.
|
|
186
|
+
this._db = new DatabaseSync(dbPath);
|
|
187
|
+
this._db.exec("PRAGMA journal_mode = WAL");
|
|
188
|
+
this._db.exec("PRAGMA busy_timeout = 5000");
|
|
189
|
+
this._db.exec("PRAGMA synchronous = NORMAL");
|
|
190
|
+
this._db.exec("PRAGMA foreign_keys = ON");
|
|
191
191
|
createSchema(this);
|
|
192
192
|
}
|
|
193
193
|
/** Prepare a reusable statement. */
|
|
@@ -200,25 +200,31 @@ var SQLiteAdapter = class {
|
|
|
200
200
|
}
|
|
201
201
|
/** Run a function inside a transaction. Auto-commits on success, auto-rollbacks on error. */
|
|
202
202
|
transaction(fn) {
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
this._db.exec("BEGIN");
|
|
204
|
+
try {
|
|
205
|
+
const result = fn();
|
|
206
|
+
this._db.exec("COMMIT");
|
|
207
|
+
return result;
|
|
208
|
+
} catch (err) {
|
|
209
|
+
this._db.exec("ROLLBACK");
|
|
210
|
+
throw err;
|
|
211
|
+
}
|
|
205
212
|
}
|
|
206
213
|
/** Run a prepared statement on multiple rows. Wraps in a single transaction. */
|
|
207
214
|
batch(sql, rows) {
|
|
208
215
|
const stmt = this._db.prepare(sql);
|
|
209
|
-
|
|
216
|
+
this.transaction(() => {
|
|
210
217
|
for (const row of rows) {
|
|
211
218
|
stmt.run(...row);
|
|
212
219
|
}
|
|
213
220
|
});
|
|
214
|
-
tx();
|
|
215
221
|
}
|
|
216
222
|
/** Close the database. */
|
|
217
223
|
close() {
|
|
218
224
|
this._db.close();
|
|
219
225
|
}
|
|
220
226
|
/**
|
|
221
|
-
* Access the underlying `
|
|
227
|
+
* Access the underlying `node:sqlite` DatabaseSync instance.
|
|
222
228
|
*
|
|
223
229
|
* @deprecated Use `DatabaseAdapter` methods instead. This exists
|
|
224
230
|
* only for gradual migration of plugins that depend on driver internals.
|
|
@@ -576,6 +582,11 @@ function filterByPath(results, prefix) {
|
|
|
576
582
|
return results.filter((r) => r.filePath?.startsWith(prefix));
|
|
577
583
|
}
|
|
578
584
|
__name(filterByPath, "filterByPath");
|
|
585
|
+
function filterByIgnore(results, ignorePaths) {
|
|
586
|
+
if (!ignorePaths || ignorePaths.length === 0) return results;
|
|
587
|
+
return results.filter((r) => !r.filePath || !ignorePaths.some((p) => r.filePath.startsWith(p)));
|
|
588
|
+
}
|
|
589
|
+
__name(filterByIgnore, "filterByIgnore");
|
|
579
590
|
|
|
580
591
|
// src/lib/logger.ts
|
|
581
592
|
import * as fs2 from "fs";
|
|
@@ -656,6 +667,13 @@ var ContextBuilder = class {
|
|
|
656
667
|
this._configFields = _configFields;
|
|
657
668
|
this._expander = _expander;
|
|
658
669
|
}
|
|
670
|
+
_search;
|
|
671
|
+
_registry;
|
|
672
|
+
_pruner;
|
|
673
|
+
_embedding;
|
|
674
|
+
_rerankerName;
|
|
675
|
+
_configFields;
|
|
676
|
+
_expander;
|
|
659
677
|
static {
|
|
660
678
|
__name(this, "ContextBuilder");
|
|
661
679
|
}
|
|
@@ -679,6 +697,7 @@ var ContextBuilder = class {
|
|
|
679
697
|
mmrLambda
|
|
680
698
|
}) : [];
|
|
681
699
|
results = filterByPath(results, options.pathPrefix);
|
|
700
|
+
results = filterByIgnore(results, options.ignorePaths);
|
|
682
701
|
const pruner = options.pruner ?? this._pruner;
|
|
683
702
|
const beforePrune = results;
|
|
684
703
|
if (pruner && results.length > 1) {
|
|
@@ -718,6 +737,7 @@ ${expanderNote}
|
|
|
718
737
|
options: {
|
|
719
738
|
sources: src,
|
|
720
739
|
pathPrefix: options.pathPrefix,
|
|
740
|
+
ignorePaths: options.ignorePaths,
|
|
721
741
|
minScore,
|
|
722
742
|
affectedFiles: options.affectedFiles
|
|
723
743
|
},
|
|
@@ -865,6 +885,7 @@ var CompositeBM25Search = class {
|
|
|
865
885
|
constructor(_registry) {
|
|
866
886
|
this._registry = _registry;
|
|
867
887
|
}
|
|
888
|
+
_registry;
|
|
868
889
|
static {
|
|
869
890
|
__name(this, "CompositeBM25Search");
|
|
870
891
|
}
|
|
@@ -910,6 +931,7 @@ var CompositeVectorSearch = class _CompositeVectorSearch {
|
|
|
910
931
|
constructor(_c) {
|
|
911
932
|
this._c = _c;
|
|
912
933
|
}
|
|
934
|
+
_c;
|
|
913
935
|
static {
|
|
914
936
|
__name(this, "CompositeVectorSearch");
|
|
915
937
|
}
|
|
@@ -962,6 +984,11 @@ var HNSWIndex = class {
|
|
|
962
984
|
this._efConstruction = _efConstruction;
|
|
963
985
|
this._efSearch = _efSearch;
|
|
964
986
|
}
|
|
987
|
+
_dims;
|
|
988
|
+
_maxElements;
|
|
989
|
+
_M;
|
|
990
|
+
_efConstruction;
|
|
991
|
+
_efSearch;
|
|
965
992
|
static {
|
|
966
993
|
__name(this, "HNSWIndex");
|
|
967
994
|
}
|
|
@@ -1113,6 +1140,12 @@ var Collection = class {
|
|
|
1113
1140
|
this._vecs = _vecs;
|
|
1114
1141
|
this._reranker = _reranker;
|
|
1115
1142
|
}
|
|
1143
|
+
_name;
|
|
1144
|
+
_db;
|
|
1145
|
+
_embedding;
|
|
1146
|
+
_hnsw;
|
|
1147
|
+
_vecs;
|
|
1148
|
+
_reranker;
|
|
1116
1149
|
static {
|
|
1117
1150
|
__name(this, "Collection");
|
|
1118
1151
|
}
|
|
@@ -1390,6 +1423,11 @@ var KVService = class {
|
|
|
1390
1423
|
this._vecs = _vecs;
|
|
1391
1424
|
this._reranker = _reranker;
|
|
1392
1425
|
}
|
|
1426
|
+
_db;
|
|
1427
|
+
_embedding;
|
|
1428
|
+
_hnsw;
|
|
1429
|
+
_vecs;
|
|
1430
|
+
_reranker;
|
|
1393
1431
|
static {
|
|
1394
1432
|
__name(this, "KVService");
|
|
1395
1433
|
}
|
|
@@ -2090,8 +2128,8 @@ async function rebuildHnsw(db, table, hnsw, vecs) {
|
|
|
2090
2128
|
`SELECT ${table.fkColumn} as id, embedding FROM ${table.vectorTable}`
|
|
2091
2129
|
).all();
|
|
2092
2130
|
for (const row of rows) {
|
|
2093
|
-
const
|
|
2094
|
-
const vec = new Float32Array(
|
|
2131
|
+
const emb = row.embedding;
|
|
2132
|
+
const vec = new Float32Array(emb.buffer.slice(emb.byteOffset, emb.byteOffset + emb.byteLength));
|
|
2095
2133
|
hnsw.add(vec, row.id);
|
|
2096
2134
|
vecs.set(row.id, vec);
|
|
2097
2135
|
}
|
|
@@ -2131,6 +2169,7 @@ var SearchAPI = class {
|
|
|
2131
2169
|
constructor(_d) {
|
|
2132
2170
|
this._d = _d;
|
|
2133
2171
|
}
|
|
2172
|
+
_d;
|
|
2134
2173
|
static {
|
|
2135
2174
|
__name(this, "SearchAPI");
|
|
2136
2175
|
}
|
|
@@ -2830,6 +2869,21 @@ function getFlag(name) {
|
|
|
2830
2869
|
return idx >= 0 ? args[idx + 1] : void 0;
|
|
2831
2870
|
}
|
|
2832
2871
|
__name(getFlag, "getFlag");
|
|
2872
|
+
function getFlagAll(name) {
|
|
2873
|
+
const values = [];
|
|
2874
|
+
const flag = `--${name}`;
|
|
2875
|
+
for (let i = 0; i < args.length; i++) {
|
|
2876
|
+
if (args[i] === flag && args[i + 1] && !args[i + 1].startsWith("--")) {
|
|
2877
|
+
for (const v of args[i + 1].split(",")) {
|
|
2878
|
+
const trimmed = v.trim();
|
|
2879
|
+
if (trimmed) values.push(trimmed);
|
|
2880
|
+
}
|
|
2881
|
+
i++;
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
return values;
|
|
2885
|
+
}
|
|
2886
|
+
__name(getFlagAll, "getFlagAll");
|
|
2833
2887
|
function hasFlag(name) {
|
|
2834
2888
|
return args.includes(`--${name}`);
|
|
2835
2889
|
}
|
|
@@ -3249,6 +3303,7 @@ export {
|
|
|
3249
3303
|
c,
|
|
3250
3304
|
args,
|
|
3251
3305
|
getFlag,
|
|
3306
|
+
getFlagAll,
|
|
3252
3307
|
hasFlag,
|
|
3253
3308
|
stripFlags,
|
|
3254
3309
|
printResults,
|
|
@@ -3260,4 +3315,4 @@ export {
|
|
|
3260
3315
|
resetFactoryCache,
|
|
3261
3316
|
createBrain
|
|
3262
3317
|
};
|
|
3263
|
-
//# sourceMappingURL=chunk-
|
|
3318
|
+
//# sourceMappingURL=chunk-Z54MHEYW.js.map
|