@wrongstack/core 0.268.0 → 0.269.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.
Files changed (75) hide show
  1. package/dist/{agent-bridge-UhojbpWx.d.ts → agent-bridge-PcHQl_UQ.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-Bvtf1o9K.d.ts → agent-subagent-runner-SHJW7t8q.d.ts} +8 -8
  3. package/dist/{brain-69wzMKp1.d.ts → brain-BYcK__Ym.d.ts} +1 -1
  4. package/dist/{compactor-CBQAJoDc.d.ts → compactor-C2RKEBtC.d.ts} +1 -1
  5. package/dist/{config-VKfOZ-6X.d.ts → config-C_ae2k86.d.ts} +11 -2
  6. package/dist/{context-C0U8B9NF.d.ts → context-Dp87Bcaq.d.ts} +24 -1
  7. package/dist/coordination/index.d.ts +22 -16
  8. package/dist/coordination/index.js +233 -86
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/defaults/index.d.ts +25 -25
  11. package/dist/defaults/index.js +272 -69
  12. package/dist/defaults/index.js.map +1 -1
  13. package/dist/execution/index.d.ts +15 -15
  14. package/dist/execution/index.js +116 -19
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/execution/prompt-enhancer.d.ts +1 -1
  17. package/dist/extension/index.d.ts +6 -6
  18. package/dist/{global-mailbox-KByEFFBa.d.ts → global-mailbox-Bvrz1P3f.d.ts} +2 -1
  19. package/dist/{goal-preamble-CrYjmdw4.d.ts → goal-preamble-CA_4yiGQ.d.ts} +9 -9
  20. package/dist/{goal-store-Y_zdLZ3q.d.ts → goal-store-DhuJoUNG.d.ts} +1 -1
  21. package/dist/hq/index.d.ts +15 -6
  22. package/dist/hq/index.js +55 -8
  23. package/dist/hq/index.js.map +1 -1
  24. package/dist/{index-CtQnmkaS.d.ts → index-CZQ6Pwbs.d.ts} +8 -8
  25. package/dist/{index-gCv830d7.d.ts → index-W4VJCzHa.d.ts} +5 -5
  26. package/dist/{index-BfaS-f_m.d.ts → index-whDfTANu.d.ts} +2 -2
  27. package/dist/index.d.ts +41 -41
  28. package/dist/index.js +531 -167
  29. package/dist/index.js.map +1 -1
  30. package/dist/infrastructure/index.d.ts +6 -6
  31. package/dist/infrastructure/index.js +3 -3
  32. package/dist/infrastructure/index.js.map +1 -1
  33. package/dist/kernel/index.d.ts +9 -9
  34. package/dist/{mcp-servers-HT3Fi7Bl.d.ts → mcp-servers-DJdZiRcv.d.ts} +3 -3
  35. package/dist/models/index.d.ts +5 -5
  36. package/dist/models/index.js +1 -1
  37. package/dist/models/index.js.map +1 -1
  38. package/dist/{models-registry-Bvcl3Vaa.d.ts → models-registry-C3a-2-Yd.d.ts} +1 -1
  39. package/dist/{multi-agent-coordinator-BACjsmkC.d.ts → multi-agent-coordinator-CJSpTe5O.d.ts} +1 -1
  40. package/dist/{null-fleet-bus-DA7fvhUg.d.ts → null-fleet-bus-QVshIsDx.d.ts} +6 -6
  41. package/dist/observability/index.d.ts +2 -2
  42. package/dist/{parallel-eternal-engine-Ci71gYu_.d.ts → parallel-eternal-engine-D9y5Pkcc.d.ts} +9 -9
  43. package/dist/{path-resolver-O1IJnmKE.d.ts → path-resolver-CnQ8SIfh.d.ts} +3 -3
  44. package/dist/{permission-Bd-57Lbl.d.ts → permission-CvYQNUqZ.d.ts} +1 -1
  45. package/dist/{permission-policy-uNXC6Kge.d.ts → permission-policy-D5Ss8j4B.d.ts} +2 -2
  46. package/dist/{pipeline-BDNvENyV.d.ts → pipeline-l_zzFRh3.d.ts} +2 -2
  47. package/dist/{plan-templates-EMsalEtN.d.ts → plan-templates-NtPgyeJA.d.ts} +6 -5
  48. package/dist/{provider-model-resolve-CEb9x886.d.ts → provider-model-resolve-d5poT5y0.d.ts} +3 -3
  49. package/dist/{provider-runner-DWJbpo70.d.ts → provider-runner-gkctlQV_.d.ts} +3 -3
  50. package/dist/{retry-policy-C3s_lvdK.d.ts → retry-policy-CtFhfwa8.d.ts} +1 -1
  51. package/dist/sdd/index.d.ts +8 -8
  52. package/dist/sdd/index.js +1 -1
  53. package/dist/sdd/index.js.map +1 -1
  54. package/dist/{secret-vault-Cgduf5xL.d.ts → secret-vault-BLsVmTIK.d.ts} +1 -1
  55. package/dist/security/index.d.ts +5 -5
  56. package/dist/security/index.js.map +1 -1
  57. package/dist/{selector-47LBnBVk.d.ts → selector-CXl2_y9W.d.ts} +1 -1
  58. package/dist/{session-event-bridge-Cw7oqmW2.d.ts → session-event-bridge-Ccud20CC.d.ts} +1 -1
  59. package/dist/{session-reader-DD4v2Obw.d.ts → session-reader-ZeXQmsmE.d.ts} +1 -1
  60. package/dist/skills/index.js.map +1 -1
  61. package/dist/storage/index.d.ts +13 -11
  62. package/dist/storage/index.js +210 -64
  63. package/dist/storage/index.js.map +1 -1
  64. package/dist/tools/index.d.ts +2 -2
  65. package/dist/tools/index.js.map +1 -1
  66. package/dist/types/index.d.ts +21 -21
  67. package/dist/types/index.js +110 -19
  68. package/dist/types/index.js.map +1 -1
  69. package/dist/utils/index.d.ts +2 -2
  70. package/dist/utils/index.js +58 -24
  71. package/dist/utils/index.js.map +1 -1
  72. package/package.json +1 -1
  73. package/skills/chimera/SKILL.md +1 -1
  74. package/skills/typescript-strict/SKILL.md +3 -3
  75. package/skills/typescript-strict/SKILL.save.md +1 -1
@@ -5,15 +5,7 @@ import * as os from 'os';
5
5
  import { hostname } from 'os';
6
6
  import 'fs';
7
7
 
8
- // src/utils/expect-defined.ts
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 (!msg || msg.role !== "assistant") return ids;
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 (!msg || msg.role !== "user") return ids;
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
- let stat7;
620
- try {
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
- return Array.from(seen.values());
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 raw = await fsp.readFile(this.filePath, "utf8");
1507
- const lines = raw.split("\n");
1508
- const kept = [];
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 targetCheckpointLine = -1;
1511
- let afterTarget = false;
1512
- for (let i = 0; i < lines.length; i++) {
1513
- const line = expectDefined(lines[i]);
1514
- if (!line.trim()) continue;
1515
- let event;
1516
- try {
1517
- event = JSON.parse(line);
1518
- } catch {
1519
- kept.push(line);
1520
- continue;
1521
- }
1522
- if (event.type === "checkpoint") {
1523
- if (event.promptIndex === targetPromptIndex) {
1524
- targetCheckpointLine = kept.length;
1525
- afterTarget = true;
1526
- } else if (event.promptIndex > targetPromptIndex) {
1527
- afterTarget = true;
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
- if (event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
1531
- removedCount++;
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
- const truncated = kept.join("\n");
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.writeFile(tmpPath, truncated + "\n", "utf8");
1591
+ const src = await fsp.open(this.filePath, "r", 384);
1545
1592
  try {
1546
- await this.handle.close();
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 || !provider.complete) return;
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 && op.text.trim()) {
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
- const tmp = `${this.filePath}.${randomUUID().slice(0, 8)}.tmp`;
5636
- await fsp.writeFile(tmp, JSON.stringify(registry, null, 2), "utf8");
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
- const tmp = `${this.filePath}.${randomUUID().slice(0, 8)}.tmp`;
5642
- await fsp.writeFile(tmp, JSON.stringify(registry, null, 2), "utf8");
5643
- await fsp.rename(tmp, this.filePath);
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 (err) {
7796
+ } catch (_err) {
7651
7797
  }
7652
7798
  },
7653
7799
  async appendBatch(events) {