@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
package/dist/storage/index.js
CHANGED
|
@@ -5,15 +5,7 @@ import * as os from 'os';
|
|
|
5
5
|
import { hostname } from 'os';
|
|
6
6
|
import 'fs';
|
|
7
7
|
|
|
8
|
-
// src/
|
|
9
|
-
function expectDefined(value, label) {
|
|
10
|
-
if (value === null || value === void 0) {
|
|
11
|
-
const err = new Error("Expected value to be defined");
|
|
12
|
-
err.name = "ExpectDefinedError";
|
|
13
|
-
throw err;
|
|
14
|
-
}
|
|
15
|
-
return value;
|
|
16
|
-
}
|
|
8
|
+
// src/storage/session-store.ts
|
|
17
9
|
async function atomicWrite(targetPath, content, opts = {}) {
|
|
18
10
|
const dir = path2.dirname(targetPath);
|
|
19
11
|
await fsp.mkdir(dir, { recursive: true });
|
|
@@ -127,6 +119,16 @@ async function renameWithRetry(from, to) {
|
|
|
127
119
|
throw lastErr;
|
|
128
120
|
}
|
|
129
121
|
|
|
122
|
+
// src/utils/expect-defined.ts
|
|
123
|
+
function expectDefined(value, label) {
|
|
124
|
+
if (value === null || value === void 0) {
|
|
125
|
+
const err = new Error("Expected value to be defined");
|
|
126
|
+
err.name = "ExpectDefinedError";
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
|
|
130
132
|
// src/utils/message-invariants.ts
|
|
131
133
|
function repairToolUseAdjacency(messages) {
|
|
132
134
|
const removedToolUses = [];
|
|
@@ -189,7 +191,7 @@ function hasToolResult(msg) {
|
|
|
189
191
|
}
|
|
190
192
|
function toolUseIds(msg) {
|
|
191
193
|
const ids = /* @__PURE__ */ new Set();
|
|
192
|
-
if (
|
|
194
|
+
if (msg?.role !== "assistant") return ids;
|
|
193
195
|
for (const block of contentBlocks(msg)) {
|
|
194
196
|
if (block.type === "tool_use") ids.add(block.id);
|
|
195
197
|
}
|
|
@@ -197,7 +199,7 @@ function toolUseIds(msg) {
|
|
|
197
199
|
}
|
|
198
200
|
function toolResultIds(msg) {
|
|
199
201
|
const ids = /* @__PURE__ */ new Set();
|
|
200
|
-
if (
|
|
202
|
+
if (msg?.role !== "user") return ids;
|
|
201
203
|
for (const block of contentBlocks(msg)) {
|
|
202
204
|
if (block.type === "tool_result") ids.add(block.tool_use_id);
|
|
203
205
|
}
|
|
@@ -455,6 +457,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
455
457
|
* processes. When the limit is reached, the oldest entry is evicted.
|
|
456
458
|
*/
|
|
457
459
|
_loadCache = /* @__PURE__ */ new Map();
|
|
460
|
+
_indexCache = null;
|
|
458
461
|
static LOAD_CACHE_MAX_ENTRIES = 50;
|
|
459
462
|
constructor(opts) {
|
|
460
463
|
this.dir = opts.dir;
|
|
@@ -616,13 +619,8 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
616
619
|
let errorMsg;
|
|
617
620
|
let cacheHit = false;
|
|
618
621
|
try {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
const s = await fsp.stat(file);
|
|
622
|
-
stat7 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
623
|
-
} catch (err) {
|
|
624
|
-
throw err;
|
|
625
|
-
}
|
|
622
|
+
const s = await fsp.stat(file);
|
|
623
|
+
const stat7 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
626
624
|
const cached = this._loadCache.get(id);
|
|
627
625
|
if (cached && cached.mtimeMs === stat7.mtimeMs && cached.size === stat7.size) {
|
|
628
626
|
cacheHit = true;
|
|
@@ -713,6 +711,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
713
711
|
await ensureDir(this.dir);
|
|
714
712
|
const line = JSON.stringify(summary) + "\n";
|
|
715
713
|
await fsp.appendFile(this.indexFile, line, "utf8");
|
|
714
|
+
this._indexCache = null;
|
|
716
715
|
this.indexAppendCount++;
|
|
717
716
|
if (this.indexAppendCount >= _DefaultSessionStore.COMPACT_EVERY) {
|
|
718
717
|
await this.compactIndex();
|
|
@@ -727,6 +726,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
727
726
|
await ensureDir(this.dir);
|
|
728
727
|
const line = JSON.stringify({ action: "delete", id }) + "\n";
|
|
729
728
|
await fsp.appendFile(this.indexFile, line, "utf8");
|
|
729
|
+
this._indexCache = null;
|
|
730
730
|
this.indexAppendCount++;
|
|
731
731
|
} catch {
|
|
732
732
|
}
|
|
@@ -746,6 +746,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
746
746
|
const lines = entries.map((s) => JSON.stringify(s)).join("\n") + "\n";
|
|
747
747
|
await fsp.writeFile(tmp, lines, "utf8");
|
|
748
748
|
await fsp.rename(tmp, this.indexFile);
|
|
749
|
+
this._indexCache = null;
|
|
749
750
|
} catch (err) {
|
|
750
751
|
outcome = "failure";
|
|
751
752
|
errorMsg = toErrorMessage(err);
|
|
@@ -759,10 +760,22 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
759
760
|
* Returns empty array when the index doesn't exist or is corrupt.
|
|
760
761
|
*/
|
|
761
762
|
async readIndex() {
|
|
763
|
+
let stat7;
|
|
764
|
+
try {
|
|
765
|
+
const s = await fsp.stat(this.indexFile);
|
|
766
|
+
stat7 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
767
|
+
} catch {
|
|
768
|
+
this._indexCache = null;
|
|
769
|
+
return [];
|
|
770
|
+
}
|
|
771
|
+
if (this._indexCache !== null && this._indexCache.mtimeMs === stat7.mtimeMs && this._indexCache.size === stat7.size) {
|
|
772
|
+
return [...this._indexCache.summaries];
|
|
773
|
+
}
|
|
762
774
|
let raw;
|
|
763
775
|
try {
|
|
764
776
|
raw = await fsp.readFile(this.indexFile, "utf8");
|
|
765
777
|
} catch {
|
|
778
|
+
this._indexCache = null;
|
|
766
779
|
return [];
|
|
767
780
|
}
|
|
768
781
|
const deleted = /* @__PURE__ */ new Set();
|
|
@@ -782,7 +795,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
782
795
|
} catch {
|
|
783
796
|
}
|
|
784
797
|
}
|
|
785
|
-
|
|
798
|
+
const summaries = Array.from(seen.values());
|
|
799
|
+
this._indexCache = { ...stat7, summaries };
|
|
800
|
+
return [...summaries];
|
|
786
801
|
}
|
|
787
802
|
/**
|
|
788
803
|
* Rebuild the index from disk by scanning all sessions and writing a
|
|
@@ -796,6 +811,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
796
811
|
const lines = valid.map((s) => JSON.stringify(s)).join("\n") + "\n";
|
|
797
812
|
await fsp.writeFile(tmp, lines, "utf8");
|
|
798
813
|
await fsp.rename(tmp, this.indexFile);
|
|
814
|
+
this._indexCache = null;
|
|
799
815
|
return valid.length;
|
|
800
816
|
}
|
|
801
817
|
/** Recursively collect session IDs from date-shard subdirectories.
|
|
@@ -1495,6 +1511,12 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
1495
1511
|
files
|
|
1496
1512
|
});
|
|
1497
1513
|
}
|
|
1514
|
+
/**
|
|
1515
|
+
* Truncate the session file to the checkpoint with the given promptIndex,
|
|
1516
|
+
* removing all events that follow it. Uses a single-pass byte-offset scan
|
|
1517
|
+
* so post-checkpoint content is never read or parsed — O(1) memory instead
|
|
1518
|
+
* of O(N) JSON.parse calls over the full file.
|
|
1519
|
+
*/
|
|
1498
1520
|
async truncateToCheckpoint(targetPromptIndex) {
|
|
1499
1521
|
if (!this.filePath) return 0;
|
|
1500
1522
|
if (this.flushTimer) {
|
|
@@ -1503,51 +1525,118 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
1503
1525
|
}
|
|
1504
1526
|
await this.flushBuffer();
|
|
1505
1527
|
await this.writeChain;
|
|
1506
|
-
const
|
|
1507
|
-
|
|
1508
|
-
|
|
1528
|
+
const CHUNK_SIZE = 65536;
|
|
1529
|
+
let fd;
|
|
1530
|
+
let fileOffset = 0;
|
|
1531
|
+
let lineStartOffset = 0;
|
|
1532
|
+
let checkpointByteOffset = -1;
|
|
1509
1533
|
let removedCount = 0;
|
|
1510
|
-
let
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1534
|
+
let targetCheckpointSeen = false;
|
|
1535
|
+
try {
|
|
1536
|
+
fd = await fsp.open(this.filePath, "r", 384);
|
|
1537
|
+
while (true) {
|
|
1538
|
+
const buf = Buffer.alloc(CHUNK_SIZE);
|
|
1539
|
+
const { bytesRead } = await fd.read(buf, 0, CHUNK_SIZE, fileOffset);
|
|
1540
|
+
if (bytesRead === 0) break;
|
|
1541
|
+
let chunkPos = 0;
|
|
1542
|
+
while (chunkPos < bytesRead) {
|
|
1543
|
+
const idx = buf.indexOf("\n", chunkPos);
|
|
1544
|
+
if (idx === -1) {
|
|
1545
|
+
lineStartOffset = fileOffset + chunkPos;
|
|
1546
|
+
break;
|
|
1547
|
+
}
|
|
1548
|
+
if (checkpointByteOffset !== -1) {
|
|
1549
|
+
removedCount++;
|
|
1550
|
+
} else {
|
|
1551
|
+
const lineBytes = buf.subarray(chunkPos, idx);
|
|
1552
|
+
const line = new TextDecoder("utf-8", { fatal: false }).decode(lineBytes);
|
|
1553
|
+
if (line.trim()) {
|
|
1554
|
+
try {
|
|
1555
|
+
const event = JSON.parse(line);
|
|
1556
|
+
if (event.type === "checkpoint") {
|
|
1557
|
+
if (event.promptIndex === targetPromptIndex) {
|
|
1558
|
+
checkpointByteOffset = lineStartOffset;
|
|
1559
|
+
targetCheckpointSeen = true;
|
|
1560
|
+
} else if (event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
1561
|
+
checkpointByteOffset = lineStartOffset;
|
|
1562
|
+
}
|
|
1563
|
+
} else if (targetCheckpointSeen && event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
1564
|
+
removedCount++;
|
|
1565
|
+
} else if (targetCheckpointSeen && event.promptIndex === void 0) {
|
|
1566
|
+
removedCount++;
|
|
1567
|
+
} else if (!targetCheckpointSeen && event.promptIndex === void 0) {
|
|
1568
|
+
removedCount++;
|
|
1569
|
+
} else if (!targetCheckpointSeen && event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
1570
|
+
removedCount++;
|
|
1571
|
+
}
|
|
1572
|
+
} catch {
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
chunkPos = idx + 1;
|
|
1577
|
+
lineStartOffset = fileOffset + chunkPos;
|
|
1528
1578
|
}
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
} else if (event.promptIndex === void 0) {
|
|
1533
|
-
if (!afterTarget || targetCheckpointLine === -1) {
|
|
1534
|
-
kept.push(line);
|
|
1535
|
-
} else {
|
|
1536
|
-
removedCount++;
|
|
1579
|
+
fileOffset += bytesRead;
|
|
1580
|
+
if (chunkPos >= bytesRead) {
|
|
1581
|
+
lineStartOffset = fileOffset;
|
|
1537
1582
|
}
|
|
1538
|
-
} else {
|
|
1539
|
-
kept.push(line);
|
|
1540
1583
|
}
|
|
1584
|
+
} finally {
|
|
1585
|
+
await fd?.close();
|
|
1541
1586
|
}
|
|
1542
|
-
|
|
1587
|
+
if (checkpointByteOffset === -1) return 0;
|
|
1588
|
+
await this.writeChain;
|
|
1589
|
+
await this.handle.close();
|
|
1543
1590
|
const tmpPath = `${this.filePath}.rewind.tmp`;
|
|
1544
|
-
await fsp.
|
|
1591
|
+
const src = await fsp.open(this.filePath, "r", 384);
|
|
1545
1592
|
try {
|
|
1546
|
-
await
|
|
1593
|
+
const statResult = await src.stat();
|
|
1594
|
+
const totalSize = statResult.size;
|
|
1595
|
+
const prefixBytes = checkpointByteOffset;
|
|
1596
|
+
let newlineAfterCheckpoint = prefixBytes;
|
|
1597
|
+
if (prefixBytes < totalSize) {
|
|
1598
|
+
const probeBuf = Buffer.alloc(Math.min(CHUNK_SIZE, totalSize - prefixBytes));
|
|
1599
|
+
const { bytesRead: probeRead } = await src.read(probeBuf, 0, probeBuf.length, prefixBytes);
|
|
1600
|
+
if (probeRead > 0) {
|
|
1601
|
+
const nl = probeBuf.indexOf("\n");
|
|
1602
|
+
newlineAfterCheckpoint = nl !== -1 ? prefixBytes + nl + 1 : totalSize;
|
|
1603
|
+
}
|
|
1604
|
+
} else {
|
|
1605
|
+
newlineAfterCheckpoint = totalSize;
|
|
1606
|
+
}
|
|
1607
|
+
const writeFd = await fsp.open(tmpPath, "w", 384);
|
|
1608
|
+
try {
|
|
1609
|
+
let copied = 0;
|
|
1610
|
+
let readOffset = 0;
|
|
1611
|
+
while (readOffset < newlineAfterCheckpoint) {
|
|
1612
|
+
const toCopy = Math.min(CHUNK_SIZE, newlineAfterCheckpoint - readOffset);
|
|
1613
|
+
const copyBuf = Buffer.alloc(toCopy);
|
|
1614
|
+
const { bytesRead: r } = await src.read(copyBuf, 0, toCopy, readOffset);
|
|
1615
|
+
if (r === 0) break;
|
|
1616
|
+
await writeFd.write(copyBuf, 0, r);
|
|
1617
|
+
readOffset += r;
|
|
1618
|
+
copied += r;
|
|
1619
|
+
}
|
|
1620
|
+
const raw = await fsp.readFile(this.filePath);
|
|
1621
|
+
const tail = raw.subarray(newlineAfterCheckpoint).toString("utf8");
|
|
1622
|
+
for (const line of tail.split("\n")) {
|
|
1623
|
+
if (!line.trim()) continue;
|
|
1624
|
+
try {
|
|
1625
|
+
JSON.parse(line);
|
|
1626
|
+
} catch {
|
|
1627
|
+
await writeFd.write(`${line}
|
|
1628
|
+
`, void 0, "utf8");
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
} finally {
|
|
1632
|
+
await writeFd.close();
|
|
1633
|
+
}
|
|
1634
|
+
await src.close();
|
|
1547
1635
|
await fsp.rename(tmpPath, this.filePath);
|
|
1548
1636
|
this.handle = await fsp.open(this.filePath, "a", 384);
|
|
1549
1637
|
} catch (err) {
|
|
1550
1638
|
await fsp.unlink(tmpPath).catch(() => void 0);
|
|
1639
|
+
this.handle = await fsp.open(this.filePath, "a", 384).catch(() => this.handle);
|
|
1551
1640
|
throw err;
|
|
1552
1641
|
}
|
|
1553
1642
|
await this.append({
|
|
@@ -1940,6 +2029,7 @@ var MEMORY_TYPE_LABELS = {
|
|
|
1940
2029
|
// src/storage/memory-backend.ts
|
|
1941
2030
|
var TYPE_PRIORITY_RE = /^\[(\w+)\|(\w+)\]\s+/;
|
|
1942
2031
|
var TAG_RE = /#([\w-]+)/g;
|
|
2032
|
+
var MAX_MEMORY_CONSOLIDATE_BACKUPS = 5;
|
|
1943
2033
|
function formatMetadata(entry) {
|
|
1944
2034
|
const parts = [];
|
|
1945
2035
|
if (entry.type && entry.priority) {
|
|
@@ -2132,6 +2222,7 @@ ${line}`;
|
|
|
2132
2222
|
const backup = `${file}.bak.${Date.now()}`;
|
|
2133
2223
|
try {
|
|
2134
2224
|
await fsp.copyFile(file, backup);
|
|
2225
|
+
await pruneConsolidateBackups(file);
|
|
2135
2226
|
} catch {
|
|
2136
2227
|
}
|
|
2137
2228
|
try {
|
|
@@ -2142,6 +2233,20 @@ ${line}`;
|
|
|
2142
2233
|
return removed;
|
|
2143
2234
|
}
|
|
2144
2235
|
};
|
|
2236
|
+
async function pruneConsolidateBackups(file) {
|
|
2237
|
+
const dir = path2.dirname(file);
|
|
2238
|
+
const base = path2.basename(file);
|
|
2239
|
+
const prefix = `${base}.bak.`;
|
|
2240
|
+
const backups = (await fsp.readdir(dir)).filter((name) => name.startsWith(prefix)).sort().reverse();
|
|
2241
|
+
await Promise.all(
|
|
2242
|
+
backups.slice(MAX_MEMORY_CONSOLIDATE_BACKUPS).map(async (name) => {
|
|
2243
|
+
try {
|
|
2244
|
+
await fsp.unlink(path2.join(dir, name));
|
|
2245
|
+
} catch {
|
|
2246
|
+
}
|
|
2247
|
+
})
|
|
2248
|
+
);
|
|
2249
|
+
}
|
|
2145
2250
|
function parseEntries(raw, scope = "project-memory") {
|
|
2146
2251
|
const entries = [];
|
|
2147
2252
|
for (const line of raw.split("\n")) {
|
|
@@ -2954,7 +3059,7 @@ var SessionMemoryConsolidator = class {
|
|
|
2954
3059
|
if (!result.finalText || result.finalText.trim().length < 20) return;
|
|
2955
3060
|
if (result.iterations < this.minIterations) return;
|
|
2956
3061
|
const provider = this.provider ?? ctx.provider;
|
|
2957
|
-
if (!provider
|
|
3062
|
+
if (!provider?.complete) return;
|
|
2958
3063
|
try {
|
|
2959
3064
|
const existingEntries = await this.memoryStore.list("project-memory", this.maxExistingEntries);
|
|
2960
3065
|
const prompt = buildConsolidationPrompt(
|
|
@@ -2997,7 +3102,7 @@ var SessionMemoryConsolidator = class {
|
|
|
2997
3102
|
break;
|
|
2998
3103
|
}
|
|
2999
3104
|
case "edit": {
|
|
3000
|
-
if (op.query && op.text
|
|
3105
|
+
if (op.query && op.text?.trim()) {
|
|
3001
3106
|
await this.memoryStore.forget(op.query);
|
|
3002
3107
|
await this.memoryStore.remember(op.text.trim(), void 0, {
|
|
3003
3108
|
type: op.type,
|
|
@@ -3298,6 +3403,9 @@ var DEFAULT_CONTEXT_CONFIG = Object.freeze({
|
|
|
3298
3403
|
preserveK: 10,
|
|
3299
3404
|
eliseThreshold: 2e3
|
|
3300
3405
|
});
|
|
3406
|
+
var DEFAULT_AUTONOMY_CONFIG = Object.freeze({
|
|
3407
|
+
autoProceedDelayMs: 45e3
|
|
3408
|
+
});
|
|
3301
3409
|
var DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({
|
|
3302
3410
|
auditLevel: "standard",
|
|
3303
3411
|
sampling: {
|
|
@@ -3341,7 +3449,9 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
3341
3449
|
plugins: true,
|
|
3342
3450
|
memory: true,
|
|
3343
3451
|
modelsRegistry: true,
|
|
3344
|
-
skills: true
|
|
3452
|
+
skills: true,
|
|
3453
|
+
tokenSavingMode: "off",
|
|
3454
|
+
allowOutsideProjectRoot: true
|
|
3345
3455
|
},
|
|
3346
3456
|
mcpServers: {},
|
|
3347
3457
|
indexing: {
|
|
@@ -3350,7 +3460,8 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
3350
3460
|
watchExternal: true,
|
|
3351
3461
|
debounceMs: 400
|
|
3352
3462
|
},
|
|
3353
|
-
session: { ...DEFAULT_SESSION_LOGGING_CONFIG }
|
|
3463
|
+
session: { ...DEFAULT_SESSION_LOGGING_CONFIG },
|
|
3464
|
+
autonomy: { autoProceedDelayMs: DEFAULT_AUTONOMY_CONFIG.autoProceedDelayMs }
|
|
3354
3465
|
};
|
|
3355
3466
|
function envBool(v) {
|
|
3356
3467
|
return !/^(0|false|no|off)$/i.test(v.trim());
|
|
@@ -5370,6 +5481,8 @@ var HEARTBEAT_INTERVAL_MS = 5e3;
|
|
|
5370
5481
|
var STALE_TIMEOUT_MS = 3e4;
|
|
5371
5482
|
var CLOSING_GRACE_MS = 15e3;
|
|
5372
5483
|
var STALE_LOCK_MS = 1e4;
|
|
5484
|
+
var STALE_TMP_MS = 6e4;
|
|
5485
|
+
var MAX_STALE_TMP_FILES = 20;
|
|
5373
5486
|
function pidAlive(pid) {
|
|
5374
5487
|
try {
|
|
5375
5488
|
process.kill(pid, 0);
|
|
@@ -5632,15 +5745,48 @@ var SessionRegistry = class {
|
|
|
5632
5745
|
}
|
|
5633
5746
|
}
|
|
5634
5747
|
async writeAtomicLocked(registry) {
|
|
5635
|
-
|
|
5636
|
-
await
|
|
5637
|
-
await fsp.rename(tmp, this.filePath);
|
|
5748
|
+
await this.pruneStaleTempFiles();
|
|
5749
|
+
await this.writeAtomicFile(registry);
|
|
5638
5750
|
}
|
|
5639
5751
|
/** Legacy write without lock — used by heartbeat for performance. */
|
|
5640
5752
|
async writeAtomic(registry) {
|
|
5641
|
-
|
|
5642
|
-
await
|
|
5643
|
-
|
|
5753
|
+
await this.pruneStaleTempFiles();
|
|
5754
|
+
await this.writeAtomicFile(registry);
|
|
5755
|
+
}
|
|
5756
|
+
async writeAtomicFile(registry) {
|
|
5757
|
+
const tmp = path2.join(
|
|
5758
|
+
path2.dirname(this.filePath),
|
|
5759
|
+
`.${path2.basename(this.filePath)}.${randomUUID().slice(0, 8)}.tmp`
|
|
5760
|
+
);
|
|
5761
|
+
try {
|
|
5762
|
+
await fsp.writeFile(tmp, JSON.stringify(registry, null, 2), "utf8");
|
|
5763
|
+
await fsp.rename(tmp, this.filePath);
|
|
5764
|
+
} catch (err) {
|
|
5765
|
+
await fsp.unlink(tmp).catch(() => void 0);
|
|
5766
|
+
throw err;
|
|
5767
|
+
}
|
|
5768
|
+
}
|
|
5769
|
+
async pruneStaleTempFiles() {
|
|
5770
|
+
try {
|
|
5771
|
+
const dir = path2.dirname(this.filePath);
|
|
5772
|
+
const base = path2.basename(this.filePath);
|
|
5773
|
+
const now = Date.now();
|
|
5774
|
+
const stale = [];
|
|
5775
|
+
for (const name of await fsp.readdir(dir)) {
|
|
5776
|
+
const isTemp = (name.startsWith(`${base}.`) || name.startsWith(`.${base}.`)) && name.endsWith(".tmp");
|
|
5777
|
+
if (!isTemp) continue;
|
|
5778
|
+
const stat7 = await fsp.stat(path2.join(dir, name)).catch(() => null);
|
|
5779
|
+
if (!stat7) continue;
|
|
5780
|
+
if (now - stat7.mtimeMs > STALE_TMP_MS) stale.push({ name, mtimeMs: stat7.mtimeMs });
|
|
5781
|
+
}
|
|
5782
|
+
stale.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
5783
|
+
await Promise.all(
|
|
5784
|
+
stale.slice(MAX_STALE_TMP_FILES).map(async ({ name }) => {
|
|
5785
|
+
await fsp.unlink(path2.join(dir, name)).catch(() => void 0);
|
|
5786
|
+
})
|
|
5787
|
+
);
|
|
5788
|
+
} catch {
|
|
5789
|
+
}
|
|
5644
5790
|
}
|
|
5645
5791
|
};
|
|
5646
5792
|
var _instance = null;
|
|
@@ -7647,7 +7793,7 @@ function createSessionEventBridge(writer, level = "standard", options = {}) {
|
|
|
7647
7793
|
if (!shouldSample(event)) return;
|
|
7648
7794
|
try {
|
|
7649
7795
|
await target.append(event);
|
|
7650
|
-
} catch (
|
|
7796
|
+
} catch (_err) {
|
|
7651
7797
|
}
|
|
7652
7798
|
},
|
|
7653
7799
|
async appendBatch(events) {
|