@cortexkit/opencode-magic-context 0.49.7 → 0.49.8

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 (200) hide show
  1. package/dist/auto-search-worker.js +6 -6
  2. package/dist/compaction-marker-candidates-worker.js +2 -2
  3. package/dist/{compaction-marker-candidates-a0edbqrr.js → compaction-marker-candidates-xxz35vwp.js} +3 -3
  4. package/dist/{conflict-warning-hook-myk5hbt9.js → conflict-warning-hook-w3crzrar.js} +8 -8
  5. package/dist/{context-ffr7e0g7.js → context-x0ccfv0f.js} +65 -42
  6. package/dist/{derive-budgets-j4ry8j8n.js → derive-budgets-3nbxsyss.js} +2 -2
  7. package/dist/embedding-backfill-3h2m5n0q.js +21 -0
  8. package/dist/embedding-worker-process.js +6 -2
  9. package/dist/embedding-worker.js +6 -5
  10. package/dist/features/magic-context/compaction-marker-candidates.d.ts.map +1 -1
  11. package/dist/features/magic-context/dreamer/cron.d.ts +2 -0
  12. package/dist/features/magic-context/dreamer/cron.d.ts.map +1 -1
  13. package/dist/features/magic-context/dreamer/provider-output-failure.d.ts +1 -0
  14. package/dist/features/magic-context/dreamer/provider-output-failure.d.ts.map +1 -1
  15. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  16. package/dist/features/magic-context/memory/embedding-worker-client.d.ts.map +1 -1
  17. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  18. package/dist/features/magic-context/migration-worker-client.d.ts.map +1 -1
  19. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  20. package/dist/features/magic-context/smart-notes/wake-plane.d.ts.map +1 -1
  21. package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
  22. package/dist/history-owner-ty29fz0f.js +244 -0
  23. package/dist/hooks/auto-update-checker/checker.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
  25. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  26. package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
  27. package/dist/hooks/magic-context/edit-marker.d.ts +2 -0
  28. package/dist/hooks/magic-context/edit-marker.d.ts.map +1 -1
  29. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  30. package/dist/hooks/magic-context/module-transport.d.ts +1 -0
  31. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -1
  33. package/dist/hooks/magic-context/read-session-chunk.d.ts +8 -4
  34. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  35. package/dist/hooks/magic-context/rust-mode-transform.d.ts +1 -0
  36. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  37. package/dist/hooks/magic-context/rust-refusal-recovery.d.ts.map +1 -1
  38. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  39. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  40. package/dist/hooks/magic-context/unresolved-history-boundary.d.ts +5 -1
  41. package/dist/hooks/magic-context/unresolved-history-boundary.d.ts.map +1 -1
  42. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  43. package/dist/{index-g8qbdb03.js → index-0jz47061.js} +6 -3
  44. package/dist/{index-4mjhqadz.js → index-150zz6fh.js} +1 -1
  45. package/dist/{index-j58gqrn2.js → index-2rw244rh.js} +31 -24
  46. package/dist/{index-0gyq3djm.js → index-4hb8nt93.js} +3 -3
  47. package/dist/{index-ax2jhztn.js → index-7bjgyaj1.js} +4 -4
  48. package/dist/{index-h2wc01qk.js → index-8kk7yh6m.js} +2 -2
  49. package/dist/{index-n5a170gs.js → index-9g1c4bt9.js} +81 -58
  50. package/dist/{index-w6bd03dc.js → index-a43xq1pg.js} +5 -5
  51. package/dist/{index-tqf7yg27.js → index-a4b0gbyg.js} +1 -1
  52. package/dist/{index-37q80veb.js → index-angx1s0k.js} +4 -3
  53. package/dist/{index-wq16ahsn.js → index-b4gcb3rk.js} +8 -8
  54. package/dist/{index-z1tjp257.js → index-b64n4d0h.js} +1 -1
  55. package/dist/{index-1bt88epp.js → index-bd9cjab3.js} +1 -1
  56. package/dist/{index-gbmqa9x9.js → index-bmwfzz28.js} +9 -6
  57. package/dist/{index-qx53vezw.js → index-gjvjh960.js} +1 -1
  58. package/dist/{index-ebnngykq.js → index-gzg9ekc1.js} +19 -18
  59. package/dist/{index-5tbvdff4.js → index-hxrvx6cy.js} +79 -40
  60. package/dist/{index-w23dh319.js → index-jw4gbfkv.js} +1 -1
  61. package/dist/index-knvkbfvh.js +25 -0
  62. package/dist/{index-vkbqdnkj.js → index-kvw6xew3.js} +6 -3
  63. package/dist/{index-rzmjkdd6.js → index-mp2kghkv.js} +3 -27
  64. package/dist/{index-nsjyysj0.js → index-mvvephtj.js} +5 -1
  65. package/dist/{index-9yyqq3mm.js → index-n78avt2p.js} +1 -1
  66. package/dist/{index-vt4sf4ep.js → index-pgy3h49n.js} +4 -4
  67. package/dist/{index-w6vr754t.js → index-pjgzdezw.js} +13 -9
  68. package/dist/{v2/server-1rfgbjfn.js → index-q28hsbpg.js} +15 -3
  69. package/dist/{index-a8acx4gc.js → index-q76br5zn.js} +3 -3
  70. package/dist/{index-j5hce1ab.js → index-qgp5vnt4.js} +5 -5
  71. package/dist/{index-sf94at64.js → index-rg1cezmj.js} +22 -22
  72. package/dist/{index-sh91t19a.js → index-s178h9z8.js} +4 -3
  73. package/dist/{index-tagss15p.js → index-w1ejb9qr.js} +105 -58
  74. package/dist/{index-k6xvbj2e.js → index-w28y7d0z.js} +2 -0
  75. package/dist/{index-j8epsc0g.js → index-wafzvyhg.js} +33 -10
  76. package/dist/{index-rwmpkss5.js → index-xf6k8szp.js} +4 -4
  77. package/dist/{index-tmtty2x5.js → index-xpn05jxq.js} +4 -4
  78. package/dist/{index-n7kwfw2r.js → index-ydjgz36f.js} +7 -7
  79. package/dist/{index-4btknbqh.js → index-zf9nydbd.js} +48 -38
  80. package/dist/index.js +51 -50
  81. package/dist/{logger-ewak5q1s.js → logger-wn328tfg.js} +1 -1
  82. package/dist/{message-index-bounded-04rycpx4.js → message-index-bounded-hxjp56qk.js} +16 -16
  83. package/dist/{message-index-rqtse28y.js → message-index-zs882h8e.js} +16 -16
  84. package/dist/{message-time-backfill-a5ytnp53.js → message-time-backfill-nb5hhnrt.js} +3 -3
  85. package/dist/migration-worker.js +11 -11
  86. package/dist/plugin/boot-quiet.d.ts.map +1 -1
  87. package/dist/plugin/dream-timer.d.ts.map +1 -1
  88. package/dist/plugin/rpc-handlers.d.ts +2 -0
  89. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  90. package/dist/{project-embedding-registry-k0sd9k7v.js → project-embedding-registry-vy7sv9jt.js} +11 -11
  91. package/dist/raw-ordinal-warmup-worker.js +6 -6
  92. package/dist/{read-session-chunk-h1btx938.js → read-session-chunk-t9r7r0sg.js} +11 -11
  93. package/dist/{read-session-raw-vdf4wh78.js → read-session-raw-gm6xj30v.js} +3 -3
  94. package/dist/recomp-orchestrator-gr36zvd2.js +60 -0
  95. package/dist/{safe-notification-target-q0cyrx3x.js → safe-notification-target-jdynm677.js} +2 -2
  96. package/dist/{search-3rbdx6hw.js → search-qjen1pmz.js} +24 -24
  97. package/dist/{send-session-notification-2tp44tfa.js → send-session-notification-q8ngbap3.js} +6 -6
  98. package/dist/shared/history-owner.d.ts +12 -0
  99. package/dist/shared/history-owner.d.ts.map +1 -0
  100. package/dist/shared/off-thread-migration-clock.d.ts +8 -1
  101. package/dist/shared/off-thread-migration-clock.d.ts.map +1 -1
  102. package/dist/shared/redaction.d.ts.map +1 -1
  103. package/dist/shared/rpc-server.d.ts.map +1 -1
  104. package/dist/shared/sqlite.d.ts +2 -0
  105. package/dist/shared/sqlite.d.ts.map +1 -1
  106. package/dist/shared/user-facing-codes.d.ts +2 -2
  107. package/dist/{sqlite-j3tvg8r0.js → sqlite-4pqyynrs.js} +3 -1
  108. package/dist/{storage-memory-8168bgef.js → storage-memory-j3v3hc83.js} +2 -2
  109. package/dist/{storage-tags-61z5j2f9.js → storage-tags-a513rkj3.js} +5 -5
  110. package/dist/{transform-postprocess-phase-7qts7h54.js → transform-postprocess-phase-yv463b7y.js} +30 -30
  111. package/dist/v2/auto-search-worker.js +6 -6
  112. package/dist/v2/{compaction-marker-candidates-6nypjkpf.js → compaction-marker-candidates-a15w3mqh.js} +3 -3
  113. package/dist/v2/compaction-marker-candidates-worker.js +2 -2
  114. package/dist/v2/{context-xq4rtywr.js → context-wd82v9z6.js} +137 -68
  115. package/dist/v2/{derive-budgets-enckmg7y.js → derive-budgets-0rmpmxjw.js} +3 -3
  116. package/dist/v2/embedding-backfill-vr7wdtrf.js +20 -0
  117. package/dist/v2/embedding-worker-process.js +6 -2
  118. package/dist/v2/embedding-worker.js +6 -5
  119. package/dist/v2/hidden-completion.d.ts.map +1 -1
  120. package/dist/v2/history-owner-2cr9py37.js +243 -0
  121. package/dist/v2/hooks/context.d.ts.map +1 -1
  122. package/dist/v2/hooks/store.d.ts +1 -0
  123. package/dist/v2/hooks/store.d.ts.map +1 -1
  124. package/dist/v2/{logger-pj02s7sr.js → logger-te6e1j72.js} +1 -1
  125. package/dist/v2/{message-index-bounded-5vh1h2g7.js → message-index-bounded-madg2kfr.js} +16 -16
  126. package/dist/v2/{message-index-8e5z2xx8.js → message-index-yd94vt9n.js} +16 -16
  127. package/dist/v2/{message-time-backfill-2z365239.js → message-time-backfill-rz1pnpaj.js} +3 -3
  128. package/dist/v2/migration-worker.js +11 -11
  129. package/dist/v2/{project-embedding-registry-b77awytr.js → project-embedding-registry-ja23aygk.js} +11 -11
  130. package/dist/v2/raw-ordinal-warmup-worker.js +6 -6
  131. package/dist/v2/{read-session-chunk-4sat83cx.js → read-session-chunk-7qs791f3.js} +11 -11
  132. package/dist/v2/{read-session-raw-a3hw9jsp.js → read-session-raw-h4azh85b.js} +3 -3
  133. package/dist/v2/recomp-orchestrator-ee91r9s6.js +59 -0
  134. package/dist/v2/{safe-notification-target-y3p1hce9.js → safe-notification-target-936374xx.js} +2 -2
  135. package/dist/v2/search-pn15rr52.js +46 -0
  136. package/dist/v2/{send-session-notification-ppgc8qdz.js → send-session-notification-6n7chhyp.js} +6 -6
  137. package/dist/v2/{server-v4fwha43.js → server-08k4zkfk.js} +48 -38
  138. package/dist/v2/{server-ras2sxnc.js → server-44ryn9rb.js} +9 -6
  139. package/dist/v2/{server-fw31krgq.js → server-4easnf78.js} +19 -19
  140. package/dist/v2/{server-hcvcxzx7.js → server-4gz0xkrc.js} +5 -5
  141. package/dist/v2/{server-d6g4whc2.js → server-4qr18rfg.js} +3 -3
  142. package/dist/v2/{server-sy4b1sra.js → server-4rs8sm06.js} +5 -5
  143. package/dist/v2/{server-brhj8qtd.js → server-63ha7f0f.js} +3 -27
  144. package/dist/v2/{server-3t0q2cqx.js → server-7dv9wt9r.js} +1 -1
  145. package/dist/v2/{server-cw6521wn.js → server-7e087rvk.js} +2 -0
  146. package/dist/v2/{server-hb6xhh9q.js → server-988cqjme.js} +6 -3
  147. package/dist/v2/{server-fpqe39as.js → server-9a6bwc12.js} +4 -4
  148. package/dist/v2/{server-t4k4qexw.js → server-9e5r8y60.js} +5 -1
  149. package/dist/v2/{server-7ekna9zs.js → server-adfte03x.js} +2 -2
  150. package/dist/v2/{server-qcw43339.js → server-ak7w74j9.js} +4 -4
  151. package/dist/v2/{server-dd0nja67.js → server-bx59ezg6.js} +4 -3
  152. package/dist/v2/{server-676xw7at.js → server-ckrb5rm8.js} +1 -1
  153. package/dist/{index-w4mw92w3.js → v2/server-cxsr0ng6.js} +15 -3
  154. package/dist/v2/{server-t528t8qm.js → server-hn9fb3v0.js} +2 -2
  155. package/dist/v2/{server-7srtwsa4.js → server-j3dm74ey.js} +9 -9
  156. package/dist/v2/{server-w3zeywp1.js → server-jjsf29aq.js} +4 -4
  157. package/dist/v2/server-knvkbfvh.js +25 -0
  158. package/dist/v2/{server-9yyqq3mm.js → server-n78avt2p.js} +1 -1
  159. package/dist/v2/{server-kdrezdy0.js → server-njnx39q2.js} +6 -3
  160. package/dist/v2/{server-x08d1xf3.js → server-npm52h2q.js} +4 -3
  161. package/dist/v2/{server-vb7pbd9p.js → server-nveratm5.js} +1 -1
  162. package/dist/v2/{server-mv1w7t6z.js → server-q360kdb8.js} +77 -38
  163. package/dist/v2/{server-kzns2hbz.js → server-s6jqh8bj.js} +1 -1
  164. package/dist/v2/{server-6byqfbqf.js → server-shme41gj.js} +1 -1
  165. package/dist/v2/{server-j8epsc0g.js → server-wafzvyhg.js} +33 -10
  166. package/dist/v2/{server-gtv9wbhq.js → server-xj4mewze.js} +81 -58
  167. package/dist/v2/{server-nfan6zb6.js → server-y5g32dhq.js} +31 -24
  168. package/dist/v2/{server-jdwd03ep.js → server-yak3sxya.js} +7 -7
  169. package/dist/v2/{server-wkdgjjch.js → server-zrwaj29a.js} +2 -2
  170. package/dist/v2/server.js +7 -6
  171. package/dist/v2/{sqlite-j3tvg8r0.js → sqlite-4pqyynrs.js} +3 -1
  172. package/dist/v2/{storage-memory-8168bgef.js → storage-memory-j3v3hc83.js} +2 -2
  173. package/dist/v2/{storage-tags-j2fzq3sw.js → storage-tags-spa92sgj.js} +5 -5
  174. package/dist/v2/store-reader.d.ts.map +1 -1
  175. package/dist/v2/{wrapup-orchestrator-s92ebfzv.js → wrapup-orchestrator-5wxy1ggv.js} +38 -35
  176. package/dist/wrapup-orchestrator-gv08c6f9.js +47 -0
  177. package/package.json +1 -1
  178. package/src/config/compaction-accessor-guard.test.ts +3 -0
  179. package/src/features/magic-context/dreamer/cron.ts +8 -0
  180. package/src/shared/history-owner.test.ts +60 -0
  181. package/src/shared/history-owner.ts +43 -0
  182. package/src/shared/host-stall-profiler-node.ts +3 -1
  183. package/src/shared/host-stall-profiler.ts +3 -1
  184. package/src/shared/off-thread-migration-clock.test.ts +80 -10
  185. package/src/shared/off-thread-migration-clock.ts +37 -13
  186. package/src/shared/redaction.test.ts +16 -0
  187. package/src/shared/redaction.ts +8 -1
  188. package/src/shared/root-async-context.probe.mjs +36 -0
  189. package/src/shared/root-async-context.test.ts +49 -0
  190. package/src/shared/rpc-server.ts +27 -23
  191. package/src/shared/sqlite-busy-budget-review.test.ts +291 -0
  192. package/src/shared/sqlite-foreground-wait.test.ts +253 -1
  193. package/src/shared/sqlite.ts +55 -14
  194. package/src/shared/user-facing-codes.ts +2 -2
  195. package/dist/embedding-backfill-re16xncd.js +0 -21
  196. package/dist/recomp-orchestrator-trcgmm23.js +0 -60
  197. package/dist/v2/embedding-backfill-xd9ygzgd.js +0 -20
  198. package/dist/v2/recomp-orchestrator-n11zv1f1.js +0 -59
  199. package/dist/v2/search-mvgqtkkz.js +0 -46
  200. package/dist/wrapup-orchestrator-df61jmz9.js +0 -47
@@ -1,8 +1,8 @@
1
1
  import"./server-pavzsdc6.js";
2
2
  import {
3
3
  sessionLog2
4
- } from "./server-t4k4qexw.js";
5
- import"./server-1rfgbjfn.js";
4
+ } from "./server-9e5r8y60.js";
5
+ import"./server-cxsr0ng6.js";
6
6
  import {
7
7
  COMPARTMENT_LEASE_RENEWAL_MS,
8
8
  acquireCompartmentLease,
@@ -19,13 +19,15 @@ import {
19
19
  registerActiveCompartmentRun,
20
20
  setRecompStarting2,
21
21
  setRecompTerminal2
22
- } from "./server-mv1w7t6z.js";
23
- import"./server-kzns2hbz.js";
24
- import"./server-hb6xhh9q.js";
25
- import"./server-j8epsc0g.js";
26
- import"./server-brhj8qtd.js";
27
- import"./server-fpqe39as.js";
28
- import"./server-7srtwsa4.js";
22
+ } from "./server-q360kdb8.js";
23
+ import"./server-s6jqh8bj.js";
24
+ import"./server-988cqjme.js";
25
+ import {
26
+ inRootAsyncContext2
27
+ } from "./server-wafzvyhg.js";
28
+ import"./server-63ha7f0f.js";
29
+ import"./server-9a6bwc12.js";
30
+ import"./server-j3dm74ey.js";
29
31
  import {
30
32
  getWrapupInProgressState,
31
33
  acquireWrapupInProgress,
@@ -34,40 +36,40 @@ import {
34
36
  getHistorianFailureState,
35
37
  clearEmergencyRecovery,
36
38
  prepareRawSessionOrdinals2
37
- } from "./server-gtv9wbhq.js";
38
- import"./server-6byqfbqf.js";
39
- import"./server-v4fwha43.js";
39
+ } from "./server-xj4mewze.js";
40
+ import"./server-shme41gj.js";
41
+ import"./server-08k4zkfk.js";
40
42
  import"./server-1zx87sdm.js";
41
- import"./server-w3zeywp1.js";
42
- import"./server-cw6521wn.js";
43
+ import"./server-jjsf29aq.js";
44
+ import"./server-7e087rvk.js";
43
45
  import"./server-51779zs2.js";
44
- import"./server-dd0nja67.js";
46
+ import"./server-bx59ezg6.js";
45
47
  import"./server-2ra6pwf3.js";
46
- import"./server-wkdgjjch.js";
47
- import"./server-7ekna9zs.js";
48
+ import"./server-zrwaj29a.js";
49
+ import"./server-adfte03x.js";
48
50
  import"./server-fr0wbhdn.js";
49
- import"./server-hcvcxzx7.js";
50
- import"./server-kdrezdy0.js";
51
- import"./server-fw31krgq.js";
51
+ import"./server-4gz0xkrc.js";
52
+ import"./server-njnx39q2.js";
53
+ import"./server-4easnf78.js";
52
54
  import"./server-fb3zxn06.js";
53
- import"./server-jdwd03ep.js";
55
+ import"./server-yak3sxya.js";
54
56
  import {
55
57
  pushNotification2
56
58
  } from "./server-x8a7jmkh.js";
57
- import"./server-x08d1xf3.js";
59
+ import"./server-npm52h2q.js";
58
60
  import"./server-qt1qqasc.js";
59
61
  import"./server-4dhv7mqz.js";
60
- import"./server-ras2sxnc.js";
61
- import"./server-sy4b1sra.js";
62
- import"./server-9yyqq3mm.js";
63
- import"./server-d6g4whc2.js";
64
- import"./server-vb7pbd9p.js";
65
- import"./server-t528t8qm.js";
66
- import"./server-676xw7at.js";
62
+ import"./server-44ryn9rb.js";
63
+ import"./server-4rs8sm06.js";
64
+ import"./server-n78avt2p.js";
65
+ import"./server-4qr18rfg.js";
66
+ import"./server-nveratm5.js";
67
+ import"./server-hn9fb3v0.js";
68
+ import"./server-ckrb5rm8.js";
67
69
  import {
68
70
  sendStatusNotification2
69
- } from "./server-qcw43339.js";
70
- import"./server-3t0q2cqx.js";
71
+ } from "./server-ak7w74j9.js";
72
+ import"./server-7dv9wt9r.js";
71
73
 
72
74
  // src/hooks/magic-context/wrapup-orchestrator.ts
73
75
  import * as crypto from "node:crypto";
@@ -190,7 +192,7 @@ async function runOneWrapupIteration(args) {
190
192
  if (!acquired.ok)
191
193
  return { ran: false, reason: acquired.reason };
192
194
  const leaseHolderId = acquired.holderId;
193
- const renewal = setInterval(() => {
195
+ const renewal = inRootAsyncContext2(() => setInterval(() => {
194
196
  try {
195
197
  if (!renewCompartmentLease(ctx.db, sessionId, leaseHolderId)) {
196
198
  sessionLog2(sessionId, "wrapup: compartment lease renewal failed");
@@ -198,7 +200,7 @@ async function runOneWrapupIteration(args) {
198
200
  } catch (err) {
199
201
  sessionLog2(sessionId, `wrapup: compartment lease renewal threw; continuing (${err instanceof Error ? err.message : String(err)})`);
200
202
  }
201
- }, COMPARTMENT_LEASE_RENEWAL_MS);
203
+ }, COMPARTMENT_LEASE_RENEWAL_MS));
202
204
  const runCompartmentAgentForWrapup = ctx.runCompartmentAgentForWrapup ?? runCompartmentAgent;
203
205
  const runnerPromise = runCompartmentAgentForWrapup({
204
206
  client: ctx.client,
@@ -208,6 +210,7 @@ async function runOneWrapupIteration(args) {
208
210
  sessionId,
209
211
  historianChunkTokens: ctx.historianChunkTokens,
210
212
  historianTimeoutMs: ctx.historianTimeoutMs,
213
+ historianMaxOutputTokens: ctx.historianMaxOutputTokens,
211
214
  boundarySnapshot: plan.snapshot,
212
215
  currentContextLimit: ctx.contextLimit,
213
216
  directory: ctx.directory,
@@ -315,7 +318,7 @@ ${message}`;
315
318
  }
316
319
  return true;
317
320
  };
318
- const markerRenewal = setInterval(() => {
321
+ const markerRenewal = inRootAsyncContext2(() => setInterval(() => {
319
322
  try {
320
323
  renewWrapupMarker({
321
324
  lastCompartmentEnd: getLastCompartmentEndMessage(ctx.db, sessionId),
@@ -324,7 +327,7 @@ ${message}`;
324
327
  } catch (err) {
325
328
  sessionLog2(sessionId, `wrapup: marker renewal threw; continuing (${err instanceof Error ? err.message : String(err)})`);
326
329
  }
327
- }, 60000);
330
+ }, 60000));
328
331
  markerRenewal.unref?.();
329
332
  try {
330
333
  const activeAtStart = await waitForExistingIncrementalRun(sessionId, resolveWrapupLeaseWaitTimeout(ctx));
@@ -0,0 +1,47 @@
1
+ import {
2
+ runManagedWrapup2
3
+ } from "./index-pjgzdezw.js";
4
+ import"./index-xf6k8szp.js";
5
+ import"./index-hxrvx6cy.js";
6
+ import"./index-s178h9z8.js";
7
+ import"./index-ydjgz36f.js";
8
+ import"./index-b4gcb3rk.js";
9
+ import"./index-sd3egckz.js";
10
+ import"./index-a43xq1pg.js";
11
+ import"./index-n78avt2p.js";
12
+ import"./index-rg1cezmj.js";
13
+ import"./index-7bjgyaj1.js";
14
+ import"./index-4dhv7mqz.js";
15
+ import"./index-jw4gbfkv.js";
16
+ import"./index-pgy3h49n.js";
17
+ import"./index-qt1qqasc.js";
18
+ import"./index-x8a7jmkh.js";
19
+ import"./index-a4b0gbyg.js";
20
+ import"./index-bmwfzz28.js";
21
+ import"./index-kvw6xew3.js";
22
+ import"./index-zf9nydbd.js";
23
+ import"./index-qgp5vnt4.js";
24
+ import"./index-fb3zxn06.js";
25
+ import"./index-fr0wbhdn.js";
26
+ import"./index-0jz47061.js";
27
+ import"./index-mp2kghkv.js";
28
+ import"./index-q28hsbpg.js";
29
+ import"./index-9g1c4bt9.js";
30
+ import"./index-xpn05jxq.js";
31
+ import"./index-1zx87sdm.js";
32
+ import"./index-q76br5zn.js";
33
+ import"./index-angx1s0k.js";
34
+ import"./index-v0p37hm2.js";
35
+ import"./index-w28y7d0z.js";
36
+ import"./index-8kk7yh6m.js";
37
+ import"./index-bd9cjab3.js";
38
+ import"./index-58e3y90n.js";
39
+ import"./index-150zz6fh.js";
40
+ import"./index-gjvjh960.js";
41
+ import"./index-wafzvyhg.js";
42
+ import"./index-mvvephtj.js";
43
+ import"./index-0sahzkwr.js";
44
+ import"./index-pavzsdc6.js";
45
+ export {
46
+ runManagedWrapup2 as runManagedWrapup
47
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-magic-context",
3
- "version": "0.49.7",
3
+ "version": "0.49.8",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",
@@ -32,6 +32,9 @@ const ALLOWED_READERS = new Set<string>([
32
32
  "packages/cli/src/lib/omp-helpers.ts",
33
33
  "packages/cli/src/commands/setup-omp.ts",
34
34
  "packages/cli/src/commands/doctor-omp.ts",
35
+ // The privacy projection recognizes the setting's name in diagnostic text;
36
+ // it never reads the parsed configuration value.
37
+ "packages/cli/src/lib/issue-privacy.ts",
35
38
  ]);
36
39
 
37
40
  function sourceFiles(directory: string): string[] {
@@ -61,6 +61,13 @@ const MINUTE_MS = 60_000;
61
61
  */
62
62
  const MAX_SEARCH_MS = 4 * 366 * 24 * 60 * MINUTE_MS;
63
63
 
64
+ let candidateVisitsForTests: (() => void) | undefined;
65
+
66
+ /** Count searched minutes in tests without affecting normal cron callers. */
67
+ export function __setCronCandidateVisitCounterForTests(counter?: () => void): void {
68
+ candidateVisitsForTests = counter;
69
+ }
70
+
64
71
  /** Parse one field into the set of matching values, or null on error. */
65
72
  function parseField(token: string, spec: FieldSpec): Set<number> | null {
66
73
  const values = new Set<number>();
@@ -226,6 +233,7 @@ export function nextOccurrence(
226
233
  const capMs = afterMs + Math.max(0, Math.min(MAX_SEARCH_MS, maxSearchMs));
227
234
 
228
235
  while (cursorMs <= capMs) {
236
+ candidateVisitsForTests?.();
229
237
  const candidate = new Date(cursorMs);
230
238
  if (matchesCron(cron, candidate)) {
231
239
  if (!excludeCivilMinute || civilMinuteKey(candidate) !== excludeCivilMinute) {
@@ -0,0 +1,60 @@
1
+ import { expect, test } from "bun:test";
2
+ import { handoffHistoryWork } from "./history-owner";
3
+ import type { MagicContextRpcClient } from "./rpc-client";
4
+
5
+ test("moved-session recomp is handed to the current directory before local work starts", async () => {
6
+ const calls: unknown[] = [];
7
+ const result = await handoffHistoryWork({
8
+ storageDir: "/isolated/mc",
9
+ directory: "/old",
10
+ sessionId: "session",
11
+ method: "recomp",
12
+ params: { sessionId: "session" },
13
+ readDirectory: async () => "/new",
14
+ findOwner: async () =>
15
+ ({
16
+ call: async (...args: unknown[]) => {
17
+ calls.push(args);
18
+ return { ok: true };
19
+ },
20
+ }) as unknown as MagicContextRpcClient,
21
+ });
22
+ expect(result).toEqual({ ok: true });
23
+ expect(calls).toEqual([
24
+ ["recomp", { sessionId: "session", directory: "/new", historyHandoff: true }],
25
+ ]);
26
+ });
27
+
28
+ test("moved-session recovery explains how to load a missing owner and stops handoff loops", async () => {
29
+ for (const historyHandoff of [false, true]) {
30
+ const result = await handoffHistoryWork({
31
+ storageDir: "/isolated/mc",
32
+ directory: "/old",
33
+ sessionId: "session",
34
+ method: "wrapup",
35
+ params: { sessionId: "session", historyHandoff },
36
+ readDirectory: async () => "/new",
37
+ findOwner: async () => null,
38
+ });
39
+ expect(result?.ok).toBe(false);
40
+ expect(result?.error).toContain(
41
+ "Reopen this session in its current project directory (/new)",
42
+ );
43
+ }
44
+ });
45
+
46
+ test("history recovery remains local when the host still reports this directory", async () => {
47
+ expect(
48
+ await handoffHistoryWork({
49
+ storageDir: "/isolated/mc",
50
+ directory: "/project",
51
+ sessionId: "session",
52
+ method: "recomp",
53
+ params: {},
54
+ readDirectory: async () => "/project",
55
+ findOwner: async () => {
56
+ throw new Error("must not discover");
57
+ },
58
+ }),
59
+ ).toBeUndefined();
60
+ });
@@ -0,0 +1,43 @@
1
+ import { sameProjectDirectory } from "./project-directory-key";
2
+ import { MagicContextRpcClient } from "./rpc-client";
3
+
4
+ /** History-compression children need the current project plugin's prompt and recognition of their run IDs. */
5
+ export async function handoffHistoryWork(args: {
6
+ storageDir: string;
7
+ directory: string;
8
+ sessionId: string;
9
+ method: string;
10
+ params: Record<string, unknown>;
11
+ readDirectory: () => Promise<string | null>;
12
+ findOwner?: typeof MagicContextRpcClient.findSessionOwner;
13
+ }): Promise<Record<string, unknown> | undefined> {
14
+ const current = await args.readDirectory();
15
+ if (current && sameProjectDirectory(current, args.directory)) return undefined;
16
+ const action = `Reopen this session in its current project directory${current ? ` (${current})` : ""}, then run /ctx-recomp.`;
17
+ if (!current || args.params.historyHandoff === true)
18
+ return {
19
+ ok: false,
20
+ error: `History recovery could not locate a stable owning instance. ${action}`,
21
+ };
22
+ const owner = await (args.findOwner ?? MagicContextRpcClient.findSessionOwner)(
23
+ args.storageDir,
24
+ args.sessionId,
25
+ );
26
+ if (!owner)
27
+ return {
28
+ ok: false,
29
+ error: `History recovery needs the instance for ${current}. ${action}`,
30
+ };
31
+ try {
32
+ return await owner.call(args.method, {
33
+ ...args.params,
34
+ directory: current,
35
+ historyHandoff: true,
36
+ });
37
+ } catch {
38
+ return {
39
+ ok: false,
40
+ error: `The owning instance could not accept history recovery. ${action}`,
41
+ };
42
+ }
43
+ }
@@ -224,7 +224,7 @@ export function createNodeHostStallProfiler(deps: NodeProfilerDeps): HostStallPr
224
224
  const api = await deps.createSession();
225
225
  if (stopped || !existsSync(enablePath)) return;
226
226
  session = api;
227
- api.connect();
227
+ inRootAsyncContext(() => api.connect());
228
228
  await post(api, "Profiler.enable");
229
229
  await post(api, "Profiler.setSamplingInterval", {
230
230
  interval: Math.round(options.sampleIntervalMs * 1000),
@@ -272,3 +272,5 @@ export function createNodeHostStallProfiler(deps: NodeProfilerDeps): HostStallPr
272
272
  isUnavailable: () => unavailable,
273
273
  };
274
274
  }
275
+
276
+ import { inRootAsyncContext } from "./sqlite";
@@ -29,7 +29,7 @@ export function startHostStallProfilerSwitch(): void {
29
29
  now: () => performance.now(),
30
30
  wallNow: () => Date.now(),
31
31
  setInterval: (callback, ms) => {
32
- const handle = setInterval(callback, ms);
32
+ const handle = inRootAsyncContext(() => setInterval(callback, ms));
33
33
  (handle as { unref?: () => void }).unref?.();
34
34
  return handle;
35
35
  },
@@ -55,3 +55,5 @@ export function startHostStallProfilerSwitch(): void {
55
55
  log("[magic-context] host stall profiler: could not start the enable-file switch", error);
56
56
  }
57
57
  }
58
+
59
+ import { inRootAsyncContext } from "./sqlite";
@@ -1,6 +1,7 @@
1
1
  import { afterEach, describe, expect, test } from "bun:test";
2
2
  import {
3
3
  __resetOffThreadMigrationClockForTests,
4
+ __setOffThreadMigrationClockForTests,
4
5
  beginOffThreadMigration,
5
6
  startBootDeadline,
6
7
  } from "./off-thread-migration-clock";
@@ -11,6 +12,49 @@ async function expiredWithin(promise: Promise<void>, ms: number): Promise<boolea
11
12
  return Promise.race([promise.then(() => true), sleep(ms).then(() => false)]);
12
13
  }
13
14
 
15
+ function createFakeClock() {
16
+ let now = 0;
17
+ let nextTimerId = 0;
18
+ const timers = new Map<number, { at: number; callback: () => void }>();
19
+ let timerCountWaiter: { count: number; resolve: () => void } | undefined;
20
+
21
+ return {
22
+ now: () => now,
23
+ setTimeout: (callback: () => void, delayMs: number) => {
24
+ const id = ++nextTimerId;
25
+ timers.set(id, { at: now + Math.max(0, delayMs), callback });
26
+ if (timerCountWaiter?.count === timers.size) {
27
+ timerCountWaiter.resolve();
28
+ timerCountWaiter = undefined;
29
+ }
30
+ return () => {
31
+ timers.delete(id);
32
+ };
33
+ },
34
+ advanceBy: (ms: number) => {
35
+ now += ms;
36
+ while (true) {
37
+ const next = [...timers.entries()].sort(
38
+ (left, right) => left[1].at - right[1].at,
39
+ )[0];
40
+ if (!next || next[1].at > now) return;
41
+ timers.delete(next[0]);
42
+ next[1].callback();
43
+ }
44
+ },
45
+ waitForTimerCount: (count: number) => {
46
+ if (timers.size === count) return Promise.resolve();
47
+ return new Promise<void>((resolve) => {
48
+ timerCountWaiter = { count, resolve };
49
+ });
50
+ },
51
+ };
52
+ }
53
+
54
+ async function isSettled(promise: Promise<void>): Promise<boolean> {
55
+ return Promise.race([promise.then(() => true), Promise.resolve(false)]);
56
+ }
57
+
14
58
  describe("boot deadline that excludes off-thread migration time", () => {
15
59
  afterEach(() => __resetOffThreadMigrationClockForTests());
16
60
 
@@ -19,32 +63,58 @@ describe("boot deadline that excludes off-thread migration time", () => {
19
63
  expect(await expiredWithin(deadline.expired, 500)).toBe(true);
20
64
  });
21
65
 
22
- test("does not expire while a migration runs, and resumes counting afterwards", async () => {
66
+ test("does not count migration time and resumes with only the pre-migration time spent", async () => {
67
+ const clock = createFakeClock();
68
+ __setOffThreadMigrationClockForTests(clock);
23
69
  let deferred = 0;
70
+ let signalDeferred!: () => void;
71
+ const wasDeferred = new Promise<void>((resolve) => {
72
+ signalDeferred = resolve;
73
+ });
24
74
  const deadline = startBootDeadline(40, () => {
25
75
  deferred += 1;
76
+ signalDeferred();
26
77
  });
78
+ clock.advanceBy(15);
27
79
  const end = beginOffThreadMigration();
28
- expect(await expiredWithin(deadline.expired, 150)).toBe(false);
80
+ clock.advanceBy(25);
81
+ await wasDeferred;
29
82
  expect(deferred).toBe(1);
30
83
 
31
- const endedAt = performance.now();
84
+ clock.advanceBy(1_000_000);
85
+ expect(await isSettled(deadline.expired)).toBe(false);
86
+
87
+ const nextTimer = clock.waitForTimerCount(1).then(() => "scheduled" as const);
32
88
  end();
89
+ expect(
90
+ await Promise.race([nextTimer, deadline.expired.then(() => "expired" as const)]),
91
+ ).toBe("scheduled");
92
+
93
+ clock.advanceBy(24);
94
+ expect(await isSettled(deadline.expired)).toBe(false);
95
+ clock.advanceBy(1);
33
96
  await deadline.expired;
34
- // Only the few milliseconds before the migration began were counted, so
35
- // nearly the whole 40ms budget is still left once it ends.
36
- expect(performance.now() - endedAt).toBeGreaterThanOrEqual(25);
37
97
  });
38
98
 
39
99
  test("time between migrations still counts", async () => {
100
+ const clock = createFakeClock();
101
+ __setOffThreadMigrationClockForTests(clock);
40
102
  const deadline = startBootDeadline(60);
41
- await sleep(40);
103
+ clock.advanceBy(40);
42
104
  const end = beginOffThreadMigration();
43
- await sleep(80);
105
+ clock.advanceBy(80);
106
+ expect(await isSettled(deadline.expired)).toBe(false);
107
+
108
+ const nextTimer = clock.waitForTimerCount(1).then(() => "scheduled" as const);
44
109
  end();
45
- const endedAt = performance.now();
110
+ expect(
111
+ await Promise.race([nextTimer, deadline.expired.then(() => "expired" as const)]),
112
+ ).toBe("scheduled");
113
+
114
+ clock.advanceBy(19);
115
+ expect(await isSettled(deadline.expired)).toBe(false);
116
+ clock.advanceBy(1);
46
117
  await deadline.expired;
47
- expect(performance.now() - endedAt).toBeLessThan(45);
48
118
  });
49
119
 
50
120
  test("a cancelled deadline never expires", async () => {
@@ -19,9 +19,26 @@ let activeSince = 0;
19
19
  let accumulatedMs = 0;
20
20
  let idleWaiters: Array<() => void> = [];
21
21
 
22
+ interface TestClock {
23
+ now(): number;
24
+ setTimeout(callback: () => void, delayMs: number): () => void;
25
+ }
26
+
27
+ let testClock: TestClock | undefined;
28
+
29
+ function now(): number {
30
+ return testClock?.now() ?? performance.now();
31
+ }
32
+
33
+ function scheduleTimeout(callback: () => void, delayMs: number): () => void {
34
+ if (testClock) return testClock.setTimeout(callback, delayMs);
35
+ const timer = setTimeout(callback, delayMs);
36
+ return () => clearTimeout(timer);
37
+ }
38
+
22
39
  /** Total milliseconds any off-thread migration has been running, up to `now`. */
23
- export function offThreadMigrationMs(now = performance.now()): number {
24
- return accumulatedMs + (activeMigrations > 0 ? Math.max(0, now - activeSince) : 0);
40
+ export function offThreadMigrationMs(at = now()): number {
41
+ return accumulatedMs + (activeMigrations > 0 ? Math.max(0, at - activeSince) : 0);
25
42
  }
26
43
 
27
44
  export function isOffThreadMigrationRunning(): boolean {
@@ -33,7 +50,7 @@ export function isOffThreadMigrationRunning(): boolean {
33
50
  * end; calling it more than once has no further effect.
34
51
  */
35
52
  export function beginOffThreadMigration(): () => void {
36
- if (activeMigrations === 0) activeSince = performance.now();
53
+ if (activeMigrations === 0) activeSince = now();
37
54
  activeMigrations += 1;
38
55
  let ended = false;
39
56
  return () => {
@@ -41,7 +58,7 @@ export function beginOffThreadMigration(): () => void {
41
58
  ended = true;
42
59
  activeMigrations -= 1;
43
60
  if (activeMigrations > 0) return;
44
- accumulatedMs += Math.max(0, performance.now() - activeSince);
61
+ accumulatedMs += Math.max(0, now() - activeSince);
45
62
  const waiters = idleWaiters;
46
63
  idleWaiters = [];
47
64
  for (const wake of waiters) wake();
@@ -66,10 +83,10 @@ export interface BootDeadlineTimer {
66
83
  * still running.
67
84
  */
68
85
  export function startBootDeadline(timeoutMs: number, onDeferred?: () => void): BootDeadlineTimer {
69
- const startedAt = performance.now();
86
+ const startedAt = now();
70
87
  const migratedAtStart = offThreadMigrationMs(startedAt);
71
88
  const budgetMs = Math.max(0, timeoutMs);
72
- let timer: ReturnType<typeof setTimeout> | undefined;
89
+ let cancelTimer: (() => void) | undefined;
73
90
  let cancelled = false;
74
91
  let deferredReported = false;
75
92
  let resolveExpired!: () => void;
@@ -78,13 +95,14 @@ export function startBootDeadline(timeoutMs: number, onDeferred?: () => void): B
78
95
  });
79
96
 
80
97
  const remainingMs = (): number => {
81
- const now = performance.now();
82
- const countedMs = now - startedAt - (offThreadMigrationMs(now) - migratedAtStart);
98
+ const currentTime = now();
99
+ const countedMs =
100
+ currentTime - startedAt - (offThreadMigrationMs(currentTime) - migratedAtStart);
83
101
  return budgetMs - countedMs;
84
102
  };
85
103
 
86
104
  const check = (): void => {
87
- timer = undefined;
105
+ cancelTimer = undefined;
88
106
  if (cancelled) return;
89
107
  if (isOffThreadMigrationRunning()) {
90
108
  if (!deferredReported) {
@@ -96,28 +114,34 @@ export function startBootDeadline(timeoutMs: number, onDeferred?: () => void): B
96
114
  }
97
115
  const left = remainingMs();
98
116
  if (left > 0) {
99
- timer = setTimeout(check, left);
117
+ cancelTimer = scheduleTimeout(check, left);
100
118
  return;
101
119
  }
102
120
  resolveExpired();
103
121
  };
104
122
 
105
- timer = setTimeout(check, budgetMs);
123
+ cancelTimer = scheduleTimeout(check, budgetMs);
106
124
  return {
107
125
  expired,
108
126
  cancel: () => {
109
127
  cancelled = true;
110
- if (timer) clearTimeout(timer);
111
- timer = undefined;
128
+ cancelTimer?.();
129
+ cancelTimer = undefined;
112
130
  },
113
131
  };
114
132
  }
115
133
 
134
+ /** Inject deterministic time and timers in tests; production uses host APIs. */
135
+ export function __setOffThreadMigrationClockForTests(clock?: TestClock): void {
136
+ testClock = clock;
137
+ }
138
+
116
139
  /** Test seam: forget accumulated migration time between isolated tests. */
117
140
  export function __resetOffThreadMigrationClockForTests(): void {
118
141
  activeMigrations = 0;
119
142
  activeSince = 0;
120
143
  accumulatedMs = 0;
144
+ testClock = undefined;
121
145
  const waiters = idleWaiters;
122
146
  idleWaiters = [];
123
147
  for (const wake of waiters) wake();
@@ -132,3 +132,19 @@ describe("redaction gaps: unambiguous secret key names and header/URL credential
132
132
  expect(apiKey).toContain("x-api-key");
133
133
  });
134
134
  });
135
+
136
+ describe("public diagnostic credential shapes", () => {
137
+ test("redacts unquoted colon credentials without removing scalar diagnostics", () => {
138
+ expect(redactSecretText("password: colonSecret700 token: anotherSecret700")).toBe(
139
+ "password: <REDACTED:credential> token: <REDACTED:credential>",
140
+ );
141
+ expect(redactSecretText("token: 1234567 secret: false")).toBe(
142
+ "token: 1234567 secret: false",
143
+ );
144
+ });
145
+ test("redacts hyphenated and underscored GitHub token payloads completely", () => {
146
+ expect(redactSecretText("ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-extra_payload")).toBe(
147
+ "<GITHUB_TOKEN_REDACTED>",
148
+ );
149
+ });
150
+ });
@@ -152,7 +152,7 @@ const SECRET_TEXT_PATTERNS: Array<{
152
152
  replacement: "<GITHUB_PAT_REDACTED>",
153
153
  },
154
154
  {
155
- pattern: /\b(?:gh[opsu]|ghr)_[A-Za-z0-9]{30,}/g,
155
+ pattern: /\b(?:gh[opsu]|ghr)_[A-Za-z0-9_-]{30,}/g,
156
156
  replacement: "<GITHUB_TOKEN_REDACTED>",
157
157
  },
158
158
  {
@@ -190,6 +190,13 @@ const SECRET_TEXT_PATTERNS: Array<{
190
190
  replacement: (full: string, prefix: string, value: string) =>
191
191
  isNonSecretScalarValue(value) ? full : `${prefix}<REDACTED:api_key>`,
192
192
  },
193
+ {
194
+ // Unquoted diagnostic prose also uses colon-delimited credentials.
195
+ pattern:
196
+ /\b((?:api[_-]?key|client[_-]?secret|access[_-]?token|token|secret|password|passwd|pwd)\s*:\s*)([^\s'"`,;<>]{6,})/gi,
197
+ replacement: (full: string, prefix: string, value: string) =>
198
+ isNonSecretScalarValue(value) ? full : `${prefix}<REDACTED:credential>`,
199
+ },
193
200
  {
194
201
  // Credentials embedded in a URL: scheme://user:password@host.
195
202
  pattern: /\b([a-z][a-z0-9+.-]*:\/\/[^\s/:@]+:)([^\s/@]+)(@)/gi,