slopie 1.6.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/potsherd.js +764 -500
- package/dist/potsherd.js.map +3 -3
- package/package.json +1 -1
package/dist/potsherd.js
CHANGED
|
@@ -482,12 +482,6 @@ function openDatabase(file, opts = {}) {
|
|
|
482
482
|
throw new NoSqliteError([...tried]);
|
|
483
483
|
return d.open(file, opts);
|
|
484
484
|
}
|
|
485
|
-
function openDatabaseSnapshot(bytes3) {
|
|
486
|
-
const native = loadBetterSqlite();
|
|
487
|
-
if (!native?.openSnapshot)
|
|
488
|
-
throw new NoSqliteError(["frozen read-only snapshot driver unavailable"]);
|
|
489
|
-
return native.openSnapshot(bytes3);
|
|
490
|
-
}
|
|
491
485
|
function resetDriverCache() {
|
|
492
486
|
cached = void 0;
|
|
493
487
|
tried.length = 0;
|
|
@@ -621,11 +615,11 @@ function wrap2(db) {
|
|
|
621
615
|
Object.assign(variant, variants);
|
|
622
616
|
return variants.default;
|
|
623
617
|
},
|
|
624
|
-
loadExtension(
|
|
618
|
+
loadExtension(path46) {
|
|
625
619
|
db.enableLoadExtension?.(true);
|
|
626
620
|
if (!db.loadExtension)
|
|
627
621
|
throw new Error("this sqlite cannot load extensions");
|
|
628
|
-
db.loadExtension(
|
|
622
|
+
db.loadExtension(path46);
|
|
629
623
|
},
|
|
630
624
|
// 5. **`function()` registers an application-defined function.** Both
|
|
631
625
|
// drivers spell it the same way and both take the arity from
|
|
@@ -846,9 +840,9 @@ async function acquire(cacheDir = modelsDir(), onProgress) {
|
|
|
846
840
|
} finally {
|
|
847
841
|
await new Promise((resolve, reject) => out.end((err) => err ? reject(err) : resolve()));
|
|
848
842
|
}
|
|
849
|
-
const
|
|
850
|
-
if (
|
|
851
|
-
throw new Error(`checksum mismatch (got ${
|
|
843
|
+
const digest3 = hash4.digest("hex");
|
|
844
|
+
if (digest3 !== file.sha256) {
|
|
845
|
+
throw new Error(`checksum mismatch (got ${digest3.slice(0, 12)}\u2026)`);
|
|
852
846
|
}
|
|
853
847
|
const size = fs2.statSync(part).size;
|
|
854
848
|
if (size !== file.bytes)
|
|
@@ -1288,7 +1282,7 @@ function lockPathFor(root, lane) {
|
|
|
1288
1282
|
function acquire2(op, opts = {}) {
|
|
1289
1283
|
const root = opts.root ?? potsherdDir();
|
|
1290
1284
|
const lockPath = lockPathFor(root, opts.lane);
|
|
1291
|
-
const
|
|
1285
|
+
const deadline2 = Date.now() + (opts.wait ?? 0);
|
|
1292
1286
|
fs3.mkdirSync(root, { recursive: true, mode: 448 });
|
|
1293
1287
|
const token = randomUUID();
|
|
1294
1288
|
const ownerFile = `owner.${token}.json`;
|
|
@@ -1314,7 +1308,7 @@ function acquire2(op, opts = {}) {
|
|
|
1314
1308
|
continue;
|
|
1315
1309
|
observed = readOwner(lockPath);
|
|
1316
1310
|
}
|
|
1317
|
-
if (Date.now() >=
|
|
1311
|
+
if (Date.now() >= deadline2)
|
|
1318
1312
|
throw new LockBusyError(observed?.info ?? null, lockPath);
|
|
1319
1313
|
sleepSync(100);
|
|
1320
1314
|
continue;
|
|
@@ -3618,84 +3612,267 @@ var init_render = __esm({
|
|
|
3618
3612
|
|
|
3619
3613
|
// packages/core/dist/audit-sqlite.js
|
|
3620
3614
|
import fs8 from "node:fs";
|
|
3615
|
+
import os4 from "node:os";
|
|
3616
|
+
import path7 from "node:path";
|
|
3621
3617
|
import { createHash as createHash2 } from "node:crypto";
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3618
|
+
import { performance } from "node:perf_hooks";
|
|
3619
|
+
function optionalStat(file) {
|
|
3620
|
+
try {
|
|
3621
|
+
return fs8.lstatSync(file, { bigint: true });
|
|
3622
|
+
} catch (error) {
|
|
3623
|
+
if (error.code === "ENOENT")
|
|
3624
|
+
return null;
|
|
3625
|
+
throw error;
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
function checksum(bytes3, start, length, bigEndian, seed = [0, 0]) {
|
|
3629
|
+
let s0 = seed[0], s1 = seed[1];
|
|
3630
|
+
for (let i = start; i < start + length; i += 8) {
|
|
3631
|
+
const a = bigEndian ? bytes3.readUInt32BE(i) : bytes3.readUInt32LE(i), b = bigEndian ? bytes3.readUInt32BE(i + 4) : bytes3.readUInt32LE(i + 4);
|
|
3632
|
+
s0 = s0 + a + s1 >>> 0;
|
|
3633
|
+
s1 = s1 + b + s0 >>> 0;
|
|
3631
3634
|
}
|
|
3635
|
+
return [s0, s1];
|
|
3632
3636
|
}
|
|
3633
|
-
function
|
|
3634
|
-
|
|
3635
|
-
|
|
3637
|
+
function readShm(file) {
|
|
3638
|
+
const stat = optionalStat(file);
|
|
3639
|
+
if (!stat?.isFile() || stat.size < 96n)
|
|
3640
|
+
throw new Error("audit_sqlite_wal_index_unavailable");
|
|
3641
|
+
const fd = fs8.openSync(file, fs8.constants.O_RDONLY | fs8.constants.O_NOFOLLOW);
|
|
3636
3642
|
try {
|
|
3637
|
-
const
|
|
3638
|
-
if (!before.isFile() || !Number.isSafeInteger(size) || size < 100 || size > maxBytes)
|
|
3639
|
-
throw new Error("audit_sqlite_snapshot_byte_limit");
|
|
3640
|
-
const bytes3 = Buffer.alloc(size);
|
|
3643
|
+
const header = Buffer.alloc(96);
|
|
3641
3644
|
let offset = 0;
|
|
3642
|
-
while (offset <
|
|
3643
|
-
const n3 = fs8.readSync(fd,
|
|
3645
|
+
while (offset < 96) {
|
|
3646
|
+
const n3 = fs8.readSync(fd, header, offset, 96 - offset, offset);
|
|
3644
3647
|
if (!n3)
|
|
3645
|
-
throw new Error("
|
|
3648
|
+
throw new Error("audit_sqlite_wal_index_unavailable");
|
|
3646
3649
|
offset += n3;
|
|
3647
3650
|
}
|
|
3648
|
-
const
|
|
3649
|
-
if (
|
|
3651
|
+
const current = fs8.fstatSync(fd, { bigint: true });
|
|
3652
|
+
if (current.dev !== stat.dev || current.ino !== stat.ino || current.size !== stat.size)
|
|
3650
3653
|
throw new Error("audit_sqlite_snapshot_stale");
|
|
3651
|
-
|
|
3652
|
-
|
|
3654
|
+
const sum2 = checksum(header, 0, 40, nativeBigEndian);
|
|
3655
|
+
if (!header.subarray(0, 48).equals(header.subarray(48, 96)) || native32(header, 0) !== 3007e3 || native32(header, 4) !== 0 || header[12] !== 1 || sum2[0] !== native32(header, 40) || sum2[1] !== native32(header, 44))
|
|
3656
|
+
throw new Error("audit_sqlite_wal_index_unavailable");
|
|
3657
|
+
return { identity: [stat.dev, stat.ino, stat.size, createHash2("sha256").update(header).digest("hex")].join(":"), header };
|
|
3653
3658
|
} finally {
|
|
3654
3659
|
fs8.closeSync(fd);
|
|
3655
3660
|
}
|
|
3656
3661
|
}
|
|
3657
|
-
function
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3662
|
+
function inspect(file, maxBytes) {
|
|
3663
|
+
const journal = optionalStat(file + "-journal");
|
|
3664
|
+
if (journal && journal.size > 0n)
|
|
3665
|
+
throw new Error("audit_sqlite_rollback_journal_unavailable");
|
|
3666
|
+
const database = fs8.lstatSync(file, { bigint: true }), wal = optionalStat(file + "-wal");
|
|
3667
|
+
if (!database.isFile() || wal && !wal.isFile() || journal && !journal.isFile())
|
|
3668
|
+
throw new Error("audit_sqlite_format_unavailable");
|
|
3669
|
+
const databaseBytes = Number(database.size), walBytes = wal ? Number(wal.size) : 0;
|
|
3670
|
+
if (!Number.isSafeInteger(databaseBytes) || !Number.isSafeInteger(walBytes) || databaseBytes < 100 || databaseBytes + walBytes > maxBytes)
|
|
3671
|
+
throw new Error("audit_sqlite_snapshot_byte_limit");
|
|
3672
|
+
const shm = walBytes > 0 ? readShm(file + "-shm") : null;
|
|
3673
|
+
return { database: fingerprint(database), wal: wal ? fingerprint(wal) : null, journal: journal ? fingerprint(journal) : null, databaseBytes, walBytes, shm: shm?.identity ?? null, shmHeader: shm?.header ?? null };
|
|
3674
|
+
}
|
|
3675
|
+
function deadline(maxMs) {
|
|
3676
|
+
const start = performance.now();
|
|
3661
3677
|
return () => {
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
throw new Error("audit_sqlite_snapshot_stale");
|
|
3678
|
+
if (performance.now() - start > maxMs)
|
|
3679
|
+
throw new Error("audit_sqlite_snapshot_time_limit");
|
|
3665
3680
|
};
|
|
3666
3681
|
}
|
|
3667
|
-
function
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
copy[18] = 1;
|
|
3675
|
-
copy[19] = 1;
|
|
3676
|
-
const db = openDatabaseSnapshot(copy), assertCurrent = verifier(file, maxBytes, identity4, hash4);
|
|
3677
|
-
const assertIdentityCurrent = () => {
|
|
3678
|
-
checkWal(file);
|
|
3679
|
-
if (fingerprint(fs8.statSync(file, { bigint: true })) !== identity4)
|
|
3682
|
+
function stream(file, size, identity4, buffer, check, destination) {
|
|
3683
|
+
check();
|
|
3684
|
+
let fd;
|
|
3685
|
+
try {
|
|
3686
|
+
fd = fs8.openSync(file, fs8.constants.O_RDONLY | fs8.constants.O_NOFOLLOW);
|
|
3687
|
+
} catch (error) {
|
|
3688
|
+
if (error.code === "ENOENT")
|
|
3680
3689
|
throw new Error("audit_sqlite_snapshot_stale");
|
|
3681
|
-
|
|
3690
|
+
throw error;
|
|
3691
|
+
}
|
|
3692
|
+
let out;
|
|
3693
|
+
try {
|
|
3694
|
+
if (fingerprint(fs8.fstatSync(fd, { bigint: true })) !== identity4)
|
|
3695
|
+
throw new Error("audit_sqlite_snapshot_stale");
|
|
3696
|
+
if (destination)
|
|
3697
|
+
out = fs8.openSync(destination, fs8.constants.O_WRONLY | fs8.constants.O_CREAT | fs8.constants.O_EXCL | fs8.constants.O_NOFOLLOW, 384);
|
|
3698
|
+
const header = Buffer.alloc(Math.min(size, 100)), hash4 = createHash2("sha256");
|
|
3699
|
+
let offset = 0;
|
|
3700
|
+
while (offset < size) {
|
|
3701
|
+
check();
|
|
3702
|
+
const n3 = fs8.readSync(fd, buffer, 0, Math.min(buffer.length, size - offset), offset);
|
|
3703
|
+
if (!n3)
|
|
3704
|
+
throw new Error("audit_sqlite_snapshot_stale");
|
|
3705
|
+
const chunk = buffer.subarray(0, n3);
|
|
3706
|
+
hash4.update(chunk);
|
|
3707
|
+
if (offset < header.length)
|
|
3708
|
+
chunk.copy(header, offset, 0, Math.min(n3, header.length - offset));
|
|
3709
|
+
if (out !== void 0) {
|
|
3710
|
+
let written = 0;
|
|
3711
|
+
while (written < n3) {
|
|
3712
|
+
check();
|
|
3713
|
+
const count2 = fs8.writeSync(out, buffer, written, n3 - written, offset + written);
|
|
3714
|
+
if (!count2)
|
|
3715
|
+
throw new Error("audit_sqlite_snapshot_copy_unavailable");
|
|
3716
|
+
written += count2;
|
|
3717
|
+
}
|
|
3718
|
+
}
|
|
3719
|
+
offset += n3;
|
|
3720
|
+
}
|
|
3721
|
+
if (out !== void 0)
|
|
3722
|
+
fs8.fsyncSync(out);
|
|
3723
|
+
check();
|
|
3724
|
+
if (fingerprint(fs8.fstatSync(fd, { bigint: true })) !== identity4)
|
|
3725
|
+
throw new Error("audit_sqlite_snapshot_stale");
|
|
3726
|
+
return { header, hash: hash4.digest("hex") };
|
|
3727
|
+
} finally {
|
|
3728
|
+
fs8.closeSync(fd);
|
|
3729
|
+
if (out !== void 0)
|
|
3730
|
+
fs8.closeSync(out);
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
function capture(file, maxBytes, check, buffer, directory) {
|
|
3734
|
+
check();
|
|
3735
|
+
const identity4 = inspect(file, maxBytes), copy = directory ? path7.join(directory, "snapshot.db") : void 0;
|
|
3736
|
+
const database = stream(file, identity4.databaseBytes, identity4.database, buffer, check, copy), wal = identity4.wal === null ? null : stream(file + "-wal", identity4.walBytes, identity4.wal, buffer, check, copy ? copy + "-wal" : void 0);
|
|
3737
|
+
if (!same(identity4, inspect(file, maxBytes)))
|
|
3738
|
+
throw new Error("audit_sqlite_snapshot_stale");
|
|
3739
|
+
check();
|
|
3740
|
+
const hash4 = createHash2("sha256").update(JSON.stringify([identity4.database, identity4.wal, identity4.journal, identity4.shm])).update(database.hash).update(wal === null ? "absent" : wal.hash).digest("hex");
|
|
3741
|
+
check();
|
|
3742
|
+
return { identity: identity4, databaseHeader: database.header, walHeader: wal?.header ?? null, hash: hash4 };
|
|
3743
|
+
}
|
|
3744
|
+
function validateEnvelope(captured) {
|
|
3745
|
+
const db = captured.databaseHeader, wal = captured.walHeader;
|
|
3746
|
+
if (db.subarray(0, 16).toString("binary") !== "SQLite format 3\0")
|
|
3747
|
+
throw new Error("audit_sqlite_format_unavailable");
|
|
3748
|
+
if (!captured.identity.walBytes)
|
|
3749
|
+
return;
|
|
3750
|
+
if (!wal || wal.length < 32)
|
|
3751
|
+
throw new Error("audit_sqlite_wal_header_unavailable");
|
|
3752
|
+
const magic = wal.readUInt32BE(0), version = wal.readUInt32BE(4), pageSize = wal.readUInt32BE(8), databasePageSize = db.readUInt16BE(16) === 1 ? 65536 : db.readUInt16BE(16);
|
|
3753
|
+
if (magic !== 931071618 && magic !== 931071619 || version !== 3007e3 || pageSize < 512 || pageSize > 65536 || (pageSize & pageSize - 1) !== 0 || pageSize !== databasePageSize)
|
|
3754
|
+
throw new Error("audit_sqlite_wal_header_unavailable");
|
|
3755
|
+
if ((captured.identity.walBytes - 32) % (pageSize + 24) !== 0)
|
|
3756
|
+
throw new Error("audit_sqlite_wal_incomplete_tail");
|
|
3757
|
+
}
|
|
3758
|
+
function validateCommittedWal(captured, copy, buffer, check) {
|
|
3759
|
+
if (!captured.identity.walBytes)
|
|
3760
|
+
return;
|
|
3761
|
+
const wal = captured.walHeader, shm = captured.identity.shmHeader;
|
|
3762
|
+
const bigEndian = wal.readUInt32BE(0) === 931071619, pageSize = wal.readUInt32BE(8), rawShmPage = nativeBigEndian ? shm.readUInt16BE(14) : shm.readUInt16LE(14), shmPage = rawShmPage === 1 ? 65536 : rawShmPage;
|
|
3763
|
+
let sum2 = checksum(wal, 0, 24, bigEndian);
|
|
3764
|
+
const mxFrame = native32(shm, 16), nPage = native32(shm, 20), committedBytes = 32 + mxFrame * (pageSize + 24);
|
|
3765
|
+
const fail6 = () => {
|
|
3766
|
+
throw new Error("audit_sqlite_wal_integrity_unavailable");
|
|
3682
3767
|
};
|
|
3683
|
-
|
|
3684
|
-
|
|
3768
|
+
if (sum2[0] !== wal.readUInt32BE(24) || sum2[1] !== wal.readUInt32BE(28) || shm[13] !== Number(bigEndian) || shmPage !== pageSize || !shm.subarray(32, 40).equals(wal.subarray(16, 24)) || committedBytes > captured.identity.walBytes)
|
|
3769
|
+
fail6();
|
|
3770
|
+
const fd = fs8.openSync(copy + "-wal", fs8.constants.O_RDONLY | fs8.constants.O_NOFOLLOW);
|
|
3771
|
+
try {
|
|
3772
|
+
for (let frame = 1; frame <= mxFrame; frame++) {
|
|
3773
|
+
check();
|
|
3774
|
+
const length = pageSize + 24, position = 32 + (frame - 1) * length;
|
|
3775
|
+
let offset = 0;
|
|
3776
|
+
while (offset < length) {
|
|
3777
|
+
const n3 = fs8.readSync(fd, buffer, offset, length - offset, position + offset);
|
|
3778
|
+
if (!n3)
|
|
3779
|
+
fail6();
|
|
3780
|
+
offset += n3;
|
|
3781
|
+
}
|
|
3782
|
+
if (buffer.readUInt32BE(0) === 0 || !buffer.subarray(8, 16).equals(wal.subarray(16, 24)))
|
|
3783
|
+
fail6();
|
|
3784
|
+
sum2 = checksum(buffer, 0, 8, bigEndian, sum2);
|
|
3785
|
+
sum2 = checksum(buffer, 24, pageSize, bigEndian, sum2);
|
|
3786
|
+
if (sum2[0] !== buffer.readUInt32BE(16) || sum2[1] !== buffer.readUInt32BE(20))
|
|
3787
|
+
fail6();
|
|
3788
|
+
if (frame === mxFrame && (buffer.readUInt32BE(4) === 0 || buffer.readUInt32BE(4) !== nPage || sum2[0] !== native32(shm, 24) || sum2[1] !== native32(shm, 28)))
|
|
3789
|
+
fail6();
|
|
3790
|
+
}
|
|
3791
|
+
} finally {
|
|
3792
|
+
fs8.closeSync(fd);
|
|
3793
|
+
}
|
|
3794
|
+
fs8.truncateSync(copy + "-wal", committedBytes);
|
|
3795
|
+
check();
|
|
3796
|
+
}
|
|
3797
|
+
function openAuditSqliteSnapshot(file, maxBytes = MAX_DISK_BYTES, options = {}) {
|
|
3798
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes < 100 || maxBytes > MAX_DISK_BYTES)
|
|
3799
|
+
throw new Error("invalid audit SQLite byte limit");
|
|
3800
|
+
const initial = inspect(file, maxBytes);
|
|
3801
|
+
const maxCaptureMs = options.maxCaptureMs ?? Math.min(6e4, Math.max(2e4, Math.ceil((initial.databaseBytes + initial.walBytes) / (1024 * 1024 * 1024)) * 2e4));
|
|
3802
|
+
if (!Number.isFinite(maxCaptureMs) || maxCaptureMs < 1 || maxCaptureMs > 6e4)
|
|
3803
|
+
throw new Error("invalid audit SQLite time limit");
|
|
3804
|
+
const check = deadline(maxCaptureMs);
|
|
3805
|
+
check();
|
|
3806
|
+
const free = fs8.statfsSync(os4.tmpdir(), { bigint: true });
|
|
3807
|
+
if (free.bavail * free.bsize < BigInt(initial.databaseBytes + initial.walBytes + DISK_HEADROOM))
|
|
3808
|
+
throw new Error("audit_sqlite_snapshot_disk_limit");
|
|
3809
|
+
const directory = fs8.mkdtempSync(path7.join(os4.tmpdir(), "slopie-audit-sqlite-"));
|
|
3810
|
+
let db;
|
|
3685
3811
|
try {
|
|
3686
|
-
|
|
3687
|
-
|
|
3812
|
+
fs8.chmodSync(directory, 448);
|
|
3813
|
+
const buffer = Buffer.allocUnsafe(BUFFER_BYTES), captured = capture(file, maxBytes, check, buffer, directory);
|
|
3814
|
+
validateEnvelope(captured);
|
|
3815
|
+
const confirmed = capture(file, maxBytes, check, buffer);
|
|
3816
|
+
if (captured.hash !== confirmed.hash || !same(captured.identity, confirmed.identity))
|
|
3817
|
+
throw new Error("audit_sqlite_snapshot_stale");
|
|
3818
|
+
const copy = path7.join(directory, "snapshot.db");
|
|
3819
|
+
validateCommittedWal(captured, copy, buffer, check);
|
|
3820
|
+
db = openDatabase(copy, { readonly: true, fileMustExist: true });
|
|
3821
|
+
db.pragma("temp_store = MEMORY");
|
|
3822
|
+
db.pragma("query_only = ON");
|
|
3823
|
+
db.prepare("SELECT count(*) FROM sqlite_schema").get();
|
|
3824
|
+
for (const name of fs8.readdirSync(directory))
|
|
3825
|
+
fs8.chmodSync(path7.join(directory, name), 384);
|
|
3826
|
+
check();
|
|
3827
|
+
const assertCurrent = () => {
|
|
3828
|
+
const now = capture(file, maxBytes, deadline(maxCaptureMs), Buffer.allocUnsafe(BUFFER_BYTES));
|
|
3829
|
+
if (now.hash !== captured.hash || !same(now.identity, captured.identity))
|
|
3830
|
+
throw new Error("audit_sqlite_snapshot_stale");
|
|
3831
|
+
};
|
|
3832
|
+
const assertIdentityCurrent = () => {
|
|
3833
|
+
if (!same(inspect(file, maxBytes), captured.identity))
|
|
3834
|
+
throw new Error("audit_sqlite_snapshot_stale");
|
|
3835
|
+
};
|
|
3836
|
+
assertIdentityCurrent();
|
|
3837
|
+
check();
|
|
3838
|
+
const handle = db, rawClose = handle.close.bind(handle);
|
|
3839
|
+
let closed = false;
|
|
3840
|
+
handle.close = () => {
|
|
3841
|
+
if (!closed) {
|
|
3842
|
+
closed = true;
|
|
3843
|
+
try {
|
|
3844
|
+
rawClose();
|
|
3845
|
+
} finally {
|
|
3846
|
+
fs8.rmSync(directory, { recursive: true, force: true });
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
return handle;
|
|
3850
|
+
};
|
|
3851
|
+
return { db, hash: captured.hash, assertCurrent, assertIdentityCurrent };
|
|
3688
3852
|
} catch (error) {
|
|
3689
|
-
|
|
3853
|
+
try {
|
|
3854
|
+
db?.close();
|
|
3855
|
+
} finally {
|
|
3856
|
+
fs8.rmSync(directory, { recursive: true, force: true });
|
|
3857
|
+
}
|
|
3858
|
+
const code = error.code;
|
|
3859
|
+
if (code?.startsWith("SQLITE_") || code === "ERR_SQLITE_ERROR")
|
|
3860
|
+
throw new Error("audit_sqlite_snapshot_corrupt", { cause: error });
|
|
3690
3861
|
throw error;
|
|
3691
3862
|
}
|
|
3692
3863
|
}
|
|
3693
|
-
var fingerprint;
|
|
3864
|
+
var MAX_DISK_BYTES, BUFFER_BYTES, DISK_HEADROOM, fingerprint, same, nativeBigEndian, native32;
|
|
3694
3865
|
var init_audit_sqlite = __esm({
|
|
3695
3866
|
"packages/core/dist/audit-sqlite.js"() {
|
|
3696
3867
|
"use strict";
|
|
3697
3868
|
init_sqlite_driver();
|
|
3698
|
-
|
|
3869
|
+
MAX_DISK_BYTES = 4 * 1024 * 1024 * 1024;
|
|
3870
|
+
BUFFER_BYTES = 1024 * 1024;
|
|
3871
|
+
DISK_HEADROOM = 32 * 1024 * 1024;
|
|
3872
|
+
fingerprint = (s) => [s.dev, s.ino, s.size, s.mtimeNs, s.ctimeNs].join(":");
|
|
3873
|
+
same = (a, b) => a.database === b.database && a.wal === b.wal && a.journal === b.journal && a.shm === b.shm;
|
|
3874
|
+
nativeBigEndian = os4.endianness() === "BE";
|
|
3875
|
+
native32 = (bytes3, offset) => nativeBigEndian ? bytes3.readUInt32BE(offset) : bytes3.readUInt32LE(offset);
|
|
3699
3876
|
}
|
|
3700
3877
|
});
|
|
3701
3878
|
|
|
@@ -3745,7 +3922,7 @@ var init_archive_state = __esm({
|
|
|
3745
3922
|
|
|
3746
3923
|
// packages/core/dist/claude/scan.js
|
|
3747
3924
|
import fs10 from "node:fs";
|
|
3748
|
-
import
|
|
3925
|
+
import path8 from "node:path";
|
|
3749
3926
|
function scanClaudeDisk(dir, opts = {}) {
|
|
3750
3927
|
const started = Date.now();
|
|
3751
3928
|
const cp = claudePaths(dir);
|
|
@@ -3767,19 +3944,19 @@ function scanClaudeDisk(dir, opts = {}) {
|
|
|
3767
3944
|
if (!entry.isDirectory())
|
|
3768
3945
|
continue;
|
|
3769
3946
|
const slug = entry.name;
|
|
3770
|
-
const projDir =
|
|
3771
|
-
const memoryDir2 =
|
|
3947
|
+
const projDir = path8.join(projectsDir, slug);
|
|
3948
|
+
const memoryDir2 = path8.join(projDir, "memory");
|
|
3772
3949
|
const memoryFiles = fs10.existsSync(memoryDir2) ? readdirSafe(memoryDir2).filter((f) => f.endsWith(".md")).length : 0;
|
|
3773
3950
|
out.projects.push({
|
|
3774
3951
|
slug,
|
|
3775
3952
|
dir: projDir,
|
|
3776
|
-
hasSessionsIndex: fs10.existsSync(
|
|
3953
|
+
hasSessionsIndex: fs10.existsSync(path8.join(projDir, "sessions-index.json")),
|
|
3777
3954
|
hasMemory: memoryFiles > 0,
|
|
3778
3955
|
memoryFiles
|
|
3779
3956
|
});
|
|
3780
3957
|
for (const child of readdirSafe(projDir, { withFileTypes: true })) {
|
|
3781
3958
|
if (child.isFile() && child.name.endsWith(".jsonl")) {
|
|
3782
|
-
const f = scanFile(
|
|
3959
|
+
const f = scanFile(path8.join(projDir, child.name), slug, {
|
|
3783
3960
|
sessionId: child.name.slice(0, -".jsonl".length),
|
|
3784
3961
|
isSidechain: false,
|
|
3785
3962
|
titles: opts.titles !== false,
|
|
@@ -3789,14 +3966,14 @@ function scanClaudeDisk(dir, opts = {}) {
|
|
|
3789
3966
|
out.totalBytes += f.bytes;
|
|
3790
3967
|
} else if (child.isDirectory()) {
|
|
3791
3968
|
const nested = child.name === SIDECHAIN_DIR;
|
|
3792
|
-
const subDir = nested ?
|
|
3969
|
+
const subDir = nested ? path8.join(projDir, child.name) : path8.join(projDir, child.name, SIDECHAIN_DIR);
|
|
3793
3970
|
if (!fs10.existsSync(subDir))
|
|
3794
3971
|
continue;
|
|
3795
3972
|
for (const sub of readdirSafe(subDir)) {
|
|
3796
3973
|
if (!sub.endsWith(".jsonl"))
|
|
3797
3974
|
continue;
|
|
3798
3975
|
const fileId = sub.slice(0, -".jsonl".length);
|
|
3799
|
-
const f = scanFile(
|
|
3976
|
+
const f = scanFile(path8.join(subDir, sub), slug, {
|
|
3800
3977
|
// With no enclosing session directory the parent session is
|
|
3801
3978
|
// whatever the records say; the filename is only an agent name.
|
|
3802
3979
|
sessionId: nested ? fileId : child.name,
|
|
@@ -4049,7 +4226,7 @@ var init_history = __esm({
|
|
|
4049
4226
|
|
|
4050
4227
|
// packages/core/dist/claude/sessions-index.js
|
|
4051
4228
|
import fs12 from "node:fs";
|
|
4052
|
-
import
|
|
4229
|
+
import path9 from "node:path";
|
|
4053
4230
|
function readSessionsIndexes(dir) {
|
|
4054
4231
|
const projectsDir = claudePaths(dir).projects;
|
|
4055
4232
|
const out = { files: [], entries: /* @__PURE__ */ new Map(), malformed: [] };
|
|
@@ -4060,7 +4237,7 @@ function readSessionsIndexes(dir) {
|
|
|
4060
4237
|
return out;
|
|
4061
4238
|
}
|
|
4062
4239
|
for (const slug of slugs) {
|
|
4063
|
-
const p =
|
|
4240
|
+
const p = path9.join(projectsDir, slug, "sessions-index.json");
|
|
4064
4241
|
if (!fs12.existsSync(p))
|
|
4065
4242
|
continue;
|
|
4066
4243
|
out.files.push(p);
|
|
@@ -4119,7 +4296,7 @@ var init_sessions_index = __esm({
|
|
|
4119
4296
|
|
|
4120
4297
|
// packages/core/dist/memory/leases.js
|
|
4121
4298
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
4122
|
-
import
|
|
4299
|
+
import os5 from "node:os";
|
|
4123
4300
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
4124
4301
|
function processStart2(pid) {
|
|
4125
4302
|
try {
|
|
@@ -4166,7 +4343,7 @@ var HOST, START;
|
|
|
4166
4343
|
var init_leases = __esm({
|
|
4167
4344
|
"packages/core/dist/memory/leases.js"() {
|
|
4168
4345
|
"use strict";
|
|
4169
|
-
HOST =
|
|
4346
|
+
HOST = os5.hostname();
|
|
4170
4347
|
START = processStart2(process.pid) ?? "unknown:" + new Date(Date.now() - process.uptime() * 1e3).toISOString();
|
|
4171
4348
|
}
|
|
4172
4349
|
});
|
|
@@ -4363,7 +4540,7 @@ var init_spans = __esm({
|
|
|
4363
4540
|
|
|
4364
4541
|
// packages/core/dist/memory/assets.js
|
|
4365
4542
|
import fs13 from "node:fs";
|
|
4366
|
-
import
|
|
4543
|
+
import path10 from "node:path";
|
|
4367
4544
|
import { createHash as createHash3 } from "node:crypto";
|
|
4368
4545
|
import { Worker } from "node:worker_threads";
|
|
4369
4546
|
function namedSpace(pooling) {
|
|
@@ -4372,7 +4549,7 @@ function namedSpace(pooling) {
|
|
|
4372
4549
|
function inspectAssets(cacheDir) {
|
|
4373
4550
|
const signature = requiredFiles().map((f) => {
|
|
4374
4551
|
try {
|
|
4375
|
-
const st = fs13.statSync(
|
|
4552
|
+
const st = fs13.statSync(path10.join(cacheDir, f.name));
|
|
4376
4553
|
return [st.dev, st.ino, st.size, st.mtimeMs, st.ctimeMs].join(":");
|
|
4377
4554
|
} catch {
|
|
4378
4555
|
return "missing";
|
|
@@ -4383,7 +4560,7 @@ function inspectAssets(cacheDir) {
|
|
|
4383
4560
|
return cached4.result;
|
|
4384
4561
|
const missing = requiredFiles().filter((f) => {
|
|
4385
4562
|
try {
|
|
4386
|
-
const b = fs13.readFileSync(
|
|
4563
|
+
const b = fs13.readFileSync(path10.join(cacheDir, f.name));
|
|
4387
4564
|
return b.length !== f.bytes || createHash3("sha256").update(b).digest("hex") !== f.sha256;
|
|
4388
4565
|
} catch {
|
|
4389
4566
|
return true;
|
|
@@ -4563,7 +4740,7 @@ var init_assets = __esm({
|
|
|
4563
4740
|
// packages/core/dist/memory/jobs.js
|
|
4564
4741
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
4565
4742
|
import fs14 from "node:fs";
|
|
4566
|
-
import
|
|
4743
|
+
import path11 from "node:path";
|
|
4567
4744
|
function enqueueJob(db, r, now = Date.now()) {
|
|
4568
4745
|
const id = identity("job/v1", r.kind, r.targetId, r.inputHash), at2 = new Date(now).toISOString();
|
|
4569
4746
|
db.prepare(`INSERT INTO maintenance_jobs(job_id,kind,target_id,target_revision_id,input_hash,state,attempts,next_attempt_at,created_at,updated_at) VALUES(?,?,?,?,?,'pending',0,?,?,?) ON CONFLICT(kind,target_id,input_hash) DO NOTHING`).run(id, r.kind, r.targetId, r.targetRevisionId ?? null, r.inputHash, at2, at2, at2);
|
|
@@ -4594,7 +4771,7 @@ function validateCapturePayload(value) {
|
|
|
4594
4771
|
if (r[key2] !== void 0 && (typeof r[key2] !== "string" || !r[key2] || r[key2].length > 8192))
|
|
4595
4772
|
throw new Error("invalid_capture_request");
|
|
4596
4773
|
for (const key2 of ["claudeDir", "codexHome", "piDir", "opencodeDir"])
|
|
4597
|
-
if (r[key2] !== void 0 && !
|
|
4774
|
+
if (r[key2] !== void 0 && !path11.isAbsolute(r[key2]))
|
|
4598
4775
|
throw new Error("invalid_capture_request");
|
|
4599
4776
|
if (r.full !== void 0 && typeof r.full !== "boolean")
|
|
4600
4777
|
throw new Error("invalid_capture_request");
|
|
@@ -4605,12 +4782,12 @@ function validateCapturePayload(value) {
|
|
|
4605
4782
|
}
|
|
4606
4783
|
function enqueueRequest(db, r) {
|
|
4607
4784
|
return db.transaction(() => {
|
|
4608
|
-
const
|
|
4785
|
+
const capture2 = r.capture === void 0 ? void 0 : validateCapturePayload(r.capture);
|
|
4609
4786
|
const id = enqueueJob(db, r);
|
|
4610
|
-
if (
|
|
4787
|
+
if (capture2) {
|
|
4611
4788
|
if (r.kind !== "capture")
|
|
4612
4789
|
throw new Error("invalid_capture_request");
|
|
4613
|
-
const detail = JSON.stringify({ capture });
|
|
4790
|
+
const detail = JSON.stringify({ capture: capture2 });
|
|
4614
4791
|
const previous = db.prepare("SELECT detail_json FROM maintenance_events WHERE job_id=? AND kind='capture_request' LIMIT 1").get(id);
|
|
4615
4792
|
if (previous && previous.detail_json !== detail)
|
|
4616
4793
|
throw new Error("capture_request_conflict");
|
|
@@ -4661,9 +4838,9 @@ function retryBlocked(db, code) {
|
|
|
4661
4838
|
db.prepare("UPDATE maintenance_jobs SET state='pending',next_attempt_at=?,updated_at=?,error_code=NULL WHERE state='blocked' AND error_code=?").run(at2, at2, code);
|
|
4662
4839
|
}
|
|
4663
4840
|
function spoolRequest(root, r) {
|
|
4664
|
-
const dir =
|
|
4841
|
+
const dir = path11.join(root, "maintenance-spool");
|
|
4665
4842
|
fs14.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
4666
|
-
const file =
|
|
4843
|
+
const file = path11.join(dir, identity("spool/v1", r.kind, r.targetId, r.inputHash) + ".json"), temp = file + "." + randomUUID3() + ".tmp";
|
|
4667
4844
|
const fd = fs14.openSync(temp, "wx", 384);
|
|
4668
4845
|
try {
|
|
4669
4846
|
fs14.writeFileSync(fd, JSON.stringify({ ...r, requestId: r.requestId ?? randomUUID3() }));
|
|
@@ -4681,12 +4858,12 @@ function spoolRequest(root, r) {
|
|
|
4681
4858
|
return file;
|
|
4682
4859
|
}
|
|
4683
4860
|
function drainSpool(db, root) {
|
|
4684
|
-
const dir =
|
|
4861
|
+
const dir = path11.join(root, "maintenance-spool");
|
|
4685
4862
|
if (!fs14.existsSync(dir))
|
|
4686
4863
|
return 0;
|
|
4687
4864
|
let n3 = 0;
|
|
4688
4865
|
for (const name of fs14.readdirSync(dir).filter((x) => /^[a-f0-9]{64}\.json$/u.test(x)).sort()) {
|
|
4689
|
-
const file =
|
|
4866
|
+
const file = path11.join(dir, name);
|
|
4690
4867
|
try {
|
|
4691
4868
|
const r = JSON.parse(fs14.readFileSync(file, "utf8"));
|
|
4692
4869
|
if (!["discover", "capture", "parse", "lineage", "embed", "rebuild", "forget"].includes(r.kind) || typeof r.targetId !== "string" || typeof r.inputHash !== "string")
|
|
@@ -4855,8 +5032,8 @@ async function* readJsonlLines(filePath, options = {}) {
|
|
|
4855
5032
|
let offset = start;
|
|
4856
5033
|
let lineNumber = options.startLine ?? 0;
|
|
4857
5034
|
let held = Buffer.alloc(0);
|
|
4858
|
-
const
|
|
4859
|
-
for await (const chunk of
|
|
5035
|
+
const stream2 = options.snapshot ? [options.snapshot.subarray(start)] : fs15.createReadStream(filePath, { start });
|
|
5036
|
+
for await (const chunk of stream2) {
|
|
4860
5037
|
held = held.length === 0 ? chunk : Buffer.concat([held, chunk]);
|
|
4861
5038
|
let idx = held.indexOf(LF);
|
|
4862
5039
|
while (idx !== -1) {
|
|
@@ -5127,10 +5304,10 @@ var init_evidence = __esm({
|
|
|
5127
5304
|
|
|
5128
5305
|
// packages/core/dist/parser/claude.js
|
|
5129
5306
|
import fs17 from "node:fs";
|
|
5130
|
-
import
|
|
5307
|
+
import path12 from "node:path";
|
|
5131
5308
|
import crypto3 from "node:crypto";
|
|
5132
5309
|
async function parseClaudeTranscript(filePath, options = {}) {
|
|
5133
|
-
const absolute2 =
|
|
5310
|
+
const absolute2 = path12.resolve(filePath);
|
|
5134
5311
|
const fromOffset = options.fromOffset ?? 0;
|
|
5135
5312
|
const snapshot = fs17.readFileSync(absolute2);
|
|
5136
5313
|
const seqByOffset = /* @__PURE__ */ new Map();
|
|
@@ -5328,7 +5505,7 @@ ${text3}` : text3;
|
|
|
5328
5505
|
function resolveSessionId(absolute2, options, recordSessionId, sidechainFlag) {
|
|
5329
5506
|
if (options.sessionId)
|
|
5330
5507
|
return options.sessionId;
|
|
5331
|
-
const base2 =
|
|
5508
|
+
const base2 = path12.basename(absolute2, ".jsonl");
|
|
5332
5509
|
const isSidechain = options.isSidechain ?? sidechainFlag ?? false;
|
|
5333
5510
|
if (isSidechain) {
|
|
5334
5511
|
const parent = options.parentSessionId ?? recordSessionId;
|
|
@@ -5337,7 +5514,7 @@ function resolveSessionId(absolute2, options, recordSessionId, sidechainFlag) {
|
|
|
5337
5514
|
return recordSessionId ?? base2;
|
|
5338
5515
|
}
|
|
5339
5516
|
function deriveProjectSlug(absolute2) {
|
|
5340
|
-
const parts = absolute2.split(
|
|
5517
|
+
const parts = absolute2.split(path12.sep);
|
|
5341
5518
|
for (let i = parts.length - 2; i >= 0; i -= 1) {
|
|
5342
5519
|
const part = parts[i];
|
|
5343
5520
|
if (!part)
|
|
@@ -5422,7 +5599,7 @@ __export(opencode_exports, {
|
|
|
5422
5599
|
sourceDir: () => sourceDir
|
|
5423
5600
|
});
|
|
5424
5601
|
import fs18 from "node:fs";
|
|
5425
|
-
import
|
|
5602
|
+
import path13 from "node:path";
|
|
5426
5603
|
function sourceDir(override) {
|
|
5427
5604
|
return opencodeDir(override);
|
|
5428
5605
|
}
|
|
@@ -5530,14 +5707,14 @@ function findStores(override) {
|
|
|
5530
5707
|
return;
|
|
5531
5708
|
}
|
|
5532
5709
|
for (const e of entries) {
|
|
5533
|
-
const full =
|
|
5710
|
+
const full = path13.join(dir, e.name);
|
|
5534
5711
|
if (e.isDirectory()) {
|
|
5535
5712
|
walk3(full, depth + 1);
|
|
5536
5713
|
continue;
|
|
5537
5714
|
}
|
|
5538
5715
|
if (!e.isFile())
|
|
5539
5716
|
continue;
|
|
5540
|
-
if (DB_EXTENSIONS.includes(
|
|
5717
|
+
if (DB_EXTENSIONS.includes(path13.extname(e.name).toLowerCase()))
|
|
5541
5718
|
out.push(full);
|
|
5542
5719
|
}
|
|
5543
5720
|
};
|
|
@@ -5596,7 +5773,7 @@ function discoverIn(schema) {
|
|
|
5596
5773
|
sessionId: id,
|
|
5597
5774
|
harness: "opencode",
|
|
5598
5775
|
path: schema.dbPath,
|
|
5599
|
-
projectSlug: directory ?
|
|
5776
|
+
projectSlug: directory ? path13.basename(directory) : "",
|
|
5600
5777
|
bytes: bytes3.get(id) ?? 0,
|
|
5601
5778
|
mtimeMs,
|
|
5602
5779
|
// opencode's `parent_id` marks a child session — a subagent
|
|
@@ -5615,7 +5792,7 @@ function discoverIn(schema) {
|
|
|
5615
5792
|
}
|
|
5616
5793
|
async function parse(source, options = {}) {
|
|
5617
5794
|
const src = typeof source === "string" ? void 0 : source;
|
|
5618
|
-
const dbPath3 =
|
|
5795
|
+
const dbPath3 = path13.resolve(typeof source === "string" ? source : source.path);
|
|
5619
5796
|
const sessionId = options.sessionId ?? src?.sessionId ?? "";
|
|
5620
5797
|
const unknownTypes = {};
|
|
5621
5798
|
const empty = (reason) => {
|
|
@@ -5721,7 +5898,7 @@ async function parse(source, options = {}) {
|
|
|
5721
5898
|
harness: "opencode",
|
|
5722
5899
|
sourcePath: dbPath3,
|
|
5723
5900
|
project: directory ?? "",
|
|
5724
|
-
projectSlug: options.projectSlug ?? src?.projectSlug ?? (directory ?
|
|
5901
|
+
projectSlug: options.projectSlug ?? src?.projectSlug ?? (directory ? path13.basename(directory) : ""),
|
|
5725
5902
|
startedAt: isoOf(sessionRow?.["created"]) ?? firstTs ?? "",
|
|
5726
5903
|
endedAt: isoOf(sessionRow?.["updated"]) ?? lastTs ?? isoOf(sessionRow?.["created"]) ?? "",
|
|
5727
5904
|
...str3("title") ? { title: str3("title") } : {},
|
|
@@ -5917,7 +6094,7 @@ function doctorLine(override) {
|
|
|
5917
6094
|
}
|
|
5918
6095
|
const stores = findStores(override);
|
|
5919
6096
|
if (stores.length === 0) {
|
|
5920
|
-
const hasStorage = fs18.existsSync(
|
|
6097
|
+
const hasStorage = fs18.existsSync(path13.join(dir, "storage"));
|
|
5921
6098
|
return formatDoctorLine({
|
|
5922
6099
|
harness: "opencode",
|
|
5923
6100
|
status: "empty",
|
|
@@ -6040,7 +6217,7 @@ __export(copilot_exports, {
|
|
|
6040
6217
|
stateFileIn: () => stateFileIn
|
|
6041
6218
|
});
|
|
6042
6219
|
import fs19 from "node:fs";
|
|
6043
|
-
import
|
|
6220
|
+
import path14 from "node:path";
|
|
6044
6221
|
function sourceDir2(override) {
|
|
6045
6222
|
return copilotSessionStateDir(override);
|
|
6046
6223
|
}
|
|
@@ -6058,7 +6235,7 @@ function scan(override) {
|
|
|
6058
6235
|
return { sources, unreadable };
|
|
6059
6236
|
}
|
|
6060
6237
|
for (const entry of entries) {
|
|
6061
|
-
const full =
|
|
6238
|
+
const full = path14.join(root, entry.name);
|
|
6062
6239
|
if (entry.isDirectory()) {
|
|
6063
6240
|
const state = stateFileIn(full);
|
|
6064
6241
|
if (!state) {
|
|
@@ -6074,10 +6251,10 @@ function scan(override) {
|
|
|
6074
6251
|
}
|
|
6075
6252
|
if (!entry.isFile())
|
|
6076
6253
|
continue;
|
|
6077
|
-
const ext =
|
|
6254
|
+
const ext = path14.extname(entry.name).toLowerCase();
|
|
6078
6255
|
if (ext !== ".json" && ext !== ".jsonl")
|
|
6079
6256
|
continue;
|
|
6080
|
-
const src = sourceFor(full,
|
|
6257
|
+
const src = sourceFor(full, path14.basename(entry.name, ext));
|
|
6081
6258
|
if (src)
|
|
6082
6259
|
sources.push(src);
|
|
6083
6260
|
}
|
|
@@ -6087,7 +6264,7 @@ function scan(override) {
|
|
|
6087
6264
|
}
|
|
6088
6265
|
function stateFileIn(dir) {
|
|
6089
6266
|
for (const name of STATE_FILES) {
|
|
6090
|
-
const candidate =
|
|
6267
|
+
const candidate = path14.join(dir, name);
|
|
6091
6268
|
try {
|
|
6092
6269
|
if (fs19.statSync(candidate).isFile())
|
|
6093
6270
|
return candidate;
|
|
@@ -6121,7 +6298,7 @@ function sourceFor(file, sessionId) {
|
|
|
6121
6298
|
}
|
|
6122
6299
|
async function parse2(source, options = {}) {
|
|
6123
6300
|
const src = typeof source === "string" ? void 0 : source;
|
|
6124
|
-
const absolute2 =
|
|
6301
|
+
const absolute2 = path14.resolve(typeof source === "string" ? source : source.path);
|
|
6125
6302
|
const unknownTypes = {};
|
|
6126
6303
|
let malformedLines = 0;
|
|
6127
6304
|
let raw = "";
|
|
@@ -6163,7 +6340,7 @@ async function parse2(source, options = {}) {
|
|
|
6163
6340
|
// empty string because copilot's session-state directory is keyed by
|
|
6164
6341
|
// session, not by project — and an empty string is not nullish, so `??`
|
|
6165
6342
|
// would let it beat a slug we can actually derive from the cwd.
|
|
6166
|
-
projectSlug: options.projectSlug || src?.projectSlug || (cwd ?
|
|
6343
|
+
projectSlug: options.projectSlug || src?.projectSlug || (cwd ? path14.basename(cwd) : ""),
|
|
6167
6344
|
startedAt,
|
|
6168
6345
|
endedAt: endedAt < startedAt ? startedAt : endedAt,
|
|
6169
6346
|
...title ? { title } : {},
|
|
@@ -6182,17 +6359,17 @@ async function parse2(source, options = {}) {
|
|
|
6182
6359
|
return { session, exchanges: built.exchanges, unknownTypes, endOffset, malformedLines };
|
|
6183
6360
|
}
|
|
6184
6361
|
function sessionIdFromPath(file) {
|
|
6185
|
-
const ext =
|
|
6186
|
-
const base2 =
|
|
6187
|
-
if (STATE_FILES.includes(
|
|
6188
|
-
return
|
|
6362
|
+
const ext = path14.extname(file);
|
|
6363
|
+
const base2 = path14.basename(file, ext);
|
|
6364
|
+
if (STATE_FILES.includes(path14.basename(file))) {
|
|
6365
|
+
return path14.basename(path14.dirname(file));
|
|
6189
6366
|
}
|
|
6190
6367
|
return base2;
|
|
6191
6368
|
}
|
|
6192
6369
|
function readDocument(file, raw) {
|
|
6193
6370
|
if (!raw.trim())
|
|
6194
6371
|
return { turns: [], malformed: 0 };
|
|
6195
|
-
if (
|
|
6372
|
+
if (path14.extname(file).toLowerCase() === ".jsonl") {
|
|
6196
6373
|
const turns = [];
|
|
6197
6374
|
let meta;
|
|
6198
6375
|
let malformed = 0;
|
|
@@ -6517,10 +6694,10 @@ var init_copilot = __esm({
|
|
|
6517
6694
|
|
|
6518
6695
|
// packages/core/dist/memory/capabilities.js
|
|
6519
6696
|
import fs20 from "node:fs";
|
|
6520
|
-
import
|
|
6697
|
+
import path15 from "node:path";
|
|
6521
6698
|
import { createHash as createHash4 } from "node:crypto";
|
|
6522
6699
|
function inspectCaptureCapability(harness, root, discovered, failed) {
|
|
6523
|
-
const value = { version: 1, harness, rootHash: createHash4("sha256").update(
|
|
6700
|
+
const value = { version: 1, harness, rootHash: createHash4("sha256").update(path15.resolve(root)).digest("hex"), present: false, fidelity: ["claude", "codex"].includes(harness) ? "record" : "projection", state: "absent", codes: [], discovered, lastObservedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
6524
6701
|
try {
|
|
6525
6702
|
value.present = fs20.statSync(root).isDirectory();
|
|
6526
6703
|
} catch (error) {
|
|
@@ -6547,21 +6724,21 @@ function inspectCaptureCapability(harness, root, discovered, failed) {
|
|
|
6547
6724
|
if (harness === "copilot") {
|
|
6548
6725
|
let native = false;
|
|
6549
6726
|
try {
|
|
6550
|
-
native = fs20.statSync(
|
|
6727
|
+
native = fs20.statSync(path15.join(root, "session-store.db")).isFile();
|
|
6551
6728
|
} catch (error) {
|
|
6552
6729
|
if (error.code !== "ENOENT") {
|
|
6553
6730
|
value.state = "failed";
|
|
6554
6731
|
value.codes.push("native_store_probe_failed");
|
|
6555
6732
|
}
|
|
6556
6733
|
}
|
|
6557
|
-
const sessions =
|
|
6734
|
+
const sessions = path15.join(root, "session-state");
|
|
6558
6735
|
if (fs20.existsSync(sessions))
|
|
6559
6736
|
for (const entry of fs20.readdirSync(sessions, { withFileTypes: true })) {
|
|
6560
|
-
if (entry.isDirectory() && fs20.existsSync(
|
|
6737
|
+
if (entry.isDirectory() && fs20.existsSync(path15.join(sessions, entry.name, "workspace.yaml")) && !stateFileIn(path15.join(sessions, entry.name)))
|
|
6561
6738
|
native = true;
|
|
6562
6739
|
}
|
|
6563
6740
|
if (native) {
|
|
6564
|
-
value.layoutFingerprint = nativeFingerprint(
|
|
6741
|
+
value.layoutFingerprint = nativeFingerprint(path15.join(root, "session-store.db"));
|
|
6565
6742
|
value.state = "unsupported";
|
|
6566
6743
|
value.codes.push("copilot_native_conversations_unread");
|
|
6567
6744
|
} else if (discovered) {
|
|
@@ -6637,7 +6814,7 @@ function storedCaptureLimitations(db, sourceIds, harnesses) {
|
|
|
6637
6814
|
}
|
|
6638
6815
|
const health = JSON.parse(saved.value);
|
|
6639
6816
|
const root = enrollment.options[names[harness]];
|
|
6640
|
-
if (!root || health.rootHash !== createHash4("sha256").update(
|
|
6817
|
+
if (!root || health.rootHash !== createHash4("sha256").update(path15.resolve(root)).digest("hex")) {
|
|
6641
6818
|
incomplete = true;
|
|
6642
6819
|
codes.push(`${harness}:capture_capability_unverified`);
|
|
6643
6820
|
continue;
|
|
@@ -7440,7 +7617,7 @@ var init_redact = __esm({
|
|
|
7440
7617
|
|
|
7441
7618
|
// packages/core/dist/memory/privacy.js
|
|
7442
7619
|
import { createHash as createHash6 } from "node:crypto";
|
|
7443
|
-
function
|
|
7620
|
+
function inspect2(text2, normalizationVersion) {
|
|
7444
7621
|
if (normalizationVersion === NORMALIZATION_VERSION)
|
|
7445
7622
|
return { unsafe: false, ranges: [] };
|
|
7446
7623
|
const key2 = createHash6("sha256").update(text2).digest("hex");
|
|
@@ -7455,10 +7632,10 @@ function inspect(text2, normalizationVersion) {
|
|
|
7455
7632
|
return result;
|
|
7456
7633
|
}
|
|
7457
7634
|
function requiresPrivacyRefresh(text2, normalizationVersion) {
|
|
7458
|
-
return
|
|
7635
|
+
return inspect2(text2, normalizationVersion).unsafe;
|
|
7459
7636
|
}
|
|
7460
7637
|
function privacyAffectedRange(text2, start, end, normalizationVersion) {
|
|
7461
|
-
return
|
|
7638
|
+
return inspect2(text2, normalizationVersion).ranges.some((range) => range.start < end && range.end > start);
|
|
7462
7639
|
}
|
|
7463
7640
|
var NORMALIZATION_VERSION, MemoryPrivacyError, checks;
|
|
7464
7641
|
var init_privacy = __esm({
|
|
@@ -7998,7 +8175,7 @@ function inspectCoverage(db, scope2 = {}, semantic = "disabled", capabilityScope
|
|
|
7998
8175
|
const historical = scopeSql({ ...scope2, learnedBy: void 0, includeHistory: true });
|
|
7999
8176
|
unknownHistory = db.prepare(`SELECT COUNT(DISTINCT s.source_id) n ${join} LEFT JOIN source_activation_baselines b ON b.source_id=s.source_id WHERE ${historical.sql} AND (b.source_id IS NULL OR (b.history_complete=0 AND b.known_from>?))`).get(...historical.params, new Date(scope2.learnedBy).toISOString()).n;
|
|
8000
8177
|
}
|
|
8001
|
-
const fallback = Boolean(db.prepare(`SELECT 1
|
|
8178
|
+
const fallback = Boolean(db.prepare(`SELECT 1 FROM evidence_spans p WHERE p.chunk_policy='span-conservative-utf8-v1' AND EXISTS(SELECT 1 FROM revision_spans rs JOIN source_revisions r ON r.revision_id=rs.revision_id JOIN memory_sources s ON s.source_id=r.source_id JOIN revision_units ru ON ru.revision_id=r.revision_id AND ru.unit_revision_id=p.unit_revision_id JOIN evidence_units u ON u.unit_revision_id=ru.unit_revision_id WHERE rs.span_id=p.span_id AND ${filter.sql}) LIMIT 1`).get(...filter.params));
|
|
8002
8179
|
let unknownEventTimes = 0;
|
|
8003
8180
|
if (scope2.eventFrom || scope2.asOf) {
|
|
8004
8181
|
const unbounded = scopeSql({ ...scope2, eventFrom: void 0, asOf: void 0 });
|
|
@@ -8794,7 +8971,7 @@ var init_keyphrase = __esm({
|
|
|
8794
8971
|
|
|
8795
8972
|
// packages/core/dist/ignore.js
|
|
8796
8973
|
import fs21 from "node:fs";
|
|
8797
|
-
import
|
|
8974
|
+
import path16 from "node:path";
|
|
8798
8975
|
function readIgnoreConfig(root = potsherdDir()) {
|
|
8799
8976
|
const file = configPath(root);
|
|
8800
8977
|
let text2;
|
|
@@ -8842,7 +9019,7 @@ function writeIgnoreList(root, list) {
|
|
|
8842
9019
|
}
|
|
8843
9020
|
const next = { ...current.rest, [IGNORE_KEY]: clean4 };
|
|
8844
9021
|
const file = current.file;
|
|
8845
|
-
fs21.mkdirSync(
|
|
9022
|
+
fs21.mkdirSync(path16.dirname(file), { recursive: true, mode: 448 });
|
|
8846
9023
|
const tmp = `${file}.tmp-${String(process.pid)}`;
|
|
8847
9024
|
fs21.writeFileSync(tmp, `${JSON.stringify(next, null, 2)}
|
|
8848
9025
|
`, { mode: 384 });
|
|
@@ -8902,7 +9079,7 @@ function rootForDb(db) {
|
|
|
8902
9079
|
const file = main2?.file;
|
|
8903
9080
|
if (!file)
|
|
8904
9081
|
return null;
|
|
8905
|
-
return
|
|
9082
|
+
return path16.dirname(file);
|
|
8906
9083
|
} catch {
|
|
8907
9084
|
return null;
|
|
8908
9085
|
}
|
|
@@ -8992,8 +9169,8 @@ import { createRequire as createRequire3 } from "node:module";
|
|
|
8992
9169
|
import { spawn } from "node:child_process";
|
|
8993
9170
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
8994
9171
|
import fs22 from "node:fs";
|
|
8995
|
-
import
|
|
8996
|
-
import
|
|
9172
|
+
import os6 from "node:os";
|
|
9173
|
+
import path17 from "node:path";
|
|
8997
9174
|
import process8 from "node:process";
|
|
8998
9175
|
function modelClass(model) {
|
|
8999
9176
|
const m = model.toLowerCase();
|
|
@@ -9206,10 +9383,10 @@ function detectBackend(o = {}) {
|
|
|
9206
9383
|
return choose(rung.backend, rung, `rung ${rung.rung} \u2014 ${rung.label}: ${where}${seam}`, rung.backend === "codex" ? avail.codex ?? void 0 : avail.claude ?? void 0);
|
|
9207
9384
|
}
|
|
9208
9385
|
function makeScratch(tmpRoot) {
|
|
9209
|
-
return fs22.mkdtempSync(
|
|
9386
|
+
return fs22.mkdtempSync(path17.join(tmpRoot ?? os6.tmpdir(), "potsherd-llm-"));
|
|
9210
9387
|
}
|
|
9211
9388
|
function stableScratch(tmpRoot) {
|
|
9212
|
-
const dir =
|
|
9389
|
+
const dir = path17.join(tmpRoot ?? os6.tmpdir(), CLAUDE_CWD_NAME);
|
|
9213
9390
|
fs22.mkdirSync(dir, { recursive: true });
|
|
9214
9391
|
return dir;
|
|
9215
9392
|
}
|
|
@@ -9370,7 +9547,7 @@ function run(bin, args, o) {
|
|
|
9370
9547
|
return;
|
|
9371
9548
|
settled = true;
|
|
9372
9549
|
killBackendTree(child);
|
|
9373
|
-
reject(new LlmError(`${
|
|
9550
|
+
reject(new LlmError(`${path17.basename(bin)} did not answer within ${Math.round(o.timeoutMs / 1e3)}s`, `POTSHERD_LLM_TIMEOUT_MS=${DEFAULT_TIMEOUT_MS * 2} potsherd card \u2026`, void 0, { timedOut: true }));
|
|
9374
9551
|
}, o.timeoutMs);
|
|
9375
9552
|
const onAbort = () => {
|
|
9376
9553
|
if (settled)
|
|
@@ -9388,7 +9565,7 @@ function run(bin, args, o) {
|
|
|
9388
9565
|
return;
|
|
9389
9566
|
settled = true;
|
|
9390
9567
|
clearTimeout(timer);
|
|
9391
|
-
reject(new LlmError(`could not run ${bin}: ${errMessage(err)}`, `which ${
|
|
9568
|
+
reject(new LlmError(`could not run ${bin}: ${errMessage(err)}`, `which ${path17.basename(bin)}`, err));
|
|
9392
9569
|
});
|
|
9393
9570
|
child.on("close", (code) => {
|
|
9394
9571
|
if (settled)
|
|
@@ -9397,7 +9574,7 @@ function run(bin, args, o) {
|
|
|
9397
9574
|
clearTimeout(timer);
|
|
9398
9575
|
o.signal?.removeEventListener("abort", onAbort);
|
|
9399
9576
|
if (code !== 0) {
|
|
9400
|
-
reject(new LlmError(`${
|
|
9577
|
+
reject(new LlmError(`${path17.basename(bin)} exited ${code}${stderr.trim() ? `: ${stderr.trim().split("\n").slice(-1)[0]}` : ""}`, `${path17.basename(bin)} --version`, void 0, { stdout }));
|
|
9401
9578
|
return;
|
|
9402
9579
|
}
|
|
9403
9580
|
resolve({ stdout, stderr, code: code ?? 0 });
|
|
@@ -9813,7 +9990,7 @@ var init_llm = __esm({
|
|
|
9813
9990
|
let result = null;
|
|
9814
9991
|
const stderr = [];
|
|
9815
9992
|
try {
|
|
9816
|
-
const
|
|
9993
|
+
const stream2 = query({
|
|
9817
9994
|
prompt: req.prompt,
|
|
9818
9995
|
options: {
|
|
9819
9996
|
model: req.model,
|
|
@@ -9839,7 +10016,7 @@ var init_llm = __esm({
|
|
|
9839
10016
|
}
|
|
9840
10017
|
}
|
|
9841
10018
|
});
|
|
9842
|
-
for await (const message2 of
|
|
10019
|
+
for await (const message2 of stream2) {
|
|
9843
10020
|
if (message2.type === "result") {
|
|
9844
10021
|
if (message2.subtype === "success") {
|
|
9845
10022
|
text2 = message2.result;
|
|
@@ -9959,7 +10136,7 @@ var init_llm = __esm({
|
|
|
9959
10136
|
async send(req) {
|
|
9960
10137
|
this.scratch ??= makeScratch(this.opts.tmpRoot);
|
|
9961
10138
|
const extra = (this.opts.env["POTSHERD_CODEX_ARGS"] ?? "").split(" ").filter(Boolean);
|
|
9962
|
-
const lastMessage =
|
|
10139
|
+
const lastMessage = path17.join(this.scratch, `last-message-${randomUUID4()}.txt`);
|
|
9963
10140
|
const codexModel = this.opts.env["POTSHERD_CODEX_MODEL"]?.trim() || (MODEL_ALIASES.includes(req.model) ? void 0 : req.model);
|
|
9964
10141
|
const args = [
|
|
9965
10142
|
"exec",
|
|
@@ -11695,7 +11872,7 @@ var init_recall = __esm({
|
|
|
11695
11872
|
|
|
11696
11873
|
// packages/core/dist/rescue.js
|
|
11697
11874
|
import fs23 from "node:fs";
|
|
11698
|
-
import
|
|
11875
|
+
import path18 from "node:path";
|
|
11699
11876
|
import crypto4 from "node:crypto";
|
|
11700
11877
|
async function rescue(opts = {}) {
|
|
11701
11878
|
const root = opts.root ?? potsherdDir();
|
|
@@ -11706,7 +11883,7 @@ async function rescueUnlocked(opts, root) {
|
|
|
11706
11883
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
11707
11884
|
const src = claudeDir(opts.claudeDir);
|
|
11708
11885
|
const cp = claudePaths(src);
|
|
11709
|
-
const dest =
|
|
11886
|
+
const dest = path18.join(archiveDir(root), HARNESS);
|
|
11710
11887
|
const result = {
|
|
11711
11888
|
ranAt: now.toISOString(),
|
|
11712
11889
|
dryRun: Boolean(opts.dryRun),
|
|
@@ -11772,12 +11949,12 @@ function copyPass(db, projectsDir, historyPath, dest, result, opts) {
|
|
|
11772
11949
|
let done = 0;
|
|
11773
11950
|
const forgotten = new Set(db.prepare("SELECT s.native_session_id FROM memory_sources s JOIN forget_tombstones t ON t.source_id=s.source_id WHERE s.harness='claude' AND t.state<>'reversed'").all().map((r) => r.native_session_id));
|
|
11774
11951
|
for (const f of files) {
|
|
11775
|
-
if (forgotten.has(
|
|
11952
|
+
if (forgotten.has(path18.basename(f.abs, ".jsonl")))
|
|
11776
11953
|
continue;
|
|
11777
11954
|
result.filesConsidered++;
|
|
11778
11955
|
done++;
|
|
11779
|
-
opts.onProgress?.({ phase: "copy", done, total: files.length, label:
|
|
11780
|
-
const target =
|
|
11956
|
+
opts.onProgress?.({ phase: "copy", done, total: files.length, label: path18.basename(f.rel) });
|
|
11957
|
+
const target = path18.join(dest, f.rel);
|
|
11781
11958
|
let stat;
|
|
11782
11959
|
try {
|
|
11783
11960
|
stat = fs23.statSync(f.abs);
|
|
@@ -11818,7 +11995,7 @@ function copyPass(db, projectsDir, historyPath, dest, result, opts) {
|
|
|
11818
11995
|
}
|
|
11819
11996
|
if (!opts.dryRun) {
|
|
11820
11997
|
try {
|
|
11821
|
-
fs23.mkdirSync(
|
|
11998
|
+
fs23.mkdirSync(path18.dirname(target), { recursive: true, mode: 448 });
|
|
11822
11999
|
const tmp = `${target}.potsherd-tmp`;
|
|
11823
12000
|
fs23.copyFileSync(f.abs, tmp);
|
|
11824
12001
|
if (safeSize(tmp) !== stat.size || sha256File(tmp) !== sha)
|
|
@@ -11832,7 +12009,7 @@ function copyPass(db, projectsDir, historyPath, dest, result, opts) {
|
|
|
11832
12009
|
fs23.closeSync(fd);
|
|
11833
12010
|
}
|
|
11834
12011
|
fs23.renameSync(tmp, target);
|
|
11835
|
-
const parent = fs23.openSync(
|
|
12012
|
+
const parent = fs23.openSync(path18.dirname(target), "r");
|
|
11836
12013
|
try {
|
|
11837
12014
|
fs23.fsyncSync(parent);
|
|
11838
12015
|
} finally {
|
|
@@ -11864,33 +12041,33 @@ function collectSourceFiles(projectsDir) {
|
|
|
11864
12041
|
if (!slugEntry.isDirectory())
|
|
11865
12042
|
continue;
|
|
11866
12043
|
const slug = slugEntry.name;
|
|
11867
|
-
const dir =
|
|
12044
|
+
const dir = path18.join(projectsDir, slug);
|
|
11868
12045
|
for (const e of readdirSafe2(dir, true)) {
|
|
11869
12046
|
if (e.isFile()) {
|
|
11870
12047
|
if (e.name.endsWith(".jsonl")) {
|
|
11871
|
-
out.push({ abs:
|
|
12048
|
+
out.push({ abs: path18.join(dir, e.name), rel: path18.join(slug, e.name), kind: "session" });
|
|
11872
12049
|
} else if (e.name === "sessions-index.json") {
|
|
11873
|
-
out.push({ abs:
|
|
12050
|
+
out.push({ abs: path18.join(dir, e.name), rel: path18.join(slug, e.name), kind: "index" });
|
|
11874
12051
|
}
|
|
11875
12052
|
} else if (e.isDirectory()) {
|
|
11876
12053
|
if (e.name === "memory") {
|
|
11877
|
-
for (const m of readdirSafe2(
|
|
12054
|
+
for (const m of readdirSafe2(path18.join(dir, "memory"))) {
|
|
11878
12055
|
out.push({
|
|
11879
|
-
abs:
|
|
11880
|
-
rel:
|
|
12056
|
+
abs: path18.join(dir, "memory", m),
|
|
12057
|
+
rel: path18.join(slug, "memory", m),
|
|
11881
12058
|
kind: "memory"
|
|
11882
12059
|
});
|
|
11883
12060
|
}
|
|
11884
12061
|
} else {
|
|
11885
12062
|
const nested = e.name === SIDECHAIN_DIR;
|
|
11886
|
-
const subDir = nested ?
|
|
11887
|
-
const relDir = nested ?
|
|
12063
|
+
const subDir = nested ? path18.join(dir, e.name) : path18.join(dir, e.name, SIDECHAIN_DIR);
|
|
12064
|
+
const relDir = nested ? path18.join(slug, e.name) : path18.join(slug, e.name, SIDECHAIN_DIR);
|
|
11888
12065
|
for (const s of readdirSafe2(subDir)) {
|
|
11889
12066
|
if (!s.endsWith(".jsonl"))
|
|
11890
12067
|
continue;
|
|
11891
12068
|
out.push({
|
|
11892
|
-
abs:
|
|
11893
|
-
rel:
|
|
12069
|
+
abs: path18.join(subDir, s),
|
|
12070
|
+
rel: path18.join(relDir, s),
|
|
11894
12071
|
kind: "sidechain"
|
|
11895
12072
|
});
|
|
11896
12073
|
}
|
|
@@ -11964,7 +12141,7 @@ function ghostFingerprint(historyPath, disk) {
|
|
|
11964
12141
|
const ids = disk.sessions.map((s) => s.sessionId).sort();
|
|
11965
12142
|
parts.push(`sessions:${ids.length}:${crypto4.createHash("sha256").update(ids.join("\n")).digest("hex")}`);
|
|
11966
12143
|
for (const proj of (disk.projects ?? []).filter((p) => p.hasSessionsIndex)) {
|
|
11967
|
-
const p =
|
|
12144
|
+
const p = path18.join(proj.dir, "sessions-index.json");
|
|
11968
12145
|
try {
|
|
11969
12146
|
const st = fs23.statSync(p);
|
|
11970
12147
|
parts.push(`index:${p}:${st.size}:${Math.floor(st.mtimeMs)}`);
|
|
@@ -13150,12 +13327,14 @@ function assertResponseFormat(transport, format2) {
|
|
|
13150
13327
|
if (format2 === "compact-v1" && (transport === "human" || typeof transport === "object"))
|
|
13151
13328
|
throw new RangeError("Compact response format requires JSON transport");
|
|
13152
13329
|
}
|
|
13153
|
-
function finalizeEmission(value, transport = "json", format2 = "expanded-v2") {
|
|
13330
|
+
function finalizeEmission(value, transport = "json", format2 = "expanded-v2", prefix3 = "") {
|
|
13154
13331
|
assertResponseFormat(transport, format2);
|
|
13332
|
+
if (prefix3.length > 32 || /[^ \t\r\n]/u.test(prefix3))
|
|
13333
|
+
throw new RangeError("Invalid emission whitespace");
|
|
13155
13334
|
if (transport === "human" || typeof transport === "object")
|
|
13156
|
-
return Object.freeze({ kind: "human", format: "expanded-v2", serialized: serializeResponse(value, transport) });
|
|
13335
|
+
return Object.freeze({ kind: "human", format: "expanded-v2", serialized: prefix3 + serializeResponse(value, transport) });
|
|
13157
13336
|
const body = format2 === "compact-v1" && value && typeof value === "object" && "evidence" in value ? encodeCompactMemoryPacket(value) : value;
|
|
13158
|
-
const text2 = JSON.stringify(body);
|
|
13337
|
+
const text2 = prefix3 + JSON.stringify(body);
|
|
13159
13338
|
if (transport === "mcp") {
|
|
13160
13339
|
const block2 = Object.freeze({ type: "text", text: text2 });
|
|
13161
13340
|
const result = { content: [block2] };
|
|
@@ -13165,6 +13344,35 @@ function finalizeEmission(value, transport = "json", format2 = "expanded-v2") {
|
|
|
13165
13344
|
}
|
|
13166
13345
|
return Object.freeze({ kind: transport, format: format2, serialized: transport === "cli_json" ? text2 + "\n" : text2 });
|
|
13167
13346
|
}
|
|
13347
|
+
function settleEmission(value, limit, byteLimit, transport, format2 = "expanded-v2") {
|
|
13348
|
+
const initial = { usedTokens: value.budget.usedTokens, remainingTokens: value.budget.remainingTokens };
|
|
13349
|
+
let overCap = null;
|
|
13350
|
+
for (const prefix3 of RECEIPT_PREFIXES) {
|
|
13351
|
+
value.budget.usedTokens = initial.usedTokens;
|
|
13352
|
+
value.budget.remainingTokens = initial.remainingTokens;
|
|
13353
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13354
|
+
for (let i = 0; i < 32; i++) {
|
|
13355
|
+
const state = `${value.budget.usedTokens}:${value.budget.remainingTokens}`;
|
|
13356
|
+
if (seen.has(state))
|
|
13357
|
+
break;
|
|
13358
|
+
seen.add(state);
|
|
13359
|
+
const emission = finalizeEmission(value, transport, format2, prefix3), serialized = emission.serialized, tokens = countTokens(serialized), remaining = Math.max(0, limit - tokens);
|
|
13360
|
+
if (value.budget.usedTokens === tokens && value.budget.remainingTokens === remaining) {
|
|
13361
|
+
const payload = { emission, serialized, tokens, bytes: Buffer.byteLength(serialized) };
|
|
13362
|
+
if (prefix3 === "" || tokens <= limit && payload.bytes <= byteLimit)
|
|
13363
|
+
return payload;
|
|
13364
|
+
if (!overCap)
|
|
13365
|
+
overCap = { payload, usedTokens: tokens, remainingTokens: remaining };
|
|
13366
|
+
break;
|
|
13367
|
+
}
|
|
13368
|
+
value.budget.usedTokens = tokens;
|
|
13369
|
+
value.budget.remainingTokens = remaining;
|
|
13370
|
+
}
|
|
13371
|
+
}
|
|
13372
|
+
value.budget.usedTokens = overCap?.usedTokens ?? initial.usedTokens;
|
|
13373
|
+
value.budget.remainingTokens = overCap?.remainingTokens ?? initial.remainingTokens;
|
|
13374
|
+
return overCap?.payload ?? null;
|
|
13375
|
+
}
|
|
13168
13376
|
function serializeResponse(value, transport = "json") {
|
|
13169
13377
|
if (transport === "human" || typeof transport === "object") {
|
|
13170
13378
|
const text3 = renderMemory(value);
|
|
@@ -13357,18 +13565,7 @@ function planResponse(original, budget2, options = {}) {
|
|
|
13357
13565
|
});
|
|
13358
13566
|
return protectedKeys.length;
|
|
13359
13567
|
};
|
|
13360
|
-
const settle = () =>
|
|
13361
|
-
for (let i = 0; i < 32; i++) {
|
|
13362
|
-
const emission = finalizeEmission(response2, transport, format2), encoded = emission.serialized;
|
|
13363
|
-
const tokens = countTokens(encoded);
|
|
13364
|
-
if (response2.budget.usedTokens === tokens && response2.budget.remainingTokens === Math.max(0, limit - tokens)) {
|
|
13365
|
-
return { emission, serialized: encoded, tokens, bytes: Buffer.byteLength(encoded) };
|
|
13366
|
-
}
|
|
13367
|
-
response2.budget.usedTokens = tokens;
|
|
13368
|
-
response2.budget.remainingTokens = Math.max(0, limit - tokens);
|
|
13369
|
-
}
|
|
13370
|
-
throw new Error("Token receipt did not converge");
|
|
13371
|
-
};
|
|
13568
|
+
const settle = () => settleEmission(response2, limit, byteLimit, transport, format2);
|
|
13372
13569
|
if (!nav)
|
|
13373
13570
|
response2.candidates = response2.candidates.map(({ evidence: _e, ...candidate }) => candidate);
|
|
13374
13571
|
for (; ; ) {
|
|
@@ -13400,7 +13597,7 @@ function planResponse(original, budget2, options = {}) {
|
|
|
13400
13597
|
delete response2.continuation;
|
|
13401
13598
|
}
|
|
13402
13599
|
let payload = settle();
|
|
13403
|
-
if (payload.tokens <= limit && payload.bytes <= byteLimit) {
|
|
13600
|
+
if (payload && payload.tokens <= limit && payload.bytes <= byteLimit) {
|
|
13404
13601
|
if (nav && !mechanical && response2.coverage.state === "complete_snapshot") {
|
|
13405
13602
|
const exposed = /* @__PURE__ */ new Set([...response2.evidence.map((item2) => refKey(item2.ref)), ...response2.candidates.map((candidate) => refKey(candidate.ref))]);
|
|
13406
13603
|
for (const key2 of initialEvidence) {
|
|
@@ -13412,7 +13609,7 @@ function planResponse(original, budget2, options = {}) {
|
|
|
13412
13609
|
response2.candidates.push({ ref: structuredClone(candidate.ref), score: candidate.score, lanes: [...candidate.lanes] });
|
|
13413
13610
|
response2.budget.omittedItems--;
|
|
13414
13611
|
const proposed = settle();
|
|
13415
|
-
if (proposed.tokens <= limit && proposed.bytes <= byteLimit) {
|
|
13612
|
+
if (proposed && proposed.tokens <= limit && proposed.bytes <= byteLimit) {
|
|
13416
13613
|
payload = proposed;
|
|
13417
13614
|
exposed.add(key2);
|
|
13418
13615
|
} else {
|
|
@@ -13488,23 +13685,16 @@ function planWriteReceipt(receipt4, budget2 = defaultBudget(), transport = "json
|
|
|
13488
13685
|
throw new RangeError("Unsupported transport tokenizer");
|
|
13489
13686
|
const limit = Math.min(budget2.maxTokens, budget2.remainingJourneyTokens ?? budget2.maxTokens);
|
|
13490
13687
|
const value = { ...receipt4, budget: { tokenizerId: TOKENIZER_ID, usedTokens: 0, remainingTokens: 0, truncated: false, omittedItems: 0 } };
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
if (used2 <= limit && Buffer.byteLength(encoded2) <= (budget2.maxBytes ?? DEFAULT_RESPONSE_BYTES))
|
|
13495
|
-
return { response: value, emission: emission2, serialized: encoded2, usedTokens: used2, usedBytes: Buffer.byteLength(encoded2) };
|
|
13496
|
-
break;
|
|
13497
|
-
}
|
|
13498
|
-
value.budget.usedTokens = used2;
|
|
13499
|
-
value.budget.remainingTokens = Math.max(0, limit - used2);
|
|
13500
|
-
}
|
|
13688
|
+
const settled = settleEmission(value, limit, budget2.maxBytes ?? DEFAULT_RESPONSE_BYTES, transport);
|
|
13689
|
+
if (settled && settled.tokens <= limit && settled.bytes <= (budget2.maxBytes ?? DEFAULT_RESPONSE_BYTES))
|
|
13690
|
+
return { response: value, emission: settled.emission, serialized: settled.serialized, usedTokens: settled.tokens, usedBytes: settled.bytes };
|
|
13501
13691
|
const error = { error: "write_receipt_over_budget", committed: true, requestKey: receipt4.requestKey };
|
|
13502
13692
|
const emission = finalizeEmission(error, transport), encoded = emission.serialized, used = countTokens(encoded);
|
|
13503
13693
|
if (used > limit || Buffer.byteLength(encoded) > (budget2.maxBytes ?? DEFAULT_RESPONSE_BYTES))
|
|
13504
13694
|
throw new RangeError("Budget cannot encode durable write acknowledgement");
|
|
13505
13695
|
return { response: error, emission, serialized: encoded, usedTokens: used, usedBytes: Buffer.byteLength(encoded) };
|
|
13506
13696
|
}
|
|
13507
|
-
var TOKENIZER_ASSET_HASH, TOKENIZER_ID, DEFAULT_RESPONSE_TOKENS, DEFAULT_RESPONSE_BYTES, tokenizer, INSPECT_ROUTE_LIMIT, INSPECT_SEEDS, INSPECT_PREVIEW_TOKENS, PREVIEW_SCAN_CHARACTERS, PREVIEW_WINDOW_CHARACTERS, PREVIEW_ANCHORS;
|
|
13697
|
+
var TOKENIZER_ASSET_HASH, TOKENIZER_ID, DEFAULT_RESPONSE_TOKENS, DEFAULT_RESPONSE_BYTES, tokenizer, RECEIPT_PREFIXES, INSPECT_ROUTE_LIMIT, INSPECT_SEEDS, INSPECT_PREVIEW_TOKENS, PREVIEW_SCAN_CHARACTERS, PREVIEW_WINDOW_CHARACTERS, PREVIEW_ANCHORS;
|
|
13508
13698
|
var init_budget = __esm({
|
|
13509
13699
|
"packages/core/dist/memory/budget.js"() {
|
|
13510
13700
|
"use strict";
|
|
@@ -13520,6 +13710,7 @@ var init_budget = __esm({
|
|
|
13520
13710
|
DEFAULT_RESPONSE_TOKENS = 4096;
|
|
13521
13711
|
DEFAULT_RESPONSE_BYTES = 65536;
|
|
13522
13712
|
tokenizer = new Tiktoken(cl100k_base_default);
|
|
13713
|
+
RECEIPT_PREFIXES = ["", "\n", "\n\n", " \n", "\n ", " ", " \n", "\n ", "\r\n", "\n \n", " \n ", "\n \n", "\n\n\n", " \n \n", " \n", "\r\n\r\n"];
|
|
13523
13714
|
INSPECT_ROUTE_LIMIT = 8;
|
|
13524
13715
|
INSPECT_SEEDS = 3;
|
|
13525
13716
|
INSPECT_PREVIEW_TOKENS = 32;
|
|
@@ -14511,7 +14702,7 @@ var init_service = __esm({
|
|
|
14511
14702
|
|
|
14512
14703
|
// packages/core/dist/analytics/source.js
|
|
14513
14704
|
import fs25 from "node:fs";
|
|
14514
|
-
import
|
|
14705
|
+
import path19 from "node:path";
|
|
14515
14706
|
import { createHash as createHash8 } from "node:crypto";
|
|
14516
14707
|
function boundedBytes(file, max2) {
|
|
14517
14708
|
const fd = fs25.openSync(file, "r");
|
|
@@ -14556,7 +14747,7 @@ async function* walk(root, maxEntries, signal, maxDepth = 8) {
|
|
|
14556
14747
|
return;
|
|
14557
14748
|
if (++visited > maxEntries)
|
|
14558
14749
|
throw new Error("discovery_entries_limit");
|
|
14559
|
-
const file =
|
|
14750
|
+
const file = path19.join(dir, item.name);
|
|
14560
14751
|
if (item.isDirectory())
|
|
14561
14752
|
yield* visit(file, depth + 1);
|
|
14562
14753
|
else if (item.isFile())
|
|
@@ -14575,7 +14766,7 @@ async function nativeFacts(file, harness, bytes3, maxRecords) {
|
|
|
14575
14766
|
const events = [];
|
|
14576
14767
|
const gaps = /* @__PURE__ */ new Set();
|
|
14577
14768
|
let project = null, parent = null, title = null;
|
|
14578
|
-
let nativeId =
|
|
14769
|
+
let nativeId = path19.basename(file, ".jsonl"), consumed = 0, records = 0, turn = null, programmatic = false;
|
|
14579
14770
|
const identity4 = /* @__PURE__ */ new Map();
|
|
14580
14771
|
const responses = [];
|
|
14581
14772
|
const markers = [];
|
|
@@ -14615,7 +14806,7 @@ async function nativeFacts(file, harness, bytes3, maxRecords) {
|
|
|
14615
14806
|
const base2 = { key: key2, rawStart: line2.start, rawEnd: line2.end, role: "user", eventAt: at2, project };
|
|
14616
14807
|
const maintenance = (text2) => hasExclusionMarker(text2);
|
|
14617
14808
|
if (harness === "claude") {
|
|
14618
|
-
if (typeof r.sessionId === "string" && !file.includes(`${
|
|
14809
|
+
if (typeof r.sessionId === "string" && !file.includes(`${path19.sep}subagents${path19.sep}`))
|
|
14619
14810
|
nativeId = r.sessionId;
|
|
14620
14811
|
if (typeof r.entrypoint === "string") {
|
|
14621
14812
|
if (r.entrypoint === "sdk-ts")
|
|
@@ -14623,7 +14814,7 @@ async function nativeFacts(file, harness, bytes3, maxRecords) {
|
|
|
14623
14814
|
else if (["cli", "desktop", "vscode"].includes(r.entrypoint))
|
|
14624
14815
|
programmatic = false;
|
|
14625
14816
|
}
|
|
14626
|
-
if (file.includes(`${
|
|
14817
|
+
if (file.includes(`${path19.sep}subagents${path19.sep}`) || r.isSidechain === true) {
|
|
14627
14818
|
parent = typeof r.sessionId === "string" ? r.sessionId : parent;
|
|
14628
14819
|
}
|
|
14629
14820
|
if (r.type === "ai-title" && typeof r.aiTitle === "string")
|
|
@@ -14655,7 +14846,7 @@ async function nativeFacts(file, harness, bytes3, maxRecords) {
|
|
|
14655
14846
|
gaps.add("human_attestation_unavailable");
|
|
14656
14847
|
if (explicitMeta && !parent)
|
|
14657
14848
|
gaps.add("explicit_meta_or_synthetic_origin_unattested");
|
|
14658
|
-
put2({ ...base2, text: clean(text2), origin: native && !declared && !programmatic && !explicitMeta ? "claude_prompt_id" : "unknown", eligible: native && excluded === null, excluded, identity: native && !explicitMeta ? `prompt:${r.promptId}` : `record:${key2}`, ...typeof r.uuid === "string" && r.uuid.length > 0 ? { nativeRecordId: r.uuid, recordCommitment:
|
|
14849
|
+
put2({ ...base2, text: clean(text2), origin: native && !declared && !programmatic && !explicitMeta ? "claude_prompt_id" : "unknown", eligible: native && excluded === null, excluded, identity: native && !explicitMeta ? `prompt:${r.promptId}` : `record:${key2}`, ...typeof r.uuid === "string" && r.uuid.length > 0 ? { nativeRecordId: r.uuid, recordCommitment: digest(JSON.stringify(stable2(recordCopy))) } : {}, ...declared ? { declaredOrigin: declared } : {} });
|
|
14659
14850
|
} else if (harness === "codex") {
|
|
14660
14851
|
if (r.type === "session_meta") {
|
|
14661
14852
|
nativeId = typeof p.session_id === "string" ? p.session_id : typeof p.id === "string" ? p.id : nativeId;
|
|
@@ -14735,7 +14926,7 @@ async function nativeFacts(file, harness, bytes3, maxRecords) {
|
|
|
14735
14926
|
}
|
|
14736
14927
|
}
|
|
14737
14928
|
if (parent && harness === "claude")
|
|
14738
|
-
nativeId = `${parent}:${
|
|
14929
|
+
nativeId = `${parent}:${path19.basename(file, ".jsonl")}`;
|
|
14739
14930
|
if (parent) {
|
|
14740
14931
|
for (const event of events) {
|
|
14741
14932
|
event.eligible = false;
|
|
@@ -14745,9 +14936,9 @@ async function nativeFacts(file, harness, bytes3, maxRecords) {
|
|
|
14745
14936
|
if (harness === "pi")
|
|
14746
14937
|
gaps.add("pi_exchange_projection_fidelity");
|
|
14747
14938
|
const complete = bytes3.subarray(0, consumed);
|
|
14748
|
-
return { nativeId, project, parent, child: parent !== null, title, events, gaps: [...gaps], hash:
|
|
14939
|
+
return { nativeId, project, parent, child: parent !== null, title, events, gaps: [...gaps], hash: digest(complete), consumed, bytes: complete };
|
|
14749
14940
|
}
|
|
14750
|
-
var
|
|
14941
|
+
var digest, clean, clock;
|
|
14751
14942
|
var init_source2 = __esm({
|
|
14752
14943
|
"packages/core/dist/analytics/source.js"() {
|
|
14753
14944
|
"use strict";
|
|
@@ -14756,7 +14947,7 @@ var init_source2 = __esm({
|
|
|
14756
14947
|
init_redact();
|
|
14757
14948
|
init_redact_elide();
|
|
14758
14949
|
init_markers();
|
|
14759
|
-
|
|
14950
|
+
digest = (value) => createHash8("sha256").update(value).digest("hex");
|
|
14760
14951
|
clean = (text2) => redact(elideBinary(text2)).text;
|
|
14761
14952
|
clock = (value) => typeof value === "string" && Number.isFinite(Date.parse(value)) ? new Date(value).toISOString() : null;
|
|
14762
14953
|
}
|
|
@@ -15315,7 +15506,7 @@ var init_language_models = __esm({
|
|
|
15315
15506
|
|
|
15316
15507
|
// packages/core/dist/analytics/derived-cache.js
|
|
15317
15508
|
import fs26 from "node:fs";
|
|
15318
|
-
import
|
|
15509
|
+
import path20 from "node:path";
|
|
15319
15510
|
import { createHash as createHash12, randomUUID as randomUUID6 } from "node:crypto";
|
|
15320
15511
|
function validDerivedBinding(v) {
|
|
15321
15512
|
if (!v || typeof v !== "object")
|
|
@@ -15357,7 +15548,7 @@ var init_derived_cache = __esm({
|
|
|
15357
15548
|
file(namespace, binding2) {
|
|
15358
15549
|
if (!/^[a-z0-9-]{1,64}$/.test(namespace) || !validDerivedBinding(binding2))
|
|
15359
15550
|
throw new Error("derived_cache_binding_invalid");
|
|
15360
|
-
return
|
|
15551
|
+
return path20.join(this.directory, `${namespace}-${derivedDigest(binding2.sourceId)}.json`);
|
|
15361
15552
|
}
|
|
15362
15553
|
read(namespace, binding2, validate3) {
|
|
15363
15554
|
const file = this.file(namespace, binding2);
|
|
@@ -15393,7 +15584,7 @@ var init_derived_cache = __esm({
|
|
|
15393
15584
|
if (!st.isDirectory() || st.isSymbolicLink())
|
|
15394
15585
|
throw new Error("derived_cache_directory_invalid");
|
|
15395
15586
|
fs26.chmodSync(this.directory, 448);
|
|
15396
|
-
const temp =
|
|
15587
|
+
const temp = path20.join(this.directory, `.launch-${randomUUID6()}.tmp`);
|
|
15397
15588
|
let fd;
|
|
15398
15589
|
try {
|
|
15399
15590
|
fd = fs26.openSync(temp, fs26.constants.O_WRONLY | fs26.constants.O_CREAT | fs26.constants.O_EXCL | fs26.constants.O_NOFOLLOW, 384);
|
|
@@ -15711,7 +15902,7 @@ function segmentContext(records, options = {}) {
|
|
|
15711
15902
|
promptIds,
|
|
15712
15903
|
coverage: segmentGaps.length ? "partial" : "complete",
|
|
15713
15904
|
gaps: segmentGaps,
|
|
15714
|
-
contentHash:
|
|
15905
|
+
contentHash: digest(JSON.stringify({ records: context.map(({ route: _, ...record4 }) => record4), promptIds }))
|
|
15715
15906
|
});
|
|
15716
15907
|
};
|
|
15717
15908
|
if (Buffer.byteLength(JSON.stringify(group)) <= max2) {
|
|
@@ -15917,7 +16108,7 @@ function abortable(promise, signal) {
|
|
|
15917
16108
|
});
|
|
15918
16109
|
});
|
|
15919
16110
|
}
|
|
15920
|
-
async function
|
|
16111
|
+
async function readBounded(response2, signal, maxBytes = 128e3) {
|
|
15921
16112
|
const reader = response2.body?.getReader();
|
|
15922
16113
|
if (!reader)
|
|
15923
16114
|
throw new JevFailure("invalid_response");
|
|
@@ -16097,7 +16288,7 @@ var init_free_jev = __esm({
|
|
|
16097
16288
|
} catch (e) {
|
|
16098
16289
|
return { state: "skipped", code: failure(e) };
|
|
16099
16290
|
}
|
|
16100
|
-
const route = this.provider.options.route, key2 =
|
|
16291
|
+
const route = this.provider.options.route, key2 = digest(JSON.stringify({ request, identity: identity4, route: { kind: route.kind, endpoint: FREE_JEV_ENDPOINT }, model: FREE_JEV_MODEL }));
|
|
16101
16292
|
try {
|
|
16102
16293
|
const cached4 = await abortable(Promise.resolve(this.provider.options.cache?.get(key2)), this.signal);
|
|
16103
16294
|
this.assertCurrent();
|
|
@@ -16159,7 +16350,7 @@ var init_free_jev = __esm({
|
|
|
16159
16350
|
}
|
|
16160
16351
|
throw new JevFailure(response2.status === 401 ? "free_access_denied" : response2.status === 429 ? "free_quota_unavailable" : "free_service_unavailable");
|
|
16161
16352
|
}
|
|
16162
|
-
const body = await
|
|
16353
|
+
const body = await readBounded(response2, controller.signal);
|
|
16163
16354
|
let raw;
|
|
16164
16355
|
try {
|
|
16165
16356
|
raw = JSON.parse(body);
|
|
@@ -16230,11 +16421,11 @@ function buildLaunchRequest(segment) {
|
|
|
16230
16421
|
const options = candidates(segment), target = new Set(segment.promptIds), choice = (items) => Object.fromEntries([["none", "No supplied candidate fits."], ...items.map((item) => [item.key, item.text])]);
|
|
16231
16422
|
const pool = (items) => items.length ? choice(items) : { none: "No supplied candidate fits.", unavailable: "No candidate source span is available." };
|
|
16232
16423
|
return { model: FREE_JEV_MODEL, state: {
|
|
16233
|
-
conversation:
|
|
16234
|
-
parent: segment.parentId === null ? null :
|
|
16424
|
+
conversation: digest(segment.conversationId),
|
|
16425
|
+
parent: segment.parentId === null ? null : digest(segment.parentId),
|
|
16235
16426
|
coverage: segment.coverage,
|
|
16236
16427
|
gaps: [...segment.gaps],
|
|
16237
|
-
dialogue: segment.records.map((r) => ({ id:
|
|
16428
|
+
dialogue: segment.records.map((r) => ({ id: digest(r.id), role: r.role, text: clean(r.text), model: r.model === null ? null : clean(r.model), provider: r.provider === null ? null : clean(r.provider), directUser: r.directUser, eventAt: r.eventAt, target: target.has(r.id) })),
|
|
16238
16429
|
candidates: { topics: options.topics, quotes: options.quotes, results: options.results.map(({ key: key2, dialogueIndex }) => ({ key: key2, dialogueIndex })), omittedSourceSpans: options.omitted }
|
|
16239
16430
|
}, questions: {
|
|
16240
16431
|
work: { type: "choice", instructions: safeInstructions + "Which work category best describes the target user request, using the complete dialogue?", criteria: Object.fromEntries(AUDIT_INTENTS.map((intent) => [intent, workLabels[intent]])) },
|
|
@@ -16257,7 +16448,7 @@ function segmentsInWindow(segments, period, until) {
|
|
|
16257
16448
|
return [];
|
|
16258
16449
|
if (promptIds.length === segment.promptIds.length && promptIds.every((id, i) => id === segment.promptIds[i]))
|
|
16259
16450
|
return [segment];
|
|
16260
|
-
return [{ ...segment, promptIds, contentHash:
|
|
16451
|
+
return [{ ...segment, promptIds, contentHash: digest(JSON.stringify({ records: segment.records.map(({ route: _, ...record4 }) => record4), promptIds })) }];
|
|
16261
16452
|
});
|
|
16262
16453
|
}
|
|
16263
16454
|
function selectedSegments(window2, segments) {
|
|
@@ -16402,7 +16593,7 @@ async function runLaunchSemantics(options) {
|
|
|
16402
16593
|
const run3 = options.provider.beginRun({ tokenLimit: window2.tokenLimit, maxAttempts: options.maxAttempts, retries: options.retries, signal: options.signal, isCurrent: options.isCurrent, estimateTokens: options.estimateTokens, estimateBasis: options.estimateBasis });
|
|
16403
16594
|
let completed = 0, cursor = 0;
|
|
16404
16595
|
try {
|
|
16405
|
-
const identity4 = (segment) => ({ sourceVersion: options.sourceVersion, privacyVersion: options.privacyVersion, segmentationVersion: CONTEXT_SEGMENTATION_VERSION, questionVersion: LAUNCH_QUESTION_VERSION, contentHash: segment.contentHash, scopeHash: options.scopeHash ??
|
|
16596
|
+
const identity4 = (segment) => ({ sourceVersion: options.sourceVersion, privacyVersion: options.privacyVersion, segmentationVersion: CONTEXT_SEGMENTATION_VERSION, questionVersion: LAUNCH_QUESTION_VERSION, contentHash: segment.contentHash, scopeHash: options.scopeHash ?? digest(JSON.stringify({ conversation: segment.conversationId, targets: segment.promptIds })) });
|
|
16406
16597
|
const consume = (segment, result) => {
|
|
16407
16598
|
if (result.state === "ok") {
|
|
16408
16599
|
const judgment = { segmentId: segment.id, conversationId: segment.conversationId, model: result.response.model, answers: result.response.answers, contentHash: segment.contentHash, questionVersion: LAUNCH_QUESTION_VERSION };
|
|
@@ -16558,7 +16749,7 @@ function openPrompts(schema, id, maxRecords, maxBytes, maxStoreBytes) {
|
|
|
16558
16749
|
if (parsed.text.trim())
|
|
16559
16750
|
prompts.push({ key: String(row2.id ?? seq), text: clean(parsed.text), time: time2, seq: ++seq });
|
|
16560
16751
|
}
|
|
16561
|
-
return { prompts, hash:
|
|
16752
|
+
return { prompts, hash: digest(JSON.stringify(commitments)), gaps: [...gaps], bytes: bytes3, nativeRecords };
|
|
16562
16753
|
})();
|
|
16563
16754
|
snapshot.assertCurrent();
|
|
16564
16755
|
return result;
|
|
@@ -16619,7 +16810,7 @@ function deterministicFindings(conversations, prompts, timezone, partial, scopeH
|
|
|
16619
16810
|
if (!supports.some((p) => p.id === prompt.id))
|
|
16620
16811
|
supports.push(prompt);
|
|
16621
16812
|
}
|
|
16622
|
-
return { id:
|
|
16813
|
+
return { id: digest(`${scopeHash}:${inputBasis}:${text2}`).slice(0, 32), text: text2, prompts: group.length, occurrences: group.length, denominator: inputs.length, measurementBasis: inputBasis, conversationIds: [...new Set(supports.map((p) => p.conversationId))], promptIds: supports.map((p) => p.id), evidenceRoutes: supports.map((p) => p.route) };
|
|
16623
16814
|
});
|
|
16624
16815
|
const insights = [];
|
|
16625
16816
|
let longest = null;
|
|
@@ -16731,7 +16922,7 @@ var init_jev_provider = __esm({
|
|
|
16731
16922
|
return structuredClone(this.attempts);
|
|
16732
16923
|
}
|
|
16733
16924
|
key(request, identity4) {
|
|
16734
|
-
return
|
|
16925
|
+
return digest(JSON.stringify({ request, identity: identity4 }));
|
|
16735
16926
|
}
|
|
16736
16927
|
evaluate(job, request, identity4) {
|
|
16737
16928
|
try {
|
|
@@ -16786,7 +16977,7 @@ var init_jev_provider = __esm({
|
|
|
16786
16977
|
}
|
|
16787
16978
|
async dispatch(item) {
|
|
16788
16979
|
const { job, request, key: key2, identity: identity4 } = item;
|
|
16789
|
-
const requestHash =
|
|
16980
|
+
const requestHash = digest(JSON.stringify(request));
|
|
16790
16981
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
16791
16982
|
try {
|
|
16792
16983
|
job.assertCurrent();
|
|
@@ -17072,7 +17263,7 @@ function prepare(selection, conversations) {
|
|
|
17072
17263
|
const state = { target: { role: "user", text: target.text }, precedingUser: preceding.map((p) => ({ role: "user", text: p.text })), assistantContext: "unavailable" };
|
|
17073
17264
|
try {
|
|
17074
17265
|
const request = promptQuestionRequest(state);
|
|
17075
|
-
prepared.push({ prompt, sourceVersion: conversation.sourceVersion, request, windowCoverage: target.truncated || preceding.some((p) => p.truncated) ? "truncated" : "partial", contentHash:
|
|
17266
|
+
prepared.push({ prompt, sourceVersion: conversation.sourceVersion, request, windowCoverage: target.truncated || preceding.some((p) => p.truncated) ? "truncated" : "partial", contentHash: digest(JSON.stringify({ sourceText: prompt.text, sentState: state })) });
|
|
17076
17267
|
} catch {
|
|
17077
17268
|
gaps.add("semantic_request_bytes_limit");
|
|
17078
17269
|
}
|
|
@@ -17107,8 +17298,8 @@ var init_jev_session = __esm({
|
|
|
17107
17298
|
job = null;
|
|
17108
17299
|
busy = false;
|
|
17109
17300
|
preview(snapshot, selection, conversations) {
|
|
17110
|
-
const selected = prepare(selection, conversations), scopeHash =
|
|
17111
|
-
const preparedRequests = selected.prepared.map((input) => ({ promptId: input.prompt.id, conversationId: input.prompt.conversationId, sourceRoute: input.prompt.route, sourceVersion: input.sourceVersion, contentHash: input.contentHash, scopeHash, normalizationVersion: NORMALIZATION_VERSION, questionVersion: JEV_QUESTION_VERSION, policyVersion: AUDIT_SEMANTIC_POLICY_VERSION, windowCoverage: input.windowCoverage, requestHash:
|
|
17301
|
+
const selected = prepare(selection, conversations), scopeHash = digest(JSON.stringify({ scope: snapshot.scope, conversationIds: selection.conversationIds }));
|
|
17302
|
+
const preparedRequests = selected.prepared.map((input) => ({ promptId: input.prompt.id, conversationId: input.prompt.conversationId, sourceRoute: input.prompt.route, sourceVersion: input.sourceVersion, contentHash: input.contentHash, scopeHash, normalizationVersion: NORMALIZATION_VERSION, questionVersion: JEV_QUESTION_VERSION, policyVersion: AUDIT_SEMANTIC_POLICY_VERSION, windowCoverage: input.windowCoverage, requestHash: digest(JSON.stringify(input.request)), requestBytes: Buffer.byteLength(JSON.stringify(input.request)), request: structuredClone(input.request) }));
|
|
17112
17303
|
return { snapshotId: snapshot.snapshotId, model: JEV_MODEL, selectedConversations: selection.conversationIds.length, eligiblePrompts: selected.eligible, selectedPrompts: selected.prepared.length, maxRequests: selection.maxRequests, budgetUsd: selection.budgetUsd, estimatedReservationUsd: Math.min(selection.maxRequests, selected.prepared.length * 2) * JEV_ATTEMPT_RESERVATION_USD, keyAvailable: jevKeyFromEnvironment() !== null, outgoingFields: ["target.role", "target.text (redacted prefix, max3500 UTF-8 bytes)", "precedingUser[].role", "precedingUser[].text (at most2 redacted prefixes, max768 bytes each)", "assistantContext:unavailable"], windowCoverage: selected.prepared.some((p) => p.windowCoverage === "truncated") ? "truncated" : "partial", samples: selected.prepared.slice(0, 3).map((p) => ({ promptId: p.prompt.id, excerpt: prefix(p.request.state && typeof p.request.state === "object" && !Array.isArray(p.request.state) ? String(p.request.state.target.text) : "", 160).text })), gapCodes: [...selected.gapCodes, "reservation_is_estimate_not_invoice_cap"], preparedRequests };
|
|
17113
17304
|
}
|
|
17114
17305
|
invalidate() {
|
|
@@ -17128,7 +17319,7 @@ var init_jev_session = __esm({
|
|
|
17128
17319
|
const selected = prepare(selection, conversations), denominator = selected.eligible;
|
|
17129
17320
|
if (selection.approvedPolicyVersion !== void 0 && selection.approvedPolicyVersion !== AUDIT_SEMANTIC_POLICY_VERSION)
|
|
17130
17321
|
throw new Error("semantic_approved_policy_changed");
|
|
17131
|
-
if (selection.approvedRequestHashes !== void 0 && JSON.stringify(selection.approvedRequestHashes) !== JSON.stringify(selected.prepared.map((input) =>
|
|
17322
|
+
if (selection.approvedRequestHashes !== void 0 && JSON.stringify(selection.approvedRequestHashes) !== JSON.stringify(selected.prepared.map((input) => digest(JSON.stringify(input.request)))))
|
|
17132
17323
|
throw new Error("semantic_approved_request_changed");
|
|
17133
17324
|
const key2 = jevKeyFromEnvironment();
|
|
17134
17325
|
if (!key2)
|
|
@@ -17136,13 +17327,13 @@ var init_jev_session = __esm({
|
|
|
17136
17327
|
if (!isCurrent())
|
|
17137
17328
|
throw new Error("audit_snapshot_stale");
|
|
17138
17329
|
this.busy = true;
|
|
17139
|
-
const signature =
|
|
17330
|
+
const signature = digest(key2);
|
|
17140
17331
|
if (!this.provider || signature !== this.keyHash) {
|
|
17141
17332
|
this.provider?.clearCache();
|
|
17142
17333
|
this.provider = new JevProvider({ apiKey: key2 });
|
|
17143
17334
|
this.keyHash = signature;
|
|
17144
17335
|
}
|
|
17145
|
-
const scopeHash =
|
|
17336
|
+
const scopeHash = digest(JSON.stringify({ scope: snapshot.scope, conversationIds: selection.conversationIds })), judgments = [];
|
|
17146
17337
|
let errorCode = null;
|
|
17147
17338
|
let skipped2 = 0;
|
|
17148
17339
|
const job = this.provider.beginJob({ consent: true, maxRequests: selection.maxRequests, budgetUsd: selection.budgetUsd, signal: selection.signal, isCurrent });
|
|
@@ -17292,7 +17483,7 @@ var init_profanity = __esm({
|
|
|
17292
17483
|
|
|
17293
17484
|
// packages/core/dist/analytics/index.js
|
|
17294
17485
|
import fs27 from "node:fs";
|
|
17295
|
-
import
|
|
17486
|
+
import path21 from "node:path";
|
|
17296
17487
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
17297
17488
|
import { setImmediate as pause2 } from "node:timers/promises";
|
|
17298
17489
|
function publicAuditSnapshot(snapshot) {
|
|
@@ -17398,19 +17589,19 @@ var init_analytics = __esm({
|
|
|
17398
17589
|
const from = options.since ? clock(options.since) : null, to = options.until ? clock(options.until) : null;
|
|
17399
17590
|
if (options.since && !from || options.until && !to || from && to && from > to)
|
|
17400
17591
|
throw new Error("invalid audit event range");
|
|
17401
|
-
const store = options.maxStoreBytes ??
|
|
17402
|
-
if (!Number.isSafeInteger(store) || store < 100 || store >
|
|
17592
|
+
const store = options.maxStoreBytes ?? 4 * 1024 * 1024 * 1024;
|
|
17593
|
+
if (!Number.isSafeInteger(store) || store < 100 || store > 4 * 1024 * 1024 * 1024)
|
|
17403
17594
|
throw new Error("invalid audit SQLite byte limit");
|
|
17404
17595
|
this.root = potsherdDir(options.potsherdDir);
|
|
17405
17596
|
if (options.launch) {
|
|
17406
|
-
this.derived = new DerivedCache(options.derivedCacheDir ??
|
|
17597
|
+
this.derived = new DerivedCache(options.derivedCacheDir ?? path21.join(this.root, "audit-derived"));
|
|
17407
17598
|
this.catalog = cachedPublicCatalog(this.derived);
|
|
17408
17599
|
}
|
|
17409
17600
|
this.limits = { source: cap(options.maxSourceBytes, 2 * 1024 * 1024, 16 * 1024 * 1024), candidates: cap(options.maxCandidates, 500, 5e3), total: cap(options.maxTotalBytes, 32 * 1024 * 1024, 128 * 1024 * 1024), prompts: cap(options.maxPrompts, 1e4, 5e4), records: cap(options.maxRecordsPerSource, 1e4, 5e4), store };
|
|
17410
17601
|
options.signal?.addEventListener("abort", () => this.cancel(), { once: true });
|
|
17411
17602
|
if (options.signal?.aborted)
|
|
17412
17603
|
this.cancel();
|
|
17413
|
-
this.current = immutable({ schemaVersion: "audit-v1", snapshotId: this.id, sequence: 0, measuredAt: (/* @__PURE__ */ new Date()).toISOString(), scope: { harnesses, project: options.project ?
|
|
17604
|
+
this.current = immutable({ schemaVersion: "audit-v1", snapshotId: this.id, sequence: 0, measuredAt: (/* @__PURE__ */ new Date()).toISOString(), scope: { harnesses, project: options.project ? path21.resolve(options.project) : null, eventFrom: from, asOf: to, timezone }, status: "discovering", coverage: emptyCoverage(), progress: { stage: "discovering", completed: 0, total: null, unit: "candidate_source", provisional: true, cancellable: true }, metrics: { conversations: metric(null, "top_level_conversation", "native_identity", "Distinct selected top-level conversations"), humanPrompts: metric(null, "eligible_human_input_event", "native_origin_discriminator_v1", "Eligible recorded human input events; child initialization excluded"), projects: metric(null, "known_project", "exact_path", "Distinct known projects in selected conversations"), linkedChildren: metric(null, "supported_child_source", "declared_parent_identity", "Selected child conversations with recorded parents") }, sources: harnesses.map((h) => ({ harness: h, state: "absent", candidateFiles: 0, conversations: 0, humanPrompts: null, humanOrigin: h === "pi" || h === "opencode" ? "projection" : "native_marker", evidence: "unavailable", usage: "unavailable", firstUnsupportedStep: null, gapCodes: [] })), projects: [], activity: [], conversations: [], insights: [], usage: { state: "unavailable", inputTokens: null, outputTokens: null, cacheTokens: null, reasoningTokens: null, costUsd: null, measurementBasis: null, inclusion: null, priceVersion: null }, ...options.launch ? { launch: { facts: null, semantics: null, stage: "discovering", notice: process.env["POTSHERD_OFFLINE"] === "1" ? "Offline audit. Conversation text stays on this machine; no analysis requests will be made. Esc cancels." : "Conversation text is redacted locally. OpenCode Zen and TypeSafe/Jev receive selected conversations for free analysis. Esc cancels." } } : {}, semantics: { state: "not_run", qualified: false, model: null, classifiedPrompts: 0, eligiblePrompts: 0, uncertainPrompts: 0, work: [], requestCount: 0, cacheHits: 0, estimatedCostUsd: null, reportedCostUsd: null, unresolvedCostUsd: null, errorCode: null }, warnings: [], sourceEpochs: null });
|
|
17414
17605
|
}
|
|
17415
17606
|
snapshot() {
|
|
17416
17607
|
return this.current;
|
|
@@ -17459,7 +17650,7 @@ var init_analytics = __esm({
|
|
|
17459
17650
|
for (const entry of entries) {
|
|
17460
17651
|
if (entry.project === null)
|
|
17461
17652
|
continue;
|
|
17462
|
-
const id =
|
|
17653
|
+
const id = digest(entry.project).slice(0, 20);
|
|
17463
17654
|
let project = projectMap.get(id);
|
|
17464
17655
|
if (!project) {
|
|
17465
17656
|
project = { id, alias: "", displayName: "", path: entry.project, humanPrompts: 0, conversations: 0, share: null };
|
|
@@ -17468,7 +17659,7 @@ var init_analytics = __esm({
|
|
|
17468
17659
|
project.conversations += entry.conversation.child ? 0 : 1;
|
|
17469
17660
|
project.humanPrompts += entry.prompts.filter((p) => p.eligibleHuman).length;
|
|
17470
17661
|
}
|
|
17471
|
-
const projects = [...projectMap.values()].sort((a, b) => a.id.localeCompare(b.id)).map((p, i) => ({ ...p, alias: `Project ${i < 26 ? String.fromCharCode(65 + i) : i + 1}`, displayName: this.options.launch ? clean(
|
|
17662
|
+
const projects = [...projectMap.values()].sort((a, b) => a.id.localeCompare(b.id)).map((p, i) => ({ ...p, alias: `Project ${i < 26 ? String.fromCharCode(65 + i) : i + 1}`, displayName: this.options.launch ? clean(path21.basename(p.path)) : `Project ${i < 26 ? String.fromCharCode(65 + i) : i + 1}`, share: eligible2.length ? p.humanPrompts / eligible2.length : null }));
|
|
17472
17663
|
if (this.options.launch)
|
|
17473
17664
|
projects.sort((a, b) => b.humanPrompts - a.humanPrompts || b.conversations - a.conversations || a.id.localeCompare(b.id));
|
|
17474
17665
|
const dates = /* @__PURE__ */ new Map();
|
|
@@ -17497,8 +17688,8 @@ var init_analytics = __esm({
|
|
|
17497
17688
|
const progress = { stage, completed: this.parsed, total: stage === "ready" || stage === "partial" ? this.candidates : null, unit: "candidate_source", provisional: !["ready", "partial", "cancelled", "error"].includes(stage), cancellable: !["ready", "partial", "cancelled", "error"].includes(stage) };
|
|
17498
17689
|
const final = ["ready", "partial", "cancelled"].includes(stage) && !this.stale;
|
|
17499
17690
|
const profanity = final ? auditProfanity(eligible2, partial) : void 0;
|
|
17500
|
-
const findings = final ? deterministicFindings(entries.map((e) => e.conversation), eligible2, this.current.scope.timezone, partial,
|
|
17501
|
-
this.update({ ...findings, profanity, sequence: ++this.sequence, measuredAt: (/* @__PURE__ */ new Date()).toISOString(), status: stage, sourceEpochs: this.epochs, coverage, progress, sources, projects, conversations: entries.map((e) => e.conversation), activity: [...dates].sort(([a], [b]) => a.localeCompare(b)).map(([date3, count2]) => ({ date: date3, count: count2 })), metrics: { conversations: metric(!this.policyAvailable && !entries.length ? null : top, "top_level_conversation", "harness_native_identity", "Distinct selected top-level conversation identities", partial), humanPrompts: metric(!this.policyAvailable && !entries.length ? null : humanValue, "eligible_human_input_event", "native_origin_discriminator_v1", "Eligible native input markers; known maintenance and programmatic inputs excluded. This is recorded-origin evidence, not universal human attestation.", partial), projects: metric(!this.policyAvailable && !entries.length ? null : projects.length, "known_project", "normalized_exact_path", "Distinct known project paths; unknown projects excluded", partial), linkedChildren: metric(!this.policyAvailable && !entries.length ? null : children, "supported_child_source", "declared_parent_identity", "Distinct selected child conversations with declared parent identities", partial) }, semantics: { ...this.current.semantics, eligiblePrompts: eligible2.length }, commitment:
|
|
17691
|
+
const findings = final ? deterministicFindings(entries.map((e) => e.conversation), eligible2, this.current.scope.timezone, partial, digest(JSON.stringify(this.current.scope))) : { insights: [], phrases: [] };
|
|
17692
|
+
this.update({ ...findings, profanity, sequence: ++this.sequence, measuredAt: (/* @__PURE__ */ new Date()).toISOString(), status: stage, sourceEpochs: this.epochs, coverage, progress, sources, projects, conversations: entries.map((e) => e.conversation), activity: [...dates].sort(([a], [b]) => a.localeCompare(b)).map(([date3, count2]) => ({ date: date3, count: count2 })), metrics: { conversations: metric(!this.policyAvailable && !entries.length ? null : top, "top_level_conversation", "harness_native_identity", "Distinct selected top-level conversation identities", partial), humanPrompts: metric(!this.policyAvailable && !entries.length ? null : humanValue, "eligible_human_input_event", "native_origin_discriminator_v1", "Eligible native input markers; known maintenance and programmatic inputs excluded. This is recorded-origin evidence, not universal human attestation.", partial), projects: metric(!this.policyAvailable && !entries.length ? null : projects.length, "known_project", "normalized_exact_path", "Distinct known project paths; unknown projects excluded", partial), linkedChildren: metric(!this.policyAvailable && !entries.length ? null : children, "supported_child_source", "declared_parent_identity", "Distinct selected child conversations with declared parent identities", partial) }, semantics: { ...this.current.semantics, eligiblePrompts: eligible2.length }, commitment: digest(JSON.stringify(entries.map((e) => [e.conversation.id, e.hash]))), warnings: [...this.gaps] });
|
|
17502
17693
|
this.callback?.({ type: "progress", snapshotId: this.id, sequence: this.sequence, progress: this.current.progress, sources: this.current.sources });
|
|
17503
17694
|
this.callback?.({ type: "snapshot", snapshot: this.current });
|
|
17504
17695
|
}
|
|
@@ -17605,13 +17796,13 @@ var init_analytics = __esm({
|
|
|
17605
17796
|
const stat = fs27.statSync(entry.file, { bigint: true });
|
|
17606
17797
|
if (Number(stat.size) !== entry.fileStat.size || String(stat.dev) !== entry.fileStat.dev || String(stat.ino) !== entry.fileStat.ino || String(stat.mtimeNs) !== entry.fileStat.mtimeNs || String(stat.ctimeNs) !== entry.fileStat.ctimeNs)
|
|
17607
17798
|
return false;
|
|
17608
|
-
if (content2 && entry.fileHash !== null &&
|
|
17799
|
+
if (content2 && entry.fileHash !== null && digest(boundedBytes(entry.file, this.limits.source)) !== entry.fileHash)
|
|
17609
17800
|
return false;
|
|
17610
17801
|
}
|
|
17611
17802
|
}
|
|
17612
17803
|
if (!this.hadStore && fs27.existsSync(dbPath(this.root)))
|
|
17613
17804
|
return false;
|
|
17614
|
-
const config = configPath(this.root), current = fs27.existsSync(config) ?
|
|
17805
|
+
const config = configPath(this.root), current = fs27.existsSync(config) ? digest(boundedBytes(config, 1024 * 1024)) : null;
|
|
17615
17806
|
if (current !== this.policyCommitment)
|
|
17616
17807
|
return false;
|
|
17617
17808
|
if (this.db && this.epochs) {
|
|
@@ -17633,7 +17824,7 @@ var init_analytics = __esm({
|
|
|
17633
17824
|
if (!s.isFile() || s.size > 1024 * 1024)
|
|
17634
17825
|
throw new Error("ignore_policy_unavailable");
|
|
17635
17826
|
fs27.accessSync(config, fs27.constants.R_OK);
|
|
17636
|
-
this.policyCommitment =
|
|
17827
|
+
this.policyCommitment = digest(boundedBytes(config, 1024 * 1024));
|
|
17637
17828
|
const ignored = readIgnoreConfig(this.root);
|
|
17638
17829
|
if (ignored.error)
|
|
17639
17830
|
throw new Error("ignore_policy_unavailable");
|
|
@@ -17713,7 +17904,7 @@ var init_analytics = __esm({
|
|
|
17713
17904
|
break;
|
|
17714
17905
|
}
|
|
17715
17906
|
const route = canonical3?.refs.get(event.evidenceStart ?? event.rawStart) ?? { basis: "transient_snapshot", sourceId: id, artifactHash: facts.hash, sourcePath: file, recordKey: event.key, rawStart: event.rawStart, rawEnd: event.rawEnd, startUtf16: 0, endUtf16: event.text.length, snapshotId: this.id };
|
|
17716
|
-
const prompt = { id:
|
|
17907
|
+
const prompt = { id: digest(`${id}:${event.identity}`).slice(0, 32), conversationId: id, role: "user", originBasis: event.origin, identityBasis: event.identity, eligibleHuman: event.eligible, excludedReason: event.excluded, eventAt: event.eventAt, text: event.text, route };
|
|
17717
17908
|
prompts.push(prompt);
|
|
17718
17909
|
for (const key2 of [event.key, event.identity, String(event.rawStart), ...event.evidenceStart !== void 0 ? [String(event.evidenceStart)] : []])
|
|
17719
17910
|
nativeKeys.set(key2, prompt.id);
|
|
@@ -17729,7 +17920,7 @@ var init_analytics = __esm({
|
|
|
17729
17920
|
const coverage = { ...emptyCoverage(), knownSources: 1, parsedSources: 1, unknownOriginEvents: ownUnknown, excludedEvents: prompts.filter((p) => !p.eligibleHuman).length, state: facts.gaps.length ? "partial" : "complete_snapshot", gapCodes: facts.gaps };
|
|
17730
17921
|
const measuredProject = this.current.scope.project ?? facts.project;
|
|
17731
17922
|
const title = this.current.scope.project || this.ignored.length ? null : facts.title;
|
|
17732
|
-
this.entries.set(id, { conversation: { id, sourceId: id, harness, nativeSessionId: facts.nativeId, projectId: measuredProject ?
|
|
17923
|
+
this.entries.set(id, { conversation: { id, sourceId: id, harness, nativeSessionId: facts.nativeId, projectId: measuredProject ? digest(measuredProject).slice(0, 20) : null, title, alias: `Conversation ${this.entries.size + 1}`, promptCount: harness === "pi" || harness === "opencode" ? null : prompts.filter((p) => p.eligibleHuman).length, unknownOriginEvents: ownUnknown, eventFrom: dates[0] ?? null, eventTo: dates.at(-1) ?? null, child: facts.child, parentId: facts.parent ? sourceId(harness, facts.parent) : null, coverage }, project: measuredProject, prompts, proofs, nativeKeys, hash: facts.hash, committedBytes: facts.bytes, file, fileHash, ...file && fileHash ? { fileStat: (({ size, dev, ino, mtimeNs, ctimeNs }) => ({ size: Number(size), dev: String(dev), ino: String(ino), mtimeNs: String(mtimeNs), ctimeNs: String(ctimeNs) }))(fs27.statSync(file, { bigint: true })) } : {} });
|
|
17733
17924
|
this.parsed++;
|
|
17734
17925
|
}
|
|
17735
17926
|
remove(id) {
|
|
@@ -17756,7 +17947,7 @@ var init_analytics = __esm({
|
|
|
17756
17947
|
this.callback?.({ type: "snapshot", snapshot: this.current });
|
|
17757
17948
|
}
|
|
17758
17949
|
cacheBinding(id, identity4, contentHash, currentness) {
|
|
17759
|
-
return { sourceId: id, sourceIdentity: identity4, contentHash, currentness, privacyPolicy:
|
|
17950
|
+
return { sourceId: id, sourceIdentity: identity4, contentHash, currentness, privacyPolicy: digest(JSON.stringify([this.policyCommitment, this.current.scope.project, this.ignored])), forgetEpoch: digest(JSON.stringify(this.epochs ?? "no-store")), normalizationVersion: NORMALIZATION_VERSION };
|
|
17760
17951
|
}
|
|
17761
17952
|
launchAllowed(project) {
|
|
17762
17953
|
return !(project && isIgnoredProject(project, this.ignored)) && (!this.current.scope.project || project === this.current.scope.project);
|
|
@@ -17776,7 +17967,7 @@ var init_analytics = __esm({
|
|
|
17776
17967
|
contextGaps.add("native_context_unavailable");
|
|
17777
17968
|
continue;
|
|
17778
17969
|
}
|
|
17779
|
-
const id = entry.conversation.id, binding2 = { ...this.cacheBinding(id, entry.file ?? id, entry.hash,
|
|
17970
|
+
const id = entry.conversation.id, binding2 = { ...this.cacheBinding(id, entry.file ?? id, entry.hash, digest(JSON.stringify(entry.fileStat ?? entry.hash))), scopeHash: digest(JSON.stringify([this.current.scope.eventFrom, this.current.scope.asOf, this.current.scope.harnesses])) };
|
|
17780
17971
|
const validateUsage = (v) => Array.isArray(v) && v.every((r) => r && typeof r === "object" && typeof r.id === "string" && r.conversationId === id && ["claude", "codex", "pi", "opencode"].includes(r.harness) && Array.isArray(r.gaps) && ["inputTokens", "outputTokens", "cacheReadTokens", "cacheWriteTokens", "reasoningTokens"].every((k) => r[k] === null || Number.isSafeInteger(r[k]) && r[k] >= 0));
|
|
17781
17972
|
let usage = this.derived?.read("native-usage", binding2, validateUsage) ?? null;
|
|
17782
17973
|
if (!usage) {
|
|
@@ -17826,8 +18017,8 @@ var init_analytics = __esm({
|
|
|
17826
18017
|
this.launchPublish({ facts, languageByModel: attributeDirectLanguage(this.current.profanity, contexts), stage: "preparing" });
|
|
17827
18018
|
const segmented = segmentContext(contexts, { gaps: [...contextGaps] });
|
|
17828
18019
|
this.launchSegments = segmented.segments;
|
|
17829
|
-
const sourceVersion = this.current.commitment ??
|
|
17830
|
-
const cacheBase = this.cacheBinding("semantic-job", "selected-context", sourceVersion,
|
|
18020
|
+
const sourceVersion = this.current.commitment ?? digest(JSON.stringify(this.epochs));
|
|
18021
|
+
const cacheBase = this.cacheBinding("semantic-job", "selected-context", sourceVersion, digest(JSON.stringify(this.epochs ?? "no-store")));
|
|
17831
18022
|
let provider;
|
|
17832
18023
|
if (!this.options.launchPrepareOnly && process.env["POTSHERD_OFFLINE"] !== "1")
|
|
17833
18024
|
provider = new FreeJevProvider({ route: { kind: "zen-public" }, cache: { get: (key2) => {
|
|
@@ -17848,24 +18039,24 @@ var init_analytics = __esm({
|
|
|
17848
18039
|
this.launchPublish({ stage: "ready" });
|
|
17849
18040
|
}
|
|
17850
18041
|
async primary(file, harness, canonical3) {
|
|
17851
|
-
const stat = fs27.statSync(file, { bigint: true }), stamp =
|
|
17852
|
-
const pointerBinding = this.cacheBinding(
|
|
18042
|
+
const stat = fs27.statSync(file, { bigint: true }), stamp = digest([stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].join(":"));
|
|
18043
|
+
const pointerBinding = this.cacheBinding(digest(file), file, "file-pointer-v1", stamp);
|
|
17853
18044
|
const validPointer = (v) => v !== null && typeof v === "object" && "artifactHash" in v && typeof v.artifactHash === "string" && /^[a-f0-9]{64}$/.test(v.artifactHash);
|
|
17854
18045
|
const pointer = this.derived?.read("file-pointer", pointerBinding, validPointer) ?? null;
|
|
17855
18046
|
if (pointer && (this.current.scope.eventFrom || this.current.scope.asOf)) {
|
|
17856
|
-
const binding2 = this.cacheBinding(
|
|
18047
|
+
const binding2 = this.cacheBinding(digest(file), file, pointer.artifactHash, stamp), index = this.derived?.read("date-index", binding2, validateHistoryDateIndex) ?? null;
|
|
17857
18048
|
if (!historyMayOverlap(index, binding2, this.current.scope.eventFrom, this.current.scope.asOf))
|
|
17858
18049
|
return;
|
|
17859
18050
|
}
|
|
17860
18051
|
const bytes3 = boundedBytes(file, Math.min(this.limits.source, this.limits.total - this.totalBytes));
|
|
17861
18052
|
this.totalBytes += bytes3.length;
|
|
17862
18053
|
if (this.derived) {
|
|
17863
|
-
const binding2 = this.cacheBinding(
|
|
18054
|
+
const binding2 = this.cacheBinding(digest(file), file, digest(bytes3), stamp);
|
|
17864
18055
|
const index = indexHistoryBytes(bytes3, harness, binding2, { maxRecords: this.limits.records });
|
|
17865
18056
|
try {
|
|
17866
18057
|
if (this.fresh()) {
|
|
17867
18058
|
this.derived.write("date-index", binding2, index, validateHistoryDateIndex);
|
|
17868
|
-
this.derived.write("file-pointer", pointerBinding, { artifactHash:
|
|
18059
|
+
this.derived.write("file-pointer", pointerBinding, { artifactHash: digest(bytes3) }, validPointer);
|
|
17869
18060
|
}
|
|
17870
18061
|
} catch {
|
|
17871
18062
|
this.gap("derived_cache_unavailable");
|
|
@@ -17891,9 +18082,9 @@ var init_analytics = __esm({
|
|
|
17891
18082
|
facts.gaps.push("record_coverage_partial");
|
|
17892
18083
|
}
|
|
17893
18084
|
const current = boundedBytes(file, this.limits.source);
|
|
17894
|
-
if (
|
|
18085
|
+
if (digest(current) !== digest(bytes3))
|
|
17895
18086
|
throw new Error("source_changed");
|
|
17896
|
-
this.add(harness, facts, file,
|
|
18087
|
+
this.add(harness, facts, file, digest(bytes3), canonical3);
|
|
17897
18088
|
}
|
|
17898
18089
|
async canonical() {
|
|
17899
18090
|
if (!this.db)
|
|
@@ -17905,7 +18096,7 @@ var init_analytics = __esm({
|
|
|
17905
18096
|
this.omitted++;
|
|
17906
18097
|
this.gap("candidate_limit");
|
|
17907
18098
|
}
|
|
17908
|
-
const coverageBinding = this.cacheBinding("canonical-coverage", this.root, this.storeSnapshot.hash,
|
|
18099
|
+
const coverageBinding = this.cacheBinding("canonical-coverage", this.root, this.storeSnapshot.hash, digest(JSON.stringify([this.storeSnapshot.hash, this.current.scope.eventFrom, this.current.scope.asOf, this.current.scope.harnesses])));
|
|
17909
18100
|
const validateCoverage = (v) => v !== null && typeof v === "object" && "omittedKinds" in v && Array.isArray(v.omittedKinds) && v.omittedKinds.every((g) => typeof g === "string");
|
|
17910
18101
|
const cachedCoverage = this.derived?.read("source-coverage", coverageBinding, validateCoverage);
|
|
17911
18102
|
const coverage = cachedCoverage ?? inspectCoverage(db, scope2, "disabled", { harnesses: [...harnesses] });
|
|
@@ -17966,8 +18157,8 @@ var init_analytics = __esm({
|
|
|
17966
18157
|
events.push({ key: String(unit.unit_key), rawStart: start, rawEnd: typeof locator.rawEnd === "number" ? locator.rawEnd : -1, role: "user", text: text2, eventAt: clock(unit.event_at), project: typeof unit.project === "string" ? unit.project : null, origin: "unknown", eligible: false, excluded: row2.parent_native_id ? "child_initialization" : "human_origin_unavailable", identity: String(unit.unit_key) });
|
|
17967
18158
|
}
|
|
17968
18159
|
if (revision.archiveRelativePath && revision.artifactBasis === "raw_prefix" && (row2.harness === "claude" || row2.harness === "codex")) {
|
|
17969
|
-
const file =
|
|
17970
|
-
if (file.startsWith(this.root +
|
|
18160
|
+
const file = path21.resolve(this.root, revision.archiveRelativePath);
|
|
18161
|
+
if (file.startsWith(this.root + path21.sep))
|
|
17971
18162
|
try {
|
|
17972
18163
|
await this.primary(file, row2.harness, { revisionId: row2.active_revision_id, refs: refs2, hash: revision.artifactHash, nativeId: row2.native_session_id, parent: row2.parent_native_id });
|
|
17973
18164
|
this.emit("parsing");
|
|
@@ -17998,7 +18189,7 @@ var init_analytics = __esm({
|
|
|
17998
18189
|
this.callback = onEvent;
|
|
17999
18190
|
this.emit("discovering");
|
|
18000
18191
|
this.policy();
|
|
18001
|
-
if (this.options.launch && !this.options.launchPrepareOnly && this.catalog)
|
|
18192
|
+
if (this.options.launch && !this.options.launchPrepareOnly && process.env["POTSHERD_OFFLINE"] !== "1" && this.catalog)
|
|
18002
18193
|
void refreshPublicCatalog(this.derived, this.catalog, this.controller.signal);
|
|
18003
18194
|
if (this.policyAvailable)
|
|
18004
18195
|
await this.canonical();
|
|
@@ -18006,7 +18197,7 @@ var init_analytics = __esm({
|
|
|
18006
18197
|
for (const harness of this.current.scope.harnesses) {
|
|
18007
18198
|
if (this.controller.signal.aborted)
|
|
18008
18199
|
break;
|
|
18009
|
-
const roots = harness === "claude" ? [
|
|
18200
|
+
const roots = harness === "claude" ? [path21.join(claudeDir(this.options.claudeDir), "projects")] : harness === "codex" ? [codexPaths(codexDir(this.options.codexDir)).sessions, codexPaths(codexDir(this.options.codexDir)).archived] : harness === "pi" ? [piSessionsDir(this.options.piDir)] : [opencodeDir(this.options.opencodeDir)];
|
|
18010
18201
|
for (const root of roots) {
|
|
18011
18202
|
try {
|
|
18012
18203
|
for await (const file of walk(root, this.limits.candidates * 32, this.controller.signal, harness === "opencode" ? 3 : 8)) {
|
|
@@ -18117,11 +18308,11 @@ var init_analytics = __esm({
|
|
|
18117
18308
|
const segments = selected ? selectedSegments(semantic.window, this.launchSegments) : [];
|
|
18118
18309
|
const requests = segments.map((segment) => {
|
|
18119
18310
|
const request = buildLaunchRequest(segment), serialized = JSON.stringify(request);
|
|
18120
|
-
return { segmentId: segment.id, hash:
|
|
18311
|
+
return { segmentId: segment.id, hash: digest(serialized), bytes: Buffer.byteLength(serialized), request };
|
|
18121
18312
|
});
|
|
18122
18313
|
if (!this.fresh(true))
|
|
18123
18314
|
throw new Error("audit_snapshot_stale");
|
|
18124
|
-
return { scope: this.current.scope, sourceVersion: this.current.commitment ??
|
|
18315
|
+
return { scope: this.current.scope, sourceVersion: this.current.commitment ?? digest(JSON.stringify(this.epochs)), privacyVersion: digest(JSON.stringify([this.policyCommitment, this.current.scope.project, this.ignored])), model: FREE_JEV_MODEL, window: semantic?.window ?? null, requests };
|
|
18125
18316
|
}
|
|
18126
18317
|
async analyzePeriod(period, onEvent) {
|
|
18127
18318
|
this.assertOpen();
|
|
@@ -18195,7 +18386,7 @@ var init_analytics = __esm({
|
|
|
18195
18386
|
const current = openPrompts(entry.open.schema, entry.open.id, this.limits.records, entry.open.maxBytes, this.limits.source);
|
|
18196
18387
|
if (current.hash !== entry.hash)
|
|
18197
18388
|
return unavailable("stale", "source_changed");
|
|
18198
|
-
} else if (
|
|
18389
|
+
} else if (digest(boundedBytes(entry.file, this.limits.source)) !== entry.fileHash)
|
|
18199
18390
|
return unavailable("stale", "source_changed");
|
|
18200
18391
|
} catch {
|
|
18201
18392
|
return unavailable("unavailable", "source_missing_or_unreadable");
|
|
@@ -18225,7 +18416,7 @@ var init_analytics = __esm({
|
|
|
18225
18416
|
if (!entry)
|
|
18226
18417
|
throw new Error("source unavailable");
|
|
18227
18418
|
entry.open?.assertCurrent();
|
|
18228
|
-
if (entry.file && entry.fileHash !== null &&
|
|
18419
|
+
if (entry.file && entry.fileHash !== null && digest(boundedBytes(entry.file, this.limits.source)) !== entry.fileHash)
|
|
18229
18420
|
throw new Error("source changed");
|
|
18230
18421
|
}
|
|
18231
18422
|
return true;
|
|
@@ -18742,12 +18933,12 @@ __export(claude_exports, {
|
|
|
18742
18933
|
sourceDir: () => sourceDir3
|
|
18743
18934
|
});
|
|
18744
18935
|
import fs28 from "node:fs";
|
|
18745
|
-
import
|
|
18936
|
+
import path22 from "node:path";
|
|
18746
18937
|
function sourceDir3(claudeConfigDir) {
|
|
18747
18938
|
return claudePaths(claudeDir(claudeConfigDir)).projects;
|
|
18748
18939
|
}
|
|
18749
18940
|
function archiveSourceDir(root) {
|
|
18750
|
-
return
|
|
18941
|
+
return path22.join(archiveDir(root ?? potsherdDir()), "claude");
|
|
18751
18942
|
}
|
|
18752
18943
|
function discover3(options = {}) {
|
|
18753
18944
|
const live = walkProjects(sourceDir3(options.claudeDir), "live");
|
|
@@ -18759,7 +18950,7 @@ function discover3(options = {}) {
|
|
|
18759
18950
|
for (const found of walkProjects(archiveRoot, "archived")) {
|
|
18760
18951
|
if (byRel.has(found.rel))
|
|
18761
18952
|
continue;
|
|
18762
|
-
found.originalPath =
|
|
18953
|
+
found.originalPath = path22.join(sourceDir3(options.claudeDir), found.rel);
|
|
18763
18954
|
byRel.set(found.rel, found);
|
|
18764
18955
|
}
|
|
18765
18956
|
}
|
|
@@ -18835,14 +19026,14 @@ function walkProjects(projectsDir, status3) {
|
|
|
18835
19026
|
if (!slugEntry.isDirectory())
|
|
18836
19027
|
continue;
|
|
18837
19028
|
const slug = slugEntry.name;
|
|
18838
|
-
const dir =
|
|
19029
|
+
const dir = path22.join(projectsDir, slug);
|
|
18839
19030
|
for (const entry of readdirSafe3(dir, true)) {
|
|
18840
19031
|
if (entry.isFile()) {
|
|
18841
19032
|
if (!entry.name.endsWith(".jsonl"))
|
|
18842
19033
|
continue;
|
|
18843
19034
|
push(out, {
|
|
18844
|
-
file:
|
|
18845
|
-
rel:
|
|
19035
|
+
file: path22.join(dir, entry.name),
|
|
19036
|
+
rel: path22.join(slug, entry.name),
|
|
18846
19037
|
slug,
|
|
18847
19038
|
sessionId: basename3(entry.name),
|
|
18848
19039
|
isSidechain: false,
|
|
@@ -18855,14 +19046,14 @@ function walkProjects(projectsDir, status3) {
|
|
|
18855
19046
|
if (entry.name === "memory")
|
|
18856
19047
|
continue;
|
|
18857
19048
|
const flat = entry.name === SIDECHAIN_DIR;
|
|
18858
|
-
const subDir = flat ?
|
|
18859
|
-
const relDir = flat ?
|
|
19049
|
+
const subDir = flat ? path22.join(dir, entry.name) : path22.join(dir, entry.name, SIDECHAIN_DIR);
|
|
19050
|
+
const relDir = flat ? path22.join(slug, entry.name) : path22.join(slug, entry.name, SIDECHAIN_DIR);
|
|
18860
19051
|
for (const name of readdirSafe3(subDir)) {
|
|
18861
19052
|
if (!name.endsWith(".jsonl"))
|
|
18862
19053
|
continue;
|
|
18863
19054
|
push(out, {
|
|
18864
|
-
file:
|
|
18865
|
-
rel:
|
|
19055
|
+
file: path22.join(subDir, name),
|
|
19056
|
+
rel: path22.join(relDir, name),
|
|
18866
19057
|
slug,
|
|
18867
19058
|
sessionId: flat ? basename3(name) : `${entry.name}:${basename3(name)}`,
|
|
18868
19059
|
isSidechain: true,
|
|
@@ -19028,9 +19219,9 @@ var init_claude2 = __esm({
|
|
|
19028
19219
|
|
|
19029
19220
|
// packages/core/dist/parser/codex.js
|
|
19030
19221
|
import fs29 from "node:fs";
|
|
19031
|
-
import
|
|
19222
|
+
import path23 from "node:path";
|
|
19032
19223
|
async function parseCodexTranscript(filePath, options = {}) {
|
|
19033
|
-
const absolute2 =
|
|
19224
|
+
const absolute2 = path23.resolve(filePath);
|
|
19034
19225
|
const fromOffset = options.fromOffset ?? 0;
|
|
19035
19226
|
const snapshot = fs29.readFileSync(absolute2);
|
|
19036
19227
|
const seqByOffset = /* @__PURE__ */ new Map();
|
|
@@ -19196,7 +19387,7 @@ async function parseCodexTranscript(filePath, options = {}) {
|
|
|
19196
19387
|
}
|
|
19197
19388
|
finalize();
|
|
19198
19389
|
const id = resolvedId();
|
|
19199
|
-
const projectSlug = options.projectSlug ?? (cwd ?
|
|
19390
|
+
const projectSlug = options.projectSlug ?? (cwd ? path23.basename(cwd) : "unknown");
|
|
19200
19391
|
const bytes3 = options.bytes ?? statBytes2(absolute2);
|
|
19201
19392
|
const session = {
|
|
19202
19393
|
id,
|
|
@@ -19251,7 +19442,7 @@ function normalise(text2) {
|
|
|
19251
19442
|
return text2.trim();
|
|
19252
19443
|
}
|
|
19253
19444
|
function sessionIdFromPath2(filePath) {
|
|
19254
|
-
const base2 =
|
|
19445
|
+
const base2 = path23.basename(filePath, ".jsonl");
|
|
19255
19446
|
const matches = base2.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi);
|
|
19256
19447
|
const last2 = matches?.[matches.length - 1];
|
|
19257
19448
|
return last2 ?? base2;
|
|
@@ -19343,9 +19534,9 @@ __export(codex_exports, {
|
|
|
19343
19534
|
sessionIdFromRolloutPath: () => sessionIdFromRolloutPath
|
|
19344
19535
|
});
|
|
19345
19536
|
import fs30 from "node:fs";
|
|
19346
|
-
import
|
|
19537
|
+
import path24 from "node:path";
|
|
19347
19538
|
function sessionIdFromRolloutPath(filePath) {
|
|
19348
|
-
const base2 =
|
|
19539
|
+
const base2 = path24.basename(filePath, ".jsonl");
|
|
19349
19540
|
const matches = base2.match(UUID);
|
|
19350
19541
|
return matches?.[matches.length - 1] ?? base2;
|
|
19351
19542
|
}
|
|
@@ -19367,7 +19558,7 @@ function walk2(dir, status3, depth, out) {
|
|
|
19367
19558
|
return;
|
|
19368
19559
|
}
|
|
19369
19560
|
for (const entry of entries) {
|
|
19370
|
-
const full =
|
|
19561
|
+
const full = path24.join(dir, entry.name);
|
|
19371
19562
|
if (entry.isDirectory()) {
|
|
19372
19563
|
walk2(full, status3, depth + 1, out);
|
|
19373
19564
|
continue;
|
|
@@ -19584,7 +19775,7 @@ async function parse4(source, options = {}) {
|
|
|
19584
19775
|
function pickSlug(session, cwd) {
|
|
19585
19776
|
if (session.projectSlug && session.projectSlug !== "unknown")
|
|
19586
19777
|
return session.projectSlug;
|
|
19587
|
-
return
|
|
19778
|
+
return path24.basename(cwd) || "unknown";
|
|
19588
19779
|
}
|
|
19589
19780
|
async function codexDoctor(options = {}) {
|
|
19590
19781
|
const paths = codexPaths(codexDir(options.codexHome));
|
|
@@ -19744,7 +19935,7 @@ __export(cursor_exports, {
|
|
|
19744
19935
|
toolName: () => toolName
|
|
19745
19936
|
});
|
|
19746
19937
|
import fs31 from "node:fs";
|
|
19747
|
-
import
|
|
19938
|
+
import path25 from "node:path";
|
|
19748
19939
|
function cursorSlug(cwd) {
|
|
19749
19940
|
return cwd.replace(/^[/\\]+/, "").replace(/[/\\_]/g, "-");
|
|
19750
19941
|
}
|
|
@@ -19759,24 +19950,24 @@ function discover5(dirOverride) {
|
|
|
19759
19950
|
const root = cursorProjectsDir(dirOverride);
|
|
19760
19951
|
const out = [];
|
|
19761
19952
|
for (const slug of readdirSafe4(root, "dir")) {
|
|
19762
|
-
const transcripts =
|
|
19953
|
+
const transcripts = path25.join(root, slug, TRANSCRIPTS_DIR);
|
|
19763
19954
|
for (const sessionId of readdirSafe4(transcripts, "dir")) {
|
|
19764
|
-
const sessionDir =
|
|
19955
|
+
const sessionDir = path25.join(transcripts, sessionId);
|
|
19765
19956
|
for (const file of readdirSafe4(sessionDir, "file")) {
|
|
19766
19957
|
if (!file.endsWith(".jsonl"))
|
|
19767
19958
|
continue;
|
|
19768
|
-
const source = statSource(
|
|
19959
|
+
const source = statSource(path25.join(sessionDir, file), slug, {
|
|
19769
19960
|
sessionId: basenameId(file),
|
|
19770
19961
|
isSidechain: false
|
|
19771
19962
|
});
|
|
19772
19963
|
if (source)
|
|
19773
19964
|
out.push(source);
|
|
19774
19965
|
}
|
|
19775
|
-
const sidechains =
|
|
19966
|
+
const sidechains = path25.join(sessionDir, SIDECHAIN_DIR3);
|
|
19776
19967
|
for (const file of readdirSafe4(sidechains, "file")) {
|
|
19777
19968
|
if (!file.endsWith(".jsonl"))
|
|
19778
19969
|
continue;
|
|
19779
|
-
const source = statSource(
|
|
19970
|
+
const source = statSource(path25.join(sidechains, file), slug, {
|
|
19780
19971
|
sessionId: basenameId(file),
|
|
19781
19972
|
isSidechain: true,
|
|
19782
19973
|
parentSessionId: sessionId
|
|
@@ -20100,7 +20291,7 @@ function recoverCwd(projectSlug, candidates2) {
|
|
|
20100
20291
|
hits.set(dir, (hits.get(dir) ?? 0) + 1);
|
|
20101
20292
|
break;
|
|
20102
20293
|
}
|
|
20103
|
-
const parent =
|
|
20294
|
+
const parent = path25.dirname(dir);
|
|
20104
20295
|
if (parent === dir)
|
|
20105
20296
|
break;
|
|
20106
20297
|
dir = parent;
|
|
@@ -20216,7 +20407,7 @@ __export(pi_exports, {
|
|
|
20216
20407
|
unslugifyPi: () => unslugifyPi
|
|
20217
20408
|
});
|
|
20218
20409
|
import fs32 from "node:fs";
|
|
20219
|
-
import
|
|
20410
|
+
import path26 from "node:path";
|
|
20220
20411
|
import crypto5 from "node:crypto";
|
|
20221
20412
|
function sourceDir4(override) {
|
|
20222
20413
|
return piSessionsDir(override);
|
|
@@ -20246,7 +20437,7 @@ function discover6(override) {
|
|
|
20246
20437
|
for (const slug of slugs) {
|
|
20247
20438
|
if (!slug.isDirectory())
|
|
20248
20439
|
continue;
|
|
20249
|
-
const dir =
|
|
20440
|
+
const dir = path26.join(root, slug.name);
|
|
20250
20441
|
let files;
|
|
20251
20442
|
try {
|
|
20252
20443
|
files = fs32.readdirSync(dir);
|
|
@@ -20256,7 +20447,7 @@ function discover6(override) {
|
|
|
20256
20447
|
for (const file of files) {
|
|
20257
20448
|
if (!file.endsWith(".jsonl"))
|
|
20258
20449
|
continue;
|
|
20259
|
-
const full =
|
|
20450
|
+
const full = path26.join(dir, file);
|
|
20260
20451
|
let stat;
|
|
20261
20452
|
try {
|
|
20262
20453
|
stat = fs32.statSync(full);
|
|
@@ -20281,13 +20472,13 @@ function discover6(override) {
|
|
|
20281
20472
|
return out;
|
|
20282
20473
|
}
|
|
20283
20474
|
function sessionIdFromFilename(file) {
|
|
20284
|
-
const base2 =
|
|
20475
|
+
const base2 = path26.basename(file, ".jsonl");
|
|
20285
20476
|
const at2 = base2.lastIndexOf("_");
|
|
20286
20477
|
return at2 === -1 ? base2 : base2.slice(at2 + 1);
|
|
20287
20478
|
}
|
|
20288
20479
|
async function parse6(source, options = {}) {
|
|
20289
20480
|
const src = typeof source === "string" ? void 0 : source;
|
|
20290
|
-
const absolute2 =
|
|
20481
|
+
const absolute2 = path26.resolve(typeof source === "string" ? source : source.path);
|
|
20291
20482
|
const unknownTypes = {};
|
|
20292
20483
|
let malformedLines = 0;
|
|
20293
20484
|
let endOffset = 0;
|
|
@@ -20364,7 +20555,7 @@ async function parse6(source, options = {}) {
|
|
|
20364
20555
|
title = node.record.name;
|
|
20365
20556
|
}
|
|
20366
20557
|
}
|
|
20367
|
-
const projectSlug = options.projectSlug ?? src?.projectSlug ??
|
|
20558
|
+
const projectSlug = options.projectSlug ?? src?.projectSlug ?? path26.basename(path26.dirname(absolute2));
|
|
20368
20559
|
const headerCwd = header && typeof header.cwd === "string" ? header.cwd : void 0;
|
|
20369
20560
|
const startedAt = header && typeof header.timestamp === "string" ? header.timestamp : nodes[0]?.ts ?? "";
|
|
20370
20561
|
let endedAt = startedAt;
|
|
@@ -20599,7 +20790,7 @@ __export(gemini_exports, {
|
|
|
20599
20790
|
sourceDir: () => sourceDir5
|
|
20600
20791
|
});
|
|
20601
20792
|
import fs33 from "node:fs";
|
|
20602
|
-
import
|
|
20793
|
+
import path27 from "node:path";
|
|
20603
20794
|
import crypto6 from "node:crypto";
|
|
20604
20795
|
function sourceDir5(override) {
|
|
20605
20796
|
return geminiTmpDir(override);
|
|
@@ -20616,7 +20807,7 @@ function discover7(override) {
|
|
|
20616
20807
|
for (const hash4 of hashes) {
|
|
20617
20808
|
if (!hash4.isDirectory())
|
|
20618
20809
|
continue;
|
|
20619
|
-
const dir =
|
|
20810
|
+
const dir = path27.join(root, hash4.name, CHATS_DIR);
|
|
20620
20811
|
let files;
|
|
20621
20812
|
try {
|
|
20622
20813
|
files = fs33.readdirSync(dir);
|
|
@@ -20626,7 +20817,7 @@ function discover7(override) {
|
|
|
20626
20817
|
for (const file of files) {
|
|
20627
20818
|
if (!file.endsWith(".json"))
|
|
20628
20819
|
continue;
|
|
20629
|
-
const full =
|
|
20820
|
+
const full = path27.join(dir, file);
|
|
20630
20821
|
let stat;
|
|
20631
20822
|
try {
|
|
20632
20823
|
stat = fs33.statSync(full);
|
|
@@ -20651,12 +20842,12 @@ function discover7(override) {
|
|
|
20651
20842
|
return out;
|
|
20652
20843
|
}
|
|
20653
20844
|
function sessionIdFromFilename2(file, projectHash) {
|
|
20654
|
-
const base2 =
|
|
20845
|
+
const base2 = path27.basename(file, ".json").replace(/^checkpoint-/, "") || "checkpoint";
|
|
20655
20846
|
return `${projectHash.slice(0, 12)}-${base2}`;
|
|
20656
20847
|
}
|
|
20657
20848
|
async function parse7(source, options = {}) {
|
|
20658
20849
|
const src = typeof source === "string" ? void 0 : source;
|
|
20659
|
-
const absolute2 =
|
|
20850
|
+
const absolute2 = path27.resolve(typeof source === "string" ? source : source.path);
|
|
20660
20851
|
const unknownTypes = {};
|
|
20661
20852
|
let malformedLines = 0;
|
|
20662
20853
|
let raw = "";
|
|
@@ -20677,7 +20868,7 @@ async function parse7(source, options = {}) {
|
|
|
20677
20868
|
const { turns, meta } = unwrap(doc);
|
|
20678
20869
|
if (doc !== void 0 && turns.length === 0 && !meta)
|
|
20679
20870
|
malformedLines += 1;
|
|
20680
|
-
const projectSlug = options.projectSlug ?? src?.projectSlug ??
|
|
20871
|
+
const projectSlug = options.projectSlug ?? src?.projectSlug ?? path27.basename(path27.dirname(path27.dirname(absolute2)));
|
|
20681
20872
|
const sessionId = options.sessionId ?? (meta && typeof meta.sessionId === "string" && meta.sessionId.trim() ? meta.sessionId : sessionIdFromFilename2(absolute2, projectSlug));
|
|
20682
20873
|
const mtimeMs = options.mtimeMs ?? src?.mtimeMs ?? statMtime2(absolute2);
|
|
20683
20874
|
const fileTime = new Date(mtimeMs).toISOString();
|
|
@@ -20873,7 +21064,7 @@ function isHumanTurn(role, parts) {
|
|
|
20873
21064
|
function projectHashes(cwd) {
|
|
20874
21065
|
const sha = (s) => crypto6.createHash("sha256").update(s).digest("hex");
|
|
20875
21066
|
const trimmed = cwd.length > 1 ? cwd.replace(/[/\\]+$/, "") : cwd;
|
|
20876
|
-
return uniq([sha(cwd), sha(trimmed), sha(trimmed +
|
|
21067
|
+
return uniq([sha(cwd), sha(trimmed), sha(trimmed + path27.sep)]);
|
|
20877
21068
|
}
|
|
20878
21069
|
function recoverCwd2(projectHash, candidates2) {
|
|
20879
21070
|
if (!/^[0-9a-f]{16,}$/i.test(projectHash))
|
|
@@ -20881,15 +21072,15 @@ function recoverCwd2(projectHash, candidates2) {
|
|
|
20881
21072
|
const seen = /* @__PURE__ */ new Set();
|
|
20882
21073
|
const dirs = [];
|
|
20883
21074
|
for (const c of candidates2) {
|
|
20884
|
-
if (!
|
|
21075
|
+
if (!path27.isAbsolute(c))
|
|
20885
21076
|
continue;
|
|
20886
|
-
let dir =
|
|
21077
|
+
let dir = path27.dirname(path27.resolve(c));
|
|
20887
21078
|
for (let i = 0; i < 40; i += 1) {
|
|
20888
21079
|
if (seen.has(dir))
|
|
20889
21080
|
break;
|
|
20890
21081
|
seen.add(dir);
|
|
20891
21082
|
dirs.push(dir);
|
|
20892
|
-
const up =
|
|
21083
|
+
const up = path27.dirname(dir);
|
|
20893
21084
|
if (up === dir)
|
|
20894
21085
|
break;
|
|
20895
21086
|
dir = up;
|
|
@@ -20964,7 +21155,7 @@ var init_gemini = __esm({
|
|
|
20964
21155
|
|
|
20965
21156
|
// packages/core/dist/memory/history.js
|
|
20966
21157
|
import fs34 from "node:fs";
|
|
20967
|
-
import
|
|
21158
|
+
import path28 from "node:path";
|
|
20968
21159
|
import crypto7 from "node:crypto";
|
|
20969
21160
|
function captureHistoryEvidence(db, options) {
|
|
20970
21161
|
if (!fs34.existsSync(options.historyPath))
|
|
@@ -21015,10 +21206,10 @@ function captureHistoryEvidence(db, options) {
|
|
|
21015
21206
|
const current = db.prepare("SELECT s.active_revision_id,r.adapter_version FROM memory_sources s LEFT JOIN source_revisions r ON r.revision_id=s.active_revision_id WHERE s.source_id=?").get(sid);
|
|
21016
21207
|
if (current?.active_revision_id && !isHistoryVersion(current.adapter_version ?? "") && current.adapter_version !== "ghost-retained-prompts-v1")
|
|
21017
21208
|
continue;
|
|
21018
|
-
const bytes3 = Buffer.concat(g.raw),
|
|
21019
|
-
fs34.mkdirSync(
|
|
21209
|
+
const bytes3 = Buffer.concat(g.raw), digest3 = hash(bytes3), relative = path28.join("archive", "evidence", `${digest3}.jsonl`), file = path28.join(options.root, relative);
|
|
21210
|
+
fs34.mkdirSync(path28.dirname(file), { recursive: true, mode: 448 });
|
|
21020
21211
|
if (fs34.existsSync(file)) {
|
|
21021
|
-
if (hash(fs34.readFileSync(file)) !==
|
|
21212
|
+
if (hash(fs34.readFileSync(file)) !== digest3)
|
|
21022
21213
|
throw new Error("history artifact corruption");
|
|
21023
21214
|
} else {
|
|
21024
21215
|
const tmp = `${file}.${crypto7.randomUUID()}.tmp`;
|
|
@@ -21031,7 +21222,7 @@ function captureHistoryEvidence(db, options) {
|
|
|
21031
21222
|
fs34.closeSync(fd);
|
|
21032
21223
|
}
|
|
21033
21224
|
fs34.renameSync(tmp, file);
|
|
21034
|
-
const dir = fs34.openSync(
|
|
21225
|
+
const dir = fs34.openSync(path28.dirname(file), "r");
|
|
21035
21226
|
try {
|
|
21036
21227
|
fs34.fsyncSync(dir);
|
|
21037
21228
|
} finally {
|
|
@@ -21047,13 +21238,13 @@ function captureHistoryEvidence(db, options) {
|
|
|
21047
21238
|
const dates = g.records.map((r) => r.eventAt).filter((s) => !!s).sort();
|
|
21048
21239
|
const parsed = { session: { id: native, harness: options.harness, sourcePath: options.historyPath, project: g.project, projectSlug: "", startedAt: dates[0] ?? "", endedAt: dates.at(-1) ?? "", isSidechain: false, status: "ghost", counts: { userPrompts: g.records.length, assistantTurns: 0, toolCalls: 0, bytes: g.bytes } }, records: g.records, exchanges: [], evidenceVersion: `${options.harness}-history-records-v1`, unknownTypes: {}, malformedLines: 0, endOffset: g.bytes };
|
|
21049
21240
|
const prior = db.prepare("SELECT artifact_hash,adapter_version,normalization_version,coverage_gaps_json FROM source_revisions WHERE revision_id=?").get(current?.active_revision_id ?? "");
|
|
21050
|
-
if (prior?.artifact_hash ===
|
|
21241
|
+
if (prior?.artifact_hash === digest3 && prior.adapter_version === parsed.evidenceVersion && prior.normalization_version === NORMALIZATION_VERSION && hasCurrentSpanManifest(prior.coverage_gaps_json, options.tokenizer))
|
|
21051
21242
|
continue;
|
|
21052
21243
|
const compatible = [];
|
|
21053
21244
|
let older = false;
|
|
21054
21245
|
for (const row2 of db.prepare("SELECT revision_id,artifact_hash,archive_relative_path FROM source_revisions WHERE source_id=? AND adapter_version LIKE '%-history-records-v1' AND archive_relative_path IS NOT NULL").all(sid)) {
|
|
21055
|
-
const original =
|
|
21056
|
-
if (!original.startsWith(
|
|
21246
|
+
const original = path28.resolve(options.root, row2.archive_relative_path);
|
|
21247
|
+
if (!original.startsWith(path28.resolve(options.root) + path28.sep))
|
|
21057
21248
|
continue;
|
|
21058
21249
|
try {
|
|
21059
21250
|
const priorBytes = fs34.readFileSync(original);
|
|
@@ -21068,7 +21259,7 @@ function captureHistoryEvidence(db, options) {
|
|
|
21068
21259
|
} catch {
|
|
21069
21260
|
}
|
|
21070
21261
|
}
|
|
21071
|
-
publishSource(db, { parsed, prefixCompatibleArtifactHashes: compatible, olderArchivedPrefix: older, artifactHash:
|
|
21262
|
+
publishSource(db, { parsed, prefixCompatibleArtifactHashes: compatible, olderArchivedPrefix: older, artifactHash: digest3, artifactBytes: g.bytes, archiveRelativePath: relative, expectedActiveRevisionId: current?.active_revision_id ?? null, beforeCommit: options.beforeCommit, tokenizer: options.tokenizer, sourceCompleteness: "complete" });
|
|
21072
21263
|
captured++;
|
|
21073
21264
|
}
|
|
21074
21265
|
db.transaction(() => {
|
|
@@ -21167,7 +21358,7 @@ var init_backfill = __esm({
|
|
|
21167
21358
|
|
|
21168
21359
|
// packages/core/dist/memory/tokenization.js
|
|
21169
21360
|
import fs35 from "node:fs";
|
|
21170
|
-
import
|
|
21361
|
+
import path29 from "node:path";
|
|
21171
21362
|
import { createHash as createHash13 } from "node:crypto";
|
|
21172
21363
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
21173
21364
|
function inspectSpanTokenizerHash(cacheDir) {
|
|
@@ -21175,7 +21366,7 @@ function inspectSpanTokenizerHash(cacheDir) {
|
|
|
21175
21366
|
for (const name of [`${MODEL_ID}/tokenizer.json`, `${MODEL_ID}/tokenizer_config.json`, `${RUNTIME_SUBDIR}/tokenizers.mjs`]) {
|
|
21176
21367
|
const file = requiredFiles().find((asset) => asset.name === name);
|
|
21177
21368
|
try {
|
|
21178
|
-
const bytes3 = fs35.readFileSync(
|
|
21369
|
+
const bytes3 = fs35.readFileSync(path29.join(cacheDir, name));
|
|
21179
21370
|
if (bytes3.length !== file.bytes || createHash13("sha256").update(bytes3).digest("hex") !== file.sha256)
|
|
21180
21371
|
return null;
|
|
21181
21372
|
blobs.push(bytes3);
|
|
@@ -21192,7 +21383,7 @@ async function loadSpanTokenizer(cacheDir) {
|
|
|
21192
21383
|
const file = requiredFiles().find((asset) => asset.name === name);
|
|
21193
21384
|
let bytes3;
|
|
21194
21385
|
try {
|
|
21195
|
-
bytes3 = fs35.readFileSync(
|
|
21386
|
+
bytes3 = fs35.readFileSync(path29.join(cacheDir, name));
|
|
21196
21387
|
} catch {
|
|
21197
21388
|
return null;
|
|
21198
21389
|
}
|
|
@@ -21200,7 +21391,7 @@ async function loadSpanTokenizer(cacheDir) {
|
|
|
21200
21391
|
return null;
|
|
21201
21392
|
blobs.push(bytes3);
|
|
21202
21393
|
}
|
|
21203
|
-
const runtime = await import(pathToFileURL2(
|
|
21394
|
+
const runtime = await import(pathToFileURL2(path29.join(cacheDir, names[2])).href);
|
|
21204
21395
|
const tokenizer2 = new runtime.Tokenizer(JSON.parse(blobs[0].toString()), JSON.parse(blobs[1].toString()));
|
|
21205
21396
|
const assetHash = createHash13("sha256").update(blobs[0]).update(blobs[1]).update(blobs[2]).digest("hex");
|
|
21206
21397
|
return {
|
|
@@ -21530,13 +21721,13 @@ var init_sentinel = __esm({
|
|
|
21530
21721
|
|
|
21531
21722
|
// packages/core/dist/cards/write.js
|
|
21532
21723
|
import fs37 from "node:fs";
|
|
21533
|
-
import
|
|
21724
|
+
import path30 from "node:path";
|
|
21534
21725
|
function cardEmbeddingText(card) {
|
|
21535
21726
|
return [card.title, card.summary, card.topics.join(", ")].filter((s) => s.trim()).join("\n");
|
|
21536
21727
|
}
|
|
21537
21728
|
function cardPath(root, harness, slug, id) {
|
|
21538
21729
|
const filename = id.replace(/[%/\\\0]/g, (c) => encodeURIComponent(c));
|
|
21539
|
-
return
|
|
21730
|
+
return path30.join(cardsDir(root), harness, safeSlug(slug), `${filename}.md`);
|
|
21540
21731
|
}
|
|
21541
21732
|
function safeSlug(slug) {
|
|
21542
21733
|
const segments = (slug ?? "").split(/[/\\]+/).map((part) => part.trim()).filter((part) => part.length > 0 && part !== "." && part !== "..");
|
|
@@ -21660,7 +21851,7 @@ function writeCard(db, root, record4, embedding) {
|
|
|
21660
21851
|
});
|
|
21661
21852
|
write();
|
|
21662
21853
|
const file = cardPath(root, record4.harness, record4.projectSlug, record4.sessionId);
|
|
21663
|
-
fs37.mkdirSync(
|
|
21854
|
+
fs37.mkdirSync(path30.dirname(file), { recursive: true });
|
|
21664
21855
|
fs37.writeFileSync(file, md, { mode: 384 });
|
|
21665
21856
|
return file;
|
|
21666
21857
|
}
|
|
@@ -21679,8 +21870,8 @@ function exportCards(root, dest) {
|
|
|
21679
21870
|
return result;
|
|
21680
21871
|
const walk3 = (dir, rel) => {
|
|
21681
21872
|
for (const entry of fs37.readdirSync(dir, { withFileTypes: true })) {
|
|
21682
|
-
const source =
|
|
21683
|
-
const relative =
|
|
21873
|
+
const source = path30.join(dir, entry.name);
|
|
21874
|
+
const relative = path30.join(rel, entry.name);
|
|
21684
21875
|
if (entry.isDirectory()) {
|
|
21685
21876
|
walk3(source, relative);
|
|
21686
21877
|
continue;
|
|
@@ -21698,8 +21889,8 @@ function exportCards(root, dest) {
|
|
|
21698
21889
|
result.skipped += 1;
|
|
21699
21890
|
continue;
|
|
21700
21891
|
}
|
|
21701
|
-
const target =
|
|
21702
|
-
fs37.mkdirSync(
|
|
21892
|
+
const target = path30.join(dest, relative);
|
|
21893
|
+
fs37.mkdirSync(path30.dirname(target), { recursive: true });
|
|
21703
21894
|
fs37.writeFileSync(target, content2, { mode: 384 });
|
|
21704
21895
|
result.files += 1;
|
|
21705
21896
|
result.bytes += Buffer.byteLength(content2);
|
|
@@ -22349,7 +22540,7 @@ var init_threads = __esm({
|
|
|
22349
22540
|
// packages/core/dist/ingest.js
|
|
22350
22541
|
import crypto8 from "node:crypto";
|
|
22351
22542
|
import fs38 from "node:fs";
|
|
22352
|
-
import
|
|
22543
|
+
import path31 from "node:path";
|
|
22353
22544
|
function adapterSpecs(o = {}) {
|
|
22354
22545
|
return [
|
|
22355
22546
|
{
|
|
@@ -22815,7 +23006,7 @@ async function indexHarness(db, spec, options, recordTypes) {
|
|
|
22815
23006
|
harness: spec.harness,
|
|
22816
23007
|
done,
|
|
22817
23008
|
total: sources.length,
|
|
22818
|
-
note:
|
|
23009
|
+
note: path31.basename(source.path)
|
|
22819
23010
|
});
|
|
22820
23011
|
if (db.prepare("SELECT 1 FROM forget_tombstones WHERE source_id=? AND state<>'reversed'").get(sourceId(source.harness, source.sessionId))) {
|
|
22821
23012
|
report.skipped += 1;
|
|
@@ -22852,10 +23043,10 @@ async function indexHarness(db, spec, options, recordTypes) {
|
|
|
22852
23043
|
let scratch;
|
|
22853
23044
|
try {
|
|
22854
23045
|
if (source.harness === "claude" || source.harness === "codex") {
|
|
22855
|
-
const scratchRoot =
|
|
23046
|
+
const scratchRoot = path31.join(options.root ?? potsherdDir(options.potsherdDir), "capture-scratch");
|
|
22856
23047
|
fs38.mkdirSync(scratchRoot, { recursive: true, mode: 448 });
|
|
22857
|
-
scratch = fs38.mkdtempSync(
|
|
22858
|
-
const file =
|
|
23048
|
+
scratch = fs38.mkdtempSync(path31.join(scratchRoot, "capture-"));
|
|
23049
|
+
const file = path31.join(scratch, path31.basename(source.path));
|
|
22859
23050
|
fs38.writeFileSync(file, raw, { mode: 384 });
|
|
22860
23051
|
capturedSource = { ...source, path: file, bytes: raw.length };
|
|
22861
23052
|
}
|
|
@@ -23195,8 +23386,8 @@ function recordCaptureFailure(db, source, errorCode, fence) {
|
|
|
23195
23386
|
})();
|
|
23196
23387
|
}
|
|
23197
23388
|
function preserveEvidenceArtifact(root, artifactHash, bytes3) {
|
|
23198
|
-
const relative =
|
|
23199
|
-
fs38.mkdirSync(
|
|
23389
|
+
const relative = path31.join("archive", "evidence", `${artifactHash}.jsonl`), file = path31.join(root, relative);
|
|
23390
|
+
fs38.mkdirSync(path31.dirname(file), { recursive: true, mode: 448 });
|
|
23200
23391
|
if (fs38.existsSync(file)) {
|
|
23201
23392
|
if (hash(fs38.readFileSync(file)) !== artifactHash)
|
|
23202
23393
|
throw new Error("immutable archive hash mismatch");
|
|
@@ -23212,7 +23403,7 @@ function preserveEvidenceArtifact(root, artifactHash, bytes3) {
|
|
|
23212
23403
|
fs38.closeSync(fd);
|
|
23213
23404
|
}
|
|
23214
23405
|
fs38.renameSync(temp, file);
|
|
23215
|
-
const dir = fs38.openSync(
|
|
23406
|
+
const dir = fs38.openSync(path31.dirname(file), "r");
|
|
23216
23407
|
try {
|
|
23217
23408
|
fs38.fsyncSync(dir);
|
|
23218
23409
|
} finally {
|
|
@@ -23244,13 +23435,13 @@ function resolveEnrolledSources(db, input) {
|
|
|
23244
23435
|
const options = { ...prior?.options ?? {} };
|
|
23245
23436
|
for (const h of harnesses) {
|
|
23246
23437
|
const key2 = names[h];
|
|
23247
|
-
options[key2] =
|
|
23438
|
+
options[key2] = path31.resolve(input[key2] ?? options[key2] ?? defaults[h]());
|
|
23248
23439
|
}
|
|
23249
23440
|
const removed = new Set(input.removeHarnesses ?? []);
|
|
23250
23441
|
const savedHarnesses = [.../* @__PURE__ */ new Set([...prior?.harnesses ?? harnesses, ...explicit, ...input.enrollHarnesses ?? []])].filter((h) => !removed.has(h));
|
|
23251
23442
|
for (const h of savedHarnesses) {
|
|
23252
23443
|
const key2 = names[h];
|
|
23253
|
-
options[key2] =
|
|
23444
|
+
options[key2] = path31.resolve(input[key2] ?? options[key2] ?? defaults[h]());
|
|
23254
23445
|
}
|
|
23255
23446
|
const enrollment = { version: 1, harnesses: savedHarnesses, options };
|
|
23256
23447
|
if (!prior || explicit.length || input.enrollHarnesses || input.removeHarnesses) {
|
|
@@ -23291,13 +23482,13 @@ function sourcePrefixProof(db, root, sid, incoming) {
|
|
|
23291
23482
|
let olderThanActive = false;
|
|
23292
23483
|
let retainedArchivePath;
|
|
23293
23484
|
for (const r of rows) {
|
|
23294
|
-
const file =
|
|
23295
|
-
if (!file.startsWith(
|
|
23485
|
+
const file = path31.resolve(root, r.archive_relative_path);
|
|
23486
|
+
if (!file.startsWith(path31.resolve(root) + path31.sep) || !r.archive_relative_path.startsWith("archive/"))
|
|
23296
23487
|
continue;
|
|
23297
23488
|
let fd;
|
|
23298
23489
|
try {
|
|
23299
23490
|
fd = fs38.openSync(file, "r");
|
|
23300
|
-
const
|
|
23491
|
+
const digest3 = crypto8.createHash("sha256");
|
|
23301
23492
|
const chunk = Buffer.alloc(65536);
|
|
23302
23493
|
let offset = 0;
|
|
23303
23494
|
let equal = true;
|
|
@@ -23305,13 +23496,13 @@ function sourcePrefixProof(db, root, sid, incoming) {
|
|
|
23305
23496
|
const count2 = fs38.readSync(fd, chunk, 0, chunk.length, null);
|
|
23306
23497
|
if (count2 === 0)
|
|
23307
23498
|
break;
|
|
23308
|
-
|
|
23499
|
+
digest3.update(chunk.subarray(0, count2));
|
|
23309
23500
|
const end = Math.min(offset + count2, incoming.length);
|
|
23310
23501
|
if (offset < incoming.length && !chunk.subarray(0, end - offset).equals(incoming.subarray(offset, end)))
|
|
23311
23502
|
equal = false;
|
|
23312
23503
|
offset += count2;
|
|
23313
23504
|
}
|
|
23314
|
-
if (offset !== r.artifact_bytes ||
|
|
23505
|
+
if (offset !== r.artifact_bytes || digest3.digest("hex") !== r.artifact_hash || !equal)
|
|
23315
23506
|
continue;
|
|
23316
23507
|
compatibleHashes.push(r.artifact_hash);
|
|
23317
23508
|
if (r.active && incoming.length < offset) {
|
|
@@ -23339,7 +23530,7 @@ function discoverEnrolledHistoryInputs(db, root) {
|
|
|
23339
23530
|
const dir = harness === "claude" ? enrolled.options.claudeDir : enrolled.options.codexHome;
|
|
23340
23531
|
if (!dir)
|
|
23341
23532
|
continue;
|
|
23342
|
-
const live =
|
|
23533
|
+
const live = path31.join(dir, "history.jsonl"), fallback = path31.join(root, "archive", "history.jsonl");
|
|
23343
23534
|
const historyPath = fs38.existsSync(live) ? live : harness === "claude" ? fallback : live;
|
|
23344
23535
|
if (fs38.existsSync(historyPath))
|
|
23345
23536
|
inputs.push({ harness, historyPath });
|
|
@@ -26568,7 +26759,7 @@ var init_pipeline = __esm({
|
|
|
26568
26759
|
|
|
26569
26760
|
// packages/core/dist/cards/run.js
|
|
26570
26761
|
import fs40 from "node:fs";
|
|
26571
|
-
import
|
|
26762
|
+
import path32 from "node:path";
|
|
26572
26763
|
async function runCards(db, llm, options) {
|
|
26573
26764
|
const started = Date.now();
|
|
26574
26765
|
const kinds2 = new Set(options.kinds ?? ["session", "ghost"]);
|
|
@@ -26757,7 +26948,7 @@ function absorb2(report, result, target, file) {
|
|
|
26757
26948
|
function writeSentinel(root, target, error) {
|
|
26758
26949
|
try {
|
|
26759
26950
|
const file = cardPath(root, target.harness, projectSlugOf(target), target.id);
|
|
26760
|
-
fs40.mkdirSync(
|
|
26951
|
+
fs40.mkdirSync(path32.dirname(file), { recursive: true });
|
|
26761
26952
|
fs40.writeFileSync(file, formatErrorSentinel(error), { mode: 384 });
|
|
26762
26953
|
} catch {
|
|
26763
26954
|
}
|
|
@@ -28811,7 +29002,7 @@ var init_ask2 = __esm({
|
|
|
28811
29002
|
|
|
28812
29003
|
// packages/core/dist/graft.js
|
|
28813
29004
|
import fs41 from "node:fs";
|
|
28814
|
-
import
|
|
29005
|
+
import path33 from "node:path";
|
|
28815
29006
|
import process10 from "node:process";
|
|
28816
29007
|
import { spawnSync } from "node:child_process";
|
|
28817
29008
|
function expandCitationGroups(line2) {
|
|
@@ -29256,15 +29447,15 @@ function cardOnlyBody(src) {
|
|
|
29256
29447
|
return out;
|
|
29257
29448
|
}
|
|
29258
29449
|
function graftDir(cwd = process10.cwd()) {
|
|
29259
|
-
return
|
|
29450
|
+
return path33.join(cwd, ".potsherd");
|
|
29260
29451
|
}
|
|
29261
29452
|
function graftPath(id8, cwd = process10.cwd()) {
|
|
29262
|
-
return
|
|
29453
|
+
return path33.join(graftDir(cwd), `graft-${id8}.md`);
|
|
29263
29454
|
}
|
|
29264
29455
|
function ensureGraftDir(cwd = process10.cwd()) {
|
|
29265
29456
|
const dir = graftDir(cwd);
|
|
29266
29457
|
fs41.mkdirSync(dir, { recursive: true });
|
|
29267
|
-
const ignore =
|
|
29458
|
+
const ignore = path33.join(dir, ".gitignore");
|
|
29268
29459
|
if (fs41.existsSync(ignore))
|
|
29269
29460
|
return { dir, wroteGitignore: false };
|
|
29270
29461
|
fs41.writeFileSync(ignore, GITIGNORE_BODY, { mode: 384 });
|
|
@@ -29710,7 +29901,7 @@ __export(setup_exports, {
|
|
|
29710
29901
|
tomlWithout: () => tomlWithout
|
|
29711
29902
|
});
|
|
29712
29903
|
import fs42 from "node:fs";
|
|
29713
|
-
import
|
|
29904
|
+
import path34 from "node:path";
|
|
29714
29905
|
import process11 from "node:process";
|
|
29715
29906
|
function resolveMcpServer(entry = process11.argv[1], env = process11.env) {
|
|
29716
29907
|
const found = onPath(MCP_BIN, env);
|
|
@@ -29729,43 +29920,43 @@ function resolveMcpServer(entry = process11.argv[1], env = process11.env) {
|
|
|
29729
29920
|
return { command: MCP_BIN, args: [], via: "assumed", exists: false };
|
|
29730
29921
|
}
|
|
29731
29922
|
function findMcpEntry(entry) {
|
|
29732
|
-
const start = entry && fs42.existsSync(entry) ?
|
|
29923
|
+
const start = entry && fs42.existsSync(entry) ? path34.dirname(path34.resolve(entry)) : process11.cwd();
|
|
29733
29924
|
let dir = start;
|
|
29734
29925
|
let workspace = null;
|
|
29735
|
-
const bundled =
|
|
29736
|
-
if (
|
|
29926
|
+
const bundled = path34.join(start, "mcp.js");
|
|
29927
|
+
if (path34.basename(start) === "dist" && fs42.existsSync(bundled)) {
|
|
29737
29928
|
return { file: bundled, exists: true };
|
|
29738
29929
|
}
|
|
29739
29930
|
for (let i = 0; i < 8; i++) {
|
|
29740
29931
|
for (const rel of [MCP_ENTRY_RELATIVE, MCP_PACKAGE_RELATIVE]) {
|
|
29741
|
-
const candidate =
|
|
29932
|
+
const candidate = path34.join(dir, rel);
|
|
29742
29933
|
if (fs42.existsSync(candidate))
|
|
29743
29934
|
return { file: candidate, exists: true };
|
|
29744
29935
|
}
|
|
29745
|
-
if (!dir.split(
|
|
29936
|
+
if (!dir.split(path34.sep).includes("node_modules") && fs42.existsSync(path34.join(dir, "package.json")) && fs42.existsSync(path34.join(dir, "packages"))) {
|
|
29746
29937
|
workspace = dir;
|
|
29747
29938
|
break;
|
|
29748
29939
|
}
|
|
29749
|
-
const up =
|
|
29940
|
+
const up = path34.dirname(dir);
|
|
29750
29941
|
if (up === dir)
|
|
29751
29942
|
break;
|
|
29752
29943
|
dir = up;
|
|
29753
29944
|
}
|
|
29754
|
-
return { file: workspace ?
|
|
29945
|
+
return { file: workspace ? path34.join(workspace, MCP_ENTRY_RELATIVE) : null, exists: false };
|
|
29755
29946
|
}
|
|
29756
29947
|
function stdio(res) {
|
|
29757
29948
|
return { command: res.command, args: [...res.args] };
|
|
29758
29949
|
}
|
|
29759
29950
|
function opencodeConfigDir(env = process11.env) {
|
|
29760
29951
|
const xdg = env["XDG_CONFIG_HOME"];
|
|
29761
|
-
const base2 = xdg && xdg.trim() ?
|
|
29762
|
-
return
|
|
29952
|
+
const base2 = xdg && xdg.trim() ? path34.resolve(expandTilde(xdg.trim())) : path34.join(home(), ".config");
|
|
29953
|
+
return path34.join(base2, "opencode");
|
|
29763
29954
|
}
|
|
29764
29955
|
function claudeJsonPath(dir, env = process11.env) {
|
|
29765
29956
|
const override = dir ?? (env["CLAUDE_CONFIG_DIR"]?.trim() || void 0);
|
|
29766
29957
|
if (override)
|
|
29767
|
-
return
|
|
29768
|
-
return
|
|
29958
|
+
return path34.join(claudeDir(override), ".claude.json");
|
|
29959
|
+
return path34.join(home(), ".claude.json");
|
|
29769
29960
|
}
|
|
29770
29961
|
function clientSpec(id) {
|
|
29771
29962
|
const spec = CLIENTS.find((c) => c.id === id);
|
|
@@ -29827,7 +30018,7 @@ function commandRunnable(command) {
|
|
|
29827
30018
|
} else if (onPath(bin) === null) {
|
|
29828
30019
|
return false;
|
|
29829
30020
|
}
|
|
29830
|
-
const script = command.trim().split(/\s+/).slice(1).find((a) => a.includes(
|
|
30021
|
+
const script = command.trim().split(/\s+/).slice(1).find((a) => a.includes(path34.sep));
|
|
29831
30022
|
if (script)
|
|
29832
30023
|
return fs42.existsSync(script);
|
|
29833
30024
|
return true;
|
|
@@ -30060,7 +30251,7 @@ function applySetupPlan(plan, now = /* @__PURE__ */ new Date()) {
|
|
|
30060
30251
|
backup = backupPath(plan.path, now);
|
|
30061
30252
|
fs42.copyFileSync(plan.path, backup);
|
|
30062
30253
|
} else {
|
|
30063
|
-
fs42.mkdirSync(
|
|
30254
|
+
fs42.mkdirSync(path34.dirname(plan.path), { recursive: true });
|
|
30064
30255
|
}
|
|
30065
30256
|
fs42.writeFileSync(plan.path, plan.after, { mode: 384 });
|
|
30066
30257
|
return { written: true, backup };
|
|
@@ -30088,8 +30279,8 @@ var init_setup = __esm({
|
|
|
30088
30279
|
init_resolve_bin();
|
|
30089
30280
|
SERVER_NAME = "potsherd";
|
|
30090
30281
|
MCP_BIN = "potsherd-mcp";
|
|
30091
|
-
MCP_ENTRY_RELATIVE =
|
|
30092
|
-
MCP_PACKAGE_RELATIVE =
|
|
30282
|
+
MCP_ENTRY_RELATIVE = path34.join("packages", "mcp", "dist", "index.js");
|
|
30283
|
+
MCP_PACKAGE_RELATIVE = path34.join("node_modules", "@potsherd", "mcp", "dist", "index.js");
|
|
30093
30284
|
CLIENTS = [
|
|
30094
30285
|
{
|
|
30095
30286
|
id: "claude",
|
|
@@ -30111,7 +30302,7 @@ var init_setup = __esm({
|
|
|
30111
30302
|
bins: ["codex"],
|
|
30112
30303
|
verified: "config",
|
|
30113
30304
|
evidenceNote: "read from a real ~/.codex/config.toml on this machine, which already carries two [mcp_servers.*] tables",
|
|
30114
|
-
configPath: () =>
|
|
30305
|
+
configPath: () => path34.join(codexDir(), "config.toml"),
|
|
30115
30306
|
homeDir: () => codexDir(),
|
|
30116
30307
|
entry: (res) => stdio(res)
|
|
30117
30308
|
},
|
|
@@ -30122,7 +30313,7 @@ var init_setup = __esm({
|
|
|
30122
30313
|
bins: ["cursor", "cursor-agent"],
|
|
30123
30314
|
verified: "config",
|
|
30124
30315
|
evidenceNote: "read from a real ~/.cursor/mcp.json on this machine",
|
|
30125
|
-
configPath: () =>
|
|
30316
|
+
configPath: () => path34.join(cursorDir(), "mcp.json"),
|
|
30126
30317
|
homeDir: () => cursorDir(),
|
|
30127
30318
|
jsonPath: ["mcpServers"],
|
|
30128
30319
|
entry: (res) => stdio(res),
|
|
@@ -30135,7 +30326,7 @@ var init_setup = __esm({
|
|
|
30135
30326
|
bins: ["gemini"],
|
|
30136
30327
|
verified: "docs",
|
|
30137
30328
|
evidenceNote: "documentation only: no gemini on this machine, and no settings.json to read",
|
|
30138
|
-
configPath: () =>
|
|
30329
|
+
configPath: () => path34.join(geminiDir(), "settings.json"),
|
|
30139
30330
|
homeDir: () => geminiDir(),
|
|
30140
30331
|
jsonPath: ["mcpServers"],
|
|
30141
30332
|
entry: (res) => stdio(res)
|
|
@@ -30147,7 +30338,7 @@ var init_setup = __esm({
|
|
|
30147
30338
|
bins: ["opencode"],
|
|
30148
30339
|
verified: "docs",
|
|
30149
30340
|
evidenceNote: "documentation only: no opencode on this machine, and no opencode.json to read",
|
|
30150
|
-
configPath: (env) =>
|
|
30341
|
+
configPath: (env) => path34.join(opencodeConfigDir(env), "opencode.json"),
|
|
30151
30342
|
homeDir: (env) => opencodeConfigDir(env),
|
|
30152
30343
|
jsonPath: ["mcp"],
|
|
30153
30344
|
// opencode is the one schema here that is not `mcpServers`: the map is
|
|
@@ -30162,7 +30353,7 @@ var init_setup = __esm({
|
|
|
30162
30353
|
bins: ["copilot"],
|
|
30163
30354
|
verified: "docs",
|
|
30164
30355
|
evidenceNote: "documentation only: ~/.copilot exists here but holds no mcp-config.json, and copilot is not on PATH",
|
|
30165
|
-
configPath: () =>
|
|
30356
|
+
configPath: () => path34.join(copilotDir(), "mcp-config.json"),
|
|
30166
30357
|
homeDir: () => copilotDir(),
|
|
30167
30358
|
jsonPath: ["mcpServers"],
|
|
30168
30359
|
entry: (res) => ({ type: "local", ...stdio(res), tools: ["*"] })
|
|
@@ -30174,7 +30365,7 @@ var init_setup = __esm({
|
|
|
30174
30365
|
bins: ["pi"],
|
|
30175
30366
|
verified: "tool",
|
|
30176
30367
|
evidenceNote: "native pi 0.74.0 loader/tool/lifecycle probe verified with synthetic MCP; model journey not qualified",
|
|
30177
|
-
configPath: () =>
|
|
30368
|
+
configPath: () => path34.join(piDir(), "agent", "extensions", "potsherd.ts"),
|
|
30178
30369
|
homeDir: () => piDir(),
|
|
30179
30370
|
entry: (res) => stdio(res)
|
|
30180
30371
|
}
|
|
@@ -30203,15 +30394,15 @@ __export(stack_exports, {
|
|
|
30203
30394
|
toolSpec: () => toolSpec
|
|
30204
30395
|
});
|
|
30205
30396
|
import { existsSync } from "node:fs";
|
|
30206
|
-
import
|
|
30397
|
+
import path35 from "node:path";
|
|
30207
30398
|
import process12 from "node:process";
|
|
30208
30399
|
function claimLegend(verifiedOn = VERIFIED_ON) {
|
|
30209
30400
|
return `claim: potsherd's row was measured by running potsherd on this machine. every other row was read from that project's own documentation on ${verifiedOn} and was never run here. sources and fetch dates: ${CLAIM_SOURCE}`;
|
|
30210
30401
|
}
|
|
30211
30402
|
function episodicIndexPath(env = process12.env) {
|
|
30212
30403
|
const xdg = env["XDG_CONFIG_HOME"];
|
|
30213
|
-
const base2 = xdg && xdg.trim() ?
|
|
30214
|
-
return
|
|
30404
|
+
const base2 = xdg && xdg.trim() ? path35.resolve(expandTilde(xdg.trim())) : path35.join(home(), ".config");
|
|
30405
|
+
return path35.join(base2, "superpowers", "conversation-index", "db.sqlite");
|
|
30215
30406
|
}
|
|
30216
30407
|
function toolSpec(id) {
|
|
30217
30408
|
const spec = TOOLS.find((t) => t.id === id);
|
|
@@ -30370,7 +30561,7 @@ var init_stack = __esm({
|
|
|
30370
30561
|
verified: "docs",
|
|
30371
30562
|
evidenceNote: "README and the GitHub licence API, read " + VERIFIED_ON + "; not installed here, so nothing was exercised",
|
|
30372
30563
|
source: "https://github.com/thedotmack/claude-mem (README + api.github.com/repos)",
|
|
30373
|
-
markers: () => [
|
|
30564
|
+
markers: () => [path35.join(home(), ".claude-mem")],
|
|
30374
30565
|
coverage: ["no", "yes", "no", "no"],
|
|
30375
30566
|
note: "five hooks, injects at SessionStart. its README documents no import of transcripts from before install.",
|
|
30376
30567
|
capturesLive: true,
|
|
@@ -30390,8 +30581,8 @@ var init_stack = __esm({
|
|
|
30390
30581
|
// detector that only knows the wrong path reports "absent" on a machine
|
|
30391
30582
|
// where the tool is running.
|
|
30392
30583
|
markers: (env = process12.env) => [
|
|
30393
|
-
|
|
30394
|
-
process12.platform === "darwin" ?
|
|
30584
|
+
path35.join(home(), ".agentmemory"),
|
|
30585
|
+
process12.platform === "darwin" ? path35.join(home(), "Library", "Application Support", "agentmemory") : path35.join(env["XDG_DATA_HOME"]?.trim() ? expandTilde(env["XDG_DATA_HOME"].trim()) : path35.join(home(), ".local", "share"), "agentmemory")
|
|
30395
30586
|
],
|
|
30396
30587
|
coverage: ["no", "yes", "partial", "partial"],
|
|
30397
30588
|
note: "the only one here that backfills: `import-jsonl` reads ~/.claude/projects. only what the sweep left.",
|
|
@@ -30407,8 +30598,8 @@ var init_stack = __esm({
|
|
|
30407
30598
|
evidenceNote: "README and the GitHub licence API, read " + VERIFIED_ON + "; not installed here. needs postgres or its embedded pg0, so detection is weak",
|
|
30408
30599
|
source: "https://github.com/vectorize-io/hindsight (README + api.github.com/repos)",
|
|
30409
30600
|
markers: () => [
|
|
30410
|
-
|
|
30411
|
-
|
|
30601
|
+
path35.join(home(), ".hindsight"),
|
|
30602
|
+
path35.join(home(), ".pg0")
|
|
30412
30603
|
],
|
|
30413
30604
|
coverage: ["no", "yes", "no", "partial"],
|
|
30414
30605
|
note: "retain/recall per bank, one bank per project. no documented import of old transcripts.",
|
|
@@ -30441,7 +30632,7 @@ var init_stack = __esm({
|
|
|
30441
30632
|
verified: "docs",
|
|
30442
30633
|
evidenceNote: "README and the GitHub licence API, read " + VERIFIED_ON + "; not installed here. it is per-repo, so a home-directory marker is the weakest signal on this list",
|
|
30443
30634
|
source: "https://github.com/Autoloops/greplica (README + api.github.com/repos)",
|
|
30444
|
-
markers: () => [
|
|
30635
|
+
markers: () => [path35.join(home(), ".greplica")],
|
|
30445
30636
|
coverage: ["no", "partial", "no", "partial"],
|
|
30446
30637
|
note: 'one knowledge graph per repo. cannot answer "which project was that in".',
|
|
30447
30638
|
capturesLive: true,
|
|
@@ -30455,7 +30646,7 @@ var init_stack = __esm({
|
|
|
30455
30646
|
verified: "docs",
|
|
30456
30647
|
evidenceNote: "README and the GitHub licence API, read " + VERIFIED_ON + "; not installed here. its vault path is fixed, which makes the marker a strong one",
|
|
30457
30648
|
source: "https://github.com/m3talux/superbrain (README + api.github.com/repos)",
|
|
30458
|
-
markers: () => [
|
|
30649
|
+
markers: () => [path35.join(home(), ".superbrain")],
|
|
30459
30650
|
coverage: ["no", "yes", "no", "no"],
|
|
30460
30651
|
note: "obsidian vault at ~/.superbrain/vault, injects a brief at start. capture-only from install.",
|
|
30461
30652
|
capturesLive: true,
|
|
@@ -30470,8 +30661,8 @@ var init_stack = __esm({
|
|
|
30470
30661
|
evidenceNote: "the files themselves were found on this machine, and the behaviour read from code.claude.com/docs/en/memory on " + VERIFIED_ON,
|
|
30471
30662
|
source: "https://code.claude.com/docs/en/memory",
|
|
30472
30663
|
markers: () => [
|
|
30473
|
-
|
|
30474
|
-
|
|
30664
|
+
path35.join(claudeDir(), "CLAUDE.md"),
|
|
30665
|
+
path35.join(claudeDir(), "projects")
|
|
30475
30666
|
],
|
|
30476
30667
|
// The one row on this table with a documented immunity to the 30-day
|
|
30477
30668
|
// sweep: *"Claude Code deletes old session transcripts after the
|
|
@@ -30643,13 +30834,13 @@ var VERSION;
|
|
|
30643
30834
|
var init_version2 = __esm({
|
|
30644
30835
|
"packages/core/dist/version.js"() {
|
|
30645
30836
|
"use strict";
|
|
30646
|
-
VERSION = "1.6.
|
|
30837
|
+
VERSION = "1.6.2";
|
|
30647
30838
|
}
|
|
30648
30839
|
});
|
|
30649
30840
|
|
|
30650
30841
|
// packages/core/dist/memory/delete.js
|
|
30651
30842
|
import fs43 from "node:fs";
|
|
30652
|
-
import
|
|
30843
|
+
import path36 from "node:path";
|
|
30653
30844
|
function finishArchive(db, id, journal, root) {
|
|
30654
30845
|
const remaining = [];
|
|
30655
30846
|
const absoluteRemaining = [];
|
|
@@ -30658,8 +30849,8 @@ function finishArchive(db, id, journal, root) {
|
|
|
30658
30849
|
absoluteRemaining.push(owned);
|
|
30659
30850
|
continue;
|
|
30660
30851
|
}
|
|
30661
|
-
const relative =
|
|
30662
|
-
if (relative.startsWith("..") ||
|
|
30852
|
+
const relative = path36.relative(root, owned);
|
|
30853
|
+
if (relative.startsWith("..") || path36.isAbsolute(relative)) {
|
|
30663
30854
|
absoluteRemaining.push(owned);
|
|
30664
30855
|
continue;
|
|
30665
30856
|
}
|
|
@@ -30671,14 +30862,14 @@ function finishArchive(db, id, journal, root) {
|
|
|
30671
30862
|
remaining.push(relative);
|
|
30672
30863
|
continue;
|
|
30673
30864
|
}
|
|
30674
|
-
const file =
|
|
30675
|
-
if (!file.startsWith(
|
|
30865
|
+
const file = path36.resolve(root, relative);
|
|
30866
|
+
if (!file.startsWith(path36.resolve(root) + path36.sep) || !(relative.startsWith("archive/") || relative.startsWith("cards/"))) {
|
|
30676
30867
|
remaining.push(relative);
|
|
30677
30868
|
continue;
|
|
30678
30869
|
}
|
|
30679
30870
|
try {
|
|
30680
|
-
const actualRoot = fs43.realpathSync(root), actualParent = fs43.realpathSync(
|
|
30681
|
-
if (actualParent !== actualRoot && !actualParent.startsWith(actualRoot +
|
|
30871
|
+
const actualRoot = fs43.realpathSync(root), actualParent = fs43.realpathSync(path36.dirname(file));
|
|
30872
|
+
if (actualParent !== actualRoot && !actualParent.startsWith(actualRoot + path36.sep)) {
|
|
30682
30873
|
remaining.push(relative);
|
|
30683
30874
|
continue;
|
|
30684
30875
|
}
|
|
@@ -30990,7 +31181,7 @@ var init_embedding_workset = __esm({
|
|
|
30990
31181
|
|
|
30991
31182
|
// packages/core/dist/memory/maintenance.js
|
|
30992
31183
|
import fs44 from "node:fs";
|
|
30993
|
-
import
|
|
31184
|
+
import path37 from "node:path";
|
|
30994
31185
|
function openMaintenanceDb(root) {
|
|
30995
31186
|
const file = dbPath(root), reader = openSqliteReadOnly(file);
|
|
30996
31187
|
try {
|
|
@@ -31095,9 +31286,9 @@ function prepareMigration(root) {
|
|
|
31095
31286
|
const check = db.prepare("PRAGMA integrity_check").all();
|
|
31096
31287
|
if (check.length !== 1 || Object.values(check[0])[0] !== "ok")
|
|
31097
31288
|
throw new Error("integrity_check_failed");
|
|
31098
|
-
const dir =
|
|
31289
|
+
const dir = path37.join(root, "backups");
|
|
31099
31290
|
fs44.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
31100
|
-
const backup =
|
|
31291
|
+
const backup = path37.join(dir, `pre-memory-${Date.now()}-${process.pid}.db`);
|
|
31101
31292
|
db.prepare("VACUUM INTO ?").run(backup);
|
|
31102
31293
|
fs44.chmodSync(backup, 384);
|
|
31103
31294
|
const fd = fs44.openSync(backup, "r");
|
|
@@ -31422,19 +31613,19 @@ var init_maintenance = __esm({
|
|
|
31422
31613
|
}).immediate();
|
|
31423
31614
|
return complete;
|
|
31424
31615
|
}
|
|
31425
|
-
const
|
|
31426
|
-
if (!
|
|
31616
|
+
const capture2 = readCapturePayload(db, j.job_id);
|
|
31617
|
+
if (!capture2 && !readEnrolledSources(db))
|
|
31427
31618
|
throw new Error("source_enrollment_required");
|
|
31428
31619
|
const enrollment = readEnrolledSources(db);
|
|
31429
|
-
const logical = !
|
|
31620
|
+
const logical = !capture2 && j.kind === "capture" && j.target_id.startsWith("source:") ? JSON.parse(j.target_id.slice(7)) : void 0;
|
|
31430
31621
|
if (logical && !enrollment?.harnesses.includes(logical[0]))
|
|
31431
31622
|
return;
|
|
31432
|
-
const report = await indexAll({ db, root: this.root, potsherdDir: this.root, ...enrollment?.options ?? {}, ...enrollment ? { harnesses: enrollment.harnesses } : {}, ...
|
|
31623
|
+
const report = await indexAll({ db, root: this.root, potsherdDir: this.root, ...enrollment?.options ?? {}, ...enrollment ? { harnesses: enrollment.harnesses } : {}, ...capture2 ?? {}, embed: false, ...logical ? { harnesses: [logical[0]], sessionId: logical[1] } : !capture2 && j.kind === "capture" && j.target_id !== "*" ? { sessionId: j.target_id } : {}, beforeCommit: () => {
|
|
31433
31624
|
this.controller.signal.throwIfAborted();
|
|
31434
31625
|
assertFence(db, f);
|
|
31435
31626
|
} });
|
|
31436
|
-
const requestedSourceMissing = Boolean(
|
|
31437
|
-
if (
|
|
31627
|
+
const requestedSourceMissing = Boolean(capture2?.sessionId) && report.harnesses.every((h) => h.discovered === 0);
|
|
31628
|
+
if (capture2)
|
|
31438
31629
|
recordCaptureResult(db, f, j, report, report.totals.failed === 0 && !requestedSourceMissing);
|
|
31439
31630
|
if (requestedSourceMissing)
|
|
31440
31631
|
throw new Error("requested_source_unavailable");
|
|
@@ -32711,7 +32902,7 @@ var require_command = __commonJS({
|
|
|
32711
32902
|
"node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports) {
|
|
32712
32903
|
var EventEmitter = __require("node:events").EventEmitter;
|
|
32713
32904
|
var childProcess = __require("node:child_process");
|
|
32714
|
-
var
|
|
32905
|
+
var path46 = __require("node:path");
|
|
32715
32906
|
var fs60 = __require("node:fs");
|
|
32716
32907
|
var process26 = __require("node:process");
|
|
32717
32908
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
@@ -33644,9 +33835,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
33644
33835
|
let launchWithNode = false;
|
|
33645
33836
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
33646
33837
|
function findFile(baseDir, baseName) {
|
|
33647
|
-
const localBin =
|
|
33838
|
+
const localBin = path46.resolve(baseDir, baseName);
|
|
33648
33839
|
if (fs60.existsSync(localBin)) return localBin;
|
|
33649
|
-
if (sourceExt.includes(
|
|
33840
|
+
if (sourceExt.includes(path46.extname(baseName))) return void 0;
|
|
33650
33841
|
const foundExt = sourceExt.find(
|
|
33651
33842
|
(ext) => fs60.existsSync(`${localBin}${ext}`)
|
|
33652
33843
|
);
|
|
@@ -33664,17 +33855,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
33664
33855
|
} catch (err) {
|
|
33665
33856
|
resolvedScriptPath = this._scriptPath;
|
|
33666
33857
|
}
|
|
33667
|
-
executableDir =
|
|
33668
|
-
|
|
33858
|
+
executableDir = path46.resolve(
|
|
33859
|
+
path46.dirname(resolvedScriptPath),
|
|
33669
33860
|
executableDir
|
|
33670
33861
|
);
|
|
33671
33862
|
}
|
|
33672
33863
|
if (executableDir) {
|
|
33673
33864
|
let localFile = findFile(executableDir, executableFile);
|
|
33674
33865
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
33675
|
-
const legacyName =
|
|
33866
|
+
const legacyName = path46.basename(
|
|
33676
33867
|
this._scriptPath,
|
|
33677
|
-
|
|
33868
|
+
path46.extname(this._scriptPath)
|
|
33678
33869
|
);
|
|
33679
33870
|
if (legacyName !== this._name) {
|
|
33680
33871
|
localFile = findFile(
|
|
@@ -33685,7 +33876,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
33685
33876
|
}
|
|
33686
33877
|
executableFile = localFile || executableFile;
|
|
33687
33878
|
}
|
|
33688
|
-
launchWithNode = sourceExt.includes(
|
|
33879
|
+
launchWithNode = sourceExt.includes(path46.extname(executableFile));
|
|
33689
33880
|
let proc;
|
|
33690
33881
|
if (process26.platform !== "win32") {
|
|
33691
33882
|
if (launchWithNode) {
|
|
@@ -34525,7 +34716,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
34525
34716
|
* @return {Command}
|
|
34526
34717
|
*/
|
|
34527
34718
|
nameFromFilename(filename) {
|
|
34528
|
-
this._name =
|
|
34719
|
+
this._name = path46.basename(filename, path46.extname(filename));
|
|
34529
34720
|
return this;
|
|
34530
34721
|
}
|
|
34531
34722
|
/**
|
|
@@ -34539,9 +34730,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
34539
34730
|
* @param {string} [path]
|
|
34540
34731
|
* @return {(string|null|Command)}
|
|
34541
34732
|
*/
|
|
34542
|
-
executableDir(
|
|
34543
|
-
if (
|
|
34544
|
-
this._executableDir =
|
|
34733
|
+
executableDir(path47) {
|
|
34734
|
+
if (path47 === void 0) return this._executableDir;
|
|
34735
|
+
this._executableDir = path47;
|
|
34545
34736
|
return this;
|
|
34546
34737
|
}
|
|
34547
34738
|
/**
|
|
@@ -34783,16 +34974,16 @@ function themeFrom(o) {
|
|
|
34783
34974
|
active = new Theme(opts);
|
|
34784
34975
|
return active;
|
|
34785
34976
|
}
|
|
34786
|
-
function silenceBrokenPipe(
|
|
34787
|
-
|
|
34977
|
+
function silenceBrokenPipe(stream2) {
|
|
34978
|
+
stream2.on("error", (err) => {
|
|
34788
34979
|
if (err.code === "EPIPE" || err.code === "ERR_STREAM_DESTROYED") {
|
|
34789
34980
|
process13.exit(0);
|
|
34790
34981
|
}
|
|
34791
34982
|
throw err;
|
|
34792
34983
|
});
|
|
34793
34984
|
}
|
|
34794
|
-
function writable(
|
|
34795
|
-
return !
|
|
34985
|
+
function writable(stream2) {
|
|
34986
|
+
return !stream2.destroyed && stream2.writable;
|
|
34796
34987
|
}
|
|
34797
34988
|
function printJson(value) {
|
|
34798
34989
|
if (!writable(process13.stdout)) return;
|
|
@@ -34889,18 +35080,75 @@ var init_output = __esm({
|
|
|
34889
35080
|
function safe(value) {
|
|
34890
35081
|
return value.replace(/\x1b\][^\x07]*(?:\x07|\x1b\\)/g, "").replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "").replace(/[\x00-\x08\x0b-\x1f\x7f-\x9f]/g, "").replace(/[\r\n\t]/g, " ");
|
|
34891
35082
|
}
|
|
35083
|
+
function launchIsLoading(snapshot) {
|
|
35084
|
+
return Boolean(snapshot.launch && snapshot.launch.stage !== "ready" && !["cancelled", "error"].includes(snapshot.status));
|
|
35085
|
+
}
|
|
35086
|
+
function launchGaps(snapshot) {
|
|
35087
|
+
return /* @__PURE__ */ new Set([...snapshot.coverage.gapCodes, ...snapshot.sources.flatMap((source) => source.gapCodes), ...snapshot.launch?.semantics?.gaps ?? [], ...snapshot.semantics.errorCode ? [snapshot.semantics.errorCode] : []]);
|
|
35088
|
+
}
|
|
35089
|
+
function localReadFailure(gaps) {
|
|
35090
|
+
const causes = [
|
|
35091
|
+
["audit_snapshot_stale", "Local history changed during this audit", "Run slopie audit again to read current sources."],
|
|
35092
|
+
["audit_sqlite_snapshot_stale", "Local SQLite snapshot changed", "Let local writes settle, then run slopie audit again."],
|
|
35093
|
+
["source_or_policy_changed", "Local source or privacy settings changed", "Run slopie audit again with the current settings."],
|
|
35094
|
+
["source_or_privacy_changed", "Local source or privacy settings changed", "Run slopie audit again with the current settings."],
|
|
35095
|
+
["audit_sqlite_rollback_journal_unavailable", "Local SQLite rollback journal is active", "Let the database writer finish, then retry."],
|
|
35096
|
+
["audit_sqlite_live_journal_unavailable", "Local SQLite journal blocks safe reading", "Let the database writer finish, then retry."],
|
|
35097
|
+
["audit_sqlite_snapshot_byte_limit", "Archive exceeds snapshot limit", "Check archive size and supported snapshot limits before retrying."],
|
|
35098
|
+
["audit_sqlite_snapshot_disk_limit", "Not enough free space for a safe snapshot", "Free local disk space, then retry."],
|
|
35099
|
+
["audit_sqlite_wal_index_unavailable", "Local WAL commit boundary is unavailable", "Let the writer finish; check an owned backup if this persists."],
|
|
35100
|
+
["audit_sqlite_wal_integrity_unavailable", "Local WAL committed data failed integrity checks", "Check the source database or an owned backup before retrying."],
|
|
35101
|
+
["audit_sqlite_snapshot_time_limit", "Local SQLite snapshot timed out", "Retry after local database activity settles."],
|
|
35102
|
+
["audit_sqlite_format_unavailable", "Local store is not readable SQLite", "Check the selected store path, then retry."],
|
|
35103
|
+
["audit_sqlite_wal_header_unavailable", "Local WAL snapshot failed integrity checks", "Retry after local writes settle; check the source if it persists."],
|
|
35104
|
+
["audit_sqlite_wal_incomplete_tail", "Local WAL snapshot is incomplete", "Let the database writer finish, then retry."],
|
|
35105
|
+
["audit_sqlite_snapshot_corrupt", "Local SQLite snapshot failed integrity checks", "Check the source database or an owned backup before retrying."],
|
|
35106
|
+
["ignore_policy_unavailable", "Local ignore settings could not be read", "Check access to your ignore settings, then retry."],
|
|
35107
|
+
["privacy_refresh_required", "Local history needs a privacy refresh", "Refresh the local privacy normalization before retrying."],
|
|
35108
|
+
["store_policy_unavailable", "Local history policy could not be read", "Check local store access and privacy settings, then retry."],
|
|
35109
|
+
["raw_lane_policy_hold", "Local history is held by its privacy policy", "Check local store access and privacy settings, then retry."]
|
|
35110
|
+
];
|
|
35111
|
+
for (const [code, summary3, action2] of causes) if (gaps.has(code)) return { summary: summary3, action: action2, code };
|
|
35112
|
+
const sqlite = [...gaps].find((code) => code.startsWith("audit_sqlite_"));
|
|
35113
|
+
if (sqlite) return { summary: "Local SQLite history could not be read", action: "Check store access and retry after local writes settle.", code: sqlite };
|
|
35114
|
+
return null;
|
|
35115
|
+
}
|
|
35116
|
+
function launchAnalysisStatus(snapshot) {
|
|
35117
|
+
const sem = snapshot.launch?.semantics, gaps = launchGaps(snapshot), attempts = sem?.attempts ?? 0, local = attempts === 0 ? localReadFailure(gaps) : null;
|
|
35118
|
+
if (local) return { kind: "local", ...local };
|
|
35119
|
+
if (launchIsLoading(snapshot)) return { kind: "loading", summary: sem?.state === "pending" ? "Analysis pending. Results appear when judgments finish." : null, action: null, code: null };
|
|
35120
|
+
if (snapshot.status === "cancelled" || sem?.state === "cancelled") return { kind: "cancelled", summary: "Analysis cancelled", action: null, code: null };
|
|
35121
|
+
if (snapshot.status === "error") return { kind: "not_run", summary: "Audit did not finish", action: "Run slopie audit again to retry.", code: null };
|
|
35122
|
+
if (sem?.state === "pending") return { kind: "not_run", summary: "Analysis did not finish", action: "Run slopie audit again to retry.", code: null };
|
|
35123
|
+
if (attempts > 0) {
|
|
35124
|
+
if (gaps.has("free_quota_unavailable")) return { kind: "provider", summary: "Jev quota exhausted", action: "Retry when free capacity returns.", code: "free_quota_unavailable" };
|
|
35125
|
+
if (gaps.has("free_retry_delay_exceeded")) return { kind: "provider", summary: "Free analysis cooldown is active", action: "Retry when free capacity returns.", code: "free_retry_delay_exceeded" };
|
|
35126
|
+
if (gaps.has("free_access_denied")) return { kind: "provider", summary: "Free analysis access was denied", action: "Local results remain available.", code: "free_access_denied" };
|
|
35127
|
+
if (sem?.state === "unavailable") return { kind: "provider", summary: "Analysis unavailable after attempted requests", action: "Local results remain available.", code: null };
|
|
35128
|
+
}
|
|
35129
|
+
if (sem?.state === "complete" || sem?.state === "partial") return { kind: "ready", summary: null, action: null, code: null };
|
|
35130
|
+
if (metricCount(snapshot.metrics.humanPrompts) === 0) return { kind: "empty", summary: "No eligible user input in this scope", action: null, code: null };
|
|
35131
|
+
if (gaps.has("offline_requested") || gaps.has("developer_prepare_only")) return { kind: "offline", summary: gaps.has("offline_requested") ? "Offline mode \xB7 analysis not requested" : "Preparation only \xB7 analysis not requested", action: null, code: null };
|
|
35132
|
+
if (gaps.has("semantic_window_unavailable") || gaps.has("free_allowance_exhausted")) return { kind: "allowance", summary: "No work window fits this run\u2019s allowance", action: "Inspect period estimates or choose a smaller scope.", code: null };
|
|
35133
|
+
if (gaps.has("free_access_unverified")) return { kind: "not_run", summary: "Free analysis access is unverified", action: null, code: "free_access_unverified" };
|
|
35134
|
+
return { kind: "not_run", summary: "Analysis not run", action: null, code: null };
|
|
35135
|
+
}
|
|
35136
|
+
function missingWorkScope(snapshot, short2 = false) {
|
|
35137
|
+
const state = launchAnalysisStatus(snapshot);
|
|
35138
|
+
return { local: short2 ? "Work unavailable \xB7 local history" : "Work window unavailable \xB7 local history could not be read", loading: short2 ? "Work \xB7 preparing window" : "Work window is being prepared", empty: short2 ? "Work \xB7 no eligible input" : "No eligible work window in this scope", offline: short2 ? "Work \xB7 offline / preparation only" : "No analyzed work window \xB7 offline or preparation only", allowance: short2 ? "Work \xB7 no fitting window" : "No work window fits this run\u2019s allowance", provider: short2 ? "Work \xB7 window unavailable" : "Work window unavailable", cancelled: short2 ? "Work \xB7 cancelled" : "Work window cancelled", not_run: short2 ? "Work \xB7 not analyzed" : "No analyzed work window", ready: short2 ? "Work \xB7 no window selected" : "No work window selected" }[state.kind];
|
|
35139
|
+
}
|
|
34892
35140
|
function semanticScope(snapshot) {
|
|
34893
35141
|
const window2 = snapshot.launch?.semantics?.window.selected;
|
|
34894
|
-
return window2 ? window2.selection ? `Newest ${window2.selection.selected} of ${window2.selection.available} episodes \xB7 ${window2.selection.eventFrom ?? "unknown"} to ${window2.selection.eventTo ?? "unknown"} UTC \xB7 partial calendar coverage` : `${window2.period === "all" ? "All available history" : `${window2.period} days`} \xB7 ${window2.from ?? "unknown start"} to ${window2.until} UTC` :
|
|
35142
|
+
return window2 ? window2.selection ? `Newest ${window2.selection.selected} of ${window2.selection.available} episodes \xB7 ${window2.selection.eventFrom ?? "unknown"} to ${window2.selection.eventTo ?? "unknown"} UTC \xB7 partial calendar coverage` : `${window2.period === "all" ? "All available history" : `${window2.period} days`} \xB7 ${window2.from ?? "unknown start"} to ${window2.until} UTC` : missingWorkScope(snapshot);
|
|
34895
35143
|
}
|
|
34896
35144
|
function shortWorkScope(snapshot) {
|
|
34897
35145
|
const window2 = snapshot.launch?.semantics?.window.selected;
|
|
34898
|
-
if (!window2) return
|
|
35146
|
+
if (!window2) return missingWorkScope(snapshot, true);
|
|
34899
35147
|
if (window2.selection) {
|
|
34900
35148
|
const selected = window2.selection, date3 = selected.eventFrom ? new Date(selected.eventFrom) : null, label4 = date3 && !Number.isNaN(date3.valueOf()) ? date3.toLocaleDateString("en-US", { month: "short", day: "numeric", timeZone: "UTC" }) : "undated";
|
|
34901
35149
|
return `Work: ${selected.selected}/${selected.available} episodes \xB7 ${label4} \xB7 partial`;
|
|
34902
35150
|
}
|
|
34903
|
-
return `Work: ${window2.period === "all" ? "all available" : `${window2.period} days`} \xB7 ${snapshot.launch?.semantics?.state ?? "pending"}`;
|
|
35151
|
+
return `Work: ${window2.period === "all" ? "all available" : `${window2.period} days`} \xB7 ${snapshot.launch?.semantics?.state === "pending" && !launchIsLoading(snapshot) ? "not completed" : snapshot.launch?.semantics?.state ?? (launchIsLoading(snapshot) ? "pending" : "not analyzed")}`;
|
|
34904
35152
|
}
|
|
34905
35153
|
function modelTokens(model) {
|
|
34906
35154
|
return model.totalTokens !== null ? `${num3(model.totalTokens)} tokens` : model.knownTokens !== void 0 && model.knownTokens > 0 ? `${num3(model.knownTokens)} known tokens \xB7 total unknown` : "tokens unknown";
|
|
@@ -35008,7 +35256,15 @@ function buildLaunchScreen(snapshot, nav, geometry = {}) {
|
|
|
35008
35256
|
}
|
|
35009
35257
|
if (current) body.push(line(current, tone2));
|
|
35010
35258
|
};
|
|
35011
|
-
const facts = snapshot.launch?.facts, sem = snapshot.launch?.semantics, stage = snapshot.launch?.stage ?? "discovering", active2 =
|
|
35259
|
+
const facts = snapshot.launch?.facts, sem = snapshot.launch?.semantics, stage = snapshot.launch?.stage ?? "discovering", active2 = launchIsLoading(snapshot), analysis = launchAnalysisStatus(snapshot);
|
|
35260
|
+
const showAnalysisStatus = (detailed = false) => {
|
|
35261
|
+
if (analysis.summary) wrap5(analysis.summary, analysis.kind === "local" ? "amber" : "dim");
|
|
35262
|
+
if (analysis.kind === "local" || detailed) {
|
|
35263
|
+
if (analysis.action) wrap5(analysis.action, "dim");
|
|
35264
|
+
if ((sem?.attempts ?? 0) === 0 && analysis.kind !== "loading" && analysis.kind !== "ready" && analysis.kind !== "empty") add("No analysis requests made", "dim");
|
|
35265
|
+
if (detailed && analysis.code) add(`Reason: ${analysis.code}`, "dim");
|
|
35266
|
+
}
|
|
35267
|
+
};
|
|
35012
35268
|
if (nav.view === "evidence") {
|
|
35013
35269
|
add("SOURCE EVIDENCE", "cyan");
|
|
35014
35270
|
if (geometry.busy) add("Reading scoped source\u2026", "dim");
|
|
@@ -35018,6 +35274,7 @@ function buildLaunchScreen(snapshot, nav, geometry = {}) {
|
|
|
35018
35274
|
} else wrap5(geometry.evidence?.state === "stale" ? "Source changed. Re-run audit to read current evidence." : "Source evidence unavailable.");
|
|
35019
35275
|
} else if (nav.view === "periods") {
|
|
35020
35276
|
wrap5(`Analyzed scope: ${semanticScope(snapshot)}`, "cyan");
|
|
35277
|
+
showAnalysisStatus(true);
|
|
35021
35278
|
wrap5(`Allowance: ${num3(sem?.window.tokenLimit)} total input tokens`, "dim");
|
|
35022
35279
|
for (const [index, row2] of launchRows(snapshot, nav).entries()) {
|
|
35023
35280
|
const choice = sem?.window.choices.find((item) => row2.id === `period:${item.period}`);
|
|
@@ -35025,7 +35282,8 @@ function buildLaunchScreen(snapshot, nav, geometry = {}) {
|
|
|
35025
35282
|
wrap5(row2.value, "dim");
|
|
35026
35283
|
if (choice?.reason) wrap5(words3(choice.reason), "dim");
|
|
35027
35284
|
}
|
|
35028
|
-
wrap5("Remaining-analysis estimates include questions and retry allowance. Local inventory has already run; these are not total cold-audit times. Enter uses this run\u2019s remaining allowance.", "dim");
|
|
35285
|
+
if (sem?.window.choices.length && analysis.kind !== "local") wrap5("Remaining-analysis estimates include questions and retry allowance. Local inventory has already run; these are not total cold-audit times. Enter uses this run\u2019s remaining allowance.", "dim");
|
|
35286
|
+
else if (!active2) add("No period estimates are available.", "dim");
|
|
35029
35287
|
if (sem?.window.reason) wrap5(words3(sem.window.reason), "dim");
|
|
35030
35288
|
} else if (nav.view === "prompts") {
|
|
35031
35289
|
add("DIRECT USER INPUTS", "cyan");
|
|
@@ -35092,7 +35350,6 @@ function buildLaunchScreen(snapshot, nav, geometry = {}) {
|
|
|
35092
35350
|
add(`${ascii ? ">" : "\u25C6"} ${words3(stage)}${stage === "analyzing" ? " \xB7 Jev" : ""}`, "amber");
|
|
35093
35351
|
if (!compact2) add(stages.map((step) => `${step === stage ? "[" : ""}${step}${step === stage ? "]" : ""}`).join(" \u2192 "), "dim");
|
|
35094
35352
|
if (snapshot.progress.total !== null) add(`${num3(snapshot.progress.completed)} / ${num3(snapshot.progress.total)} ${words3(snapshot.progress.unit)}`, "dim");
|
|
35095
|
-
if (sem?.state === "unavailable") wrap5("Jev unavailable \xB7 local facts continue.", "dim");
|
|
35096
35353
|
}
|
|
35097
35354
|
if (facts) {
|
|
35098
35355
|
add(`${usd(equivalent(facts))} recorded API-equivalent value`, "amberLight");
|
|
@@ -35120,7 +35377,8 @@ function buildLaunchScreen(snapshot, nav, geometry = {}) {
|
|
|
35120
35377
|
const total = sem.work.reduce((sum2, row2) => sum2 + row2.count, 0);
|
|
35121
35378
|
add(sem.work.slice(0, compact2 ? 2 : 3).map((row2) => `${words3(row2.label)} ${num3(row2.count)}`).join(" \xB7 "), "violet");
|
|
35122
35379
|
if (wide) add(spark(sem.work.map((row2) => row2.count), 30, ascii) + ` ${num3(total)} judged segments`, "dim");
|
|
35123
|
-
}
|
|
35380
|
+
}
|
|
35381
|
+
showAnalysisStatus();
|
|
35124
35382
|
const direct = snapshot.profanity?.buckets.find((bucket) => bucket.kind === "direct_prose"), highlight = snapshot.profanity?.matches?.find((match) => match.kind === "direct_prose");
|
|
35125
35383
|
if (direct) {
|
|
35126
35384
|
const attributed = snapshot.launch?.languageByModel?.find((row2) => highlight && row2.promptIds.includes(highlight.promptId));
|
|
@@ -35142,10 +35400,10 @@ function buildLaunchScreen(snapshot, nav, geometry = {}) {
|
|
|
35142
35400
|
}
|
|
35143
35401
|
if (nav.section === "projects") wrap5(`${factScope(snapshot)} \xB7 direct human prompts`, "dim");
|
|
35144
35402
|
if (nav.section === "work" || nav.section === "hall") {
|
|
35145
|
-
wrap5(`${semanticScope(snapshot)} \xB7
|
|
35146
|
-
|
|
35147
|
-
|
|
35148
|
-
if (
|
|
35403
|
+
wrap5(`${semanticScope(snapshot)} \xB7 tone ${sem?.tone ?? "elegant"}`, "cyan");
|
|
35404
|
+
showAnalysisStatus(true);
|
|
35405
|
+
const requestFailures = /* @__PURE__ */ new Set(["free_quota_unavailable", "free_retry_delay_exceeded", "free_access_denied", "free_service_unavailable", "transport_failure", "attempt_timeout", "retry_limit"]), visibleGaps = (sem?.gaps ?? []).filter((gap2) => (sem?.attempts ?? 0) > 0 || !requestFailures.has(gap2));
|
|
35406
|
+
if (visibleGaps.length) wrap5(`Coverage: ${visibleGaps.map(words3).join(", ")}`, "dim");
|
|
35149
35407
|
if (nav.section === "work" && sem?.work.length) {
|
|
35150
35408
|
const total = sem.work.reduce((sum2, item) => sum2 + item.count, 0);
|
|
35151
35409
|
for (const item of sem.work) body.push([{ text: words3(item.label) + " ", tone: "normal" }, { text: bar(total ? item.count / total : 0, compact2 ? 6 : 18, ascii), tone: "violet" }, { text: ` ${num3(item.count)} segments`, tone: "dim" }]);
|
|
@@ -35167,7 +35425,7 @@ function buildLaunchScreen(snapshot, nav, geometry = {}) {
|
|
|
35167
35425
|
body.push([{ text: `${index === selectedIndex ? ascii ? "> " : "\u203A " : " "}${row2.label}`, tone: index === selectedIndex ? "amber" : "normal" }]);
|
|
35168
35426
|
add(` ${row2.value}`, "dim");
|
|
35169
35427
|
}
|
|
35170
|
-
if (!rows.length &&
|
|
35428
|
+
if (!rows.length && analysis.kind === "ready") add("No recorded rows for this scope.", "dim");
|
|
35171
35429
|
}
|
|
35172
35430
|
if (geometry.notice) wrap5(geometry.notice, "amber");
|
|
35173
35431
|
const header = [[{ text: ascii ? "SLOPIE " : "\u259F SLOPIE ", tone: "amber" }, { text: nav.frozen ? "FROZEN \xB7 current view" : nav.view === "section" ? { elegant: "your recorded work", witty: "the receipts", chaotic: "the session pile", roast: "receipts, served cold" }[sem?.tone ?? "elegant"] : NAMES[nav.section], tone: "dim" }]];
|
|
@@ -35207,7 +35465,7 @@ async function runLaunchTerminal(session, options = {}) {
|
|
|
35207
35465
|
function App() {
|
|
35208
35466
|
const [live, setLive] = useState(finalSnapshot), [nav, setNav] = useState(createLaunchNavigation()), [frozen, setFrozen] = useState(null), [page, setPage] = useState(null), [evidence2, setEvidence] = useState(null), [busy, setBusy] = useState(false), [notice, setNotice] = useState("");
|
|
35209
35467
|
const { columns, rows } = useWindowSize(), { exit } = useApp(), mounted = useRef(true), generation = useRef(0), pending = useRef(null), readBusy = useRef(false);
|
|
35210
|
-
const snapshot = nav.frozen && frozen ? frozen : live, active2 =
|
|
35468
|
+
const snapshot = nav.frozen && frozen ? frozen : live, active2 = launchIsLoading(live), visible = Math.max(1, rows - 6), items = launchRows(snapshot, nav, page);
|
|
35211
35469
|
const { frame } = useAnimation({ interval: 120, isActive: active2 && !nav.frozen && nav.section === "overview" && nav.view === "section" && options.motion !== false });
|
|
35212
35470
|
useEffect(() => {
|
|
35213
35471
|
mounted.current = true;
|
|
@@ -35335,6 +35593,11 @@ async function runLaunchTerminal(session, options = {}) {
|
|
|
35335
35593
|
return;
|
|
35336
35594
|
}
|
|
35337
35595
|
if (selected.kind === "period") {
|
|
35596
|
+
const sourceFailure = launchAnalysisStatus(snapshot);
|
|
35597
|
+
if (sourceFailure.kind === "local") {
|
|
35598
|
+
setNotice(sourceFailure.summary ?? "Local history is unavailable");
|
|
35599
|
+
return;
|
|
35600
|
+
}
|
|
35338
35601
|
const choice = snapshot.launch?.semantics?.window.choices.find((window2) => selected.id === `period:${window2.period}`);
|
|
35339
35602
|
if (!choice || !choice.fits) {
|
|
35340
35603
|
setNotice("This period exceeds the available allowance \xB7 choose a smaller scope");
|
|
@@ -35367,7 +35630,8 @@ async function runLaunchTerminal(session, options = {}) {
|
|
|
35367
35630
|
}
|
|
35368
35631
|
}
|
|
35369
35632
|
} catch {
|
|
35370
|
-
|
|
35633
|
+
refreshCurrent();
|
|
35634
|
+
if (mounted.current && token === generation.current) setNotice(launchAnalysisStatus(finalSnapshot).summary ?? "Period analysis stopped \xB7 retained results remain");
|
|
35371
35635
|
} finally {
|
|
35372
35636
|
periodJob = null;
|
|
35373
35637
|
if (mounted.current && token === generation.current) setBusy(false);
|
|
@@ -36139,7 +36403,7 @@ var init_markers2 = __esm({
|
|
|
36139
36403
|
|
|
36140
36404
|
// packages/core/src/analytics/source.ts
|
|
36141
36405
|
import { createHash as createHash16 } from "node:crypto";
|
|
36142
|
-
var
|
|
36406
|
+
var digest2, clean2;
|
|
36143
36407
|
var init_source3 = __esm({
|
|
36144
36408
|
"packages/core/src/analytics/source.ts"() {
|
|
36145
36409
|
"use strict";
|
|
@@ -36148,7 +36412,7 @@ var init_source3 = __esm({
|
|
|
36148
36412
|
init_redact2();
|
|
36149
36413
|
init_redact_elide2();
|
|
36150
36414
|
init_markers2();
|
|
36151
|
-
|
|
36415
|
+
digest2 = (value) => createHash16("sha256").update(value).digest("hex");
|
|
36152
36416
|
clean2 = (text2) => redact2(elideBinary3(text2)).text;
|
|
36153
36417
|
}
|
|
36154
36418
|
});
|
|
@@ -36310,7 +36574,7 @@ var init_jev_provider2 = __esm({
|
|
|
36310
36574
|
return structuredClone(this.attempts);
|
|
36311
36575
|
}
|
|
36312
36576
|
key(request, identity4) {
|
|
36313
|
-
return
|
|
36577
|
+
return digest2(JSON.stringify({ request, identity: identity4 }));
|
|
36314
36578
|
}
|
|
36315
36579
|
evaluate(job, request, identity4) {
|
|
36316
36580
|
try {
|
|
@@ -36364,7 +36628,7 @@ var init_jev_provider2 = __esm({
|
|
|
36364
36628
|
}
|
|
36365
36629
|
async dispatch(item) {
|
|
36366
36630
|
const { job, request, key: key2, identity: identity4 } = item;
|
|
36367
|
-
const requestHash =
|
|
36631
|
+
const requestHash = digest2(JSON.stringify(request));
|
|
36368
36632
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
36369
36633
|
try {
|
|
36370
36634
|
job.assertCurrent();
|
|
@@ -36636,7 +36900,7 @@ function prepare2(selection, conversations) {
|
|
|
36636
36900
|
const state = { target: { role: "user", text: target.text }, precedingUser: preceding.map((p) => ({ role: "user", text: p.text })), assistantContext: "unavailable" };
|
|
36637
36901
|
try {
|
|
36638
36902
|
const request = promptQuestionRequest2(state);
|
|
36639
|
-
prepared.push({ prompt, sourceVersion: conversation.sourceVersion, request, windowCoverage: target.truncated || preceding.some((p) => p.truncated) ? "truncated" : "partial", contentHash:
|
|
36903
|
+
prepared.push({ prompt, sourceVersion: conversation.sourceVersion, request, windowCoverage: target.truncated || preceding.some((p) => p.truncated) ? "truncated" : "partial", contentHash: digest2(JSON.stringify({ sourceText: prompt.text, sentState: state })) });
|
|
36640
36904
|
} catch {
|
|
36641
36905
|
gaps.add("semantic_request_bytes_limit");
|
|
36642
36906
|
}
|
|
@@ -36671,8 +36935,8 @@ var init_jev_session2 = __esm({
|
|
|
36671
36935
|
job = null;
|
|
36672
36936
|
busy = false;
|
|
36673
36937
|
preview(snapshot, selection, conversations) {
|
|
36674
|
-
const selected = prepare2(selection, conversations), scopeHash =
|
|
36675
|
-
const preparedRequests = selected.prepared.map((input) => ({ promptId: input.prompt.id, conversationId: input.prompt.conversationId, sourceRoute: input.prompt.route, sourceVersion: input.sourceVersion, contentHash: input.contentHash, scopeHash, normalizationVersion: NORMALIZATION_VERSION2, questionVersion: JEV_QUESTION_VERSION2, policyVersion: AUDIT_SEMANTIC_POLICY_VERSION2, windowCoverage: input.windowCoverage, requestHash:
|
|
36938
|
+
const selected = prepare2(selection, conversations), scopeHash = digest2(JSON.stringify({ scope: snapshot.scope, conversationIds: selection.conversationIds }));
|
|
36939
|
+
const preparedRequests = selected.prepared.map((input) => ({ promptId: input.prompt.id, conversationId: input.prompt.conversationId, sourceRoute: input.prompt.route, sourceVersion: input.sourceVersion, contentHash: input.contentHash, scopeHash, normalizationVersion: NORMALIZATION_VERSION2, questionVersion: JEV_QUESTION_VERSION2, policyVersion: AUDIT_SEMANTIC_POLICY_VERSION2, windowCoverage: input.windowCoverage, requestHash: digest2(JSON.stringify(input.request)), requestBytes: Buffer.byteLength(JSON.stringify(input.request)), request: structuredClone(input.request) }));
|
|
36676
36940
|
return { snapshotId: snapshot.snapshotId, model: JEV_MODEL2, selectedConversations: selection.conversationIds.length, eligiblePrompts: selected.eligible, selectedPrompts: selected.prepared.length, maxRequests: selection.maxRequests, budgetUsd: selection.budgetUsd, estimatedReservationUsd: Math.min(selection.maxRequests, selected.prepared.length * 2) * JEV_ATTEMPT_RESERVATION_USD2, keyAvailable: jevKeyFromEnvironment2() !== null, outgoingFields: ["target.role", "target.text (redacted prefix, max3500 UTF-8 bytes)", "precedingUser[].role", "precedingUser[].text (at most2 redacted prefixes, max768 bytes each)", "assistantContext:unavailable"], windowCoverage: selected.prepared.some((p) => p.windowCoverage === "truncated") ? "truncated" : "partial", samples: selected.prepared.slice(0, 3).map((p) => ({ promptId: p.prompt.id, excerpt: prefix2(p.request.state && typeof p.request.state === "object" && !Array.isArray(p.request.state) ? String(p.request.state.target.text) : "", 160).text })), gapCodes: [...selected.gapCodes, "reservation_is_estimate_not_invoice_cap"], preparedRequests };
|
|
36677
36941
|
}
|
|
36678
36942
|
invalidate() {
|
|
@@ -36689,18 +36953,18 @@ var init_jev_session2 = __esm({
|
|
|
36689
36953
|
if (this.busy) throw new Error("semantic_job_running");
|
|
36690
36954
|
const selected = prepare2(selection, conversations), denominator = selected.eligible;
|
|
36691
36955
|
if (selection.approvedPolicyVersion !== void 0 && selection.approvedPolicyVersion !== AUDIT_SEMANTIC_POLICY_VERSION2) throw new Error("semantic_approved_policy_changed");
|
|
36692
|
-
if (selection.approvedRequestHashes !== void 0 && JSON.stringify(selection.approvedRequestHashes) !== JSON.stringify(selected.prepared.map((input) =>
|
|
36956
|
+
if (selection.approvedRequestHashes !== void 0 && JSON.stringify(selection.approvedRequestHashes) !== JSON.stringify(selected.prepared.map((input) => digest2(JSON.stringify(input.request))))) throw new Error("semantic_approved_request_changed");
|
|
36693
36957
|
const key2 = jevKeyFromEnvironment2();
|
|
36694
36958
|
if (!key2) return { semantics: { ...semantics2("no_key", denominator), model: null, estimatedCostUsd: null, reportedCostUsd: null, unresolvedCostUsd: null }, judgments: [], gaps: selected.gapCodes };
|
|
36695
36959
|
if (!isCurrent()) throw new Error("audit_snapshot_stale");
|
|
36696
36960
|
this.busy = true;
|
|
36697
|
-
const signature =
|
|
36961
|
+
const signature = digest2(key2);
|
|
36698
36962
|
if (!this.provider || signature !== this.keyHash) {
|
|
36699
36963
|
this.provider?.clearCache();
|
|
36700
36964
|
this.provider = new JevProvider2({ apiKey: key2 });
|
|
36701
36965
|
this.keyHash = signature;
|
|
36702
36966
|
}
|
|
36703
|
-
const scopeHash =
|
|
36967
|
+
const scopeHash = digest2(JSON.stringify({ scope: snapshot.scope, conversationIds: selection.conversationIds })), judgments = [];
|
|
36704
36968
|
let errorCode = null;
|
|
36705
36969
|
let skipped2 = 0;
|
|
36706
36970
|
const job = this.provider.beginJob({ consent: true, maxRequests: selection.maxRequests, budgetUsd: selection.budgetUsd, signal: selection.signal, isCurrent });
|
|
@@ -37633,13 +37897,13 @@ __export(audit_overview_exports, {
|
|
|
37633
37897
|
runAuditOverview: () => runAuditOverview
|
|
37634
37898
|
});
|
|
37635
37899
|
import fs51 from "node:fs";
|
|
37636
|
-
import
|
|
37900
|
+
import path43 from "node:path";
|
|
37637
37901
|
async function runAuditOverview(o) {
|
|
37638
37902
|
const harnesses = o.harness ? [...new Set(o.harness.split(",").map((h) => h.trim()))] : void 0;
|
|
37639
37903
|
if (harnesses?.some((h) => !["claude", "codex", "pi", "opencode"].includes(h))) {
|
|
37640
37904
|
throw new UserError("Choose overview sources from claude,codex,pi,opencode.");
|
|
37641
37905
|
}
|
|
37642
|
-
if (o.export &&
|
|
37906
|
+
if (o.export && path43.extname(o.export).toLowerCase() !== ".svg") {
|
|
37643
37907
|
throw new UserError("Use a .svg path for the safe share preview.");
|
|
37644
37908
|
}
|
|
37645
37909
|
if (o.tone && !["elegant", "witty", "chaotic", "roast"].includes(o.tone)) throw new UserError("Choose a tone: elegant, witty, chaotic, roast.");
|
|
@@ -37683,7 +37947,7 @@ async function runAuditOverview(o) {
|
|
|
37683
37947
|
if (o.json) printJson(publicAuditSnapshot(snapshot));
|
|
37684
37948
|
else print(ui.renderLaunchPlain(snapshot, { ascii: o.ascii, width }));
|
|
37685
37949
|
if (o.export) {
|
|
37686
|
-
const file =
|
|
37950
|
+
const file = path43.resolve(o.export);
|
|
37687
37951
|
fs51.writeFileSync(file, ui.renderAuditShareSvg(snapshot, { width }), { flag: "wx" });
|
|
37688
37952
|
if (!o.json) print(`Saved safe share preview: ${file}`);
|
|
37689
37953
|
}
|
|
@@ -37973,11 +38237,11 @@ init_dist();
|
|
|
37973
38237
|
// packages/bridges/dist/types.js
|
|
37974
38238
|
var SCHEMA_UNRECOGNISED = "schema not recognised";
|
|
37975
38239
|
var SCHEMA_UNAVAILABLE = `bridge unavailable: ${SCHEMA_UNRECOGNISED}`;
|
|
37976
|
-
function absentStatus(bridge,
|
|
38240
|
+
function absentStatus(bridge, path46, what) {
|
|
37977
38241
|
return {
|
|
37978
38242
|
bridge,
|
|
37979
38243
|
presence: "absent",
|
|
37980
|
-
path:
|
|
38244
|
+
path: path46,
|
|
37981
38245
|
available: false,
|
|
37982
38246
|
detail: `not installed (${what})`,
|
|
37983
38247
|
headline: "not installed",
|
|
@@ -37986,11 +38250,11 @@ function absentStatus(bridge, path45, what) {
|
|
|
37986
38250
|
worker: null
|
|
37987
38251
|
};
|
|
37988
38252
|
}
|
|
37989
|
-
function emptyStatus(bridge,
|
|
38253
|
+
function emptyStatus(bridge, path46, why2) {
|
|
37990
38254
|
return {
|
|
37991
38255
|
bridge,
|
|
37992
38256
|
presence: "empty",
|
|
37993
|
-
path:
|
|
38257
|
+
path: path46,
|
|
37994
38258
|
available: false,
|
|
37995
38259
|
detail: `installed, nothing to search (${why2})`,
|
|
37996
38260
|
headline: "installed, nothing to search",
|
|
@@ -38014,11 +38278,11 @@ function unavailableList(status3, ms = 0) {
|
|
|
38014
38278
|
relaxed: false
|
|
38015
38279
|
};
|
|
38016
38280
|
}
|
|
38017
|
-
function unrecognisedStatus(bridge,
|
|
38281
|
+
function unrecognisedStatus(bridge, path46, why2, schema = null, headline4 = SCHEMA_UNAVAILABLE) {
|
|
38018
38282
|
return {
|
|
38019
38283
|
bridge,
|
|
38020
38284
|
presence: "unrecognised",
|
|
38021
|
-
path:
|
|
38285
|
+
path: path46,
|
|
38022
38286
|
available: false,
|
|
38023
38287
|
detail: `${headline4} (${why2})`,
|
|
38024
38288
|
// The default headline is the long form, because `detail` reads
|
|
@@ -38107,8 +38371,8 @@ function isFts5(info) {
|
|
|
38107
38371
|
|
|
38108
38372
|
// packages/bridges/dist/claude-mem.js
|
|
38109
38373
|
init_dist();
|
|
38110
|
-
import
|
|
38111
|
-
import
|
|
38374
|
+
import os7 from "node:os";
|
|
38375
|
+
import path38 from "node:path";
|
|
38112
38376
|
import fs46 from "node:fs";
|
|
38113
38377
|
var NO_UID = 77;
|
|
38114
38378
|
var WORKER_TIMEOUT_MS = 1500;
|
|
@@ -38116,11 +38380,11 @@ function claudeMemDir(opts = {}) {
|
|
|
38116
38380
|
const env = opts.env ?? process.env;
|
|
38117
38381
|
const override = env["CLAUDE_MEM_DATA_DIR"];
|
|
38118
38382
|
if (override && override.trim())
|
|
38119
|
-
return
|
|
38120
|
-
return
|
|
38383
|
+
return path38.resolve(override.trim());
|
|
38384
|
+
return path38.join(opts.home ?? os7.homedir(), ".claude-mem");
|
|
38121
38385
|
}
|
|
38122
38386
|
function claudeMemDbPath(opts = {}) {
|
|
38123
|
-
return
|
|
38387
|
+
return path38.join(claudeMemDir(opts), "claude-mem.db");
|
|
38124
38388
|
}
|
|
38125
38389
|
function claudeMemWorkerPort(opts = {}) {
|
|
38126
38390
|
const env = opts.env ?? process.env;
|
|
@@ -38471,37 +38735,37 @@ function oneLine(s) {
|
|
|
38471
38735
|
return s.replace(/\s+/g, " ").trim().slice(0, 160);
|
|
38472
38736
|
}
|
|
38473
38737
|
function tilde(p) {
|
|
38474
|
-
const home2 =
|
|
38738
|
+
const home2 = os7.homedir();
|
|
38475
38739
|
return p.startsWith(home2) ? `~${p.slice(home2.length)}` : p;
|
|
38476
38740
|
}
|
|
38477
38741
|
|
|
38478
38742
|
// packages/bridges/dist/agentmemory.js
|
|
38479
38743
|
import { spawn as spawn2 } from "node:child_process";
|
|
38480
38744
|
import fs47 from "node:fs";
|
|
38481
|
-
import
|
|
38482
|
-
import
|
|
38745
|
+
import os8 from "node:os";
|
|
38746
|
+
import path39 from "node:path";
|
|
38483
38747
|
var AGENTMEMORY_TIMEOUT_MS = 5e3;
|
|
38484
38748
|
var SEARCH_TOOL = "memory_smart_search";
|
|
38485
38749
|
function agentMemoryDirs(opts = {}) {
|
|
38486
38750
|
const env = opts.env ?? process.env;
|
|
38487
|
-
const home2 = opts.home ??
|
|
38751
|
+
const home2 = opts.home ?? os8.homedir();
|
|
38488
38752
|
const out = [];
|
|
38489
38753
|
const push2 = (p, kind2) => {
|
|
38490
38754
|
if (p && !out.some((e) => e.path === p))
|
|
38491
38755
|
out.push({ path: p, kind: kind2 });
|
|
38492
38756
|
};
|
|
38493
38757
|
if (process.platform === "darwin") {
|
|
38494
|
-
push2(
|
|
38758
|
+
push2(path39.join(home2, "Library", "Application Support", "agentmemory"), "app-data");
|
|
38495
38759
|
} else if (process.platform === "win32") {
|
|
38496
38760
|
const appData = env["APPDATA"];
|
|
38497
38761
|
if (appData)
|
|
38498
|
-
push2(
|
|
38762
|
+
push2(path39.join(appData, "agentmemory"), "app-data");
|
|
38499
38763
|
}
|
|
38500
38764
|
const xdgData = env["XDG_DATA_HOME"];
|
|
38501
|
-
push2(
|
|
38765
|
+
push2(path39.join(xdgData || path39.join(home2, ".local", "share"), "agentmemory"), "app-data");
|
|
38502
38766
|
const xdgConfig = env["XDG_CONFIG_HOME"];
|
|
38503
|
-
push2(
|
|
38504
|
-
push2(
|
|
38767
|
+
push2(path39.join(xdgConfig || path39.join(home2, ".config"), "agentmemory"), "app-data");
|
|
38768
|
+
push2(path39.join(home2, ".agentmemory"), "dotdir");
|
|
38505
38769
|
return out;
|
|
38506
38770
|
}
|
|
38507
38771
|
function agentMemoryDir(opts = {}) {
|
|
@@ -38510,7 +38774,7 @@ function agentMemoryDir(opts = {}) {
|
|
|
38510
38774
|
if (fs47.existsSync(c.path))
|
|
38511
38775
|
return c.path;
|
|
38512
38776
|
}
|
|
38513
|
-
return candidates2[0]?.path ??
|
|
38777
|
+
return candidates2[0]?.path ?? path39.join(opts.home ?? os8.homedir(), ".agentmemory");
|
|
38514
38778
|
}
|
|
38515
38779
|
function discoverLaunch(opts = {}) {
|
|
38516
38780
|
const env = opts.env ?? process.env;
|
|
@@ -38523,14 +38787,14 @@ function discoverLaunch(opts = {}) {
|
|
|
38523
38787
|
return { command, args: parts.slice(1), via: "env" };
|
|
38524
38788
|
}
|
|
38525
38789
|
for (const name of [".mcp.json", "mcp.json"]) {
|
|
38526
|
-
const found = fromMcpJson(
|
|
38790
|
+
const found = fromMcpJson(path39.join(dir, name));
|
|
38527
38791
|
if (found)
|
|
38528
38792
|
return found;
|
|
38529
38793
|
}
|
|
38530
38794
|
const onPath3 = which("agentmemory-mcp", env);
|
|
38531
38795
|
if (onPath3)
|
|
38532
38796
|
return { command: onPath3, args: [], via: "PATH" };
|
|
38533
|
-
const local =
|
|
38797
|
+
const local = path39.join(dir, "node_modules", ".bin", "agentmemory-mcp");
|
|
38534
38798
|
if (isExecutable(local))
|
|
38535
38799
|
return { command: local, args: [], via: "node_modules" };
|
|
38536
38800
|
return null;
|
|
@@ -38553,16 +38817,16 @@ function fromMcpJson(file) {
|
|
|
38553
38817
|
if (!command)
|
|
38554
38818
|
continue;
|
|
38555
38819
|
const args = Array.isArray(entry.args) ? entry.args.map(String) : [];
|
|
38556
|
-
if (/^(npx|pnpx|bunx|yarn|npm)$/.test(
|
|
38820
|
+
if (/^(npx|pnpx|bunx|yarn|npm)$/.test(path39.basename(command)))
|
|
38557
38821
|
continue;
|
|
38558
38822
|
return { command, args, via: "mcp.json" };
|
|
38559
38823
|
}
|
|
38560
38824
|
return null;
|
|
38561
38825
|
}
|
|
38562
38826
|
function which(binary, env) {
|
|
38563
|
-
const dirs = (env["PATH"] ?? "").split(
|
|
38827
|
+
const dirs = (env["PATH"] ?? "").split(path39.delimiter).filter(Boolean);
|
|
38564
38828
|
for (const dir of dirs) {
|
|
38565
|
-
const candidate =
|
|
38829
|
+
const candidate = path39.join(dir, binary);
|
|
38566
38830
|
if (isExecutable(candidate))
|
|
38567
38831
|
return candidate;
|
|
38568
38832
|
}
|
|
@@ -38594,7 +38858,7 @@ function detectAgentMemory(opts = {}) {
|
|
|
38594
38858
|
presence: "store",
|
|
38595
38859
|
path: dir,
|
|
38596
38860
|
available: true,
|
|
38597
|
-
detail: `mcp server via ${launch.via} (${
|
|
38861
|
+
detail: `mcp server via ${launch.via} (${path39.basename(launch.command)}), one tool: ${SEARCH_TOOL}`,
|
|
38598
38862
|
headline: `mcp server via ${launch.via}`,
|
|
38599
38863
|
schema: null,
|
|
38600
38864
|
rows: null,
|
|
@@ -38639,7 +38903,7 @@ var StdioClient = class {
|
|
|
38639
38903
|
env: { ...env }
|
|
38640
38904
|
});
|
|
38641
38905
|
} catch (err) {
|
|
38642
|
-
this.failed = `could not start ${
|
|
38906
|
+
this.failed = `could not start ${path39.basename(this.launch.command)}: ${firstLine5(err)}`;
|
|
38643
38907
|
return false;
|
|
38644
38908
|
}
|
|
38645
38909
|
const child = this.child;
|
|
@@ -38941,32 +39205,32 @@ function pick2(row2, keys6) {
|
|
|
38941
39205
|
return "";
|
|
38942
39206
|
}
|
|
38943
39207
|
function tilde2(p) {
|
|
38944
|
-
const home2 =
|
|
39208
|
+
const home2 = os8.homedir();
|
|
38945
39209
|
return p.startsWith(home2) ? `~${p.slice(home2.length)}` : p;
|
|
38946
39210
|
}
|
|
38947
39211
|
|
|
38948
39212
|
// packages/bridges/dist/notes.js
|
|
38949
39213
|
init_dist();
|
|
38950
39214
|
import fs48 from "node:fs";
|
|
38951
|
-
import
|
|
38952
|
-
import
|
|
39215
|
+
import os9 from "node:os";
|
|
39216
|
+
import path40 from "node:path";
|
|
38953
39217
|
var MAX_BYTES = 256 * 1024;
|
|
38954
39218
|
function notesPaths(opts = {}) {
|
|
38955
39219
|
const claude = paths_exports.claudePaths(opts.claudeDir ? paths_exports.expandTilde(opts.claudeDir) : void 0);
|
|
38956
39220
|
const cwd = opts.cwd ?? process.cwd();
|
|
38957
39221
|
const out = [];
|
|
38958
39222
|
out.push({ path: memoryDir(claude.projects, cwd), kind: "auto-memory" });
|
|
38959
|
-
const global =
|
|
38960
|
-
let dir =
|
|
39223
|
+
const global = path40.join(claude.root, "CLAUDE.md");
|
|
39224
|
+
let dir = path40.resolve(cwd);
|
|
38961
39225
|
for (let depth = 0; depth < (opts.maxDepth ?? 6); depth += 1) {
|
|
38962
39226
|
for (const candidate of [
|
|
38963
|
-
|
|
38964
|
-
|
|
39227
|
+
path40.join(dir, "CLAUDE.md"),
|
|
39228
|
+
path40.join(dir, ".claude", "CLAUDE.md")
|
|
38965
39229
|
]) {
|
|
38966
39230
|
if (candidate !== global)
|
|
38967
39231
|
out.push({ path: candidate, kind: "project-claude-md" });
|
|
38968
39232
|
}
|
|
38969
|
-
const parent =
|
|
39233
|
+
const parent = path40.dirname(dir);
|
|
38970
39234
|
if (parent === dir)
|
|
38971
39235
|
break;
|
|
38972
39236
|
dir = parent;
|
|
@@ -38975,7 +39239,7 @@ function notesPaths(opts = {}) {
|
|
|
38975
39239
|
return out;
|
|
38976
39240
|
}
|
|
38977
39241
|
function memoryDir(projectsDir, cwd) {
|
|
38978
|
-
return
|
|
39242
|
+
return path40.join(projectsDir, paths_exports.slugify(path40.resolve(cwd)), "memory");
|
|
38979
39243
|
}
|
|
38980
39244
|
function detectNotes(opts = {}) {
|
|
38981
39245
|
const candidates2 = notesPaths(opts);
|
|
@@ -39028,7 +39292,7 @@ function readableFiles(candidates2) {
|
|
|
39028
39292
|
}
|
|
39029
39293
|
function markdownIn(dir) {
|
|
39030
39294
|
try {
|
|
39031
|
-
return fs48.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.toLowerCase().endsWith(".md")).map((e) =>
|
|
39295
|
+
return fs48.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.toLowerCase().endsWith(".md")).map((e) => path40.join(dir, e.name)).sort();
|
|
39032
39296
|
} catch {
|
|
39033
39297
|
return [];
|
|
39034
39298
|
}
|
|
@@ -39050,7 +39314,7 @@ function describe2(files) {
|
|
|
39050
39314
|
function sections(file, kind2, content2) {
|
|
39051
39315
|
const lines = content2.split("\n");
|
|
39052
39316
|
const out = [];
|
|
39053
|
-
let heading3 =
|
|
39317
|
+
let heading3 = path40.basename(file);
|
|
39054
39318
|
let start = 1;
|
|
39055
39319
|
let buffer = [];
|
|
39056
39320
|
const flush = () => {
|
|
@@ -39063,7 +39327,7 @@ function sections(file, kind2, content2) {
|
|
|
39063
39327
|
const m = /^(#{1,6})\s+(.*\S)\s*$/.exec(line2);
|
|
39064
39328
|
if (m) {
|
|
39065
39329
|
flush();
|
|
39066
|
-
heading3 = m[2] ??
|
|
39330
|
+
heading3 = m[2] ?? path40.basename(file);
|
|
39067
39331
|
start = i + 1;
|
|
39068
39332
|
return;
|
|
39069
39333
|
}
|
|
@@ -39176,7 +39440,7 @@ function oneLine2(s) {
|
|
|
39176
39440
|
return s.replace(/\s+/g, " ").trim().slice(0, 160);
|
|
39177
39441
|
}
|
|
39178
39442
|
function tildify2(p) {
|
|
39179
|
-
const home2 =
|
|
39443
|
+
const home2 = os9.homedir();
|
|
39180
39444
|
return p.startsWith(home2) ? `~${p.slice(home2.length)}` : p;
|
|
39181
39445
|
}
|
|
39182
39446
|
|
|
@@ -39240,11 +39504,11 @@ function federationLine(bridges) {
|
|
|
39240
39504
|
// packages/bridges/dist/export/markdown.js
|
|
39241
39505
|
init_dist();
|
|
39242
39506
|
import fs49 from "node:fs";
|
|
39243
|
-
import
|
|
39507
|
+
import path41 from "node:path";
|
|
39244
39508
|
var TRANSCRIPT_LIMIT = 500;
|
|
39245
39509
|
function exportMarkdown(options) {
|
|
39246
39510
|
const started = Date.now();
|
|
39247
|
-
const dest =
|
|
39511
|
+
const dest = path41.resolve(options.dest);
|
|
39248
39512
|
fs49.mkdirSync(dest, { recursive: true });
|
|
39249
39513
|
const cards = exportCards(options.root, dest);
|
|
39250
39514
|
const transcripts = options.transcripts ? writeTranscripts(dest, options) : null;
|
|
@@ -39258,7 +39522,7 @@ function writeTranscripts(dest, options) {
|
|
|
39258
39522
|
return out;
|
|
39259
39523
|
}
|
|
39260
39524
|
const limit = Math.max(1, options.limit ?? TRANSCRIPT_LIMIT);
|
|
39261
|
-
const root =
|
|
39525
|
+
const root = path41.join(dest, "transcripts");
|
|
39262
39526
|
let listed;
|
|
39263
39527
|
try {
|
|
39264
39528
|
listed = listSessions(db, {}, { limit });
|
|
@@ -39280,9 +39544,9 @@ function writeTranscripts(dest, options) {
|
|
|
39280
39544
|
pushReason(out, firstLine5(err));
|
|
39281
39545
|
continue;
|
|
39282
39546
|
}
|
|
39283
|
-
const file =
|
|
39547
|
+
const file = path41.join(root, session.harness, safeSegment(session.projectName), `${session.id}.md`);
|
|
39284
39548
|
try {
|
|
39285
|
-
fs49.mkdirSync(
|
|
39549
|
+
fs49.mkdirSync(path41.dirname(file), { recursive: true });
|
|
39286
39550
|
fs49.writeFileSync(file, markdown, { mode: 384 });
|
|
39287
39551
|
} catch (err) {
|
|
39288
39552
|
out.skipped += 1;
|
|
@@ -39306,7 +39570,7 @@ function safeSegment(name) {
|
|
|
39306
39570
|
// packages/bridges/dist/export/agentmemory.js
|
|
39307
39571
|
init_dist();
|
|
39308
39572
|
import fs50 from "node:fs";
|
|
39309
|
-
import
|
|
39573
|
+
import path42 from "node:path";
|
|
39310
39574
|
var WRITE_VERBS = ["store", "add", "create", "remember", "write", "upsert", "ingest", "save"];
|
|
39311
39575
|
async function pushToAgentMemory(cards, opts = {}) {
|
|
39312
39576
|
const status3 = detectAgentMemory(opts);
|
|
@@ -39413,7 +39677,7 @@ function collectCards(root, limit = 1e3) {
|
|
|
39413
39677
|
for (const entry of entries) {
|
|
39414
39678
|
if (out.length >= limit)
|
|
39415
39679
|
return;
|
|
39416
|
-
const source =
|
|
39680
|
+
const source = path42.join(dir, entry.name);
|
|
39417
39681
|
if (entry.isDirectory()) {
|
|
39418
39682
|
walk3(source);
|
|
39419
39683
|
continue;
|
|
@@ -40631,10 +40895,10 @@ function wrap4(db) {
|
|
|
40631
40895
|
for (const variant of Object.values(variants)) Object.assign(variant, variants);
|
|
40632
40896
|
return variants.default;
|
|
40633
40897
|
},
|
|
40634
|
-
loadExtension(
|
|
40898
|
+
loadExtension(path46) {
|
|
40635
40899
|
db.enableLoadExtension?.(true);
|
|
40636
40900
|
if (!db.loadExtension) throw new Error("this sqlite cannot load extensions");
|
|
40637
|
-
db.loadExtension(
|
|
40901
|
+
db.loadExtension(path46);
|
|
40638
40902
|
},
|
|
40639
40903
|
// 5. **`function()` registers an application-defined function.** Both
|
|
40640
40904
|
// drivers spell it the same way and both take the arity from
|
|
@@ -41782,12 +42046,12 @@ import { randomUUID as randomUUID13 } from "node:crypto";
|
|
|
41782
42046
|
// packages/core/src/memory/jobs.ts
|
|
41783
42047
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
41784
42048
|
import fs55 from "node:fs";
|
|
41785
|
-
import
|
|
42049
|
+
import path44 from "node:path";
|
|
41786
42050
|
|
|
41787
42051
|
// packages/core/src/memory/leases.ts
|
|
41788
|
-
import
|
|
42052
|
+
import os10 from "node:os";
|
|
41789
42053
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
41790
|
-
var HOST2 =
|
|
42054
|
+
var HOST2 = os10.hostname();
|
|
41791
42055
|
function processStart3(pid) {
|
|
41792
42056
|
try {
|
|
41793
42057
|
return execFileSync3("ps", ["-p", String(pid), "-o", "lstart="], { encoding: "utf8", timeout: 1e3 }).trim() || null;
|
|
@@ -41849,9 +42113,9 @@ function captureStatus(db, jobId) {
|
|
|
41849
42113
|
return { jobId, state: job.state, durable: true, captured: job.state === "done" && result?.captured === true, ...result ? { report: result.report } : {} };
|
|
41850
42114
|
}
|
|
41851
42115
|
function spoolRequest2(root, r) {
|
|
41852
|
-
const dir =
|
|
42116
|
+
const dir = path44.join(root, "maintenance-spool");
|
|
41853
42117
|
fs55.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
41854
|
-
const file =
|
|
42118
|
+
const file = path44.join(dir, identity3("spool/v1", r.kind, r.targetId, r.inputHash) + ".json"), temp = file + "." + randomUUID12() + ".tmp";
|
|
41855
42119
|
const fd = fs55.openSync(temp, "wx", 384);
|
|
41856
42120
|
try {
|
|
41857
42121
|
fs55.writeFileSync(fd, JSON.stringify({ ...r, requestId: r.requestId ?? randomUUID12() }));
|
|
@@ -41874,7 +42138,7 @@ init_dist();
|
|
|
41874
42138
|
init_output();
|
|
41875
42139
|
import { spawn as spawn3 } from "node:child_process";
|
|
41876
42140
|
import process19 from "node:process";
|
|
41877
|
-
import
|
|
42141
|
+
import path45 from "node:path";
|
|
41878
42142
|
var WORKER_ENV = "POTSHERD_EMBED_WORKER";
|
|
41879
42143
|
var INDEXABLE = ["claude", "codex", "cursor", "pi", "opencode"];
|
|
41880
42144
|
var NOT_YET = ["gemini", "copilot"];
|
|
@@ -41891,19 +42155,19 @@ async function runIndex(o) {
|
|
|
41891
42155
|
}
|
|
41892
42156
|
const harnesses = parseHarnesses(o.harness);
|
|
41893
42157
|
const enrollment = { ...o.enroll ? { enrollHarnesses: parseHarnesses(o.enroll) } : {}, ...o.unenroll ? { removeHarnesses: parseHarnesses(o.unenroll) } : {} };
|
|
41894
|
-
const hostRoots = { ...o.piDir ? { piDir:
|
|
42158
|
+
const hostRoots = { ...o.piDir ? { piDir: path45.resolve(paths_exports.expandTilde(o.piDir)) } : {}, ...o.opencodeDir ? { opencodeDir: path45.resolve(paths_exports.expandTilde(o.opencodeDir)) } : {} };
|
|
41895
42159
|
const bar2 = new Progress("indexing", showProgress);
|
|
41896
42160
|
let report;
|
|
41897
42161
|
const queued = async () => {
|
|
41898
|
-
const requestId = randomUUID13(),
|
|
41899
|
-
const request = { kind: "capture", targetId: o.session ?? "*", inputHash: requestId, requestId, capture };
|
|
42162
|
+
const requestId = randomUUID13(), capture2 = { ...enrollment, ...hostRoots, ...o.claudeDir ? { claudeDir: path45.resolve(paths_exports.expandTilde(o.claudeDir)) } : {}, ...o.codexDir ? { codexHome: path45.resolve(paths_exports.expandTilde(o.codexDir)) } : {}, ...harnesses ? { harnesses } : {}, ...o.session ? { sessionId: o.session } : {}, full: Boolean(o.full) };
|
|
42163
|
+
const request = { kind: "capture", targetId: o.session ?? "*", inputHash: requestId, requestId, capture: capture2 };
|
|
41900
42164
|
spoolRequest2(root, request);
|
|
41901
42165
|
const { identity: identity4 } = await Promise.resolve().then(() => (init_spans2(), spans_exports));
|
|
41902
42166
|
const jobId = identity4("job/v1", request.kind, request.targetId, request.inputHash);
|
|
41903
42167
|
startBackgroundEmbedding(root, o);
|
|
41904
|
-
const
|
|
42168
|
+
const deadline2 = Date.now() + Math.max(0, 4e3 - process19.uptime() * 1e3);
|
|
41905
42169
|
let status3 = null;
|
|
41906
|
-
while (Date.now() <
|
|
42170
|
+
while (Date.now() < deadline2) {
|
|
41907
42171
|
try {
|
|
41908
42172
|
const reader = db_exports.openSqliteReadOnly(paths_exports.dbPath(root));
|
|
41909
42173
|
try {
|
|
@@ -44652,8 +44916,8 @@ function recorder() {
|
|
|
44652
44916
|
};
|
|
44653
44917
|
return { fn, seen };
|
|
44654
44918
|
}
|
|
44655
|
-
async function recordReaders(db, question, base2,
|
|
44656
|
-
const { file, abs, probe: probe2 } = await writeReadersFile(db, question, base2,
|
|
44919
|
+
async function recordReaders(db, question, base2, path46, o, t) {
|
|
44920
|
+
const { file, abs, probe: probe2 } = await writeReadersFile(db, question, base2, path46);
|
|
44657
44921
|
if (o.json) {
|
|
44658
44922
|
printJson({
|
|
44659
44923
|
kind: READERS_FILE_KIND,
|
|
@@ -44695,7 +44959,7 @@ async function recordReaders(db, question, base2, path45, o, t) {
|
|
|
44695
44959
|
}
|
|
44696
44960
|
return file.targets.length > 0 ? 0 : 1;
|
|
44697
44961
|
}
|
|
44698
|
-
async function writeReadersFile(db, question, base2,
|
|
44962
|
+
async function writeReadersFile(db, question, base2, path46) {
|
|
44699
44963
|
const rec = recorder();
|
|
44700
44964
|
const probe2 = await ask(db, question, {
|
|
44701
44965
|
...base2,
|
|
@@ -44729,7 +44993,7 @@ async function writeReadersFile(db, question, base2, path45) {
|
|
|
44729
44993
|
// that property worthless. Everything here is a function of the index.
|
|
44730
44994
|
index: { ...indexState(db, base2.root), matching: probe2.matching }
|
|
44731
44995
|
};
|
|
44732
|
-
const abs = nodePath2.resolve(
|
|
44996
|
+
const abs = nodePath2.resolve(path46);
|
|
44733
44997
|
fs59.mkdirSync(nodePath2.dirname(abs), { recursive: true });
|
|
44734
44998
|
fs59.writeFileSync(abs, `${JSON.stringify(file, null, 2)}
|
|
44735
44999
|
`, "utf8");
|
|
@@ -44766,13 +45030,13 @@ function readersOutReceipt(file, abs, probe2, t) {
|
|
|
44766
45030
|
lines.push(` potsherd ask "${file.question}" --readers-in ${abs}`);
|
|
44767
45031
|
return lines.join("\n");
|
|
44768
45032
|
}
|
|
44769
|
-
async function replayReaders(db, question, base2,
|
|
44770
|
-
const staged = await stageReaders(db, question, base2,
|
|
45033
|
+
async function replayReaders(db, question, base2, path46, onNote) {
|
|
45034
|
+
const staged = await stageReaders(db, question, base2, path46);
|
|
44771
45035
|
for (const line2 of staged.notes) onNote?.(line2);
|
|
44772
45036
|
return ask(db, question, { ...base2, pin: staged.pin, readerFn: staged.readerFn });
|
|
44773
45037
|
}
|
|
44774
|
-
async function stageReaders(db, question, base2,
|
|
44775
|
-
const abs = nodePath2.resolve(
|
|
45038
|
+
async function stageReaders(db, question, base2, path46) {
|
|
45039
|
+
const abs = nodePath2.resolve(path46);
|
|
44776
45040
|
const file = readReadersFile(abs);
|
|
44777
45041
|
const q2 = redactOutgoing(question).text;
|
|
44778
45042
|
if (file.question !== q2) {
|
|
@@ -44858,7 +45122,7 @@ function synthCapture() {
|
|
|
44858
45122
|
};
|
|
44859
45123
|
return { fn, seen };
|
|
44860
45124
|
}
|
|
44861
|
-
async function writeSynthesisFile(db, question, base2,
|
|
45125
|
+
async function writeSynthesisFile(db, question, base2, path46, readersPath, onProgress) {
|
|
44862
45126
|
const staged = readersPath ? await stageReaders(db, question, base2, readersPath) : null;
|
|
44863
45127
|
const cap3 = synthCapture();
|
|
44864
45128
|
const probe2 = await ask(db, question, {
|
|
@@ -44874,7 +45138,7 @@ async function writeSynthesisFile(db, question, base2, path45, readersPath, onPr
|
|
|
44874
45138
|
synthFn: cap3.fn,
|
|
44875
45139
|
openThreads: false
|
|
44876
45140
|
});
|
|
44877
|
-
const abs = nodePath2.resolve(
|
|
45141
|
+
const abs = nodePath2.resolve(path46);
|
|
44878
45142
|
const notes = staged?.notes ?? [];
|
|
44879
45143
|
if (!cap3.seen.input) return { file: null, abs, probe: probe2, notes };
|
|
44880
45144
|
const input = cap3.seen.input;
|
|
@@ -44912,12 +45176,12 @@ async function writeSynthesisFile(db, question, base2, path45, readersPath, onPr
|
|
|
44912
45176
|
`, "utf8");
|
|
44913
45177
|
return { file, abs, probe: probe2, notes };
|
|
44914
45178
|
}
|
|
44915
|
-
async function recordSynthesis(db, question, base2,
|
|
45179
|
+
async function recordSynthesis(db, question, base2, path46, readersPath, o, t, onProgress) {
|
|
44916
45180
|
const { file, abs, probe: probe2, notes } = await writeSynthesisFile(
|
|
44917
45181
|
db,
|
|
44918
45182
|
question,
|
|
44919
45183
|
base2,
|
|
44920
|
-
|
|
45184
|
+
path46,
|
|
44921
45185
|
readersPath,
|
|
44922
45186
|
onProgress
|
|
44923
45187
|
);
|
|
@@ -44975,8 +45239,8 @@ function synthesisOutReceipt(file, abs, probe2, t) {
|
|
|
44975
45239
|
lines.push(` potsherd ask "${file.question}" --filter-in ${abs}`);
|
|
44976
45240
|
return lines.join("\n");
|
|
44977
45241
|
}
|
|
44978
|
-
async function filterHostAnswer(db, question, base2,
|
|
44979
|
-
const abs = nodePath2.resolve(
|
|
45242
|
+
async function filterHostAnswer(db, question, base2, path46, onNote) {
|
|
45243
|
+
const abs = nodePath2.resolve(path46);
|
|
44980
45244
|
const file = readSynthesisFile(abs);
|
|
44981
45245
|
const q2 = redactOutgoing(question).text;
|
|
44982
45246
|
if (file.question !== q2) {
|