@retaw106/mmc-oc 2.4.0 → 2.6.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 (188) hide show
  1. package/dist/{context-c72brxe5.js → context-cfbjrr0n.js} +1636 -513
  2. package/dist/features/magic-context/compaction-marker.d.ts +34 -6
  3. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  4. package/dist/features/magic-context/message-index-async.d.ts +6 -2
  5. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  6. package/dist/features/magic-context/message-index.d.ts +0 -26
  7. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  8. package/dist/features/magic-context/search.d.ts +5 -1
  9. package/dist/features/magic-context/search.d.ts.map +1 -1
  10. package/dist/features/magic-context/session-decision-calibration.d.ts.map +1 -1
  11. package/dist/features/magic-context/session-retention.fixture.d.ts +4 -0
  12. package/dist/features/magic-context/session-retention.fixture.d.ts.map +1 -0
  13. package/dist/features/magic-context/storage-db.d.ts +2 -0
  14. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  15. package/dist/features/magic-context/storage-host-instruction-retention.d.ts +4 -0
  16. package/dist/features/magic-context/storage-host-instruction-retention.d.ts.map +1 -0
  17. package/dist/features/magic-context/storage-meta-persisted.d.ts +21 -1
  18. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  19. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  20. package/dist/features/magic-context/storage-meta-shared.d.ts +2 -2
  21. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  22. package/dist/features/magic-context/storage-native-replay.d.ts +2 -0
  23. package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -1
  24. package/dist/features/magic-context/storage-session-tables.d.ts +5 -4
  25. package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
  26. package/dist/features/magic-context/tool-definition-tokens.d.ts +113 -58
  27. package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
  28. package/dist/features/magic-context/work-metrics.d.ts +5 -3
  29. package/dist/features/magic-context/work-metrics.d.ts.map +1 -1
  30. package/dist/hooks/magic-context/apply-operations.d.ts +32 -0
  31. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/ask-answer-notice.d.ts +25 -0
  33. package/dist/hooks/magic-context/ask-answer-notice.d.ts.map +1 -0
  34. package/dist/hooks/magic-context/auto-search-hint.d.ts +3 -0
  35. package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -1
  36. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  37. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  38. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +5 -5
  39. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  40. package/dist/hooks/magic-context/compaction-marker-publication.d.ts +14 -0
  41. package/dist/hooks/magic-context/compaction-marker-publication.d.ts.map +1 -0
  42. package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -2
  44. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +11 -0
  45. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  47. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  48. package/dist/hooks/magic-context/diagnostic-log-state.d.ts +4 -0
  49. package/dist/hooks/magic-context/diagnostic-log-state.d.ts.map +1 -0
  50. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  51. package/dist/hooks/magic-context/file-token-coverage.d.ts +11 -0
  52. package/dist/hooks/magic-context/file-token-coverage.d.ts.map +1 -0
  53. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +11 -3
  54. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
  55. package/dist/hooks/magic-context/historian-history-wait.d.ts +16 -0
  56. package/dist/hooks/magic-context/historian-history-wait.d.ts.map +1 -0
  57. package/dist/hooks/magic-context/history-boundary-repair.d.ts +1 -1
  58. package/dist/hooks/magic-context/history-boundary-repair.d.ts.map +1 -1
  59. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  60. package/dist/hooks/magic-context/host-served-rows.d.ts +10 -0
  61. package/dist/hooks/magic-context/host-served-rows.d.ts.map +1 -1
  62. package/dist/hooks/magic-context/inject-compartments.d.ts +1 -1
  63. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  64. package/dist/hooks/magic-context/lkg-measured-request.d.ts.map +1 -1
  65. package/dist/hooks/magic-context/lkg-recovery-fence.d.ts.map +1 -1
  66. package/dist/hooks/magic-context/lkg-recovery-prefix.d.ts +3 -1
  67. package/dist/hooks/magic-context/lkg-recovery-prefix.d.ts.map +1 -1
  68. package/dist/hooks/magic-context/lkg-replay-fit.d.ts.map +1 -1
  69. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  70. package/dist/hooks/magic-context/lkg-slot.d.ts +3 -1
  71. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  72. package/dist/hooks/magic-context/nudge-evaluation-log.d.ts +3 -0
  73. package/dist/hooks/magic-context/nudge-evaluation-log.d.ts.map +1 -0
  74. package/dist/hooks/magic-context/pass-outcome.d.ts +2 -0
  75. package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
  76. package/dist/hooks/magic-context/pending-drop-eligibility.d.ts.map +1 -1
  77. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +2 -0
  78. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  79. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  80. package/dist/hooks/magic-context/read-session-db.d.ts +8 -2
  81. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  82. package/dist/hooks/magic-context/read-session-raw.d.ts +20 -0
  83. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  84. package/dist/hooks/magic-context/recomp-orchestrator.d.ts +3 -3
  85. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  86. package/dist/hooks/magic-context/signed-thinking-fit-snapshot.d.ts +42 -0
  87. package/dist/hooks/magic-context/signed-thinking-fit-snapshot.d.ts.map +1 -0
  88. package/dist/hooks/magic-context/system-date-refresh.d.ts +3 -2
  89. package/dist/hooks/magic-context/system-date-refresh.d.ts.map +1 -1
  90. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  91. package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts +4 -0
  92. package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts.map +1 -0
  93. package/dist/hooks/magic-context/tag-content-primitives.d.ts +1 -1
  94. package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -1
  95. package/dist/hooks/magic-context/tag-messages.d.ts +17 -2
  96. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  97. package/dist/hooks/magic-context/text-complete.d.ts +1 -1
  98. package/dist/hooks/magic-context/text-complete.d.ts.map +1 -1
  99. package/dist/hooks/magic-context/tool-drop-target.d.ts +3 -2
  100. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  101. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +1 -0
  102. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  103. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +6 -0
  104. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  105. package/dist/hooks/magic-context/transform-stage-logger.d.ts +3 -0
  106. package/dist/hooks/magic-context/transform-stage-logger.d.ts.map +1 -1
  107. package/dist/hooks/magic-context/transform.d.ts +4 -2
  108. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  109. package/dist/{index-27ddyx39.js → index-1np16gxq.js} +1 -1
  110. package/dist/{index-ykq24x1n.js → index-8rmt6s4f.js} +78 -32
  111. package/dist/{index-dwh99z66.js → index-pte3cfs9.js} +194 -5
  112. package/dist/{index-r7s7d350.js → index-s3ebcy63.js} +1 -1
  113. package/dist/{index-48e9znrc.js → index-t0zx3tgz.js} +481 -109
  114. package/dist/{index-kahkxcqw.js → index-xk1dz6q9.js} +870 -315
  115. package/dist/index.js +2 -2
  116. package/dist/{message-time-backfill-j96x1sab.js → message-time-backfill-g9py24yt.js} +1 -1
  117. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  118. package/dist/plugin/subagent-tool-policy.d.ts +4 -0
  119. package/dist/plugin/subagent-tool-policy.d.ts.map +1 -1
  120. package/dist/{read-session-chunk-t8bg6wkz.js → read-session-chunk-2s8x6xps.js} +3 -3
  121. package/dist/{recomp-orchestrator-k760qy1n.js → recomp-orchestrator-51xyaexp.js} +6 -6
  122. package/dist/{send-session-notification-njjf3b4s.js → send-session-notification-vdppp5x6.js} +3 -3
  123. package/dist/shared/model-suggestion-retry.d.ts +2 -0
  124. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  125. package/dist/shared/rpc-discovery-cleanup.d.ts +3 -0
  126. package/dist/shared/rpc-discovery-cleanup.d.ts.map +1 -0
  127. package/dist/shared/rpc-server.d.ts +2 -0
  128. package/dist/shared/rpc-server.d.ts.map +1 -1
  129. package/dist/shared/search-text.d.ts +8 -0
  130. package/dist/shared/search-text.d.ts.map +1 -0
  131. package/dist/shared/sqlite.d.ts +6 -1
  132. package/dist/shared/sqlite.d.ts.map +1 -1
  133. package/dist/shared/storage-file-mutex.d.ts.map +1 -1
  134. package/dist/shared/system-directive.d.ts +2 -0
  135. package/dist/shared/system-directive.d.ts.map +1 -1
  136. package/dist/shared/tag-transcript.d.ts +2 -0
  137. package/dist/shared/tag-transcript.d.ts.map +1 -1
  138. package/dist/shared/transcript.d.ts +3 -1
  139. package/dist/shared/transcript.d.ts.map +1 -1
  140. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  141. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  142. package/dist/tools/parameter-descriptions.d.ts +6 -6
  143. package/dist/tools/parameter-descriptions.d.ts.map +1 -1
  144. package/dist/v2/fold/native-replay.d.ts +11 -2
  145. package/dist/v2/fold/native-replay.d.ts.map +1 -1
  146. package/dist/v2/fold/policy.d.ts.map +1 -1
  147. package/dist/v2/fold/restore.d.ts.map +1 -1
  148. package/dist/v2/hooks/context.d.ts +4 -0
  149. package/dist/v2/hooks/context.d.ts.map +1 -1
  150. package/dist/v2/hooks/generate.d.ts +36 -1
  151. package/dist/v2/hooks/generate.d.ts.map +1 -1
  152. package/dist/v2/hooks/lkg-system.d.ts +35 -4
  153. package/dist/v2/hooks/lkg-system.d.ts.map +1 -1
  154. package/dist/v2/hooks/payload.d.ts +10 -1
  155. package/dist/v2/hooks/payload.d.ts.map +1 -1
  156. package/dist/v2/hooks/store.d.ts +2 -0
  157. package/dist/v2/hooks/store.d.ts.map +1 -1
  158. package/dist/v2/hooks/types.d.ts +12 -0
  159. package/dist/v2/hooks/types.d.ts.map +1 -1
  160. package/dist/v2/message-times.d.ts +17 -0
  161. package/dist/v2/message-times.d.ts.map +1 -0
  162. package/dist/v2/server.js +4692 -2394
  163. package/dist/v2/store-reader.d.ts +21 -0
  164. package/dist/v2/store-reader.d.ts.map +1 -1
  165. package/dist/web/main.js +307 -12
  166. package/dist/{wrapup-orchestrator-b2gswatj.js → wrapup-orchestrator-g0mww1h4.js} +6 -6
  167. package/package.json +1 -1
  168. package/src/config/latch-permanence-guard.test.ts +4 -5
  169. package/src/shared/model-suggestion-retry.test.ts +52 -0
  170. package/src/shared/model-suggestion-retry.ts +8 -3
  171. package/src/shared/prompt-surface-a1-golden.md +6 -7
  172. package/src/shared/rpc-discovery-cleanup.test.ts +125 -0
  173. package/src/shared/rpc-discovery-cleanup.ts +57 -0
  174. package/src/shared/rpc-server.ts +36 -13
  175. package/src/shared/search-text.test.ts +30 -0
  176. package/src/shared/search-text.ts +62 -0
  177. package/src/shared/sqlite-transaction-mode-guard.test.ts +2 -0
  178. package/src/shared/sqlite-turn-deadline.test.ts +286 -0
  179. package/src/shared/sqlite.ts +237 -9
  180. package/src/shared/storage-file-mutex.test.ts +51 -2
  181. package/src/shared/storage-file-mutex.ts +11 -1
  182. package/src/shared/system-directive.test.ts +37 -0
  183. package/src/shared/system-directive.ts +19 -1
  184. package/src/shared/tag-transcript.ts +63 -8
  185. package/src/shared/transcript.ts +1 -1
  186. package/src/shared/write-transaction-attribution.test.ts +1 -6
  187. package/dist/features/magic-context/message-index-sweep.d.ts +0 -11
  188. package/dist/features/magic-context/message-index-sweep.d.ts.map +0 -1
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  Database,
3
3
  getSqliteDatabasePath
4
- } from "./index-dwh99z66.js";
4
+ } from "./index-pte3cfs9.js";
5
5
  import {
6
+ getHarness,
6
7
  harnessOwnsOpenCodeStore,
7
8
  log
8
9
  } from "./index-k59af64t.js";
@@ -477,6 +478,9 @@ var ordinalWatermarks = new WeakMap;
477
478
  var ordinalWatermarkEpochs = new Map;
478
479
  var ordinalRowsVisited = 0;
479
480
  var STABLE_STORE_ATTEMPTS = 3;
481
+ function forgetRawSessionOrdinalWatermark(sessionId) {
482
+ ordinalWatermarkEpochs.set(sessionId, (ordinalWatermarkEpochs.get(sessionId) ?? 0) + 1);
483
+ }
480
484
  function compareOrdinalKeys(left, right) {
481
485
  if (left.timeCreated !== right.timeCreated)
482
486
  return left.timeCreated < right.timeCreated ? -1 : 1;
@@ -503,6 +507,11 @@ var writtenSummaryIds = new Map;
503
507
  var indexedCountUnsupported = new WeakSet;
504
508
  var ordinalJsonRowsRead = 0;
505
509
  var summaryFullScans = 0;
510
+ function forgetRawSessionSummaryRows(sessionId) {
511
+ summaryCandidateEpochs.set(sessionId, (summaryCandidateEpochs.get(sessionId) ?? 0) + 1);
512
+ writtenSummaryIds.delete(sessionId);
513
+ forgetRawSessionOrdinalWatermark(sessionId);
514
+ }
506
515
  var ANCHOR_ROWS_SQL = `SELECT rowid AS rid, id, 1 AS kind FROM message
507
516
  WHERE rowid > (SELECT MAX(rowid) FROM message) - ${SUMMARY_ANCHOR_SPAN}`;
508
517
  var SUMMARY_FULL_SCAN_SQL = `${ANCHOR_ROWS_SQL}
@@ -523,6 +532,20 @@ function survivingAnchor(db, set) {
523
532
  }
524
533
  var ordinalCheckpoints = new WeakMap;
525
534
  var ordinalSummarySeeds = new WeakMap;
535
+ function hasLateCommitBehindCheckpoint(db, sessionId, scan) {
536
+ const tail = scan.checkpoints?.at(-1);
537
+ if (!tail || scan.maxRowid === undefined)
538
+ return false;
539
+ const row = db.prepare(`SELECT COUNT(*) AS count FROM message
540
+ WHERE rowid > ? AND +session_id = ?
541
+ AND (time_created, id) <= (?, ?)
542
+ AND NOT (${EXCLUDED_ROW_SQL})`).get(scan.maxRowid, sessionId, tail.timeCreated, tail.id);
543
+ return typeof row?.count === "number" && row.count > 0;
544
+ }
545
+ function discardRetainedOrdinalRanks(db, sessionId) {
546
+ ordinalCheckpoints.get(db)?.delete(sessionId);
547
+ ordinalSummarySeeds.get(db)?.delete(sessionId);
548
+ }
526
549
  var ORDINAL_LOOKUP_LIMIT = 512;
527
550
  function currentOrdinalCheckpoints(db, sessionId) {
528
551
  const cached = ordinalCheckpoints.get(db)?.get(sessionId);
@@ -553,10 +576,16 @@ function extendOrdinalCheckpoints(db, sessionId, scan, limit) {
553
576
  scan.sessionRows = points.at(-1)?.storedCount ?? 0;
554
577
  }
555
578
  const tail = points.at(-1);
556
- const rows = db.prepare(`SELECT id, time_created AS timeCreated, ${EXCLUDED_ROW_SQL} AS excluded FROM message
579
+ const rows = db.prepare(`SELECT id, time_created AS timeCreated, rowid AS rowid, ${EXCLUDED_ROW_SQL} AS excluded FROM message
557
580
  WHERE session_id=?${tail ? " AND (time_created,id) > (?,?)" : ""}
558
581
  ORDER BY time_created,id${limit === undefined ? "" : ` LIMIT ${limit + 1}`}`).all(sessionId, ...tail ? [tail.timeCreated, tail.id] : []);
559
582
  ordinalJsonRowsRead += rows.length;
583
+ if (hasLateCommitBehindCheckpoint(db, sessionId, scan)) {
584
+ discardRetainedOrdinalRanks(db, sessionId);
585
+ if (isMainThread)
586
+ forgetRawSessionSummaryRows(sessionId);
587
+ return false;
588
+ }
560
589
  if (limit !== undefined && rows.length > limit)
561
590
  return false;
562
591
  let total = scan.total ?? 0;
@@ -573,6 +602,13 @@ function extendOrdinalCheckpoints(db, sessionId, scan, limit) {
573
602
  scan.checkpoints = points;
574
603
  scan.sessionRows += rows.length;
575
604
  scan.total = total;
605
+ if (rows.length > 0) {
606
+ let maxRowid = scan.maxRowid ?? -1;
607
+ for (const row of rows)
608
+ if (row.rowid > maxRowid)
609
+ maxRowid = row.rowid;
610
+ scan.maxRowid = maxRowid;
611
+ }
576
612
  return true;
577
613
  }
578
614
  function warmRawSessionOrdinalsForDb(db, sessionId) {
@@ -587,6 +623,10 @@ function warmRawSessionOrdinalsForDb(db, sessionId) {
587
623
  }
588
624
  return isRawSessionSummaryWarm(db, sessionId);
589
625
  }
626
+ function dropRawSessionOrdinalCheckpoints(db, sessionId) {
627
+ discardRetainedOrdinalRanks(db, sessionId);
628
+ forgetRawSessionSummaryRows(sessionId);
629
+ }
590
630
  function boundedOrdinalPrefix(db, sessionId, through) {
591
631
  try {
592
632
  return boundedOrdinalPrefixBounded(db, sessionId, through);
@@ -648,8 +688,7 @@ function boundedOrdinalPrefixBounded(db, sessionId, through) {
648
688
  }
649
689
  function scanRawSessionSummaryRows(db, sessionId, previous) {
650
690
  return withReadSnapshot(db, () => {
651
- if (previous?.checkpoints) {
652
- extendOrdinalCheckpoints(db, sessionId, previous);
691
+ if (previous?.checkpoints && extendOrdinalCheckpoints(db, sessionId, previous)) {
653
692
  return previous;
654
693
  }
655
694
  if (previous) {
@@ -681,12 +720,15 @@ function scanRawSessionSummaryRows(db, sessionId, previous) {
681
720
  }
682
721
  anchors.sort((left, right) => right.rowid - left.rowid);
683
722
  anchors.length = Math.min(anchors.length, SUMMARY_ANCHOR_LIMIT);
684
- const keys = db.prepare(`SELECT id, time_created AS timeCreated, ${EXCLUDED_ROW_SQL} AS excluded FROM message WHERE session_id = ?
723
+ const keys = db.prepare(`SELECT id, time_created AS timeCreated, rowid AS rowid, ${EXCLUDED_ROW_SQL} AS excluded FROM message WHERE session_id = ?
685
724
  ORDER BY time_created, id`).all(sessionId);
686
725
  const checkpoints = [];
687
726
  let total = 0;
727
+ let maxRowid;
688
728
  for (let index = 0;index < keys.length; index++) {
689
729
  const key = keys[index];
730
+ if (typeof key.rowid === "number")
731
+ maxRowid = maxRowid === undefined ? key.rowid : Math.max(maxRowid, key.rowid);
690
732
  if (key.excluded !== 1)
691
733
  total++;
692
734
  if (index % 256 === 255 || index === keys.length - 1)
@@ -697,7 +739,7 @@ function scanRawSessionSummaryRows(db, sessionId, previous) {
697
739
  storedCount: index + 1
698
740
  });
699
741
  }
700
- return { anchors, ids, sessionRows, checkpoints, total };
742
+ return { anchors, ids, sessionRows, checkpoints, total, maxRowid };
701
743
  });
702
744
  }
703
745
  function getRawSessionSummaryEpoch(sessionId) {
@@ -1130,48 +1172,53 @@ function isKnownAutocommit(db) {
1130
1172
  }
1131
1173
 
1132
1174
  // src/hooks/magic-context/read-session-db.ts
1133
- function openCodeDbExists() {
1134
- return harnessOwnsOpenCodeStore() && openCodeDbPathExists(resolveOpenCodeDbPath());
1135
- }
1136
- var cachedReadOnlyDb = null;
1137
- function closeCachedReadOnlyDb() {
1138
- if (!cachedReadOnlyDb) {
1175
+ function openCodeDbExists(generation = "v1") {
1176
+ return harnessOwnsOpenCodeStore() && openCodeDbPathExists(resolveOpenCodeDbPath(generation));
1177
+ }
1178
+ var cachedReadOnlyDbs = {
1179
+ v1: null,
1180
+ v2: null
1181
+ };
1182
+ function closeCachedReadOnlyDb(generation) {
1183
+ const cached = cachedReadOnlyDbs[generation];
1184
+ if (!cached) {
1139
1185
  return;
1140
1186
  }
1141
1187
  try {
1142
- closeQuietly(cachedReadOnlyDb.db);
1188
+ closeQuietly(cached.db);
1143
1189
  } catch (error) {
1144
1190
  log("[magic-context] failed to close cached OpenCode read-only DB:", error);
1145
1191
  } finally {
1146
- cachedReadOnlyDb = null;
1192
+ cachedReadOnlyDbs[generation] = null;
1147
1193
  }
1148
1194
  }
1149
- function getReadOnlySessionDb() {
1195
+ function getReadOnlySessionDb(generation = "v1") {
1150
1196
  if (!harnessOwnsOpenCodeStore()) {
1151
1197
  throw new Error("OpenCode session database is not readable from a Pi-compatible process; its history lives in Pi sessions");
1152
1198
  }
1153
- const resolution = resolveOpenCodeDbPath();
1199
+ const resolution = resolveOpenCodeDbPath(generation);
1154
1200
  const dbPath = resolution.path;
1155
1201
  if (!openCodeDbPathExists(resolution)) {
1156
1202
  throw new Error(`OpenCode session database is unavailable at ${dbPath} (source=${resolution.source})`);
1157
1203
  }
1158
- if (cachedReadOnlyDb?.path === dbPath) {
1159
- return cachedReadOnlyDb.db;
1204
+ const cached = cachedReadOnlyDbs[generation];
1205
+ if (cached?.path === dbPath) {
1206
+ return cached.db;
1160
1207
  }
1161
- closeCachedReadOnlyDb();
1208
+ closeCachedReadOnlyDb(generation);
1162
1209
  const db = new Database(dbPath, { readonly: true });
1163
1210
  try {
1164
- assertOpenCodeStoreGeneration(db, "v1", dbPath);
1211
+ assertOpenCodeStoreGeneration(db, generation, dbPath);
1165
1212
  } catch (error) {
1166
1213
  closeQuietly(db);
1167
1214
  throw error;
1168
1215
  }
1169
- cachedReadOnlyDb = { path: dbPath, db };
1216
+ cachedReadOnlyDbs[generation] = { path: dbPath, db };
1170
1217
  clearOpenCodeDbReadFailure();
1171
1218
  return db;
1172
1219
  }
1173
- function withReadOnlySessionDb(fn) {
1174
- return fn(getReadOnlySessionDb());
1220
+ function withReadOnlySessionDb(fn, generation = "v1") {
1221
+ return fn(getReadOnlySessionDb(generation));
1175
1222
  }
1176
1223
  function getRawSessionMessageCountFromDb(db, sessionId) {
1177
1224
  const row = db.prepare(`SELECT COUNT(*) as count FROM message WHERE session_id = ?
@@ -1401,15 +1448,14 @@ function getMessageTimesFromOpenCodeDb(sessionId, messageIds) {
1401
1448
  if (messageIds.length === 0 || !harnessOwnsOpenCodeStore())
1402
1449
  return result;
1403
1450
  try {
1404
- withReadOnlySessionDb((db) => {
1405
- const placeholders = messageIds.map(() => "?").join(",");
1406
- const rows = db.prepare(`SELECT id, time_created FROM message WHERE +session_id = ? AND id IN (${placeholders})`).all(sessionId, ...messageIds);
1407
- for (const row of rows) {
1408
- if (typeof row.id === "string" && typeof row.time_created === "number") {
1409
- result.set(row.id, row.time_created);
1410
- }
1451
+ const placeholders = messageIds.map(() => "?").join(",");
1452
+ const rows = getHarness() === "opencode2" ? getReadOnlySessionDb("v2").prepare(`SELECT id, COALESCE(time_created, json_extract(data, '$.time.created')) AS time_created
1453
+ FROM session_message WHERE +session_id = ? AND id IN (${placeholders})`).all(sessionId, ...messageIds) : withReadOnlySessionDb((db) => db.prepare(`SELECT id, time_created FROM message WHERE +session_id = ? AND id IN (${placeholders})`).all(sessionId, ...messageIds));
1454
+ for (const row of rows) {
1455
+ if (typeof row.id === "string" && typeof row.time_created === "number") {
1456
+ result.set(row.id, row.time_created);
1411
1457
  }
1412
- });
1458
+ }
1413
1459
  } catch (error) {
1414
1460
  logProbeFailureOnce(resolveOpenCodeDbPath(), error);
1415
1461
  }
@@ -1474,4 +1520,4 @@ function findLastAssistantModelFromOpenCodeDb(sessionId) {
1474
1520
  }
1475
1521
  }
1476
1522
 
1477
- export { closeQuietly, isKnownAutocommit, resolveOpenCodeDbPath, hasV1MessageTables, assertOpenCodeStoreGeneration, openCodeDbPathExists, claimOpenCodeDbDiagnosticOnce, isStrictGapHealingMessage, readRawSessionMessagesFromDb, readRawSessionMessagePageFromDb, readRawSessionMessageSummaryPageFromDb, countRawSessionMessageOrdinalsFromDb, readRawSessionMessageIdOrdinalsForRangeFromDb, readRawSessionTailFromDb, extractInMemoryMessageViews, buildInMemoryTailRawMessages, warmRawSessionOrdinalsForDb, readRawSessionMessageOrdinalByIdFromDb, readRawSessionMessageByIdFromDb, hasRawSessionMessageByIdFromDb, openCodeDbExists, withReadOnlySessionDb, getRawSessionMessageCountFromDb, shouldHoldIgnoredNotification, latestRealUserTurnIdFromOpenCodeDb, getMessageTimesFromOpenCodeDb, findLastAssistantModelFromOpenCodeDb };
1523
+ export { closeQuietly, isKnownAutocommit, resolveOpenCodeDbPath, hasV1MessageTables, assertOpenCodeStoreGeneration, openCodeDbPathExists, claimOpenCodeDbDiagnosticOnce, isStrictGapHealingMessage, readRawSessionMessagesFromDb, readRawSessionMessagePageFromDb, readRawSessionMessageSummaryPageFromDb, countRawSessionMessageOrdinalsFromDb, readRawSessionMessageIdOrdinalsForRangeFromDb, readRawSessionTailFromDb, extractInMemoryMessageViews, buildInMemoryTailRawMessages, warmRawSessionOrdinalsForDb, dropRawSessionOrdinalCheckpoints, readRawSessionMessageOrdinalByIdFromDb, readRawSessionMessageByIdFromDb, hasRawSessionMessageByIdFromDb, openCodeDbExists, withReadOnlySessionDb, getRawSessionMessageCountFromDb, shouldHoldIgnoredNotification, latestRealUserTurnIdFromOpenCodeDb, getMessageTimesFromOpenCodeDb, findLastAssistantModelFromOpenCodeDb };
@@ -167,6 +167,177 @@ function topLevelCommaSegments(text) {
167
167
  function getTagIdentityWriteGeneration() {
168
168
  return tagIdentityWriteGeneration;
169
169
  }
170
+ var busyTimeoutStates = new WeakMap;
171
+ var BUSY_TIMEOUT_QUERY = /^\s*PRAGMA\s+(?:(?:\w+|"[^"]+"|`[^`]+`|\[[^\]]+\])\s*\.\s*)?(?:busy_timeout|"busy_timeout"|`busy_timeout`|\[busy_timeout\])\s*;?\s*$/i;
172
+ var BUSY_TIMEOUT_SETTER = /^\s*PRAGMA\s+(?:(?:\w+|"[^"]+"|`[^`]+`|\[[^\]]+\])\s*\.\s*)?(?:busy_timeout|"busy_timeout"|`busy_timeout`|\[busy_timeout\])\s*(?==|\()/i;
173
+ function literalBusyTimeout(sql) {
174
+ const head = BUSY_TIMEOUT_SETTER.exec(sql);
175
+ if (!head)
176
+ return;
177
+ const match = /^(?:=\s*|\(\s*)(?:'(-?\d+)'|"(-?\d+)"|(-?\d+))\s*\)?\s*;?\s*$/.exec(sql.slice(head[0].length));
178
+ if (!match)
179
+ return;
180
+ const value = Number(match[1] ?? match[2] ?? match[3]);
181
+ return value < 0 ? 0 : value <= 2147483647 ? value : undefined;
182
+ }
183
+ function busyTimeoutStatements(sql) {
184
+ const statements = [];
185
+ let statement = "";
186
+ let quote = "";
187
+ for (let i = 0;i < sql.length; i++) {
188
+ const char = sql[i];
189
+ if (quote) {
190
+ statement += char;
191
+ if (char === quote) {
192
+ if (sql[i + 1] === quote)
193
+ statement += sql[++i];
194
+ else
195
+ quote = "";
196
+ }
197
+ } else if (char === "'" || char === '"' || char === "`" || char === "[") {
198
+ quote = char === "[" ? "]" : char;
199
+ statement += char;
200
+ } else if (char === "-" && sql[i + 1] === "-") {
201
+ while (i + 1 < sql.length && sql[i + 1] !== `
202
+ `)
203
+ i++;
204
+ statement += " ";
205
+ } else if (char === "/" && sql[i + 1] === "*") {
206
+ i += 2;
207
+ while (i < sql.length && !(sql[i] === "*" && sql[i + 1] === "/"))
208
+ i++;
209
+ i++;
210
+ statement += " ";
211
+ } else if (char === ";") {
212
+ statements.push(statement);
213
+ statement = "";
214
+ } else
215
+ statement += char;
216
+ }
217
+ statements.push(statement);
218
+ return statements.filter((part) => part.trim().length > 0);
219
+ }
220
+ function installNativeDeadlineRouting(db) {
221
+ const rawExec = db.exec.bind(db);
222
+ const rawPrepare = db.prepare.bind(db);
223
+ const readTimeout = () => {
224
+ const statement = rawPrepare("PRAGMA busy_timeout");
225
+ try {
226
+ return Object.values(statement.get())[0];
227
+ } finally {
228
+ statement.finalize?.();
229
+ }
230
+ };
231
+ const timeoutState = { current: readTimeout() };
232
+ busyTimeoutStates.set(db, timeoutState);
233
+ const setBusyTimeout = (timeout) => {
234
+ rawExec(`PRAGMA busy_timeout=${timeout}`);
235
+ timeoutState.current = timeout;
236
+ };
237
+ const withinDeadline = (operation) => {
238
+ const deadline = nativeWaitScope?.getStore();
239
+ if (!deadline?.active || !deadline.remainingMs)
240
+ return operation();
241
+ const remaining = deadline.remainingMs();
242
+ if (remaining === Infinity)
243
+ return operation();
244
+ const previous = timeoutState.current;
245
+ const timeout = Math.min(previous, Math.max(0, Math.floor(remaining)));
246
+ if (timeout === previous)
247
+ return operation();
248
+ setBusyTimeout(timeout);
249
+ try {
250
+ return operation();
251
+ } finally {
252
+ setBusyTimeout(previous);
253
+ }
254
+ };
255
+ Object.defineProperty(db, "exec", {
256
+ configurable: true,
257
+ writable: true,
258
+ value: (sql) => {
259
+ const parts = /\bbusy_timeout\b/i.test(sql) ? busyTimeoutStatements(sql) : [];
260
+ if (parts.length === 1 && BUSY_TIMEOUT_QUERY.test(parts[0]))
261
+ return rawExec(sql);
262
+ const singleSetter = parts.length === 1 && BUSY_TIMEOUT_SETTER.test(parts[0]);
263
+ const setting = singleSetter ? literalBusyTimeout(parts[0]) : undefined;
264
+ if (singleSetter) {
265
+ const result = rawExec(sql);
266
+ timeoutState.current = setting ?? readTimeout();
267
+ return result;
268
+ }
269
+ if (!/\bbusy_timeout\b/i.test(sql))
270
+ return withinDeadline(() => rawExec(sql));
271
+ const setters = parts.filter((part) => BUSY_TIMEOUT_SETTER.test(part));
272
+ return withinDeadline(() => {
273
+ try {
274
+ const result = rawExec(sql);
275
+ if (setters.length)
276
+ timeoutState.current = literalBusyTimeout(setters[setters.length - 1]) ?? readTimeout();
277
+ return result;
278
+ } catch (error) {
279
+ if (setters.length)
280
+ timeoutState.current = readTimeout();
281
+ throw error;
282
+ }
283
+ });
284
+ }
285
+ });
286
+ const nativePrepare = (sql) => BUSY_TIMEOUT_QUERY.test(sql) || BUSY_TIMEOUT_SETTER.test(sql) ? rawPrepare(sql) : withinDeadline(() => rawPrepare(sql));
287
+ Object.defineProperty(db, "prepare", {
288
+ configurable: true,
289
+ writable: true,
290
+ value: (sql) => {
291
+ const statement = nativePrepare(sql);
292
+ const normalized = /\bbusy_timeout\b/i.test(sql) ? busyTimeoutStatements(sql)[0] ?? sql : sql;
293
+ const setting = literalBusyTimeout(normalized);
294
+ const timeoutSetter = BUSY_TIMEOUT_SETTER.test(normalized);
295
+ const timeoutQuery = BUSY_TIMEOUT_QUERY.test(normalized);
296
+ if (timeoutSetter)
297
+ timeoutState.current = setting ?? readTimeout();
298
+ for (const method of ["run", "get", "all", "values"]) {
299
+ const execute = statement[method]?.bind(statement);
300
+ if (!execute)
301
+ continue;
302
+ Object.defineProperty(statement, method, {
303
+ configurable: true,
304
+ value: (...args) => {
305
+ if (timeoutQuery)
306
+ return execute(...args);
307
+ if (!timeoutSetter)
308
+ return withinDeadline(() => execute(...args));
309
+ const result = execute(...args);
310
+ timeoutState.current = readTimeout();
311
+ return result;
312
+ }
313
+ });
314
+ }
315
+ if (typeof statement.iterate === "function") {
316
+ const iterate = statement.iterate.bind(statement);
317
+ Object.defineProperty(statement, "iterate", {
318
+ configurable: true,
319
+ value: (...args) => {
320
+ const iterator = !timeoutSetter && !timeoutQuery ? withinDeadline(() => iterate(...args)) : iterate(...args);
321
+ const next = iterator.next.bind(iterator);
322
+ if (timeoutSetter)
323
+ timeoutState.current = readTimeout();
324
+ iterator.next = () => {
325
+ if (timeoutQuery)
326
+ return next();
327
+ if (!timeoutSetter)
328
+ return withinDeadline(next);
329
+ const result = next();
330
+ timeoutState.current = readTimeout();
331
+ return result;
332
+ };
333
+ return iterator;
334
+ }
335
+ });
336
+ }
337
+ return statement;
338
+ }
339
+ });
340
+ }
170
341
  function installTransactionRouting(db, readonly) {
171
342
  const nativeExec = db.exec.bind(db);
172
343
  Object.defineProperty(db, "exec", {
@@ -304,7 +475,7 @@ function wrapRemainingTagWriteForms(statement) {
304
475
  });
305
476
  }
306
477
  }
307
- function trackSqliteConnection(db, filename, options) {
478
+ function trackSqliteConnection(db, filename, options, turnDeadlines = false) {
308
479
  const originalClose = db.close.bind(db);
309
480
  const sequence = nextSqliteConnectionSequence++;
310
481
  const metadata = {
@@ -312,6 +483,8 @@ function trackSqliteConnection(db, filename, options) {
312
483
  filename: typeof filename === "string" ? filename : Buffer.isBuffer(filename) ? "<buffer>" : ":memory:",
313
484
  readonly: Boolean(options) && typeof options === "object" && (options.readonly === true || options.readOnly === true)
314
485
  };
486
+ if (turnDeadlines)
487
+ installNativeDeadlineRouting(db);
315
488
  installTransactionRouting(db, metadata.readonly);
316
489
  Object.defineProperty(db, "close", {
317
490
  configurable: true,
@@ -364,6 +537,12 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
364
537
  return NodeSqliteDatabase;
365
538
  }
366
539
  var Database = TrackedDatabase;
540
+ function createSqliteTurnDatabase(filename, options) {
541
+ return trackSqliteConnection(new DatabaseImpl(filename, options), filename, options, true);
542
+ }
543
+ function hasSqliteTurnDeadlineRouting(db) {
544
+ return busyTimeoutStates.has(db);
545
+ }
367
546
  function getSqliteDatabasePath(db) {
368
547
  for (const connection of trackedSqliteConnections.values()) {
369
548
  if (connection.reference.deref() === db) {
@@ -383,6 +562,11 @@ function pragmaValue(db, name) {
383
562
  return row[name] ?? Object.values(row)[0];
384
563
  }
385
564
  function pragmaNumber(db, name) {
565
+ if (name === "busy_timeout") {
566
+ const state = busyTimeoutStates.get(db);
567
+ if (state)
568
+ return state.current;
569
+ }
386
570
  try {
387
571
  const value = pragmaValue(db, name);
388
572
  return typeof value === "number" && Number.isFinite(value) ? value : null;
@@ -513,11 +697,14 @@ function prepareCachedStatement(db, sql) {
513
697
  return ownPreparedStatement(db, db.prepare(sql));
514
698
  }
515
699
  var privilegeDepth = new WeakMap;
700
+ var nativeWaitScope;
516
701
  var transformPassScope = new AsyncLocalStorage;
517
702
  var admissionScope = new AsyncLocalStorage;
518
703
  var backgroundWriterScope = new AsyncLocalStorage;
519
704
  function withSqliteBackgroundWriter(operation) {
520
- return backgroundWriterScope.run(true, operation);
705
+ if (!nativeWaitScope?.getStore())
706
+ return backgroundWriterScope.run(true, operation);
707
+ return nativeWaitScope.run(undefined, () => backgroundWriterScope.run(true, operation));
521
708
  }
522
709
  function withSqliteTransformPass(operation) {
523
710
  const existing = transformPassScope.getStore();
@@ -548,7 +735,9 @@ function withSqliteTransformPass(operation) {
548
735
  return typeof reservation === "function" ? run(reservation) : reservation.then(run);
549
736
  }
550
737
  function withoutSqliteTransformPass(operation) {
551
- return transformPassScope.run(undefined, operation);
738
+ if (!nativeWaitScope?.getStore())
739
+ return transformPassScope.run(undefined, operation);
740
+ return nativeWaitScope.run(undefined, () => transformPassScope.run(undefined, operation));
552
741
  }
553
742
  function assertTransformWrite() {
554
743
  if (!backgroundWriterScope.getStore())
@@ -744,7 +933,7 @@ async function withAsyncPrivilegedWriter(db, operation, options = {}) {
744
933
  } catch (error) {
745
934
  if (entered || !(error instanceof SqliteAcquisitionBusyError))
746
935
  throw error;
747
- options.beforeRetry?.(error);
936
+ await options.beforeRetry?.(error);
748
937
  const elapsed = performance.now() - started;
749
938
  if (elapsed >= budgetMs) {
750
939
  reportSqliteDiagnostic(`sqlite writer site=privileged_writer lane=foreground acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`);
@@ -879,4 +1068,4 @@ async function withIndexChunk(input, operation) {
879
1068
  }
880
1069
  }
881
1070
 
882
- export { inRootAsyncContext, registerSlowWriteReporter, registerSqliteDiagnosticSink, detectSqliteRuntime, getTagIdentityWriteGeneration, Database, getSqliteDatabasePath, getSqliteMemoryStats, prepareCachedStatement, withSqliteBackgroundWriter, withSqliteTransformPass, withoutSqliteTransformPass, isTransientSqliteError, SqliteAcquisitionBusyError, beginSqliteWriterAsync, withAsyncPrivilegedWriter, withPrivilegedWriter, indexCoordinationInput, withIndexChunk };
1071
+ export { inRootAsyncContext, registerSlowWriteReporter, registerSqliteDiagnosticSink, detectSqliteRuntime, getTagIdentityWriteGeneration, Database, createSqliteTurnDatabase, hasSqliteTurnDeadlineRouting, getSqliteDatabasePath, getSqliteMemoryStats, prepareCachedStatement, withSqliteBackgroundWriter, withSqliteTransformPass, withoutSqliteTransformPass, isTransientSqliteError, SqliteAcquisitionBusyError, beginSqliteWriterAsync, withAsyncPrivilegedWriter, withPrivilegedWriter, indexCoordinationInput, withIndexChunk };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./index-k59af64t.js";
4
4
  import {
5
5
  shouldHoldIgnoredNotification
6
- } from "./index-ykq24x1n.js";
6
+ } from "./index-8rmt6s4f.js";
7
7
 
8
8
  // src/shared/error-message.ts
9
9
  function getErrorMessage(error) {