@wrongstack/core 0.268.0 → 0.270.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-bridge-UhojbpWx.d.ts → agent-bridge-PcHQl_UQ.d.ts} +1 -1
- package/dist/{agent-subagent-runner-Bvtf1o9K.d.ts → agent-subagent-runner-SHJW7t8q.d.ts} +8 -8
- package/dist/{brain-69wzMKp1.d.ts → brain-BYcK__Ym.d.ts} +1 -1
- package/dist/{compactor-CBQAJoDc.d.ts → compactor-C2RKEBtC.d.ts} +1 -1
- package/dist/{config-VKfOZ-6X.d.ts → config-C_ae2k86.d.ts} +11 -2
- package/dist/{context-C0U8B9NF.d.ts → context-Dp87Bcaq.d.ts} +24 -1
- package/dist/coordination/index.d.ts +22 -16
- package/dist/coordination/index.js +233 -86
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +25 -25
- package/dist/defaults/index.js +272 -69
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +15 -15
- package/dist/execution/index.js +116 -19
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{global-mailbox-KByEFFBa.d.ts → global-mailbox-Bvrz1P3f.d.ts} +2 -1
- package/dist/{goal-preamble-CrYjmdw4.d.ts → goal-preamble-CA_4yiGQ.d.ts} +9 -9
- package/dist/{goal-store-Y_zdLZ3q.d.ts → goal-store-DhuJoUNG.d.ts} +1 -1
- package/dist/hq/index.d.ts +15 -6
- package/dist/hq/index.js +58 -11
- package/dist/hq/index.js.map +1 -1
- package/dist/{index-CtQnmkaS.d.ts → index-CZQ6Pwbs.d.ts} +8 -8
- package/dist/{index-gCv830d7.d.ts → index-W4VJCzHa.d.ts} +5 -5
- package/dist/{index-BfaS-f_m.d.ts → index-whDfTANu.d.ts} +2 -2
- package/dist/index.d.ts +41 -41
- package/dist/index.js +534 -170
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +3 -3
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +9 -9
- package/dist/{mcp-servers-HT3Fi7Bl.d.ts → mcp-servers-DJdZiRcv.d.ts} +3 -3
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +1 -1
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-Bvcl3Vaa.d.ts → models-registry-C3a-2-Yd.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-BACjsmkC.d.ts → multi-agent-coordinator-CJSpTe5O.d.ts} +1 -1
- package/dist/{null-fleet-bus-DA7fvhUg.d.ts → null-fleet-bus-QVshIsDx.d.ts} +6 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-Ci71gYu_.d.ts → parallel-eternal-engine-D9y5Pkcc.d.ts} +9 -9
- package/dist/{path-resolver-O1IJnmKE.d.ts → path-resolver-CnQ8SIfh.d.ts} +3 -3
- package/dist/{permission-Bd-57Lbl.d.ts → permission-CvYQNUqZ.d.ts} +1 -1
- package/dist/{permission-policy-uNXC6Kge.d.ts → permission-policy-D5Ss8j4B.d.ts} +2 -2
- package/dist/{pipeline-BDNvENyV.d.ts → pipeline-l_zzFRh3.d.ts} +2 -2
- package/dist/{plan-templates-EMsalEtN.d.ts → plan-templates-NtPgyeJA.d.ts} +6 -5
- package/dist/{provider-model-resolve-CEb9x886.d.ts → provider-model-resolve-d5poT5y0.d.ts} +3 -3
- package/dist/{provider-runner-DWJbpo70.d.ts → provider-runner-gkctlQV_.d.ts} +3 -3
- package/dist/{retry-policy-C3s_lvdK.d.ts → retry-policy-CtFhfwa8.d.ts} +1 -1
- package/dist/sdd/index.d.ts +8 -8
- package/dist/sdd/index.js +1 -1
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-Cgduf5xL.d.ts → secret-vault-BLsVmTIK.d.ts} +1 -1
- package/dist/security/index.d.ts +5 -5
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-47LBnBVk.d.ts → selector-CXl2_y9W.d.ts} +1 -1
- package/dist/{session-event-bridge-Cw7oqmW2.d.ts → session-event-bridge-Ccud20CC.d.ts} +1 -1
- package/dist/{session-reader-DD4v2Obw.d.ts → session-reader-ZeXQmsmE.d.ts} +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +13 -11
- package/dist/storage/index.js +210 -64
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +21 -21
- package/dist/types/index.js +110 -19
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.js +58 -24
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/chimera/SKILL.md +1 -1
- package/skills/typescript-strict/SKILL.md +3 -3
- package/skills/typescript-strict/SKILL.save.md +1 -1
|
@@ -172,8 +172,8 @@ async function atomicWrite(targetPath, content, opts = {}) {
|
|
|
172
172
|
}
|
|
173
173
|
let mode;
|
|
174
174
|
try {
|
|
175
|
-
const
|
|
176
|
-
mode =
|
|
175
|
+
const stat7 = await fsp6.stat(targetPath);
|
|
176
|
+
mode = stat7.mode & 511;
|
|
177
177
|
} catch {
|
|
178
178
|
mode = opts.mode;
|
|
179
179
|
}
|
|
@@ -213,8 +213,8 @@ async function withFileLock(targetPath, fn, opts = {}) {
|
|
|
213
213
|
}
|
|
214
214
|
if (code !== "EEXIST") throw err;
|
|
215
215
|
try {
|
|
216
|
-
const
|
|
217
|
-
if (Date.now() -
|
|
216
|
+
const stat7 = await fsp6.stat(lockPath);
|
|
217
|
+
if (Date.now() - stat7.mtimeMs > staleMs) {
|
|
218
218
|
await fsp6.unlink(lockPath);
|
|
219
219
|
continue;
|
|
220
220
|
}
|
|
@@ -545,8 +545,8 @@ async function expandGlob(pattern) {
|
|
|
545
545
|
for (const e of entries) {
|
|
546
546
|
const full = `${dir}${SEP}${e}`;
|
|
547
547
|
try {
|
|
548
|
-
const
|
|
549
|
-
if (
|
|
548
|
+
const stat7 = await fsp6.stat(full);
|
|
549
|
+
if (stat7.isDirectory()) await walk(full, rest);
|
|
550
550
|
} catch {
|
|
551
551
|
}
|
|
552
552
|
}
|
|
@@ -563,8 +563,8 @@ async function expandGlob(pattern) {
|
|
|
563
563
|
if (entries.includes(seg)) {
|
|
564
564
|
const full = `${dir}${SEP}${seg}`;
|
|
565
565
|
try {
|
|
566
|
-
const
|
|
567
|
-
if (
|
|
566
|
+
const stat7 = await fsp6.stat(full);
|
|
567
|
+
if (stat7.isDirectory()) await walk(full, rest);
|
|
568
568
|
} catch {
|
|
569
569
|
}
|
|
570
570
|
}
|
|
@@ -636,7 +636,7 @@ function hasToolResult(msg) {
|
|
|
636
636
|
}
|
|
637
637
|
function toolUseIds(msg) {
|
|
638
638
|
const ids = /* @__PURE__ */ new Set();
|
|
639
|
-
if (
|
|
639
|
+
if (msg?.role !== "assistant") return ids;
|
|
640
640
|
for (const block of contentBlocks(msg)) {
|
|
641
641
|
if (block.type === "tool_use") ids.add(block.id);
|
|
642
642
|
}
|
|
@@ -644,7 +644,7 @@ function toolUseIds(msg) {
|
|
|
644
644
|
}
|
|
645
645
|
function toolResultIds(msg) {
|
|
646
646
|
const ids = /* @__PURE__ */ new Set();
|
|
647
|
-
if (
|
|
647
|
+
if (msg?.role !== "user") return ids;
|
|
648
648
|
for (const block of contentBlocks(msg)) {
|
|
649
649
|
if (block.type === "tool_result") ids.add(block.tool_use_id);
|
|
650
650
|
}
|
|
@@ -996,7 +996,7 @@ var CollabSession = class extends EventEmitter {
|
|
|
996
996
|
}
|
|
997
997
|
for (const filePath of allFiles) {
|
|
998
998
|
try {
|
|
999
|
-
const [content,
|
|
999
|
+
const [content, stat7] = await Promise.all([
|
|
1000
1000
|
fsp6.readFile(filePath, "utf8"),
|
|
1001
1001
|
fsp6.stat(filePath)
|
|
1002
1002
|
]);
|
|
@@ -1006,8 +1006,8 @@ var CollabSession = class extends EventEmitter {
|
|
|
1006
1006
|
path: filePath,
|
|
1007
1007
|
content,
|
|
1008
1008
|
language,
|
|
1009
|
-
snapshotMtimeMs:
|
|
1010
|
-
snapshotSizeBytes:
|
|
1009
|
+
snapshotMtimeMs: stat7.mtimeMs,
|
|
1010
|
+
snapshotSizeBytes: stat7.size
|
|
1011
1011
|
});
|
|
1012
1012
|
} catch {
|
|
1013
1013
|
this.snapshot.files.push({ path: filePath, content: "", language: void 0 });
|
|
@@ -1420,9 +1420,9 @@ Emit each evaluation immediately. Do not wait until you have read all reports.`;
|
|
|
1420
1420
|
for (const file of this.snapshot.files) {
|
|
1421
1421
|
if (file.snapshotMtimeMs === void 0 && file.snapshotSizeBytes === void 0) continue;
|
|
1422
1422
|
try {
|
|
1423
|
-
const
|
|
1424
|
-
const mtimeChanged = file.snapshotMtimeMs !== void 0 &&
|
|
1425
|
-
const sizeChanged = file.snapshotSizeBytes !== void 0 &&
|
|
1423
|
+
const stat7 = await fsp6.stat(file.path);
|
|
1424
|
+
const mtimeChanged = file.snapshotMtimeMs !== void 0 && stat7.mtimeMs > file.snapshotMtimeMs + 1;
|
|
1425
|
+
const sizeChanged = file.snapshotSizeBytes !== void 0 && stat7.size !== file.snapshotSizeBytes;
|
|
1426
1426
|
if (mtimeChanged || sizeChanged) {
|
|
1427
1427
|
warnings.push(`${file.path} changed after the collab snapshot was captured.`);
|
|
1428
1428
|
}
|
|
@@ -5432,7 +5432,7 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
5432
5432
|
*/
|
|
5433
5433
|
_busRequestDecision(entry) {
|
|
5434
5434
|
const bus = this._events;
|
|
5435
|
-
if (!bus
|
|
5435
|
+
if (!bus?.hasListenerFor("budget.threshold_reached")) {
|
|
5436
5436
|
return Promise.resolve("stop");
|
|
5437
5437
|
}
|
|
5438
5438
|
return new Promise((resolve3) => {
|
|
@@ -8763,6 +8763,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
8763
8763
|
* processes. When the limit is reached, the oldest entry is evicted.
|
|
8764
8764
|
*/
|
|
8765
8765
|
_loadCache = /* @__PURE__ */ new Map();
|
|
8766
|
+
_indexCache = null;
|
|
8766
8767
|
static LOAD_CACHE_MAX_ENTRIES = 50;
|
|
8767
8768
|
constructor(opts) {
|
|
8768
8769
|
this.dir = opts.dir;
|
|
@@ -8924,15 +8925,10 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
8924
8925
|
let errorMsg;
|
|
8925
8926
|
let cacheHit = false;
|
|
8926
8927
|
try {
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
const s = await fsp6.stat(file);
|
|
8930
|
-
stat6 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
8931
|
-
} catch (err) {
|
|
8932
|
-
throw err;
|
|
8933
|
-
}
|
|
8928
|
+
const s = await fsp6.stat(file);
|
|
8929
|
+
const stat7 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
8934
8930
|
const cached = this._loadCache.get(id);
|
|
8935
|
-
if (cached && cached.mtimeMs ===
|
|
8931
|
+
if (cached && cached.mtimeMs === stat7.mtimeMs && cached.size === stat7.size) {
|
|
8936
8932
|
cacheHit = true;
|
|
8937
8933
|
this._loadCache.delete(id);
|
|
8938
8934
|
this._loadCache.set(id, cached);
|
|
@@ -8960,7 +8956,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
8960
8956
|
this._loadCache.delete(oldest);
|
|
8961
8957
|
}
|
|
8962
8958
|
}
|
|
8963
|
-
this._loadCache.set(id, { mtimeMs:
|
|
8959
|
+
this._loadCache.set(id, { mtimeMs: stat7.mtimeMs, size: stat7.size, data });
|
|
8964
8960
|
return data;
|
|
8965
8961
|
} catch (err) {
|
|
8966
8962
|
outcome = "failure";
|
|
@@ -9021,6 +9017,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
9021
9017
|
await ensureDir(this.dir);
|
|
9022
9018
|
const line = JSON.stringify(summary) + "\n";
|
|
9023
9019
|
await fsp6.appendFile(this.indexFile, line, "utf8");
|
|
9020
|
+
this._indexCache = null;
|
|
9024
9021
|
this.indexAppendCount++;
|
|
9025
9022
|
if (this.indexAppendCount >= _DefaultSessionStore.COMPACT_EVERY) {
|
|
9026
9023
|
await this.compactIndex();
|
|
@@ -9035,6 +9032,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
9035
9032
|
await ensureDir(this.dir);
|
|
9036
9033
|
const line = JSON.stringify({ action: "delete", id }) + "\n";
|
|
9037
9034
|
await fsp6.appendFile(this.indexFile, line, "utf8");
|
|
9035
|
+
this._indexCache = null;
|
|
9038
9036
|
this.indexAppendCount++;
|
|
9039
9037
|
} catch {
|
|
9040
9038
|
}
|
|
@@ -9054,6 +9052,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
9054
9052
|
const lines = entries.map((s) => JSON.stringify(s)).join("\n") + "\n";
|
|
9055
9053
|
await fsp6.writeFile(tmp, lines, "utf8");
|
|
9056
9054
|
await fsp6.rename(tmp, this.indexFile);
|
|
9055
|
+
this._indexCache = null;
|
|
9057
9056
|
} catch (err) {
|
|
9058
9057
|
outcome = "failure";
|
|
9059
9058
|
errorMsg = toErrorMessage(err);
|
|
@@ -9067,10 +9066,22 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
9067
9066
|
* Returns empty array when the index doesn't exist or is corrupt.
|
|
9068
9067
|
*/
|
|
9069
9068
|
async readIndex() {
|
|
9069
|
+
let stat7;
|
|
9070
|
+
try {
|
|
9071
|
+
const s = await fsp6.stat(this.indexFile);
|
|
9072
|
+
stat7 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
9073
|
+
} catch {
|
|
9074
|
+
this._indexCache = null;
|
|
9075
|
+
return [];
|
|
9076
|
+
}
|
|
9077
|
+
if (this._indexCache !== null && this._indexCache.mtimeMs === stat7.mtimeMs && this._indexCache.size === stat7.size) {
|
|
9078
|
+
return [...this._indexCache.summaries];
|
|
9079
|
+
}
|
|
9070
9080
|
let raw;
|
|
9071
9081
|
try {
|
|
9072
9082
|
raw = await fsp6.readFile(this.indexFile, "utf8");
|
|
9073
9083
|
} catch {
|
|
9084
|
+
this._indexCache = null;
|
|
9074
9085
|
return [];
|
|
9075
9086
|
}
|
|
9076
9087
|
const deleted = /* @__PURE__ */ new Set();
|
|
@@ -9090,7 +9101,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
9090
9101
|
} catch {
|
|
9091
9102
|
}
|
|
9092
9103
|
}
|
|
9093
|
-
|
|
9104
|
+
const summaries = Array.from(seen.values());
|
|
9105
|
+
this._indexCache = { ...stat7, summaries };
|
|
9106
|
+
return [...summaries];
|
|
9094
9107
|
}
|
|
9095
9108
|
/**
|
|
9096
9109
|
* Rebuild the index from disk by scanning all sessions and writing a
|
|
@@ -9104,6 +9117,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
9104
9117
|
const lines = valid.map((s) => JSON.stringify(s)).join("\n") + "\n";
|
|
9105
9118
|
await fsp6.writeFile(tmp, lines, "utf8");
|
|
9106
9119
|
await fsp6.rename(tmp, this.indexFile);
|
|
9120
|
+
this._indexCache = null;
|
|
9107
9121
|
return valid.length;
|
|
9108
9122
|
}
|
|
9109
9123
|
/** Recursively collect session IDs from date-shard subdirectories.
|
|
@@ -9144,8 +9158,8 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
9144
9158
|
return JSON.parse(raw);
|
|
9145
9159
|
} catch {
|
|
9146
9160
|
const full = this.sessionPath(id, ".jsonl");
|
|
9147
|
-
const
|
|
9148
|
-
const summary = await this.summarize(id,
|
|
9161
|
+
const stat7 = await fsp6.stat(full);
|
|
9162
|
+
const summary = await this.summarize(id, stat7.mtime.toISOString());
|
|
9149
9163
|
await atomicWrite(manifest, JSON.stringify(summary), { mode: 384 }).catch((err) => {
|
|
9150
9164
|
const msg = toErrorMessage(err);
|
|
9151
9165
|
this.emitError(id, manifest, "summary_fallback", msg, true);
|
|
@@ -9227,8 +9241,8 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
9227
9241
|
const pruneFile = async (dir, name, prefix) => {
|
|
9228
9242
|
const jsonlPath = path5.join(dir, name);
|
|
9229
9243
|
try {
|
|
9230
|
-
const
|
|
9231
|
-
if (
|
|
9244
|
+
const stat7 = await fsp6.stat(jsonlPath);
|
|
9245
|
+
if (stat7.mtimeMs >= cutoff) return;
|
|
9232
9246
|
} catch {
|
|
9233
9247
|
return;
|
|
9234
9248
|
}
|
|
@@ -9803,6 +9817,12 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
9803
9817
|
files
|
|
9804
9818
|
});
|
|
9805
9819
|
}
|
|
9820
|
+
/**
|
|
9821
|
+
* Truncate the session file to the checkpoint with the given promptIndex,
|
|
9822
|
+
* removing all events that follow it. Uses a single-pass byte-offset scan
|
|
9823
|
+
* so post-checkpoint content is never read or parsed — O(1) memory instead
|
|
9824
|
+
* of O(N) JSON.parse calls over the full file.
|
|
9825
|
+
*/
|
|
9806
9826
|
async truncateToCheckpoint(targetPromptIndex) {
|
|
9807
9827
|
if (!this.filePath) return 0;
|
|
9808
9828
|
if (this.flushTimer) {
|
|
@@ -9811,51 +9831,118 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
9811
9831
|
}
|
|
9812
9832
|
await this.flushBuffer();
|
|
9813
9833
|
await this.writeChain;
|
|
9814
|
-
const
|
|
9815
|
-
|
|
9816
|
-
|
|
9834
|
+
const CHUNK_SIZE = 65536;
|
|
9835
|
+
let fd;
|
|
9836
|
+
let fileOffset = 0;
|
|
9837
|
+
let lineStartOffset = 0;
|
|
9838
|
+
let checkpointByteOffset = -1;
|
|
9817
9839
|
let removedCount = 0;
|
|
9818
|
-
let
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
|
|
9840
|
+
let targetCheckpointSeen = false;
|
|
9841
|
+
try {
|
|
9842
|
+
fd = await fsp6.open(this.filePath, "r", 384);
|
|
9843
|
+
while (true) {
|
|
9844
|
+
const buf = Buffer.alloc(CHUNK_SIZE);
|
|
9845
|
+
const { bytesRead } = await fd.read(buf, 0, CHUNK_SIZE, fileOffset);
|
|
9846
|
+
if (bytesRead === 0) break;
|
|
9847
|
+
let chunkPos = 0;
|
|
9848
|
+
while (chunkPos < bytesRead) {
|
|
9849
|
+
const idx = buf.indexOf("\n", chunkPos);
|
|
9850
|
+
if (idx === -1) {
|
|
9851
|
+
lineStartOffset = fileOffset + chunkPos;
|
|
9852
|
+
break;
|
|
9853
|
+
}
|
|
9854
|
+
if (checkpointByteOffset !== -1) {
|
|
9855
|
+
removedCount++;
|
|
9856
|
+
} else {
|
|
9857
|
+
const lineBytes = buf.subarray(chunkPos, idx);
|
|
9858
|
+
const line = new TextDecoder("utf-8", { fatal: false }).decode(lineBytes);
|
|
9859
|
+
if (line.trim()) {
|
|
9860
|
+
try {
|
|
9861
|
+
const event = JSON.parse(line);
|
|
9862
|
+
if (event.type === "checkpoint") {
|
|
9863
|
+
if (event.promptIndex === targetPromptIndex) {
|
|
9864
|
+
checkpointByteOffset = lineStartOffset;
|
|
9865
|
+
targetCheckpointSeen = true;
|
|
9866
|
+
} else if (event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
9867
|
+
checkpointByteOffset = lineStartOffset;
|
|
9868
|
+
}
|
|
9869
|
+
} else if (targetCheckpointSeen && event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
9870
|
+
removedCount++;
|
|
9871
|
+
} else if (targetCheckpointSeen && event.promptIndex === void 0) {
|
|
9872
|
+
removedCount++;
|
|
9873
|
+
} else if (!targetCheckpointSeen && event.promptIndex === void 0) {
|
|
9874
|
+
removedCount++;
|
|
9875
|
+
} else if (!targetCheckpointSeen && event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
9876
|
+
removedCount++;
|
|
9877
|
+
}
|
|
9878
|
+
} catch {
|
|
9879
|
+
}
|
|
9880
|
+
}
|
|
9881
|
+
}
|
|
9882
|
+
chunkPos = idx + 1;
|
|
9883
|
+
lineStartOffset = fileOffset + chunkPos;
|
|
9836
9884
|
}
|
|
9837
|
-
|
|
9838
|
-
|
|
9839
|
-
|
|
9840
|
-
} else if (event.promptIndex === void 0) {
|
|
9841
|
-
if (!afterTarget || targetCheckpointLine === -1) {
|
|
9842
|
-
kept.push(line);
|
|
9843
|
-
} else {
|
|
9844
|
-
removedCount++;
|
|
9885
|
+
fileOffset += bytesRead;
|
|
9886
|
+
if (chunkPos >= bytesRead) {
|
|
9887
|
+
lineStartOffset = fileOffset;
|
|
9845
9888
|
}
|
|
9846
|
-
} else {
|
|
9847
|
-
kept.push(line);
|
|
9848
9889
|
}
|
|
9890
|
+
} finally {
|
|
9891
|
+
await fd?.close();
|
|
9849
9892
|
}
|
|
9850
|
-
|
|
9893
|
+
if (checkpointByteOffset === -1) return 0;
|
|
9894
|
+
await this.writeChain;
|
|
9895
|
+
await this.handle.close();
|
|
9851
9896
|
const tmpPath = `${this.filePath}.rewind.tmp`;
|
|
9852
|
-
await fsp6.
|
|
9897
|
+
const src = await fsp6.open(this.filePath, "r", 384);
|
|
9853
9898
|
try {
|
|
9854
|
-
await
|
|
9899
|
+
const statResult = await src.stat();
|
|
9900
|
+
const totalSize = statResult.size;
|
|
9901
|
+
const prefixBytes = checkpointByteOffset;
|
|
9902
|
+
let newlineAfterCheckpoint = prefixBytes;
|
|
9903
|
+
if (prefixBytes < totalSize) {
|
|
9904
|
+
const probeBuf = Buffer.alloc(Math.min(CHUNK_SIZE, totalSize - prefixBytes));
|
|
9905
|
+
const { bytesRead: probeRead } = await src.read(probeBuf, 0, probeBuf.length, prefixBytes);
|
|
9906
|
+
if (probeRead > 0) {
|
|
9907
|
+
const nl = probeBuf.indexOf("\n");
|
|
9908
|
+
newlineAfterCheckpoint = nl !== -1 ? prefixBytes + nl + 1 : totalSize;
|
|
9909
|
+
}
|
|
9910
|
+
} else {
|
|
9911
|
+
newlineAfterCheckpoint = totalSize;
|
|
9912
|
+
}
|
|
9913
|
+
const writeFd = await fsp6.open(tmpPath, "w", 384);
|
|
9914
|
+
try {
|
|
9915
|
+
let copied = 0;
|
|
9916
|
+
let readOffset = 0;
|
|
9917
|
+
while (readOffset < newlineAfterCheckpoint) {
|
|
9918
|
+
const toCopy = Math.min(CHUNK_SIZE, newlineAfterCheckpoint - readOffset);
|
|
9919
|
+
const copyBuf = Buffer.alloc(toCopy);
|
|
9920
|
+
const { bytesRead: r } = await src.read(copyBuf, 0, toCopy, readOffset);
|
|
9921
|
+
if (r === 0) break;
|
|
9922
|
+
await writeFd.write(copyBuf, 0, r);
|
|
9923
|
+
readOffset += r;
|
|
9924
|
+
copied += r;
|
|
9925
|
+
}
|
|
9926
|
+
const raw = await fsp6.readFile(this.filePath);
|
|
9927
|
+
const tail = raw.subarray(newlineAfterCheckpoint).toString("utf8");
|
|
9928
|
+
for (const line of tail.split("\n")) {
|
|
9929
|
+
if (!line.trim()) continue;
|
|
9930
|
+
try {
|
|
9931
|
+
JSON.parse(line);
|
|
9932
|
+
} catch {
|
|
9933
|
+
await writeFd.write(`${line}
|
|
9934
|
+
`, void 0, "utf8");
|
|
9935
|
+
}
|
|
9936
|
+
}
|
|
9937
|
+
} finally {
|
|
9938
|
+
await writeFd.close();
|
|
9939
|
+
}
|
|
9940
|
+
await src.close();
|
|
9855
9941
|
await fsp6.rename(tmpPath, this.filePath);
|
|
9856
9942
|
this.handle = await fsp6.open(this.filePath, "a", 384);
|
|
9857
9943
|
} catch (err) {
|
|
9858
9944
|
await fsp6.unlink(tmpPath).catch(() => void 0);
|
|
9945
|
+
this.handle = await fsp6.open(this.filePath, "a", 384).catch(() => this.handle);
|
|
9859
9946
|
throw err;
|
|
9860
9947
|
}
|
|
9861
9948
|
await this.append({
|
|
@@ -10394,8 +10481,12 @@ function normalizeRecipient(to) {
|
|
|
10394
10481
|
// src/coordination/mailbox.ts
|
|
10395
10482
|
var MAILBOX_FILE = "_mailbox.jsonl";
|
|
10396
10483
|
var LINE_SEPARATOR = "\n";
|
|
10484
|
+
var MESSAGE_CACHE_MAX_ENTRIES = 1e4;
|
|
10397
10485
|
var DefaultMailbox = class {
|
|
10398
10486
|
filePath;
|
|
10487
|
+
_messageCache = null;
|
|
10488
|
+
_messageCacheMtime = -1;
|
|
10489
|
+
_messageCacheSize = -1;
|
|
10399
10490
|
constructor(sessionDir) {
|
|
10400
10491
|
this.filePath = path5.join(sessionDir, MAILBOX_FILE);
|
|
10401
10492
|
}
|
|
@@ -10425,12 +10516,13 @@ var DefaultMailbox = class {
|
|
|
10425
10516
|
await fsp6.mkdir(path5.dirname(this.filePath), { recursive: true });
|
|
10426
10517
|
await withFileLock(this.filePath, async () => {
|
|
10427
10518
|
await fsp6.appendFile(this.filePath, line, "utf8");
|
|
10519
|
+
this._pushToCache(msg);
|
|
10428
10520
|
});
|
|
10429
10521
|
return msg;
|
|
10430
10522
|
}
|
|
10431
10523
|
// ── Query ─────────────────────────────────────────────────────────────
|
|
10432
10524
|
async query(q) {
|
|
10433
|
-
const all = await this.
|
|
10525
|
+
const all = await this._readAllCached();
|
|
10434
10526
|
const limit = q.limit ?? 50;
|
|
10435
10527
|
const order = q.minPriority !== void 0 ? { low: 0, normal: 1, high: 2 } : null;
|
|
10436
10528
|
const minPriorityRank = order && q.minPriority !== void 0 ? order[q.minPriority] : 0;
|
|
@@ -10485,12 +10577,13 @@ var DefaultMailbox = class {
|
|
|
10485
10577
|
const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
|
|
10486
10578
|
await fsp6.writeFile(this.filePath, serialized, "utf8");
|
|
10487
10579
|
}
|
|
10580
|
+
this._setMessageCache(all);
|
|
10488
10581
|
});
|
|
10489
10582
|
return updated;
|
|
10490
10583
|
}
|
|
10491
10584
|
// ── Agent statuses ────────────────────────────────────────────────────
|
|
10492
10585
|
async getAgentStatuses() {
|
|
10493
|
-
const all = await this.
|
|
10586
|
+
const all = await this._readAllCached();
|
|
10494
10587
|
const latest = /* @__PURE__ */ new Map();
|
|
10495
10588
|
for (const m of all) {
|
|
10496
10589
|
if (m.type !== "status") continue;
|
|
@@ -10526,16 +10619,20 @@ var DefaultMailbox = class {
|
|
|
10526
10619
|
async heartbeat(_input) {
|
|
10527
10620
|
}
|
|
10528
10621
|
async unreadCount(forAgentId) {
|
|
10529
|
-
const all = await this.
|
|
10622
|
+
const all = await this._readAllCached();
|
|
10530
10623
|
return all.filter(
|
|
10531
10624
|
(m) => (m.to === forAgentId || m.to === "*") && !(forAgentId in m.readBy) && !m.completed
|
|
10532
10625
|
).length;
|
|
10533
10626
|
}
|
|
10534
10627
|
async close() {
|
|
10628
|
+
this._messageCache = null;
|
|
10629
|
+
this._messageCacheMtime = -1;
|
|
10630
|
+
this._messageCacheSize = -1;
|
|
10535
10631
|
}
|
|
10536
10632
|
async clearAll() {
|
|
10537
10633
|
await withFileLock(this.filePath, async () => {
|
|
10538
10634
|
await fsp6.writeFile(this.filePath, "", "utf8");
|
|
10635
|
+
this._setMessageCache([]);
|
|
10539
10636
|
});
|
|
10540
10637
|
}
|
|
10541
10638
|
async purgeStale(opts) {
|
|
@@ -10543,13 +10640,14 @@ var DefaultMailbox = class {
|
|
|
10543
10640
|
const INCOMPLETE_MAX_AGE_MS = opts?.incompleteMaxAgeMs ?? 6048e5;
|
|
10544
10641
|
let completedPurged = 0;
|
|
10545
10642
|
let incompletePurged = 0;
|
|
10643
|
+
let remaining = 0;
|
|
10546
10644
|
await withFileLock(this.filePath, async () => {
|
|
10547
|
-
const
|
|
10645
|
+
const all = await this._readAll();
|
|
10548
10646
|
const now = Date.now();
|
|
10549
10647
|
const cutoffCompleted = now - COMPLETED_MAX_AGE_MS;
|
|
10550
10648
|
const cutoffIncomplete = now - INCOMPLETE_MAX_AGE_MS;
|
|
10551
10649
|
const kept = [];
|
|
10552
|
-
for (const msg of
|
|
10650
|
+
for (const msg of all) {
|
|
10553
10651
|
const msgTime = new Date(msg.timestamp).getTime();
|
|
10554
10652
|
const completedTime = msg.completedAt ? new Date(msg.completedAt).getTime() : 0;
|
|
10555
10653
|
if (msg.completed && completedTime < cutoffCompleted) {
|
|
@@ -10562,17 +10660,18 @@ var DefaultMailbox = class {
|
|
|
10562
10660
|
}
|
|
10563
10661
|
kept.push(msg);
|
|
10564
10662
|
}
|
|
10565
|
-
|
|
10663
|
+
remaining = kept.length;
|
|
10664
|
+
if (kept.length < all.length) {
|
|
10566
10665
|
const content = kept.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
|
|
10567
10666
|
await fsp6.writeFile(this.filePath, content, "utf8");
|
|
10568
10667
|
}
|
|
10668
|
+
this._setMessageCache(kept);
|
|
10569
10669
|
});
|
|
10570
|
-
const all = await this._readAll();
|
|
10571
10670
|
return {
|
|
10572
10671
|
completedPurged,
|
|
10573
10672
|
incompletePurged,
|
|
10574
10673
|
totalPurged: completedPurged + incompletePurged,
|
|
10575
|
-
remaining
|
|
10674
|
+
remaining
|
|
10576
10675
|
};
|
|
10577
10676
|
}
|
|
10578
10677
|
// ── Client registry stubs (not applicable per-session) ─────────────────
|
|
@@ -10611,6 +10710,52 @@ var DefaultMailbox = class {
|
|
|
10611
10710
|
throw err;
|
|
10612
10711
|
}
|
|
10613
10712
|
}
|
|
10713
|
+
async _readAllCached() {
|
|
10714
|
+
try {
|
|
10715
|
+
const st = await fsp6.stat(this.filePath);
|
|
10716
|
+
if (this._messageCache !== null && this._messageCacheMtime === st.mtimeMs && this._messageCacheSize === st.size) {
|
|
10717
|
+
return this._messageCache;
|
|
10718
|
+
}
|
|
10719
|
+
const all = await this._readAll();
|
|
10720
|
+
this._setMessageCache(all, st.mtimeMs, st.size);
|
|
10721
|
+
return all;
|
|
10722
|
+
} catch (err) {
|
|
10723
|
+
if (err.code === "ENOENT") {
|
|
10724
|
+
this._setMessageCache([], -1, -1);
|
|
10725
|
+
return [];
|
|
10726
|
+
}
|
|
10727
|
+
throw err;
|
|
10728
|
+
}
|
|
10729
|
+
}
|
|
10730
|
+
_setMessageCache(messages, mtime, size) {
|
|
10731
|
+
if (messages.length > MESSAGE_CACHE_MAX_ENTRIES) {
|
|
10732
|
+
this._messageCache = null;
|
|
10733
|
+
this._messageCacheMtime = -1;
|
|
10734
|
+
this._messageCacheSize = -1;
|
|
10735
|
+
return;
|
|
10736
|
+
}
|
|
10737
|
+
this._messageCache = messages;
|
|
10738
|
+
if (mtime !== void 0 && size !== void 0) {
|
|
10739
|
+
this._messageCacheMtime = mtime;
|
|
10740
|
+
this._messageCacheSize = size;
|
|
10741
|
+
return;
|
|
10742
|
+
}
|
|
10743
|
+
void fsp6.stat(this.filePath).then((st) => {
|
|
10744
|
+
this._messageCacheMtime = st.mtimeMs;
|
|
10745
|
+
this._messageCacheSize = st.size;
|
|
10746
|
+
}).catch(() => {
|
|
10747
|
+
});
|
|
10748
|
+
}
|
|
10749
|
+
_pushToCache(msg) {
|
|
10750
|
+
if (this._messageCache === null) return;
|
|
10751
|
+
if (this._messageCache.length >= MESSAGE_CACHE_MAX_ENTRIES) {
|
|
10752
|
+
this._messageCache = null;
|
|
10753
|
+
this._messageCacheMtime = -1;
|
|
10754
|
+
this._messageCacheSize = -1;
|
|
10755
|
+
return;
|
|
10756
|
+
}
|
|
10757
|
+
this._messageCache.push(msg);
|
|
10758
|
+
}
|
|
10614
10759
|
};
|
|
10615
10760
|
var BrainMonitor = class {
|
|
10616
10761
|
constructor(opts) {
|
|
@@ -10751,7 +10896,7 @@ var CLIENT_STALE_MS = 6e4;
|
|
|
10751
10896
|
var HEARTBEAT_THROTTLE_MS = 5e3;
|
|
10752
10897
|
var REGISTRY_CACHE_TTL_MS = 2e3;
|
|
10753
10898
|
var LINE_SEPARATOR2 = "\n";
|
|
10754
|
-
var
|
|
10899
|
+
var MESSAGE_CACHE_MAX_ENTRIES2 = 1e4;
|
|
10755
10900
|
function resolveProjectDir(projectRoot, globalRoot) {
|
|
10756
10901
|
return path5.join(globalRoot, "projects", projectSlug(projectRoot));
|
|
10757
10902
|
}
|
|
@@ -11083,6 +11228,7 @@ var GlobalMailbox = class {
|
|
|
11083
11228
|
name: input.name,
|
|
11084
11229
|
source: input.source
|
|
11085
11230
|
});
|
|
11231
|
+
this.publishHqMailboxSnapshot();
|
|
11086
11232
|
}
|
|
11087
11233
|
async clientHeartbeat(input) {
|
|
11088
11234
|
const last = this._lastClientHeartbeat.get(input.clientId) ?? 0;
|
|
@@ -11104,6 +11250,7 @@ var GlobalMailbox = class {
|
|
|
11104
11250
|
this._events?.emitCustom("mailbox.client_heartbeat", {
|
|
11105
11251
|
clientId: input.clientId
|
|
11106
11252
|
});
|
|
11253
|
+
this.publishHqMailboxSnapshot();
|
|
11107
11254
|
}
|
|
11108
11255
|
async getClientStatuses() {
|
|
11109
11256
|
await this._ensureClientRegistry();
|
|
@@ -11250,7 +11397,7 @@ var GlobalMailbox = class {
|
|
|
11250
11397
|
* read or wrote it under the file lock).
|
|
11251
11398
|
*/
|
|
11252
11399
|
_setMessageCache(messages, mtime, size) {
|
|
11253
|
-
if (messages.length >
|
|
11400
|
+
if (messages.length > MESSAGE_CACHE_MAX_ENTRIES2) {
|
|
11254
11401
|
this._messageCache = null;
|
|
11255
11402
|
this._messageCacheMtime = -1;
|
|
11256
11403
|
this._messageCacheSize = -1;
|
|
@@ -11276,7 +11423,7 @@ var GlobalMailbox = class {
|
|
|
11276
11423
|
*/
|
|
11277
11424
|
_pushToCache(msg) {
|
|
11278
11425
|
if (this._messageCache === null) return;
|
|
11279
|
-
if (this._messageCache.length >=
|
|
11426
|
+
if (this._messageCache.length >= MESSAGE_CACHE_MAX_ENTRIES2) {
|
|
11280
11427
|
this._messageCache = null;
|
|
11281
11428
|
this._messageCacheMtime = -1;
|
|
11282
11429
|
this._messageCacheSize = -1;
|
|
@@ -11325,7 +11472,7 @@ var GlobalMailbox = class {
|
|
|
11325
11472
|
obj[id] = agent;
|
|
11326
11473
|
}
|
|
11327
11474
|
const tmp = `${this.registryPath}.${randomUUID().slice(0, 8)}.tmp`;
|
|
11328
|
-
await fsp6.writeFile(tmp, JSON.stringify(obj
|
|
11475
|
+
await fsp6.writeFile(tmp, JSON.stringify(obj), "utf8");
|
|
11329
11476
|
await fsp6.rename(tmp, this.registryPath);
|
|
11330
11477
|
}
|
|
11331
11478
|
// ── Client registry internals ───────────────────────────────────────────
|
|
@@ -11370,7 +11517,7 @@ var GlobalMailbox = class {
|
|
|
11370
11517
|
obj[id] = client;
|
|
11371
11518
|
}
|
|
11372
11519
|
const tmp = `${this.clientRegistryPath}.${randomUUID().slice(0, 8)}.tmp`;
|
|
11373
|
-
await fsp6.writeFile(tmp, JSON.stringify(obj
|
|
11520
|
+
await fsp6.writeFile(tmp, JSON.stringify(obj), "utf8");
|
|
11374
11521
|
await fsp6.rename(tmp, this.clientRegistryPath);
|
|
11375
11522
|
}
|
|
11376
11523
|
};
|
|
@@ -12563,7 +12710,7 @@ var TaskDAG = class {
|
|
|
12563
12710
|
}
|
|
12564
12711
|
for (const depId of node.dependents) {
|
|
12565
12712
|
const dep = this.nodes.get(depId);
|
|
12566
|
-
if (dep
|
|
12713
|
+
if (dep?.deps.every((d) => !this.nodes.has(d) || this.nodes.get(d).status === "done")) {
|
|
12567
12714
|
this._transition(depId, "pending", "ready");
|
|
12568
12715
|
}
|
|
12569
12716
|
}
|
|
@@ -12825,7 +12972,7 @@ var ConsensusProtocol = class {
|
|
|
12825
12972
|
*/
|
|
12826
12973
|
async initiateVote(changeId) {
|
|
12827
12974
|
const change = this.graph.get(changeId);
|
|
12828
|
-
if (
|
|
12975
|
+
if (change?.type !== "change") {
|
|
12829
12976
|
throw new Error(`ConsensusProtocol: no change found with id "${changeId}"`);
|
|
12830
12977
|
}
|
|
12831
12978
|
await this.graph.update(changeId, { status: "proposed", votes: [] });
|
|
@@ -12838,7 +12985,7 @@ var ConsensusProtocol = class {
|
|
|
12838
12985
|
*/
|
|
12839
12986
|
async castVote(changeId, voterId, value, rationale) {
|
|
12840
12987
|
const change = this.graph.get(changeId);
|
|
12841
|
-
if (
|
|
12988
|
+
if (change?.type !== "change") {
|
|
12842
12989
|
throw new Error(`ConsensusProtocol: no change found for "${changeId}"`);
|
|
12843
12990
|
}
|
|
12844
12991
|
const voter = this.voters.get(voterId);
|
|
@@ -12892,7 +13039,7 @@ var ConsensusProtocol = class {
|
|
|
12892
13039
|
*/
|
|
12893
13040
|
getStatus(changeId) {
|
|
12894
13041
|
const change = this.graph.get(changeId);
|
|
12895
|
-
if (
|
|
13042
|
+
if (change?.type !== "change") return null;
|
|
12896
13043
|
const eligible = this._eligibleVoters(change);
|
|
12897
13044
|
return this._resolve(changeId, change.votes, eligible);
|
|
12898
13045
|
}
|
|
@@ -13095,7 +13242,7 @@ var ChangeManager = class {
|
|
|
13095
13242
|
*/
|
|
13096
13243
|
async submitForReview(changeId) {
|
|
13097
13244
|
const change = this.graph.get(changeId);
|
|
13098
|
-
if (
|
|
13245
|
+
if (change?.type !== "change") {
|
|
13099
13246
|
throw new Error(`ChangeManager: no change found "${changeId}"`);
|
|
13100
13247
|
}
|
|
13101
13248
|
if (change.status !== "proposed") {
|
|
@@ -13157,7 +13304,7 @@ var ChangeManager = class {
|
|
|
13157
13304
|
*/
|
|
13158
13305
|
async proposeRollback(appliedChangeId, reason) {
|
|
13159
13306
|
const original = this.graph.get(appliedChangeId);
|
|
13160
|
-
if (
|
|
13307
|
+
if (original?.type !== "change") return null;
|
|
13161
13308
|
const rollbackFiles = original.files.map((f) => ({
|
|
13162
13309
|
path: f.path,
|
|
13163
13310
|
action: f.action === "create" ? "delete" : f.action === "delete" ? "create" : "modify"
|
|
@@ -13711,7 +13858,7 @@ var TaskAuctioneer = class {
|
|
|
13711
13858
|
*/
|
|
13712
13859
|
async bid(taskId, agent, rationale) {
|
|
13713
13860
|
const goal = this.graph.get(taskId);
|
|
13714
|
-
if (
|
|
13861
|
+
if (goal?.type !== "goal") return false;
|
|
13715
13862
|
if (goal.status !== "pending") return false;
|
|
13716
13863
|
const currentCount = this._getAgentTaskCount(agent.agentId);
|
|
13717
13864
|
if (currentCount >= this.maxTasksPerAgent) return false;
|
|
@@ -13760,7 +13907,7 @@ Score: ${score.toFixed(2)}`
|
|
|
13760
13907
|
*/
|
|
13761
13908
|
async claim(taskId, agentId, agentName) {
|
|
13762
13909
|
const goal = this.graph.get(taskId);
|
|
13763
|
-
if (
|
|
13910
|
+
if (goal?.type !== "goal") return false;
|
|
13764
13911
|
if (goal.status !== "pending") return false;
|
|
13765
13912
|
this._cancelBidWindow(taskId);
|
|
13766
13913
|
await this.graph.update(taskId, {
|