@plur-ai/core 0.4.0 → 0.4.1

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/index.js CHANGED
@@ -6,9 +6,787 @@ import {
6
6
  ftsTokenize,
7
7
  getSyncStatus,
8
8
  searchEngrams,
9
- sync
10
- } from "./chunk-WPD4MPTT.js";
11
- import "./chunk-2ZDO52B4.js";
9
+ sync,
10
+ withLock
11
+ } from "./chunk-KMVQYBNP.js";
12
+ import {
13
+ __commonJS,
14
+ __require
15
+ } from "./chunk-2ZDO52B4.js";
16
+
17
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/util.js
18
+ var require_util = __commonJS({
19
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/util.js"(exports) {
20
+ "use strict";
21
+ exports.getBooleanOption = (options, key) => {
22
+ let value = false;
23
+ if (key in options && typeof (value = options[key]) !== "boolean") {
24
+ throw new TypeError(`Expected the "${key}" option to be a boolean`);
25
+ }
26
+ return value;
27
+ };
28
+ exports.cppdb = /* @__PURE__ */ Symbol();
29
+ exports.inspect = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
30
+ }
31
+ });
32
+
33
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/sqlite-error.js
34
+ var require_sqlite_error = __commonJS({
35
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/sqlite-error.js"(exports, module) {
36
+ "use strict";
37
+ var descriptor = { value: "SqliteError", writable: true, enumerable: false, configurable: true };
38
+ function SqliteError(message, code) {
39
+ if (new.target !== SqliteError) {
40
+ return new SqliteError(message, code);
41
+ }
42
+ if (typeof code !== "string") {
43
+ throw new TypeError("Expected second argument to be a string");
44
+ }
45
+ Error.call(this, message);
46
+ descriptor.value = "" + message;
47
+ Object.defineProperty(this, "message", descriptor);
48
+ Error.captureStackTrace(this, SqliteError);
49
+ this.code = code;
50
+ }
51
+ Object.setPrototypeOf(SqliteError, Error);
52
+ Object.setPrototypeOf(SqliteError.prototype, Error.prototype);
53
+ Object.defineProperty(SqliteError.prototype, "name", descriptor);
54
+ module.exports = SqliteError;
55
+ }
56
+ });
57
+
58
+ // ../../node_modules/.pnpm/file-uri-to-path@1.0.0/node_modules/file-uri-to-path/index.js
59
+ var require_file_uri_to_path = __commonJS({
60
+ "../../node_modules/.pnpm/file-uri-to-path@1.0.0/node_modules/file-uri-to-path/index.js"(exports, module) {
61
+ "use strict";
62
+ var sep = __require("path").sep || "/";
63
+ module.exports = fileUriToPath;
64
+ function fileUriToPath(uri) {
65
+ if ("string" != typeof uri || uri.length <= 7 || "file://" != uri.substring(0, 7)) {
66
+ throw new TypeError("must pass in a file:// URI to convert to a file path");
67
+ }
68
+ var rest = decodeURI(uri.substring(7));
69
+ var firstSlash = rest.indexOf("/");
70
+ var host = rest.substring(0, firstSlash);
71
+ var path2 = rest.substring(firstSlash + 1);
72
+ if ("localhost" == host) host = "";
73
+ if (host) {
74
+ host = sep + sep + host;
75
+ }
76
+ path2 = path2.replace(/^(.+)\|/, "$1:");
77
+ if (sep == "\\") {
78
+ path2 = path2.replace(/\//g, "\\");
79
+ }
80
+ if (/^.+\:/.test(path2)) {
81
+ } else {
82
+ path2 = sep + path2;
83
+ }
84
+ return host + path2;
85
+ }
86
+ }
87
+ });
88
+
89
+ // ../../node_modules/.pnpm/bindings@1.5.0/node_modules/bindings/bindings.js
90
+ var require_bindings = __commonJS({
91
+ "../../node_modules/.pnpm/bindings@1.5.0/node_modules/bindings/bindings.js"(exports, module) {
92
+ "use strict";
93
+ var fs3 = __require("fs");
94
+ var path2 = __require("path");
95
+ var fileURLToPath = require_file_uri_to_path();
96
+ var join3 = path2.join;
97
+ var dirname = path2.dirname;
98
+ var exists = fs3.accessSync && function(path3) {
99
+ try {
100
+ fs3.accessSync(path3);
101
+ } catch (e) {
102
+ return false;
103
+ }
104
+ return true;
105
+ } || fs3.existsSync || path2.existsSync;
106
+ var defaults = {
107
+ arrow: process.env.NODE_BINDINGS_ARROW || " \u2192 ",
108
+ compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
109
+ platform: process.platform,
110
+ arch: process.arch,
111
+ nodePreGyp: "node-v" + process.versions.modules + "-" + process.platform + "-" + process.arch,
112
+ version: process.versions.node,
113
+ bindings: "bindings.node",
114
+ try: [
115
+ // node-gyp's linked version in the "build" dir
116
+ ["module_root", "build", "bindings"],
117
+ // node-waf and gyp_addon (a.k.a node-gyp)
118
+ ["module_root", "build", "Debug", "bindings"],
119
+ ["module_root", "build", "Release", "bindings"],
120
+ // Debug files, for development (legacy behavior, remove for node v0.9)
121
+ ["module_root", "out", "Debug", "bindings"],
122
+ ["module_root", "Debug", "bindings"],
123
+ // Release files, but manually compiled (legacy behavior, remove for node v0.9)
124
+ ["module_root", "out", "Release", "bindings"],
125
+ ["module_root", "Release", "bindings"],
126
+ // Legacy from node-waf, node <= 0.4.x
127
+ ["module_root", "build", "default", "bindings"],
128
+ // Production "Release" buildtype binary (meh...)
129
+ ["module_root", "compiled", "version", "platform", "arch", "bindings"],
130
+ // node-qbs builds
131
+ ["module_root", "addon-build", "release", "install-root", "bindings"],
132
+ ["module_root", "addon-build", "debug", "install-root", "bindings"],
133
+ ["module_root", "addon-build", "default", "install-root", "bindings"],
134
+ // node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch}
135
+ ["module_root", "lib", "binding", "nodePreGyp", "bindings"]
136
+ ]
137
+ };
138
+ function bindings(opts) {
139
+ if (typeof opts == "string") {
140
+ opts = { bindings: opts };
141
+ } else if (!opts) {
142
+ opts = {};
143
+ }
144
+ Object.keys(defaults).map(function(i2) {
145
+ if (!(i2 in opts)) opts[i2] = defaults[i2];
146
+ });
147
+ if (!opts.module_root) {
148
+ opts.module_root = exports.getRoot(exports.getFileName());
149
+ }
150
+ if (path2.extname(opts.bindings) != ".node") {
151
+ opts.bindings += ".node";
152
+ }
153
+ var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
154
+ var tries = [], i = 0, l = opts.try.length, n, b, err;
155
+ for (; i < l; i++) {
156
+ n = join3.apply(
157
+ null,
158
+ opts.try[i].map(function(p) {
159
+ return opts[p] || p;
160
+ })
161
+ );
162
+ tries.push(n);
163
+ try {
164
+ b = opts.path ? requireFunc.resolve(n) : requireFunc(n);
165
+ if (!opts.path) {
166
+ b.path = n;
167
+ }
168
+ return b;
169
+ } catch (e) {
170
+ if (e.code !== "MODULE_NOT_FOUND" && e.code !== "QUALIFIED_PATH_RESOLUTION_FAILED" && !/not find/i.test(e.message)) {
171
+ throw e;
172
+ }
173
+ }
174
+ }
175
+ err = new Error(
176
+ "Could not locate the bindings file. Tried:\n" + tries.map(function(a) {
177
+ return opts.arrow + a;
178
+ }).join("\n")
179
+ );
180
+ err.tries = tries;
181
+ throw err;
182
+ }
183
+ module.exports = exports = bindings;
184
+ exports.getFileName = function getFileName(calling_file) {
185
+ var origPST = Error.prepareStackTrace, origSTL = Error.stackTraceLimit, dummy = {}, fileName;
186
+ Error.stackTraceLimit = 10;
187
+ Error.prepareStackTrace = function(e, st) {
188
+ for (var i = 0, l = st.length; i < l; i++) {
189
+ fileName = st[i].getFileName();
190
+ if (fileName !== __filename) {
191
+ if (calling_file) {
192
+ if (fileName !== calling_file) {
193
+ return;
194
+ }
195
+ } else {
196
+ return;
197
+ }
198
+ }
199
+ }
200
+ };
201
+ Error.captureStackTrace(dummy);
202
+ dummy.stack;
203
+ Error.prepareStackTrace = origPST;
204
+ Error.stackTraceLimit = origSTL;
205
+ var fileSchema = "file://";
206
+ if (fileName.indexOf(fileSchema) === 0) {
207
+ fileName = fileURLToPath(fileName);
208
+ }
209
+ return fileName;
210
+ };
211
+ exports.getRoot = function getRoot(file) {
212
+ var dir = dirname(file), prev;
213
+ while (true) {
214
+ if (dir === ".") {
215
+ dir = process.cwd();
216
+ }
217
+ if (exists(join3(dir, "package.json")) || exists(join3(dir, "node_modules"))) {
218
+ return dir;
219
+ }
220
+ if (prev === dir) {
221
+ throw new Error(
222
+ 'Could not find module root given file: "' + file + '". Do you have a `package.json` file? '
223
+ );
224
+ }
225
+ prev = dir;
226
+ dir = join3(dir, "..");
227
+ }
228
+ };
229
+ }
230
+ });
231
+
232
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/wrappers.js
233
+ var require_wrappers = __commonJS({
234
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/wrappers.js"(exports) {
235
+ "use strict";
236
+ var { cppdb } = require_util();
237
+ exports.prepare = function prepare(sql) {
238
+ return this[cppdb].prepare(sql, this, false);
239
+ };
240
+ exports.exec = function exec(sql) {
241
+ this[cppdb].exec(sql);
242
+ return this;
243
+ };
244
+ exports.close = function close() {
245
+ this[cppdb].close();
246
+ return this;
247
+ };
248
+ exports.loadExtension = function loadExtension(...args) {
249
+ this[cppdb].loadExtension(...args);
250
+ return this;
251
+ };
252
+ exports.defaultSafeIntegers = function defaultSafeIntegers(...args) {
253
+ this[cppdb].defaultSafeIntegers(...args);
254
+ return this;
255
+ };
256
+ exports.unsafeMode = function unsafeMode(...args) {
257
+ this[cppdb].unsafeMode(...args);
258
+ return this;
259
+ };
260
+ exports.getters = {
261
+ name: {
262
+ get: function name() {
263
+ return this[cppdb].name;
264
+ },
265
+ enumerable: true
266
+ },
267
+ open: {
268
+ get: function open() {
269
+ return this[cppdb].open;
270
+ },
271
+ enumerable: true
272
+ },
273
+ inTransaction: {
274
+ get: function inTransaction() {
275
+ return this[cppdb].inTransaction;
276
+ },
277
+ enumerable: true
278
+ },
279
+ readonly: {
280
+ get: function readonly() {
281
+ return this[cppdb].readonly;
282
+ },
283
+ enumerable: true
284
+ },
285
+ memory: {
286
+ get: function memory() {
287
+ return this[cppdb].memory;
288
+ },
289
+ enumerable: true
290
+ }
291
+ };
292
+ }
293
+ });
294
+
295
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/transaction.js
296
+ var require_transaction = __commonJS({
297
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/transaction.js"(exports, module) {
298
+ "use strict";
299
+ var { cppdb } = require_util();
300
+ var controllers = /* @__PURE__ */ new WeakMap();
301
+ module.exports = function transaction(fn) {
302
+ if (typeof fn !== "function") throw new TypeError("Expected first argument to be a function");
303
+ const db = this[cppdb];
304
+ const controller = getController(db, this);
305
+ const { apply } = Function.prototype;
306
+ const properties = {
307
+ default: { value: wrapTransaction(apply, fn, db, controller.default) },
308
+ deferred: { value: wrapTransaction(apply, fn, db, controller.deferred) },
309
+ immediate: { value: wrapTransaction(apply, fn, db, controller.immediate) },
310
+ exclusive: { value: wrapTransaction(apply, fn, db, controller.exclusive) },
311
+ database: { value: this, enumerable: true }
312
+ };
313
+ Object.defineProperties(properties.default.value, properties);
314
+ Object.defineProperties(properties.deferred.value, properties);
315
+ Object.defineProperties(properties.immediate.value, properties);
316
+ Object.defineProperties(properties.exclusive.value, properties);
317
+ return properties.default.value;
318
+ };
319
+ var getController = (db, self) => {
320
+ let controller = controllers.get(db);
321
+ if (!controller) {
322
+ const shared = {
323
+ commit: db.prepare("COMMIT", self, false),
324
+ rollback: db.prepare("ROLLBACK", self, false),
325
+ savepoint: db.prepare("SAVEPOINT ` _bs3. `", self, false),
326
+ release: db.prepare("RELEASE ` _bs3. `", self, false),
327
+ rollbackTo: db.prepare("ROLLBACK TO ` _bs3. `", self, false)
328
+ };
329
+ controllers.set(db, controller = {
330
+ default: Object.assign({ begin: db.prepare("BEGIN", self, false) }, shared),
331
+ deferred: Object.assign({ begin: db.prepare("BEGIN DEFERRED", self, false) }, shared),
332
+ immediate: Object.assign({ begin: db.prepare("BEGIN IMMEDIATE", self, false) }, shared),
333
+ exclusive: Object.assign({ begin: db.prepare("BEGIN EXCLUSIVE", self, false) }, shared)
334
+ });
335
+ }
336
+ return controller;
337
+ };
338
+ var wrapTransaction = (apply, fn, db, { begin, commit, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction() {
339
+ let before, after, undo;
340
+ if (db.inTransaction) {
341
+ before = savepoint;
342
+ after = release;
343
+ undo = rollbackTo;
344
+ } else {
345
+ before = begin;
346
+ after = commit;
347
+ undo = rollback;
348
+ }
349
+ before.run();
350
+ try {
351
+ const result = apply.call(fn, this, arguments);
352
+ if (result && typeof result.then === "function") {
353
+ throw new TypeError("Transaction function cannot return a promise");
354
+ }
355
+ after.run();
356
+ return result;
357
+ } catch (ex) {
358
+ if (db.inTransaction) {
359
+ undo.run();
360
+ if (undo !== rollback) after.run();
361
+ }
362
+ throw ex;
363
+ }
364
+ };
365
+ }
366
+ });
367
+
368
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/pragma.js
369
+ var require_pragma = __commonJS({
370
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/pragma.js"(exports, module) {
371
+ "use strict";
372
+ var { getBooleanOption, cppdb } = require_util();
373
+ module.exports = function pragma(source, options) {
374
+ if (options == null) options = {};
375
+ if (typeof source !== "string") throw new TypeError("Expected first argument to be a string");
376
+ if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
377
+ const simple = getBooleanOption(options, "simple");
378
+ const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);
379
+ return simple ? stmt.pluck().get() : stmt.all();
380
+ };
381
+ }
382
+ });
383
+
384
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/backup.js
385
+ var require_backup = __commonJS({
386
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/backup.js"(exports, module) {
387
+ "use strict";
388
+ var fs3 = __require("fs");
389
+ var path2 = __require("path");
390
+ var { promisify } = __require("util");
391
+ var { cppdb } = require_util();
392
+ var fsAccess = promisify(fs3.access);
393
+ module.exports = async function backup(filename, options) {
394
+ if (options == null) options = {};
395
+ if (typeof filename !== "string") throw new TypeError("Expected first argument to be a string");
396
+ if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
397
+ filename = filename.trim();
398
+ const attachedName = "attached" in options ? options.attached : "main";
399
+ const handler = "progress" in options ? options.progress : null;
400
+ if (!filename) throw new TypeError("Backup filename cannot be an empty string");
401
+ if (filename === ":memory:") throw new TypeError('Invalid backup filename ":memory:"');
402
+ if (typeof attachedName !== "string") throw new TypeError('Expected the "attached" option to be a string');
403
+ if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
404
+ if (handler != null && typeof handler !== "function") throw new TypeError('Expected the "progress" option to be a function');
405
+ await fsAccess(path2.dirname(filename)).catch(() => {
406
+ throw new TypeError("Cannot save backup because the directory does not exist");
407
+ });
408
+ const isNewFile = await fsAccess(filename).then(() => false, () => true);
409
+ return runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null);
410
+ };
411
+ var runBackup = (backup, handler) => {
412
+ let rate = 0;
413
+ let useDefault = true;
414
+ return new Promise((resolve, reject) => {
415
+ setImmediate(function step() {
416
+ try {
417
+ const progress = backup.transfer(rate);
418
+ if (!progress.remainingPages) {
419
+ backup.close();
420
+ resolve(progress);
421
+ return;
422
+ }
423
+ if (useDefault) {
424
+ useDefault = false;
425
+ rate = 100;
426
+ }
427
+ if (handler) {
428
+ const ret = handler(progress);
429
+ if (ret !== void 0) {
430
+ if (typeof ret === "number" && ret === ret) rate = Math.max(0, Math.min(2147483647, Math.round(ret)));
431
+ else throw new TypeError("Expected progress callback to return a number or undefined");
432
+ }
433
+ }
434
+ setImmediate(step);
435
+ } catch (err) {
436
+ backup.close();
437
+ reject(err);
438
+ }
439
+ });
440
+ });
441
+ };
442
+ }
443
+ });
444
+
445
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/serialize.js
446
+ var require_serialize = __commonJS({
447
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/serialize.js"(exports, module) {
448
+ "use strict";
449
+ var { cppdb } = require_util();
450
+ module.exports = function serialize(options) {
451
+ if (options == null) options = {};
452
+ if (typeof options !== "object") throw new TypeError("Expected first argument to be an options object");
453
+ const attachedName = "attached" in options ? options.attached : "main";
454
+ if (typeof attachedName !== "string") throw new TypeError('Expected the "attached" option to be a string');
455
+ if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
456
+ return this[cppdb].serialize(attachedName);
457
+ };
458
+ }
459
+ });
460
+
461
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/function.js
462
+ var require_function = __commonJS({
463
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/function.js"(exports, module) {
464
+ "use strict";
465
+ var { getBooleanOption, cppdb } = require_util();
466
+ module.exports = function defineFunction(name, options, fn) {
467
+ if (options == null) options = {};
468
+ if (typeof options === "function") {
469
+ fn = options;
470
+ options = {};
471
+ }
472
+ if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
473
+ if (typeof fn !== "function") throw new TypeError("Expected last argument to be a function");
474
+ if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
475
+ if (!name) throw new TypeError("User-defined function name cannot be an empty string");
476
+ const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
477
+ const deterministic = getBooleanOption(options, "deterministic");
478
+ const directOnly = getBooleanOption(options, "directOnly");
479
+ const varargs = getBooleanOption(options, "varargs");
480
+ let argCount = -1;
481
+ if (!varargs) {
482
+ argCount = fn.length;
483
+ if (!Number.isInteger(argCount) || argCount < 0) throw new TypeError("Expected function.length to be a positive integer");
484
+ if (argCount > 100) throw new RangeError("User-defined functions cannot have more than 100 arguments");
485
+ }
486
+ this[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly);
487
+ return this;
488
+ };
489
+ }
490
+ });
491
+
492
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/aggregate.js
493
+ var require_aggregate = __commonJS({
494
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/aggregate.js"(exports, module) {
495
+ "use strict";
496
+ var { getBooleanOption, cppdb } = require_util();
497
+ module.exports = function defineAggregate(name, options) {
498
+ if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
499
+ if (typeof options !== "object" || options === null) throw new TypeError("Expected second argument to be an options object");
500
+ if (!name) throw new TypeError("User-defined function name cannot be an empty string");
501
+ const start = "start" in options ? options.start : null;
502
+ const step = getFunctionOption(options, "step", true);
503
+ const inverse = getFunctionOption(options, "inverse", false);
504
+ const result = getFunctionOption(options, "result", false);
505
+ const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
506
+ const deterministic = getBooleanOption(options, "deterministic");
507
+ const directOnly = getBooleanOption(options, "directOnly");
508
+ const varargs = getBooleanOption(options, "varargs");
509
+ let argCount = -1;
510
+ if (!varargs) {
511
+ argCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0);
512
+ if (argCount > 0) argCount -= 1;
513
+ if (argCount > 100) throw new RangeError("User-defined functions cannot have more than 100 arguments");
514
+ }
515
+ this[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly);
516
+ return this;
517
+ };
518
+ var getFunctionOption = (options, key, required) => {
519
+ const value = key in options ? options[key] : null;
520
+ if (typeof value === "function") return value;
521
+ if (value != null) throw new TypeError(`Expected the "${key}" option to be a function`);
522
+ if (required) throw new TypeError(`Missing required option "${key}"`);
523
+ return null;
524
+ };
525
+ var getLength = ({ length }) => {
526
+ if (Number.isInteger(length) && length >= 0) return length;
527
+ throw new TypeError("Expected function.length to be a positive integer");
528
+ };
529
+ }
530
+ });
531
+
532
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/table.js
533
+ var require_table = __commonJS({
534
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/table.js"(exports, module) {
535
+ "use strict";
536
+ var { cppdb } = require_util();
537
+ module.exports = function defineTable(name, factory) {
538
+ if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
539
+ if (!name) throw new TypeError("Virtual table module name cannot be an empty string");
540
+ let eponymous = false;
541
+ if (typeof factory === "object" && factory !== null) {
542
+ eponymous = true;
543
+ factory = defer(parseTableDefinition(factory, "used", name));
544
+ } else {
545
+ if (typeof factory !== "function") throw new TypeError("Expected second argument to be a function or a table definition object");
546
+ factory = wrapFactory(factory);
547
+ }
548
+ this[cppdb].table(factory, name, eponymous);
549
+ return this;
550
+ };
551
+ function wrapFactory(factory) {
552
+ return function virtualTableFactory(moduleName, databaseName, tableName, ...args) {
553
+ const thisObject = {
554
+ module: moduleName,
555
+ database: databaseName,
556
+ table: tableName
557
+ };
558
+ const def = apply.call(factory, thisObject, args);
559
+ if (typeof def !== "object" || def === null) {
560
+ throw new TypeError(`Virtual table module "${moduleName}" did not return a table definition object`);
561
+ }
562
+ return parseTableDefinition(def, "returned", moduleName);
563
+ };
564
+ }
565
+ function parseTableDefinition(def, verb, moduleName) {
566
+ if (!hasOwnProperty.call(def, "rows")) {
567
+ throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "rows" property`);
568
+ }
569
+ if (!hasOwnProperty.call(def, "columns")) {
570
+ throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "columns" property`);
571
+ }
572
+ const rows = def.rows;
573
+ if (typeof rows !== "function" || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) {
574
+ throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "rows" property (should be a generator function)`);
575
+ }
576
+ let columns = def.columns;
577
+ if (!Array.isArray(columns) || !(columns = [...columns]).every((x) => typeof x === "string")) {
578
+ throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "columns" property (should be an array of strings)`);
579
+ }
580
+ if (columns.length !== new Set(columns).size) {
581
+ throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate column names`);
582
+ }
583
+ if (!columns.length) {
584
+ throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with zero columns`);
585
+ }
586
+ let parameters;
587
+ if (hasOwnProperty.call(def, "parameters")) {
588
+ parameters = def.parameters;
589
+ if (!Array.isArray(parameters) || !(parameters = [...parameters]).every((x) => typeof x === "string")) {
590
+ throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "parameters" property (should be an array of strings)`);
591
+ }
592
+ } else {
593
+ parameters = inferParameters(rows);
594
+ }
595
+ if (parameters.length !== new Set(parameters).size) {
596
+ throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate parameter names`);
597
+ }
598
+ if (parameters.length > 32) {
599
+ throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with more than the maximum number of 32 parameters`);
600
+ }
601
+ for (const parameter of parameters) {
602
+ if (columns.includes(parameter)) {
603
+ throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with column "${parameter}" which was ambiguously defined as both a column and parameter`);
604
+ }
605
+ }
606
+ let safeIntegers = 2;
607
+ if (hasOwnProperty.call(def, "safeIntegers")) {
608
+ const bool = def.safeIntegers;
609
+ if (typeof bool !== "boolean") {
610
+ throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "safeIntegers" property (should be a boolean)`);
611
+ }
612
+ safeIntegers = +bool;
613
+ }
614
+ let directOnly = false;
615
+ if (hasOwnProperty.call(def, "directOnly")) {
616
+ directOnly = def.directOnly;
617
+ if (typeof directOnly !== "boolean") {
618
+ throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "directOnly" property (should be a boolean)`);
619
+ }
620
+ }
621
+ const columnDefinitions = [
622
+ ...parameters.map(identifier).map((str) => `${str} HIDDEN`),
623
+ ...columns.map(identifier)
624
+ ];
625
+ return [
626
+ `CREATE TABLE x(${columnDefinitions.join(", ")});`,
627
+ wrapGenerator(rows, new Map(columns.map((x, i) => [x, parameters.length + i])), moduleName),
628
+ parameters,
629
+ safeIntegers,
630
+ directOnly
631
+ ];
632
+ }
633
+ function wrapGenerator(generator, columnMap, moduleName) {
634
+ return function* virtualTable(...args) {
635
+ const output = args.map((x) => Buffer.isBuffer(x) ? Buffer.from(x) : x);
636
+ for (let i = 0; i < columnMap.size; ++i) {
637
+ output.push(null);
638
+ }
639
+ for (const row of generator(...args)) {
640
+ if (Array.isArray(row)) {
641
+ extractRowArray(row, output, columnMap.size, moduleName);
642
+ yield output;
643
+ } else if (typeof row === "object" && row !== null) {
644
+ extractRowObject(row, output, columnMap, moduleName);
645
+ yield output;
646
+ } else {
647
+ throw new TypeError(`Virtual table module "${moduleName}" yielded something that isn't a valid row object`);
648
+ }
649
+ }
650
+ };
651
+ }
652
+ function extractRowArray(row, output, columnCount, moduleName) {
653
+ if (row.length !== columnCount) {
654
+ throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an incorrect number of columns`);
655
+ }
656
+ const offset = output.length - columnCount;
657
+ for (let i = 0; i < columnCount; ++i) {
658
+ output[i + offset] = row[i];
659
+ }
660
+ }
661
+ function extractRowObject(row, output, columnMap, moduleName) {
662
+ let count = 0;
663
+ for (const key of Object.keys(row)) {
664
+ const index = columnMap.get(key);
665
+ if (index === void 0) {
666
+ throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an undeclared column "${key}"`);
667
+ }
668
+ output[index] = row[key];
669
+ count += 1;
670
+ }
671
+ if (count !== columnMap.size) {
672
+ throw new TypeError(`Virtual table module "${moduleName}" yielded a row with missing columns`);
673
+ }
674
+ }
675
+ function inferParameters({ length }) {
676
+ if (!Number.isInteger(length) || length < 0) {
677
+ throw new TypeError("Expected function.length to be a positive integer");
678
+ }
679
+ const params = [];
680
+ for (let i = 0; i < length; ++i) {
681
+ params.push(`$${i + 1}`);
682
+ }
683
+ return params;
684
+ }
685
+ var { hasOwnProperty } = Object.prototype;
686
+ var { apply } = Function.prototype;
687
+ var GeneratorFunctionPrototype = Object.getPrototypeOf(function* () {
688
+ });
689
+ var identifier = (str) => `"${str.replace(/"/g, '""')}"`;
690
+ var defer = (x) => () => x;
691
+ }
692
+ });
693
+
694
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/inspect.js
695
+ var require_inspect = __commonJS({
696
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/inspect.js"(exports, module) {
697
+ "use strict";
698
+ var DatabaseInspection = function Database2() {
699
+ };
700
+ module.exports = function inspect(depth, opts) {
701
+ return Object.assign(new DatabaseInspection(), this);
702
+ };
703
+ }
704
+ });
705
+
706
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/database.js
707
+ var require_database = __commonJS({
708
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/database.js"(exports, module) {
709
+ "use strict";
710
+ var fs3 = __require("fs");
711
+ var path2 = __require("path");
712
+ var util = require_util();
713
+ var SqliteError = require_sqlite_error();
714
+ var DEFAULT_ADDON;
715
+ function Database2(filenameGiven, options) {
716
+ if (new.target == null) {
717
+ return new Database2(filenameGiven, options);
718
+ }
719
+ let buffer;
720
+ if (Buffer.isBuffer(filenameGiven)) {
721
+ buffer = filenameGiven;
722
+ filenameGiven = ":memory:";
723
+ }
724
+ if (filenameGiven == null) filenameGiven = "";
725
+ if (options == null) options = {};
726
+ if (typeof filenameGiven !== "string") throw new TypeError("Expected first argument to be a string");
727
+ if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
728
+ if ("readOnly" in options) throw new TypeError('Misspelled option "readOnly" should be "readonly"');
729
+ if ("memory" in options) throw new TypeError('Option "memory" was removed in v7.0.0 (use ":memory:" filename instead)');
730
+ const filename = filenameGiven.trim();
731
+ const anonymous = filename === "" || filename === ":memory:";
732
+ const readonly = util.getBooleanOption(options, "readonly");
733
+ const fileMustExist = util.getBooleanOption(options, "fileMustExist");
734
+ const timeout = "timeout" in options ? options.timeout : 5e3;
735
+ const verbose = "verbose" in options ? options.verbose : null;
736
+ const nativeBinding = "nativeBinding" in options ? options.nativeBinding : null;
737
+ if (readonly && anonymous && !buffer) throw new TypeError("In-memory/temporary databases cannot be readonly");
738
+ if (!Number.isInteger(timeout) || timeout < 0) throw new TypeError('Expected the "timeout" option to be a positive integer');
739
+ if (timeout > 2147483647) throw new RangeError('Option "timeout" cannot be greater than 2147483647');
740
+ if (verbose != null && typeof verbose !== "function") throw new TypeError('Expected the "verbose" option to be a function');
741
+ if (nativeBinding != null && typeof nativeBinding !== "string" && typeof nativeBinding !== "object") throw new TypeError('Expected the "nativeBinding" option to be a string or addon object');
742
+ let addon;
743
+ if (nativeBinding == null) {
744
+ addon = DEFAULT_ADDON || (DEFAULT_ADDON = require_bindings()("better_sqlite3.node"));
745
+ } else if (typeof nativeBinding === "string") {
746
+ const requireFunc = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : __require;
747
+ addon = requireFunc(path2.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
748
+ } else {
749
+ addon = nativeBinding;
750
+ }
751
+ if (!addon.isInitialized) {
752
+ addon.setErrorConstructor(SqliteError);
753
+ addon.isInitialized = true;
754
+ }
755
+ if (!anonymous && !fs3.existsSync(path2.dirname(filename))) {
756
+ throw new TypeError("Cannot open database because the directory does not exist");
757
+ }
758
+ Object.defineProperties(this, {
759
+ [util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },
760
+ ...wrappers.getters
761
+ });
762
+ }
763
+ var wrappers = require_wrappers();
764
+ Database2.prototype.prepare = wrappers.prepare;
765
+ Database2.prototype.transaction = require_transaction();
766
+ Database2.prototype.pragma = require_pragma();
767
+ Database2.prototype.backup = require_backup();
768
+ Database2.prototype.serialize = require_serialize();
769
+ Database2.prototype.function = require_function();
770
+ Database2.prototype.aggregate = require_aggregate();
771
+ Database2.prototype.table = require_table();
772
+ Database2.prototype.loadExtension = wrappers.loadExtension;
773
+ Database2.prototype.exec = wrappers.exec;
774
+ Database2.prototype.close = wrappers.close;
775
+ Database2.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
776
+ Database2.prototype.unsafeMode = wrappers.unsafeMode;
777
+ Database2.prototype[util.inspect] = require_inspect();
778
+ module.exports = Database2;
779
+ }
780
+ });
781
+
782
+ // ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/index.js
783
+ var require_lib = __commonJS({
784
+ "../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/index.js"(exports, module) {
785
+ "use strict";
786
+ module.exports = require_database();
787
+ module.exports.SqliteError = require_sqlite_error();
788
+ }
789
+ });
12
790
 
13
791
  // src/storage.ts
14
792
  import { existsSync, mkdirSync } from "fs";
@@ -26,98 +804,70 @@ function detectPlurStorage(explicitPath) {
26
804
  candidates: join(root, "candidates.yaml"),
27
805
  packs: packsDir,
28
806
  exchange: join(root, "exchange"),
29
- config: join(root, "config.yaml")
807
+ config: join(root, "config.yaml"),
808
+ db: join(root, "engrams.db")
30
809
  };
31
810
  }
32
811
 
33
- // src/config.ts
34
- import { existsSync as existsSync2, readFileSync } from "fs";
35
- import yaml from "js-yaml";
36
-
37
- // src/schemas/config.ts
38
- import { z } from "zod";
39
- var PlurConfigSchema = z.object({
40
- auto_learn: z.boolean().default(true),
41
- auto_capture: z.boolean().default(true),
42
- injection_budget: z.number().default(2e3),
43
- decay_enabled: z.boolean().default(true),
44
- decay_threshold: z.number().default(0.15),
45
- packs: z.array(z.string()).default([]),
46
- injection: z.object({
47
- spread_cap: z.number().default(3),
48
- spread_budget: z.number().default(480),
49
- co_access: z.boolean().default(true)
50
- }).default({}),
51
- allow_secrets: z.boolean().default(false)
52
- }).partial();
53
-
54
- // src/config.ts
55
- function loadConfig(configPath) {
56
- if (!existsSync2(configPath)) return PlurConfigSchema.parse({});
57
- try {
58
- const raw = yaml.load(readFileSync(configPath, "utf8"));
59
- return PlurConfigSchema.parse(raw ?? {});
60
- } catch {
61
- return PlurConfigSchema.parse({});
62
- }
63
- }
812
+ // src/storage-indexed.ts
813
+ import { existsSync as existsSync3 } from "fs";
64
814
 
65
815
  // src/engrams.ts
66
816
  import * as fs from "fs";
67
- import * as yaml2 from "js-yaml";
817
+ import * as yaml from "js-yaml";
68
818
 
69
819
  // src/schemas/engram.ts
70
- import { z as z2 } from "zod";
71
- var ActivationSchema = z2.object({
72
- retrieval_strength: z2.number().min(0).max(1),
73
- storage_strength: z2.number().min(0).max(1),
74
- frequency: z2.number().int().min(0),
75
- last_accessed: z2.string()
820
+ import { z } from "zod";
821
+ var ActivationSchema = z.object({
822
+ retrieval_strength: z.number().min(0).max(1),
823
+ storage_strength: z.number().min(0).max(1),
824
+ frequency: z.number().int().min(0),
825
+ last_accessed: z.string()
76
826
  });
77
- var KnowledgeTypeSchema = z2.object({
78
- memory_class: z2.enum(["semantic", "episodic", "procedural", "metacognitive"]),
79
- cognitive_level: z2.enum(["remember", "understand", "apply", "analyze", "evaluate", "create"])
827
+ var KnowledgeTypeSchema = z.object({
828
+ memory_class: z.enum(["semantic", "episodic", "procedural", "metacognitive"]),
829
+ cognitive_level: z.enum(["remember", "understand", "apply", "analyze", "evaluate", "create"])
80
830
  });
81
- var KnowledgeAnchorSchema = z2.object({
82
- path: z2.string(),
83
- relevance: z2.enum(["primary", "supporting", "example"]).default("supporting"),
84
- snippet: z2.string().max(200).optional(),
85
- snippet_extracted_at: z2.string().optional()
831
+ var KnowledgeAnchorSchema = z.object({
832
+ path: z.string(),
833
+ relevance: z.enum(["primary", "supporting", "example"]).default("supporting"),
834
+ snippet: z.string().max(200).optional(),
835
+ snippet_extracted_at: z.string().optional()
86
836
  });
87
- var AssociationSchema = z2.object({
88
- target_type: z2.enum(["engram", "document"]),
89
- target: z2.string(),
90
- strength: z2.number().min(0).max(0.95),
91
- type: z2.enum(["semantic", "temporal", "causal", "co_accessed"]),
92
- updated_at: z2.string().optional()
837
+ var AssociationSchema = z.object({
838
+ target_type: z.enum(["engram", "document"]),
839
+ target: z.string(),
840
+ strength: z.number().min(0).max(0.95),
841
+ type: z.enum(["semantic", "temporal", "causal", "co_accessed"]),
842
+ updated_at: z.string().optional()
93
843
  });
94
- var DualCodingSchema = z2.object({
95
- example: z2.string().optional(),
96
- analogy: z2.string().optional()
844
+ var DualCodingSchema = z.object({
845
+ example: z.string().optional(),
846
+ analogy: z.string().optional()
97
847
  }).refine(
98
848
  (d) => d.example || d.analogy,
99
849
  "At least one of example or analogy must be provided"
100
850
  );
101
- var RelationsSchema = z2.object({
102
- broader: z2.array(z2.string()).default([]),
103
- narrower: z2.array(z2.string()).default([]),
104
- related: z2.array(z2.string()).default([]),
105
- conflicts: z2.array(z2.string()).default([])
851
+ var RelationsSchema = z.object({
852
+ broader: z.array(z.string()).default([]),
853
+ narrower: z.array(z.string()).default([]),
854
+ related: z.array(z.string()).default([]),
855
+ conflicts: z.array(z.string()).default([])
106
856
  });
107
- var ProvenanceSchema = z2.object({
108
- origin: z2.string(),
109
- chain: z2.array(z2.string()).default([]),
110
- signature: z2.string().nullable().default(null),
111
- license: z2.string().default("cc-by-sa-4.0")
857
+ var ProvenanceSchema = z.object({
858
+ origin: z.string(),
859
+ chain: z.array(z.string()).default([]),
860
+ signature: z.string().nullable().default(null),
861
+ license: z.string().default("cc-by-sa-4.0")
112
862
  });
113
- var FeedbackSignalsSchema = z2.object({
114
- positive: z2.number().int().default(0),
115
- negative: z2.number().int().default(0),
116
- neutral: z2.number().int().default(0)
863
+ var FeedbackSignalsSchema = z.object({
864
+ positive: z.number().int().default(0),
865
+ negative: z.number().int().default(0),
866
+ neutral: z.number().int().default(0)
117
867
  });
118
- var EntityRefSchema = z2.object({
119
- name: z2.string(),
120
- type: z2.enum([
868
+ var EntityRefSchema = z.object({
869
+ name: z.string(),
870
+ type: z.enum([
121
871
  "person",
122
872
  "organization",
123
873
  "technology",
@@ -129,56 +879,56 @@ var EntityRefSchema = z2.object({
129
879
  "standard",
130
880
  "other"
131
881
  ]),
132
- uri: z2.string().url().optional()
882
+ uri: z.string().url().optional()
133
883
  });
134
- var TemporalSchema = z2.object({
135
- learned_at: z2.string(),
136
- valid_from: z2.string().optional(),
137
- valid_until: z2.string().optional(),
138
- ingested_at: z2.string().optional()
884
+ var TemporalSchema = z.object({
885
+ learned_at: z.string(),
886
+ valid_from: z.string().optional(),
887
+ valid_until: z.string().optional(),
888
+ ingested_at: z.string().optional()
139
889
  });
140
- var UsageStatsSchema = z2.object({
141
- injections: z2.number().int().default(0),
142
- hits: z2.number().int().default(0),
143
- misses: z2.number().int().default(0),
144
- last_hit_at: z2.string().optional()
890
+ var UsageStatsSchema = z.object({
891
+ injections: z.number().int().default(0),
892
+ hits: z.number().int().default(0),
893
+ misses: z.number().int().default(0),
894
+ last_hit_at: z.string().optional()
145
895
  });
146
- var EpisodicFieldsSchema = z2.object({
147
- emotional_weight: z2.number().int().min(1).max(10).default(5),
148
- confidence: z2.number().int().min(1).max(10).default(5),
149
- trigger_context: z2.string().optional(),
150
- journal_ref: z2.string().optional()
896
+ var EpisodicFieldsSchema = z.object({
897
+ emotional_weight: z.number().int().min(1).max(10).default(5),
898
+ confidence: z.number().int().min(1).max(10).default(5),
899
+ trigger_context: z.string().optional(),
900
+ journal_ref: z.string().optional()
151
901
  });
152
- var ExchangeMetadataSchema = z2.object({
153
- fitness_score: z2.number().min(0).max(1).optional(),
154
- environmental_diversity: z2.number().int().default(0),
155
- adoption_count: z2.number().int().default(0),
156
- contradiction_rate: z2.number().min(0).max(1).default(0)
902
+ var ExchangeMetadataSchema = z.object({
903
+ fitness_score: z.number().min(0).max(1).optional(),
904
+ environmental_diversity: z.number().int().default(0),
905
+ adoption_count: z.number().int().default(0),
906
+ contradiction_rate: z.number().min(0).max(1).default(0)
157
907
  });
158
- var EngramSchema = z2.object({
908
+ var EngramSchema = z.object({
159
909
  // Identity
160
- id: z2.string().regex(/^(ENG|ABS|META)-[A-Za-z0-9-]+$/),
161
- version: z2.number().int().min(1).default(2),
162
- status: z2.enum(["active", "dormant", "retired", "candidate"]),
163
- consolidated: z2.boolean().default(false),
164
- type: z2.enum(["behavioral", "terminological", "procedural", "architectural"]),
165
- scope: z2.string(),
166
- visibility: z2.enum(["private", "public", "template"]).default("private"),
910
+ id: z.string().regex(/^(ENG|ABS|META)-[A-Za-z0-9-]+$/),
911
+ version: z.number().int().min(1).default(2),
912
+ status: z.enum(["active", "dormant", "retired", "candidate"]),
913
+ consolidated: z.boolean().default(false),
914
+ type: z.enum(["behavioral", "terminological", "procedural", "architectural"]),
915
+ scope: z.string(),
916
+ visibility: z.enum(["private", "public", "template"]).default("private"),
167
917
  // Content
168
- statement: z2.string().min(1),
169
- rationale: z2.string().optional(),
170
- contraindications: z2.array(z2.string()).optional(),
918
+ statement: z.string().min(1),
919
+ rationale: z.string().optional(),
920
+ contraindications: z.array(z.string()).optional(),
171
921
  // Lineage
172
- source: z2.string().optional(),
173
- source_patterns: z2.array(z2.string()).optional(),
174
- derivation_count: z2.number().int().min(0).default(1),
175
- pack: z2.string().nullable().default(null),
176
- abstract: z2.string().nullable().default(null),
177
- derived_from: z2.string().nullable().default(null),
922
+ source: z.string().optional(),
923
+ source_patterns: z.array(z.string()).optional(),
924
+ derivation_count: z.number().int().min(0).default(1),
925
+ pack: z.string().nullable().default(null),
926
+ abstract: z.string().nullable().default(null),
927
+ derived_from: z.string().nullable().default(null),
178
928
  // Classification
179
929
  knowledge_type: KnowledgeTypeSchema.optional(),
180
- domain: z2.string().optional(),
181
- tags: z2.array(z2.string()).default([]),
930
+ domain: z.string().optional(),
931
+ tags: z.array(z.string()).default([]),
182
932
  // Activation (ACT-R model)
183
933
  activation: ActivationSchema.default({
184
934
  retrieval_strength: 0.7,
@@ -188,8 +938,8 @@ var EngramSchema = z2.object({
188
938
  }),
189
939
  // Relations & grounding
190
940
  relations: RelationsSchema.optional(),
191
- associations: z2.array(AssociationSchema).default([]),
192
- knowledge_anchors: z2.array(KnowledgeAnchorSchema).default([]),
941
+ associations: z.array(AssociationSchema).default([]),
942
+ knowledge_anchors: z.array(KnowledgeAnchorSchema).default([]),
193
943
  dual_coding: DualCodingSchema.optional(),
194
944
  // Provenance
195
945
  provenance: ProvenanceSchema.optional(),
@@ -197,7 +947,7 @@ var EngramSchema = z2.object({
197
947
  feedback_signals: FeedbackSignalsSchema.default({ positive: 0, negative: 0, neutral: 0 }),
198
948
  // === NEW OPTIONAL FIELDS (v2.1) ===
199
949
  /** Typed entity references extracted from statement. Enables graph queries. */
200
- entities: z2.array(EntityRefSchema).optional(),
950
+ entities: z.array(EntityRefSchema).optional(),
201
951
  /** Temporal validity window. When is this knowledge true? */
202
952
  temporal: TemporalSchema.optional(),
203
953
  /** Automatic usage tracking. Injections, hits, misses. */
@@ -207,33 +957,33 @@ var EngramSchema = z2.object({
207
957
  /** Exchange marketplace metadata: fitness, adoption, diversity. */
208
958
  exchange: ExchangeMetadataSchema.optional(),
209
959
  /** Extensible key-value data for domain-specific fields. */
210
- structured_data: z2.record(z2.string(), z2.unknown()).optional(),
960
+ structured_data: z.record(z.string(), z.unknown()).optional(),
211
961
  /** Polarity classification: 'do' for directives, 'dont' for prohibitions, null for unclassified. */
212
- polarity: z2.enum(["do", "dont"]).nullable().default(null)
962
+ polarity: z.enum(["do", "dont"]).nullable().default(null)
213
963
  });
214
964
 
215
965
  // src/schemas/pack.ts
216
- import { z as z3 } from "zod";
217
- var PackManifestSchema = z3.object({
218
- name: z3.string(),
219
- version: z3.string(),
220
- description: z3.string().optional(),
221
- creator: z3.string().optional(),
222
- license: z3.string().default("cc-by-sa-4.0"),
223
- tags: z3.array(z3.string()).default([]),
224
- metadata: z3.object({
225
- id: z3.string().optional(),
226
- injection_policy: z3.enum(["on_match", "on_request", "always"]).default("on_match"),
227
- match_terms: z3.array(z3.string()).default([]),
228
- domain: z3.string().optional(),
229
- engram_count: z3.number().optional()
966
+ import { z as z2 } from "zod";
967
+ var PackManifestSchema = z2.object({
968
+ name: z2.string(),
969
+ version: z2.string(),
970
+ description: z2.string().optional(),
971
+ creator: z2.string().optional(),
972
+ license: z2.string().default("cc-by-sa-4.0"),
973
+ tags: z2.array(z2.string()).default([]),
974
+ metadata: z2.object({
975
+ id: z2.string().optional(),
976
+ injection_policy: z2.enum(["on_match", "on_request", "always"]).default("on_match"),
977
+ match_terms: z2.array(z2.string()).default([]),
978
+ domain: z2.string().optional(),
979
+ engram_count: z2.number().optional()
230
980
  }).optional(),
231
- "x-datacore": z3.object({
232
- id: z3.string(),
233
- injection_policy: z3.enum(["on_match", "on_request"]),
234
- match_terms: z3.array(z3.string()).default([]),
235
- domain: z3.string().optional(),
236
- engram_count: z3.number().int().min(0)
981
+ "x-datacore": z2.object({
982
+ id: z2.string(),
983
+ injection_policy: z2.enum(["on_match", "on_request"]),
984
+ match_terms: z2.array(z2.string()).default([]),
985
+ domain: z2.string().optional(),
986
+ engram_count: z2.number().int().min(0)
237
987
  }).optional()
238
988
  });
239
989
 
@@ -260,7 +1010,7 @@ var logger = {
260
1010
  function loadEngrams(filePath) {
261
1011
  if (!fs.existsSync(filePath)) return [];
262
1012
  try {
263
- const raw = yaml2.load(fs.readFileSync(filePath, "utf8"));
1013
+ const raw = yaml.load(fs.readFileSync(filePath, "utf8"));
264
1014
  if (!raw?.engrams || !Array.isArray(raw.engrams)) return [];
265
1015
  const valid = [];
266
1016
  let skipped = 0;
@@ -277,14 +1027,14 @@ function loadEngrams(filePath) {
277
1027
  }
278
1028
  }
279
1029
  function saveEngrams(filePath, engrams) {
280
- const content = yaml2.dump({ engrams }, { lineWidth: 120, noRefs: true, quotingType: '"' });
1030
+ const content = yaml.dump({ engrams }, { lineWidth: 120, noRefs: true, quotingType: '"' });
281
1031
  atomicWrite(filePath, content);
282
1032
  }
283
1033
  function parseSkillMdFrontmatter(filePath) {
284
1034
  const content = fs.readFileSync(filePath, "utf8");
285
1035
  const match = content.match(/^---\n([\s\S]*?)\n---/);
286
1036
  if (!match) throw new Error(`No frontmatter found in ${filePath}`);
287
- return yaml2.load(match[1]);
1037
+ return yaml.load(match[1]);
288
1038
  }
289
1039
  function loadPack(packDir) {
290
1040
  const skillMdPath = `${packDir}/SKILL.md`;
@@ -294,7 +1044,7 @@ function loadPack(packDir) {
294
1044
  if (fs.existsSync(skillMdPath)) {
295
1045
  rawManifest = parseSkillMdFrontmatter(skillMdPath);
296
1046
  } else if (fs.existsSync(manifestYamlPath)) {
297
- rawManifest = yaml2.load(fs.readFileSync(manifestYamlPath, "utf8"));
1047
+ rawManifest = yaml.load(fs.readFileSync(manifestYamlPath, "utf8"));
298
1048
  } else {
299
1049
  throw new Error(`No SKILL.md or manifest.yaml found in ${packDir}`);
300
1050
  }
@@ -326,6 +1076,165 @@ function generateEngramId(existing) {
326
1076
  return `${prefix}${String(next).padStart(3, "0")}`;
327
1077
  }
328
1078
 
1079
+ // src/storage-indexed.ts
1080
+ var Database = null;
1081
+ function getDatabase() {
1082
+ if (!Database) {
1083
+ try {
1084
+ Database = require_lib();
1085
+ } catch {
1086
+ throw new Error(
1087
+ "better-sqlite3 is required for index: true. Install it with: npm install better-sqlite3"
1088
+ );
1089
+ }
1090
+ }
1091
+ return Database;
1092
+ }
1093
+ var IndexedStorage = class {
1094
+ dbPath;
1095
+ engramsPath;
1096
+ db = null;
1097
+ constructor(engramsPath, dbPath) {
1098
+ this.engramsPath = engramsPath;
1099
+ this.dbPath = dbPath;
1100
+ }
1101
+ getDb() {
1102
+ if (!this.db) {
1103
+ const DB = getDatabase();
1104
+ this.db = new DB(this.dbPath);
1105
+ this.db.pragma("journal_mode = WAL");
1106
+ this.db.exec(`
1107
+ CREATE TABLE IF NOT EXISTS engrams (
1108
+ id TEXT PRIMARY KEY,
1109
+ status TEXT NOT NULL,
1110
+ scope TEXT NOT NULL,
1111
+ domain TEXT,
1112
+ last_accessed TEXT,
1113
+ data TEXT NOT NULL
1114
+ );
1115
+ CREATE INDEX IF NOT EXISTS idx_status ON engrams(status);
1116
+ CREATE INDEX IF NOT EXISTS idx_scope ON engrams(scope);
1117
+ CREATE INDEX IF NOT EXISTS idx_domain ON engrams(domain);
1118
+ `);
1119
+ }
1120
+ return this.db;
1121
+ }
1122
+ /** Load all engrams from SQLite index. Auto-rebuilds if db missing. */
1123
+ loadAll() {
1124
+ if (!existsSync3(this.dbPath)) {
1125
+ this.reindex();
1126
+ }
1127
+ const db = this.getDb();
1128
+ const rows = db.prepare("SELECT data FROM engrams").all();
1129
+ return rows.map((r) => JSON.parse(r.data));
1130
+ }
1131
+ /** Load engrams with SQL-level filtering. */
1132
+ loadFiltered(filter) {
1133
+ if (!existsSync3(this.dbPath)) {
1134
+ this.reindex();
1135
+ }
1136
+ const db = this.getDb();
1137
+ const conditions = [];
1138
+ const params = [];
1139
+ if (filter.status) {
1140
+ conditions.push("status = ?");
1141
+ params.push(filter.status);
1142
+ }
1143
+ if (filter.scope) {
1144
+ conditions.push("(scope = 'global' OR scope = ? OR scope LIKE ? || '%')");
1145
+ params.push(filter.scope, filter.scope);
1146
+ }
1147
+ if (filter.domain) {
1148
+ conditions.push("domain LIKE ? || '%'");
1149
+ params.push(filter.domain);
1150
+ }
1151
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1152
+ const rows = db.prepare(`SELECT data FROM engrams ${where}`).all(...params);
1153
+ return rows.map((r) => JSON.parse(r.data));
1154
+ }
1155
+ /** Count engrams with optional status filter. */
1156
+ count(filter) {
1157
+ if (!existsSync3(this.dbPath)) {
1158
+ this.reindex();
1159
+ }
1160
+ const db = this.getDb();
1161
+ if (filter?.status) {
1162
+ return db.prepare("SELECT COUNT(*) as c FROM engrams WHERE status = ?").get(filter.status).c;
1163
+ }
1164
+ return db.prepare("SELECT COUNT(*) as c FROM engrams").get().c;
1165
+ }
1166
+ /** Sync SQLite index from YAML source of truth. */
1167
+ syncFromYaml() {
1168
+ const engrams = loadEngrams(this.engramsPath);
1169
+ const db = this.getDb();
1170
+ const upsert = db.prepare(`
1171
+ INSERT OR REPLACE INTO engrams (id, status, scope, domain, last_accessed, data)
1172
+ VALUES (?, ?, ?, ?, ?, ?)
1173
+ `);
1174
+ const deleteStmt = db.prepare("DELETE FROM engrams WHERE id = ?");
1175
+ const yamlIds = new Set(engrams.map((e) => e.id));
1176
+ const dbIds = new Set(
1177
+ db.prepare("SELECT id FROM engrams").all().map((r) => r.id)
1178
+ );
1179
+ const tx = db.transaction(() => {
1180
+ for (const e of engrams) {
1181
+ upsert.run(e.id, e.status, e.scope, e.domain ?? null, e.activation.last_accessed, JSON.stringify(e));
1182
+ }
1183
+ for (const id of dbIds) {
1184
+ if (!yamlIds.has(id)) deleteStmt.run(id);
1185
+ }
1186
+ });
1187
+ tx();
1188
+ }
1189
+ /** Drop and rebuild the entire index from YAML. */
1190
+ reindex() {
1191
+ this.close();
1192
+ const db = this.getDb();
1193
+ db.exec("DELETE FROM engrams");
1194
+ this.syncFromYaml();
1195
+ }
1196
+ /** Close the database connection. */
1197
+ close() {
1198
+ if (this.db) {
1199
+ this.db.close();
1200
+ this.db = null;
1201
+ }
1202
+ }
1203
+ };
1204
+
1205
+ // src/config.ts
1206
+ import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
1207
+ import yaml2 from "js-yaml";
1208
+
1209
+ // src/schemas/config.ts
1210
+ import { z as z3 } from "zod";
1211
+ var PlurConfigSchema = z3.object({
1212
+ auto_learn: z3.boolean().default(true),
1213
+ auto_capture: z3.boolean().default(true),
1214
+ injection_budget: z3.number().default(2e3),
1215
+ decay_enabled: z3.boolean().default(true),
1216
+ decay_threshold: z3.number().default(0.15),
1217
+ packs: z3.array(z3.string()).default([]),
1218
+ injection: z3.object({
1219
+ spread_cap: z3.number().default(3),
1220
+ spread_budget: z3.number().default(480),
1221
+ co_access: z3.boolean().default(true)
1222
+ }).default({}),
1223
+ allow_secrets: z3.boolean().default(false),
1224
+ index: z3.boolean().default(false)
1225
+ }).partial();
1226
+
1227
+ // src/config.ts
1228
+ function loadConfig(configPath) {
1229
+ if (!existsSync4(configPath)) return PlurConfigSchema.parse({});
1230
+ try {
1231
+ const raw = yaml2.load(readFileSync2(configPath, "utf8"));
1232
+ return PlurConfigSchema.parse(raw ?? {});
1233
+ } catch {
1234
+ return PlurConfigSchema.parse({});
1235
+ }
1236
+ }
1237
+
329
1238
  // src/decay.ts
330
1239
  var DECAY_RATE = 0.05;
331
1240
  var FLOOR = 0.05;
@@ -653,7 +1562,7 @@ function selectAndSpread(ctx, personalEngrams, packs, config, embeddingBoosts) {
653
1562
  }
654
1563
 
655
1564
  // src/episodes.ts
656
- import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
1565
+ import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
657
1566
  import yaml3 from "js-yaml";
658
1567
  function generateEpisodeId() {
659
1568
  const ts = Date.now();
@@ -688,7 +1597,7 @@ function queryTimeline(path2, query) {
688
1597
  return episodes;
689
1598
  }
690
1599
  function loadEpisodes(path2) {
691
- if (!existsSync4(path2)) return [];
1600
+ if (!existsSync5(path2)) return [];
692
1601
  try {
693
1602
  const raw = yaml3.load(readFileSync3(path2, "utf8"));
694
1603
  return Array.isArray(raw) ? raw : [];
@@ -1097,7 +2006,7 @@ async function computeSimilarityMatrix(templates) {
1097
2006
  const n = templates.length;
1098
2007
  const matrix = Array.from({ length: n }, () => Array(n).fill(0));
1099
2008
  try {
1100
- const { embed, cosineSimilarity } = await import("./embeddings-Q76LNQ5B.js");
2009
+ const { embed, cosineSimilarity } = await import("./embeddings-2IODIQAF.js");
1101
2010
  const embeddings = [];
1102
2011
  for (const t of templates) {
1103
2012
  embeddings.push(await embed(t));
@@ -1832,9 +2741,13 @@ var INGEST_PATTERNS = [
1832
2741
  var Plur = class {
1833
2742
  paths;
1834
2743
  config;
2744
+ indexedStorage = null;
1835
2745
  constructor(options) {
1836
2746
  this.paths = detectPlurStorage(options?.path);
1837
2747
  this.config = loadConfig(this.paths.config);
2748
+ if (this.config.index) {
2749
+ this.indexedStorage = new IndexedStorage(this.paths.engrams, this.paths.db);
2750
+ }
1838
2751
  }
1839
2752
  /** Create engram, detect conflicts, save. Returns the created engram. */
1840
2753
  learn(statement, context) {
@@ -1844,48 +2757,51 @@ var Plur = class {
1844
2757
  throw new Error(`Secret detected in statement: ${secrets[0].pattern}. Use config.allow_secrets to override.`);
1845
2758
  }
1846
2759
  }
1847
- const engrams = loadEngrams(this.paths.engrams);
1848
- const id = generateEngramId(engrams);
1849
- const scope = context?.scope ?? "global";
1850
- const now = (/* @__PURE__ */ new Date()).toISOString();
1851
- const conflictingEngrams = detectConflicts({ statement, scope }, engrams);
1852
- const conflictIds = conflictingEngrams.map((e) => e.id);
1853
- const engram = {
1854
- id,
1855
- version: 2,
1856
- status: "active",
1857
- consolidated: false,
1858
- type: context?.type ?? "behavioral",
1859
- scope,
1860
- visibility: "private",
1861
- statement,
1862
- source: context?.source,
1863
- domain: context?.domain,
1864
- activation: {
1865
- retrieval_strength: 0.7,
1866
- storage_strength: 1,
1867
- frequency: 0,
1868
- last_accessed: now.slice(0, 10)
1869
- },
1870
- feedback_signals: { positive: 0, negative: 0, neutral: 0 },
1871
- knowledge_anchors: [],
1872
- associations: [],
1873
- derivation_count: 1,
1874
- tags: [],
1875
- pack: null,
1876
- abstract: null,
1877
- derived_from: null,
1878
- polarity: null,
1879
- relations: conflictIds.length > 0 ? {
1880
- broader: [],
1881
- narrower: [],
1882
- related: [],
1883
- conflicts: conflictIds
1884
- } : void 0
1885
- };
1886
- engrams.push(engram);
1887
- saveEngrams(this.paths.engrams, engrams);
1888
- return engram;
2760
+ return withLock(this.paths.engrams, () => {
2761
+ const engrams = loadEngrams(this.paths.engrams);
2762
+ const id = generateEngramId(engrams);
2763
+ const scope = context?.scope ?? "global";
2764
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2765
+ const conflictingEngrams = detectConflicts({ statement, scope }, engrams);
2766
+ const conflictIds = conflictingEngrams.map((e) => e.id);
2767
+ const engram = {
2768
+ id,
2769
+ version: 2,
2770
+ status: "active",
2771
+ consolidated: false,
2772
+ type: context?.type ?? "behavioral",
2773
+ scope,
2774
+ visibility: "private",
2775
+ statement,
2776
+ source: context?.source,
2777
+ domain: context?.domain,
2778
+ activation: {
2779
+ retrieval_strength: 0.7,
2780
+ storage_strength: 1,
2781
+ frequency: 0,
2782
+ last_accessed: now.slice(0, 10)
2783
+ },
2784
+ feedback_signals: { positive: 0, negative: 0, neutral: 0 },
2785
+ knowledge_anchors: [],
2786
+ associations: [],
2787
+ derivation_count: 1,
2788
+ tags: [],
2789
+ pack: null,
2790
+ abstract: null,
2791
+ derived_from: null,
2792
+ polarity: null,
2793
+ relations: conflictIds.length > 0 ? {
2794
+ broader: [],
2795
+ narrower: [],
2796
+ related: [],
2797
+ conflicts: conflictIds
2798
+ } : void 0
2799
+ };
2800
+ engrams.push(engram);
2801
+ saveEngrams(this.paths.engrams, engrams);
2802
+ this._syncIndex();
2803
+ return engram;
2804
+ });
1889
2805
  }
1890
2806
  /**
1891
2807
  * Search engrams, filter by scope/domain/strength, reactivate accessed.
@@ -1939,75 +2855,89 @@ var Plur = class {
1939
2855
  }
1940
2856
  /** Filter engrams by scope/domain/strength (shared by both modes) */
1941
2857
  _filterEngrams(options) {
1942
- let engrams = loadEngrams(this.paths.engrams);
1943
- engrams = engrams.filter((e) => e.status === "active");
2858
+ let engrams;
2859
+ if (this.indexedStorage) {
2860
+ engrams = this.indexedStorage.loadFiltered({
2861
+ status: "active",
2862
+ scope: options?.scope,
2863
+ domain: options?.domain
2864
+ });
2865
+ } else {
2866
+ engrams = loadEngrams(this.paths.engrams);
2867
+ engrams = engrams.filter((e) => e.status === "active");
2868
+ if (options?.domain) {
2869
+ engrams = engrams.filter((e) => e.domain?.startsWith(options.domain));
2870
+ }
2871
+ if (options?.scope) {
2872
+ const scope = options.scope;
2873
+ engrams = engrams.filter(
2874
+ (e) => e.scope === "global" || e.scope === scope || e.scope.startsWith(scope)
2875
+ );
2876
+ }
2877
+ }
1944
2878
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1945
2879
  engrams = engrams.filter((e) => {
1946
2880
  if (e.temporal?.valid_until && e.temporal.valid_until < today) return false;
1947
2881
  if (e.temporal?.valid_from && e.temporal.valid_from > today) return false;
1948
2882
  return true;
1949
2883
  });
1950
- if (options?.domain) {
1951
- engrams = engrams.filter((e) => e.domain?.startsWith(options.domain));
1952
- }
1953
2884
  if (options?.min_strength !== void 0) {
1954
2885
  engrams = engrams.filter((e) => e.activation.retrieval_strength >= options.min_strength);
1955
2886
  }
1956
- if (options?.scope) {
1957
- const scope = options.scope;
1958
- engrams = engrams.filter(
1959
- (e) => e.scope === "global" || e.scope === scope || e.scope.startsWith(scope)
1960
- );
1961
- }
1962
2887
  return engrams;
1963
2888
  }
1964
2889
  /** Reactivate accessed engrams and update co-access associations */
1965
2890
  _reactivateResults(results) {
1966
2891
  if (results.length === 0) return;
1967
- const allEngrams = loadEngrams(this.paths.engrams);
1968
- const resultIds = new Set(results.map((e) => e.id));
1969
- const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1970
- let modified = false;
1971
- for (const e of allEngrams) {
1972
- if (resultIds.has(e.id)) {
1973
- e.activation.retrieval_strength = reactivate(e.activation.retrieval_strength);
1974
- e.activation.last_accessed = today;
1975
- e.activation.frequency += 1;
1976
- modified = true;
1977
- }
1978
- }
1979
- if (results.length >= 2 && this.config.injection?.co_access !== false) {
1980
- const topHalf = results.slice(0, Math.max(2, Math.ceil(results.length / 2)));
1981
- const topIds = topHalf.map((e) => e.id);
1982
- for (const sourceId of topIds) {
1983
- const source = allEngrams.find((e) => e.id === sourceId);
1984
- if (!source) continue;
1985
- for (const targetId of topIds) {
1986
- if (targetId === sourceId) continue;
1987
- const existing = source.associations.find(
1988
- (a) => a.type === "co_accessed" && a.target === targetId
1989
- );
1990
- if (existing) {
1991
- existing.strength = Math.min(0.95, existing.strength + 0.05);
1992
- existing.updated_at = today;
1993
- modified = true;
1994
- } else {
1995
- const coAccessCount = source.associations.filter((a) => a.type === "co_accessed").length;
1996
- if (coAccessCount < 5) {
1997
- source.associations.push({
1998
- target_type: "engram",
1999
- target: targetId,
2000
- type: "co_accessed",
2001
- strength: 0.3,
2002
- updated_at: today
2003
- });
2892
+ withLock(this.paths.engrams, () => {
2893
+ const allEngrams = loadEngrams(this.paths.engrams);
2894
+ const resultIds = new Set(results.map((e) => e.id));
2895
+ const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2896
+ let modified = false;
2897
+ for (const e of allEngrams) {
2898
+ if (resultIds.has(e.id)) {
2899
+ e.activation.retrieval_strength = reactivate(e.activation.retrieval_strength);
2900
+ e.activation.last_accessed = today;
2901
+ e.activation.frequency += 1;
2902
+ modified = true;
2903
+ }
2904
+ }
2905
+ if (results.length >= 2 && this.config.injection?.co_access !== false) {
2906
+ const topHalf = results.slice(0, Math.max(2, Math.ceil(results.length / 2)));
2907
+ const topIds = topHalf.map((e) => e.id);
2908
+ for (const sourceId of topIds) {
2909
+ const source = allEngrams.find((e) => e.id === sourceId);
2910
+ if (!source) continue;
2911
+ for (const targetId of topIds) {
2912
+ if (targetId === sourceId) continue;
2913
+ const existing = source.associations.find(
2914
+ (a) => a.type === "co_accessed" && a.target === targetId
2915
+ );
2916
+ if (existing) {
2917
+ existing.strength = Math.min(0.95, existing.strength + 0.05);
2918
+ existing.updated_at = today;
2004
2919
  modified = true;
2920
+ } else {
2921
+ const coAccessCount = source.associations.filter((a) => a.type === "co_accessed").length;
2922
+ if (coAccessCount < 5) {
2923
+ source.associations.push({
2924
+ target_type: "engram",
2925
+ target: targetId,
2926
+ type: "co_accessed",
2927
+ strength: 0.3,
2928
+ updated_at: today
2929
+ });
2930
+ modified = true;
2931
+ }
2005
2932
  }
2006
2933
  }
2007
2934
  }
2008
2935
  }
2009
- }
2010
- if (modified) saveEngrams(this.paths.engrams, allEngrams);
2936
+ if (modified) {
2937
+ saveEngrams(this.paths.engrams, allEngrams);
2938
+ this._syncIndex();
2939
+ }
2940
+ });
2011
2941
  }
2012
2942
  /** Scored injection within token budget (BM25 only). Returns formatted strings. */
2013
2943
  inject(task, options) {
@@ -2066,56 +2996,96 @@ var Plur = class {
2066
2996
  }
2067
2997
  /** Update feedback_signals and adjust retrieval_strength. */
2068
2998
  feedback(id, signal) {
2069
- const engrams = loadEngrams(this.paths.engrams);
2070
- const engram = engrams.find((e) => e.id === id);
2071
- if (!engram) throw new Error(`Engram not found: ${id}`);
2072
- if (!engram.feedback_signals) {
2073
- engram.feedback_signals = { positive: 0, negative: 0, neutral: 0 };
2074
- }
2075
- engram.feedback_signals[signal] += 1;
2076
- if (signal === "positive") {
2077
- engram.activation.retrieval_strength = Math.min(1, engram.activation.retrieval_strength + 0.05);
2078
- } else if (signal === "negative") {
2079
- engram.activation.retrieval_strength = Math.max(0, engram.activation.retrieval_strength - 0.1);
2080
- }
2081
- saveEngrams(this.paths.engrams, engrams);
2999
+ withLock(this.paths.engrams, () => {
3000
+ const engrams = loadEngrams(this.paths.engrams);
3001
+ const engram = engrams.find((e) => e.id === id);
3002
+ if (!engram) throw new Error(`Engram not found: ${id}`);
3003
+ if (!engram.feedback_signals) {
3004
+ engram.feedback_signals = { positive: 0, negative: 0, neutral: 0 };
3005
+ }
3006
+ engram.feedback_signals[signal] += 1;
3007
+ if (signal === "positive") {
3008
+ engram.activation.retrieval_strength = Math.min(1, engram.activation.retrieval_strength + 0.05);
3009
+ } else if (signal === "negative") {
3010
+ engram.activation.retrieval_strength = Math.max(0, engram.activation.retrieval_strength - 0.1);
3011
+ }
3012
+ saveEngrams(this.paths.engrams, engrams);
3013
+ this._syncIndex();
3014
+ });
2082
3015
  }
2083
3016
  /** Save extracted meta-engrams to the engram store. Skips IDs that already exist. */
2084
3017
  saveMetaEngrams(metas) {
2085
- const engrams = loadEngrams(this.paths.engrams);
2086
- const existingIds = new Set(engrams.map((e) => e.id));
2087
- let saved = 0;
2088
- let skipped = 0;
2089
- for (const meta of metas) {
2090
- if (existingIds.has(meta.id)) {
2091
- skipped++;
2092
- } else {
2093
- engrams.push(meta);
2094
- saved++;
3018
+ return withLock(this.paths.engrams, () => {
3019
+ const engrams = loadEngrams(this.paths.engrams);
3020
+ const existingIds = new Set(engrams.map((e) => e.id));
3021
+ let saved = 0;
3022
+ let skipped = 0;
3023
+ for (const meta of metas) {
3024
+ if (existingIds.has(meta.id)) {
3025
+ skipped++;
3026
+ } else {
3027
+ engrams.push(meta);
3028
+ saved++;
3029
+ }
2095
3030
  }
2096
- }
2097
- if (saved > 0) saveEngrams(this.paths.engrams, engrams);
2098
- return { saved, skipped };
3031
+ if (saved > 0) {
3032
+ saveEngrams(this.paths.engrams, engrams);
3033
+ this._syncIndex();
3034
+ }
3035
+ return { saved, skipped };
3036
+ });
2099
3037
  }
2100
3038
  /** Update an existing engram in the store by ID. Returns true if found and updated. */
2101
3039
  updateEngram(updated) {
2102
- const engrams = loadEngrams(this.paths.engrams);
2103
- const idx = engrams.findIndex((e) => e.id === updated.id);
2104
- if (idx === -1) return false;
2105
- engrams[idx] = updated;
2106
- saveEngrams(this.paths.engrams, engrams);
2107
- return true;
3040
+ return withLock(this.paths.engrams, () => {
3041
+ const engrams = loadEngrams(this.paths.engrams);
3042
+ const idx = engrams.findIndex((e) => e.id === updated.id);
3043
+ if (idx === -1) return false;
3044
+ engrams[idx] = updated;
3045
+ saveEngrams(this.paths.engrams, engrams);
3046
+ this._syncIndex();
3047
+ return true;
3048
+ });
2108
3049
  }
2109
3050
  /** Set engram status to 'retired'. */
2110
3051
  forget(id, reason) {
2111
- const engrams = loadEngrams(this.paths.engrams);
2112
- const engram = engrams.find((e) => e.id === id);
2113
- if (!engram) throw new Error(`Engram not found: ${id}`);
2114
- engram.status = "retired";
2115
- if (reason && !engram.rationale) {
2116
- engram.rationale = `Retired: ${reason}`;
3052
+ withLock(this.paths.engrams, () => {
3053
+ const engrams = loadEngrams(this.paths.engrams);
3054
+ const engram = engrams.find((e) => e.id === id);
3055
+ if (!engram) throw new Error(`Engram not found: ${id}`);
3056
+ engram.status = "retired";
3057
+ if (reason && !engram.rationale) {
3058
+ engram.rationale = `Retired: ${reason}`;
3059
+ }
3060
+ saveEngrams(this.paths.engrams, engrams);
3061
+ this._syncIndex();
3062
+ });
3063
+ }
3064
+ /** Remove retired engrams from storage. Returns count of removed and remaining. */
3065
+ compact() {
3066
+ return withLock(this.paths.engrams, () => {
3067
+ const engrams = loadEngrams(this.paths.engrams);
3068
+ const active = engrams.filter((e) => e.status !== "retired");
3069
+ const removed = engrams.length - active.length;
3070
+ if (removed > 0) {
3071
+ saveEngrams(this.paths.engrams, active);
3072
+ this._syncIndex();
3073
+ }
3074
+ return { removed, remaining: active.length };
3075
+ });
3076
+ }
3077
+ /** Rebuild SQLite index from YAML source of truth. Only works when index: true. */
3078
+ reindex() {
3079
+ if (!this.indexedStorage) {
3080
+ this.indexedStorage = new IndexedStorage(this.paths.engrams, this.paths.db);
3081
+ }
3082
+ this.indexedStorage.reindex();
3083
+ }
3084
+ /** Sync SQLite index after YAML write (no-op if index disabled) */
3085
+ _syncIndex() {
3086
+ if (this.indexedStorage) {
3087
+ this.indexedStorage.syncFromYaml();
2117
3088
  }
2118
- saveEngrams(this.paths.engrams, engrams);
2119
3089
  }
2120
3090
  /** Capture an episodic memory. */
2121
3091
  capture(summary, context) {
@@ -2196,6 +3166,7 @@ export {
2196
3166
  EvidenceEntrySchema,
2197
3167
  FalsificationSchema,
2198
3168
  HierarchyPositionSchema,
3169
+ IndexedStorage,
2199
3170
  MetaConfidenceSchema,
2200
3171
  MetaFieldSchema,
2201
3172
  PLATITUDE_PATTERNS,