crispy-recall 0.1.6 → 0.2.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 +88 -1
- package/dist/embed-pending.js +961 -1452
- package/dist/recall.js +2217 -1630
- package/dist/stop-hook.js +928 -1451
- package/package.json +7 -3
- package/dist/node-sqlite3-wasm.wasm +0 -0
package/dist/recall.js
CHANGED
|
@@ -858,9 +858,9 @@ var require_pump = __commonJS({
|
|
|
858
858
|
"node_modules/pump/index.js"(exports2, module2) {
|
|
859
859
|
var once = require_once();
|
|
860
860
|
var eos = require_end_of_stream();
|
|
861
|
-
var
|
|
861
|
+
var fs5;
|
|
862
862
|
try {
|
|
863
|
-
|
|
863
|
+
fs5 = require("fs");
|
|
864
864
|
} catch (e2) {
|
|
865
865
|
}
|
|
866
866
|
var noop = function() {
|
|
@@ -872,9 +872,9 @@ var require_pump = __commonJS({
|
|
|
872
872
|
var isFS = function(stream2) {
|
|
873
873
|
if (!ancient)
|
|
874
874
|
return false;
|
|
875
|
-
if (!
|
|
875
|
+
if (!fs5)
|
|
876
876
|
return false;
|
|
877
|
-
return (stream2 instanceof (
|
|
877
|
+
return (stream2 instanceof (fs5.ReadStream || noop) || stream2 instanceof (fs5.WriteStream || noop)) && isFn(stream2.close);
|
|
878
878
|
};
|
|
879
879
|
var isRequest = function(stream2) {
|
|
880
880
|
return stream2.setHeader && isFn(stream2.abort);
|
|
@@ -1098,7 +1098,7 @@ var require_pend = __commonJS({
|
|
|
1098
1098
|
// node_modules/fd-slicer/index.js
|
|
1099
1099
|
var require_fd_slicer = __commonJS({
|
|
1100
1100
|
"node_modules/fd-slicer/index.js"(exports2) {
|
|
1101
|
-
var
|
|
1101
|
+
var fs5 = require("fs");
|
|
1102
1102
|
var util = require("util");
|
|
1103
1103
|
var stream2 = require("stream");
|
|
1104
1104
|
var Readable = stream2.Readable;
|
|
@@ -1123,7 +1123,7 @@ var require_fd_slicer = __commonJS({
|
|
|
1123
1123
|
FdSlicer.prototype.read = function(buffer, offset2, length, position, callback) {
|
|
1124
1124
|
var self = this;
|
|
1125
1125
|
self.pend.go(function(cb) {
|
|
1126
|
-
|
|
1126
|
+
fs5.read(self.fd, buffer, offset2, length, position, function(err, bytesRead, buffer2) {
|
|
1127
1127
|
cb();
|
|
1128
1128
|
callback(err, bytesRead, buffer2);
|
|
1129
1129
|
});
|
|
@@ -1132,7 +1132,7 @@ var require_fd_slicer = __commonJS({
|
|
|
1132
1132
|
FdSlicer.prototype.write = function(buffer, offset2, length, position, callback) {
|
|
1133
1133
|
var self = this;
|
|
1134
1134
|
self.pend.go(function(cb) {
|
|
1135
|
-
|
|
1135
|
+
fs5.write(self.fd, buffer, offset2, length, position, function(err, written, buffer2) {
|
|
1136
1136
|
cb();
|
|
1137
1137
|
callback(err, written, buffer2);
|
|
1138
1138
|
});
|
|
@@ -1155,7 +1155,7 @@ var require_fd_slicer = __commonJS({
|
|
|
1155
1155
|
if (self.refCount < 0)
|
|
1156
1156
|
throw new Error("invalid unref");
|
|
1157
1157
|
if (self.autoClose) {
|
|
1158
|
-
|
|
1158
|
+
fs5.close(self.fd, onCloseDone);
|
|
1159
1159
|
}
|
|
1160
1160
|
function onCloseDone(err) {
|
|
1161
1161
|
if (err) {
|
|
@@ -1194,7 +1194,7 @@ var require_fd_slicer = __commonJS({
|
|
|
1194
1194
|
if (self.destroyed)
|
|
1195
1195
|
return cb();
|
|
1196
1196
|
var buffer = new Buffer(toRead);
|
|
1197
|
-
|
|
1197
|
+
fs5.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
|
|
1198
1198
|
if (err) {
|
|
1199
1199
|
self.destroy(err);
|
|
1200
1200
|
} else if (bytesRead === 0) {
|
|
@@ -1244,7 +1244,7 @@ var require_fd_slicer = __commonJS({
|
|
|
1244
1244
|
self.context.pend.go(function(cb) {
|
|
1245
1245
|
if (self.destroyed)
|
|
1246
1246
|
return cb();
|
|
1247
|
-
|
|
1247
|
+
fs5.write(self.context.fd, buffer, 0, buffer.length, self.pos, function(err2, bytes) {
|
|
1248
1248
|
if (err2) {
|
|
1249
1249
|
self.destroy();
|
|
1250
1250
|
cb();
|
|
@@ -1673,7 +1673,7 @@ var require_buffer_crc32 = __commonJS({
|
|
|
1673
1673
|
// node_modules/yauzl/index.js
|
|
1674
1674
|
var require_yauzl = __commonJS({
|
|
1675
1675
|
"node_modules/yauzl/index.js"(exports2) {
|
|
1676
|
-
var
|
|
1676
|
+
var fs5 = require("fs");
|
|
1677
1677
|
var zlib = require("zlib");
|
|
1678
1678
|
var fd_slicer = require_fd_slicer();
|
|
1679
1679
|
var crc32 = require_buffer_crc32();
|
|
@@ -1691,7 +1691,7 @@ var require_yauzl = __commonJS({
|
|
|
1691
1691
|
exports2.ZipFile = ZipFile;
|
|
1692
1692
|
exports2.Entry = Entry;
|
|
1693
1693
|
exports2.RandomAccessReader = RandomAccessReader;
|
|
1694
|
-
function open(
|
|
1694
|
+
function open(path4, options, callback) {
|
|
1695
1695
|
if (typeof options === "function") {
|
|
1696
1696
|
callback = options;
|
|
1697
1697
|
options = null;
|
|
@@ -1710,12 +1710,12 @@ var require_yauzl = __commonJS({
|
|
|
1710
1710
|
options.strictFileNames = false;
|
|
1711
1711
|
if (callback == null)
|
|
1712
1712
|
callback = defaultCallback;
|
|
1713
|
-
|
|
1713
|
+
fs5.open(path4, "r", function(err, fd) {
|
|
1714
1714
|
if (err)
|
|
1715
1715
|
return callback(err);
|
|
1716
1716
|
fromFd(fd, options, function(err2, zipfile) {
|
|
1717
1717
|
if (err2)
|
|
1718
|
-
|
|
1718
|
+
fs5.close(fd, defaultCallback);
|
|
1719
1719
|
callback(err2, zipfile);
|
|
1720
1720
|
});
|
|
1721
1721
|
});
|
|
@@ -1739,7 +1739,7 @@ var require_yauzl = __commonJS({
|
|
|
1739
1739
|
options.strictFileNames = false;
|
|
1740
1740
|
if (callback == null)
|
|
1741
1741
|
callback = defaultCallback;
|
|
1742
|
-
|
|
1742
|
+
fs5.fstat(fd, function(err, stats) {
|
|
1743
1743
|
if (err)
|
|
1744
1744
|
return callback(err);
|
|
1745
1745
|
var reader = fd_slicer.createFromFd(fd, { autoClose: true });
|
|
@@ -2375,9 +2375,9 @@ var require_yauzl = __commonJS({
|
|
|
2375
2375
|
var require_extract_zip = __commonJS({
|
|
2376
2376
|
"node_modules/extract-zip/index.js"(exports2, module2) {
|
|
2377
2377
|
var debug = require_src()("extract-zip");
|
|
2378
|
-
var { createWriteStream: createWriteStream3, promises:
|
|
2378
|
+
var { createWriteStream: createWriteStream3, promises: fs5 } = require("fs");
|
|
2379
2379
|
var getStream = require_get_stream();
|
|
2380
|
-
var
|
|
2380
|
+
var path4 = require("path");
|
|
2381
2381
|
var { promisify: promisify3 } = require("util");
|
|
2382
2382
|
var stream2 = require("stream");
|
|
2383
2383
|
var yauzl = require_yauzl();
|
|
@@ -2414,12 +2414,12 @@ var require_extract_zip = __commonJS({
|
|
|
2414
2414
|
this.zipfile.readEntry();
|
|
2415
2415
|
return;
|
|
2416
2416
|
}
|
|
2417
|
-
const destDir =
|
|
2417
|
+
const destDir = path4.dirname(path4.join(this.opts.dir, entry.fileName));
|
|
2418
2418
|
try {
|
|
2419
|
-
await
|
|
2420
|
-
const canonicalDestDir = await
|
|
2421
|
-
const relativeDestDir =
|
|
2422
|
-
if (relativeDestDir.split(
|
|
2419
|
+
await fs5.mkdir(destDir, { recursive: true });
|
|
2420
|
+
const canonicalDestDir = await fs5.realpath(destDir);
|
|
2421
|
+
const relativeDestDir = path4.relative(this.opts.dir, canonicalDestDir);
|
|
2422
|
+
if (relativeDestDir.split(path4.sep).includes("..")) {
|
|
2423
2423
|
throw new Error(`Out of bound path "${canonicalDestDir}" found while processing file ${entry.fileName}`);
|
|
2424
2424
|
}
|
|
2425
2425
|
await this.extractEntry(entry);
|
|
@@ -2441,7 +2441,7 @@ var require_extract_zip = __commonJS({
|
|
|
2441
2441
|
if (this.opts.onEntry) {
|
|
2442
2442
|
this.opts.onEntry(entry, this.zipfile);
|
|
2443
2443
|
}
|
|
2444
|
-
const dest =
|
|
2444
|
+
const dest = path4.join(this.opts.dir, entry.fileName);
|
|
2445
2445
|
const mode = entry.externalFileAttributes >> 16 & 65535;
|
|
2446
2446
|
const IFMT2 = 61440;
|
|
2447
2447
|
const IFDIR2 = 16384;
|
|
@@ -2456,13 +2456,13 @@ var require_extract_zip = __commonJS({
|
|
|
2456
2456
|
isDir = madeBy === 0 && entry.externalFileAttributes === 16;
|
|
2457
2457
|
debug("extracting entry", { filename: entry.fileName, isDir, isSymlink: symlink });
|
|
2458
2458
|
const procMode = this.getExtractedMode(mode, isDir) & 511;
|
|
2459
|
-
const destDir = isDir ? dest :
|
|
2459
|
+
const destDir = isDir ? dest : path4.dirname(dest);
|
|
2460
2460
|
const mkdirOptions = { recursive: true };
|
|
2461
2461
|
if (isDir) {
|
|
2462
2462
|
mkdirOptions.mode = procMode;
|
|
2463
2463
|
}
|
|
2464
2464
|
debug("mkdir", { dir: destDir, ...mkdirOptions });
|
|
2465
|
-
await
|
|
2465
|
+
await fs5.mkdir(destDir, mkdirOptions);
|
|
2466
2466
|
if (isDir)
|
|
2467
2467
|
return;
|
|
2468
2468
|
debug("opening read stream", dest);
|
|
@@ -2470,7 +2470,7 @@ var require_extract_zip = __commonJS({
|
|
|
2470
2470
|
if (symlink) {
|
|
2471
2471
|
const link = await getStream(readStream);
|
|
2472
2472
|
debug("creating symlink", link, dest);
|
|
2473
|
-
await
|
|
2473
|
+
await fs5.symlink(link, dest);
|
|
2474
2474
|
} else {
|
|
2475
2475
|
await pipeline(readStream, createWriteStream3(dest, { mode: procMode }));
|
|
2476
2476
|
}
|
|
@@ -2499,11 +2499,11 @@ var require_extract_zip = __commonJS({
|
|
|
2499
2499
|
};
|
|
2500
2500
|
module2.exports = async function(zipPath, opts) {
|
|
2501
2501
|
debug("creating target directory", opts.dir);
|
|
2502
|
-
if (!
|
|
2502
|
+
if (!path4.isAbsolute(opts.dir)) {
|
|
2503
2503
|
throw new Error("Target directory is expected to be absolute");
|
|
2504
2504
|
}
|
|
2505
|
-
await
|
|
2506
|
-
opts.dir = await
|
|
2505
|
+
await fs5.mkdir(opts.dir, { recursive: true });
|
|
2506
|
+
opts.dir = await fs5.realpath(opts.dir);
|
|
2507
2507
|
return new Extractor(zipPath, opts).extract();
|
|
2508
2508
|
};
|
|
2509
2509
|
}
|
|
@@ -2585,11 +2585,11 @@ var init_paths = __esm({
|
|
|
2585
2585
|
});
|
|
2586
2586
|
|
|
2587
2587
|
// src/installer/settings-merge.ts
|
|
2588
|
-
function writeFileAtomic(
|
|
2589
|
-
const tmp = `${
|
|
2588
|
+
function writeFileAtomic(path4, contents) {
|
|
2589
|
+
const tmp = `${path4}.tmp.${process.pid}`;
|
|
2590
2590
|
try {
|
|
2591
2591
|
(0, import_node_fs2.writeFileSync)(tmp, contents);
|
|
2592
|
-
(0, import_node_fs2.renameSync)(tmp,
|
|
2592
|
+
(0, import_node_fs2.renameSync)(tmp, path4);
|
|
2593
2593
|
} catch (err) {
|
|
2594
2594
|
try {
|
|
2595
2595
|
if ((0, import_node_fs2.existsSync)(tmp))
|
|
@@ -2602,9 +2602,9 @@ function writeFileAtomic(path3, contents) {
|
|
|
2602
2602
|
function backupStamp() {
|
|
2603
2603
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2604
2604
|
}
|
|
2605
|
-
function backupFile(
|
|
2606
|
-
const dest = `${
|
|
2607
|
-
(0, import_node_fs2.copyFileSync)(
|
|
2605
|
+
function backupFile(path4) {
|
|
2606
|
+
const dest = `${path4}.bak.${backupStamp()}`;
|
|
2607
|
+
(0, import_node_fs2.copyFileSync)(path4, dest);
|
|
2608
2608
|
return dest;
|
|
2609
2609
|
}
|
|
2610
2610
|
function detectLineEnding(raw2) {
|
|
@@ -2653,7 +2653,7 @@ function makeEntry(command) {
|
|
|
2653
2653
|
return { matcher: "", hooks: [{ type: "command", command }] };
|
|
2654
2654
|
}
|
|
2655
2655
|
function mergeStopHook(filePath, hookScriptPath) {
|
|
2656
|
-
const desiredCommand = `
|
|
2656
|
+
const desiredCommand = `"${process.execPath}" "${hookScriptPath}"`;
|
|
2657
2657
|
const exists = (0, import_node_fs2.existsSync)(filePath);
|
|
2658
2658
|
const raw2 = exists ? (0, import_node_fs2.readFileSync)(filePath, "utf-8") : null;
|
|
2659
2659
|
const obj = raw2 && raw2.trim().length > 0 ? parseTolerant(raw2) : {};
|
|
@@ -3409,13 +3409,13 @@ async function retryServer() {
|
|
|
3409
3409
|
serverRetryPromise = null;
|
|
3410
3410
|
}
|
|
3411
3411
|
}
|
|
3412
|
-
function httpPost(socketPath,
|
|
3412
|
+
function httpPost(socketPath, path4, body, timeoutMs) {
|
|
3413
3413
|
return new Promise((resolve, reject) => {
|
|
3414
3414
|
const data = JSON.stringify(body);
|
|
3415
3415
|
const req = (0, import_node_http.request)(
|
|
3416
3416
|
{
|
|
3417
3417
|
socketPath,
|
|
3418
|
-
path:
|
|
3418
|
+
path: path4,
|
|
3419
3419
|
method: "POST",
|
|
3420
3420
|
headers: {
|
|
3421
3421
|
"Content-Type": "application/json",
|
|
@@ -3749,1418 +3749,842 @@ var init_quantize = __esm({
|
|
|
3749
3749
|
}
|
|
3750
3750
|
});
|
|
3751
3751
|
|
|
3752
|
-
// node_modules/
|
|
3753
|
-
var
|
|
3754
|
-
"node_modules/
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
var SQLITE_OK = 0;
|
|
3761
|
-
var SQLITE_ROW = 100;
|
|
3762
|
-
var SQLITE_DONE = 101;
|
|
3763
|
-
var SQLITE_INTEGER = 1;
|
|
3764
|
-
var SQLITE_FLOAT = 2;
|
|
3765
|
-
var SQLITE_TEXT = 3;
|
|
3766
|
-
var SQLITE_BLOB = 4;
|
|
3767
|
-
var SQLITE_NULL = 5;
|
|
3768
|
-
var SQLITE_UTF8 = 1;
|
|
3769
|
-
var SQLITE_TRANSIENT = -1;
|
|
3770
|
-
var SQLITE_DETERMINISTIC = 2048;
|
|
3771
|
-
var temp;
|
|
3772
|
-
var sqlite3 = {};
|
|
3773
|
-
Module.onRuntimeInitialized = () => {
|
|
3774
|
-
temp = stackAlloc(4);
|
|
3775
|
-
const v2 = null;
|
|
3776
|
-
const n = "number";
|
|
3777
|
-
const s = "string";
|
|
3778
|
-
const n1 = [n];
|
|
3779
|
-
const n2 = [n, ...n1];
|
|
3780
|
-
const n3 = [n, ...n2];
|
|
3781
|
-
const n4 = [n, ...n3];
|
|
3782
|
-
const n5 = [n, ...n4];
|
|
3783
|
-
const signatures = { open_v2: [n, [s, n, n, s]], exec: [n, n5], errmsg: [s, n1], prepare_v2: [n, n5], close_v2: [n, n1], finalize: [n, n1], reset: [n, n1], clear_bindings: [n, n1], bind_int: [n, n3], bind_int64: [n, n3], bind_double: [n, n3], bind_text: [n, n5], bind_blob: [n, n5], bind_blob64: [n, n5], bind_null: [n, n2], bind_parameter_index: [n, [n, s]], step: [n, n1], column_int64: [n, n2], column_double: [n, n2], column_text: [s, n2], column_blob: [n, n2], column_type: [n, n2], column_name: [s, n2], column_count: [n, n1], column_bytes: [n, n2], last_insert_rowid: [n, n1], changes: [n, n1], create_function_v2: [n, [n, s, n, n, n, n, n, n, n]], value_type: [n, n1], value_text: [s, n1], value_blob: [n, n1], value_int64: [n, n1], value_double: [n, n1], value_bytes: [n, n1], result_double: [v2, n2], result_null: [v2, n1], result_text: [v2, n4], result_blob: [v2, n4], result_blob64: [v2, n4], result_int: [v2, n2], result_int64: [v2, n2], result_error: [v2, n3], column_table_name: [s, n2], get_autocommit: [n, n1] };
|
|
3784
|
-
for (const [name, sig] of Object.entries(signatures)) {
|
|
3785
|
-
sqlite3[name] = cwrap(`sqlite3_${name}`, sig[0], sig[1]);
|
|
3786
|
-
}
|
|
3787
|
-
};
|
|
3788
|
-
var SQLite3Error = class extends Error {
|
|
3789
|
-
constructor(message) {
|
|
3790
|
-
super(message);
|
|
3791
|
-
this.name = "SQLite3Error";
|
|
3752
|
+
// node_modules/better-sqlite3/lib/util.js
|
|
3753
|
+
var require_util = __commonJS({
|
|
3754
|
+
"node_modules/better-sqlite3/lib/util.js"(exports2) {
|
|
3755
|
+
"use strict";
|
|
3756
|
+
exports2.getBooleanOption = (options, key) => {
|
|
3757
|
+
let value = false;
|
|
3758
|
+
if (key in options && typeof (value = options[key]) !== "boolean") {
|
|
3759
|
+
throw new TypeError(`Expected the "${key}" option to be a boolean`);
|
|
3792
3760
|
}
|
|
3761
|
+
return value;
|
|
3793
3762
|
};
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
let arg;
|
|
3817
|
-
switch (type) {
|
|
3818
|
-
case SQLITE_INTEGER:
|
|
3819
|
-
arg = toNumberOrNot(sqlite3.value_int64(ptr));
|
|
3820
|
-
break;
|
|
3821
|
-
case SQLITE_FLOAT:
|
|
3822
|
-
arg = sqlite3.value_double(ptr);
|
|
3823
|
-
break;
|
|
3824
|
-
case SQLITE_TEXT:
|
|
3825
|
-
arg = sqlite3.value_text(ptr);
|
|
3826
|
-
break;
|
|
3827
|
-
case SQLITE_BLOB:
|
|
3828
|
-
const p = sqlite3.value_blob(ptr);
|
|
3829
|
-
if (p != NULL) {
|
|
3830
|
-
arg = HEAPU8.slice(p, p + sqlite3.value_bytes(ptr));
|
|
3831
|
-
} else {
|
|
3832
|
-
arg = new Uint8Array();
|
|
3833
|
-
}
|
|
3834
|
-
break;
|
|
3835
|
-
case SQLITE_NULL:
|
|
3836
|
-
arg = null;
|
|
3837
|
-
break;
|
|
3838
|
-
}
|
|
3839
|
-
args.push(arg);
|
|
3840
|
-
}
|
|
3841
|
-
return args;
|
|
3763
|
+
exports2.cppdb = Symbol();
|
|
3764
|
+
exports2.inspect = Symbol.for("nodejs.util.inspect.custom");
|
|
3765
|
+
}
|
|
3766
|
+
});
|
|
3767
|
+
|
|
3768
|
+
// node_modules/better-sqlite3/lib/sqlite-error.js
|
|
3769
|
+
var require_sqlite_error = __commonJS({
|
|
3770
|
+
"node_modules/better-sqlite3/lib/sqlite-error.js"(exports2, module2) {
|
|
3771
|
+
"use strict";
|
|
3772
|
+
var descriptor = { value: "SqliteError", writable: true, enumerable: false, configurable: true };
|
|
3773
|
+
function SqliteError(message, code) {
|
|
3774
|
+
if (new.target !== SqliteError) {
|
|
3775
|
+
return new SqliteError(message, code);
|
|
3776
|
+
}
|
|
3777
|
+
if (typeof code !== "string") {
|
|
3778
|
+
throw new TypeError("Expected second argument to be a string");
|
|
3779
|
+
}
|
|
3780
|
+
Error.call(this, message);
|
|
3781
|
+
descriptor.value = "" + message;
|
|
3782
|
+
Object.defineProperty(this, "message", descriptor);
|
|
3783
|
+
Error.captureStackTrace(this, SqliteError);
|
|
3784
|
+
this.code = code;
|
|
3842
3785
|
}
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
sqlite3.result_blob64(cx, tempPtr2, BigInt(result.byteLength), SQLITE_TRANSIENT);
|
|
3876
|
-
}
|
|
3877
|
-
_free(tempPtr2);
|
|
3878
|
-
} else {
|
|
3879
|
-
throw new SQLite3Error(`Unsupported type for function result: "${typeof result}"`);
|
|
3880
|
-
}
|
|
3881
|
-
break;
|
|
3882
|
-
default:
|
|
3883
|
-
throw new SQLite3Error(`Unsupported type for function result: "${typeof result}"`);
|
|
3786
|
+
Object.setPrototypeOf(SqliteError, Error);
|
|
3787
|
+
Object.setPrototypeOf(SqliteError.prototype, Error.prototype);
|
|
3788
|
+
Object.defineProperty(SqliteError.prototype, "name", descriptor);
|
|
3789
|
+
module2.exports = SqliteError;
|
|
3790
|
+
}
|
|
3791
|
+
});
|
|
3792
|
+
|
|
3793
|
+
// node_modules/file-uri-to-path/index.js
|
|
3794
|
+
var require_file_uri_to_path = __commonJS({
|
|
3795
|
+
"node_modules/file-uri-to-path/index.js"(exports2, module2) {
|
|
3796
|
+
var sep2 = require("path").sep || "/";
|
|
3797
|
+
module2.exports = fileUriToPath;
|
|
3798
|
+
function fileUriToPath(uri) {
|
|
3799
|
+
if ("string" != typeof uri || uri.length <= 7 || "file://" != uri.substring(0, 7)) {
|
|
3800
|
+
throw new TypeError("must pass in a file:// URI to convert to a file path");
|
|
3801
|
+
}
|
|
3802
|
+
var rest = decodeURI(uri.substring(7));
|
|
3803
|
+
var firstSlash = rest.indexOf("/");
|
|
3804
|
+
var host = rest.substring(0, firstSlash);
|
|
3805
|
+
var path4 = rest.substring(firstSlash + 1);
|
|
3806
|
+
if ("localhost" == host)
|
|
3807
|
+
host = "";
|
|
3808
|
+
if (host) {
|
|
3809
|
+
host = sep2 + sep2 + host;
|
|
3810
|
+
}
|
|
3811
|
+
path4 = path4.replace(/^(.+)\|/, "$1:");
|
|
3812
|
+
if (sep2 == "\\") {
|
|
3813
|
+
path4 = path4.replace(/\//g, "\\");
|
|
3814
|
+
}
|
|
3815
|
+
if (/^.+\:/.test(path4)) {
|
|
3816
|
+
} else {
|
|
3817
|
+
path4 = sep2 + path4;
|
|
3884
3818
|
}
|
|
3819
|
+
return host + path4;
|
|
3885
3820
|
}
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
}
|
|
3903
|
-
this._functions = /* @__PURE__ */ new Map();
|
|
3904
|
-
}
|
|
3905
|
-
get isOpen() {
|
|
3906
|
-
return this._ptr !== null;
|
|
3907
|
-
}
|
|
3908
|
-
get inTransaction() {
|
|
3909
|
-
this._assertOpen();
|
|
3910
|
-
return sqlite3.get_autocommit(this._ptr) === 0;
|
|
3911
|
-
}
|
|
3912
|
-
close() {
|
|
3913
|
-
this._assertOpen();
|
|
3914
|
-
for (const func of this._functions.values())
|
|
3915
|
-
removeFunction(func);
|
|
3916
|
-
this._functions.clear();
|
|
3917
|
-
this._handleError(sqlite3.close_v2(this._ptr));
|
|
3918
|
-
this._ptr = null;
|
|
3919
|
-
}
|
|
3920
|
-
function(name, func, { deterministic = false } = {}) {
|
|
3921
|
-
this._assertOpen();
|
|
3922
|
-
function wrappedFunc(cx, argc, argv2) {
|
|
3923
|
-
const args = parseFunctionArguments(argc, argv2);
|
|
3924
|
-
let result;
|
|
3925
|
-
try {
|
|
3926
|
-
result = func.apply(null, args);
|
|
3927
|
-
} catch (err2) {
|
|
3928
|
-
const tempPtr = stringToHeap(err2.toString());
|
|
3929
|
-
sqlite3.result_error(cx, tempPtr, -1);
|
|
3930
|
-
_free(tempPtr);
|
|
3931
|
-
return;
|
|
3932
|
-
}
|
|
3933
|
-
setFunctionResult(cx, result);
|
|
3934
|
-
}
|
|
3935
|
-
if (this._functions.has(name)) {
|
|
3936
|
-
removeFunction(this._functions.get(name));
|
|
3937
|
-
this._functions.delete(name);
|
|
3938
|
-
}
|
|
3939
|
-
const funcPtr = addFunction(wrappedFunc, "viii");
|
|
3940
|
-
this._functions.set(name, funcPtr);
|
|
3941
|
-
let eTextRep = SQLITE_UTF8;
|
|
3942
|
-
if (deterministic)
|
|
3943
|
-
eTextRep |= SQLITE_DETERMINISTIC;
|
|
3944
|
-
this._handleError(sqlite3.create_function_v2(this._ptr, name, func.length, eTextRep, NULL, funcPtr, NULL, NULL, NULL));
|
|
3945
|
-
return this;
|
|
3946
|
-
}
|
|
3947
|
-
exec(sql) {
|
|
3948
|
-
this._assertOpen();
|
|
3949
|
-
const tempPtr = stringToHeap(sql);
|
|
3950
|
-
try {
|
|
3951
|
-
this._handleError(sqlite3.exec(this._ptr, tempPtr, NULL, NULL, NULL));
|
|
3952
|
-
} finally {
|
|
3953
|
-
_free(tempPtr);
|
|
3954
|
-
}
|
|
3955
|
-
}
|
|
3956
|
-
prepare(sql) {
|
|
3957
|
-
this._assertOpen();
|
|
3958
|
-
return new Statement(this, sql);
|
|
3959
|
-
}
|
|
3960
|
-
run(sql, values) {
|
|
3961
|
-
const stmt = this.prepare(sql);
|
|
3962
|
-
try {
|
|
3963
|
-
return stmt.run(values);
|
|
3964
|
-
} finally {
|
|
3965
|
-
stmt.finalize();
|
|
3966
|
-
}
|
|
3967
|
-
}
|
|
3968
|
-
all(sql, values, { expand: expand2 = false } = {}) {
|
|
3969
|
-
return this._query(sql, values, false, expand2);
|
|
3970
|
-
}
|
|
3971
|
-
get(sql, values, { expand: expand2 = false } = {}) {
|
|
3972
|
-
return this._query(sql, values, true, expand2);
|
|
3973
|
-
}
|
|
3974
|
-
_query(sql, values, single, expand2) {
|
|
3975
|
-
const stmt = this.prepare(sql);
|
|
3976
|
-
try {
|
|
3977
|
-
if (single) {
|
|
3978
|
-
return stmt.get(values, { expand: expand2 });
|
|
3979
|
-
} else {
|
|
3980
|
-
return stmt.all(values, { expand: expand2 });
|
|
3981
|
-
}
|
|
3982
|
-
} finally {
|
|
3983
|
-
stmt.finalize();
|
|
3984
|
-
}
|
|
3985
|
-
}
|
|
3986
|
-
_assertOpen() {
|
|
3987
|
-
if (!this.isOpen)
|
|
3988
|
-
throw new SQLite3Error("Database already closed");
|
|
3989
|
-
}
|
|
3990
|
-
_handleError(returnCode) {
|
|
3991
|
-
if (returnCode !== SQLITE_OK)
|
|
3992
|
-
throw new SQLite3Error(sqlite3.errmsg(this._ptr));
|
|
3821
|
+
}
|
|
3822
|
+
});
|
|
3823
|
+
|
|
3824
|
+
// node_modules/bindings/bindings.js
|
|
3825
|
+
var require_bindings = __commonJS({
|
|
3826
|
+
"node_modules/bindings/bindings.js"(exports2, module2) {
|
|
3827
|
+
var fs5 = require("fs");
|
|
3828
|
+
var path4 = require("path");
|
|
3829
|
+
var fileURLToPath3 = require_file_uri_to_path();
|
|
3830
|
+
var join17 = path4.join;
|
|
3831
|
+
var dirname5 = path4.dirname;
|
|
3832
|
+
var exists = fs5.accessSync && function(path5) {
|
|
3833
|
+
try {
|
|
3834
|
+
fs5.accessSync(path5);
|
|
3835
|
+
} catch (e2) {
|
|
3836
|
+
return false;
|
|
3993
3837
|
}
|
|
3838
|
+
return true;
|
|
3839
|
+
} || fs5.existsSync || path4.existsSync;
|
|
3840
|
+
var defaults2 = {
|
|
3841
|
+
arrow: process.env.NODE_BINDINGS_ARROW || " \u2192 ",
|
|
3842
|
+
compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
|
|
3843
|
+
platform: process.platform,
|
|
3844
|
+
arch: process.arch,
|
|
3845
|
+
nodePreGyp: "node-v" + process.versions.modules + "-" + process.platform + "-" + process.arch,
|
|
3846
|
+
version: process.versions.node,
|
|
3847
|
+
bindings: "bindings.node",
|
|
3848
|
+
try: [
|
|
3849
|
+
// node-gyp's linked version in the "build" dir
|
|
3850
|
+
["module_root", "build", "bindings"],
|
|
3851
|
+
// node-waf and gyp_addon (a.k.a node-gyp)
|
|
3852
|
+
["module_root", "build", "Debug", "bindings"],
|
|
3853
|
+
["module_root", "build", "Release", "bindings"],
|
|
3854
|
+
// Debug files, for development (legacy behavior, remove for node v0.9)
|
|
3855
|
+
["module_root", "out", "Debug", "bindings"],
|
|
3856
|
+
["module_root", "Debug", "bindings"],
|
|
3857
|
+
// Release files, but manually compiled (legacy behavior, remove for node v0.9)
|
|
3858
|
+
["module_root", "out", "Release", "bindings"],
|
|
3859
|
+
["module_root", "Release", "bindings"],
|
|
3860
|
+
// Legacy from node-waf, node <= 0.4.x
|
|
3861
|
+
["module_root", "build", "default", "bindings"],
|
|
3862
|
+
// Production "Release" buildtype binary (meh...)
|
|
3863
|
+
["module_root", "compiled", "version", "platform", "arch", "bindings"],
|
|
3864
|
+
// node-qbs builds
|
|
3865
|
+
["module_root", "addon-build", "release", "install-root", "bindings"],
|
|
3866
|
+
["module_root", "addon-build", "debug", "install-root", "bindings"],
|
|
3867
|
+
["module_root", "addon-build", "default", "install-root", "bindings"],
|
|
3868
|
+
// node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch}
|
|
3869
|
+
["module_root", "lib", "binding", "nodePreGyp", "bindings"]
|
|
3870
|
+
]
|
|
3994
3871
|
};
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
} finally {
|
|
4001
|
-
_free(tempPtr);
|
|
4002
|
-
}
|
|
4003
|
-
this._ptr = getValue(temp, "i32");
|
|
4004
|
-
if (this._ptr === NULL)
|
|
4005
|
-
throw new SQLite3Error("Nothing to prepare");
|
|
4006
|
-
this._db = db4;
|
|
4007
|
-
}
|
|
4008
|
-
get database() {
|
|
4009
|
-
return this._db;
|
|
4010
|
-
}
|
|
4011
|
-
get isFinalized() {
|
|
4012
|
-
return this._ptr === null;
|
|
4013
|
-
}
|
|
4014
|
-
run(values) {
|
|
4015
|
-
this._assertReady();
|
|
4016
|
-
this._bind(values);
|
|
4017
|
-
this._step();
|
|
4018
|
-
return { changes: sqlite3.changes(this._db._ptr), lastInsertRowid: toNumberOrNot(sqlite3.last_insert_rowid(this._db._ptr)) };
|
|
4019
|
-
}
|
|
4020
|
-
iterate(values, { expand: expand2 = false } = {}) {
|
|
4021
|
-
return this._queryRows(values, expand2);
|
|
4022
|
-
}
|
|
4023
|
-
all(values, { expand: expand2 = false } = {}) {
|
|
4024
|
-
return Array.from(this.iterate(values, { expand: expand2 }));
|
|
4025
|
-
}
|
|
4026
|
-
get(values, { expand: expand2 = false } = {}) {
|
|
4027
|
-
const result = this._queryRows(values, expand2).next();
|
|
4028
|
-
return result.done ? null : result.value;
|
|
3872
|
+
function bindings(opts) {
|
|
3873
|
+
if (typeof opts == "string") {
|
|
3874
|
+
opts = { bindings: opts };
|
|
3875
|
+
} else if (!opts) {
|
|
3876
|
+
opts = {};
|
|
4029
3877
|
}
|
|
4030
|
-
|
|
4031
|
-
if (
|
|
4032
|
-
|
|
3878
|
+
Object.keys(defaults2).map(function(i2) {
|
|
3879
|
+
if (!(i2 in opts))
|
|
3880
|
+
opts[i2] = defaults2[i2];
|
|
3881
|
+
});
|
|
3882
|
+
if (!opts.module_root) {
|
|
3883
|
+
opts.module_root = exports2.getRoot(exports2.getFileName());
|
|
3884
|
+
}
|
|
3885
|
+
if (path4.extname(opts.bindings) != ".node") {
|
|
3886
|
+
opts.bindings += ".node";
|
|
3887
|
+
}
|
|
3888
|
+
var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
|
|
3889
|
+
var tries = [], i = 0, l2 = opts.try.length, n, b3, err;
|
|
3890
|
+
for (; i < l2; i++) {
|
|
3891
|
+
n = join17.apply(
|
|
3892
|
+
null,
|
|
3893
|
+
opts.try[i].map(function(p) {
|
|
3894
|
+
return opts[p] || p;
|
|
3895
|
+
})
|
|
3896
|
+
);
|
|
3897
|
+
tries.push(n);
|
|
4033
3898
|
try {
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
this._assertReady();
|
|
4044
|
-
this._bind(values);
|
|
4045
|
-
const columns = this._getColumnNames();
|
|
4046
|
-
while (this._step())
|
|
4047
|
-
yield this._getRow(columns, expand2);
|
|
4048
|
-
}
|
|
4049
|
-
_bind(values) {
|
|
4050
|
-
if (!this._reset()) {
|
|
4051
|
-
throw new SQLite3Error("Could not reset statement prior to binding new values");
|
|
4052
|
-
}
|
|
4053
|
-
if (Array.isArray(values)) {
|
|
4054
|
-
this._bindArray(values);
|
|
4055
|
-
} else if (values != null && typeof values === "object") {
|
|
4056
|
-
this._bindObject(values);
|
|
4057
|
-
} else if (typeof values !== "undefined") {
|
|
4058
|
-
this._bindValue(values, 1);
|
|
4059
|
-
}
|
|
4060
|
-
}
|
|
4061
|
-
_step() {
|
|
4062
|
-
const ret = sqlite3.step(this._ptr);
|
|
4063
|
-
switch (ret) {
|
|
4064
|
-
case SQLITE_ROW:
|
|
4065
|
-
return true;
|
|
4066
|
-
case SQLITE_DONE:
|
|
4067
|
-
return false;
|
|
4068
|
-
default:
|
|
4069
|
-
this._db._handleError(ret);
|
|
3899
|
+
b3 = opts.path ? requireFunc.resolve(n) : requireFunc(n);
|
|
3900
|
+
if (!opts.path) {
|
|
3901
|
+
b3.path = n;
|
|
3902
|
+
}
|
|
3903
|
+
return b3;
|
|
3904
|
+
} catch (e2) {
|
|
3905
|
+
if (e2.code !== "MODULE_NOT_FOUND" && e2.code !== "QUALIFIED_PATH_RESOLUTION_FAILED" && !/not find/i.test(e2.message)) {
|
|
3906
|
+
throw e2;
|
|
3907
|
+
}
|
|
4070
3908
|
}
|
|
4071
3909
|
}
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
if (
|
|
4090
|
-
|
|
4091
|
-
} else {
|
|
4092
|
-
v2 = new Uint8Array();
|
|
3910
|
+
err = new Error(
|
|
3911
|
+
"Could not locate the bindings file. Tried:\n" + tries.map(function(a3) {
|
|
3912
|
+
return opts.arrow + a3;
|
|
3913
|
+
}).join("\n")
|
|
3914
|
+
);
|
|
3915
|
+
err.tries = tries;
|
|
3916
|
+
throw err;
|
|
3917
|
+
}
|
|
3918
|
+
module2.exports = exports2 = bindings;
|
|
3919
|
+
exports2.getFileName = function getFileName(calling_file) {
|
|
3920
|
+
var origPST = Error.prepareStackTrace, origSTL = Error.stackTraceLimit, dummy = {}, fileName;
|
|
3921
|
+
Error.stackTraceLimit = 10;
|
|
3922
|
+
Error.prepareStackTrace = function(e2, st) {
|
|
3923
|
+
for (var i = 0, l2 = st.length; i < l2; i++) {
|
|
3924
|
+
fileName = st[i].getFileName();
|
|
3925
|
+
if (fileName !== __filename) {
|
|
3926
|
+
if (calling_file) {
|
|
3927
|
+
if (fileName !== calling_file) {
|
|
3928
|
+
return;
|
|
4093
3929
|
}
|
|
4094
|
-
break;
|
|
4095
|
-
case SQLITE_NULL:
|
|
4096
|
-
v2 = null;
|
|
4097
|
-
break;
|
|
4098
|
-
}
|
|
4099
|
-
const column = columns[i];
|
|
4100
|
-
if (expand2) {
|
|
4101
|
-
let table = sqlite3.column_table_name(this._ptr, i);
|
|
4102
|
-
table = table === "" ? "$" : table;
|
|
4103
|
-
if (Object.hasOwn(row, table)) {
|
|
4104
|
-
row[table][column] = v2;
|
|
4105
3930
|
} else {
|
|
4106
|
-
|
|
3931
|
+
return;
|
|
4107
3932
|
}
|
|
4108
|
-
} else {
|
|
4109
|
-
row[column] = v2;
|
|
4110
3933
|
}
|
|
4111
3934
|
}
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
}
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
if (i === 0)
|
|
4129
|
-
throw new SQLite3Error(`Unknown binding parameter: "${param}"`);
|
|
4130
|
-
this._bindValue(value, i);
|
|
4131
|
-
}
|
|
4132
|
-
}
|
|
4133
|
-
_bindValue(value, position) {
|
|
4134
|
-
let ret;
|
|
4135
|
-
switch (typeof value) {
|
|
4136
|
-
case "string":
|
|
4137
|
-
const tempPtr = stringToHeap(value);
|
|
4138
|
-
ret = sqlite3.bind_text(this._ptr, position, tempPtr, -1, SQLITE_TRANSIENT);
|
|
4139
|
-
_free(tempPtr);
|
|
4140
|
-
break;
|
|
4141
|
-
case "number":
|
|
4142
|
-
if (Number.isSafeInteger(value)) {
|
|
4143
|
-
if (value >= INT32_MIN && value <= INT32_MAX) {
|
|
4144
|
-
ret = sqlite3.bind_int(this._ptr, position, value);
|
|
4145
|
-
} else {
|
|
4146
|
-
ret = sqlite3.bind_int64(this._ptr, position, BigInt(value));
|
|
4147
|
-
}
|
|
4148
|
-
} else {
|
|
4149
|
-
ret = sqlite3.bind_double(this._ptr, position, value);
|
|
4150
|
-
}
|
|
4151
|
-
break;
|
|
4152
|
-
case "bigint":
|
|
4153
|
-
ret = sqlite3.bind_int64(this._ptr, position, value);
|
|
4154
|
-
break;
|
|
4155
|
-
case "boolean":
|
|
4156
|
-
ret = sqlite3.bind_int(this._ptr, position, value ? 1 : 0);
|
|
4157
|
-
break;
|
|
4158
|
-
case "object":
|
|
4159
|
-
if (value === null) {
|
|
4160
|
-
ret = sqlite3.bind_null(this._ptr, position);
|
|
4161
|
-
} else if (value instanceof Uint8Array) {
|
|
4162
|
-
const tempPtr2 = arrayToHeap(value);
|
|
4163
|
-
if (value.byteLength <= INT32_MAX) {
|
|
4164
|
-
ret = sqlite3.bind_blob(this._ptr, position, tempPtr2, value.byteLength, SQLITE_TRANSIENT);
|
|
4165
|
-
} else {
|
|
4166
|
-
ret = sqlite3.bind_blob64(this._ptr, position, tempPtr2, BigInt(value.byteLength), SQLITE_TRANSIENT);
|
|
4167
|
-
}
|
|
4168
|
-
_free(tempPtr2);
|
|
4169
|
-
} else {
|
|
4170
|
-
throw new SQLite3Error(`Unsupported type for binding: "${typeof value}"`);
|
|
4171
|
-
}
|
|
4172
|
-
break;
|
|
4173
|
-
default:
|
|
4174
|
-
throw new SQLite3Error(`Unsupported type for binding: "${typeof value}"`);
|
|
3935
|
+
};
|
|
3936
|
+
Error.captureStackTrace(dummy);
|
|
3937
|
+
dummy.stack;
|
|
3938
|
+
Error.prepareStackTrace = origPST;
|
|
3939
|
+
Error.stackTraceLimit = origSTL;
|
|
3940
|
+
var fileSchema = "file://";
|
|
3941
|
+
if (fileName.indexOf(fileSchema) === 0) {
|
|
3942
|
+
fileName = fileURLToPath3(fileName);
|
|
3943
|
+
}
|
|
3944
|
+
return fileName;
|
|
3945
|
+
};
|
|
3946
|
+
exports2.getRoot = function getRoot(file) {
|
|
3947
|
+
var dir = dirname5(file), prev;
|
|
3948
|
+
while (true) {
|
|
3949
|
+
if (dir === ".") {
|
|
3950
|
+
dir = process.cwd();
|
|
4175
3951
|
}
|
|
4176
|
-
if (
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
3952
|
+
if (exists(join17(dir, "package.json")) || exists(join17(dir, "node_modules"))) {
|
|
3953
|
+
return dir;
|
|
3954
|
+
}
|
|
3955
|
+
if (prev === dir) {
|
|
3956
|
+
throw new Error(
|
|
3957
|
+
'Could not find module root given file: "' + file + '". Do you have a `package.json` file? '
|
|
3958
|
+
);
|
|
3959
|
+
}
|
|
3960
|
+
prev = dir;
|
|
3961
|
+
dir = join17(dir, "..");
|
|
4184
3962
|
}
|
|
4185
3963
|
};
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
var
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
var SQLITE_IOERR_CLOSE = 4106;
|
|
4197
|
-
var SQLITE_IOERR_TRUNCATE = 1546;
|
|
4198
|
-
var SQLITE_IOERR_FSTAT = 1802;
|
|
4199
|
-
var SQLITE_IOERR_LOCK = 3850;
|
|
4200
|
-
var SQLITE_IOERR_UNLOCK = 2058;
|
|
4201
|
-
var SQLITE_OPEN_READONLY = 1;
|
|
4202
|
-
var SQLITE_OPEN_READWRITE = 2;
|
|
4203
|
-
var SQLITE_OPEN_CREATE = 4;
|
|
4204
|
-
var SQLITE_OPEN_EXCLUSIVE = 16;
|
|
4205
|
-
var SQLITE_ACCESS_READWRITE = 1;
|
|
4206
|
-
var SQLITE_ACCESS_READ = 2;
|
|
4207
|
-
var SQLITE_LOCK_NONE = 0;
|
|
4208
|
-
var SQLITE_BUSY = 5;
|
|
4209
|
-
function _fd(fileInfo) {
|
|
4210
|
-
return getValue(fileInfo + 4, "i32");
|
|
4211
|
-
}
|
|
4212
|
-
function _isLocked(fileInfo) {
|
|
4213
|
-
return getValue(fileInfo + 8, "i32") != 0;
|
|
4214
|
-
}
|
|
4215
|
-
function _setLocked(fileInfo, locked) {
|
|
4216
|
-
setValue(fileInfo + 8, locked ? 1 : 0, "i32");
|
|
4217
|
-
}
|
|
4218
|
-
function _path(fileInfo) {
|
|
4219
|
-
return UTF8ToString(getValue(fileInfo + 12, "i32"));
|
|
4220
|
-
}
|
|
4221
|
-
function _safeInt(bigInt) {
|
|
4222
|
-
if (bigInt < Number.MIN_SAFE_INTEGER || bigInt > Number.MAX_SAFE_INTEGER)
|
|
4223
|
-
throw 0;
|
|
4224
|
-
return Number(bigInt);
|
|
4225
|
-
}
|
|
4226
|
-
var arguments_ = [];
|
|
4227
|
-
var thisProgram = "./this.program";
|
|
4228
|
-
var quit_ = (status2, toThrow) => {
|
|
4229
|
-
throw toThrow;
|
|
3964
|
+
}
|
|
3965
|
+
});
|
|
3966
|
+
|
|
3967
|
+
// node_modules/better-sqlite3/lib/methods/wrappers.js
|
|
3968
|
+
var require_wrappers = __commonJS({
|
|
3969
|
+
"node_modules/better-sqlite3/lib/methods/wrappers.js"(exports2) {
|
|
3970
|
+
"use strict";
|
|
3971
|
+
var { cppdb } = require_util();
|
|
3972
|
+
exports2.prepare = function prepare(sql) {
|
|
3973
|
+
return this[cppdb].prepare(sql, this, false);
|
|
4230
3974
|
};
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
} else {
|
|
4235
|
-
}
|
|
4236
|
-
var scriptDirectory = "";
|
|
4237
|
-
function locateFile(path4) {
|
|
4238
|
-
if (Module["locateFile"]) {
|
|
4239
|
-
return Module["locateFile"](path4, scriptDirectory);
|
|
4240
|
-
}
|
|
4241
|
-
return scriptDirectory + path4;
|
|
4242
|
-
}
|
|
4243
|
-
var readAsync;
|
|
4244
|
-
var readBinary;
|
|
4245
|
-
if (ENVIRONMENT_IS_NODE) {
|
|
4246
|
-
fs3 = require("node:fs");
|
|
4247
|
-
scriptDirectory = __dirname + "/";
|
|
4248
|
-
readBinary = (filename) => {
|
|
4249
|
-
filename = isFileURI(filename) ? new URL(filename) : filename;
|
|
4250
|
-
var ret = fs3.readFileSync(filename);
|
|
4251
|
-
return ret;
|
|
4252
|
-
};
|
|
4253
|
-
readAsync = async (filename, binary = true) => {
|
|
4254
|
-
filename = isFileURI(filename) ? new URL(filename) : filename;
|
|
4255
|
-
var ret = fs3.readFileSync(filename, binary ? void 0 : "utf8");
|
|
4256
|
-
return ret;
|
|
4257
|
-
};
|
|
4258
|
-
if (process.argv.length > 1) {
|
|
4259
|
-
thisProgram = process.argv[1].replace(/\\/g, "/");
|
|
4260
|
-
}
|
|
4261
|
-
arguments_ = process.argv.slice(2);
|
|
4262
|
-
if (typeof module2 != "undefined") {
|
|
4263
|
-
module2["exports"] = Module;
|
|
4264
|
-
}
|
|
4265
|
-
quit_ = (status2, toThrow) => {
|
|
4266
|
-
process.exitCode = status2;
|
|
4267
|
-
throw toThrow;
|
|
4268
|
-
};
|
|
4269
|
-
} else {
|
|
4270
|
-
}
|
|
4271
|
-
var fs3;
|
|
4272
|
-
var out = console.log.bind(console);
|
|
4273
|
-
var err = console.error.bind(console);
|
|
4274
|
-
var wasmBinary;
|
|
4275
|
-
var ABORT2 = false;
|
|
4276
|
-
var EXITSTATUS;
|
|
4277
|
-
var isFileURI = (filename) => filename.startsWith("file://");
|
|
4278
|
-
var runtimeInitialized = false;
|
|
4279
|
-
function updateMemoryViews() {
|
|
4280
|
-
var b3 = wasmMemory.buffer;
|
|
4281
|
-
HEAP8 = new Int8Array(b3);
|
|
4282
|
-
HEAP16 = new Int16Array(b3);
|
|
4283
|
-
HEAPU8 = new Uint8Array(b3);
|
|
4284
|
-
HEAPU16 = new Uint16Array(b3);
|
|
4285
|
-
HEAP32 = new Int32Array(b3);
|
|
4286
|
-
HEAPU32 = new Uint32Array(b3);
|
|
4287
|
-
HEAPF32 = new Float32Array(b3);
|
|
4288
|
-
HEAPF64 = new Float64Array(b3);
|
|
4289
|
-
HEAP64 = new BigInt64Array(b3);
|
|
4290
|
-
HEAPU64 = new BigUint64Array(b3);
|
|
4291
|
-
}
|
|
4292
|
-
function preRun() {
|
|
4293
|
-
if (Module["preRun"]) {
|
|
4294
|
-
if (typeof Module["preRun"] == "function")
|
|
4295
|
-
Module["preRun"] = [Module["preRun"]];
|
|
4296
|
-
while (Module["preRun"].length) {
|
|
4297
|
-
addOnPreRun(Module["preRun"].shift());
|
|
4298
|
-
}
|
|
4299
|
-
}
|
|
4300
|
-
callRuntimeCallbacks(onPreRuns);
|
|
4301
|
-
}
|
|
4302
|
-
function initRuntime() {
|
|
4303
|
-
runtimeInitialized = true;
|
|
4304
|
-
wasmExports["z"]();
|
|
4305
|
-
}
|
|
4306
|
-
function postRun() {
|
|
4307
|
-
if (Module["postRun"]) {
|
|
4308
|
-
if (typeof Module["postRun"] == "function")
|
|
4309
|
-
Module["postRun"] = [Module["postRun"]];
|
|
4310
|
-
while (Module["postRun"].length) {
|
|
4311
|
-
addOnPostRun(Module["postRun"].shift());
|
|
4312
|
-
}
|
|
4313
|
-
}
|
|
4314
|
-
callRuntimeCallbacks(onPostRuns);
|
|
4315
|
-
}
|
|
4316
|
-
function abort(what) {
|
|
4317
|
-
Module["onAbort"]?.(what);
|
|
4318
|
-
what = `Aborted(${what})`;
|
|
4319
|
-
err(what);
|
|
4320
|
-
ABORT2 = true;
|
|
4321
|
-
what += ". Build with -sASSERTIONS for more info.";
|
|
4322
|
-
var e2 = new WebAssembly.RuntimeError(what);
|
|
4323
|
-
throw e2;
|
|
4324
|
-
}
|
|
4325
|
-
var wasmBinaryFile;
|
|
4326
|
-
function findWasmBinary() {
|
|
4327
|
-
return locateFile("node-sqlite3-wasm.wasm");
|
|
4328
|
-
}
|
|
4329
|
-
function getBinarySync(file) {
|
|
4330
|
-
if (file == wasmBinaryFile && wasmBinary) {
|
|
4331
|
-
return new Uint8Array(wasmBinary);
|
|
4332
|
-
}
|
|
4333
|
-
if (readBinary) {
|
|
4334
|
-
return readBinary(file);
|
|
4335
|
-
}
|
|
4336
|
-
throw 'sync fetching of the wasm failed: you can preload it to Module["wasmBinary"] manually, or emcc.py will do that for you when generating HTML (but not JS)';
|
|
4337
|
-
}
|
|
4338
|
-
function instantiateSync(file, info) {
|
|
4339
|
-
var module3;
|
|
4340
|
-
var binary = getBinarySync(file);
|
|
4341
|
-
module3 = new WebAssembly.Module(binary);
|
|
4342
|
-
var instance = new WebAssembly.Instance(module3, info);
|
|
4343
|
-
return [instance, module3];
|
|
4344
|
-
}
|
|
4345
|
-
function getWasmImports() {
|
|
4346
|
-
var imports = { a: wasmImports };
|
|
4347
|
-
return imports;
|
|
4348
|
-
}
|
|
4349
|
-
function createWasm() {
|
|
4350
|
-
function receiveInstance(instance, module3) {
|
|
4351
|
-
wasmExports = instance.exports;
|
|
4352
|
-
assignWasmExports(wasmExports);
|
|
4353
|
-
updateMemoryViews();
|
|
4354
|
-
return wasmExports;
|
|
4355
|
-
}
|
|
4356
|
-
var info = getWasmImports();
|
|
4357
|
-
if (Module["instantiateWasm"]) {
|
|
4358
|
-
return new Promise((resolve, reject) => {
|
|
4359
|
-
Module["instantiateWasm"](info, (inst, mod) => {
|
|
4360
|
-
resolve(receiveInstance(inst, mod));
|
|
4361
|
-
});
|
|
4362
|
-
});
|
|
4363
|
-
}
|
|
4364
|
-
wasmBinaryFile ??= findWasmBinary();
|
|
4365
|
-
var result = instantiateSync(wasmBinaryFile, info);
|
|
4366
|
-
return receiveInstance(result[0]);
|
|
4367
|
-
}
|
|
4368
|
-
var ExitStatus = class {
|
|
4369
|
-
name = "ExitStatus";
|
|
4370
|
-
constructor(status2) {
|
|
4371
|
-
this.message = `Program terminated with exit(${status2})`;
|
|
4372
|
-
this.status = status2;
|
|
4373
|
-
}
|
|
3975
|
+
exports2.exec = function exec(sql) {
|
|
3976
|
+
this[cppdb].exec(sql);
|
|
3977
|
+
return this;
|
|
4374
3978
|
};
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
var HEAP8;
|
|
4379
|
-
var HEAPF32;
|
|
4380
|
-
var HEAPF64;
|
|
4381
|
-
var HEAPU16;
|
|
4382
|
-
var HEAPU32;
|
|
4383
|
-
var HEAPU64;
|
|
4384
|
-
var HEAPU8;
|
|
4385
|
-
var callRuntimeCallbacks = (callbacks) => {
|
|
4386
|
-
while (callbacks.length > 0) {
|
|
4387
|
-
callbacks.shift()(Module);
|
|
4388
|
-
}
|
|
3979
|
+
exports2.close = function close() {
|
|
3980
|
+
this[cppdb].close();
|
|
3981
|
+
return this;
|
|
4389
3982
|
};
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
var addOnPreRun = (cb) => onPreRuns.push(cb);
|
|
4394
|
-
function getValue(ptr, type = "i8") {
|
|
4395
|
-
if (type.endsWith("*"))
|
|
4396
|
-
type = "*";
|
|
4397
|
-
switch (type) {
|
|
4398
|
-
case "i1":
|
|
4399
|
-
return HEAP8[ptr];
|
|
4400
|
-
case "i8":
|
|
4401
|
-
return HEAP8[ptr];
|
|
4402
|
-
case "i16":
|
|
4403
|
-
return HEAP16[ptr >> 1];
|
|
4404
|
-
case "i32":
|
|
4405
|
-
return HEAP32[ptr >> 2];
|
|
4406
|
-
case "i64":
|
|
4407
|
-
return HEAP64[ptr >> 3];
|
|
4408
|
-
case "float":
|
|
4409
|
-
return HEAPF32[ptr >> 2];
|
|
4410
|
-
case "double":
|
|
4411
|
-
return HEAPF64[ptr >> 3];
|
|
4412
|
-
case "*":
|
|
4413
|
-
return HEAPU32[ptr >> 2];
|
|
4414
|
-
default:
|
|
4415
|
-
abort(`invalid type for getValue: ${type}`);
|
|
4416
|
-
}
|
|
4417
|
-
}
|
|
4418
|
-
var noExitRuntime = true;
|
|
4419
|
-
function setValue(ptr, value, type = "i8") {
|
|
4420
|
-
if (type.endsWith("*"))
|
|
4421
|
-
type = "*";
|
|
4422
|
-
switch (type) {
|
|
4423
|
-
case "i1":
|
|
4424
|
-
HEAP8[ptr] = value;
|
|
4425
|
-
break;
|
|
4426
|
-
case "i8":
|
|
4427
|
-
HEAP8[ptr] = value;
|
|
4428
|
-
break;
|
|
4429
|
-
case "i16":
|
|
4430
|
-
HEAP16[ptr >> 1] = value;
|
|
4431
|
-
break;
|
|
4432
|
-
case "i32":
|
|
4433
|
-
HEAP32[ptr >> 2] = value;
|
|
4434
|
-
break;
|
|
4435
|
-
case "i64":
|
|
4436
|
-
HEAP64[ptr >> 3] = BigInt(value);
|
|
4437
|
-
break;
|
|
4438
|
-
case "float":
|
|
4439
|
-
HEAPF32[ptr >> 2] = value;
|
|
4440
|
-
break;
|
|
4441
|
-
case "double":
|
|
4442
|
-
HEAPF64[ptr >> 3] = value;
|
|
4443
|
-
break;
|
|
4444
|
-
case "*":
|
|
4445
|
-
HEAPU32[ptr >> 2] = value;
|
|
4446
|
-
break;
|
|
4447
|
-
default:
|
|
4448
|
-
abort(`invalid type for setValue: ${type}`);
|
|
4449
|
-
}
|
|
4450
|
-
}
|
|
4451
|
-
var stackRestore = (val) => __emscripten_stack_restore(val);
|
|
4452
|
-
var stackSave = () => _emscripten_stack_get_current();
|
|
4453
|
-
var __abort_js = () => abort("");
|
|
4454
|
-
var runtimeKeepaliveCounter = 0;
|
|
4455
|
-
var __emscripten_runtime_keepalive_clear = () => {
|
|
4456
|
-
noExitRuntime = false;
|
|
4457
|
-
runtimeKeepaliveCounter = 0;
|
|
3983
|
+
exports2.loadExtension = function loadExtension(...args) {
|
|
3984
|
+
this[cppdb].loadExtension(...args);
|
|
3985
|
+
return this;
|
|
4458
3986
|
};
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
var ydayFromDate = (date) => {
|
|
4463
|
-
var leap = isLeapYear(date.getFullYear());
|
|
4464
|
-
var monthDaysCumulative = leap ? MONTH_DAYS_LEAP_CUMULATIVE : MONTH_DAYS_REGULAR_CUMULATIVE;
|
|
4465
|
-
var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1;
|
|
4466
|
-
return yday;
|
|
3987
|
+
exports2.defaultSafeIntegers = function defaultSafeIntegers(...args) {
|
|
3988
|
+
this[cppdb].defaultSafeIntegers(...args);
|
|
3989
|
+
return this;
|
|
4467
3990
|
};
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
function __localtime_js(time, tmPtr) {
|
|
4472
|
-
time = bigintToI53Checked(time);
|
|
4473
|
-
var date = new Date(time * 1e3);
|
|
4474
|
-
HEAP32[tmPtr >> 2] = date.getSeconds();
|
|
4475
|
-
HEAP32[tmPtr + 4 >> 2] = date.getMinutes();
|
|
4476
|
-
HEAP32[tmPtr + 8 >> 2] = date.getHours();
|
|
4477
|
-
HEAP32[tmPtr + 12 >> 2] = date.getDate();
|
|
4478
|
-
HEAP32[tmPtr + 16 >> 2] = date.getMonth();
|
|
4479
|
-
HEAP32[tmPtr + 20 >> 2] = date.getFullYear() - 1900;
|
|
4480
|
-
HEAP32[tmPtr + 24 >> 2] = date.getDay();
|
|
4481
|
-
var yday = ydayFromDate(date) | 0;
|
|
4482
|
-
HEAP32[tmPtr + 28 >> 2] = yday;
|
|
4483
|
-
HEAP32[tmPtr + 36 >> 2] = -(date.getTimezoneOffset() * 60);
|
|
4484
|
-
var start = new Date(date.getFullYear(), 0, 1);
|
|
4485
|
-
var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
|
|
4486
|
-
var winterOffset = start.getTimezoneOffset();
|
|
4487
|
-
var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset)) | 0;
|
|
4488
|
-
HEAP32[tmPtr + 32 >> 2] = dst;
|
|
4489
|
-
}
|
|
4490
|
-
var timers = {};
|
|
4491
|
-
var handleException = (e2) => {
|
|
4492
|
-
if (e2 instanceof ExitStatus || e2 == "unwind") {
|
|
4493
|
-
return EXITSTATUS;
|
|
4494
|
-
}
|
|
4495
|
-
quit_(1, e2);
|
|
3991
|
+
exports2.unsafeMode = function unsafeMode(...args) {
|
|
3992
|
+
this[cppdb].unsafeMode(...args);
|
|
3993
|
+
return this;
|
|
4496
3994
|
};
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
}
|
|
4504
|
-
|
|
3995
|
+
exports2.getters = {
|
|
3996
|
+
name: {
|
|
3997
|
+
get: function name() {
|
|
3998
|
+
return this[cppdb].name;
|
|
3999
|
+
},
|
|
4000
|
+
enumerable: true
|
|
4001
|
+
},
|
|
4002
|
+
open: {
|
|
4003
|
+
get: function open() {
|
|
4004
|
+
return this[cppdb].open;
|
|
4005
|
+
},
|
|
4006
|
+
enumerable: true
|
|
4007
|
+
},
|
|
4008
|
+
inTransaction: {
|
|
4009
|
+
get: function inTransaction() {
|
|
4010
|
+
return this[cppdb].inTransaction;
|
|
4011
|
+
},
|
|
4012
|
+
enumerable: true
|
|
4013
|
+
},
|
|
4014
|
+
readonly: {
|
|
4015
|
+
get: function readonly() {
|
|
4016
|
+
return this[cppdb].readonly;
|
|
4017
|
+
},
|
|
4018
|
+
enumerable: true
|
|
4019
|
+
},
|
|
4020
|
+
memory: {
|
|
4021
|
+
get: function memory() {
|
|
4022
|
+
return this[cppdb].memory;
|
|
4023
|
+
},
|
|
4024
|
+
enumerable: true
|
|
4025
|
+
}
|
|
4505
4026
|
};
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4027
|
+
}
|
|
4028
|
+
});
|
|
4029
|
+
|
|
4030
|
+
// node_modules/better-sqlite3/lib/methods/transaction.js
|
|
4031
|
+
var require_transaction = __commonJS({
|
|
4032
|
+
"node_modules/better-sqlite3/lib/methods/transaction.js"(exports2, module2) {
|
|
4033
|
+
"use strict";
|
|
4034
|
+
var { cppdb } = require_util();
|
|
4035
|
+
var controllers = /* @__PURE__ */ new WeakMap();
|
|
4036
|
+
module2.exports = function transaction(fn) {
|
|
4037
|
+
if (typeof fn !== "function")
|
|
4038
|
+
throw new TypeError("Expected first argument to be a function");
|
|
4039
|
+
const db4 = this[cppdb];
|
|
4040
|
+
const controller = getController(db4, this);
|
|
4041
|
+
const { apply } = Function.prototype;
|
|
4042
|
+
const properties = {
|
|
4043
|
+
default: { value: wrapTransaction(apply, fn, db4, controller.default) },
|
|
4044
|
+
deferred: { value: wrapTransaction(apply, fn, db4, controller.deferred) },
|
|
4045
|
+
immediate: { value: wrapTransaction(apply, fn, db4, controller.immediate) },
|
|
4046
|
+
exclusive: { value: wrapTransaction(apply, fn, db4, controller.exclusive) },
|
|
4047
|
+
database: { value: this, enumerable: true }
|
|
4048
|
+
};
|
|
4049
|
+
Object.defineProperties(properties.default.value, properties);
|
|
4050
|
+
Object.defineProperties(properties.deferred.value, properties);
|
|
4051
|
+
Object.defineProperties(properties.immediate.value, properties);
|
|
4052
|
+
Object.defineProperties(properties.exclusive.value, properties);
|
|
4053
|
+
return properties.default.value;
|
|
4509
4054
|
};
|
|
4510
|
-
var
|
|
4511
|
-
|
|
4512
|
-
if (!
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4055
|
+
var getController = (db4, self) => {
|
|
4056
|
+
let controller = controllers.get(db4);
|
|
4057
|
+
if (!controller) {
|
|
4058
|
+
const shared = {
|
|
4059
|
+
commit: db4.prepare("COMMIT", self, false),
|
|
4060
|
+
rollback: db4.prepare("ROLLBACK", self, false),
|
|
4061
|
+
savepoint: db4.prepare("SAVEPOINT ` _bs3. `", self, false),
|
|
4062
|
+
release: db4.prepare("RELEASE ` _bs3. `", self, false),
|
|
4063
|
+
rollbackTo: db4.prepare("ROLLBACK TO ` _bs3. `", self, false)
|
|
4064
|
+
};
|
|
4065
|
+
controllers.set(db4, controller = {
|
|
4066
|
+
default: Object.assign({ begin: db4.prepare("BEGIN", self, false) }, shared),
|
|
4067
|
+
deferred: Object.assign({ begin: db4.prepare("BEGIN DEFERRED", self, false) }, shared),
|
|
4068
|
+
immediate: Object.assign({ begin: db4.prepare("BEGIN IMMEDIATE", self, false) }, shared),
|
|
4069
|
+
exclusive: Object.assign({ begin: db4.prepare("BEGIN EXCLUSIVE", self, false) }, shared)
|
|
4070
|
+
});
|
|
4518
4071
|
}
|
|
4072
|
+
return controller;
|
|
4519
4073
|
};
|
|
4520
|
-
var
|
|
4521
|
-
|
|
4522
|
-
|
|
4074
|
+
var wrapTransaction = (apply, fn, db4, { begin, commit, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction() {
|
|
4075
|
+
let before, after, undo;
|
|
4076
|
+
if (db4.inTransaction) {
|
|
4077
|
+
before = savepoint;
|
|
4078
|
+
after = release;
|
|
4079
|
+
undo = rollbackTo;
|
|
4080
|
+
} else {
|
|
4081
|
+
before = begin;
|
|
4082
|
+
after = commit;
|
|
4083
|
+
undo = rollback;
|
|
4523
4084
|
}
|
|
4085
|
+
before.run();
|
|
4524
4086
|
try {
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4087
|
+
const result = apply.call(fn, this, arguments);
|
|
4088
|
+
if (result && typeof result.then === "function") {
|
|
4089
|
+
throw new TypeError("Transaction function cannot return a promise");
|
|
4090
|
+
}
|
|
4091
|
+
after.run();
|
|
4092
|
+
return result;
|
|
4093
|
+
} catch (ex) {
|
|
4094
|
+
if (db4.inTransaction) {
|
|
4095
|
+
undo.run();
|
|
4096
|
+
if (undo !== rollback)
|
|
4097
|
+
after.run();
|
|
4098
|
+
}
|
|
4099
|
+
throw ex;
|
|
4530
4100
|
}
|
|
4531
4101
|
};
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4102
|
+
}
|
|
4103
|
+
});
|
|
4104
|
+
|
|
4105
|
+
// node_modules/better-sqlite3/lib/methods/pragma.js
|
|
4106
|
+
var require_pragma = __commonJS({
|
|
4107
|
+
"node_modules/better-sqlite3/lib/methods/pragma.js"(exports2, module2) {
|
|
4108
|
+
"use strict";
|
|
4109
|
+
var { getBooleanOption, cppdb } = require_util();
|
|
4110
|
+
module2.exports = function pragma(source, options) {
|
|
4111
|
+
if (options == null)
|
|
4112
|
+
options = {};
|
|
4113
|
+
if (typeof source !== "string")
|
|
4114
|
+
throw new TypeError("Expected first argument to be a string");
|
|
4115
|
+
if (typeof options !== "object")
|
|
4116
|
+
throw new TypeError("Expected second argument to be an options object");
|
|
4117
|
+
const simple = getBooleanOption(options, "simple");
|
|
4118
|
+
const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);
|
|
4119
|
+
return simple ? stmt.pluck().get() : stmt.all();
|
|
4546
4120
|
};
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4121
|
+
}
|
|
4122
|
+
});
|
|
4123
|
+
|
|
4124
|
+
// node_modules/better-sqlite3/lib/methods/backup.js
|
|
4125
|
+
var require_backup = __commonJS({
|
|
4126
|
+
"node_modules/better-sqlite3/lib/methods/backup.js"(exports2, module2) {
|
|
4127
|
+
"use strict";
|
|
4128
|
+
var fs5 = require("fs");
|
|
4129
|
+
var path4 = require("path");
|
|
4130
|
+
var { promisify: promisify3 } = require("util");
|
|
4131
|
+
var { cppdb } = require_util();
|
|
4132
|
+
var fsAccess = promisify3(fs5.access);
|
|
4133
|
+
module2.exports = async function backup(filename, options) {
|
|
4134
|
+
if (options == null)
|
|
4135
|
+
options = {};
|
|
4136
|
+
if (typeof filename !== "string")
|
|
4137
|
+
throw new TypeError("Expected first argument to be a string");
|
|
4138
|
+
if (typeof options !== "object")
|
|
4139
|
+
throw new TypeError("Expected second argument to be an options object");
|
|
4140
|
+
filename = filename.trim();
|
|
4141
|
+
const attachedName = "attached" in options ? options.attached : "main";
|
|
4142
|
+
const handler = "progress" in options ? options.progress : null;
|
|
4143
|
+
if (!filename)
|
|
4144
|
+
throw new TypeError("Backup filename cannot be an empty string");
|
|
4145
|
+
if (filename === ":memory:")
|
|
4146
|
+
throw new TypeError('Invalid backup filename ":memory:"');
|
|
4147
|
+
if (typeof attachedName !== "string")
|
|
4148
|
+
throw new TypeError('Expected the "attached" option to be a string');
|
|
4149
|
+
if (!attachedName)
|
|
4150
|
+
throw new TypeError('The "attached" option cannot be an empty string');
|
|
4151
|
+
if (handler != null && typeof handler !== "function")
|
|
4152
|
+
throw new TypeError('Expected the "progress" option to be a function');
|
|
4153
|
+
await fsAccess(path4.dirname(filename)).catch(() => {
|
|
4154
|
+
throw new TypeError("Cannot save backup because the directory does not exist");
|
|
4155
|
+
});
|
|
4156
|
+
const isNewFile = await fsAccess(filename).then(() => false, () => true);
|
|
4157
|
+
return runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null);
|
|
4581
4158
|
};
|
|
4582
|
-
var
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4159
|
+
var runBackup = (backup, handler) => {
|
|
4160
|
+
let rate = 0;
|
|
4161
|
+
let useDefault = true;
|
|
4162
|
+
return new Promise((resolve, reject) => {
|
|
4163
|
+
setImmediate(function step() {
|
|
4164
|
+
try {
|
|
4165
|
+
const progress = backup.transfer(rate);
|
|
4166
|
+
if (!progress.remainingPages) {
|
|
4167
|
+
backup.close();
|
|
4168
|
+
resolve(progress);
|
|
4169
|
+
return;
|
|
4170
|
+
}
|
|
4171
|
+
if (useDefault) {
|
|
4172
|
+
useDefault = false;
|
|
4173
|
+
rate = 100;
|
|
4174
|
+
}
|
|
4175
|
+
if (handler) {
|
|
4176
|
+
const ret = handler(progress);
|
|
4177
|
+
if (ret !== void 0) {
|
|
4178
|
+
if (typeof ret === "number" && ret === ret)
|
|
4179
|
+
rate = Math.max(0, Math.min(2147483647, Math.round(ret)));
|
|
4180
|
+
else
|
|
4181
|
+
throw new TypeError("Expected progress callback to return a number or undefined");
|
|
4182
|
+
}
|
|
4183
|
+
}
|
|
4184
|
+
setImmediate(step);
|
|
4185
|
+
} catch (err) {
|
|
4186
|
+
backup.close();
|
|
4187
|
+
reject(err);
|
|
4188
|
+
}
|
|
4189
|
+
});
|
|
4190
|
+
});
|
|
4608
4191
|
};
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4192
|
+
}
|
|
4193
|
+
});
|
|
4194
|
+
|
|
4195
|
+
// node_modules/better-sqlite3/lib/methods/serialize.js
|
|
4196
|
+
var require_serialize = __commonJS({
|
|
4197
|
+
"node_modules/better-sqlite3/lib/methods/serialize.js"(exports2, module2) {
|
|
4198
|
+
"use strict";
|
|
4199
|
+
var { cppdb } = require_util();
|
|
4200
|
+
module2.exports = function serialize2(options) {
|
|
4201
|
+
if (options == null)
|
|
4202
|
+
options = {};
|
|
4203
|
+
if (typeof options !== "object")
|
|
4204
|
+
throw new TypeError("Expected first argument to be an options object");
|
|
4205
|
+
const attachedName = "attached" in options ? options.attached : "main";
|
|
4206
|
+
if (typeof attachedName !== "string")
|
|
4207
|
+
throw new TypeError('Expected the "attached" option to be a string');
|
|
4208
|
+
if (!attachedName)
|
|
4209
|
+
throw new TypeError('The "attached" option cannot be an empty string');
|
|
4210
|
+
return this[cppdb].serialize(attachedName);
|
|
4621
4211
|
};
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
}
|
|
4212
|
+
}
|
|
4213
|
+
});
|
|
4214
|
+
|
|
4215
|
+
// node_modules/better-sqlite3/lib/methods/function.js
|
|
4216
|
+
var require_function = __commonJS({
|
|
4217
|
+
"node_modules/better-sqlite3/lib/methods/function.js"(exports2, module2) {
|
|
4218
|
+
"use strict";
|
|
4219
|
+
var { getBooleanOption, cppdb } = require_util();
|
|
4220
|
+
module2.exports = function defineFunction(name, options, fn) {
|
|
4221
|
+
if (options == null)
|
|
4222
|
+
options = {};
|
|
4223
|
+
if (typeof options === "function") {
|
|
4224
|
+
fn = options;
|
|
4225
|
+
options = {};
|
|
4637
4226
|
}
|
|
4638
|
-
|
|
4227
|
+
if (typeof name !== "string")
|
|
4228
|
+
throw new TypeError("Expected first argument to be a string");
|
|
4229
|
+
if (typeof fn !== "function")
|
|
4230
|
+
throw new TypeError("Expected last argument to be a function");
|
|
4231
|
+
if (typeof options !== "object")
|
|
4232
|
+
throw new TypeError("Expected second argument to be an options object");
|
|
4233
|
+
if (!name)
|
|
4234
|
+
throw new TypeError("User-defined function name cannot be an empty string");
|
|
4235
|
+
const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
|
|
4236
|
+
const deterministic = getBooleanOption(options, "deterministic");
|
|
4237
|
+
const directOnly = getBooleanOption(options, "directOnly");
|
|
4238
|
+
const varargs = getBooleanOption(options, "varargs");
|
|
4239
|
+
let argCount = -1;
|
|
4240
|
+
if (!varargs) {
|
|
4241
|
+
argCount = fn.length;
|
|
4242
|
+
if (!Number.isInteger(argCount) || argCount < 0)
|
|
4243
|
+
throw new TypeError("Expected function.length to be a positive integer");
|
|
4244
|
+
if (argCount > 100)
|
|
4245
|
+
throw new RangeError("User-defined functions cannot have more than 100 arguments");
|
|
4246
|
+
}
|
|
4247
|
+
this[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly);
|
|
4248
|
+
return this;
|
|
4639
4249
|
};
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4250
|
+
}
|
|
4251
|
+
});
|
|
4252
|
+
|
|
4253
|
+
// node_modules/better-sqlite3/lib/methods/aggregate.js
|
|
4254
|
+
var require_aggregate = __commonJS({
|
|
4255
|
+
"node_modules/better-sqlite3/lib/methods/aggregate.js"(exports2, module2) {
|
|
4256
|
+
"use strict";
|
|
4257
|
+
var { getBooleanOption, cppdb } = require_util();
|
|
4258
|
+
module2.exports = function defineAggregate(name, options) {
|
|
4259
|
+
if (typeof name !== "string")
|
|
4260
|
+
throw new TypeError("Expected first argument to be a string");
|
|
4261
|
+
if (typeof options !== "object" || options === null)
|
|
4262
|
+
throw new TypeError("Expected second argument to be an options object");
|
|
4263
|
+
if (!name)
|
|
4264
|
+
throw new TypeError("User-defined function name cannot be an empty string");
|
|
4265
|
+
const start = "start" in options ? options.start : null;
|
|
4266
|
+
const step = getFunctionOption(options, "step", true);
|
|
4267
|
+
const inverse = getFunctionOption(options, "inverse", false);
|
|
4268
|
+
const result = getFunctionOption(options, "result", false);
|
|
4269
|
+
const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
|
|
4270
|
+
const deterministic = getBooleanOption(options, "deterministic");
|
|
4271
|
+
const directOnly = getBooleanOption(options, "directOnly");
|
|
4272
|
+
const varargs = getBooleanOption(options, "varargs");
|
|
4273
|
+
let argCount = -1;
|
|
4274
|
+
if (!varargs) {
|
|
4275
|
+
argCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0);
|
|
4276
|
+
if (argCount > 0)
|
|
4277
|
+
argCount -= 1;
|
|
4278
|
+
if (argCount > 100)
|
|
4279
|
+
throw new RangeError("User-defined functions cannot have more than 100 arguments");
|
|
4280
|
+
}
|
|
4281
|
+
this[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly);
|
|
4282
|
+
return this;
|
|
4648
4283
|
};
|
|
4649
|
-
var
|
|
4650
|
-
|
|
4651
|
-
if (
|
|
4652
|
-
return
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
str += String.fromCharCode(u0);
|
|
4659
|
-
continue;
|
|
4660
|
-
}
|
|
4661
|
-
var u1 = heapOrArray[idx++] & 63;
|
|
4662
|
-
if ((u0 & 224) == 192) {
|
|
4663
|
-
str += String.fromCharCode((u0 & 31) << 6 | u1);
|
|
4664
|
-
continue;
|
|
4665
|
-
}
|
|
4666
|
-
var u2 = heapOrArray[idx++] & 63;
|
|
4667
|
-
if ((u0 & 240) == 224) {
|
|
4668
|
-
u0 = (u0 & 15) << 12 | u1 << 6 | u2;
|
|
4669
|
-
} else {
|
|
4670
|
-
u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heapOrArray[idx++] & 63;
|
|
4671
|
-
}
|
|
4672
|
-
if (u0 < 65536) {
|
|
4673
|
-
str += String.fromCharCode(u0);
|
|
4674
|
-
} else {
|
|
4675
|
-
var ch = u0 - 65536;
|
|
4676
|
-
str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
|
|
4677
|
-
}
|
|
4678
|
-
}
|
|
4679
|
-
return str;
|
|
4284
|
+
var getFunctionOption = (options, key, required) => {
|
|
4285
|
+
const value = key in options ? options[key] : null;
|
|
4286
|
+
if (typeof value === "function")
|
|
4287
|
+
return value;
|
|
4288
|
+
if (value != null)
|
|
4289
|
+
throw new TypeError(`Expected the "${key}" option to be a function`);
|
|
4290
|
+
if (required)
|
|
4291
|
+
throw new TypeError(`Missing required option "${key}"`);
|
|
4292
|
+
return null;
|
|
4680
4293
|
};
|
|
4681
|
-
var
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4294
|
+
var getLength = ({ length }) => {
|
|
4295
|
+
if (Number.isInteger(length) && length >= 0)
|
|
4296
|
+
return length;
|
|
4297
|
+
throw new TypeError("Expected function.length to be a positive integer");
|
|
4298
|
+
};
|
|
4299
|
+
}
|
|
4300
|
+
});
|
|
4301
|
+
|
|
4302
|
+
// node_modules/better-sqlite3/lib/methods/table.js
|
|
4303
|
+
var require_table = __commonJS({
|
|
4304
|
+
"node_modules/better-sqlite3/lib/methods/table.js"(exports2, module2) {
|
|
4305
|
+
"use strict";
|
|
4306
|
+
var { cppdb } = require_util();
|
|
4307
|
+
module2.exports = function defineTable(name, factory) {
|
|
4308
|
+
if (typeof name !== "string")
|
|
4309
|
+
throw new TypeError("Expected first argument to be a string");
|
|
4310
|
+
if (!name)
|
|
4311
|
+
throw new TypeError("Virtual table module name cannot be an empty string");
|
|
4312
|
+
let eponymous = false;
|
|
4313
|
+
if (typeof factory === "object" && factory !== null) {
|
|
4314
|
+
eponymous = true;
|
|
4315
|
+
factory = defer2(parseTableDefinition(factory, "used", name));
|
|
4316
|
+
} else {
|
|
4317
|
+
if (typeof factory !== "function")
|
|
4318
|
+
throw new TypeError("Expected second argument to be a function or a table definition object");
|
|
4319
|
+
factory = wrapFactory(factory);
|
|
4693
4320
|
}
|
|
4694
|
-
|
|
4321
|
+
this[cppdb].table(factory, name, eponymous);
|
|
4322
|
+
return this;
|
|
4323
|
+
};
|
|
4324
|
+
function wrapFactory(factory) {
|
|
4325
|
+
return function virtualTableFactory(moduleName, databaseName, tableName, ...args) {
|
|
4326
|
+
const thisObject = {
|
|
4327
|
+
module: moduleName,
|
|
4328
|
+
database: databaseName,
|
|
4329
|
+
table: tableName
|
|
4330
|
+
};
|
|
4331
|
+
const def = apply.call(factory, thisObject, args);
|
|
4332
|
+
if (typeof def !== "object" || def === null) {
|
|
4333
|
+
throw new TypeError(`Virtual table module "${moduleName}" did not return a table definition object`);
|
|
4334
|
+
}
|
|
4335
|
+
return parseTableDefinition(def, "returned", moduleName);
|
|
4336
|
+
};
|
|
4695
4337
|
}
|
|
4696
|
-
function
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
setValue(outResult, 1, "i32");
|
|
4700
|
-
} catch {
|
|
4701
|
-
setValue(outResult, 0, "i32");
|
|
4338
|
+
function parseTableDefinition(def, verb, moduleName) {
|
|
4339
|
+
if (!hasOwnProperty.call(def, "rows")) {
|
|
4340
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "rows" property`);
|
|
4702
4341
|
}
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
function _nodejsClose(fi) {
|
|
4706
|
-
_nodejsUnlock(fi, SQLITE_LOCK_NONE);
|
|
4707
|
-
try {
|
|
4708
|
-
fs3.closeSync(_fd(fi));
|
|
4709
|
-
} catch {
|
|
4710
|
-
return SQLITE_IOERR_CLOSE;
|
|
4342
|
+
if (!hasOwnProperty.call(def, "columns")) {
|
|
4343
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "columns" property`);
|
|
4711
4344
|
}
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
const pathStr = UTF8ToString(filePath);
|
|
4716
|
-
try {
|
|
4717
|
-
fs3.unlinkSync(pathStr);
|
|
4718
|
-
} catch (err2) {
|
|
4719
|
-
if (err2.code != "ENOENT")
|
|
4720
|
-
return SQLITE_IOERR_DELETE;
|
|
4345
|
+
const rows = def.rows;
|
|
4346
|
+
if (typeof rows !== "function" || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) {
|
|
4347
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "rows" property (should be a generator function)`);
|
|
4721
4348
|
}
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
fd = fs3.openSync(path3.dirname(pathStr), "r");
|
|
4726
|
-
fs3.fsyncSync(fd);
|
|
4727
|
-
} catch {
|
|
4728
|
-
return SQLITE_IOERR_FSYNC;
|
|
4729
|
-
} finally {
|
|
4730
|
-
try {
|
|
4731
|
-
fs3.closeSync(fd);
|
|
4732
|
-
} catch {
|
|
4733
|
-
return SQLITE_IOERR_FSYNC;
|
|
4734
|
-
}
|
|
4735
|
-
}
|
|
4349
|
+
let columns = def.columns;
|
|
4350
|
+
if (!Array.isArray(columns) || !(columns = [...columns]).every((x3) => typeof x3 === "string")) {
|
|
4351
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "columns" property (should be an array of strings)`);
|
|
4736
4352
|
}
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
function _nodejsFileSize(fi, outSize) {
|
|
4740
|
-
try {
|
|
4741
|
-
setValue(outSize, fs3.fstatSync(_fd(fi)).size, "i64");
|
|
4742
|
-
} catch {
|
|
4743
|
-
return SQLITE_IOERR_FSTAT;
|
|
4353
|
+
if (columns.length !== new Set(columns).size) {
|
|
4354
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate column names`);
|
|
4744
4355
|
}
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
function _nodejsFullPathname(vfs, relPath, sizeFullPath, outFullPath) {
|
|
4748
|
-
const full = path3.resolve(UTF8ToString(relPath));
|
|
4749
|
-
stringToUTF8(full, outFullPath, sizeFullPath);
|
|
4750
|
-
return full.length < sizeFullPath ? SQLITE_OK : SQLITE_CANTOPEN;
|
|
4751
|
-
}
|
|
4752
|
-
function _nodejsLock(fi, level) {
|
|
4753
|
-
if (!_isLocked(fi)) {
|
|
4754
|
-
try {
|
|
4755
|
-
fs3.mkdirSync(`${_path(fi)}.lock`);
|
|
4756
|
-
} catch (err2) {
|
|
4757
|
-
return err2.code == "EEXIST" ? SQLITE_BUSY : SQLITE_IOERR_LOCK;
|
|
4758
|
-
}
|
|
4759
|
-
_setLocked(fi, true);
|
|
4760
|
-
}
|
|
4761
|
-
return SQLITE_OK;
|
|
4762
|
-
}
|
|
4763
|
-
function _nodejsRandomness(vfs, bytes, outBuffer) {
|
|
4764
|
-
const buf = HEAPU8.subarray(outBuffer, outBuffer + bytes);
|
|
4765
|
-
crypto.randomFillSync(buf);
|
|
4766
|
-
return bytes;
|
|
4767
|
-
}
|
|
4768
|
-
function _nodejsRead(fi, outBuffer, bytes, offset2) {
|
|
4769
|
-
const buf = HEAPU8.subarray(outBuffer, outBuffer + bytes);
|
|
4770
|
-
let bytesRead;
|
|
4771
|
-
try {
|
|
4772
|
-
bytesRead = fs3.readSync(_fd(fi), buf, 0, bytes, offset2);
|
|
4773
|
-
} catch {
|
|
4774
|
-
return SQLITE_IOERR_READ;
|
|
4356
|
+
if (!columns.length) {
|
|
4357
|
+
throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with zero columns`);
|
|
4775
4358
|
}
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
if (
|
|
4780
|
-
|
|
4781
|
-
buf.fill(0, bytesRead);
|
|
4782
|
-
} catch {
|
|
4783
|
-
return SQLITE_IOERR_READ;
|
|
4784
|
-
}
|
|
4359
|
+
let parameters;
|
|
4360
|
+
if (hasOwnProperty.call(def, "parameters")) {
|
|
4361
|
+
parameters = def.parameters;
|
|
4362
|
+
if (!Array.isArray(parameters) || !(parameters = [...parameters]).every((x3) => typeof x3 === "string")) {
|
|
4363
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "parameters" property (should be an array of strings)`);
|
|
4785
4364
|
}
|
|
4786
|
-
|
|
4365
|
+
} else {
|
|
4366
|
+
parameters = inferParameters(rows);
|
|
4787
4367
|
}
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
function _nodejsSync(fi, flags) {
|
|
4791
|
-
try {
|
|
4792
|
-
fs3.fsyncSync(_fd(fi));
|
|
4793
|
-
} catch {
|
|
4794
|
-
return SQLITE_IOERR_FSYNC;
|
|
4368
|
+
if (parameters.length !== new Set(parameters).size) {
|
|
4369
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate parameter names`);
|
|
4795
4370
|
}
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
function _nodejsTruncate(fi, size) {
|
|
4799
|
-
try {
|
|
4800
|
-
fs3.ftruncateSync(_fd(fi), _safeInt(size));
|
|
4801
|
-
} catch {
|
|
4802
|
-
return SQLITE_IOERR_TRUNCATE;
|
|
4371
|
+
if (parameters.length > 32) {
|
|
4372
|
+
throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with more than the maximum number of 32 parameters`);
|
|
4803
4373
|
}
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
if (level == SQLITE_LOCK_NONE && _isLocked(fi)) {
|
|
4808
|
-
try {
|
|
4809
|
-
fs3.rmdirSync(`${_path(fi)}.lock`);
|
|
4810
|
-
} catch (err2) {
|
|
4811
|
-
if (err2.code != "ENOENT")
|
|
4812
|
-
return SQLITE_IOERR_UNLOCK;
|
|
4374
|
+
for (const parameter of parameters) {
|
|
4375
|
+
if (columns.includes(parameter)) {
|
|
4376
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with column "${parameter}" which was ambiguously defined as both a column and parameter`);
|
|
4813
4377
|
}
|
|
4814
|
-
_setLocked(fi, false);
|
|
4815
4378
|
}
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
return SQLITE_IOERR_WRITE;
|
|
4824
|
-
}
|
|
4825
|
-
}
|
|
4826
|
-
function _nodejs_max_path_length() {
|
|
4827
|
-
return process.platform == "win32" ? 260 : 4096;
|
|
4828
|
-
}
|
|
4829
|
-
function _nodejs_open(filePath, flags, mode) {
|
|
4830
|
-
let oflags = 0;
|
|
4831
|
-
if (flags & SQLITE_OPEN_EXCLUSIVE)
|
|
4832
|
-
oflags |= fs3.constants.O_EXCL;
|
|
4833
|
-
if (flags & SQLITE_OPEN_CREATE)
|
|
4834
|
-
oflags |= fs3.constants.O_CREAT;
|
|
4835
|
-
if (flags & SQLITE_OPEN_READONLY)
|
|
4836
|
-
oflags |= fs3.constants.O_RDONLY;
|
|
4837
|
-
if (flags & SQLITE_OPEN_READWRITE)
|
|
4838
|
-
oflags |= fs3.constants.O_RDWR;
|
|
4839
|
-
try {
|
|
4840
|
-
return fs3.openSync(UTF8ToString(filePath), oflags, mode);
|
|
4841
|
-
} catch {
|
|
4842
|
-
return -1;
|
|
4379
|
+
let safeIntegers = 2;
|
|
4380
|
+
if (hasOwnProperty.call(def, "safeIntegers")) {
|
|
4381
|
+
const bool = def.safeIntegers;
|
|
4382
|
+
if (typeof bool !== "boolean") {
|
|
4383
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "safeIntegers" property (should be a boolean)`);
|
|
4384
|
+
}
|
|
4385
|
+
safeIntegers = +bool;
|
|
4843
4386
|
}
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
var writeArrayToMemory = (array, buffer) => {
|
|
4850
|
-
HEAP8.set(array, buffer);
|
|
4851
|
-
};
|
|
4852
|
-
var lengthBytesUTF8 = (str) => {
|
|
4853
|
-
var len = 0;
|
|
4854
|
-
for (var i = 0; i < str.length; ++i) {
|
|
4855
|
-
var c = str.charCodeAt(i);
|
|
4856
|
-
if (c <= 127) {
|
|
4857
|
-
len++;
|
|
4858
|
-
} else if (c <= 2047) {
|
|
4859
|
-
len += 2;
|
|
4860
|
-
} else if (c >= 55296 && c <= 57343) {
|
|
4861
|
-
len += 4;
|
|
4862
|
-
++i;
|
|
4863
|
-
} else {
|
|
4864
|
-
len += 3;
|
|
4387
|
+
let directOnly = false;
|
|
4388
|
+
if (hasOwnProperty.call(def, "directOnly")) {
|
|
4389
|
+
directOnly = def.directOnly;
|
|
4390
|
+
if (typeof directOnly !== "boolean") {
|
|
4391
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "directOnly" property (should be a boolean)`);
|
|
4865
4392
|
}
|
|
4866
4393
|
}
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
if (returnType === "boolean")
|
|
4893
|
-
return Boolean(ret2);
|
|
4894
|
-
return ret2;
|
|
4895
|
-
}
|
|
4896
|
-
var func = getCFunc(ident);
|
|
4897
|
-
var cArgs = [];
|
|
4898
|
-
var stack = 0;
|
|
4899
|
-
if (args) {
|
|
4900
|
-
for (var i = 0; i < args.length; i++) {
|
|
4901
|
-
var converter = toC[argTypes[i]];
|
|
4902
|
-
if (converter) {
|
|
4903
|
-
if (stack === 0)
|
|
4904
|
-
stack = stackSave();
|
|
4905
|
-
cArgs[i] = converter(args[i]);
|
|
4394
|
+
const columnDefinitions = [
|
|
4395
|
+
...parameters.map(identifier).map((str) => `${str} HIDDEN`),
|
|
4396
|
+
...columns.map(identifier)
|
|
4397
|
+
];
|
|
4398
|
+
return [
|
|
4399
|
+
`CREATE TABLE x(${columnDefinitions.join(", ")});`,
|
|
4400
|
+
wrapGenerator(rows, new Map(columns.map((x3, i) => [x3, parameters.length + i])), moduleName),
|
|
4401
|
+
parameters,
|
|
4402
|
+
safeIntegers,
|
|
4403
|
+
directOnly
|
|
4404
|
+
];
|
|
4405
|
+
}
|
|
4406
|
+
function wrapGenerator(generator, columnMap, moduleName) {
|
|
4407
|
+
return function* virtualTable(...args) {
|
|
4408
|
+
const output = args.map((x3) => Buffer.isBuffer(x3) ? Buffer.from(x3) : x3);
|
|
4409
|
+
for (let i = 0; i < columnMap.size; ++i) {
|
|
4410
|
+
output.push(null);
|
|
4411
|
+
}
|
|
4412
|
+
for (const row of generator(...args)) {
|
|
4413
|
+
if (Array.isArray(row)) {
|
|
4414
|
+
extractRowArray(row, output, columnMap.size, moduleName);
|
|
4415
|
+
yield output;
|
|
4416
|
+
} else if (typeof row === "object" && row !== null) {
|
|
4417
|
+
extractRowObject(row, output, columnMap, moduleName);
|
|
4418
|
+
yield output;
|
|
4906
4419
|
} else {
|
|
4907
|
-
|
|
4420
|
+
throw new TypeError(`Virtual table module "${moduleName}" yielded something that isn't a valid row object`);
|
|
4908
4421
|
}
|
|
4909
4422
|
}
|
|
4423
|
+
};
|
|
4424
|
+
}
|
|
4425
|
+
function extractRowArray(row, output, columnCount, moduleName) {
|
|
4426
|
+
if (row.length !== columnCount) {
|
|
4427
|
+
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an incorrect number of columns`);
|
|
4910
4428
|
}
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
stackRestore(stack);
|
|
4915
|
-
return convertReturnValue(ret2);
|
|
4916
|
-
}
|
|
4917
|
-
ret = onDone(ret);
|
|
4918
|
-
return ret;
|
|
4919
|
-
};
|
|
4920
|
-
var cwrap = (ident, returnType, argTypes, opts) => {
|
|
4921
|
-
var numericArgs = !argTypes || argTypes.every((type) => type === "number" || type === "boolean");
|
|
4922
|
-
var numericRet = returnType !== "string";
|
|
4923
|
-
if (numericRet && numericArgs && !opts) {
|
|
4924
|
-
return getCFunc(ident);
|
|
4925
|
-
}
|
|
4926
|
-
return (...args) => ccall(ident, returnType, argTypes, args, opts);
|
|
4927
|
-
};
|
|
4928
|
-
var wasmTableMirror = [];
|
|
4929
|
-
var getWasmTableEntry = (funcPtr) => {
|
|
4930
|
-
var func = wasmTableMirror[funcPtr];
|
|
4931
|
-
if (!func) {
|
|
4932
|
-
wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
|
|
4429
|
+
const offset2 = output.length - columnCount;
|
|
4430
|
+
for (let i = 0; i < columnCount; ++i) {
|
|
4431
|
+
output[i + offset2] = row[i];
|
|
4933
4432
|
}
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
functionsInTableMap.set(item, i);
|
|
4942
|
-
}
|
|
4433
|
+
}
|
|
4434
|
+
function extractRowObject(row, output, columnMap, moduleName) {
|
|
4435
|
+
let count = 0;
|
|
4436
|
+
for (const key of Object.keys(row)) {
|
|
4437
|
+
const index = columnMap.get(key);
|
|
4438
|
+
if (index === void 0) {
|
|
4439
|
+
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an undeclared column "${key}"`);
|
|
4943
4440
|
}
|
|
4441
|
+
output[index] = row[key];
|
|
4442
|
+
count += 1;
|
|
4944
4443
|
}
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
var getFunctionAddress = (func) => {
|
|
4948
|
-
if (!functionsInTableMap) {
|
|
4949
|
-
functionsInTableMap = /* @__PURE__ */ new WeakMap();
|
|
4950
|
-
updateTableMap(0, wasmTable.length);
|
|
4951
|
-
}
|
|
4952
|
-
return functionsInTableMap.get(func) || 0;
|
|
4953
|
-
};
|
|
4954
|
-
var freeTableIndexes = [];
|
|
4955
|
-
var getEmptyTableSlot = () => {
|
|
4956
|
-
if (freeTableIndexes.length) {
|
|
4957
|
-
return freeTableIndexes.pop();
|
|
4444
|
+
if (count !== columnMap.size) {
|
|
4445
|
+
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with missing columns`);
|
|
4958
4446
|
}
|
|
4959
|
-
|
|
4960
|
-
}
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
wasmTableMirror[idx] = wasmTable.get(idx);
|
|
4964
|
-
};
|
|
4965
|
-
var uleb128EncodeWithLen = (arr) => {
|
|
4966
|
-
const n = arr.length;
|
|
4967
|
-
return [n % 128 | 128, n >> 7, ...arr];
|
|
4968
|
-
};
|
|
4969
|
-
var wasmTypeCodes = { i: 127, p: 127, j: 126, f: 125, d: 124, e: 111 };
|
|
4970
|
-
var generateTypePack = (types2) => uleb128EncodeWithLen(Array.from(types2, (type) => {
|
|
4971
|
-
var code = wasmTypeCodes[type];
|
|
4972
|
-
return code;
|
|
4973
|
-
}));
|
|
4974
|
-
var convertJsFunctionToWasm = (func, sig) => {
|
|
4975
|
-
var bytes = Uint8Array.of(0, 97, 115, 109, 1, 0, 0, 0, 1, ...uleb128EncodeWithLen([1, 96, ...generateTypePack(sig.slice(1)), ...generateTypePack(sig[0] === "v" ? "" : sig[0])]), 2, 7, 1, 1, 101, 1, 102, 0, 0, 7, 5, 1, 1, 102, 0, 0);
|
|
4976
|
-
var module3 = new WebAssembly.Module(bytes);
|
|
4977
|
-
var instance = new WebAssembly.Instance(module3, { e: { f: func } });
|
|
4978
|
-
var wrappedFunc = instance.exports["f"];
|
|
4979
|
-
return wrappedFunc;
|
|
4980
|
-
};
|
|
4981
|
-
var addFunction = (func, sig) => {
|
|
4982
|
-
var rtn = getFunctionAddress(func);
|
|
4983
|
-
if (rtn) {
|
|
4984
|
-
return rtn;
|
|
4447
|
+
}
|
|
4448
|
+
function inferParameters({ length }) {
|
|
4449
|
+
if (!Number.isInteger(length) || length < 0) {
|
|
4450
|
+
throw new TypeError("Expected function.length to be a positive integer");
|
|
4985
4451
|
}
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
} catch (err2) {
|
|
4990
|
-
if (!(err2 instanceof TypeError)) {
|
|
4991
|
-
throw err2;
|
|
4992
|
-
}
|
|
4993
|
-
var wrapped = convertJsFunctionToWasm(func, sig);
|
|
4994
|
-
setWasmTableEntry(ret, wrapped);
|
|
4452
|
+
const params = [];
|
|
4453
|
+
for (let i = 0; i < length; ++i) {
|
|
4454
|
+
params.push(`$${i + 1}`);
|
|
4995
4455
|
}
|
|
4996
|
-
|
|
4997
|
-
|
|
4456
|
+
return params;
|
|
4457
|
+
}
|
|
4458
|
+
var { hasOwnProperty } = Object.prototype;
|
|
4459
|
+
var { apply } = Function.prototype;
|
|
4460
|
+
var GeneratorFunctionPrototype = Object.getPrototypeOf(function* () {
|
|
4461
|
+
});
|
|
4462
|
+
var identifier = (str) => `"${str.replace(/"/g, '""')}"`;
|
|
4463
|
+
var defer2 = (x3) => () => x3;
|
|
4464
|
+
}
|
|
4465
|
+
});
|
|
4466
|
+
|
|
4467
|
+
// node_modules/better-sqlite3/lib/methods/inspect.js
|
|
4468
|
+
var require_inspect = __commonJS({
|
|
4469
|
+
"node_modules/better-sqlite3/lib/methods/inspect.js"(exports2, module2) {
|
|
4470
|
+
"use strict";
|
|
4471
|
+
var DatabaseInspection = function Database4() {
|
|
4998
4472
|
};
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
setWasmTableEntry(index, null);
|
|
5002
|
-
freeTableIndexes.push(index);
|
|
4473
|
+
module2.exports = function inspect(depth, opts) {
|
|
4474
|
+
return Object.assign(new DatabaseInspection(), this);
|
|
5003
4475
|
};
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
if (
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
var _sqlite3_bind_null;
|
|
5061
|
-
var _sqlite3_bind_text;
|
|
5062
|
-
var _sqlite3_bind_parameter_index;
|
|
5063
|
-
var _sqlite3_exec;
|
|
5064
|
-
var _sqlite3_prepare_v2;
|
|
5065
|
-
var _sqlite3_errmsg;
|
|
5066
|
-
var _sqlite3_last_insert_rowid;
|
|
5067
|
-
var _sqlite3_changes;
|
|
5068
|
-
var _sqlite3_close_v2;
|
|
5069
|
-
var _sqlite3_create_function_v2;
|
|
5070
|
-
var _sqlite3_open_v2;
|
|
5071
|
-
var _sqlite3_get_autocommit;
|
|
5072
|
-
var _malloc;
|
|
5073
|
-
var _free;
|
|
5074
|
-
var __emscripten_timeout;
|
|
5075
|
-
var __emscripten_stack_restore;
|
|
5076
|
-
var __emscripten_stack_alloc;
|
|
5077
|
-
var _emscripten_stack_get_current;
|
|
5078
|
-
var memory;
|
|
5079
|
-
var __indirect_function_table;
|
|
5080
|
-
var wasmMemory;
|
|
5081
|
-
var wasmTable;
|
|
5082
|
-
function assignWasmExports(wasmExports2) {
|
|
5083
|
-
_sqlite3_finalize = Module["_sqlite3_finalize"] = wasmExports2["A"];
|
|
5084
|
-
_sqlite3_reset = Module["_sqlite3_reset"] = wasmExports2["B"];
|
|
5085
|
-
_sqlite3_clear_bindings = Module["_sqlite3_clear_bindings"] = wasmExports2["C"];
|
|
5086
|
-
_sqlite3_value_blob = Module["_sqlite3_value_blob"] = wasmExports2["D"];
|
|
5087
|
-
_sqlite3_value_text = Module["_sqlite3_value_text"] = wasmExports2["E"];
|
|
5088
|
-
_sqlite3_value_bytes = Module["_sqlite3_value_bytes"] = wasmExports2["F"];
|
|
5089
|
-
_sqlite3_value_double = Module["_sqlite3_value_double"] = wasmExports2["G"];
|
|
5090
|
-
_sqlite3_value_int64 = Module["_sqlite3_value_int64"] = wasmExports2["H"];
|
|
5091
|
-
_sqlite3_value_type = Module["_sqlite3_value_type"] = wasmExports2["I"];
|
|
5092
|
-
_sqlite3_result_blob = Module["_sqlite3_result_blob"] = wasmExports2["J"];
|
|
5093
|
-
_sqlite3_result_blob64 = Module["_sqlite3_result_blob64"] = wasmExports2["K"];
|
|
5094
|
-
_sqlite3_result_double = Module["_sqlite3_result_double"] = wasmExports2["L"];
|
|
5095
|
-
_sqlite3_result_error = Module["_sqlite3_result_error"] = wasmExports2["M"];
|
|
5096
|
-
_sqlite3_result_int = Module["_sqlite3_result_int"] = wasmExports2["N"];
|
|
5097
|
-
_sqlite3_result_int64 = Module["_sqlite3_result_int64"] = wasmExports2["O"];
|
|
5098
|
-
_sqlite3_result_null = Module["_sqlite3_result_null"] = wasmExports2["P"];
|
|
5099
|
-
_sqlite3_result_text = Module["_sqlite3_result_text"] = wasmExports2["Q"];
|
|
5100
|
-
_sqlite3_step = Module["_sqlite3_step"] = wasmExports2["R"];
|
|
5101
|
-
_sqlite3_column_count = Module["_sqlite3_column_count"] = wasmExports2["S"];
|
|
5102
|
-
_sqlite3_column_blob = Module["_sqlite3_column_blob"] = wasmExports2["T"];
|
|
5103
|
-
_sqlite3_column_bytes = Module["_sqlite3_column_bytes"] = wasmExports2["U"];
|
|
5104
|
-
_sqlite3_column_double = Module["_sqlite3_column_double"] = wasmExports2["V"];
|
|
5105
|
-
_sqlite3_column_int64 = Module["_sqlite3_column_int64"] = wasmExports2["W"];
|
|
5106
|
-
_sqlite3_column_text = Module["_sqlite3_column_text"] = wasmExports2["X"];
|
|
5107
|
-
_sqlite3_column_type = Module["_sqlite3_column_type"] = wasmExports2["Y"];
|
|
5108
|
-
_sqlite3_column_name = Module["_sqlite3_column_name"] = wasmExports2["Z"];
|
|
5109
|
-
_sqlite3_column_table_name = Module["_sqlite3_column_table_name"] = wasmExports2["_"];
|
|
5110
|
-
_sqlite3_bind_blob = Module["_sqlite3_bind_blob"] = wasmExports2["$"];
|
|
5111
|
-
_sqlite3_bind_blob64 = Module["_sqlite3_bind_blob64"] = wasmExports2["aa"];
|
|
5112
|
-
_sqlite3_bind_double = Module["_sqlite3_bind_double"] = wasmExports2["ba"];
|
|
5113
|
-
_sqlite3_bind_int = Module["_sqlite3_bind_int"] = wasmExports2["ca"];
|
|
5114
|
-
_sqlite3_bind_int64 = Module["_sqlite3_bind_int64"] = wasmExports2["da"];
|
|
5115
|
-
_sqlite3_bind_null = Module["_sqlite3_bind_null"] = wasmExports2["ea"];
|
|
5116
|
-
_sqlite3_bind_text = Module["_sqlite3_bind_text"] = wasmExports2["fa"];
|
|
5117
|
-
_sqlite3_bind_parameter_index = Module["_sqlite3_bind_parameter_index"] = wasmExports2["ga"];
|
|
5118
|
-
_sqlite3_exec = Module["_sqlite3_exec"] = wasmExports2["ha"];
|
|
5119
|
-
_sqlite3_prepare_v2 = Module["_sqlite3_prepare_v2"] = wasmExports2["ia"];
|
|
5120
|
-
_sqlite3_errmsg = Module["_sqlite3_errmsg"] = wasmExports2["ja"];
|
|
5121
|
-
_sqlite3_last_insert_rowid = Module["_sqlite3_last_insert_rowid"] = wasmExports2["ka"];
|
|
5122
|
-
_sqlite3_changes = Module["_sqlite3_changes"] = wasmExports2["la"];
|
|
5123
|
-
_sqlite3_close_v2 = Module["_sqlite3_close_v2"] = wasmExports2["ma"];
|
|
5124
|
-
_sqlite3_create_function_v2 = Module["_sqlite3_create_function_v2"] = wasmExports2["na"];
|
|
5125
|
-
_sqlite3_open_v2 = Module["_sqlite3_open_v2"] = wasmExports2["oa"];
|
|
5126
|
-
_sqlite3_get_autocommit = Module["_sqlite3_get_autocommit"] = wasmExports2["pa"];
|
|
5127
|
-
_malloc = Module["_malloc"] = wasmExports2["qa"];
|
|
5128
|
-
_free = Module["_free"] = wasmExports2["ra"];
|
|
5129
|
-
__emscripten_timeout = wasmExports2["ta"];
|
|
5130
|
-
__emscripten_stack_restore = wasmExports2["ua"];
|
|
5131
|
-
__emscripten_stack_alloc = wasmExports2["va"];
|
|
5132
|
-
_emscripten_stack_get_current = wasmExports2["wa"];
|
|
5133
|
-
memory = wasmMemory = wasmExports2["y"];
|
|
5134
|
-
__indirect_function_table = wasmTable = wasmExports2["sa"];
|
|
5135
|
-
}
|
|
5136
|
-
var wasmImports = { n: __abort_js, l: __emscripten_runtime_keepalive_clear, o: __localtime_js, i: __setitimer_js, p: __tzset_js, q: _emscripten_date_now, a: _emscripten_get_now, j: _emscripten_resize_heap, w: _nodejsAccess, s: _nodejsCheckReservedLock, f: _nodejsClose, x: _nodejsDelete, v: _nodejsFileSize, m: _nodejsFullPathname, u: _nodejsLock, h: _nodejsRandomness, e: _nodejsRead, b: _nodejsSync, c: _nodejsTruncate, t: _nodejsUnlock, d: _nodejsWrite, g: _nodejs_max_path_length, r: _nodejs_open, k: _proc_exit };
|
|
5137
|
-
function run() {
|
|
5138
|
-
preRun();
|
|
5139
|
-
function doRun() {
|
|
5140
|
-
Module["calledRun"] = true;
|
|
5141
|
-
if (ABORT2)
|
|
5142
|
-
return;
|
|
5143
|
-
initRuntime();
|
|
5144
|
-
Module["onRuntimeInitialized"]?.();
|
|
5145
|
-
postRun();
|
|
5146
|
-
}
|
|
5147
|
-
if (Module["setStatus"]) {
|
|
5148
|
-
Module["setStatus"]("Running...");
|
|
5149
|
-
setTimeout(() => {
|
|
5150
|
-
setTimeout(() => Module["setStatus"](""), 1);
|
|
5151
|
-
doRun();
|
|
5152
|
-
}, 1);
|
|
4476
|
+
}
|
|
4477
|
+
});
|
|
4478
|
+
|
|
4479
|
+
// node_modules/better-sqlite3/lib/database.js
|
|
4480
|
+
var require_database = __commonJS({
|
|
4481
|
+
"node_modules/better-sqlite3/lib/database.js"(exports2, module2) {
|
|
4482
|
+
"use strict";
|
|
4483
|
+
var fs5 = require("fs");
|
|
4484
|
+
var path4 = require("path");
|
|
4485
|
+
var util = require_util();
|
|
4486
|
+
var SqliteError = require_sqlite_error();
|
|
4487
|
+
var DEFAULT_ADDON;
|
|
4488
|
+
function Database4(filenameGiven, options) {
|
|
4489
|
+
if (new.target == null) {
|
|
4490
|
+
return new Database4(filenameGiven, options);
|
|
4491
|
+
}
|
|
4492
|
+
let buffer;
|
|
4493
|
+
if (Buffer.isBuffer(filenameGiven)) {
|
|
4494
|
+
buffer = filenameGiven;
|
|
4495
|
+
filenameGiven = ":memory:";
|
|
4496
|
+
}
|
|
4497
|
+
if (filenameGiven == null)
|
|
4498
|
+
filenameGiven = "";
|
|
4499
|
+
if (options == null)
|
|
4500
|
+
options = {};
|
|
4501
|
+
if (typeof filenameGiven !== "string")
|
|
4502
|
+
throw new TypeError("Expected first argument to be a string");
|
|
4503
|
+
if (typeof options !== "object")
|
|
4504
|
+
throw new TypeError("Expected second argument to be an options object");
|
|
4505
|
+
if ("readOnly" in options)
|
|
4506
|
+
throw new TypeError('Misspelled option "readOnly" should be "readonly"');
|
|
4507
|
+
if ("memory" in options)
|
|
4508
|
+
throw new TypeError('Option "memory" was removed in v7.0.0 (use ":memory:" filename instead)');
|
|
4509
|
+
const filename = filenameGiven.trim();
|
|
4510
|
+
const anonymous = filename === "" || filename === ":memory:";
|
|
4511
|
+
const readonly = util.getBooleanOption(options, "readonly");
|
|
4512
|
+
const fileMustExist = util.getBooleanOption(options, "fileMustExist");
|
|
4513
|
+
const timeout = "timeout" in options ? options.timeout : 5e3;
|
|
4514
|
+
const verbose = "verbose" in options ? options.verbose : null;
|
|
4515
|
+
const nativeBinding = "nativeBinding" in options ? options.nativeBinding : null;
|
|
4516
|
+
if (readonly && anonymous && !buffer)
|
|
4517
|
+
throw new TypeError("In-memory/temporary databases cannot be readonly");
|
|
4518
|
+
if (!Number.isInteger(timeout) || timeout < 0)
|
|
4519
|
+
throw new TypeError('Expected the "timeout" option to be a positive integer');
|
|
4520
|
+
if (timeout > 2147483647)
|
|
4521
|
+
throw new RangeError('Option "timeout" cannot be greater than 2147483647');
|
|
4522
|
+
if (verbose != null && typeof verbose !== "function")
|
|
4523
|
+
throw new TypeError('Expected the "verbose" option to be a function');
|
|
4524
|
+
if (nativeBinding != null && typeof nativeBinding !== "string" && typeof nativeBinding !== "object")
|
|
4525
|
+
throw new TypeError('Expected the "nativeBinding" option to be a string or addon object');
|
|
4526
|
+
let addon;
|
|
4527
|
+
if (nativeBinding == null) {
|
|
4528
|
+
addon = DEFAULT_ADDON || (DEFAULT_ADDON = require_bindings()("better_sqlite3.node"));
|
|
4529
|
+
} else if (typeof nativeBinding === "string") {
|
|
4530
|
+
const requireFunc = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : require;
|
|
4531
|
+
addon = requireFunc(path4.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
|
|
5153
4532
|
} else {
|
|
5154
|
-
|
|
4533
|
+
addon = nativeBinding;
|
|
4534
|
+
}
|
|
4535
|
+
if (!addon.isInitialized) {
|
|
4536
|
+
addon.setErrorConstructor(SqliteError);
|
|
4537
|
+
addon.isInitialized = true;
|
|
5155
4538
|
}
|
|
4539
|
+
if (!anonymous && !filename.startsWith("file:") && !fs5.existsSync(path4.dirname(filename))) {
|
|
4540
|
+
throw new TypeError("Cannot open database because the directory does not exist");
|
|
4541
|
+
}
|
|
4542
|
+
Object.defineProperties(this, {
|
|
4543
|
+
[util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },
|
|
4544
|
+
...wrappers.getters
|
|
4545
|
+
});
|
|
5156
4546
|
}
|
|
5157
|
-
var
|
|
5158
|
-
|
|
5159
|
-
|
|
4547
|
+
var wrappers = require_wrappers();
|
|
4548
|
+
Database4.prototype.prepare = wrappers.prepare;
|
|
4549
|
+
Database4.prototype.transaction = require_transaction();
|
|
4550
|
+
Database4.prototype.pragma = require_pragma();
|
|
4551
|
+
Database4.prototype.backup = require_backup();
|
|
4552
|
+
Database4.prototype.serialize = require_serialize();
|
|
4553
|
+
Database4.prototype.function = require_function();
|
|
4554
|
+
Database4.prototype.aggregate = require_aggregate();
|
|
4555
|
+
Database4.prototype.table = require_table();
|
|
4556
|
+
Database4.prototype.loadExtension = wrappers.loadExtension;
|
|
4557
|
+
Database4.prototype.exec = wrappers.exec;
|
|
4558
|
+
Database4.prototype.close = wrappers.close;
|
|
4559
|
+
Database4.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
|
|
4560
|
+
Database4.prototype.unsafeMode = wrappers.unsafeMode;
|
|
4561
|
+
Database4.prototype[util.inspect] = require_inspect();
|
|
4562
|
+
module2.exports = Database4;
|
|
4563
|
+
}
|
|
4564
|
+
});
|
|
4565
|
+
|
|
4566
|
+
// node_modules/better-sqlite3/lib/index.js
|
|
4567
|
+
var require_lib = __commonJS({
|
|
4568
|
+
"node_modules/better-sqlite3/lib/index.js"(exports2, module2) {
|
|
4569
|
+
"use strict";
|
|
4570
|
+
module2.exports = require_database();
|
|
4571
|
+
module2.exports.SqliteError = require_sqlite_error();
|
|
5160
4572
|
}
|
|
5161
4573
|
});
|
|
5162
4574
|
|
|
5163
4575
|
// src/db.ts
|
|
4576
|
+
function isBindingLoadError(e2) {
|
|
4577
|
+
if (!e2 || typeof e2 !== "object")
|
|
4578
|
+
return false;
|
|
4579
|
+
const err = e2;
|
|
4580
|
+
const code = typeof err.code === "string" ? err.code : "";
|
|
4581
|
+
if (code === "ERR_DLOPEN_FAILED" || code === "MODULE_NOT_FOUND")
|
|
4582
|
+
return true;
|
|
4583
|
+
const msg = typeof err.message === "string" ? err.message : "";
|
|
4584
|
+
return /NODE_MODULE_VERSION|different Node\.?js version|dlopen|invalid ELF|not a valid Win32 application|better_sqlite3\.node|Could not locate the bindings|was compiled against/i.test(
|
|
4585
|
+
msg
|
|
4586
|
+
);
|
|
4587
|
+
}
|
|
5164
4588
|
function getDb(dbPath2) {
|
|
5165
4589
|
if (db && currentDbPath === dbPath2)
|
|
5166
4590
|
return db;
|
|
@@ -5168,15 +4592,16 @@ function getDb(dbPath2) {
|
|
|
5168
4592
|
closeDb();
|
|
5169
4593
|
}
|
|
5170
4594
|
(0, import_node_fs5.mkdirSync)((0, import_node_path4.dirname)(dbPath2), { recursive: true });
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
4595
|
+
cleanupWasmArtifacts(dbPath2);
|
|
4596
|
+
const raw2 = openDatabase(dbPath2);
|
|
4597
|
+
try {
|
|
4598
|
+
configurePragmas(raw2, dbPath2);
|
|
4599
|
+
} catch (e2) {
|
|
4600
|
+
raw2.close();
|
|
4601
|
+
throw e2;
|
|
4602
|
+
}
|
|
4603
|
+
db = createAdapter(raw2);
|
|
5174
4604
|
currentDbPath = dbPath2;
|
|
5175
|
-
db.exec("PRAGMA busy_timeout = 5000");
|
|
5176
|
-
db.exec("PRAGMA journal_mode = WAL");
|
|
5177
|
-
db.exec("PRAGMA synchronous = NORMAL");
|
|
5178
|
-
db.exec("PRAGMA wal_autocheckpoint = 1000");
|
|
5179
|
-
db.exec("PRAGMA foreign_keys = ON");
|
|
5180
4605
|
ensureSchema(db);
|
|
5181
4606
|
log({ source: "db", level: "info", summary: `DB: initialized at ${dbPath2}` });
|
|
5182
4607
|
return db;
|
|
@@ -5184,84 +4609,114 @@ function getDb(dbPath2) {
|
|
|
5184
4609
|
function closeDb() {
|
|
5185
4610
|
if (db) {
|
|
5186
4611
|
db.close();
|
|
5187
|
-
if (currentDbPath)
|
|
5188
|
-
removeOwnerFile(currentDbPath);
|
|
5189
4612
|
db = null;
|
|
5190
4613
|
currentDbPath = null;
|
|
5191
4614
|
}
|
|
5192
4615
|
}
|
|
5193
|
-
function
|
|
5194
|
-
|
|
4616
|
+
function _resetDb() {
|
|
4617
|
+
closeDb();
|
|
5195
4618
|
}
|
|
5196
|
-
function
|
|
5197
|
-
|
|
5198
|
-
return "";
|
|
4619
|
+
function openDatabase(dbPath2) {
|
|
4620
|
+
const nativeBinding = resolveNativeBinding();
|
|
5199
4621
|
try {
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
if (
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
const starttime = rest[19];
|
|
5206
|
-
return starttime ?? "";
|
|
5207
|
-
} catch {
|
|
5208
|
-
return "";
|
|
4622
|
+
return nativeBinding ? new import_better_sqlite3.default(dbPath2, { nativeBinding }) : new import_better_sqlite3.default(dbPath2);
|
|
4623
|
+
} catch (e2) {
|
|
4624
|
+
if (isBindingLoadError(e2))
|
|
4625
|
+
throw new BindingLoadError(dbPath2, e2);
|
|
4626
|
+
throw e2;
|
|
5209
4627
|
}
|
|
5210
4628
|
}
|
|
5211
|
-
function
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
4629
|
+
function resolveNativeBinding() {
|
|
4630
|
+
const sibling = (0, import_node_path4.join)(__dirname, "better_sqlite3.node");
|
|
4631
|
+
if ((0, import_node_fs5.existsSync)(sibling))
|
|
4632
|
+
return sibling;
|
|
4633
|
+
const resolved = resolveInstalledBinding();
|
|
4634
|
+
if (resolved)
|
|
4635
|
+
return resolved;
|
|
4636
|
+
const staged = (0, import_node_path4.join)(binDir(), "better_sqlite3.node");
|
|
4637
|
+
if ((0, import_node_fs5.existsSync)(staged))
|
|
4638
|
+
return staged;
|
|
4639
|
+
return null;
|
|
5217
4640
|
}
|
|
5218
|
-
function
|
|
4641
|
+
function resolveInstalledBinding() {
|
|
5219
4642
|
try {
|
|
5220
|
-
(0,
|
|
4643
|
+
const pkgJson = (0, import_node_module.createRequire)(__filename).resolve("better-sqlite3/package.json");
|
|
4644
|
+
return findNativeBinding((0, import_node_path4.dirname)(pkgJson));
|
|
5221
4645
|
} catch {
|
|
4646
|
+
return null;
|
|
5222
4647
|
}
|
|
5223
4648
|
}
|
|
5224
|
-
function
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
4649
|
+
function findNativeBinding(baseDir) {
|
|
4650
|
+
for (const c of [
|
|
4651
|
+
(0, import_node_path4.join)(baseDir, "build", "Release", "better_sqlite3.node"),
|
|
4652
|
+
(0, import_node_path4.join)(baseDir, "build", "Debug", "better_sqlite3.node")
|
|
4653
|
+
]) {
|
|
4654
|
+
try {
|
|
4655
|
+
if ((0, import_node_fs5.statSync)(c).isFile())
|
|
4656
|
+
return c;
|
|
4657
|
+
} catch {
|
|
4658
|
+
}
|
|
5230
4659
|
}
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
return;
|
|
5236
|
-
const ownerFile = ownerFilePath(dbPath2);
|
|
5237
|
-
if ((0, import_node_fs5.existsSync)(ownerFile)) {
|
|
4660
|
+
const stack = [baseDir];
|
|
4661
|
+
while (stack.length) {
|
|
4662
|
+
const dir = stack.pop();
|
|
4663
|
+
let entries;
|
|
5238
4664
|
try {
|
|
5239
|
-
|
|
5240
|
-
const sep2 = raw2.indexOf(":");
|
|
5241
|
-
const pidStr = sep2 === -1 ? raw2 : raw2.slice(0, sep2);
|
|
5242
|
-
const storedToken = sep2 === -1 ? "" : raw2.slice(sep2 + 1);
|
|
5243
|
-
const pid = parseInt(pidStr, 10);
|
|
5244
|
-
if (!isNaN(pid) && isProcessAlive2(pid)) {
|
|
5245
|
-
if (storedToken === "" || storedToken === processStartToken(pid)) {
|
|
5246
|
-
return;
|
|
5247
|
-
}
|
|
5248
|
-
}
|
|
4665
|
+
entries = (0, import_node_fs5.readdirSync)(dir, { withFileTypes: true });
|
|
5249
4666
|
} catch {
|
|
4667
|
+
continue;
|
|
4668
|
+
}
|
|
4669
|
+
for (const e2 of entries) {
|
|
4670
|
+
const p = (0, import_node_path4.join)(dir, e2.name);
|
|
4671
|
+
if (e2.isDirectory())
|
|
4672
|
+
stack.push(p);
|
|
4673
|
+
else if (e2.name.endsWith(".node"))
|
|
4674
|
+
return p;
|
|
5250
4675
|
}
|
|
5251
4676
|
}
|
|
4677
|
+
return null;
|
|
4678
|
+
}
|
|
4679
|
+
function createAdapter(raw2) {
|
|
4680
|
+
return {
|
|
4681
|
+
all: (sql, params) => raw2.prepare(sql).all(...params ?? []),
|
|
4682
|
+
get: (sql, params) => raw2.prepare(sql).get(...params ?? []),
|
|
4683
|
+
run: (sql, params) => raw2.prepare(sql).run(...params ?? []),
|
|
4684
|
+
exec: (sql) => {
|
|
4685
|
+
raw2.exec(sql);
|
|
4686
|
+
},
|
|
4687
|
+
prepare: (sql) => {
|
|
4688
|
+
const st = raw2.prepare(sql);
|
|
4689
|
+
return {
|
|
4690
|
+
run: (p) => st.run(...p ?? []),
|
|
4691
|
+
all: (p) => st.all(...p ?? []),
|
|
4692
|
+
get: (p) => st.get(...p ?? [])
|
|
4693
|
+
};
|
|
4694
|
+
},
|
|
4695
|
+
close: () => raw2.close()
|
|
4696
|
+
};
|
|
4697
|
+
}
|
|
4698
|
+
function configurePragmas(raw2, dbPath2) {
|
|
4699
|
+
const isMemory = dbPath2 === ":memory:" || dbPath2.includes(":memory:") || dbPath2.startsWith("file::memory:");
|
|
4700
|
+
raw2.pragma("busy_timeout = 5000");
|
|
4701
|
+
const mode = raw2.pragma("journal_mode = WAL", { simple: true });
|
|
4702
|
+
if (!isMemory && mode !== "wal") {
|
|
4703
|
+
throw new Error(
|
|
4704
|
+
`recall: expected WAL journal_mode, got '${String(mode)}' \u2014 refusing to run on a non-WAL DB (${dbPath2}). A native build on a delete-mode DB is drift; run \`recall doctor\`.`
|
|
4705
|
+
);
|
|
4706
|
+
}
|
|
4707
|
+
raw2.pragma("synchronous = NORMAL");
|
|
4708
|
+
raw2.pragma("wal_autocheckpoint = 1000");
|
|
4709
|
+
raw2.pragma("foreign_keys = ON");
|
|
4710
|
+
}
|
|
4711
|
+
function cleanupWasmArtifacts(dbPath2) {
|
|
5252
4712
|
try {
|
|
5253
|
-
(0, import_node_fs5.rmSync)(
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
} catch
|
|
5260
|
-
log({
|
|
5261
|
-
source: "db",
|
|
5262
|
-
level: "error",
|
|
5263
|
-
summary: `DB: failed to remove stale lock directory: ${err}`
|
|
5264
|
-
});
|
|
4713
|
+
(0, import_node_fs5.rmSync)(`${dbPath2}.lock`, { recursive: true, force: true });
|
|
4714
|
+
} catch {
|
|
4715
|
+
}
|
|
4716
|
+
try {
|
|
4717
|
+
if ((0, import_node_fs5.existsSync)(`${dbPath2}.owner`))
|
|
4718
|
+
(0, import_node_fs5.unlinkSync)(`${dbPath2}.owner`);
|
|
4719
|
+
} catch {
|
|
5265
4720
|
}
|
|
5266
4721
|
}
|
|
5267
4722
|
function ensureSchema(db4) {
|
|
@@ -5279,6 +4734,12 @@ function ensureSchema(db4) {
|
|
|
5279
4734
|
|
|
5280
4735
|
CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id, created_at);
|
|
5281
4736
|
CREATE INDEX IF NOT EXISTS idx_messages_project ON messages(project_id);
|
|
4737
|
+
-- getUnembeddedMessages() orders the whole table by created_at DESC (LIMIT N).
|
|
4738
|
+
-- Without a standalone created_at index SQLite full-scans messages and builds
|
|
4739
|
+
-- a TEMP B-TREE to sort on every call \u2014 a ~4s/batch cost that dominates the
|
|
4740
|
+
-- embed drain and every Stop-hook catch-up. This index serves the ORDER BY so
|
|
4741
|
+
-- the planner walks it and early-terminates at LIMIT instead.
|
|
4742
|
+
CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at);
|
|
5282
4743
|
`);
|
|
5283
4744
|
db4.exec(`
|
|
5284
4745
|
CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(
|
|
@@ -5319,9 +4780,19 @@ function ensureSchema(db4) {
|
|
|
5319
4780
|
message_id TEXT PRIMARY KEY REFERENCES messages(message_id) ON DELETE CASCADE,
|
|
5320
4781
|
embedding_q8 BLOB NOT NULL,
|
|
5321
4782
|
norm REAL NOT NULL,
|
|
5322
|
-
quant_scale REAL NOT NULL
|
|
4783
|
+
quant_scale REAL NOT NULL,
|
|
4784
|
+
embed_version INTEGER NOT NULL DEFAULT 1
|
|
5323
4785
|
);
|
|
5324
4786
|
`);
|
|
4787
|
+
const hasEmbedVersion = () => db4.all(`PRAGMA table_info(message_vectors)`).some((c) => c.name === "embed_version");
|
|
4788
|
+
if (!hasEmbedVersion()) {
|
|
4789
|
+
try {
|
|
4790
|
+
db4.exec(`ALTER TABLE message_vectors ADD COLUMN embed_version INTEGER NOT NULL DEFAULT 1`);
|
|
4791
|
+
} catch (e2) {
|
|
4792
|
+
if (!hasEmbedVersion())
|
|
4793
|
+
throw e2;
|
|
4794
|
+
}
|
|
4795
|
+
}
|
|
5325
4796
|
db4.exec(`
|
|
5326
4797
|
CREATE TABLE IF NOT EXISTS ingest_watermark (
|
|
5327
4798
|
transcript_path TEXT PRIMARY KEY,
|
|
@@ -5332,14 +4803,27 @@ function ensureSchema(db4) {
|
|
|
5332
4803
|
CREATE INDEX IF NOT EXISTS idx_watermark_vendor ON ingest_watermark(vendor);
|
|
5333
4804
|
`);
|
|
5334
4805
|
}
|
|
5335
|
-
var import_node_fs5, import_node_path4,
|
|
4806
|
+
var import_node_fs5, import_node_path4, import_node_module, import_better_sqlite3, BindingLoadError, db, currentDbPath;
|
|
5336
4807
|
var init_db = __esm({
|
|
5337
4808
|
"src/db.ts"() {
|
|
5338
4809
|
"use strict";
|
|
5339
4810
|
import_node_fs5 = require("node:fs");
|
|
5340
4811
|
import_node_path4 = require("node:path");
|
|
4812
|
+
import_node_module = require("node:module");
|
|
5341
4813
|
init_log();
|
|
5342
|
-
|
|
4814
|
+
init_paths();
|
|
4815
|
+
import_better_sqlite3 = __toESM(require_lib());
|
|
4816
|
+
BindingLoadError = class extends Error {
|
|
4817
|
+
constructor(dbPath2, cause) {
|
|
4818
|
+
super(
|
|
4819
|
+
`recall: failed to load the better-sqlite3 native binding while opening ${dbPath2}: ${cause.message}
|
|
4820
|
+
The binding is ABI-locked to the Node it was built for \u2014 run \`recall doctor\` (usually fixed by re-running \`recall install\`).`
|
|
4821
|
+
);
|
|
4822
|
+
this.dbPath = dbPath2;
|
|
4823
|
+
this.cause = cause;
|
|
4824
|
+
this.name = "BindingLoadError";
|
|
4825
|
+
}
|
|
4826
|
+
};
|
|
5343
4827
|
db = null;
|
|
5344
4828
|
currentDbPath = null;
|
|
5345
4829
|
}
|
|
@@ -5393,7 +4877,7 @@ function normalizeTokenSeparators(input) {
|
|
|
5393
4877
|
return part.replace(/(\w)[-_](\w)/g, "$1 $2");
|
|
5394
4878
|
}).join("");
|
|
5395
4879
|
}
|
|
5396
|
-
function sanitizeFts5Query(raw2) {
|
|
4880
|
+
function sanitizeFts5Query(raw2, opts) {
|
|
5397
4881
|
const trimmed = raw2.trim();
|
|
5398
4882
|
if (!trimmed)
|
|
5399
4883
|
return null;
|
|
@@ -5416,21 +4900,23 @@ function sanitizeFts5Query(raw2) {
|
|
|
5416
4900
|
if (words.length <= 2)
|
|
5417
4901
|
return words.map((w3) => `"${w3}"`).join(" ");
|
|
5418
4902
|
const originalCount = words.length;
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
if (dropped.length > 0) {
|
|
5429
|
-
log({
|
|
5430
|
-
source: "query-sanitizer",
|
|
5431
|
-
level: "debug",
|
|
5432
|
-
summary: `IDF filter: ${originalCount} \u2192 ${words.length} terms, dropped: ${dropped.join(", ")}`
|
|
4903
|
+
if (!opts?.skipIdf) {
|
|
4904
|
+
const dropped = [];
|
|
4905
|
+
words = words.filter((w3) => {
|
|
4906
|
+
const df = getTermDocFrequency(w3);
|
|
4907
|
+
if (df >= IDF_PERCENTILE_THRESHOLD) {
|
|
4908
|
+
dropped.push(`${w3}(${(df * 100).toFixed(0)}%)`);
|
|
4909
|
+
return false;
|
|
4910
|
+
}
|
|
4911
|
+
return true;
|
|
5433
4912
|
});
|
|
4913
|
+
if (dropped.length > 0) {
|
|
4914
|
+
log({
|
|
4915
|
+
source: "query-sanitizer",
|
|
4916
|
+
level: "debug",
|
|
4917
|
+
summary: `IDF filter: ${originalCount} \u2192 ${words.length} terms, dropped: ${dropped.join(", ")}`
|
|
4918
|
+
});
|
|
4919
|
+
}
|
|
5434
4920
|
}
|
|
5435
4921
|
words = [...new Set(words.map((w3) => w3.toLowerCase()))];
|
|
5436
4922
|
if (words.length === 0) {
|
|
@@ -5467,6 +4953,25 @@ var init_query_sanitizer = __esm({
|
|
|
5467
4953
|
}
|
|
5468
4954
|
});
|
|
5469
4955
|
|
|
4956
|
+
// src/recall/embed-config.ts
|
|
4957
|
+
function buildEmbedText(messageText, prevText) {
|
|
4958
|
+
if (messageText.length >= ENRICH_MAX_CHARS || !prevText)
|
|
4959
|
+
return messageText;
|
|
4960
|
+
return prevText.slice(-ENRICH_PREV_CHARS) + ENRICH_SEP + messageText;
|
|
4961
|
+
}
|
|
4962
|
+
var DOC_PREFIX, QUERY_PREFIX, EMBED_VERSION, ENRICH_MAX_CHARS, ENRICH_PREV_CHARS, ENRICH_SEP;
|
|
4963
|
+
var init_embed_config = __esm({
|
|
4964
|
+
"src/recall/embed-config.ts"() {
|
|
4965
|
+
"use strict";
|
|
4966
|
+
DOC_PREFIX = "search_document: ";
|
|
4967
|
+
QUERY_PREFIX = "search_query: ";
|
|
4968
|
+
EMBED_VERSION = 3;
|
|
4969
|
+
ENRICH_MAX_CHARS = 200;
|
|
4970
|
+
ENRICH_PREV_CHARS = 512;
|
|
4971
|
+
ENRICH_SEP = "\n";
|
|
4972
|
+
}
|
|
4973
|
+
});
|
|
4974
|
+
|
|
5470
4975
|
// src/recall/message-store.ts
|
|
5471
4976
|
function db2() {
|
|
5472
4977
|
return getDb(dbPath());
|
|
@@ -5482,7 +4987,7 @@ function insertMessages(messages, opts) {
|
|
|
5482
4987
|
return;
|
|
5483
4988
|
ensureDir2();
|
|
5484
4989
|
const d3 = db2();
|
|
5485
|
-
d3.exec("BEGIN");
|
|
4990
|
+
d3.exec("BEGIN IMMEDIATE");
|
|
5486
4991
|
try {
|
|
5487
4992
|
if (opts?.replaceSessionId) {
|
|
5488
4993
|
d3.run(
|
|
@@ -5497,20 +5002,16 @@ function insertMessages(messages, opts) {
|
|
|
5497
5002
|
(message_id, session_id, message_seq, message_text, project_id, created_at, message_role)
|
|
5498
5003
|
VALUES (?, ?, ?, ?, ?, ?, ?)`
|
|
5499
5004
|
);
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
]);
|
|
5511
|
-
}
|
|
5512
|
-
} finally {
|
|
5513
|
-
stmt.finalize();
|
|
5005
|
+
for (const m2 of messages) {
|
|
5006
|
+
stmt.run([
|
|
5007
|
+
m2.message_id,
|
|
5008
|
+
m2.session_id,
|
|
5009
|
+
m2.message_seq,
|
|
5010
|
+
m2.message_text,
|
|
5011
|
+
m2.project_id,
|
|
5012
|
+
m2.created_at,
|
|
5013
|
+
m2.message_role
|
|
5014
|
+
]);
|
|
5514
5015
|
}
|
|
5515
5016
|
d3.exec("COMMIT");
|
|
5516
5017
|
} catch (e2) {
|
|
@@ -5518,9 +5019,9 @@ function insertMessages(messages, opts) {
|
|
|
5518
5019
|
throw e2;
|
|
5519
5020
|
}
|
|
5520
5021
|
}
|
|
5521
|
-
function searchMessagesFts(query, limit2 = 20, projectId, sessionId, excludeSessionId) {
|
|
5022
|
+
function searchMessagesFts(query, limit2 = 20, projectId, sessionId, excludeSessionId, skipIdf) {
|
|
5522
5023
|
try {
|
|
5523
|
-
const sanitized = sanitizeFts5Query(query);
|
|
5024
|
+
const sanitized = sanitizeFts5Query(query, { skipIdf });
|
|
5524
5025
|
if (!sanitized)
|
|
5525
5026
|
return [];
|
|
5526
5027
|
const params = [sanitized];
|
|
@@ -5631,24 +5132,21 @@ function insertMessageVectors(records) {
|
|
|
5631
5132
|
return;
|
|
5632
5133
|
ensureDir2();
|
|
5633
5134
|
const d3 = db2();
|
|
5634
|
-
d3.exec("BEGIN");
|
|
5135
|
+
d3.exec("BEGIN IMMEDIATE");
|
|
5635
5136
|
try {
|
|
5636
5137
|
const stmt = d3.prepare(
|
|
5637
5138
|
`INSERT OR REPLACE INTO message_vectors
|
|
5638
|
-
(message_id, embedding_q8, norm, quant_scale)
|
|
5639
|
-
VALUES (?, ?, ?, ?)`
|
|
5139
|
+
(message_id, embedding_q8, norm, quant_scale, embed_version)
|
|
5140
|
+
VALUES (?, ?, ?, ?, ?)`
|
|
5640
5141
|
);
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
}
|
|
5650
|
-
} finally {
|
|
5651
|
-
stmt.finalize();
|
|
5142
|
+
for (const r2 of records) {
|
|
5143
|
+
stmt.run([
|
|
5144
|
+
r2.messageId,
|
|
5145
|
+
Buffer.from(r2.embeddingQ8.buffer, r2.embeddingQ8.byteOffset, r2.embeddingQ8.byteLength),
|
|
5146
|
+
r2.norm,
|
|
5147
|
+
r2.quantScale,
|
|
5148
|
+
EMBED_VERSION
|
|
5149
|
+
]);
|
|
5652
5150
|
}
|
|
5653
5151
|
d3.exec("COMMIT");
|
|
5654
5152
|
} catch (e2) {
|
|
@@ -5656,6 +5154,23 @@ function insertMessageVectors(records) {
|
|
|
5656
5154
|
throw e2;
|
|
5657
5155
|
}
|
|
5658
5156
|
}
|
|
5157
|
+
function getEmbedVersionStats() {
|
|
5158
|
+
try {
|
|
5159
|
+
const row = db2().get(
|
|
5160
|
+
`SELECT COUNT(*) AS total,
|
|
5161
|
+
COALESCE(SUM(CASE WHEN embed_version = ? THEN 1 ELSE 0 END), 0) AS current
|
|
5162
|
+
FROM message_vectors`,
|
|
5163
|
+
[EMBED_VERSION]
|
|
5164
|
+
);
|
|
5165
|
+
const total = row ? row.total : 0;
|
|
5166
|
+
const current = row ? row.current ?? 0 : 0;
|
|
5167
|
+
const stale = total - current;
|
|
5168
|
+
const coverage = total === 0 ? 1 : current / total;
|
|
5169
|
+
return { total, current, stale, coverage };
|
|
5170
|
+
} catch {
|
|
5171
|
+
return { total: 0, current: 0, stale: 0, coverage: 1 };
|
|
5172
|
+
}
|
|
5173
|
+
}
|
|
5659
5174
|
function searchMessagesSemantic(queryQ8, queryNorm, queryScale, opts) {
|
|
5660
5175
|
try {
|
|
5661
5176
|
const limit2 = opts?.limit ?? 20;
|
|
@@ -5673,13 +5188,16 @@ function searchMessagesSemantic(queryQ8, queryNorm, queryScale, opts) {
|
|
|
5673
5188
|
filterClauses += " AND m.session_id != ?";
|
|
5674
5189
|
params.push(opts.excludeSessionId);
|
|
5675
5190
|
}
|
|
5191
|
+
const versionClause = opts?.tolerant ? "" : " AND mv.embed_version = ?";
|
|
5192
|
+
if (!opts?.tolerant)
|
|
5193
|
+
params.push(EMBED_VERSION);
|
|
5676
5194
|
const rows = db2().all(
|
|
5677
5195
|
`SELECT mv.message_id, mv.embedding_q8, mv.norm, mv.quant_scale,
|
|
5678
5196
|
m.session_id, m.message_seq, m.project_id, m.created_at, m.message_role,
|
|
5679
5197
|
SUBSTR(m.message_text, 1, 401) as message_preview_raw
|
|
5680
5198
|
FROM message_vectors mv
|
|
5681
5199
|
JOIN messages m ON m.message_id = mv.message_id
|
|
5682
|
-
WHERE 1=1${filterClauses}`,
|
|
5200
|
+
WHERE 1=1${filterClauses}${versionClause}`,
|
|
5683
5201
|
params
|
|
5684
5202
|
);
|
|
5685
5203
|
if (rows.length === 0)
|
|
@@ -5692,6 +5210,8 @@ function searchMessagesSemantic(queryQ8, queryNorm, queryScale, opts) {
|
|
|
5692
5210
|
if (storedNorm === 0 || queryNorm === 0)
|
|
5693
5211
|
continue;
|
|
5694
5212
|
const storedQ8Buf = row.embedding_q8;
|
|
5213
|
+
if (storedQ8Buf.byteLength !== queryQ8.byteLength)
|
|
5214
|
+
continue;
|
|
5695
5215
|
const storedQ8 = new Int8Array(
|
|
5696
5216
|
storedQ8Buf.buffer,
|
|
5697
5217
|
storedQ8Buf.byteOffset,
|
|
@@ -5740,9 +5260,12 @@ function getEmbeddingGapStats() {
|
|
|
5740
5260
|
const row = db2().get(
|
|
5741
5261
|
`SELECT
|
|
5742
5262
|
COUNT(*) as total,
|
|
5743
|
-
SUM(CASE WHEN NOT EXISTS (SELECT 1 FROM message_vectors mv WHERE mv.message_id = m.message_id)
|
|
5744
|
-
AND LENGTH(m.message_text) >= ${MIN_EMBED_CHARS}
|
|
5745
|
-
|
|
5263
|
+
SUM(CASE WHEN NOT EXISTS (SELECT 1 FROM message_vectors mv WHERE mv.message_id = m.message_id AND mv.embed_version = ?)
|
|
5264
|
+
AND (LENGTH(m.message_text) >= ${MIN_EMBED_CHARS}
|
|
5265
|
+
OR EXISTS (SELECT 1 FROM messages p WHERE p.session_id = m.session_id AND p.message_seq < m.message_seq))
|
|
5266
|
+
THEN 1 ELSE 0 END) as gap
|
|
5267
|
+
FROM messages m WHERE m.message_text != ''`,
|
|
5268
|
+
[EMBED_VERSION]
|
|
5746
5269
|
);
|
|
5747
5270
|
return {
|
|
5748
5271
|
totalMessages: row ? row.total : 0,
|
|
@@ -5755,19 +5278,29 @@ function getEmbeddingGapStats() {
|
|
|
5755
5278
|
function getUnembeddedMessages(limit2) {
|
|
5756
5279
|
try {
|
|
5757
5280
|
const rows = db2().all(
|
|
5758
|
-
`SELECT m.message_id, m.session_id, m.message_text
|
|
5281
|
+
`SELECT m.message_id, m.session_id, m.message_text,
|
|
5282
|
+
(SELECT p.message_text FROM messages p
|
|
5283
|
+
WHERE p.session_id = m.session_id AND p.message_seq < m.message_seq
|
|
5284
|
+
ORDER BY p.message_seq DESC LIMIT 1) AS prev_text
|
|
5285
|
+
FROM messages m
|
|
5759
5286
|
WHERE m.message_text != ''
|
|
5760
|
-
AND LENGTH(m.message_text) >= ${MIN_EMBED_CHARS}
|
|
5761
|
-
|
|
5287
|
+
AND (LENGTH(m.message_text) >= ${MIN_EMBED_CHARS}
|
|
5288
|
+
OR EXISTS (SELECT 1 FROM messages p2 WHERE p2.session_id = m.session_id AND p2.message_seq < m.message_seq))
|
|
5289
|
+
AND NOT EXISTS (SELECT 1 FROM message_vectors mv WHERE mv.message_id = m.message_id AND mv.embed_version = ?)
|
|
5762
5290
|
ORDER BY m.created_at DESC
|
|
5763
5291
|
LIMIT ?`,
|
|
5764
|
-
[limit2]
|
|
5292
|
+
[EMBED_VERSION, limit2]
|
|
5765
5293
|
);
|
|
5766
|
-
return rows.map((r2) =>
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5294
|
+
return rows.map((r2) => {
|
|
5295
|
+
const message_text = r2.message_text;
|
|
5296
|
+
const prev_text = r2.prev_text ?? null;
|
|
5297
|
+
return {
|
|
5298
|
+
message_id: r2.message_id,
|
|
5299
|
+
session_id: r2.session_id,
|
|
5300
|
+
message_text,
|
|
5301
|
+
embed_text: buildEmbedText(message_text, prev_text)
|
|
5302
|
+
};
|
|
5303
|
+
});
|
|
5771
5304
|
} catch {
|
|
5772
5305
|
return [];
|
|
5773
5306
|
}
|
|
@@ -5791,6 +5324,7 @@ var init_message_store = __esm({
|
|
|
5791
5324
|
init_paths();
|
|
5792
5325
|
init_query_sanitizer();
|
|
5793
5326
|
init_quantize();
|
|
5327
|
+
init_embed_config();
|
|
5794
5328
|
dirEnsured = false;
|
|
5795
5329
|
MIN_EMBED_CHARS = 50;
|
|
5796
5330
|
}
|
|
@@ -10203,12 +9737,12 @@ var init_esm4 = __esm({
|
|
|
10203
9737
|
/**
|
|
10204
9738
|
* Get the Path object referenced by the string path, resolved from this Path
|
|
10205
9739
|
*/
|
|
10206
|
-
resolve(
|
|
10207
|
-
if (!
|
|
9740
|
+
resolve(path4) {
|
|
9741
|
+
if (!path4) {
|
|
10208
9742
|
return this;
|
|
10209
9743
|
}
|
|
10210
|
-
const rootPath = this.getRootString(
|
|
10211
|
-
const dir =
|
|
9744
|
+
const rootPath = this.getRootString(path4);
|
|
9745
|
+
const dir = path4.substring(rootPath.length);
|
|
10212
9746
|
const dirParts = dir.split(this.splitSep);
|
|
10213
9747
|
const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
|
|
10214
9748
|
return result;
|
|
@@ -10960,8 +10494,8 @@ var init_esm4 = __esm({
|
|
|
10960
10494
|
/**
|
|
10961
10495
|
* @internal
|
|
10962
10496
|
*/
|
|
10963
|
-
getRootString(
|
|
10964
|
-
return import_node_path5.win32.parse(
|
|
10497
|
+
getRootString(path4) {
|
|
10498
|
+
return import_node_path5.win32.parse(path4).root;
|
|
10965
10499
|
}
|
|
10966
10500
|
/**
|
|
10967
10501
|
* @internal
|
|
@@ -11007,8 +10541,8 @@ var init_esm4 = __esm({
|
|
|
11007
10541
|
/**
|
|
11008
10542
|
* @internal
|
|
11009
10543
|
*/
|
|
11010
|
-
getRootString(
|
|
11011
|
-
return
|
|
10544
|
+
getRootString(path4) {
|
|
10545
|
+
return path4.startsWith("/") ? "/" : "";
|
|
11012
10546
|
}
|
|
11013
10547
|
/**
|
|
11014
10548
|
* @internal
|
|
@@ -11057,8 +10591,8 @@ var init_esm4 = __esm({
|
|
|
11057
10591
|
*
|
|
11058
10592
|
* @internal
|
|
11059
10593
|
*/
|
|
11060
|
-
constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs:
|
|
11061
|
-
this.#fs = fsFromOption(
|
|
10594
|
+
constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs5 = defaultFS } = {}) {
|
|
10595
|
+
this.#fs = fsFromOption(fs5);
|
|
11062
10596
|
if (cwd instanceof URL || cwd.startsWith("file://")) {
|
|
11063
10597
|
cwd = (0, import_node_url.fileURLToPath)(cwd);
|
|
11064
10598
|
}
|
|
@@ -11097,11 +10631,11 @@ var init_esm4 = __esm({
|
|
|
11097
10631
|
/**
|
|
11098
10632
|
* Get the depth of a provided path, string, or the cwd
|
|
11099
10633
|
*/
|
|
11100
|
-
depth(
|
|
11101
|
-
if (typeof
|
|
11102
|
-
|
|
10634
|
+
depth(path4 = this.cwd) {
|
|
10635
|
+
if (typeof path4 === "string") {
|
|
10636
|
+
path4 = this.cwd.resolve(path4);
|
|
11103
10637
|
}
|
|
11104
|
-
return
|
|
10638
|
+
return path4.depth();
|
|
11105
10639
|
}
|
|
11106
10640
|
/**
|
|
11107
10641
|
* Return the cache of child entries. Exposed so subclasses can create
|
|
@@ -11588,9 +11122,9 @@ var init_esm4 = __esm({
|
|
|
11588
11122
|
process2();
|
|
11589
11123
|
return results;
|
|
11590
11124
|
}
|
|
11591
|
-
chdir(
|
|
11125
|
+
chdir(path4 = this.cwd) {
|
|
11592
11126
|
const oldCwd = this.cwd;
|
|
11593
|
-
this.cwd = typeof
|
|
11127
|
+
this.cwd = typeof path4 === "string" ? this.cwd.resolve(path4) : path4;
|
|
11594
11128
|
this.cwd[setAsCwd](oldCwd);
|
|
11595
11129
|
}
|
|
11596
11130
|
};
|
|
@@ -11616,8 +11150,8 @@ var init_esm4 = __esm({
|
|
|
11616
11150
|
/**
|
|
11617
11151
|
* @internal
|
|
11618
11152
|
*/
|
|
11619
|
-
newRoot(
|
|
11620
|
-
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
11153
|
+
newRoot(fs5) {
|
|
11154
|
+
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs5 });
|
|
11621
11155
|
}
|
|
11622
11156
|
/**
|
|
11623
11157
|
* Return true if the provided path string is an absolute path
|
|
@@ -11645,8 +11179,8 @@ var init_esm4 = __esm({
|
|
|
11645
11179
|
/**
|
|
11646
11180
|
* @internal
|
|
11647
11181
|
*/
|
|
11648
|
-
newRoot(
|
|
11649
|
-
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
11182
|
+
newRoot(fs5) {
|
|
11183
|
+
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs5 });
|
|
11650
11184
|
}
|
|
11651
11185
|
/**
|
|
11652
11186
|
* Return true if the provided path string is an absolute path
|
|
@@ -11965,8 +11499,8 @@ var init_processor = __esm({
|
|
|
11965
11499
|
}
|
|
11966
11500
|
// match, absolute, ifdir
|
|
11967
11501
|
entries() {
|
|
11968
|
-
return [...this.store.entries()].map(([
|
|
11969
|
-
|
|
11502
|
+
return [...this.store.entries()].map(([path4, n]) => [
|
|
11503
|
+
path4,
|
|
11970
11504
|
!!(n & 2),
|
|
11971
11505
|
!!(n & 1)
|
|
11972
11506
|
]);
|
|
@@ -12179,9 +11713,9 @@ var init_walker = __esm({
|
|
|
12179
11713
|
signal;
|
|
12180
11714
|
maxDepth;
|
|
12181
11715
|
includeChildMatches;
|
|
12182
|
-
constructor(patterns,
|
|
11716
|
+
constructor(patterns, path4, opts) {
|
|
12183
11717
|
this.patterns = patterns;
|
|
12184
|
-
this.path =
|
|
11718
|
+
this.path = path4;
|
|
12185
11719
|
this.opts = opts;
|
|
12186
11720
|
this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
|
|
12187
11721
|
this.includeChildMatches = opts.includeChildMatches !== false;
|
|
@@ -12200,11 +11734,11 @@ var init_walker = __esm({
|
|
|
12200
11734
|
});
|
|
12201
11735
|
}
|
|
12202
11736
|
}
|
|
12203
|
-
#ignored(
|
|
12204
|
-
return this.seen.has(
|
|
11737
|
+
#ignored(path4) {
|
|
11738
|
+
return this.seen.has(path4) || !!this.#ignore?.ignored?.(path4);
|
|
12205
11739
|
}
|
|
12206
|
-
#childrenIgnored(
|
|
12207
|
-
return !!this.#ignore?.childrenIgnored?.(
|
|
11740
|
+
#childrenIgnored(path4) {
|
|
11741
|
+
return !!this.#ignore?.childrenIgnored?.(path4);
|
|
12208
11742
|
}
|
|
12209
11743
|
// backpressure mechanism
|
|
12210
11744
|
pause() {
|
|
@@ -12419,8 +11953,8 @@ var init_walker = __esm({
|
|
|
12419
11953
|
};
|
|
12420
11954
|
GlobWalker = class extends GlobUtil {
|
|
12421
11955
|
matches = /* @__PURE__ */ new Set();
|
|
12422
|
-
constructor(patterns,
|
|
12423
|
-
super(patterns,
|
|
11956
|
+
constructor(patterns, path4, opts) {
|
|
11957
|
+
super(patterns, path4, opts);
|
|
12424
11958
|
}
|
|
12425
11959
|
matchEmit(e2) {
|
|
12426
11960
|
this.matches.add(e2);
|
|
@@ -12457,8 +11991,8 @@ var init_walker = __esm({
|
|
|
12457
11991
|
};
|
|
12458
11992
|
GlobStream = class extends GlobUtil {
|
|
12459
11993
|
results;
|
|
12460
|
-
constructor(patterns,
|
|
12461
|
-
super(patterns,
|
|
11994
|
+
constructor(patterns, path4, opts) {
|
|
11995
|
+
super(patterns, path4, opts);
|
|
12462
11996
|
this.results = new Minipass({
|
|
12463
11997
|
signal: this.signal,
|
|
12464
11998
|
objectMode: true
|
|
@@ -13689,6 +13223,7 @@ async function ingestSessionMessages(sessionId, transcriptPath, vendor, options)
|
|
|
13689
13223
|
async function embedRowsResilient(rows) {
|
|
13690
13224
|
const { embedBatch: embedBatch2 } = await Promise.resolve().then(() => (init_embedder(), embedder_exports));
|
|
13691
13225
|
const { quantizeToQ8: quantizeToQ82, computeNorm: computeNorm2 } = await Promise.resolve().then(() => (init_quantize(), quantize_exports));
|
|
13226
|
+
rows = rows.map((r2) => ({ messageId: r2.messageId, text: DOC_PREFIX + r2.text }));
|
|
13692
13227
|
const toRecord = (messageId, f32) => {
|
|
13693
13228
|
const { q8, scale } = quantizeToQ82(f32);
|
|
13694
13229
|
return { messageId, embeddingQ8: q8, norm: computeNorm2(f32), quantScale: scale };
|
|
@@ -13723,7 +13258,7 @@ async function embedMessageBatch(messages) {
|
|
|
13723
13258
|
return 0;
|
|
13724
13259
|
const truncated = [];
|
|
13725
13260
|
for (const m2 of messages) {
|
|
13726
|
-
const text = m2.message_text.trim();
|
|
13261
|
+
const text = (m2.embed_text ?? m2.message_text).trim();
|
|
13727
13262
|
if (!text)
|
|
13728
13263
|
continue;
|
|
13729
13264
|
truncated.push({
|
|
@@ -13743,6 +13278,7 @@ var init_message_ingest = __esm({
|
|
|
13743
13278
|
"use strict";
|
|
13744
13279
|
init_transcript_utils();
|
|
13745
13280
|
init_message_store();
|
|
13281
|
+
init_embed_config();
|
|
13746
13282
|
init_db();
|
|
13747
13283
|
init_paths();
|
|
13748
13284
|
init_url_path_resolver();
|
|
@@ -15180,11 +14716,11 @@ function downloadFile2(url, destPath) {
|
|
|
15180
14716
|
(0, import_node_https.get)(url, { headers: { "User-Agent": "recall" } }, pipeTo).on("error", done);
|
|
15181
14717
|
});
|
|
15182
14718
|
}
|
|
15183
|
-
var
|
|
14719
|
+
var import_node_child_process3, import_node_fs9, import_node_path9, import_node_util2, import_node_os6, import_node_https, import_extract_zip2, execFileAsync2, EXPECTED_DIMS2, OFFLOAD_TIMEOUT_MS, DEFAULT_NGL, CUDA_ASSET_NAME, CUDA_ASSET_URL, STAGE_DOWNLOAD_TIMEOUT_MS;
|
|
15184
14720
|
var init_gpu = __esm({
|
|
15185
14721
|
"src/installer/gpu.ts"() {
|
|
15186
14722
|
"use strict";
|
|
15187
|
-
|
|
14723
|
+
import_node_child_process3 = require("node:child_process");
|
|
15188
14724
|
import_node_fs9 = require("node:fs");
|
|
15189
14725
|
import_node_path9 = require("node:path");
|
|
15190
14726
|
import_node_util2 = require("node:util");
|
|
@@ -15195,7 +14731,7 @@ var init_gpu = __esm({
|
|
|
15195
14731
|
init_paths();
|
|
15196
14732
|
init_config();
|
|
15197
14733
|
init_log();
|
|
15198
|
-
execFileAsync2 = (0, import_node_util2.promisify)(
|
|
14734
|
+
execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process3.execFile);
|
|
15199
14735
|
EXPECTED_DIMS2 = 768;
|
|
15200
14736
|
OFFLOAD_TIMEOUT_MS = 15e3;
|
|
15201
14737
|
DEFAULT_NGL = 999;
|
|
@@ -15286,25 +14822,25 @@ function detectWsl() {
|
|
|
15286
14822
|
return false;
|
|
15287
14823
|
}
|
|
15288
14824
|
}
|
|
15289
|
-
function canWrite(
|
|
14825
|
+
function canWrite(path4) {
|
|
15290
14826
|
try {
|
|
15291
|
-
(0, import_node_fs10.accessSync)(
|
|
14827
|
+
(0, import_node_fs10.accessSync)(path4, import_node_fs10.constants.W_OK);
|
|
15292
14828
|
return true;
|
|
15293
14829
|
} catch {
|
|
15294
14830
|
return false;
|
|
15295
14831
|
}
|
|
15296
14832
|
}
|
|
15297
14833
|
function checkPlatform(report, opts) {
|
|
15298
|
-
const
|
|
14834
|
+
const os3 = opts.platform ?? (0, import_node_os7.platform)();
|
|
15299
14835
|
const a3 = opts.arch ?? (0, import_node_os7.arch)();
|
|
15300
14836
|
const isWsl = detectWsl();
|
|
15301
|
-
const supported =
|
|
15302
|
-
report.platform = { os:
|
|
14837
|
+
const supported = os3 === "linux" && (a3 === "x64" || a3 === "arm64") || os3 === "darwin" && (a3 === "x64" || a3 === "arm64") || os3 === "win32" && a3 === "x64";
|
|
14838
|
+
report.platform = { os: os3, arch: a3, isWsl, ok: supported };
|
|
15303
14839
|
if (!supported) {
|
|
15304
14840
|
report.failures.push({
|
|
15305
14841
|
check: "platform",
|
|
15306
14842
|
severity: "FAIL",
|
|
15307
|
-
message: `Unsupported platform ${
|
|
14843
|
+
message: `Unsupported platform ${os3}/${a3}`,
|
|
15308
14844
|
remediation: "recall supports Linux x64/arm64, macOS x64/arm64, Windows x64."
|
|
15309
14845
|
});
|
|
15310
14846
|
}
|
|
@@ -15590,10 +15126,140 @@ var init_manifest = __esm({
|
|
|
15590
15126
|
}
|
|
15591
15127
|
});
|
|
15592
15128
|
|
|
15129
|
+
// src/installer/upgrade-migrate.ts
|
|
15130
|
+
function openReadonly(dbFile) {
|
|
15131
|
+
const staged = (0, import_node_path11.join)(binDir(), "better_sqlite3.node");
|
|
15132
|
+
try {
|
|
15133
|
+
return (0, import_node_fs11.existsSync)(staged) ? new import_better_sqlite32.default(dbFile, { readonly: true, fileMustExist: true, nativeBinding: staged }) : new import_better_sqlite32.default(dbFile, { readonly: true, fileMustExist: true });
|
|
15134
|
+
} catch {
|
|
15135
|
+
try {
|
|
15136
|
+
return new import_better_sqlite32.default(dbFile, { readonly: true, fileMustExist: true });
|
|
15137
|
+
} catch {
|
|
15138
|
+
return null;
|
|
15139
|
+
}
|
|
15140
|
+
}
|
|
15141
|
+
}
|
|
15142
|
+
function classifyUpgrade() {
|
|
15143
|
+
const dbFile = dbPath();
|
|
15144
|
+
if (!(0, import_node_fs11.existsSync)(dbFile)) {
|
|
15145
|
+
return { state: "fresh", journalMode: null, markerPresent: false, coverage: 1 };
|
|
15146
|
+
}
|
|
15147
|
+
const markerPresent = (0, import_node_fs11.existsSync)((0, import_node_path11.join)(binDir(), ".binding-info.json"));
|
|
15148
|
+
let journalMode = null;
|
|
15149
|
+
let coverage = 1;
|
|
15150
|
+
const raw2 = openReadonly(dbFile);
|
|
15151
|
+
if (raw2) {
|
|
15152
|
+
try {
|
|
15153
|
+
journalMode = String(raw2.pragma("journal_mode", { simple: true }));
|
|
15154
|
+
} catch {
|
|
15155
|
+
journalMode = null;
|
|
15156
|
+
}
|
|
15157
|
+
try {
|
|
15158
|
+
const row = raw2.prepare(
|
|
15159
|
+
`SELECT COUNT(*) AS total,
|
|
15160
|
+
COALESCE(SUM(CASE WHEN embed_version = ? THEN 1 ELSE 0 END), 0) AS current
|
|
15161
|
+
FROM message_vectors`
|
|
15162
|
+
).get(EMBED_VERSION);
|
|
15163
|
+
const total = row ? Number(row.total) : 0;
|
|
15164
|
+
const current = row ? Number(row.current ?? 0) : 0;
|
|
15165
|
+
coverage = total === 0 ? 1 : current / total;
|
|
15166
|
+
} catch {
|
|
15167
|
+
coverage = 1;
|
|
15168
|
+
}
|
|
15169
|
+
try {
|
|
15170
|
+
raw2.close();
|
|
15171
|
+
} catch {
|
|
15172
|
+
}
|
|
15173
|
+
}
|
|
15174
|
+
const state = markerPresent && journalMode === "wal" ? "already-migrated" : "needs-migration";
|
|
15175
|
+
return { state, journalMode, markerPresent, coverage };
|
|
15176
|
+
}
|
|
15177
|
+
function snapshotDb() {
|
|
15178
|
+
const dbFile = dbPath();
|
|
15179
|
+
if (!(0, import_node_fs11.existsSync)(dbFile))
|
|
15180
|
+
return null;
|
|
15181
|
+
const dest = `${dbFile}.pre-upgrade-${backupStamp()}`;
|
|
15182
|
+
try {
|
|
15183
|
+
(0, import_node_fs11.copyFileSync)(dbFile, dest);
|
|
15184
|
+
const journal = `${dbFile}-journal`;
|
|
15185
|
+
if ((0, import_node_fs11.existsSync)(journal))
|
|
15186
|
+
(0, import_node_fs11.copyFileSync)(journal, `${dest}-journal`);
|
|
15187
|
+
return dest;
|
|
15188
|
+
} catch (e2) {
|
|
15189
|
+
log({ source: "installer/upgrade", level: "warn", summary: `pre-upgrade snapshot failed: ${e2.message}` });
|
|
15190
|
+
return null;
|
|
15191
|
+
}
|
|
15192
|
+
}
|
|
15193
|
+
function integrityStatus() {
|
|
15194
|
+
try {
|
|
15195
|
+
const d3 = getDb(dbPath());
|
|
15196
|
+
const row = d3.get("PRAGMA integrity_check");
|
|
15197
|
+
const detail = row ? String(Object.values(row)[0] ?? "") : "unknown";
|
|
15198
|
+
return { ok: detail === "ok", detail };
|
|
15199
|
+
} catch (e2) {
|
|
15200
|
+
return { ok: false, detail: e2.message };
|
|
15201
|
+
}
|
|
15202
|
+
}
|
|
15203
|
+
function repairStemTables() {
|
|
15204
|
+
try {
|
|
15205
|
+
const d3 = getDb(dbPath());
|
|
15206
|
+
d3.exec("DROP TABLE IF EXISTS _stem_vocab");
|
|
15207
|
+
d3.exec("DROP TABLE IF EXISTS _stem");
|
|
15208
|
+
_resetDb();
|
|
15209
|
+
getDb(dbPath());
|
|
15210
|
+
return integrityStatus().ok;
|
|
15211
|
+
} catch {
|
|
15212
|
+
return false;
|
|
15213
|
+
}
|
|
15214
|
+
}
|
|
15215
|
+
function handleIntegrity() {
|
|
15216
|
+
const st = integrityStatus();
|
|
15217
|
+
if (st.ok)
|
|
15218
|
+
return { status: "ok" };
|
|
15219
|
+
if (/_stem/i.test(st.detail) && repairStemTables()) {
|
|
15220
|
+
return { status: "repaired-stem" };
|
|
15221
|
+
}
|
|
15222
|
+
return { status: "unrecoverable", detail: st.detail };
|
|
15223
|
+
}
|
|
15224
|
+
function backfillAlreadyRunning() {
|
|
15225
|
+
const pidFile = (0, import_node_path11.join)(runDir(), "backfill.pid");
|
|
15226
|
+
if (!(0, import_node_fs11.existsSync)(pidFile))
|
|
15227
|
+
return false;
|
|
15228
|
+
try {
|
|
15229
|
+
const pid = parseInt((0, import_node_fs11.readFileSync)(pidFile, "utf-8").trim(), 10);
|
|
15230
|
+
if (Number.isNaN(pid))
|
|
15231
|
+
return false;
|
|
15232
|
+
process.kill(pid, 0);
|
|
15233
|
+
return true;
|
|
15234
|
+
} catch {
|
|
15235
|
+
return false;
|
|
15236
|
+
}
|
|
15237
|
+
}
|
|
15238
|
+
function migrationReportLine(coverage) {
|
|
15239
|
+
if (coverage >= 1)
|
|
15240
|
+
return null;
|
|
15241
|
+
const pct = Math.round(coverage * 100);
|
|
15242
|
+
return `Embed migration: re-embedding in background (${pct}% at v${EMBED_VERSION}) \u2014 semantic search stays available`;
|
|
15243
|
+
}
|
|
15244
|
+
var import_node_fs11, import_node_path11, import_better_sqlite32;
|
|
15245
|
+
var init_upgrade_migrate = __esm({
|
|
15246
|
+
"src/installer/upgrade-migrate.ts"() {
|
|
15247
|
+
"use strict";
|
|
15248
|
+
import_node_fs11 = require("node:fs");
|
|
15249
|
+
import_node_path11 = require("node:path");
|
|
15250
|
+
import_better_sqlite32 = __toESM(require_lib());
|
|
15251
|
+
init_db();
|
|
15252
|
+
init_paths();
|
|
15253
|
+
init_embed_config();
|
|
15254
|
+
init_settings_merge();
|
|
15255
|
+
init_log();
|
|
15256
|
+
}
|
|
15257
|
+
});
|
|
15258
|
+
|
|
15593
15259
|
// src/installer/claudemd-nudge.ts
|
|
15594
15260
|
function applyNudge(filePath) {
|
|
15595
|
-
const exists = (0,
|
|
15596
|
-
const raw2 = exists ? (0,
|
|
15261
|
+
const exists = (0, import_node_fs12.existsSync)(filePath);
|
|
15262
|
+
const raw2 = exists ? (0, import_node_fs12.readFileSync)(filePath, "utf-8") : "";
|
|
15597
15263
|
if (RECALL_HEADING.test(raw2))
|
|
15598
15264
|
return { changed: false };
|
|
15599
15265
|
const ending = raw2.includes("\r\n") ? "\r\n" : "\n";
|
|
@@ -15607,9 +15273,9 @@ function applyNudge(filePath) {
|
|
|
15607
15273
|
return backup ? { changed: true, backup } : { changed: true };
|
|
15608
15274
|
}
|
|
15609
15275
|
function removeNudge(filePath) {
|
|
15610
|
-
if (!(0,
|
|
15276
|
+
if (!(0, import_node_fs12.existsSync)(filePath))
|
|
15611
15277
|
return { changed: false };
|
|
15612
|
-
const raw2 = (0,
|
|
15278
|
+
const raw2 = (0, import_node_fs12.readFileSync)(filePath, "utf-8");
|
|
15613
15279
|
if (!RECALL_HEADING.test(raw2))
|
|
15614
15280
|
return { changed: false };
|
|
15615
15281
|
const ending = raw2.includes("\r\n") ? "\r\n" : "\n";
|
|
@@ -15637,11 +15303,11 @@ function removeNudge(filePath) {
|
|
|
15637
15303
|
writeFileAtomic(filePath, next);
|
|
15638
15304
|
return { changed: true, backup };
|
|
15639
15305
|
}
|
|
15640
|
-
var
|
|
15306
|
+
var import_node_fs12, RECALL_BLOCK, RECALL_HEADING;
|
|
15641
15307
|
var init_claudemd_nudge = __esm({
|
|
15642
15308
|
"src/installer/claudemd-nudge.ts"() {
|
|
15643
15309
|
"use strict";
|
|
15644
|
-
|
|
15310
|
+
import_node_fs12 = require("node:fs");
|
|
15645
15311
|
init_settings_merge();
|
|
15646
15312
|
RECALL_BLOCK = [
|
|
15647
15313
|
"",
|
|
@@ -15665,60 +15331,132 @@ function defaultDistDir() {
|
|
|
15665
15331
|
const argv1 = process.argv[1];
|
|
15666
15332
|
if (argv1) {
|
|
15667
15333
|
try {
|
|
15668
|
-
return (0,
|
|
15334
|
+
return (0, import_node_path12.dirname)((0, import_node_fs13.realpathSync)(argv1));
|
|
15669
15335
|
} catch {
|
|
15670
|
-
return (0,
|
|
15336
|
+
return (0, import_node_path12.dirname)(argv1);
|
|
15671
15337
|
}
|
|
15672
15338
|
}
|
|
15673
15339
|
return __dirname;
|
|
15674
15340
|
}
|
|
15675
15341
|
function resolveTemplatePath(explicit) {
|
|
15676
|
-
if (explicit && (0,
|
|
15342
|
+
if (explicit && (0, import_node_fs13.existsSync)(explicit))
|
|
15677
15343
|
return explicit;
|
|
15678
15344
|
const here = __dirname;
|
|
15679
15345
|
const candidates = [
|
|
15680
|
-
(0,
|
|
15346
|
+
(0, import_node_path12.join)(here, "SKILL.md.template"),
|
|
15681
15347
|
// bundled: copied next to recall.js
|
|
15682
|
-
(0,
|
|
15348
|
+
(0, import_node_path12.join)(here, "..", "skill", "SKILL.md.template"),
|
|
15683
15349
|
// dist/ sibling skill/
|
|
15684
|
-
(0,
|
|
15350
|
+
(0, import_node_path12.join)(here, "..", "..", "skill", "SKILL.md.template")
|
|
15685
15351
|
// source: src/installer/
|
|
15686
15352
|
];
|
|
15687
15353
|
for (const c of candidates)
|
|
15688
|
-
if ((0,
|
|
15354
|
+
if ((0, import_node_fs13.existsSync)(c))
|
|
15689
15355
|
return c;
|
|
15690
15356
|
return candidates[candidates.length - 1];
|
|
15691
15357
|
}
|
|
15692
15358
|
function recallBinCommand() {
|
|
15693
|
-
return `
|
|
15359
|
+
return `"${process.execPath}" "${(0, import_node_path12.join)(binDir(), "recall.js")}"`;
|
|
15694
15360
|
}
|
|
15695
15361
|
function writeSkill(targetPath, templatePath, runnable) {
|
|
15696
|
-
const template = (0,
|
|
15362
|
+
const template = (0, import_node_fs13.readFileSync)(templatePath, "utf-8");
|
|
15697
15363
|
const body = template.replaceAll("$RECALL_BIN", runnable);
|
|
15698
|
-
(0,
|
|
15699
|
-
if ((0,
|
|
15700
|
-
if ((0,
|
|
15364
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path12.dirname)(targetPath), { recursive: true });
|
|
15365
|
+
if ((0, import_node_fs13.existsSync)(targetPath)) {
|
|
15366
|
+
if ((0, import_node_fs13.readFileSync)(targetPath, "utf-8") === body)
|
|
15701
15367
|
return false;
|
|
15702
15368
|
backupFile(targetPath);
|
|
15703
15369
|
}
|
|
15704
|
-
(0,
|
|
15370
|
+
(0, import_node_fs13.writeFileSync)(targetPath, body);
|
|
15705
15371
|
return true;
|
|
15706
15372
|
}
|
|
15707
15373
|
function stageBundles(distDir, written) {
|
|
15708
|
-
(0,
|
|
15374
|
+
(0, import_node_fs13.mkdirSync)(binDir(), { recursive: true });
|
|
15709
15375
|
for (const name of STAGED_BUNDLES) {
|
|
15710
|
-
const src = (0,
|
|
15711
|
-
if (!(0,
|
|
15376
|
+
const src = (0, import_node_path12.join)(distDir, name);
|
|
15377
|
+
if (!(0, import_node_fs13.existsSync)(src)) {
|
|
15712
15378
|
log({ source: "installer/install", level: "warn", summary: `bundle ${name} not found in ${distDir} \u2014 skipping stage` });
|
|
15713
15379
|
continue;
|
|
15714
15380
|
}
|
|
15715
|
-
const dest = (0,
|
|
15716
|
-
(0,
|
|
15381
|
+
const dest = (0, import_node_path12.join)(binDir(), name);
|
|
15382
|
+
(0, import_node_fs13.copyFileSync)(src, dest);
|
|
15717
15383
|
written.push(dest);
|
|
15718
15384
|
}
|
|
15719
|
-
|
|
15720
|
-
|
|
15721
|
-
|
|
15385
|
+
stageNativeBinding(written);
|
|
15386
|
+
}
|
|
15387
|
+
function stageNativeBinding(written) {
|
|
15388
|
+
const staleWasm = (0, import_node_path12.join)(binDir(), "node-sqlite3-wasm.wasm");
|
|
15389
|
+
if ((0, import_node_fs13.existsSync)(staleWasm)) {
|
|
15390
|
+
try {
|
|
15391
|
+
(0, import_node_fs13.unlinkSync)(staleWasm);
|
|
15392
|
+
} catch {
|
|
15393
|
+
}
|
|
15394
|
+
}
|
|
15395
|
+
const binding = resolveInstalledBinding2();
|
|
15396
|
+
if (!binding) {
|
|
15397
|
+
log({
|
|
15398
|
+
source: "installer/install",
|
|
15399
|
+
level: "warn",
|
|
15400
|
+
summary: "better_sqlite3.node not found in node_modules \u2014 the CLI/hooks will fail to load SQLite until reinstalled"
|
|
15401
|
+
});
|
|
15402
|
+
return;
|
|
15403
|
+
}
|
|
15404
|
+
const dest = (0, import_node_path12.join)(binDir(), "better_sqlite3.node");
|
|
15405
|
+
(0, import_node_fs13.copyFileSync)(binding, dest);
|
|
15406
|
+
written.push(dest);
|
|
15407
|
+
const markerPath = (0, import_node_path12.join)(binDir(), ".binding-info.json");
|
|
15408
|
+
(0, import_node_fs13.writeFileSync)(
|
|
15409
|
+
markerPath,
|
|
15410
|
+
JSON.stringify(
|
|
15411
|
+
{
|
|
15412
|
+
platform: process.platform,
|
|
15413
|
+
arch: process.arch,
|
|
15414
|
+
nodeModuleVersion: process.versions.modules,
|
|
15415
|
+
nodePath: process.execPath
|
|
15416
|
+
},
|
|
15417
|
+
null,
|
|
15418
|
+
2
|
|
15419
|
+
)
|
|
15420
|
+
);
|
|
15421
|
+
written.push(markerPath);
|
|
15422
|
+
}
|
|
15423
|
+
function resolveInstalledBinding2() {
|
|
15424
|
+
try {
|
|
15425
|
+
const pkgJson = (0, import_node_module2.createRequire)(__filename).resolve("better-sqlite3/package.json");
|
|
15426
|
+
return findDotNode((0, import_node_path12.dirname)(pkgJson));
|
|
15427
|
+
} catch {
|
|
15428
|
+
return null;
|
|
15429
|
+
}
|
|
15430
|
+
}
|
|
15431
|
+
function findDotNode(baseDir) {
|
|
15432
|
+
for (const c of [
|
|
15433
|
+
(0, import_node_path12.join)(baseDir, "build", "Release", "better_sqlite3.node"),
|
|
15434
|
+
(0, import_node_path12.join)(baseDir, "build", "Debug", "better_sqlite3.node")
|
|
15435
|
+
]) {
|
|
15436
|
+
try {
|
|
15437
|
+
if ((0, import_node_fs13.statSync)(c).isFile())
|
|
15438
|
+
return c;
|
|
15439
|
+
} catch {
|
|
15440
|
+
}
|
|
15441
|
+
}
|
|
15442
|
+
const stack = [baseDir];
|
|
15443
|
+
while (stack.length) {
|
|
15444
|
+
const dir = stack.pop();
|
|
15445
|
+
let entries;
|
|
15446
|
+
try {
|
|
15447
|
+
entries = (0, import_node_fs13.readdirSync)(dir, { withFileTypes: true });
|
|
15448
|
+
} catch {
|
|
15449
|
+
continue;
|
|
15450
|
+
}
|
|
15451
|
+
for (const e2 of entries) {
|
|
15452
|
+
const p = (0, import_node_path12.join)(dir, e2.name);
|
|
15453
|
+
if (e2.isDirectory())
|
|
15454
|
+
stack.push(p);
|
|
15455
|
+
else if (e2.name.endsWith(".node"))
|
|
15456
|
+
return p;
|
|
15457
|
+
}
|
|
15458
|
+
}
|
|
15459
|
+
return null;
|
|
15722
15460
|
}
|
|
15723
15461
|
async function runInstall(opts = {}) {
|
|
15724
15462
|
const interactive = !!process.stdout.isTTY && !opts.yes && !opts.json;
|
|
@@ -15775,21 +15513,41 @@ ${wmsg}` });
|
|
|
15775
15513
|
log({ source: "installer/install", level: "error", summary: msg });
|
|
15776
15514
|
return { aborted: true, report, selected: [...selected], gpu: { mode: "cpu", libDir: null, ngl: 0, cudaAvailable: "none" }, filesWritten: [] };
|
|
15777
15515
|
}
|
|
15516
|
+
const migration = classifyUpgrade();
|
|
15778
15517
|
const filesWritten = [];
|
|
15779
15518
|
let gpu = { mode: "cpu", libDir: null, ngl: 0, cudaAvailable: "none" };
|
|
15780
15519
|
let backfillPid;
|
|
15520
|
+
let snapshotPath;
|
|
15521
|
+
let integrity;
|
|
15522
|
+
let drainLaunched = false;
|
|
15781
15523
|
try {
|
|
15524
|
+
if (migration.state === "needs-migration") {
|
|
15525
|
+
for (const p of [claudeSettingsPath(), codexHooksPath()]) {
|
|
15526
|
+
const r2 = removeStopHook(p);
|
|
15527
|
+
if (r2.changed)
|
|
15528
|
+
filesWritten.push(p);
|
|
15529
|
+
}
|
|
15530
|
+
say("upgrade: quiesced stale Stop hook before migration");
|
|
15531
|
+
}
|
|
15782
15532
|
for (const d3 of [binDir(), modelsDir(), runDir(), logsDir()])
|
|
15783
|
-
(0,
|
|
15533
|
+
(0, import_node_fs13.mkdirSync)(d3, { recursive: true });
|
|
15784
15534
|
stageBundles(opts.distDir ?? defaultDistDir(), filesWritten);
|
|
15785
15535
|
say(`scaffolded ${recallRoot()}`);
|
|
15786
15536
|
if (opts.offline) {
|
|
15787
|
-
const haveBin = (0,
|
|
15788
|
-
const haveModel = (0,
|
|
15537
|
+
const haveBin = (0, import_node_fs13.existsSync)(getBinaryPath());
|
|
15538
|
+
const haveModel = (0, import_node_fs13.existsSync)(getModelPath());
|
|
15789
15539
|
if (!haveBin || !haveModel) {
|
|
15790
|
-
const msg = `--offline but runtime not pre-staged (binary=${haveBin}, model=${haveModel})
|
|
15540
|
+
const msg = `--offline but runtime not pre-staged (binary=${haveBin}, model=${haveModel}). Pre-stage ~/.recall/bin + model (or drop --offline), then re-run \`recall install\`` + (migration.state === "needs-migration" ? " (which restores the recall Stop hook)." : ".");
|
|
15791
15541
|
log({ source: "installer/install", level: "error", summary: msg });
|
|
15792
|
-
return {
|
|
15542
|
+
return {
|
|
15543
|
+
aborted: true,
|
|
15544
|
+
abortReason: msg,
|
|
15545
|
+
report,
|
|
15546
|
+
selected: [...selected],
|
|
15547
|
+
gpu,
|
|
15548
|
+
filesWritten,
|
|
15549
|
+
migration: { state: migration.state, coverage: migration.coverage, drainLaunched: false }
|
|
15550
|
+
};
|
|
15793
15551
|
}
|
|
15794
15552
|
say("offline: CPU runtime already staged");
|
|
15795
15553
|
} else {
|
|
@@ -15806,11 +15564,75 @@ ${wmsg}` });
|
|
|
15806
15564
|
...opts.offline ? { offline: true } : {}
|
|
15807
15565
|
});
|
|
15808
15566
|
say(gpu.mode === "gpu" ? `GPU acceleration enabled (${gpu.cudaAvailable})` : `using CPU embeddings${gpu.reason ? ` (${gpu.reason})` : ""}`);
|
|
15809
|
-
|
|
15567
|
+
if (migration.state === "needs-migration") {
|
|
15568
|
+
snapshotPath = snapshotDb() ?? void 0;
|
|
15569
|
+
say(snapshotPath ? `pre-upgrade snapshot: ${snapshotPath}` : "pre-upgrade snapshot skipped (no DB / copy failed)");
|
|
15570
|
+
}
|
|
15571
|
+
try {
|
|
15572
|
+
getDb(dbPath());
|
|
15573
|
+
} catch (e2) {
|
|
15574
|
+
const emsg = e2.message;
|
|
15575
|
+
const rerun = migration.state === "needs-migration" ? " Then re-run `recall install` to finish migrating and restore the recall Stop hook." : " Then re-run `recall install`.";
|
|
15576
|
+
let remediation;
|
|
15577
|
+
if (isBindingLoadError(e2)) {
|
|
15578
|
+
remediation = `The native SQLite binding failed to load (${emsg}). Run \`recall install\` (or \`recall doctor\`).`;
|
|
15579
|
+
} else if (/database is locked|SQLITE_BUSY|busy_timeout/i.test(emsg)) {
|
|
15580
|
+
remediation = `A live session is holding the database. Exit all Claude/Codex sessions.${rerun}`;
|
|
15581
|
+
} else if (/expected WAL journal_mode/i.test(emsg)) {
|
|
15582
|
+
remediation = `recall could not enable WAL on this filesystem (e.g. a network / virtual mount). Put ~/.recall on a local disk (or set RECALL_HOME to one).${rerun}`;
|
|
15583
|
+
} else {
|
|
15584
|
+
remediation = `Could not open the database (${emsg}). Run \`recall doctor --integrity\`; if unrecoverable, rebuild from JSONL with \`recall repair --full\`.${rerun}`;
|
|
15585
|
+
}
|
|
15586
|
+
if (interactive)
|
|
15587
|
+
le(remediation, "Migration aborted");
|
|
15588
|
+
else
|
|
15589
|
+
log({ source: "installer/install", level: "error", summary: `migration aborted: ${remediation}` });
|
|
15590
|
+
return {
|
|
15591
|
+
aborted: true,
|
|
15592
|
+
abortReason: remediation,
|
|
15593
|
+
report,
|
|
15594
|
+
selected: [...selected],
|
|
15595
|
+
gpu,
|
|
15596
|
+
filesWritten,
|
|
15597
|
+
migration: {
|
|
15598
|
+
state: migration.state,
|
|
15599
|
+
coverage: migration.coverage,
|
|
15600
|
+
drainLaunched: false,
|
|
15601
|
+
...snapshotPath ? { snapshotPath } : {}
|
|
15602
|
+
}
|
|
15603
|
+
};
|
|
15604
|
+
}
|
|
15810
15605
|
say("database initialized");
|
|
15606
|
+
if (migration.state === "needs-migration") {
|
|
15607
|
+
const res = handleIntegrity();
|
|
15608
|
+
integrity = res.status;
|
|
15609
|
+
if (res.status === "unrecoverable") {
|
|
15610
|
+
const remediation = `Database integrity check failed (${res.detail ?? "unknown"}) and could not be auto-repaired. Your pre-upgrade snapshot is preserved at ${snapshotPath ?? "(snapshot unavailable)"}. Rebuild the index from JSONL with \`recall repair --full\`, then re-run \`recall install\` to restore the recall Stop hook.`;
|
|
15611
|
+
if (interactive)
|
|
15612
|
+
le(remediation, "Migration aborted");
|
|
15613
|
+
else
|
|
15614
|
+
log({ source: "installer/install", level: "error", summary: `migration aborted: ${remediation}` });
|
|
15615
|
+
return {
|
|
15616
|
+
aborted: true,
|
|
15617
|
+
abortReason: remediation,
|
|
15618
|
+
report,
|
|
15619
|
+
selected: [...selected],
|
|
15620
|
+
gpu,
|
|
15621
|
+
filesWritten,
|
|
15622
|
+
migration: {
|
|
15623
|
+
state: migration.state,
|
|
15624
|
+
coverage: migration.coverage,
|
|
15625
|
+
drainLaunched: false,
|
|
15626
|
+
integrity,
|
|
15627
|
+
...snapshotPath ? { snapshotPath } : {}
|
|
15628
|
+
}
|
|
15629
|
+
};
|
|
15630
|
+
}
|
|
15631
|
+
say(res.status === "repaired-stem" ? "upgrade: repaired corrupt _stem index" : "upgrade: integrity check passed");
|
|
15632
|
+
}
|
|
15811
15633
|
const runnable = recallBinCommand();
|
|
15812
15634
|
const templatePath = resolveTemplatePath(opts.templatePath);
|
|
15813
|
-
const hookScript = (0,
|
|
15635
|
+
const hookScript = (0, import_node_path12.join)(binDir(), "stop-hook.js");
|
|
15814
15636
|
if (selected.has("skill")) {
|
|
15815
15637
|
if (writeSkill(claudeRecallSkillPath(), templatePath, runnable))
|
|
15816
15638
|
filesWritten.push(claudeRecallSkillPath());
|
|
@@ -15834,7 +15656,11 @@ ${wmsg}` });
|
|
|
15834
15656
|
if (r2.changed)
|
|
15835
15657
|
filesWritten.push(codexAgentsPath());
|
|
15836
15658
|
}
|
|
15659
|
+
if (filesWritten.length !== new Set(filesWritten).size) {
|
|
15660
|
+
filesWritten.splice(0, filesWritten.length, ...new Set(filesWritten));
|
|
15661
|
+
}
|
|
15837
15662
|
say(`wrote ${filesWritten.length} files`);
|
|
15663
|
+
const coverage = getEmbedVersionStats().coverage;
|
|
15838
15664
|
if (opts.noBackfill) {
|
|
15839
15665
|
say("backfill skipped (--no-backfill)");
|
|
15840
15666
|
} else if (opts.autoBackfill) {
|
|
@@ -15845,56 +15671,84 @@ ${wmsg}` });
|
|
|
15845
15671
|
await startRecallCatchup2({ autoEmbed: true });
|
|
15846
15672
|
await mtimeScan2();
|
|
15847
15673
|
sp?.stop("Backfill complete");
|
|
15674
|
+
drainLaunched = true;
|
|
15675
|
+
} else if (backfillAlreadyRunning()) {
|
|
15676
|
+
say("backfill already running in background \u2014 not relaunching");
|
|
15677
|
+
} else if (migration.state === "already-migrated" && coverage >= 1 && getEmbeddingGapStats().gapCount === 0) {
|
|
15678
|
+
say("already migrated (all vectors current) \u2014 no background re-embed needed");
|
|
15848
15679
|
} else {
|
|
15849
15680
|
backfillPid = spawnDetachedBackfill();
|
|
15681
|
+
drainLaunched = backfillPid !== void 0;
|
|
15850
15682
|
say(backfillPid ? `backfill running in background (PID ${backfillPid})` : "backfill could not be launched");
|
|
15851
15683
|
}
|
|
15852
15684
|
} finally {
|
|
15853
15685
|
releaseInstallLock();
|
|
15854
15686
|
}
|
|
15687
|
+
const finalCoverage = getEmbedVersionStats().coverage;
|
|
15688
|
+
const migrationInfo = {
|
|
15689
|
+
state: migration.state,
|
|
15690
|
+
coverage: finalCoverage,
|
|
15691
|
+
drainLaunched,
|
|
15692
|
+
...snapshotPath ? { snapshotPath } : {},
|
|
15693
|
+
...integrity ? { integrity } : {}
|
|
15694
|
+
};
|
|
15695
|
+
const migLine = migrationReportLine(finalCoverage);
|
|
15855
15696
|
if (interactive) {
|
|
15856
15697
|
const lines = [
|
|
15857
15698
|
gpu.mode === "gpu" ? "GPU acceleration: enabled" : `Embeddings: CPU${gpu.reason ? ` (${gpu.reason})` : ""}`,
|
|
15858
15699
|
`Files written/edited: ${filesWritten.length}`,
|
|
15859
15700
|
backfillPid ? `Backfill running in background (PID ${backfillPid}) \u2014 check with \`recall status\`.` : "Backfill: see above",
|
|
15701
|
+
...migLine ? [migLine] : [],
|
|
15860
15702
|
'Try it \u2014 ask Claude: "what did I work on yesterday?"',
|
|
15861
15703
|
"Commands: recall doctor \xB7 recall status \xB7 recall uninstall"
|
|
15862
15704
|
];
|
|
15863
15705
|
$e(lines.join("\n"));
|
|
15706
|
+
} else if (migLine) {
|
|
15707
|
+
log({ source: "installer/install", level: "info", summary: migLine });
|
|
15864
15708
|
}
|
|
15865
|
-
return {
|
|
15709
|
+
return {
|
|
15710
|
+
report,
|
|
15711
|
+
selected: [...selected],
|
|
15712
|
+
gpu,
|
|
15713
|
+
filesWritten,
|
|
15714
|
+
migration: migrationInfo,
|
|
15715
|
+
...backfillPid ? { backfillPid } : {}
|
|
15716
|
+
};
|
|
15866
15717
|
}
|
|
15867
15718
|
function spawnDetachedBackfill() {
|
|
15868
|
-
(0,
|
|
15869
|
-
(0,
|
|
15870
|
-
const recallBundle = (0,
|
|
15871
|
-
const logFd = (0,
|
|
15872
|
-
const child = (0,
|
|
15719
|
+
(0, import_node_fs13.mkdirSync)(runDir(), { recursive: true });
|
|
15720
|
+
(0, import_node_fs13.mkdirSync)(logsDir(), { recursive: true });
|
|
15721
|
+
const recallBundle = (0, import_node_path12.join)(binDir(), "recall.js");
|
|
15722
|
+
const logFd = (0, import_node_fs13.openSync)((0, import_node_path12.join)(logsDir(), "backfill.log"), "a");
|
|
15723
|
+
const child = (0, import_node_child_process4.spawn)(process.execPath, [recallBundle, "backfill", "--auto-embed"], {
|
|
15873
15724
|
detached: true,
|
|
15874
15725
|
stdio: ["ignore", logFd, logFd],
|
|
15875
15726
|
windowsHide: true,
|
|
15876
15727
|
env: { ...process.env }
|
|
15877
15728
|
});
|
|
15878
15729
|
if (child.pid !== void 0) {
|
|
15879
|
-
(0,
|
|
15730
|
+
(0, import_node_fs13.writeFileSync)((0, import_node_path12.join)(runDir(), "backfill.pid"), String(child.pid));
|
|
15880
15731
|
}
|
|
15881
15732
|
child.unref();
|
|
15882
15733
|
return child.pid;
|
|
15883
15734
|
}
|
|
15884
|
-
var
|
|
15735
|
+
var import_node_fs13, import_node_child_process4, import_node_module2, import_node_path12, STAGED_BUNDLES;
|
|
15885
15736
|
var init_install = __esm({
|
|
15886
15737
|
"src/installer/install.ts"() {
|
|
15887
15738
|
"use strict";
|
|
15888
15739
|
init_dist2();
|
|
15889
|
-
|
|
15890
|
-
|
|
15891
|
-
|
|
15740
|
+
import_node_fs13 = require("node:fs");
|
|
15741
|
+
import_node_child_process4 = require("node:child_process");
|
|
15742
|
+
import_node_module2 = require("node:module");
|
|
15743
|
+
import_node_path12 = require("node:path");
|
|
15892
15744
|
init_paths();
|
|
15893
15745
|
init_db();
|
|
15746
|
+
init_message_store();
|
|
15894
15747
|
init_preflight();
|
|
15895
15748
|
init_manifest();
|
|
15896
15749
|
init_gpu();
|
|
15897
15750
|
init_settings_merge();
|
|
15751
|
+
init_upgrade_migrate();
|
|
15898
15752
|
init_claudemd_nudge();
|
|
15899
15753
|
init_embedder();
|
|
15900
15754
|
init_log();
|
|
@@ -15910,9 +15764,9 @@ __export(uninstall_exports, {
|
|
|
15910
15764
|
function runUninstall(opts = {}) {
|
|
15911
15765
|
const removed = [];
|
|
15912
15766
|
for (const skillFile of [claudeRecallSkillPath(), codexRecallSkillPath()]) {
|
|
15913
|
-
const dir = (0,
|
|
15914
|
-
if ((0,
|
|
15915
|
-
(0,
|
|
15767
|
+
const dir = (0, import_node_path13.dirname)(skillFile);
|
|
15768
|
+
if ((0, import_node_fs14.existsSync)(dir)) {
|
|
15769
|
+
(0, import_node_fs14.rmSync)(dir, { recursive: true, force: true });
|
|
15916
15770
|
removed.push(dir);
|
|
15917
15771
|
}
|
|
15918
15772
|
}
|
|
@@ -15927,8 +15781,8 @@ function runUninstall(opts = {}) {
|
|
|
15927
15781
|
let purged = false;
|
|
15928
15782
|
if (opts.purge) {
|
|
15929
15783
|
closeDb();
|
|
15930
|
-
if ((0,
|
|
15931
|
-
(0,
|
|
15784
|
+
if ((0, import_node_fs14.existsSync)(recallRoot())) {
|
|
15785
|
+
(0, import_node_fs14.rmSync)(recallRoot(), { recursive: true, force: true });
|
|
15932
15786
|
removed.push(recallRoot());
|
|
15933
15787
|
}
|
|
15934
15788
|
purged = true;
|
|
@@ -15936,12 +15790,12 @@ function runUninstall(opts = {}) {
|
|
|
15936
15790
|
log({ source: "installer/uninstall", level: "info", summary: `uninstall removed ${removed.length} targets (purge=${purged})` });
|
|
15937
15791
|
return { removed, purged };
|
|
15938
15792
|
}
|
|
15939
|
-
var
|
|
15793
|
+
var import_node_fs14, import_node_path13;
|
|
15940
15794
|
var init_uninstall = __esm({
|
|
15941
15795
|
"src/installer/uninstall.ts"() {
|
|
15942
15796
|
"use strict";
|
|
15943
|
-
|
|
15944
|
-
|
|
15797
|
+
import_node_fs14 = require("node:fs");
|
|
15798
|
+
import_node_path13 = require("node:path");
|
|
15945
15799
|
init_settings_merge();
|
|
15946
15800
|
init_claudemd_nudge();
|
|
15947
15801
|
init_preflight();
|
|
@@ -15962,13 +15816,14 @@ function getStatus() {
|
|
|
15962
15816
|
const messageCount = d3.get("SELECT COUNT(*) AS c FROM messages").c;
|
|
15963
15817
|
const lastRow = d3.get("SELECT MAX(created_at) AS m FROM messages");
|
|
15964
15818
|
const lastIngest = lastRow.m ? new Date(lastRow.m).toISOString() : null;
|
|
15965
|
-
const dbSizeBytes = (0,
|
|
15819
|
+
const dbSizeBytes = (0, import_node_fs15.existsSync)(dbPath()) ? (0, import_node_fs15.statSync)(dbPath()).size : 0;
|
|
15966
15820
|
const embeddingGap = getEmbeddingGapStats();
|
|
15821
|
+
const embedVersions = getEmbedVersionStats();
|
|
15967
15822
|
let backfillPid = null;
|
|
15968
15823
|
let backfillRunning = false;
|
|
15969
|
-
const pidFile = (0,
|
|
15970
|
-
if ((0,
|
|
15971
|
-
const pid = parseInt((0,
|
|
15824
|
+
const pidFile = (0, import_node_path14.join)(runDir(), "backfill.pid");
|
|
15825
|
+
if ((0, import_node_fs15.existsSync)(pidFile)) {
|
|
15826
|
+
const pid = parseInt((0, import_node_fs15.readFileSync)(pidFile, "utf-8").trim(), 10);
|
|
15972
15827
|
if (!Number.isNaN(pid)) {
|
|
15973
15828
|
backfillPid = pid;
|
|
15974
15829
|
try {
|
|
@@ -15985,6 +15840,7 @@ function getStatus() {
|
|
|
15985
15840
|
messageCount,
|
|
15986
15841
|
lastIngest,
|
|
15987
15842
|
embeddingGap,
|
|
15843
|
+
embedVersions,
|
|
15988
15844
|
backfillPid,
|
|
15989
15845
|
backfillRunning,
|
|
15990
15846
|
embedder: readEmbedderConfig().mode
|
|
@@ -16003,18 +15859,23 @@ function printStatus(json) {
|
|
|
16003
15859
|
console.log(`Messages: ${s.messageCount}`);
|
|
16004
15860
|
console.log(`Last ingest: ${s.lastIngest ?? "never"}`);
|
|
16005
15861
|
console.log(`Embedding gap: ${s.embeddingGap.gapCount} of ${s.embeddingGap.totalMessages} unembedded`);
|
|
15862
|
+
if (s.embedVersions.coverage < 1) {
|
|
15863
|
+
const pct = Math.round(s.embedVersions.coverage * 100);
|
|
15864
|
+
console.log(`Embed migration: ${s.embedVersions.current} of ${s.embedVersions.total} at v${EMBED_VERSION} (${pct}%)`);
|
|
15865
|
+
}
|
|
16006
15866
|
console.log(`Embedder: ${s.embedder.toUpperCase()}`);
|
|
16007
15867
|
console.log(`Backfill: ${s.backfillPid === null ? "none recorded" : `PID ${s.backfillPid} (${s.backfillRunning ? "running" : "finished"})`}`);
|
|
16008
15868
|
}
|
|
16009
|
-
var
|
|
15869
|
+
var import_node_fs15, import_node_path14;
|
|
16010
15870
|
var init_status = __esm({
|
|
16011
15871
|
"src/installer/status.ts"() {
|
|
16012
15872
|
"use strict";
|
|
16013
|
-
|
|
16014
|
-
|
|
15873
|
+
import_node_fs15 = require("node:fs");
|
|
15874
|
+
import_node_path14 = require("node:path");
|
|
16015
15875
|
init_db();
|
|
16016
15876
|
init_paths();
|
|
16017
15877
|
init_message_store();
|
|
15878
|
+
init_embed_config();
|
|
16018
15879
|
init_config();
|
|
16019
15880
|
}
|
|
16020
15881
|
});
|
|
@@ -16068,7 +15929,7 @@ async function repairFull(opts = {}) {
|
|
|
16068
15929
|
}
|
|
16069
15930
|
}
|
|
16070
15931
|
const d3 = db3();
|
|
16071
|
-
d3.exec("BEGIN");
|
|
15932
|
+
d3.exec("BEGIN IMMEDIATE");
|
|
16072
15933
|
try {
|
|
16073
15934
|
d3.exec("DELETE FROM messages;");
|
|
16074
15935
|
d3.exec("DELETE FROM ingest_watermark;");
|
|
@@ -16107,12 +15968,125 @@ async function runDoctor(opts = {}) {
|
|
|
16107
15968
|
return printIntegrity(opts.json ?? false);
|
|
16108
15969
|
const report = await runPreflight({ ...opts.offline ? { offline: true } : {} });
|
|
16109
15970
|
const embedder = readConfig()?.embedder ?? null;
|
|
15971
|
+
const binding = checkBindingHealth();
|
|
16110
15972
|
if (opts.json) {
|
|
16111
|
-
console.log(JSON.stringify({ ...report, embedder }, null, 2));
|
|
15973
|
+
console.log(JSON.stringify({ ...report, embedder, binding }, null, 2));
|
|
16112
15974
|
} else {
|
|
16113
15975
|
printTable(report, embedder?.mode ?? "cpu", embedder?.fallbackReason);
|
|
15976
|
+
printBinding(binding);
|
|
15977
|
+
}
|
|
15978
|
+
const bindingFailed = binding.installed && binding.problems.length > 0;
|
|
15979
|
+
return report.failures.length > 0 || bindingFailed ? 1 : 0;
|
|
15980
|
+
}
|
|
15981
|
+
function stagedBindingPath() {
|
|
15982
|
+
return (0, import_node_path15.join)(binDir(), "better_sqlite3.node");
|
|
15983
|
+
}
|
|
15984
|
+
function checkBindingHealth() {
|
|
15985
|
+
const problems = [];
|
|
15986
|
+
const installed = (0, import_node_fs16.existsSync)((0, import_node_path15.join)(binDir(), "recall.js"));
|
|
15987
|
+
if (!installed) {
|
|
15988
|
+
return {
|
|
15989
|
+
installed: false,
|
|
15990
|
+
markerPresent: false,
|
|
15991
|
+
abiOk: null,
|
|
15992
|
+
pinnedNodeOk: null,
|
|
15993
|
+
bindingLoads: false,
|
|
15994
|
+
journalMode: null,
|
|
15995
|
+
embedCoverage: null,
|
|
15996
|
+
problems: ["recall is not installed \u2014 run `recall install`"]
|
|
15997
|
+
};
|
|
15998
|
+
}
|
|
15999
|
+
const markerPath = (0, import_node_path15.join)(binDir(), ".binding-info.json");
|
|
16000
|
+
const markerPresent = (0, import_node_fs16.existsSync)(markerPath);
|
|
16001
|
+
let abiOk = null;
|
|
16002
|
+
let pinnedNodeOk = null;
|
|
16003
|
+
if (!markerPresent) {
|
|
16004
|
+
problems.push("no .binding-info.json marker \u2014 pre-migration (wasm-era) install; run `recall install`");
|
|
16005
|
+
} else {
|
|
16006
|
+
try {
|
|
16007
|
+
const marker = JSON.parse((0, import_node_fs16.readFileSync)(markerPath, "utf-8"));
|
|
16008
|
+
abiOk = String(marker.nodeModuleVersion) === String(process.versions.modules);
|
|
16009
|
+
if (!abiOk) {
|
|
16010
|
+
problems.push(
|
|
16011
|
+
`binding ABI mismatch (staged for NODE_MODULE_VERSION ${marker.nodeModuleVersion}, current ${process.versions.modules}) \u2014 run \`recall install\``
|
|
16012
|
+
);
|
|
16013
|
+
}
|
|
16014
|
+
pinnedNodeOk = !!marker.nodePath && (0, import_node_fs16.existsSync)(marker.nodePath);
|
|
16015
|
+
if (!pinnedNodeOk) {
|
|
16016
|
+
problems.push(`pinned Node path missing (${marker.nodePath ?? "unset"}) \u2014 run \`recall install\``);
|
|
16017
|
+
}
|
|
16018
|
+
} catch {
|
|
16019
|
+
problems.push("unreadable .binding-info.json marker \u2014 run `recall install`");
|
|
16020
|
+
}
|
|
16021
|
+
}
|
|
16022
|
+
let bindingLoads = false;
|
|
16023
|
+
let journalMode = null;
|
|
16024
|
+
let embedCoverage = null;
|
|
16025
|
+
const localBinding = stagedBindingPath();
|
|
16026
|
+
const dbFile = dbPath();
|
|
16027
|
+
if ((0, import_node_fs16.existsSync)(dbFile)) {
|
|
16028
|
+
try {
|
|
16029
|
+
const raw2 = (0, import_node_fs16.existsSync)(localBinding) ? new import_better_sqlite33.default(dbFile, { readonly: true, fileMustExist: true, nativeBinding: localBinding }) : new import_better_sqlite33.default(dbFile, { readonly: true, fileMustExist: true });
|
|
16030
|
+
bindingLoads = true;
|
|
16031
|
+
journalMode = String(raw2.pragma("journal_mode", { simple: true }));
|
|
16032
|
+
try {
|
|
16033
|
+
const row = raw2.prepare(
|
|
16034
|
+
`SELECT COUNT(*) AS total,
|
|
16035
|
+
COALESCE(SUM(CASE WHEN embed_version = ? THEN 1 ELSE 0 END), 0) AS current
|
|
16036
|
+
FROM message_vectors`
|
|
16037
|
+
).get(EMBED_VERSION);
|
|
16038
|
+
const total = row ? Number(row.total) : 0;
|
|
16039
|
+
const current = row ? Number(row.current ?? 0) : 0;
|
|
16040
|
+
embedCoverage = total === 0 ? null : current / total;
|
|
16041
|
+
} catch {
|
|
16042
|
+
embedCoverage = null;
|
|
16043
|
+
}
|
|
16044
|
+
raw2.close();
|
|
16045
|
+
if (journalMode !== "wal") {
|
|
16046
|
+
problems.push(
|
|
16047
|
+
`live DB journal_mode is '${journalMode}', not 'wal' \u2014 a native build on a non-WAL DB is drift (the WAL conversion is a separate attended step; do not restage over a delete-mode DB blindly)`
|
|
16048
|
+
);
|
|
16049
|
+
}
|
|
16050
|
+
} catch (e2) {
|
|
16051
|
+
if (isBindingLoadError(e2)) {
|
|
16052
|
+
problems.push("better_sqlite3.node failed to load (ABI/dlopen) \u2014 run `recall install`");
|
|
16053
|
+
} else {
|
|
16054
|
+
problems.push(`could not read live DB journal_mode: ${e2.message}`);
|
|
16055
|
+
}
|
|
16056
|
+
}
|
|
16057
|
+
} else {
|
|
16058
|
+
try {
|
|
16059
|
+
const raw2 = (0, import_node_fs16.existsSync)(localBinding) ? new import_better_sqlite33.default(":memory:", { nativeBinding: localBinding }) : new import_better_sqlite33.default(":memory:");
|
|
16060
|
+
bindingLoads = true;
|
|
16061
|
+
raw2.close();
|
|
16062
|
+
} catch (e2) {
|
|
16063
|
+
problems.push(
|
|
16064
|
+
isBindingLoadError(e2) ? "better_sqlite3.node failed to load (ABI/dlopen) \u2014 run `recall install`" : `binding self-test failed: ${e2.message}`
|
|
16065
|
+
);
|
|
16066
|
+
}
|
|
16067
|
+
}
|
|
16068
|
+
return { installed, markerPresent, abiOk, pinnedNodeOk, bindingLoads, journalMode, embedCoverage, problems };
|
|
16069
|
+
}
|
|
16070
|
+
function printBinding(b3) {
|
|
16071
|
+
const ok = (v2) => v2 ? "OK" : "FAIL";
|
|
16072
|
+
console.log("\nSQLite binding (better-sqlite3, native WAL)");
|
|
16073
|
+
console.log("------------------------------------------");
|
|
16074
|
+
if (!b3.installed) {
|
|
16075
|
+
console.log(" not installed \u2014 run `recall install`");
|
|
16076
|
+
return;
|
|
16077
|
+
}
|
|
16078
|
+
console.log(`Binding loads: ${ok(b3.bindingLoads)}`);
|
|
16079
|
+
console.log(`ABI marker: ${b3.markerPresent ? b3.abiOk ? "OK" : "MISMATCH" : "absent (wasm-era)"}`);
|
|
16080
|
+
console.log(`Pinned Node: ${b3.pinnedNodeOk === null ? "n/a" : ok(b3.pinnedNodeOk)}`);
|
|
16081
|
+
console.log(`journal_mode: ${b3.journalMode ?? "no DB yet"}${b3.journalMode && b3.journalMode !== "wal" ? " [DRIFT]" : ""}`);
|
|
16082
|
+
if (b3.embedCoverage !== null && b3.embedCoverage < 1) {
|
|
16083
|
+
console.log(`Embed migration: re-embedding to v${EMBED_VERSION} (${Math.round(b3.embedCoverage * 100)}%) \u2014 semantic search stays available`);
|
|
16084
|
+
}
|
|
16085
|
+
if (b3.problems.length) {
|
|
16086
|
+
console.log(" Issues:");
|
|
16087
|
+
for (const p of b3.problems)
|
|
16088
|
+
console.log(` \u2716 ${p}`);
|
|
16114
16089
|
}
|
|
16115
|
-
return report.failures.length > 0 ? 1 : 0;
|
|
16116
16090
|
}
|
|
16117
16091
|
function printIntegrity(json) {
|
|
16118
16092
|
const r2 = integrityCheck();
|
|
@@ -16156,12 +16130,19 @@ function printTable(report, embedderMode, fallbackReason) {
|
|
|
16156
16130
|
if (!report.warnings.length && !report.failures.length)
|
|
16157
16131
|
console.log("\nAll checks passed.");
|
|
16158
16132
|
}
|
|
16133
|
+
var import_node_fs16, import_node_path15, import_better_sqlite33;
|
|
16159
16134
|
var init_doctor = __esm({
|
|
16160
16135
|
"src/installer/doctor.ts"() {
|
|
16161
16136
|
"use strict";
|
|
16137
|
+
import_node_fs16 = require("node:fs");
|
|
16138
|
+
import_node_path15 = require("node:path");
|
|
16139
|
+
import_better_sqlite33 = __toESM(require_lib());
|
|
16162
16140
|
init_preflight();
|
|
16163
16141
|
init_config();
|
|
16164
16142
|
init_repair();
|
|
16143
|
+
init_db();
|
|
16144
|
+
init_paths();
|
|
16145
|
+
init_embed_config();
|
|
16165
16146
|
}
|
|
16166
16147
|
});
|
|
16167
16148
|
|
|
@@ -16169,23 +16150,31 @@ var init_doctor = __esm({
|
|
|
16169
16150
|
init_embedder();
|
|
16170
16151
|
init_quantize();
|
|
16171
16152
|
init_message_store();
|
|
16153
|
+
init_embed_config();
|
|
16172
16154
|
init_log();
|
|
16173
16155
|
var DEFAULT_LIMIT = 200;
|
|
16174
16156
|
var FETCH_MULTIPLIER = 3;
|
|
16175
16157
|
var RRF_K = 60;
|
|
16176
|
-
var DEFAULT_RECENCY_DECAY = 0.02;
|
|
16177
16158
|
var SEMANTIC_DISCOVERY_BOOST = 1.05;
|
|
16159
|
+
function recencyMultiplier(decay, ageMs) {
|
|
16160
|
+
if (!(decay && decay > 0))
|
|
16161
|
+
return 1;
|
|
16162
|
+
const ageDays = Math.max(0, ageMs) / 864e5;
|
|
16163
|
+
return 1 / (1 + ageDays * decay);
|
|
16164
|
+
}
|
|
16178
16165
|
async function dualPathSearch(query, opts) {
|
|
16179
16166
|
const limit2 = opts?.limit ?? DEFAULT_LIMIT;
|
|
16180
16167
|
const fetchLimit = limit2 * FETCH_MULTIPLIER;
|
|
16181
16168
|
if (!query.trim())
|
|
16182
|
-
return { results: [], scored: [], semanticAvailable: false, ftsCount: 0, semanticCount: 0 };
|
|
16169
|
+
return { results: [], scored: [], semanticAvailable: false, ftsCount: 0, semanticCount: 0, embedCoverage: 1 };
|
|
16170
|
+
const embedCoverage = getEmbedVersionStats().coverage;
|
|
16171
|
+
const tolerant = embedCoverage < 0.95;
|
|
16183
16172
|
let queryQ8 = null;
|
|
16184
16173
|
let queryNorm = 0;
|
|
16185
16174
|
let queryScale = 0;
|
|
16186
16175
|
let semanticAvailable = true;
|
|
16187
16176
|
try {
|
|
16188
|
-
const queryF32 = await embed(query);
|
|
16177
|
+
const queryF32 = await embed(QUERY_PREFIX + query);
|
|
16189
16178
|
queryNorm = computeNorm(queryF32);
|
|
16190
16179
|
const quantized = quantizeToQ8(queryF32);
|
|
16191
16180
|
queryQ8 = quantized.q8;
|
|
@@ -16198,32 +16187,31 @@ async function dualPathSearch(query, opts) {
|
|
|
16198
16187
|
summary: `Semantic path disabled \u2014 embed() failed: ${err instanceof Error ? err.message : String(err)}`
|
|
16199
16188
|
});
|
|
16200
16189
|
}
|
|
16201
|
-
const ftsResults = searchMessagesFts(query, fetchLimit, opts?.projectId, opts?.sessionId, opts?.excludeSessionId);
|
|
16190
|
+
const ftsResults = searchMessagesFts(query, fetchLimit, opts?.projectId, opts?.sessionId, opts?.excludeSessionId, opts?.skipIdf);
|
|
16202
16191
|
const semanticResults = queryQ8 && queryNorm > 0 ? searchMessagesSemantic(queryQ8, queryNorm, queryScale, {
|
|
16203
16192
|
limit: fetchLimit,
|
|
16204
16193
|
projectId: opts?.projectId,
|
|
16205
16194
|
sessionId: opts?.sessionId,
|
|
16206
|
-
excludeSessionId: opts?.excludeSessionId
|
|
16195
|
+
excludeSessionId: opts?.excludeSessionId,
|
|
16196
|
+
tolerant
|
|
16207
16197
|
}) : [];
|
|
16208
16198
|
log({
|
|
16209
16199
|
source: "recall:dual-path",
|
|
16210
16200
|
level: semanticAvailable ? "info" : "warn",
|
|
16211
16201
|
summary: `FTS5: ${ftsResults.length} results, Semantic: ${semanticResults.length} results${!semanticAvailable ? " (UNAVAILABLE \u2014 embed failed)" : ""}`
|
|
16212
16202
|
});
|
|
16213
|
-
const decay = opts?.recencyDecay
|
|
16203
|
+
const decay = opts?.recencyDecay;
|
|
16214
16204
|
const now = Date.now();
|
|
16215
16205
|
const rrfScores = /* @__PURE__ */ new Map();
|
|
16216
16206
|
for (let i = 0; i < ftsResults.length; i++) {
|
|
16217
16207
|
const r2 = ftsResults[i];
|
|
16218
|
-
const
|
|
16219
|
-
const recency = 1 / (1 + ageDays * decay);
|
|
16208
|
+
const recency = recencyMultiplier(decay, now - r2.created_at);
|
|
16220
16209
|
rrfScores.set(r2.message_id, { result: r2, score: 1 / (RRF_K + i) * recency, paths: ["fts5"] });
|
|
16221
16210
|
}
|
|
16222
16211
|
const ftsSessionIdSet = new Set(ftsResults.map((r2) => r2.session_id));
|
|
16223
16212
|
for (let i = 0; i < semanticResults.length; i++) {
|
|
16224
16213
|
const r2 = semanticResults[i];
|
|
16225
|
-
const
|
|
16226
|
-
const recency = 1 / (1 + ageDays * decay);
|
|
16214
|
+
const recency = recencyMultiplier(decay, now - r2.created_at);
|
|
16227
16215
|
const rrfScore = 1 / (RRF_K + i) * recency;
|
|
16228
16216
|
const existing = rrfScores.get(r2.message_id);
|
|
16229
16217
|
if (existing) {
|
|
@@ -16246,7 +16234,8 @@ async function dualPathSearch(query, opts) {
|
|
|
16246
16234
|
// full list with RRF scores — groupBySession uses for gap detection
|
|
16247
16235
|
semanticAvailable,
|
|
16248
16236
|
ftsCount: ftsResults.length,
|
|
16249
|
-
semanticCount: semanticResults.length
|
|
16237
|
+
semanticCount: semanticResults.length,
|
|
16238
|
+
embedCoverage
|
|
16250
16239
|
};
|
|
16251
16240
|
}
|
|
16252
16241
|
|
|
@@ -16307,9 +16296,451 @@ init_url_path_resolver();
|
|
|
16307
16296
|
init_mtime_scan();
|
|
16308
16297
|
init_catchup();
|
|
16309
16298
|
init_paths();
|
|
16310
|
-
|
|
16311
|
-
|
|
16312
|
-
var
|
|
16299
|
+
|
|
16300
|
+
// src/git-attribution.ts
|
|
16301
|
+
var fs4 = __toESM(require("node:fs"));
|
|
16302
|
+
var path3 = __toESM(require("node:path"));
|
|
16303
|
+
var os2 = __toESM(require("node:os"));
|
|
16304
|
+
var import_node_child_process2 = require("node:child_process");
|
|
16305
|
+
|
|
16306
|
+
// src/adapters/claude/transcript-edits.ts
|
|
16307
|
+
var fs3 = __toESM(require("node:fs"));
|
|
16308
|
+
var readline = __toESM(require("node:readline"));
|
|
16309
|
+
async function extractSessionEdits(filePath, opts = {}) {
|
|
16310
|
+
const sessionId = sessionIdFromPath3(filePath);
|
|
16311
|
+
const edits = [];
|
|
16312
|
+
let firstTs = Infinity;
|
|
16313
|
+
let lastTs = -Infinity;
|
|
16314
|
+
let skippedLines = 0;
|
|
16315
|
+
let skippedEvents = 0;
|
|
16316
|
+
const stream2 = fs3.createReadStream(filePath, { encoding: "utf8" });
|
|
16317
|
+
const rl = readline.createInterface({ input: stream2, crlfDelay: Infinity });
|
|
16318
|
+
const pushEdit = (fp, cnt, ts) => {
|
|
16319
|
+
if (typeof fp !== "string" || typeof cnt !== "string")
|
|
16320
|
+
return;
|
|
16321
|
+
edits.push({ file: normalizePath2(fp, opts.repoRoot), content: cnt, ts });
|
|
16322
|
+
if (ts < firstTs)
|
|
16323
|
+
firstTs = ts;
|
|
16324
|
+
if (ts > lastTs)
|
|
16325
|
+
lastTs = ts;
|
|
16326
|
+
};
|
|
16327
|
+
for await (const line of rl) {
|
|
16328
|
+
if (!line.trim())
|
|
16329
|
+
continue;
|
|
16330
|
+
let evt;
|
|
16331
|
+
try {
|
|
16332
|
+
evt = JSON.parse(line);
|
|
16333
|
+
} catch {
|
|
16334
|
+
skippedLines++;
|
|
16335
|
+
continue;
|
|
16336
|
+
}
|
|
16337
|
+
if (!isAssistantEvent(evt))
|
|
16338
|
+
continue;
|
|
16339
|
+
const ts = parseTimestamp(evt);
|
|
16340
|
+
if (!Number.isFinite(ts)) {
|
|
16341
|
+
skippedEvents++;
|
|
16342
|
+
continue;
|
|
16343
|
+
}
|
|
16344
|
+
for (const block of evt.message.content) {
|
|
16345
|
+
if (!isToolUseBlock(block))
|
|
16346
|
+
continue;
|
|
16347
|
+
const input = block.input;
|
|
16348
|
+
if (block.name === "Edit") {
|
|
16349
|
+
pushEdit(input.file_path, input.new_string, ts);
|
|
16350
|
+
} else if (block.name === "Write") {
|
|
16351
|
+
pushEdit(input.file_path, input.content, ts);
|
|
16352
|
+
} else if (block.name === "MultiEdit") {
|
|
16353
|
+
const fp = input.file_path;
|
|
16354
|
+
const edArr = input.edits;
|
|
16355
|
+
if (Array.isArray(edArr)) {
|
|
16356
|
+
for (const e2 of edArr) {
|
|
16357
|
+
if (e2 && typeof e2 === "object") {
|
|
16358
|
+
pushEdit(fp, e2.new_string, ts);
|
|
16359
|
+
}
|
|
16360
|
+
}
|
|
16361
|
+
}
|
|
16362
|
+
}
|
|
16363
|
+
}
|
|
16364
|
+
}
|
|
16365
|
+
return { sessionId, edits, firstTs, lastTs, skippedLines, skippedEvents };
|
|
16366
|
+
}
|
|
16367
|
+
function sessionIdFromPath3(filePath) {
|
|
16368
|
+
const base = filePath.replace(/^.*[\\/]/, "");
|
|
16369
|
+
return base.endsWith(".jsonl") ? base.slice(0, -".jsonl".length) : base;
|
|
16370
|
+
}
|
|
16371
|
+
function isAssistantEvent(evt) {
|
|
16372
|
+
if (!evt || typeof evt !== "object")
|
|
16373
|
+
return false;
|
|
16374
|
+
const e2 = evt;
|
|
16375
|
+
if (e2.type !== "assistant")
|
|
16376
|
+
return false;
|
|
16377
|
+
const m2 = e2.message;
|
|
16378
|
+
return !!m2 && Array.isArray(m2.content);
|
|
16379
|
+
}
|
|
16380
|
+
function isToolUseBlock(block) {
|
|
16381
|
+
if (!block || typeof block !== "object")
|
|
16382
|
+
return false;
|
|
16383
|
+
const b3 = block;
|
|
16384
|
+
if (b3.type !== "tool_use")
|
|
16385
|
+
return false;
|
|
16386
|
+
if (typeof b3.name !== "string")
|
|
16387
|
+
return false;
|
|
16388
|
+
if (b3.input && typeof b3.input !== "object")
|
|
16389
|
+
return false;
|
|
16390
|
+
return true;
|
|
16391
|
+
}
|
|
16392
|
+
function parseTimestamp(evt) {
|
|
16393
|
+
if (typeof evt.timestamp !== "string")
|
|
16394
|
+
return NaN;
|
|
16395
|
+
return new Date(evt.timestamp).getTime();
|
|
16396
|
+
}
|
|
16397
|
+
function normalizePath2(p, repoRoot) {
|
|
16398
|
+
if (!repoRoot)
|
|
16399
|
+
return p;
|
|
16400
|
+
const prefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
|
|
16401
|
+
if (p.startsWith(prefix))
|
|
16402
|
+
return p.slice(prefix.length);
|
|
16403
|
+
if (p === repoRoot)
|
|
16404
|
+
return "";
|
|
16405
|
+
return p;
|
|
16406
|
+
}
|
|
16407
|
+
|
|
16408
|
+
// src/git-attribution.ts
|
|
16409
|
+
init_log();
|
|
16410
|
+
function parseBlameSpec(s) {
|
|
16411
|
+
const lastColon = s.lastIndexOf(":");
|
|
16412
|
+
if (lastColon < 0)
|
|
16413
|
+
return { path: s };
|
|
16414
|
+
const tail = s.slice(lastColon + 1);
|
|
16415
|
+
const m2 = tail.match(/^(\d+)(?:-(\d+))?$/);
|
|
16416
|
+
if (!m2)
|
|
16417
|
+
return { path: s };
|
|
16418
|
+
const lineStart = parseInt(m2[1], 10);
|
|
16419
|
+
const lineEnd = m2[2] !== void 0 ? parseInt(m2[2], 10) : lineStart;
|
|
16420
|
+
return { path: s.slice(0, lastColon), lineStart, lineEnd };
|
|
16421
|
+
}
|
|
16422
|
+
async function findSessionsForCommit(commitHash, opts) {
|
|
16423
|
+
const info = getCommitInfo(opts.repoRoot, commitHash);
|
|
16424
|
+
return matchCommit(info, opts, /* @__PURE__ */ new Map());
|
|
16425
|
+
}
|
|
16426
|
+
async function findSessionsForBlame(specs, opts) {
|
|
16427
|
+
if (specs.length === 0)
|
|
16428
|
+
return [];
|
|
16429
|
+
const commitSet = /* @__PURE__ */ new Set();
|
|
16430
|
+
for (const spec of specs) {
|
|
16431
|
+
for (const h2 of blameCommits(opts.repoRoot, spec)) {
|
|
16432
|
+
commitSet.add(h2);
|
|
16433
|
+
}
|
|
16434
|
+
}
|
|
16435
|
+
const commitFileTriCache = /* @__PURE__ */ new Map();
|
|
16436
|
+
const all = [];
|
|
16437
|
+
for (const h2 of commitSet) {
|
|
16438
|
+
let info;
|
|
16439
|
+
try {
|
|
16440
|
+
info = getCommitInfo(opts.repoRoot, h2);
|
|
16441
|
+
} catch (err) {
|
|
16442
|
+
log({
|
|
16443
|
+
source: "git-attribution",
|
|
16444
|
+
level: "warn",
|
|
16445
|
+
summary: `failed to read commit ${h2}`,
|
|
16446
|
+
data: { error: String(err) }
|
|
16447
|
+
});
|
|
16448
|
+
continue;
|
|
16449
|
+
}
|
|
16450
|
+
const ms = await matchCommit(info, opts, commitFileTriCache);
|
|
16451
|
+
for (const m2 of ms)
|
|
16452
|
+
all.push(m2);
|
|
16453
|
+
}
|
|
16454
|
+
all.sort((a3, b3) => Date.parse(a3.last_edit_at) - Date.parse(b3.last_edit_at));
|
|
16455
|
+
if (opts.limit && opts.limit > 0 && all.length > opts.limit) {
|
|
16456
|
+
return all.slice(-opts.limit);
|
|
16457
|
+
}
|
|
16458
|
+
return all;
|
|
16459
|
+
}
|
|
16460
|
+
function getCommitInfo(repoRoot, hash) {
|
|
16461
|
+
const meta = git(repoRoot, ["show", "--pretty=format:%H%n%aI", "--name-only", hash]).trim().split("\n");
|
|
16462
|
+
const fullHash = meta[0] ?? hash;
|
|
16463
|
+
const commitTime = meta[1] ? Date.parse(meta[1]) : 0;
|
|
16464
|
+
const files = meta.slice(2).filter((f3) => f3.length > 0);
|
|
16465
|
+
const parentRaw = gitSafe(repoRoot, ["log", "-1", "--pretty=format:%aI", `${hash}^`]);
|
|
16466
|
+
const parentTime = parentRaw ? Date.parse(parentRaw.trim()) : 0;
|
|
16467
|
+
const diff = git(repoRoot, ["show", "-U0", hash]);
|
|
16468
|
+
const added = /* @__PURE__ */ new Map();
|
|
16469
|
+
const removed = /* @__PURE__ */ new Map();
|
|
16470
|
+
let curFile = null;
|
|
16471
|
+
for (const line of diff.split("\n")) {
|
|
16472
|
+
if (line.startsWith("diff --git")) {
|
|
16473
|
+
curFile = null;
|
|
16474
|
+
continue;
|
|
16475
|
+
}
|
|
16476
|
+
if (line.startsWith("+++ b/")) {
|
|
16477
|
+
curFile = line.slice(6);
|
|
16478
|
+
if (!added.has(curFile))
|
|
16479
|
+
added.set(curFile, []);
|
|
16480
|
+
if (!removed.has(curFile))
|
|
16481
|
+
removed.set(curFile, []);
|
|
16482
|
+
continue;
|
|
16483
|
+
}
|
|
16484
|
+
if (line.startsWith("--- ") || line.startsWith("+++ "))
|
|
16485
|
+
continue;
|
|
16486
|
+
if (line.startsWith("@@"))
|
|
16487
|
+
continue;
|
|
16488
|
+
if (!curFile)
|
|
16489
|
+
continue;
|
|
16490
|
+
if (line.startsWith("+"))
|
|
16491
|
+
added.get(curFile).push(line.slice(1));
|
|
16492
|
+
else if (line.startsWith("-"))
|
|
16493
|
+
removed.get(curFile).push(line.slice(1));
|
|
16494
|
+
}
|
|
16495
|
+
return { hash: fullHash, commitTime, parentTime, files, addedLines: added, removedLines: removed };
|
|
16496
|
+
}
|
|
16497
|
+
function cwdToProjectSlug(cwd) {
|
|
16498
|
+
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
16499
|
+
}
|
|
16500
|
+
function cwdToProjectSlugNarrow(cwd) {
|
|
16501
|
+
return cwd.replace(/[:\/\\]/g, "-");
|
|
16502
|
+
}
|
|
16503
|
+
function defaultSessionsDir(repoRoot) {
|
|
16504
|
+
const claudeRoot = process.env["CLAUDE_CONFIG_DIR"] ?? path3.join(os2.homedir(), ".claude");
|
|
16505
|
+
const broad = path3.join(claudeRoot, "projects", cwdToProjectSlug(repoRoot));
|
|
16506
|
+
if (fs4.existsSync(broad))
|
|
16507
|
+
return broad;
|
|
16508
|
+
const narrow = path3.join(claudeRoot, "projects", cwdToProjectSlugNarrow(repoRoot));
|
|
16509
|
+
if (fs4.existsSync(narrow))
|
|
16510
|
+
return narrow;
|
|
16511
|
+
return broad;
|
|
16512
|
+
}
|
|
16513
|
+
async function matchCommit(info, opts, commitFileTriCache) {
|
|
16514
|
+
const commitFiles = new Set(info.files);
|
|
16515
|
+
const windowAfterMs = opts.windowAfterMs ?? 60 * 60 * 1e3;
|
|
16516
|
+
const lower = info.parentTime;
|
|
16517
|
+
const upper = info.commitTime + windowAfterMs;
|
|
16518
|
+
const sessionsDir = opts.sessionsDir ?? defaultSessionsDir(opts.repoRoot);
|
|
16519
|
+
if (!fs4.existsSync(sessionsDir)) {
|
|
16520
|
+
log({
|
|
16521
|
+
source: "git-attribution",
|
|
16522
|
+
level: "warn",
|
|
16523
|
+
summary: `sessions dir not found: ${sessionsDir}`
|
|
16524
|
+
});
|
|
16525
|
+
return [];
|
|
16526
|
+
}
|
|
16527
|
+
const candidates = collectCandidates(sessionsDir, lower, info.commitTime);
|
|
16528
|
+
const addedTriByFile = /* @__PURE__ */ new Map();
|
|
16529
|
+
for (const [file, lines] of info.addedLines) {
|
|
16530
|
+
addedTriByFile.set(file, triGrams(lines));
|
|
16531
|
+
}
|
|
16532
|
+
const matches = [];
|
|
16533
|
+
for (const cand of candidates) {
|
|
16534
|
+
let trace;
|
|
16535
|
+
try {
|
|
16536
|
+
trace = await extractSessionEdits(cand.jsonlPath, { repoRoot: opts.repoRoot });
|
|
16537
|
+
} catch (err) {
|
|
16538
|
+
log({
|
|
16539
|
+
source: "git-attribution",
|
|
16540
|
+
level: "debug",
|
|
16541
|
+
summary: `extractSessionEdits failed for ${cand.jsonlPath}`,
|
|
16542
|
+
data: { error: String(err) }
|
|
16543
|
+
});
|
|
16544
|
+
continue;
|
|
16545
|
+
}
|
|
16546
|
+
if (trace.skippedLines > 0 || trace.skippedEvents > 0) {
|
|
16547
|
+
log({
|
|
16548
|
+
source: "git-attribution",
|
|
16549
|
+
level: "debug",
|
|
16550
|
+
summary: `skipped content in ${cand.jsonlPath}`,
|
|
16551
|
+
data: { skippedLines: trace.skippedLines, skippedEvents: trace.skippedEvents }
|
|
16552
|
+
});
|
|
16553
|
+
}
|
|
16554
|
+
if (trace.edits.length === 0)
|
|
16555
|
+
continue;
|
|
16556
|
+
const inWindow = trace.edits.filter((e2) => e2.ts >= lower && e2.ts <= upper);
|
|
16557
|
+
if (inWindow.length === 0)
|
|
16558
|
+
continue;
|
|
16559
|
+
const touchedFiles = new Set(inWindow.map((e2) => e2.file).filter((f3) => commitFiles.has(f3)));
|
|
16560
|
+
if (touchedFiles.size === 0)
|
|
16561
|
+
continue;
|
|
16562
|
+
const sessionTriByFile = /* @__PURE__ */ new Map();
|
|
16563
|
+
for (const e2 of inWindow) {
|
|
16564
|
+
if (!commitFiles.has(e2.file))
|
|
16565
|
+
continue;
|
|
16566
|
+
let bucket = sessionTriByFile.get(e2.file);
|
|
16567
|
+
if (!bucket) {
|
|
16568
|
+
bucket = /* @__PURE__ */ new Set();
|
|
16569
|
+
sessionTriByFile.set(e2.file, bucket);
|
|
16570
|
+
}
|
|
16571
|
+
for (const t of triGrams(e2.content.split("\n")))
|
|
16572
|
+
bucket.add(t);
|
|
16573
|
+
}
|
|
16574
|
+
if (sessionTriByFile.size === 0)
|
|
16575
|
+
continue;
|
|
16576
|
+
let contentHits = 0;
|
|
16577
|
+
for (const [file, sessTri] of sessionTriByFile) {
|
|
16578
|
+
const add = addedTriByFile.get(file);
|
|
16579
|
+
if (!add)
|
|
16580
|
+
continue;
|
|
16581
|
+
for (const t of sessTri) {
|
|
16582
|
+
if (add.has(t))
|
|
16583
|
+
contentHits++;
|
|
16584
|
+
}
|
|
16585
|
+
}
|
|
16586
|
+
if (contentHits === 0)
|
|
16587
|
+
continue;
|
|
16588
|
+
let survivingHits = 0;
|
|
16589
|
+
let totalTris = 0;
|
|
16590
|
+
for (const [file, sessTri] of sessionTriByFile) {
|
|
16591
|
+
const commitTri = lookupCommitFileTri(opts.repoRoot, info.hash, file, commitFileTriCache);
|
|
16592
|
+
totalTris += sessTri.size;
|
|
16593
|
+
for (const t of sessTri) {
|
|
16594
|
+
if (commitTri.has(t))
|
|
16595
|
+
survivingHits++;
|
|
16596
|
+
}
|
|
16597
|
+
}
|
|
16598
|
+
const ratio = totalTris === 0 ? 0 : survivingHits / totalTris;
|
|
16599
|
+
const lastEditTs = inWindow.reduce((m2, e2) => e2.ts > m2 ? e2.ts : m2, -Infinity);
|
|
16600
|
+
matches.push({
|
|
16601
|
+
session: trace.sessionId,
|
|
16602
|
+
parent_session_id: cand.parentSessionId,
|
|
16603
|
+
agent_type: cand.agentType,
|
|
16604
|
+
commit: info.hash,
|
|
16605
|
+
matched_files: [...touchedFiles],
|
|
16606
|
+
content_hits: contentHits,
|
|
16607
|
+
edit_count: inWindow.length,
|
|
16608
|
+
last_edit_at: new Date(lastEditTs).toISOString(),
|
|
16609
|
+
surviving_in_commit: ratio >= 0.5,
|
|
16610
|
+
surviving_ratio: Math.round(ratio * 100) / 100
|
|
16611
|
+
});
|
|
16612
|
+
}
|
|
16613
|
+
matches.sort((a3, b3) => Date.parse(a3.last_edit_at) - Date.parse(b3.last_edit_at));
|
|
16614
|
+
return matches;
|
|
16615
|
+
}
|
|
16616
|
+
function collectCandidates(sessionsDir, lower, commitTime) {
|
|
16617
|
+
const mtimeLower = lower - 6e4;
|
|
16618
|
+
const mtimeUpper = commitTime + 24 * 60 * 60 * 1e3;
|
|
16619
|
+
const inWindow = (p) => {
|
|
16620
|
+
let stat;
|
|
16621
|
+
try {
|
|
16622
|
+
stat = fs4.statSync(p);
|
|
16623
|
+
} catch {
|
|
16624
|
+
return false;
|
|
16625
|
+
}
|
|
16626
|
+
if (stat.mtimeMs < mtimeLower)
|
|
16627
|
+
return false;
|
|
16628
|
+
if (stat.mtimeMs > mtimeUpper)
|
|
16629
|
+
return false;
|
|
16630
|
+
return true;
|
|
16631
|
+
};
|
|
16632
|
+
const out = [];
|
|
16633
|
+
let entries;
|
|
16634
|
+
try {
|
|
16635
|
+
entries = fs4.readdirSync(sessionsDir, { withFileTypes: true });
|
|
16636
|
+
} catch {
|
|
16637
|
+
return out;
|
|
16638
|
+
}
|
|
16639
|
+
for (const ent of entries) {
|
|
16640
|
+
if (ent.isFile() && ent.name.endsWith(".jsonl")) {
|
|
16641
|
+
const full = path3.join(sessionsDir, ent.name);
|
|
16642
|
+
if (inWindow(full)) {
|
|
16643
|
+
out.push({ jsonlPath: full, parentSessionId: null, agentType: null });
|
|
16644
|
+
}
|
|
16645
|
+
continue;
|
|
16646
|
+
}
|
|
16647
|
+
if (!ent.isDirectory())
|
|
16648
|
+
continue;
|
|
16649
|
+
const parentDir = path3.join(sessionsDir, ent.name);
|
|
16650
|
+
const subDir = path3.join(parentDir, "subagents");
|
|
16651
|
+
let subEntries;
|
|
16652
|
+
try {
|
|
16653
|
+
subEntries = fs4.readdirSync(subDir);
|
|
16654
|
+
} catch {
|
|
16655
|
+
continue;
|
|
16656
|
+
}
|
|
16657
|
+
for (const sub of subEntries) {
|
|
16658
|
+
if (!sub.endsWith(".jsonl"))
|
|
16659
|
+
continue;
|
|
16660
|
+
const full = path3.join(subDir, sub);
|
|
16661
|
+
if (!inWindow(full))
|
|
16662
|
+
continue;
|
|
16663
|
+
const metaPath = path3.join(subDir, sub.slice(0, -".jsonl".length) + ".meta.json");
|
|
16664
|
+
let agentType = null;
|
|
16665
|
+
try {
|
|
16666
|
+
const raw2 = fs4.readFileSync(metaPath, "utf8");
|
|
16667
|
+
const meta = JSON.parse(raw2);
|
|
16668
|
+
if (typeof meta.agentType === "string")
|
|
16669
|
+
agentType = meta.agentType;
|
|
16670
|
+
} catch {
|
|
16671
|
+
}
|
|
16672
|
+
out.push({ jsonlPath: full, parentSessionId: ent.name, agentType });
|
|
16673
|
+
}
|
|
16674
|
+
}
|
|
16675
|
+
return out;
|
|
16676
|
+
}
|
|
16677
|
+
function lookupCommitFileTri(repoRoot, commit, file, cache) {
|
|
16678
|
+
const key = `${commit}:${file}`;
|
|
16679
|
+
const hit = cache.get(key);
|
|
16680
|
+
if (hit)
|
|
16681
|
+
return hit;
|
|
16682
|
+
const raw2 = gitSafe(repoRoot, ["show", `${commit}:${file}`]);
|
|
16683
|
+
const tri = raw2 ? triGrams(raw2.split("\n")) : /* @__PURE__ */ new Set();
|
|
16684
|
+
cache.set(key, tri);
|
|
16685
|
+
return tri;
|
|
16686
|
+
}
|
|
16687
|
+
function triGrams(lines) {
|
|
16688
|
+
const nonBlank = [];
|
|
16689
|
+
for (const l2 of lines) {
|
|
16690
|
+
const t = normalizeWs(l2).trim();
|
|
16691
|
+
if (t.length > 0)
|
|
16692
|
+
nonBlank.push(t);
|
|
16693
|
+
}
|
|
16694
|
+
const out = /* @__PURE__ */ new Set();
|
|
16695
|
+
for (let i = 0; i + 3 <= nonBlank.length; i++) {
|
|
16696
|
+
out.add(nonBlank[i] + "\n" + nonBlank[i + 1] + "\n" + nonBlank[i + 2]);
|
|
16697
|
+
}
|
|
16698
|
+
return out;
|
|
16699
|
+
}
|
|
16700
|
+
function normalizeWs(s) {
|
|
16701
|
+
return s.replace(/[ \t]+/g, " ").replace(/[ \t]+$/g, "");
|
|
16702
|
+
}
|
|
16703
|
+
function blameCommits(repoRoot, spec) {
|
|
16704
|
+
const args = ["blame", "--porcelain"];
|
|
16705
|
+
if (spec.lineStart !== void 0) {
|
|
16706
|
+
const end = spec.lineEnd ?? spec.lineStart;
|
|
16707
|
+
if (end < spec.lineStart) {
|
|
16708
|
+
throw new Error(`blame range end (${end}) is before start (${spec.lineStart})`);
|
|
16709
|
+
}
|
|
16710
|
+
args.push("-L", `${spec.lineStart},${end}`);
|
|
16711
|
+
}
|
|
16712
|
+
args.push("--", spec.path);
|
|
16713
|
+
const out = gitSafe(repoRoot, args);
|
|
16714
|
+
const hashes = /* @__PURE__ */ new Set();
|
|
16715
|
+
if (!out)
|
|
16716
|
+
return hashes;
|
|
16717
|
+
for (const line of out.split("\n")) {
|
|
16718
|
+
const m2 = line.match(/^([0-9a-f]{40}) \d+ \d+/);
|
|
16719
|
+
if (m2 && m2[1] !== "0".repeat(40))
|
|
16720
|
+
hashes.add(m2[1]);
|
|
16721
|
+
}
|
|
16722
|
+
return hashes;
|
|
16723
|
+
}
|
|
16724
|
+
function git(repoRoot, args) {
|
|
16725
|
+
return (0, import_node_child_process2.execFileSync)("git", args, {
|
|
16726
|
+
cwd: repoRoot,
|
|
16727
|
+
encoding: "utf8",
|
|
16728
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
16729
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
16730
|
+
});
|
|
16731
|
+
}
|
|
16732
|
+
function gitSafe(repoRoot, args) {
|
|
16733
|
+
try {
|
|
16734
|
+
return git(repoRoot, args);
|
|
16735
|
+
} catch {
|
|
16736
|
+
return null;
|
|
16737
|
+
}
|
|
16738
|
+
}
|
|
16739
|
+
|
|
16740
|
+
// src/cli/recall.ts
|
|
16741
|
+
var import_node_fs17 = require("node:fs");
|
|
16742
|
+
var import_node_child_process5 = require("node:child_process");
|
|
16743
|
+
var import_node_path16 = require("node:path");
|
|
16313
16744
|
var UUID_PREFIX = /^[0-9a-f]{8}/i;
|
|
16314
16745
|
var argv = process.argv.slice(2);
|
|
16315
16746
|
function hasFlag(name) {
|
|
@@ -16329,6 +16760,8 @@ function flagInt(name, fallback) {
|
|
|
16329
16760
|
return Number.isNaN(n) ? fallback : n;
|
|
16330
16761
|
}
|
|
16331
16762
|
var raw = hasFlag("--raw");
|
|
16763
|
+
var rawMessages = hasFlag("--raw-messages");
|
|
16764
|
+
var noIdf = hasFlag("--no-idf");
|
|
16332
16765
|
var showHelp = hasFlag("--help") || hasFlag("-h");
|
|
16333
16766
|
var showVersion = hasFlag("--version") || hasFlag("-v");
|
|
16334
16767
|
var listMode = hasFlag("--list");
|
|
@@ -16340,6 +16773,8 @@ var projectFlag = flagValue("--project");
|
|
|
16340
16773
|
var allProjects = hasFlag("--all");
|
|
16341
16774
|
var reverse = hasFlag("--reverse");
|
|
16342
16775
|
var recent = hasFlag("--recent");
|
|
16776
|
+
var commitFlag = flagValue("--commit");
|
|
16777
|
+
var blameMode = hasFlag("--blame");
|
|
16343
16778
|
var ExitSignal = class extends Error {
|
|
16344
16779
|
constructor(code) {
|
|
16345
16780
|
super(`exit:${code}`);
|
|
@@ -16351,9 +16786,11 @@ function exit(code) {
|
|
|
16351
16786
|
throw new ExitSignal(code);
|
|
16352
16787
|
}
|
|
16353
16788
|
var effectiveProject = allProjects ? void 0 : normalizePath(projectFlag ?? process.cwd());
|
|
16354
|
-
var FLAG_WITH_VALUE = /* @__PURE__ */ new Set(["--limit", "--offset", "--since", "--until", "--project", "--vendor"]);
|
|
16789
|
+
var FLAG_WITH_VALUE = /* @__PURE__ */ new Set(["--limit", "--offset", "--since", "--until", "--project", "--vendor", "--commit"]);
|
|
16355
16790
|
var FLAG_BOOLEAN = /* @__PURE__ */ new Set([
|
|
16356
16791
|
"--raw",
|
|
16792
|
+
"--raw-messages",
|
|
16793
|
+
"--no-idf",
|
|
16357
16794
|
"--help",
|
|
16358
16795
|
"-h",
|
|
16359
16796
|
"--version",
|
|
@@ -16362,6 +16799,7 @@ var FLAG_BOOLEAN = /* @__PURE__ */ new Set([
|
|
|
16362
16799
|
"--all",
|
|
16363
16800
|
"--reverse",
|
|
16364
16801
|
"--recent",
|
|
16802
|
+
"--blame",
|
|
16365
16803
|
"--no-catchup",
|
|
16366
16804
|
"--auto-embed",
|
|
16367
16805
|
"--detach",
|
|
@@ -16392,7 +16830,7 @@ for (let i = 0; i < argv.length; i++) {
|
|
|
16392
16830
|
function getVersion() {
|
|
16393
16831
|
try {
|
|
16394
16832
|
const pkg = JSON.parse(
|
|
16395
|
-
(0,
|
|
16833
|
+
(0, import_node_fs17.readFileSync)((0, import_node_path16.join)(__dirname, "..", "package.json"), "utf8")
|
|
16396
16834
|
);
|
|
16397
16835
|
return pkg.version ?? "unknown";
|
|
16398
16836
|
} catch {
|
|
@@ -16408,6 +16846,9 @@ USAGE
|
|
|
16408
16846
|
recall <session-id> Read messages from a session
|
|
16409
16847
|
recall <session-id> <message-id> Read centered on matched message
|
|
16410
16848
|
recall --list List recent sessions
|
|
16849
|
+
recall --commit <hash> Sessions that produced a commit
|
|
16850
|
+
recall --blame <path>[:<line>[-<line>]]... Sessions responsible for a file
|
|
16851
|
+
or a specific line/range (via git blame)
|
|
16411
16852
|
recall backfill [flags] Catch up FTS5 + embeddings against transcript files
|
|
16412
16853
|
|
|
16413
16854
|
ARGUMENTS
|
|
@@ -16425,7 +16866,15 @@ FLAGS
|
|
|
16425
16866
|
--recent Strongly boost recent sessions in search ranking
|
|
16426
16867
|
--reverse Read session messages newest-first (default: oldest-first)
|
|
16427
16868
|
--raw Output raw JSON instead of formatted tables
|
|
16869
|
+
--raw-messages Output the FULL pre-shaping per-message ranked list as JSON
|
|
16870
|
+
(bypasses score-gap cutoff, session-dedup, and pagination);
|
|
16871
|
+
for per-turn retrieval scoring. Honors --limit as the top-k.
|
|
16872
|
+
--no-idf Bypass the FTS5 IDF high-frequency-term filter (keeps
|
|
16873
|
+
common-but-meaningful terms like when/before/after)
|
|
16428
16874
|
--list List sessions mode
|
|
16875
|
+
--commit HASH Sessions that produced the given commit (git attribution)
|
|
16876
|
+
--blame SPEC... Sessions responsible for a file or line range at HEAD; takes
|
|
16877
|
+
one or more <path>[:<line>[-<line>]] specs (via git blame)
|
|
16429
16878
|
--no-catchup Skip the per-invocation mtime catch-up scan (T1)
|
|
16430
16879
|
--help, -h Show this help
|
|
16431
16880
|
--version, -v Print the recall version
|
|
@@ -16450,6 +16899,18 @@ EXAMPLES
|
|
|
16450
16899
|
recall a1b2c3d4 e5f6a7b8
|
|
16451
16900
|
recall a1b2c3d4 --reverse
|
|
16452
16901
|
recall --list --since 2026-04-10 --until 2026-04-10
|
|
16902
|
+
recall --commit 25dd0f8
|
|
16903
|
+
recall --blame src/paths.ts:82-84
|
|
16904
|
+
recall --blame src/foo.ts:42 src/bar.ts:10-20 --limit 20
|
|
16905
|
+
|
|
16906
|
+
COMMIT ATTRIBUTION (--commit / --blame)
|
|
16907
|
+
Returns the session(s) whose Edit/Write/MultiEdit tool calls structurally
|
|
16908
|
+
match each commit's diff. Sessions are listed chronologically (oldest first).
|
|
16909
|
+
The most recent is usually the load-bearing edit for current code; earlier
|
|
16910
|
+
sessions show evolution and may reveal originating intent or rejected
|
|
16911
|
+
approaches. --blame runs git blame to find the commits responsible for the
|
|
16912
|
+
current file (or line range) at HEAD, then attributes each. --limit (with
|
|
16913
|
+
--blame) caps the number of returned matches.
|
|
16453
16914
|
`.trim());
|
|
16454
16915
|
}
|
|
16455
16916
|
function initDb() {
|
|
@@ -16667,7 +17128,9 @@ async function runSearch(query) {
|
|
|
16667
17128
|
const r2 = await dualPathSearch(query, {
|
|
16668
17129
|
limit: ceiling,
|
|
16669
17130
|
projectId: effectiveProject,
|
|
17131
|
+
...noIdf ? { skipIdf: true } : {},
|
|
16670
17132
|
...recent ? { recencyDecay: 0.1 } : {}
|
|
17133
|
+
// default is off; --recent opts into absolute age decay
|
|
16671
17134
|
});
|
|
16672
17135
|
let { scored } = r2;
|
|
16673
17136
|
if (since) {
|
|
@@ -16694,6 +17157,28 @@ async function runSearch(query) {
|
|
|
16694
17157
|
exit(1);
|
|
16695
17158
|
}
|
|
16696
17159
|
}
|
|
17160
|
+
if (rawMessages) {
|
|
17161
|
+
const top = scored.slice(0, ceiling);
|
|
17162
|
+
console.log(JSON.stringify({
|
|
17163
|
+
query,
|
|
17164
|
+
no_idf: noIdf,
|
|
17165
|
+
semantic_available: r2.semanticAvailable,
|
|
17166
|
+
semantic_count: r2.semanticCount,
|
|
17167
|
+
fts_count: r2.ftsCount,
|
|
17168
|
+
embed_coverage: r2.embedCoverage,
|
|
17169
|
+
total: top.length,
|
|
17170
|
+
messages: top.map((x3, i) => ({
|
|
17171
|
+
rank: i + 1,
|
|
17172
|
+
session_id: x3.result.session_id,
|
|
17173
|
+
message_id: x3.result.message_id,
|
|
17174
|
+
message_seq: x3.result.message_seq,
|
|
17175
|
+
score: x3.score,
|
|
17176
|
+
snippet: (x3.result.match_snippet || x3.result.message_preview || "").slice(0, 200).replace(/\n/g, " "),
|
|
17177
|
+
tag: x3.paths.includes("fts5") && x3.paths.includes("semantic") ? "FTS5+SEMANTIC" : x3.paths.includes("semantic") ? "SEMANTIC-ONLY" : "FTS5-ONLY"
|
|
17178
|
+
}))
|
|
17179
|
+
}, null, 2));
|
|
17180
|
+
return;
|
|
17181
|
+
}
|
|
16697
17182
|
let cutoffIdx = scored.length;
|
|
16698
17183
|
if (scored.length > 10) {
|
|
16699
17184
|
let maxDrop = 0;
|
|
@@ -16771,6 +17256,7 @@ async function runSearch(query) {
|
|
|
16771
17256
|
fts_count: r2.ftsCount,
|
|
16772
17257
|
semantic_count: r2.semanticCount,
|
|
16773
17258
|
semantic_available: r2.semanticAvailable,
|
|
17259
|
+
embed_coverage: r2.embedCoverage,
|
|
16774
17260
|
unique_sessions: totalSessions,
|
|
16775
17261
|
showing_offset: pageStart,
|
|
16776
17262
|
showing_count: page.length,
|
|
@@ -16780,7 +17266,8 @@ async function runSearch(query) {
|
|
|
16780
17266
|
} else {
|
|
16781
17267
|
console.log(`Query: "${query}"`);
|
|
16782
17268
|
console.log(`Results: ${trimmed.length} messages, ${totalSessions} unique sessions (showing ${pageStart + 1}-${pageEnd})`);
|
|
16783
|
-
|
|
17269
|
+
const migrating = r2.embedCoverage < 0.95 ? ` (migrating: ${Math.round(r2.embedCoverage * 100)}% re-embedded)` : "";
|
|
17270
|
+
console.log(`Paths: FTS5=${r2.ftsCount} Semantic=${r2.semanticCount} (${r2.semanticAvailable ? "active" : "UNAVAILABLE"})${migrating}`);
|
|
16784
17271
|
if (cutoffIdx < scored.length) {
|
|
16785
17272
|
console.log(`Cutoff: position ${cutoffIdx} of ${scored.length} (score gap detected)`);
|
|
16786
17273
|
}
|
|
@@ -16805,6 +17292,102 @@ async function runSearch(query) {
|
|
|
16805
17292
|
}
|
|
16806
17293
|
}
|
|
16807
17294
|
}
|
|
17295
|
+
function blamePositionals() {
|
|
17296
|
+
const idx = argv.indexOf("--blame");
|
|
17297
|
+
if (idx < 0)
|
|
17298
|
+
return [];
|
|
17299
|
+
const out = [];
|
|
17300
|
+
for (let i = idx + 1; i < argv.length; i++) {
|
|
17301
|
+
const a3 = argv[i];
|
|
17302
|
+
if (a3.startsWith("--"))
|
|
17303
|
+
break;
|
|
17304
|
+
out.push(a3);
|
|
17305
|
+
}
|
|
17306
|
+
return out;
|
|
17307
|
+
}
|
|
17308
|
+
function printCommitAttribution(query, matches) {
|
|
17309
|
+
const note = "Sessions are listed chronologically (oldest first). The most recent is usually the load-bearing one for current code; earlier sessions show evolution and may reveal originating intent or rejected approaches.";
|
|
17310
|
+
if (raw) {
|
|
17311
|
+
console.log(JSON.stringify({
|
|
17312
|
+
query,
|
|
17313
|
+
note,
|
|
17314
|
+
count: matches.length,
|
|
17315
|
+
matches
|
|
17316
|
+
}, null, 2));
|
|
17317
|
+
return;
|
|
17318
|
+
}
|
|
17319
|
+
console.log(`Query: ${query}`);
|
|
17320
|
+
console.log(`Matches: ${matches.length}`);
|
|
17321
|
+
console.log(`Note: ${note}`);
|
|
17322
|
+
console.log("---");
|
|
17323
|
+
if (matches.length === 0) {
|
|
17324
|
+
console.log("No sessions matched.");
|
|
17325
|
+
return;
|
|
17326
|
+
}
|
|
17327
|
+
const sessLabels = matches.map(
|
|
17328
|
+
(m2) => m2.parent_session_id ? `${m2.session} \u21B3` : m2.session
|
|
17329
|
+
);
|
|
17330
|
+
const sessW = Math.max("Session".length, ...sessLabels.map((s) => s.length));
|
|
17331
|
+
const commitW = 12;
|
|
17332
|
+
const hitsW = 6;
|
|
17333
|
+
const survW = 5;
|
|
17334
|
+
const ratioW = 6;
|
|
17335
|
+
const dateW = 19;
|
|
17336
|
+
const GAP = " ";
|
|
17337
|
+
const header = "Session".padEnd(sessW) + GAP + "Commit".padEnd(commitW) + GAP + "Hits".padStart(hitsW) + GAP + "Surv?".padEnd(survW) + GAP + "Ratio".padStart(ratioW) + GAP + "Last edit".padEnd(dateW) + GAP + "Files";
|
|
17338
|
+
console.log(header);
|
|
17339
|
+
console.log("-".repeat(header.length));
|
|
17340
|
+
matches.forEach((m2, i) => {
|
|
17341
|
+
const date = m2.last_edit_at.slice(0, 19).replace("T", " ");
|
|
17342
|
+
console.log(
|
|
17343
|
+
sessLabels[i].padEnd(sessW) + GAP + m2.commit.slice(0, 10).padEnd(commitW) + GAP + String(m2.content_hits).padStart(hitsW) + GAP + (m2.surviving_in_commit ? "yes" : "no").padEnd(survW) + GAP + String(m2.surviving_ratio).padStart(ratioW) + GAP + date.padEnd(dateW) + GAP + m2.matched_files.join(", ")
|
|
17344
|
+
);
|
|
17345
|
+
if (m2.parent_session_id) {
|
|
17346
|
+
console.log(
|
|
17347
|
+
" ".repeat(2) + `(subagent of ${m2.parent_session_id.slice(0, 8)}${m2.agent_type ? `, type=${m2.agent_type}` : ""})`
|
|
17348
|
+
);
|
|
17349
|
+
}
|
|
17350
|
+
});
|
|
17351
|
+
}
|
|
17352
|
+
async function runCommitAttribution() {
|
|
17353
|
+
const repoRoot = projectFlag ?? process.cwd();
|
|
17354
|
+
if (hasFlag("--commit")) {
|
|
17355
|
+
if (commitFlag === void 0 || commitFlag.startsWith("--")) {
|
|
17356
|
+
console.error("--commit requires a commit hash. Use --help for usage.");
|
|
17357
|
+
exit(1);
|
|
17358
|
+
}
|
|
17359
|
+
let matches2;
|
|
17360
|
+
try {
|
|
17361
|
+
matches2 = await findSessionsForCommit(commitFlag, { repoRoot });
|
|
17362
|
+
} catch (err) {
|
|
17363
|
+
console.error(`recall --commit: git failed for "${commitFlag}" in ${repoRoot}: ${gitErrLine(err)}`);
|
|
17364
|
+
exit(1);
|
|
17365
|
+
}
|
|
17366
|
+
printCommitAttribution(`--commit ${commitFlag}`, matches2);
|
|
17367
|
+
return;
|
|
17368
|
+
}
|
|
17369
|
+
const rawSpecs = blamePositionals();
|
|
17370
|
+
if (rawSpecs.length === 0) {
|
|
17371
|
+
console.error("--blame requires at least one path or path:line[-line] spec. Use --help for usage.");
|
|
17372
|
+
exit(1);
|
|
17373
|
+
}
|
|
17374
|
+
const specs = rawSpecs.map(parseBlameSpec);
|
|
17375
|
+
const matchLimit = limit > 0 ? limit : void 0;
|
|
17376
|
+
let matches;
|
|
17377
|
+
try {
|
|
17378
|
+
matches = await findSessionsForBlame(specs, { repoRoot, ...matchLimit !== void 0 ? { limit: matchLimit } : {} });
|
|
17379
|
+
} catch (err) {
|
|
17380
|
+
console.error(`recall --blame: ${gitErrLine(err)}`);
|
|
17381
|
+
exit(1);
|
|
17382
|
+
}
|
|
17383
|
+
printCommitAttribution(`--blame ${rawSpecs.join(" ")}`, matches);
|
|
17384
|
+
}
|
|
17385
|
+
function gitErrLine(err) {
|
|
17386
|
+
const stderr = err.stderr;
|
|
17387
|
+
if (typeof stderr === "string" && stderr.trim())
|
|
17388
|
+
return stderr.trim().split("\n")[0];
|
|
17389
|
+
return err instanceof Error ? err.message.split("\n")[0] : String(err);
|
|
17390
|
+
}
|
|
16808
17391
|
function parseVendors() {
|
|
16809
17392
|
const v2 = flagValue("--vendor");
|
|
16810
17393
|
if (!v2)
|
|
@@ -16823,22 +17406,22 @@ async function runBackfill() {
|
|
|
16823
17406
|
clearCancelFlag();
|
|
16824
17407
|
const detach = hasFlag("--detach");
|
|
16825
17408
|
if (detach) {
|
|
16826
|
-
(0,
|
|
16827
|
-
(0,
|
|
16828
|
-
const logPath = (0,
|
|
16829
|
-
const logFd = (0,
|
|
17409
|
+
(0, import_node_fs17.mkdirSync)(logsDir(), { recursive: true });
|
|
17410
|
+
(0, import_node_fs17.mkdirSync)(runDir(), { recursive: true });
|
|
17411
|
+
const logPath = (0, import_node_path16.join)(logsDir(), "backfill.log");
|
|
17412
|
+
const logFd = (0, import_node_fs17.openSync)(logPath, "a");
|
|
16830
17413
|
const args = [process.argv[1], "backfill", "--auto-embed"];
|
|
16831
17414
|
const vendors2 = parseVendors();
|
|
16832
17415
|
if (vendors2) {
|
|
16833
17416
|
args.push("--vendor", vendors2[0]);
|
|
16834
17417
|
}
|
|
16835
|
-
const child = (0,
|
|
17418
|
+
const child = (0, import_node_child_process5.spawn)(process.execPath, args, {
|
|
16836
17419
|
detached: true,
|
|
16837
17420
|
stdio: ["ignore", logFd, logFd],
|
|
16838
17421
|
windowsHide: true
|
|
16839
17422
|
});
|
|
16840
17423
|
if (child.pid !== void 0) {
|
|
16841
|
-
(0,
|
|
17424
|
+
(0, import_node_fs17.writeFileSync)((0, import_node_path16.join)(runDir(), "backfill.pid"), String(child.pid));
|
|
16842
17425
|
}
|
|
16843
17426
|
child.unref();
|
|
16844
17427
|
process.stderr.write(`[recall] backfill detached (pid=${child.pid}, log=${logPath})
|
|
@@ -16940,6 +17523,10 @@ async function main() {
|
|
|
16940
17523
|
printHelp();
|
|
16941
17524
|
exit(0);
|
|
16942
17525
|
}
|
|
17526
|
+
if (hasFlag("--commit") || blameMode) {
|
|
17527
|
+
await runCommitAttribution();
|
|
17528
|
+
exit(0);
|
|
17529
|
+
}
|
|
16943
17530
|
if (positional[0] === "backfill") {
|
|
16944
17531
|
await runBackfill();
|
|
16945
17532
|
exit(0);
|