@cortexkit/opencode-magic-context 0.46.1 → 0.48.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 (462) hide show
  1. package/dist/agents/magic-context-prompt.d.ts +1 -1
  2. package/dist/agents/magic-context-prompt.d.ts.map +1 -1
  3. package/dist/{announcement-y35wzg2r.js → announcement-fp14dw0n.js} +3 -2
  4. package/dist/auto-search-worker.js +112 -0
  5. package/dist/config/index.d.ts.map +1 -1
  6. package/dist/config/live-run-config.d.ts.map +1 -1
  7. package/dist/config/migrate-config-location.d.ts.map +1 -1
  8. package/dist/config/mural-model-deprecation.d.ts +15 -0
  9. package/dist/config/mural-model-deprecation.d.ts.map +1 -0
  10. package/dist/config/project-security.d.ts +0 -3
  11. package/dist/config/project-security.d.ts.map +1 -1
  12. package/dist/config/schema/magic-context.d.ts +21 -9
  13. package/dist/config/schema/magic-context.d.ts.map +1 -1
  14. package/dist/{conflict-warning-hook-7fj2b9jw.js → conflict-warning-hook-w8cykrnf.js} +12 -9
  15. package/dist/{context-sh2m2vde.js → context-m0cy262m.js} +1785 -913
  16. package/dist/{derive-budgets-7nj7r1rv.js → derive-budgets-sg0xsq7s.js} +4 -3
  17. package/dist/embedding-activity-g1dhes6g.js +10 -0
  18. package/dist/embedding-backfill-9rcm1mfy.js +21 -0
  19. package/dist/embedding-cache-mgyr73ef.js +16 -0
  20. package/dist/embedding-worker.js +11 -9
  21. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +1 -0
  23. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  24. package/dist/features/magic-context/dreamer/task-config.d.ts +3 -3
  25. package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
  26. package/dist/features/magic-context/dreamer/task-executor.d.ts +1 -1
  27. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  28. package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
  29. package/dist/features/magic-context/dreamer/task-registry.d.ts +1 -0
  30. package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
  31. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  32. package/dist/features/magic-context/message-index-async.d.ts +16 -3
  33. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  34. package/dist/features/magic-context/message-index-bounded.d.ts +17 -0
  35. package/dist/features/magic-context/message-index-bounded.d.ts.map +1 -0
  36. package/dist/features/magic-context/message-index.d.ts +7 -1
  37. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  38. package/dist/features/magic-context/mural/render-trigger.d.ts +7 -4
  39. package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
  40. package/dist/features/magic-context/overflow-detection.d.ts +2 -0
  41. package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
  42. package/dist/features/magic-context/pi-content-decisions.d.ts +7 -1
  43. package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -1
  44. package/dist/features/magic-context/project-embedding-registry.d.ts +7 -0
  45. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  46. package/dist/features/magic-context/search.d.ts +31 -0
  47. package/dist/features/magic-context/search.d.ts.map +1 -1
  48. package/dist/features/magic-context/session-activity.d.ts.map +1 -1
  49. package/dist/features/magic-context/session-project-storage.d.ts +8 -2
  50. package/dist/features/magic-context/session-project-storage.d.ts.map +1 -1
  51. package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
  52. package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
  53. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  54. package/dist/features/magic-context/storage-historian-runs.d.ts +2 -5
  55. package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
  56. package/dist/features/magic-context/storage-meta-persisted.d.ts +12 -0
  57. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  58. package/dist/features/magic-context/storage-meta-session.d.ts +6 -0
  59. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  60. package/dist/features/magic-context/storage-tag-identity-revision.d.ts +30 -0
  61. package/dist/features/magic-context/storage-tag-identity-revision.d.ts.map +1 -0
  62. package/dist/features/magic-context/storage-tags.d.ts +148 -3
  63. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  64. package/dist/features/magic-context/storage.d.ts +1 -0
  65. package/dist/features/magic-context/storage.d.ts.map +1 -1
  66. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
  67. package/dist/features/magic-context/transform-decision-log.d.ts +4 -2
  68. package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
  69. package/dist/harness-e4avh192.js +10 -0
  70. package/dist/hooks/magic-context/active-anthropic-turn.d.ts +10 -0
  71. package/dist/hooks/magic-context/active-anthropic-turn.d.ts.map +1 -0
  72. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  73. package/dist/hooks/magic-context/auto-search-blocking.fixture.d.ts +2 -0
  74. package/dist/hooks/magic-context/auto-search-blocking.fixture.d.ts.map +1 -0
  75. package/dist/hooks/magic-context/auto-search-deadline.d.ts +7 -0
  76. package/dist/hooks/magic-context/auto-search-deadline.d.ts.map +1 -1
  77. package/dist/hooks/magic-context/auto-search-host-review.fixture.d.ts +3 -0
  78. package/dist/hooks/magic-context/auto-search-host-review.fixture.d.ts.map +1 -0
  79. package/dist/hooks/magic-context/auto-search-lock-review.fixture.d.ts +2 -0
  80. package/dist/hooks/magic-context/auto-search-lock-review.fixture.d.ts.map +1 -0
  81. package/dist/hooks/magic-context/auto-search-long-lock-review.fixture.d.ts +2 -0
  82. package/dist/hooks/magic-context/auto-search-long-lock-review.fixture.d.ts.map +1 -0
  83. package/dist/hooks/magic-context/auto-search-omp-host-review.fixture.d.ts +4 -0
  84. package/dist/hooks/magic-context/auto-search-omp-host-review.fixture.d.ts.map +1 -0
  85. package/dist/hooks/magic-context/auto-search-omp-loader.fixture.d.ts +3 -0
  86. package/dist/hooks/magic-context/auto-search-omp-loader.fixture.d.ts.map +1 -0
  87. package/dist/hooks/magic-context/auto-search-runner.d.ts +1 -1
  88. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  89. package/dist/hooks/magic-context/auto-search-snapshot.fixture.d.ts +4 -0
  90. package/dist/hooks/magic-context/auto-search-snapshot.fixture.d.ts.map +1 -0
  91. package/dist/hooks/magic-context/auto-search-worker-client.d.ts +98 -0
  92. package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -0
  93. package/dist/hooks/magic-context/auto-search-worker.d.ts +2 -0
  94. package/dist/hooks/magic-context/auto-search-worker.d.ts.map +1 -0
  95. package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
  96. package/dist/hooks/magic-context/command-handler.d.ts +1 -0
  97. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  98. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  99. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  100. package/dist/hooks/magic-context/compartment-runner-types.d.ts +3 -5
  101. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  102. package/dist/hooks/magic-context/compartment-runner.d.ts +2 -1
  103. package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
  104. package/dist/hooks/magic-context/compartment-trigger.d.ts +3 -1
  105. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  106. package/dist/hooks/magic-context/event-handler.d.ts +1 -1
  107. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  108. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  109. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  110. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +2 -0
  111. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
  112. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  113. package/dist/hooks/magic-context/historian-drain-gate.d.ts +11 -0
  114. package/dist/hooks/magic-context/historian-drain-gate.d.ts.map +1 -0
  115. package/dist/hooks/magic-context/hook.d.ts +3 -2
  116. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  117. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  118. package/dist/hooks/magic-context/latest-assistant-turn.d.ts +25 -0
  119. package/dist/hooks/magic-context/latest-assistant-turn.d.ts.map +1 -0
  120. package/dist/hooks/magic-context/latest-thinking-recovery.d.ts +61 -0
  121. package/dist/hooks/magic-context/latest-thinking-recovery.d.ts.map +1 -0
  122. package/dist/hooks/magic-context/lkg-persist.d.ts +4 -3
  123. package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
  124. package/dist/hooks/magic-context/lkg-replay.d.ts +13 -8
  125. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  126. package/dist/hooks/magic-context/lkg-slot.d.ts +139 -2
  127. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  128. package/dist/hooks/magic-context/message-search-accepting-silent-worker.fixture.d.ts +2 -0
  129. package/dist/hooks/magic-context/message-search-accepting-silent-worker.fixture.d.ts.map +1 -0
  130. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  131. package/dist/hooks/magic-context/oc-stall-r2-warmup-worker.fixture.d.ts +2 -0
  132. package/dist/hooks/magic-context/oc-stall-r2-warmup-worker.fixture.d.ts.map +1 -0
  133. package/dist/hooks/magic-context/oc-stall-search-review.fixture.d.ts +2 -0
  134. package/dist/hooks/magic-context/oc-stall-search-review.fixture.d.ts.map +1 -0
  135. package/dist/hooks/magic-context/opencode-proven-floor.d.ts +6 -0
  136. package/dist/hooks/magic-context/opencode-proven-floor.d.ts.map +1 -0
  137. package/dist/hooks/magic-context/opencode1-to-model-messages.fixture.d.ts +63 -0
  138. package/dist/hooks/magic-context/opencode1-to-model-messages.fixture.d.ts.map +1 -0
  139. package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
  140. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  141. package/dist/hooks/magic-context/provider-visible-parts.d.ts +45 -0
  142. package/dist/hooks/magic-context/provider-visible-parts.d.ts.map +1 -0
  143. package/dist/hooks/magic-context/raw-ordinal-warmup-silent-worker.fixture.d.ts +2 -0
  144. package/dist/hooks/magic-context/raw-ordinal-warmup-silent-worker.fixture.d.ts.map +1 -0
  145. package/dist/hooks/magic-context/raw-ordinal-warmup-worker.d.ts +2 -0
  146. package/dist/hooks/magic-context/raw-ordinal-warmup-worker.d.ts.map +1 -0
  147. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts +87 -0
  148. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -0
  149. package/dist/hooks/magic-context/read-session-chunk.d.ts +12 -0
  150. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  151. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  152. package/dist/hooks/magic-context/read-session-formatting.d.ts +5 -0
  153. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  154. package/dist/hooks/magic-context/read-session-raw.d.ts +83 -1
  155. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  156. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  157. package/dist/hooks/magic-context/reasoning-budget-status.d.ts +15 -0
  158. package/dist/hooks/magic-context/reasoning-budget-status.d.ts.map +1 -0
  159. package/dist/hooks/magic-context/reasoning-budget.d.ts +40 -0
  160. package/dist/hooks/magic-context/reasoning-budget.d.ts.map +1 -0
  161. package/dist/hooks/magic-context/reasoning-removal.d.ts +6 -6
  162. package/dist/hooks/magic-context/reasoning-removal.d.ts.map +1 -1
  163. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  164. package/dist/hooks/magic-context/sentinel.d.ts +45 -1
  165. package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
  166. package/dist/hooks/magic-context/strip-content.d.ts +21 -5
  167. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  168. package/dist/hooks/magic-context/system-prompt-hash.d.ts +1 -0
  169. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  170. package/dist/hooks/magic-context/tag-messages.d.ts +21 -0
  171. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  172. package/dist/hooks/magic-context/tag-owner-warmup.d.ts +6 -0
  173. package/dist/hooks/magic-context/tag-owner-warmup.d.ts.map +1 -0
  174. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  175. package/dist/hooks/magic-context/token-count-exact.d.ts +35 -0
  176. package/dist/hooks/magic-context/token-count-exact.d.ts.map +1 -0
  177. package/dist/hooks/magic-context/tool-drop-target.d.ts +5 -0
  178. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  179. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +3 -28
  180. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  181. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +28 -6
  182. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  183. package/dist/hooks/magic-context/transform.d.ts +11 -3
  184. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  185. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  186. package/dist/{index-hpecdzec.js → index-0an7742d.js} +6820 -6587
  187. package/dist/index-0qhce371.js +120 -0
  188. package/dist/{index-q6hef7fh.js → index-0sahzkwr.js} +6 -19
  189. package/dist/{index-k5bdx1bx.js → index-0w56v4fm.js} +3 -5
  190. package/dist/index-14cjxt20.js +819 -0
  191. package/dist/{v2/server-51dv1pr5.js → index-1qb0z7wa.js} +301 -27
  192. package/dist/index-2bvekkfy.js +11 -0
  193. package/dist/{index-sj29b3z2.js → index-2y0s2hep.js} +3 -3
  194. package/dist/index-4dhv7mqz.js +131 -0
  195. package/dist/{index-b35pxds2.js → index-58e3y90n.js} +1 -18
  196. package/dist/index-5zygecde.js +152 -0
  197. package/dist/{index-sjthx78w.js → index-692jzy0p.js} +16879 -22907
  198. package/dist/index-72nhv486.js +2307 -0
  199. package/dist/index-7jzrrxap.js +931 -0
  200. package/dist/index-7mx8v0pw.js +3591 -0
  201. package/dist/index-8ajstryz.js +18 -0
  202. package/dist/{index-sfpzqvdz.js → index-8cd2j99z.js} +2 -3
  203. package/dist/{index-hybnrwq0.js → index-8j7gqj40.js} +131 -128
  204. package/dist/index-bdckkfw6.js +3261 -0
  205. package/dist/{index-8x2v7gg9.js → index-bhvjj0ys.js} +158 -2455
  206. package/dist/index-c43kr12f.js +3030 -0
  207. package/dist/index-cb7emxgj.js +984 -0
  208. package/dist/index-d9vfe7xq.js +16 -0
  209. package/dist/{index-5gq3b2ya.js → index-db7zwa3v.js} +147 -209
  210. package/dist/index-dhwzyd54.js +1142 -0
  211. package/dist/{index-8da2zjhz.js → index-eeezr5zz.js} +9 -7
  212. package/dist/{index-pkbcrdqs.js → index-f0h6xwqm.js} +3412 -4552
  213. package/dist/index-fb3zxn06.js +13 -0
  214. package/dist/index-fbv1dn35.js +171 -0
  215. package/dist/index-fr0wbhdn.js +43 -0
  216. package/dist/{index-mc22ayvf.js → index-ghc9f0n7.js} +11 -9
  217. package/dist/{index-fzbvakh0.js → index-jcbd3znx.js} +3 -3
  218. package/dist/{index-5p8jdswx.js → index-k1xb52kd.js} +20 -13
  219. package/dist/index-k9nnwad5.js +3532 -0
  220. package/dist/{v2/server-fg34g6a5.js → index-kb9nn0a0.js} +309 -52
  221. package/dist/index-knh4y330.js +566 -0
  222. package/dist/{index-q4yp4b52.js → index-mfkzp7qj.js} +28 -28
  223. package/dist/{index-sgthv3f7.js → index-mmyh6d8f.js} +4 -4
  224. package/dist/index-pavzsdc6.js +17 -0
  225. package/dist/{index-0d3g3461.js → index-pdecwzrd.js} +19 -16
  226. package/dist/index-pg50n748.js +1060 -0
  227. package/dist/index-q2tqeqde.js +2106 -0
  228. package/dist/index-q7h7csab.js +3469 -0
  229. package/dist/index-qt1qqasc.js +22 -0
  230. package/dist/{index-majxda46.js → index-ty64eqcn.js} +28 -18
  231. package/dist/{index-7qw742ev.js → index-yq8n9qcb.js} +25 -44
  232. package/dist/{index-sfnj6h8h.js → index-z8e0psj8.js} +20 -20
  233. package/dist/index.d.ts.map +1 -1
  234. package/dist/index.js +1061 -260
  235. package/dist/logger-d3wex3dz.js +20 -0
  236. package/dist/message-index-bounded-7ezbgddp.js +124 -0
  237. package/dist/{v2/message-time-backfill-r6qkem1x.js → message-time-backfill-brbd63hv.js} +8 -6
  238. package/dist/migration-worker.js +25 -16
  239. package/dist/{model-resolution-xhfmyyvy.js → model-resolution-nx97z3x7.js} +1 -1
  240. package/dist/plugin/dream-timer.d.ts +1 -1
  241. package/dist/plugin/dream-timer.d.ts.map +1 -1
  242. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -1
  243. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  244. package/dist/plugin/host-stall-profiler-report.d.ts +2 -0
  245. package/dist/plugin/host-stall-profiler-report.d.ts.map +1 -0
  246. package/dist/plugin/host-stall-profiler.d.ts +3 -0
  247. package/dist/plugin/host-stall-profiler.d.ts.map +1 -0
  248. package/dist/plugin/messages-transform.d.ts +21 -19
  249. package/dist/plugin/messages-transform.d.ts.map +1 -1
  250. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  251. package/dist/plugin/tool-registry.d.ts.map +1 -1
  252. package/dist/project-embedding-registry-7qzptcw7.js +88 -0
  253. package/dist/raw-ordinal-warmup-worker.js +60 -0
  254. package/dist/{read-session-chunk-egz7r68d.js → read-session-chunk-6k83m4fj.js} +15 -9
  255. package/dist/read-session-raw-3g9qy1xa.js +58 -0
  256. package/dist/recomp-orchestrator-d3fp1cy0.js +57 -0
  257. package/dist/{v2/safe-notification-target-eb1n1vfb.js → safe-notification-target-5ffqq32m.js} +4 -2
  258. package/dist/search-epax1ecv.js +45 -0
  259. package/dist/{v2/send-session-notification-qs0j78v6.js → send-session-notification-erecz4y4.js} +10 -6
  260. package/dist/shared/auto-search-lifecycle.d.ts +7 -0
  261. package/dist/shared/auto-search-lifecycle.d.ts.map +1 -0
  262. package/dist/shared/conflict-detector.d.ts.map +1 -1
  263. package/dist/shared/historian-tool-expansions.d.ts +1 -1
  264. package/dist/shared/historian-tool-expansions.d.ts.map +1 -1
  265. package/dist/shared/historian-tool-template.d.ts +2 -2
  266. package/dist/shared/historian-tool-template.d.ts.map +1 -1
  267. package/dist/shared/host-stall-profiler-bun.d.ts +46 -0
  268. package/dist/shared/host-stall-profiler-bun.d.ts.map +1 -0
  269. package/dist/shared/host-stall-profiler-common.d.ts +58 -0
  270. package/dist/shared/host-stall-profiler-common.d.ts.map +1 -0
  271. package/dist/shared/host-stall-profiler-node.d.ts +36 -0
  272. package/dist/shared/host-stall-profiler-node.d.ts.map +1 -0
  273. package/dist/shared/host-stall-profiler-report.d.ts +68 -0
  274. package/dist/shared/host-stall-profiler-report.d.ts.map +1 -0
  275. package/dist/shared/host-stall-profiler.d.ts +5 -0
  276. package/dist/shared/host-stall-profiler.d.ts.map +1 -0
  277. package/dist/shared/model-resolution.d.ts +2 -3
  278. package/dist/shared/model-resolution.d.ts.map +1 -1
  279. package/dist/shared/sqlite.d.ts +46 -1
  280. package/dist/shared/sqlite.d.ts.map +1 -1
  281. package/dist/shared/stable-json.d.ts.map +1 -1
  282. package/dist/shared/status-view.d.ts.map +1 -1
  283. package/dist/shared/user-facing-codes.d.ts +0 -5
  284. package/dist/shared/user-facing-codes.d.ts.map +1 -1
  285. package/dist/shared/window-geometry.d.ts +4 -0
  286. package/dist/shared/window-geometry.d.ts.map +1 -1
  287. package/dist/sqlite-context-pragmas-mv9jqwjh.js +6 -0
  288. package/dist/sqlite-mhjkerzq.js +46 -0
  289. package/dist/storage-memory-07fx57k6.js +71 -0
  290. package/dist/storage-tags-d3b0v2ss.js +131 -0
  291. package/dist/{task-config-v81k8jvk.js → task-config-cgpg0nvh.js} +2 -2
  292. package/dist/tools/ctx-expand/render.d.ts.map +1 -1
  293. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  294. package/dist/tools/ctx-note/constants.d.ts +4 -0
  295. package/dist/tools/ctx-note/constants.d.ts.map +1 -1
  296. package/dist/tools/ctx-note/tools.d.ts +1 -0
  297. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  298. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  299. package/dist/tools/parameter-descriptions.d.ts +2 -2
  300. package/dist/tools/parameter-descriptions.d.ts.map +1 -1
  301. package/dist/{transform-postprocess-phase-bqhz6vdr.js → transform-postprocess-phase-spcy2qre.js} +35 -17
  302. package/dist/transformers-node-wasm.js +18415 -18415
  303. package/dist/v2/auto-search-worker.js +112 -0
  304. package/dist/v2/{context-zecmzk5s.js → context-sf98kstd.js} +8378 -8530
  305. package/dist/v2/{derive-budgets-kdgp4s3r.js → derive-budgets-3vc0y84t.js} +4 -3
  306. package/dist/v2/embedding-activity-g1dhes6g.js +10 -0
  307. package/dist/v2/embedding-backfill-vn8g1nh1.js +21 -0
  308. package/dist/v2/embedding-cache-mgyr73ef.js +16 -0
  309. package/dist/v2/embedding-worker.js +12 -9
  310. package/dist/v2/fold/host-media.d.ts +4 -0
  311. package/dist/v2/fold/host-media.d.ts.map +1 -1
  312. package/dist/v2/fold/memory-cache.d.ts +70 -0
  313. package/dist/v2/fold/memory-cache.d.ts.map +1 -0
  314. package/dist/v2/fold/native-codec.d.ts +10 -0
  315. package/dist/v2/fold/native-codec.d.ts.map +1 -0
  316. package/dist/v2/fold/native-replay.d.ts +58 -0
  317. package/dist/v2/fold/native-replay.d.ts.map +1 -0
  318. package/dist/v2/fold/policy.d.ts +24 -0
  319. package/dist/v2/fold/policy.d.ts.map +1 -0
  320. package/dist/v2/harness-e4avh192.js +10 -0
  321. package/dist/v2/hidden-completion.d.ts.map +1 -1
  322. package/dist/v2/hooks/context.d.ts +2 -2
  323. package/dist/v2/hooks/context.d.ts.map +1 -1
  324. package/dist/v2/hooks/dream-manual.d.ts +1 -1
  325. package/dist/v2/hooks/dream-manual.d.ts.map +1 -1
  326. package/dist/v2/hooks/dream-timer.d.ts.map +1 -1
  327. package/dist/v2/hooks/dream-trigger.d.ts +1 -2
  328. package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
  329. package/dist/v2/hooks/payload.d.ts.map +1 -1
  330. package/dist/v2/hooks/tools.d.ts.map +1 -1
  331. package/dist/v2/hooks/types.d.ts +6 -0
  332. package/dist/v2/hooks/types.d.ts.map +1 -1
  333. package/dist/v2/logger-mxd0ym09.js +19 -0
  334. package/dist/v2/message-index-bounded-dy3s2k1e.js +123 -0
  335. package/dist/{message-time-backfill-68gj6t3e.js → v2/message-time-backfill-gtx1pwk1.js} +7 -7
  336. package/dist/v2/migration-worker.js +24 -15
  337. package/dist/v2/{model-resolution-xhfmyyvy.js → model-resolution-nx97z3x7.js} +1 -1
  338. package/dist/v2/project-embedding-registry-1tgba5dv.js +86 -0
  339. package/dist/v2/raw-ordinal-warmup-worker.js +60 -0
  340. package/dist/v2/{read-session-chunk-8vjp6581.js → read-session-chunk-rh4khdkv.js} +14 -8
  341. package/dist/v2/read-session-raw-bsbmf0vj.js +57 -0
  342. package/dist/v2/recomp-orchestrator-az61rfcg.js +57 -0
  343. package/dist/{safe-notification-target-43r8jsxw.js → v2/safe-notification-target-73ax1p5v.js} +3 -3
  344. package/dist/v2/search-nzkwrc6n.js +45 -0
  345. package/dist/{send-session-notification-dyw42dtr.js → v2/send-session-notification-6km439kn.js} +9 -7
  346. package/dist/{index-5eqk6z3s.js → v2/server-1r6pmz4f.js} +301 -27
  347. package/dist/v2/server-2bvekkfy.js +11 -0
  348. package/dist/v2/server-2fbhp79z.js +3205 -0
  349. package/dist/v2/{server-ajzeteqw.js → server-2ra6pwf3.js} +1 -18
  350. package/dist/v2/server-4dhv7mqz.js +131 -0
  351. package/dist/v2/{server-xa4xe3rv.js → server-4k748ke6.js} +11 -1053
  352. package/dist/v2/{server-vs5gpnd4.js → server-52awr2mw.js} +81 -145
  353. package/dist/v2/{server-1qbnzc80.js → server-5m3dt5r1.js} +136 -148
  354. package/dist/v2/server-686jg6eb.js +3508 -0
  355. package/dist/v2/server-7jzrrxap.js +931 -0
  356. package/dist/v2/server-7wwc2nga.js +3023 -0
  357. package/dist/v2/server-8ajstryz.js +18 -0
  358. package/dist/v2/{server-sfpzqvdz.js → server-8cd2j99z.js} +2 -3
  359. package/dist/v2/server-8pyt7hev.js +3408 -0
  360. package/dist/v2/server-8tqanswc.js +984 -0
  361. package/dist/v2/{server-14vq4kpm.js → server-aan4q8mx.js} +3 -3
  362. package/dist/v2/server-d9vfe7xq.js +16 -0
  363. package/dist/v2/server-e0vdaae2.js +3591 -0
  364. package/dist/v2/server-ezhze64f.js +1048 -0
  365. package/dist/v2/server-fb3zxn06.js +13 -0
  366. package/dist/v2/server-fr0wbhdn.js +43 -0
  367. package/dist/v2/server-g5r0n3b6.js +1137 -0
  368. package/dist/v2/server-gjcr4w98.js +154 -0
  369. package/dist/v2/server-k228xhjg.js +171 -0
  370. package/dist/v2/{server-jc7y02q0.js → server-k8x2rbxc.js} +5119 -10948
  371. package/dist/{index-fg34g6a5.js → v2/server-kb9nn0a0.js} +309 -52
  372. package/dist/v2/{server-g0fjrkta.js → server-mfkzp7qj.js} +28 -28
  373. package/dist/v2/server-pavzsdc6.js +17 -0
  374. package/dist/v2/server-psqc7e9n.js +2106 -0
  375. package/dist/v2/server-qt1qqasc.js +22 -0
  376. package/dist/v2/server-qye6ykf7.js +120 -0
  377. package/dist/v2/{server-qdjnb2z1.js → server-r5p3b1wy.js} +11 -9
  378. package/dist/v2/server-sggvvzhb.js +759 -0
  379. package/dist/v2/{server-y8maxeft.js → server-v06jcv0w.js} +16 -13
  380. package/dist/v2/server-vqpf3167.js +1048 -0
  381. package/dist/v2/{server-c5gz8wph.js → server-x2g40a71.js} +2048 -2059
  382. package/dist/v2/{server-wvjvfhck.js → server-xdfwt6kh.js} +20 -16
  383. package/dist/v2/{server-mcfawjgc.js → server-xxm59eww.js} +25 -44
  384. package/dist/v2/server-yczc713m.js +564 -0
  385. package/dist/v2/{server-3n4q9xme.js → server-z2037m6z.js} +4 -4
  386. package/dist/v2/{server-e29d7p7c.js → server-zm570tr2.js} +166 -160
  387. package/dist/v2/{server-6r257mf5.js → server-zxhgvsf9.js} +3 -3
  388. package/dist/v2/server.js +16 -14
  389. package/dist/v2/sqlite-context-pragmas-mv9jqwjh.js +6 -0
  390. package/dist/v2/sqlite-mhjkerzq.js +46 -0
  391. package/dist/v2/storage-memory-07fx57k6.js +71 -0
  392. package/dist/v2/storage-tags-w4tv77sn.js +130 -0
  393. package/dist/v2/store-reader.d.ts +16 -0
  394. package/dist/v2/store-reader.d.ts.map +1 -1
  395. package/dist/v2/{task-config-tbndqyny.js → task-config-x0hq3qfd.js} +2 -2
  396. package/dist/v2/transformers-node-wasm.js +18415 -18415
  397. package/dist/v2/tui/index.d.ts.map +1 -1
  398. package/dist/v2/tui/types.d.ts +1 -10
  399. package/dist/v2/tui/types.d.ts.map +1 -1
  400. package/dist/v2/{wrapup-orchestrator-0snhvwcv.js → wrapup-orchestrator-mz7efs7w.js} +51 -27
  401. package/dist/wrapup-orchestrator-amzta1t4.js +44 -0
  402. package/package.json +4 -3
  403. package/src/agents/magic-context-prompt.ts +27 -2
  404. package/src/agents/smart-notes-enabled.test.ts +294 -0
  405. package/src/agents/smart-notes-on.golden.json +70 -0
  406. package/src/config/index.test.ts +67 -1
  407. package/src/config/index.ts +8 -0
  408. package/src/config/latch-permanence-guard.test.ts +4 -0
  409. package/src/config/live-run-config.test.ts +37 -1
  410. package/src/config/live-run-config.ts +28 -0
  411. package/src/config/migrate-config-location.ts +10 -3
  412. package/src/config/mural-model-deprecation.ts +24 -0
  413. package/src/config/project-security.hostile-matrix.test.ts +4 -44
  414. package/src/config/project-security.test.ts +9 -14
  415. package/src/config/project-security.ts +13 -55
  416. package/src/config/schema/magic-context.test.ts +6 -5
  417. package/src/config/schema/magic-context.ts +34 -16
  418. package/src/features/magic-context/dreamer/task-registry.ts +6 -0
  419. package/src/shared/auto-search-lifecycle.ts +27 -0
  420. package/src/shared/conflict-detector.test.ts +56 -0
  421. package/src/shared/conflict-detector.ts +16 -5
  422. package/src/shared/historian-tool-defaults.json +6 -6
  423. package/src/shared/historian-tool-expansions.ts +65 -8
  424. package/src/shared/historian-tool-preview-defaults.json +13 -0
  425. package/src/shared/historian-tool-template.ts +48 -14
  426. package/src/shared/host-stall-profiler-bun.ts +358 -0
  427. package/src/shared/host-stall-profiler-common.ts +159 -0
  428. package/src/shared/host-stall-profiler-node.test.ts +234 -0
  429. package/src/shared/host-stall-profiler-node.ts +274 -0
  430. package/src/shared/host-stall-profiler-report.ts +248 -0
  431. package/src/shared/host-stall-profiler.ts +57 -0
  432. package/src/shared/model-resolution.test.ts +54 -17
  433. package/src/shared/model-resolution.ts +6 -17
  434. package/src/shared/sqlite-640-review-r2.test.ts +136 -0
  435. package/src/shared/sqlite-640-review.test.ts +183 -0
  436. package/src/shared/sqlite-acquisition-routing.test.ts +18 -0
  437. package/src/shared/sqlite.test.ts +52 -0
  438. package/src/shared/sqlite.ts +423 -37
  439. package/src/shared/stable-json-linear.test.ts +109 -0
  440. package/src/shared/stable-json.ts +37 -7
  441. package/src/shared/status-view.test.ts +6 -1
  442. package/src/shared/status-view.ts +15 -1
  443. package/src/shared/tag-transcript.ts +6 -0
  444. package/src/shared/user-facing-codes.ts +2 -6
  445. package/src/shared/window-geometry.ts +10 -0
  446. package/src/shared/write-transaction-attribution.test.ts +2 -2
  447. package/src/v2/tui/host-contract.test.ts +41 -67
  448. package/src/v2/tui/index.ts +6 -214
  449. package/src/v2/tui/types.ts +5 -17
  450. package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts +0 -45
  451. package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts.map +0 -1
  452. package/dist/features/magic-context/checkout-claim.d.ts +0 -155
  453. package/dist/features/magic-context/checkout-claim.d.ts.map +0 -1
  454. package/dist/index-3h0ybwah.js +0 -6540
  455. package/dist/index-r5hmbx3t.js +0 -7773
  456. package/dist/recomp-orchestrator-y15j0rb9.js +0 -39
  457. package/dist/v2/recomp-orchestrator-8ejxvrzz.js +0 -39
  458. package/dist/v2/server-frbm99q5.js +0 -7698
  459. package/dist/v2/server-qp5hx1ad.js +0 -6366
  460. package/dist/wrapup-orchestrator-39amhv9s.js +0 -26
  461. /package/dist/{index-en1k8h8m.js → index-2pp04pmg.js} +0 -0
  462. /package/dist/v2/{index-en1k8h8m.js → index-2pp04pmg.js} +0 -0
@@ -41,6 +41,7 @@
41
41
 
42
42
  import { AsyncLocalStorage } from "node:async_hooks";
43
43
  import { statSync } from "node:fs";
44
+
44
45
  // Type import only — runtime is loaded dynamically below. @types/better-sqlite3
45
46
  // has the richest definitions and is a structural superset of the API surface
46
47
  // we use, so calls typed against BetterSqlite3 work under bun:sqlite and
@@ -169,13 +170,51 @@ export class SqliteRuntimeUnavailableError extends Error {
169
170
  }
170
171
  }
171
172
 
173
+ // Node requests this warning during node:sqlite's module evaluation, although
174
+ // warning delivery happens later. Intercept only the request while importing;
175
+ // replacing warning listeners would not suppress the default stderr output.
176
+ function isNodeSqliteExperimentalWarning(args: unknown[]): boolean {
177
+ const [warning, options] = args;
178
+ const message = warning instanceof Error ? warning.message : warning;
179
+ const type =
180
+ typeof options === "string"
181
+ ? options
182
+ : options && typeof options === "object"
183
+ ? (options as { type?: unknown }).type
184
+ : undefined;
185
+ return (
186
+ type === "ExperimentalWarning" &&
187
+ typeof message === "string" &&
188
+ message.startsWith("SQLite is an experimental feature")
189
+ );
190
+ }
191
+
192
+ async function importSqliteModuleForRuntime(
193
+ runtime: SqliteRuntime,
194
+ specifier: string,
195
+ importer: (specifier: string) => Promise<SqliteModule>,
196
+ ): Promise<SqliteModule> {
197
+ if (runtime !== "Node.js") return importer(specifier);
198
+
199
+ const originalEmitWarning = process.emitWarning;
200
+ process.emitWarning = function (this: unknown, ...args: unknown[]): void {
201
+ if (isNodeSqliteExperimentalWarning(args)) return;
202
+ Reflect.apply(originalEmitWarning, this, args);
203
+ } as typeof process.emitWarning;
204
+ try {
205
+ return await importer(specifier);
206
+ } finally {
207
+ process.emitWarning = originalEmitWarning;
208
+ }
209
+ }
210
+
172
211
  export async function loadSqliteModule(
173
212
  runtime: SqliteRuntime = detectSqliteRuntime(),
174
213
  importer: (specifier: string) => Promise<SqliteModule> = importSqliteModule,
175
214
  ): Promise<SqliteModule> {
176
215
  const specifier = runtime === "Bun" ? bunSpec : nodeSpec;
177
216
  try {
178
- return await importer(specifier);
217
+ return await importSqliteModuleForRuntime(runtime, specifier, importer);
179
218
  } catch (error) {
180
219
  if (isModuleNotFoundError(error, specifier)) {
181
220
  throw new SqliteRuntimeUnavailableError(runtime, specifier, error);
@@ -234,6 +273,110 @@ export interface SqliteMemoryStats {
234
273
  const trackedSqliteConnections = new Map<number, TrackedSqliteConnection>();
235
274
  let nextSqliteConnectionSequence = 1;
236
275
 
276
+ /**
277
+ * Columns of Magic Context's `tags` table (context.db) that never decide which
278
+ * message a tag belongs to, its number, its type, or its reasoning token estimate.
279
+ */
280
+ const TAG_COLUMNS_OUTSIDE_IDENTITY = new Set([
281
+ "status",
282
+ "drop_mode",
283
+ "byte_size",
284
+ "input_byte_size",
285
+ "reasoning_byte_size",
286
+ "token_count",
287
+ "input_token_count",
288
+ "caveman_depth",
289
+ "entry_fingerprint",
290
+ "tool_name",
291
+ "harness",
292
+ ]);
293
+
294
+ let tagIdentityWriteGeneration = 0;
295
+
296
+ /**
297
+ * Whether a write statement may change an existing `tags` row's identity
298
+ * (session, number, type, owner message, reasoning token count) or remove a
299
+ * row. Plain appends without an explicit `id`, and updates that assign only
300
+ * columns in {@link TAG_COLUMNS_OUTSIDE_IDENTITY}, cannot; everything else that
301
+ * names the table is treated as if it could, including DDL and multi-statement
302
+ * scripts. Erring towards true only costs a cache rebuild.
303
+ */
304
+ export function mayChangeTagIdentity(sql: string): boolean {
305
+ if (!/\btags\b/i.test(sql) || /^\s*(?:SELECT|EXPLAIN|PRAGMA)\b/i.test(sql)) return false;
306
+ if (/^\s*WITH\b/i.test(sql) && !/\b(?:INSERT|UPDATE|DELETE|REPLACE)\b/i.test(sql)) return false;
307
+ // One statement only: a script can hide a DELETE behind a harmless first statement.
308
+ if (/;\s*\S/.test(sql) || /\bREPLACE\b/i.test(sql) || /\bON\s+CONFLICT\b/i.test(sql))
309
+ return true;
310
+ const insert = /^\s*INSERT\s+INTO\s+(?:main\.)?["`]?tags["`]?\s*\(([^)]*)\)/i.exec(sql);
311
+ if (insert) {
312
+ const columns = (insert[1] ?? "").split(",").map((column) =>
313
+ column
314
+ .trim()
315
+ .replace(/["`[\]]/g, "")
316
+ .toLowerCase(),
317
+ );
318
+ return columns.includes("id") || columns.includes("rowid");
319
+ }
320
+ const update = /^\s*UPDATE\s+(?:main\.)?["`]?tags["`]?\s+SET\s+([\s\S]*?)\bWHERE\b/i.exec(sql);
321
+ if (update && !/\bSELECT\b/i.test(sql)) {
322
+ // Provably identity-free only when every top-level assignment is a plain
323
+ // `column = ...` naming an allowed column. A tuple assignment such as
324
+ // `(tag_number, reasoning_token_count) = (...)`, or anything this cannot
325
+ // read, counts as an identity write.
326
+ const assignments = topLevelCommaSegments(update[1] ?? "");
327
+ if (!assignments) return true;
328
+ return !assignments.every((assignment) => {
329
+ const column = /^\s*["`]?(\w+)["`]?\s*=(?!=)/.exec(assignment)?.[1];
330
+ return column !== undefined && TAG_COLUMNS_OUTSIDE_IDENTITY.has(column.toLowerCase());
331
+ });
332
+ }
333
+ return true;
334
+ }
335
+
336
+ /**
337
+ * Split SQL text at commas outside parentheses and quotes. Returns null when
338
+ * the parentheses or quotes do not balance.
339
+ */
340
+ function topLevelCommaSegments(text: string): string[] | null {
341
+ const segments: string[] = [];
342
+ let depth = 0;
343
+ let quote: string | null = null;
344
+ let start = 0;
345
+ for (let index = 0; index < text.length; index += 1) {
346
+ const char = text[index];
347
+ if (quote) {
348
+ // A doubled quote inside a quoted run is an escaped quote.
349
+ if (char === quote) {
350
+ if (text[index + 1] === quote) index += 1;
351
+ else quote = null;
352
+ }
353
+ continue;
354
+ }
355
+ if (char === "'" || char === '"' || char === "`") quote = char;
356
+ else if (char === "(") depth += 1;
357
+ else if (char === ")") {
358
+ depth -= 1;
359
+ if (depth < 0) return null;
360
+ } else if (char === "," && depth === 0) {
361
+ segments.push(text.slice(start, index));
362
+ start = index + 1;
363
+ }
364
+ }
365
+ if (quote || depth !== 0) return null;
366
+ segments.push(text.slice(start));
367
+ return segments;
368
+ }
369
+
370
+ /**
371
+ * Counts executions, on any connection this process opened, of statements for
372
+ * which {@link mayChangeTagIdentity} is true. A cache built from `tags` stays
373
+ * valid for this process's own writes while the count is unchanged; commits by
374
+ * other connections show up in `PRAGMA data_version` instead.
375
+ */
376
+ export function getTagIdentityWriteGeneration(): number {
377
+ return tagIdentityWriteGeneration;
378
+ }
379
+
237
380
  /** Route native Bun and Node transaction entry through the same acquisition retry.
238
381
  * Native Bun transaction wrappers execute BEGIN internally, bypassing an exec override,
239
382
  * so both runtimes use this small synchronous wrapper instead. Writable handles
@@ -245,6 +388,7 @@ function installTransactionRouting(db: BetterSqlite3.Database, readonly: boolean
245
388
  configurable: true,
246
389
  writable: true,
247
390
  value: (sql: string) => {
391
+ if (/^\s*(?:COMMIT|END)\b/i.test(sql)) assertTransformWrite();
248
392
  if (/^\s*BEGIN\s+(?:IMMEDIATE|EXCLUSIVE)(?:\s+TRANSACTION)?\s*;?\s*$/i.test(sql)) {
249
393
  // A transaction that ended without passing through exec (for
250
394
  // example an automatic rollback) must not be timed as this one.
@@ -256,8 +400,15 @@ function installTransactionRouting(db: BetterSqlite3.Database, readonly: boolean
256
400
  }
257
401
  if (WRITER_TRANSACTION_END.test(sql) && openWriterTransactions.has(db))
258
402
  return endWriterTransaction(db, () => nativeExec(sql), sql);
259
- if (!/^\s*(?:SELECT|EXPLAIN|PRAGMA|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\b/i.test(sql))
260
- return withAutocommitTimeout(db, () => nativeExec(sql));
403
+ if (
404
+ !/^\s*(?:SELECT|EXPLAIN|PRAGMA|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\b/i.test(sql)
405
+ ) {
406
+ try {
407
+ return withAutocommitTimeout(db, () => nativeExec(sql));
408
+ } finally {
409
+ if (mayChangeTagIdentity(sql)) tagIdentityWriteGeneration += 1;
410
+ }
411
+ }
261
412
  return nativeExec(sql);
262
413
  },
263
414
  });
@@ -270,15 +421,22 @@ function installTransactionRouting(db: BetterSqlite3.Database, readonly: boolean
270
421
  // SELECT/EXPLAIN cannot acquire a writer. Treat CTEs conservatively:
271
422
  // WITH can introduce INSERT/UPDATE/DELETE as well as a read query.
272
423
  if (!readonly && !/^\s*(?:SELECT|EXPLAIN|PRAGMA)\b/i.test(sql)) {
424
+ const changesTagIdentity = mayChangeTagIdentity(sql);
273
425
  for (const method of ["run", "get", "all"] as const) {
274
426
  const execute = statement[method].bind(statement);
275
427
  Object.defineProperty(statement, method, {
276
428
  configurable: true,
277
429
  // biome-ignore lint/suspicious/noExplicitAny: retain SQLite's native binding overloads.
278
- value: (...args: any[]) =>
279
- withAutocommitTimeout(db, () => execute(...args)),
430
+ value: (...args: any[]) => {
431
+ try {
432
+ return withAutocommitTimeout(db, () => execute(...args));
433
+ } finally {
434
+ if (changesTagIdentity) tagIdentityWriteGeneration += 1;
435
+ }
436
+ },
280
437
  });
281
438
  }
439
+ if (changesTagIdentity) wrapRemainingTagWriteForms(statement);
282
440
  }
283
441
  return statement;
284
442
  },
@@ -329,6 +487,43 @@ function installTransactionRouting(db: BetterSqlite3.Database, readonly: boolean
329
487
  });
330
488
  }
331
489
 
490
+ /**
491
+ * Count tag identity writes made through the statement forms the transaction
492
+ * routing does not wrap. `iterate()` runs the statement while its result is
493
+ * consumed, so the generation moves both when iteration starts and when it
494
+ * ends: a summary read in between is then rebuilt on its next read.
495
+ */
496
+ // biome-ignore lint/suspicious/noExplicitAny: statements from both backends share these method names.
497
+ function wrapRemainingTagWriteForms(statement: any): void {
498
+ if (typeof statement.iterate === "function") {
499
+ const iterate = statement.iterate.bind(statement);
500
+ Object.defineProperty(statement, "iterate", {
501
+ configurable: true,
502
+ value: function* (...args: unknown[]) {
503
+ tagIdentityWriteGeneration += 1;
504
+ try {
505
+ yield* iterate(...args);
506
+ } finally {
507
+ tagIdentityWriteGeneration += 1;
508
+ }
509
+ },
510
+ });
511
+ }
512
+ if (typeof statement.values === "function") {
513
+ const values = statement.values.bind(statement);
514
+ Object.defineProperty(statement, "values", {
515
+ configurable: true,
516
+ value: (...args: unknown[]) => {
517
+ try {
518
+ return values(...args);
519
+ } finally {
520
+ tagIdentityWriteGeneration += 1;
521
+ }
522
+ },
523
+ });
524
+ }
525
+ }
526
+
332
527
  function trackSqliteConnection(
333
528
  db: BetterSqlite3.Database,
334
529
  filename: unknown,
@@ -430,6 +625,23 @@ function buildNodeSqliteDatabaseClass(DatabaseSync: any): typeof BetterSqlite3 {
430
625
 
431
626
  export const Database: typeof BetterSqlite3 = TrackedDatabase;
432
627
 
628
+ /** The constructor path, without querying SQLite on the prompt thread. */
629
+ export function getSqliteDatabasePath(db: Database): string | null {
630
+ for (const connection of trackedSqliteConnections.values()) {
631
+ if (connection.reference.deref() === db) {
632
+ return connection.filename === ":memory:" || connection.filename === "<buffer>"
633
+ ? null
634
+ : connection.filename;
635
+ }
636
+ }
637
+ // Native Bun/better-sqlite3 handles can reach readers without our constructor
638
+ // wrapper. Their filename is still available without a SQLite query.
639
+ const native = db as unknown as { filename?: unknown; name?: unknown };
640
+ const path = native.filename ?? native.name;
641
+ if (typeof path === "string" && path !== ":memory:" && path !== "") return path;
642
+ return null;
643
+ }
644
+
433
645
  function pragmaValue(db: BetterSqlite3.Database, name: string): unknown {
434
646
  const row = db.prepare(`PRAGMA ${name}`).get() as Record<string, unknown> | undefined;
435
647
  if (!row) return undefined;
@@ -556,6 +768,33 @@ interface StatementOwner {
556
768
  const statementOwners = new WeakMap<Database, StatementOwner>();
557
769
  const FIRST_PRUNE_AT = 256;
558
770
 
771
+ /**
772
+ * Bun's default close (`sqlite3_close_v2`) only releases the native connection
773
+ * once every statement created by prepare() is finalized. The close override
774
+ * in ownPreparedStatement can finalize only statements that are still
775
+ * reachable. Once the garbage collector
776
+ * has marked a one-shot statement dead, its weak reference is already cleared,
777
+ * but the statement is finalized only when its memory is later swept. Until
778
+ * then the closed connection keeps the database, WAL and shared-memory files
779
+ * open, for an unbounded time.
780
+ *
781
+ * `close(true)` finalizes every outstanding statement, reachable or not, and
782
+ * releases the connection immediately. When the caller did not ask for errors
783
+ * and that close fails, fall back to the caller's own close so a teardown path
784
+ * never starts throwing; the fallback can defer the release as before.
785
+ */
786
+ function closeReleasingStatements(
787
+ close: (...args: unknown[]) => unknown,
788
+ args: unknown[],
789
+ ): unknown {
790
+ if (args[0] === true) return close(true);
791
+ try {
792
+ return close(true);
793
+ } catch {
794
+ return close(...args);
795
+ }
796
+ }
797
+
559
798
  function ownPreparedStatement(db: Database, statement: Statement): Statement {
560
799
  const finalizable = statement as FinalizableStatement;
561
800
  // Node finalizes its statements on close and exposes no finalize() method.
@@ -579,7 +818,7 @@ function ownPreparedStatement(db: Database, statement: Statement): Statement {
579
818
  }
580
819
  }
581
820
  references.clear();
582
- const result = close(...args);
821
+ const result = closeReleasingStatements(close, args);
583
822
  if (failure) throw failure;
584
823
  return result;
585
824
  },
@@ -617,7 +856,12 @@ export function prepareCachedStatement(db: Database, sql: string): Statement {
617
856
 
618
857
  const privilegeDepth = new WeakMap<Database, number>();
619
858
  const transformPassScope = new AsyncLocalStorage<
620
- { active: boolean; remainingWaitMs: number } | undefined
859
+ | {
860
+ active: boolean;
861
+ remainingWaitMs: number;
862
+ guard?: { assert(): void; remainingMs(): number };
863
+ }
864
+ | undefined
621
865
  >();
622
866
  const admissionScope = new AsyncLocalStorage<boolean>();
623
867
  const backgroundWriterScope = new AsyncLocalStorage<boolean>();
@@ -632,22 +876,31 @@ export function withSqliteBackgroundWriter<T>(operation: () => T): T {
632
876
  export function withSqliteTransformPass<T>(operation: () => T): T {
633
877
  const existing = transformPassScope.getStore();
634
878
  if (existing?.active) return operation();
635
- const lease = { active: true, remainingWaitMs: FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS };
636
- return transformPassScope.run(lease, () => {
637
- try {
638
- const result = operation();
639
- if (result && typeof (result as { then?: unknown }).then === "function") {
640
- return Promise.resolve(result).finally(() => {
641
- lease.active = false;
642
- }) as T;
879
+ const reservation = reserveForegroundSqliteTurn();
880
+ const run = (release: () => void): T => {
881
+ const lease = { active: true, remainingWaitMs: FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS };
882
+ return transformPassScope.run(lease, () => {
883
+ try {
884
+ const result = operation();
885
+ if (result && typeof (result as { then?: unknown }).then === "function") {
886
+ return Promise.resolve(result).finally(() => {
887
+ lease.active = false;
888
+ release();
889
+ }) as T;
890
+ }
891
+ lease.active = false;
892
+ release();
893
+ return result;
894
+ } catch (error) {
895
+ lease.active = false;
896
+ release();
897
+ throw error;
643
898
  }
644
- lease.active = false;
645
- return result;
646
- } catch (error) {
647
- lease.active = false;
648
- throw error;
649
- }
650
- });
899
+ });
900
+ };
901
+ // Foreground callers racing maintenance are awaited transforms. Idle
902
+ // synchronous callers keep the existing immediate return/throw behavior.
903
+ return typeof reservation === "function" ? run(reservation) : (reservation.then(run) as T);
651
904
  }
652
905
 
653
906
  /** Start detached maintenance work without borrowing a foreground pass's budget. */
@@ -655,6 +908,17 @@ export function withoutSqliteTransformPass<T>(operation: () => T): T {
655
908
  return transformPassScope.run(undefined, operation);
656
909
  }
657
910
 
911
+ /** Attach the adapter's existing generation/cancellation/deadline guard to writes. */
912
+ export function guardSqliteTransformPass(guard: { assert(): void; remainingMs(): number }): void {
913
+ const lease = transformPassScope.getStore();
914
+ if (lease) lease.guard = guard;
915
+ }
916
+
917
+ /** Check the attached generation/cancellation/deadline guard before SQL or cache publication. */
918
+ export function assertTransformWrite(): void {
919
+ if (!backgroundWriterScope.getStore()) transformPassScope.getStore()?.guard?.assert();
920
+ }
921
+
658
922
  /** Bun names SQLite codes; node:sqlite exposes the numeric (possibly extended) errcode. */
659
923
  export function isTransientSqliteError(error: unknown): boolean {
660
924
  if (!error || typeof error !== "object") return false;
@@ -698,6 +962,7 @@ interface WriterAcquisition {
698
962
  startedAt: number;
699
963
  attempts: number;
700
964
  claimed: boolean;
965
+ remainingMs?: () => number;
701
966
  }
702
967
 
703
968
  /** A write transaction whose BEGIN went through `acquireShort` and has not ended yet. */
@@ -724,6 +989,7 @@ function foregroundWaitLease() {
724
989
  * native API cannot separate lock waiting from statement execution. Exhaustion
725
990
  * switches to zero-wait acquisition, not a refusal when the writer is free. */
726
991
  function withAutocommitTimeout<T>(db: Database, operation: () => T): T {
992
+ assertTransformWrite();
727
993
  const lease = foregroundWaitLease();
728
994
  if (isInTransaction(db) || (!lease && !backgroundWriterScope.getStore())) return operation();
729
995
  const previous = pragmaNumber(db, "busy_timeout");
@@ -749,6 +1015,7 @@ function withAutocommitTimeout<T>(db: Database, operation: () => T): T {
749
1015
 
750
1016
  /** The connection is never handed back to another caller with a shortened timeout. */
751
1017
  function acquireShort(db: Database, acquire: () => unknown, site: string): void {
1018
+ assertTransformWrite();
752
1019
  const started = performance.now();
753
1020
  const previous = pragmaNumber(db, "busy_timeout");
754
1021
  const outer = writerAcquisitionScope.getStore();
@@ -763,7 +1030,12 @@ function acquireShort(db: Database, acquire: () => unknown, site: string): void
763
1030
  // stays short. An ordinary BEGIN inside a transform pass cannot yield;
764
1031
  // give that single attempt enough time for a brief writer to finish.
765
1032
  const lease = foregroundWaitLease();
766
- const timeout = lease ? Math.floor(lease.remainingWaitMs) : SHORT_BUSY_TIMEOUT_MS;
1033
+ const timeout = Math.floor(
1034
+ Math.min(
1035
+ lease ? lease.remainingWaitMs : SHORT_BUSY_TIMEOUT_MS,
1036
+ owner?.remainingMs?.() ?? lease?.guard?.remainingMs() ?? Infinity,
1037
+ ),
1038
+ );
767
1039
  db.exec(`PRAGMA busy_timeout=${timeout}`);
768
1040
  acquire();
769
1041
  acquiredAt = performance.now();
@@ -799,16 +1071,20 @@ function acquireShort(db: Database, acquire: () => unknown, site: string): void
799
1071
  * `acquireShort`, then report how long the writer waited for the lock
800
1072
  * (`acquire_ms`) and how long it then held it (`hold_ms`) when either crosses
801
1073
  * the threshold. A long hold blocks every other process's writer, so it is
802
- * worth seeing even when the lock itself came quickly.
1074
+ * worth seeing even when the lock itself came quickly. The native end statement's
1075
+ * `end_ms` is reported separately, so a slow FTS merge or checkpoint at COMMIT
1076
+ * is not mistaken for acquisition time.
803
1077
  */
804
1078
  function endWriterTransaction(db: Database, end: () => unknown, sql: string): unknown {
805
1079
  let ended = false;
1080
+ const endStarted = performance.now();
806
1081
  try {
807
1082
  const result = end();
808
1083
  ended = true;
809
1084
  return result;
810
1085
  } finally {
811
1086
  const open = openWriterTransactions.get(db);
1087
+ const endMs = performance.now() - endStarted;
812
1088
  // A COMMIT that failed with the transaction still open has not ended it.
813
1089
  if (open && !isInTransaction(db)) {
814
1090
  openWriterTransactions.delete(db);
@@ -820,7 +1096,7 @@ function endWriterTransaction(db: Database, end: () => unknown, sql: string): un
820
1096
  ? "committed"
821
1097
  : "failed";
822
1098
  reportSqliteDiagnostic(
823
- `sqlite writer site=${open.site} lane=${open.lane} acquire_ms=${Math.round(open.acquireMs)} hold_ms=${Math.round(holdMs)} attempts=${open.attempts} outcome=${outcome}`,
1099
+ `sqlite writer site=${open.site} lane=${open.lane} acquire_ms=${Math.round(open.acquireMs)} hold_ms=${Math.round(holdMs)} end_ms=${Math.round(endMs)} attempts=${open.attempts} outcome=${outcome}`,
824
1100
  );
825
1101
  }
826
1102
  }
@@ -871,11 +1147,28 @@ export async function beginSqliteWriterAsync(db: Database, site: string): Promis
871
1147
  }
872
1148
 
873
1149
  /** Retry admission before any turn work, yielding between short lock attempts. */
874
- export async function withAsyncPrivilegedWriter<T>(db: Database, operation: () => T): Promise<T> {
1150
+ export async function withAsyncPrivilegedWriter<T>(
1151
+ db: Database,
1152
+ operation: () => T,
1153
+ options: {
1154
+ signal?: AbortSignal;
1155
+ beforeRetry?: (error: SqliteAcquisitionBusyError) => void;
1156
+ jitter?: boolean;
1157
+ budgetMs?: number;
1158
+ assertCurrentPass?: () => void;
1159
+ } = {},
1160
+ ): Promise<T> {
875
1161
  const started = performance.now();
1162
+ const budgetMs = Math.max(
1163
+ 0,
1164
+ Math.min(FOREGROUND_ACQUISITION_BUDGET_MS, options.budgetMs ?? Infinity),
1165
+ );
876
1166
  let attempts = 0;
877
1167
  for (;;) {
1168
+ options.signal?.throwIfAborted();
1169
+ options.assertCurrentPass?.();
878
1170
  attempts++;
1171
+ let entered = false;
879
1172
  try {
880
1173
  const acquisition: WriterAcquisition = {
881
1174
  site: "privileged_writer",
@@ -883,35 +1176,51 @@ export async function withAsyncPrivilegedWriter<T>(db: Database, operation: () =
883
1176
  startedAt: started,
884
1177
  attempts,
885
1178
  claimed: false,
1179
+ remainingMs: () => Math.max(0, budgetMs - (performance.now() - started)),
886
1180
  };
887
1181
  // The acquisition and hold of this transaction are reported when it
888
1182
  // commits or rolls back (see endWriterTransaction).
889
1183
  return admissionScope.run(true, () =>
890
1184
  withSqliteTransformPass(() =>
891
1185
  writerAcquisitionScope.run(acquisition, () =>
892
- withPrivilegedWriter(db, operation),
1186
+ withPrivilegedWriter(db, () => {
1187
+ entered = true;
1188
+ return operation();
1189
+ }),
893
1190
  ),
894
1191
  ),
895
1192
  );
896
1193
  } catch (error) {
897
1194
  // A callback failure can occur after writes; only retry a failed BEGIN.
898
- if (!(error instanceof SqliteAcquisitionBusyError)) throw error;
1195
+ if (entered || !(error instanceof SqliteAcquisitionBusyError)) throw error;
1196
+ // Adapters may serve a validated saved request instead of waiting.
1197
+ // This runs only after a failed BEGIN, never after callback writes.
1198
+ options.beforeRetry?.(error);
899
1199
  const elapsed = performance.now() - started;
900
- if (elapsed >= FOREGROUND_ACQUISITION_BUDGET_MS) {
1200
+ if (elapsed >= budgetMs) {
901
1201
  reportSqliteDiagnostic(
902
1202
  `sqlite writer site=privileged_writer lane=foreground acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`,
903
1203
  );
904
1204
  throw error;
905
1205
  }
906
- await new Promise<void>((resolve) =>
907
- setTimeout(
908
- resolve,
909
- Math.min(
910
- attempts === 1 ? 500 : 1000,
911
- FOREGROUND_ACQUISITION_BUDGET_MS - elapsed,
912
- ),
913
- ),
1206
+ const backoff = attempts === 1 ? 500 : 1000;
1207
+ const delay = Math.min(
1208
+ options.jitter ? backoff * (0.8 + Math.random() * 0.4) : backoff,
1209
+ budgetMs - elapsed,
914
1210
  );
1211
+ await new Promise<void>((resolve, reject) => {
1212
+ const abort = () => {
1213
+ clearTimeout(timer);
1214
+ options.signal?.removeEventListener("abort", abort);
1215
+ reject(options.signal?.reason ?? new Error("Writer wait aborted"));
1216
+ };
1217
+ const timer = setTimeout(() => {
1218
+ options.signal?.removeEventListener("abort", abort);
1219
+ resolve();
1220
+ }, delay);
1221
+ options.signal?.addEventListener("abort", abort, { once: true });
1222
+ if (options.signal?.aborted) abort();
1223
+ });
915
1224
  }
916
1225
  }
917
1226
  }
@@ -986,3 +1295,80 @@ export function withPrivilegedWriter<T>(db: Database, operation: () => T): T {
986
1295
  throw error;
987
1296
  }
988
1297
  }
1298
+
1299
+ // Process-local admission only; SQLite remains the cross-process writer arbiter.
1300
+ const indexCoordinationKey = Symbol.for("magic-context.index-foreground-coordination.v1");
1301
+ const indexCoordinationHeap = globalThis as unknown as Record<
1302
+ symbol,
1303
+ SharedArrayBuffer | undefined
1304
+ >;
1305
+ const indexCoordinationBuffer =
1306
+ indexCoordinationHeap[indexCoordinationKey] ??
1307
+ new SharedArrayBuffer(3 * Int32Array.BYTES_PER_ELEMENT);
1308
+ indexCoordinationHeap[indexCoordinationKey] = indexCoordinationBuffer;
1309
+ const indexCoordinationState = new Int32Array(indexCoordinationBuffer);
1310
+ // Slots: foreground interest, current maintenance owner, next owner token.
1311
+
1312
+ export function indexCoordinationInput(): {
1313
+ indexCoordination: SharedArrayBuffer;
1314
+ indexOwner: number;
1315
+ } {
1316
+ return {
1317
+ indexCoordination: indexCoordinationBuffer,
1318
+ indexOwner: Atomics.add(indexCoordinationState, 2, 1) + 1,
1319
+ };
1320
+ }
1321
+
1322
+ const yieldIndexTurn = () => new Promise<void>((resolve) => setTimeout(resolve, 1));
1323
+
1324
+ /** Announce interest before waiting, so no maintenance chunk overtakes a foreground turn. */
1325
+ function reserveForegroundSqliteTurn(): (() => void) | Promise<() => void> {
1326
+ Atomics.add(indexCoordinationState, 0, 1);
1327
+ const release = () => {
1328
+ Atomics.sub(indexCoordinationState, 0, 1);
1329
+ Atomics.notify(indexCoordinationState, 0);
1330
+ };
1331
+ if (Atomics.load(indexCoordinationState, 1) === 0) return release;
1332
+ return (async () => {
1333
+ while (Atomics.load(indexCoordinationState, 1) !== 0) await yieldIndexTurn();
1334
+ return release;
1335
+ })();
1336
+ }
1337
+
1338
+ export function releaseIndexOwner(input: {
1339
+ indexCoordination?: SharedArrayBuffer;
1340
+ indexOwner?: number;
1341
+ }): void {
1342
+ if (!input.indexCoordination || !input.indexOwner) return;
1343
+ const shared = new Int32Array(input.indexCoordination);
1344
+ Atomics.compareExchange(shared, 1, input.indexOwner, 0);
1345
+ Atomics.notify(shared, 1);
1346
+ }
1347
+
1348
+ /** One synchronous transaction per permit; release the permit before yielding. */
1349
+ export async function withIndexChunk<T>(
1350
+ input: { indexCoordination?: SharedArrayBuffer; indexOwner?: number },
1351
+ operation: () => T,
1352
+ ): Promise<T> {
1353
+ if (!input.indexCoordination || !input.indexOwner) return operation();
1354
+ const shared = new Int32Array(input.indexCoordination);
1355
+ for (;;) {
1356
+ if (
1357
+ Atomics.load(shared, 0) === 0 &&
1358
+ Atomics.compareExchange(shared, 1, 0, input.indexOwner) === 0
1359
+ ) {
1360
+ if (Atomics.load(shared, 0) === 0) break;
1361
+ releaseIndexOwner(input);
1362
+ }
1363
+ await yieldIndexTurn();
1364
+ }
1365
+ try {
1366
+ return await operation();
1367
+ } finally {
1368
+ releaseIndexOwner(input);
1369
+ }
1370
+ }
1371
+
1372
+ export async function yieldIndexChunk(): Promise<void> {
1373
+ await yieldIndexTurn();
1374
+ }