@cortexkit/opencode-magic-context 0.44.3 → 0.45.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 (701) hide show
  1. package/dist/agents/hidden-agent-registrations.d.ts +3 -2
  2. package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
  3. package/dist/agents/magic-context-prompt.d.ts +1 -0
  4. package/dist/agents/magic-context-prompt.d.ts.map +1 -1
  5. package/dist/agents/permissions.d.ts +8 -28
  6. package/dist/agents/permissions.d.ts.map +1 -1
  7. package/dist/{announcement-n8hs7kjw.js → announcement-f75t58v9.js} +4 -2
  8. package/dist/config/index.d.ts.map +1 -1
  9. package/dist/config/project-security.d.ts +48 -0
  10. package/dist/config/project-security.d.ts.map +1 -1
  11. package/dist/config/raw-loader.d.ts.map +1 -1
  12. package/dist/config/schema/magic-context.d.ts +10 -7
  13. package/dist/config/schema/magic-context.d.ts.map +1 -1
  14. package/dist/{conflict-warning-hook-hmpzxep6.js → conflict-warning-hook-5yrz2r24.js} +10 -6
  15. package/dist/{derive-budgets-vjmvh6pz.js → derive-budgets-a63zsm5c.js} +4 -4
  16. package/dist/embedding-worker.js +49 -0
  17. package/dist/emscripten-module-0g8f45e6.js +602 -0
  18. package/dist/emscripten-module-0pekdjxz.js +1532 -0
  19. package/dist/emscripten-module-e67xwsp3.js +503 -0
  20. package/dist/emscripten-module-pj1vyb44.js +4559 -0
  21. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +23 -3
  22. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  23. package/dist/features/magic-context/compartment-embedding.d.ts.map +1 -1
  24. package/dist/features/magic-context/compartment-storage.d.ts +14 -3
  25. package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
  26. package/dist/features/magic-context/context-store-uuid.d.ts +7 -0
  27. package/dist/features/magic-context/context-store-uuid.d.ts.map +1 -0
  28. package/dist/features/magic-context/dreamer/classify.d.ts +1 -3
  29. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  30. package/dist/features/magic-context/dreamer/cron.d.ts +5 -4
  31. package/dist/features/magic-context/dreamer/cron.d.ts.map +1 -1
  32. package/dist/features/magic-context/dreamer/docs-proposals.d.ts.map +1 -1
  33. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  34. package/dist/features/magic-context/dreamer/expire-memories.d.ts.map +1 -1
  35. package/dist/features/magic-context/dreamer/idle-schedule-prune.d.ts +24 -0
  36. package/dist/features/magic-context/dreamer/idle-schedule-prune.d.ts.map +1 -0
  37. package/dist/features/magic-context/dreamer/manual-summary.d.ts.map +1 -1
  38. package/dist/features/magic-context/dreamer/map-memories.d.ts +5 -5
  39. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  40. package/dist/features/magic-context/dreamer/module-apply.d.ts +4 -25
  41. package/dist/features/magic-context/dreamer/module-apply.d.ts.map +1 -1
  42. package/dist/features/magic-context/dreamer/retrospective-learnings.d.ts.map +1 -1
  43. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +5 -1
  44. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  45. package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts +12 -5
  46. package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts.map +1 -1
  47. package/dist/features/magic-context/dreamer/task-executor.d.ts +6 -0
  48. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  49. package/dist/features/magic-context/dreamer/task-gates.d.ts +34 -0
  50. package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
  51. package/dist/features/magic-context/dreamer/task-prompts.d.ts +1 -1
  52. package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -1
  53. package/dist/features/magic-context/dreamer/task-registry.d.ts +7 -5
  54. package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
  55. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +10 -3
  56. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  57. package/dist/features/magic-context/dreamer/token-budget.d.ts +3 -0
  58. package/dist/features/magic-context/dreamer/token-budget.d.ts.map +1 -1
  59. package/dist/features/magic-context/dreamer/verify.d.ts +2 -2
  60. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  61. package/dist/features/magic-context/git-commits/git-log-reader.d.ts +11 -2
  62. package/dist/features/magic-context/git-commits/git-log-reader.d.ts.map +1 -1
  63. package/dist/features/magic-context/git-commits/indexer.d.ts.map +1 -1
  64. package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
  65. package/dist/features/magic-context/git-commits/storage-git-commits.d.ts +2 -0
  66. package/dist/features/magic-context/git-commits/storage-git-commits.d.ts.map +1 -1
  67. package/dist/features/magic-context/legacy-authority-fixture.test-support.d.ts +6 -0
  68. package/dist/features/magic-context/legacy-authority-fixture.test-support.d.ts.map +1 -0
  69. package/dist/features/magic-context/lkg-prefix-chunks.d.ts +53 -0
  70. package/dist/features/magic-context/lkg-prefix-chunks.d.ts.map +1 -0
  71. package/dist/features/magic-context/memory/embedding-backfill.d.ts.map +1 -1
  72. package/dist/features/magic-context/memory/embedding-local.d.ts +8 -0
  73. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  74. package/dist/features/magic-context/memory/embedding-openai.d.ts +1 -0
  75. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  76. package/dist/features/magic-context/memory/embedding-worker-client.d.ts +27 -0
  77. package/dist/features/magic-context/memory/embedding-worker-client.d.ts.map +1 -0
  78. package/dist/features/magic-context/memory/embedding-worker.d.ts +2 -0
  79. package/dist/features/magic-context/memory/embedding-worker.d.ts.map +1 -0
  80. package/dist/features/magic-context/memory/embedding-worker.fixture.d.ts +2 -0
  81. package/dist/features/magic-context/memory/embedding-worker.fixture.d.ts.map +1 -0
  82. package/dist/features/magic-context/memory/memory-selection.d.ts.map +1 -1
  83. package/dist/features/magic-context/memory/project-identity-cache.d.ts +4 -3
  84. package/dist/features/magic-context/memory/project-identity-cache.d.ts.map +1 -1
  85. package/dist/features/magic-context/memory/project-identity.d.ts +5 -4
  86. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  87. package/dist/features/magic-context/memory/storage-memory-fts.d.ts.map +1 -1
  88. package/dist/features/magic-context/memory/visibility.d.ts +1 -1
  89. package/dist/features/magic-context/memory/visibility.d.ts.map +1 -1
  90. package/dist/features/magic-context/message-fts-rowid-map.d.ts +14 -1
  91. package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -1
  92. package/dist/features/magic-context/message-fts-session-filter.d.ts +14 -0
  93. package/dist/features/magic-context/message-fts-session-filter.d.ts.map +1 -0
  94. package/dist/features/magic-context/message-index.d.ts +1 -7
  95. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  96. package/dist/features/magic-context/message-time-backfill.d.ts.map +1 -1
  97. package/dist/features/magic-context/migration-v94-write-split.d.ts +62 -0
  98. package/dist/features/magic-context/migration-v94-write-split.d.ts.map +1 -0
  99. package/dist/features/magic-context/migration-worker-client.d.ts +23 -0
  100. package/dist/features/magic-context/migration-worker-client.d.ts.map +1 -0
  101. package/dist/features/magic-context/migration-worker-protocol.d.ts +30 -0
  102. package/dist/features/magic-context/migration-worker-protocol.d.ts.map +1 -0
  103. package/dist/features/magic-context/migration-worker.d.ts +2 -0
  104. package/dist/features/magic-context/migration-worker.d.ts.map +1 -0
  105. package/dist/features/magic-context/migrations.d.ts +7 -0
  106. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  107. package/dist/features/magic-context/mural/render-mural.d.ts +24 -2
  108. package/dist/features/magic-context/mural/render-mural.d.ts.map +1 -1
  109. package/dist/features/magic-context/mural/render-trigger.d.ts +1 -1
  110. package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
  111. package/dist/features/magic-context/overflow-detection.d.ts +18 -7
  112. package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
  113. package/dist/features/magic-context/project-embedding-registry.d.ts +2 -0
  114. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  115. package/dist/features/magic-context/range-parser.d.ts +2 -3
  116. package/dist/features/magic-context/range-parser.d.ts.map +1 -1
  117. package/dist/features/magic-context/resolve-subagent-fallback.d.ts +2 -0
  118. package/dist/features/magic-context/resolve-subagent-fallback.d.ts.map +1 -1
  119. package/dist/features/magic-context/scheduler.d.ts +2 -0
  120. package/dist/features/magic-context/scheduler.d.ts.map +1 -1
  121. package/dist/features/magic-context/search.d.ts +7 -0
  122. package/dist/features/magic-context/search.d.ts.map +1 -1
  123. package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
  124. package/dist/features/magic-context/session-project-storage.d.ts +10 -1
  125. package/dist/features/magic-context/session-project-storage.d.ts.map +1 -1
  126. package/dist/features/magic-context/smart-notes/compiler-prompt.d.ts +1 -1
  127. package/dist/features/magic-context/smart-notes/compiler-prompt.d.ts.map +1 -1
  128. package/dist/features/magic-context/smart-notes/compiler.d.ts +4 -0
  129. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  130. package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
  131. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +2 -0
  132. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
  133. package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts +10 -8
  134. package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts.map +1 -1
  135. package/dist/features/magic-context/smart-notes/storage.d.ts +2 -2
  136. package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
  137. package/dist/features/magic-context/smart-notes/types.d.ts +7 -2
  138. package/dist/features/magic-context/smart-notes/types.d.ts.map +1 -1
  139. package/dist/features/magic-context/storage-caveman-rules.d.ts +21 -0
  140. package/dist/features/magic-context/storage-caveman-rules.d.ts.map +1 -0
  141. package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
  142. package/dist/features/magic-context/storage-compartment-history-version.d.ts +4 -0
  143. package/dist/features/magic-context/storage-compartment-history-version.d.ts.map +1 -0
  144. package/dist/features/magic-context/storage-db.d.ts +68 -3
  145. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  146. package/dist/features/magic-context/storage-identity-merge.d.ts +6 -0
  147. package/dist/features/magic-context/storage-identity-merge.d.ts.map +1 -1
  148. package/dist/features/magic-context/storage-meta-persisted.d.ts +15 -0
  149. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  150. package/dist/features/magic-context/storage-meta-session.d.ts +1 -1
  151. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  152. package/dist/features/magic-context/storage-meta-shared.d.ts +1 -1
  153. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  154. package/dist/features/magic-context/storage-notes.d.ts +2 -2
  155. package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
  156. package/dist/features/magic-context/storage-reasoning-removal.d.ts +30 -0
  157. package/dist/features/magic-context/storage-reasoning-removal.d.ts.map +1 -0
  158. package/dist/features/magic-context/storage-replay-document.d.ts +42 -5
  159. package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -1
  160. package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
  161. package/dist/features/magic-context/storage-tags.d.ts +7 -1
  162. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  163. package/dist/features/magic-context/storage.d.ts +1 -1
  164. package/dist/features/magic-context/storage.d.ts.map +1 -1
  165. package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -1
  166. package/dist/features/magic-context/tag-input.d.ts +4 -0
  167. package/dist/features/magic-context/tag-input.d.ts.map +1 -0
  168. package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
  169. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  170. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
  171. package/dist/features/magic-context/v22-deferred-backfill.d.ts.map +1 -1
  172. package/dist/ffi-3cx1cxpk.js +78 -0
  173. package/dist/ffi-7bqqe4cd.js +91 -0
  174. package/dist/ffi-7e6gryj5.js +91 -0
  175. package/dist/ffi-bpvkebwr.js +78 -0
  176. package/dist/hooks/magic-context/apply-operations.d.ts +9 -1
  177. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  178. package/dist/hooks/magic-context/auto-search-deadline.d.ts +10 -0
  179. package/dist/hooks/magic-context/auto-search-deadline.d.ts.map +1 -0
  180. package/dist/hooks/magic-context/auto-search-hint.d.ts +3 -0
  181. package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -1
  182. package/dist/hooks/magic-context/auto-search-runner.d.ts +3 -0
  183. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  184. package/dist/hooks/magic-context/caveman-cleanup.d.ts +8 -1
  185. package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
  186. package/dist/hooks/magic-context/caveman.d.ts +56 -1
  187. package/dist/hooks/magic-context/caveman.d.ts.map +1 -1
  188. package/dist/hooks/magic-context/child-session-spawn.d.ts +2 -0
  189. package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
  190. package/dist/hooks/magic-context/command-handler.d.ts +1 -1
  191. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  192. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +1 -1
  193. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  194. package/dist/hooks/magic-context/compartment-parser.d.ts +3 -3
  195. package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -1
  196. package/dist/hooks/magic-context/compartment-render-epoch.d.ts +12 -1
  197. package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
  198. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  199. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +0 -1
  200. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  201. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
  202. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  203. package/dist/hooks/magic-context/compartment-runner-types.d.ts +3 -0
  204. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  205. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +6 -0
  206. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  207. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  208. package/dist/hooks/magic-context/degraded-pass-refusal.d.ts +35 -0
  209. package/dist/hooks/magic-context/degraded-pass-refusal.d.ts.map +1 -0
  210. package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -1
  211. package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -1
  212. package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -1
  213. package/dist/hooks/magic-context/embed-history-runner.d.ts.map +1 -1
  214. package/dist/hooks/magic-context/emergency-drop.d.ts +15 -0
  215. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  216. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  217. package/dist/hooks/magic-context/event-resolvers.d.ts +7 -0
  218. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  219. package/dist/hooks/magic-context/execute-status.d.ts +1 -0
  220. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  221. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +17 -0
  222. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
  223. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +2 -0
  224. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  225. package/dist/hooks/magic-context/historian-host-runner.d.ts +5 -0
  226. package/dist/hooks/magic-context/historian-host-runner.d.ts.map +1 -1
  227. package/dist/hooks/magic-context/historian-prompt-fit.d.ts +116 -0
  228. package/dist/hooks/magic-context/historian-prompt-fit.d.ts.map +1 -0
  229. package/dist/hooks/magic-context/historian-prompt.generated.d.ts +1 -1
  230. package/dist/hooks/magic-context/historian-prompt.generated.d.ts.map +1 -1
  231. package/dist/hooks/magic-context/history-boundary-repair.d.ts +44 -0
  232. package/dist/hooks/magic-context/history-boundary-repair.d.ts.map +1 -0
  233. package/dist/hooks/magic-context/hook.d.ts +4 -0
  234. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  235. package/dist/hooks/magic-context/inject-compartments.d.ts +13 -0
  236. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  237. package/dist/hooks/magic-context/lkg-persist.d.ts +12 -0
  238. package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
  239. package/dist/hooks/magic-context/lkg-replay-fit.d.ts +104 -0
  240. package/dist/hooks/magic-context/lkg-replay-fit.d.ts.map +1 -0
  241. package/dist/hooks/magic-context/lkg-replay.d.ts +64 -0
  242. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  243. package/dist/hooks/magic-context/module-client.d.ts.map +1 -1
  244. package/dist/hooks/magic-context/module-state-sync-timing.d.ts +1 -1
  245. package/dist/hooks/magic-context/module-state-sync-timing.d.ts.map +1 -1
  246. package/dist/hooks/magic-context/module-state-sync.d.ts +6 -68
  247. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  248. package/dist/hooks/magic-context/module-tool-backends.d.ts +1 -34
  249. package/dist/hooks/magic-context/module-tool-backends.d.ts.map +1 -1
  250. package/dist/hooks/magic-context/module-transport.d.ts +1 -55
  251. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  252. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  253. package/dist/hooks/magic-context/note-nudger.d.ts +2 -0
  254. package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
  255. package/dist/hooks/magic-context/pass-outcome.d.ts +59 -2
  256. package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
  257. package/dist/hooks/magic-context/producer-window-guard.d.ts +6 -0
  258. package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -1
  259. package/dist/hooks/magic-context/read-session-chunk.d.ts +17 -4
  260. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  261. package/dist/hooks/magic-context/read-session-formatting.d.ts +11 -0
  262. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  263. package/dist/hooks/magic-context/read-session-raw.d.ts +2 -2
  264. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  265. package/dist/hooks/magic-context/reasoning-removal.d.ts +60 -0
  266. package/dist/hooks/magic-context/reasoning-removal.d.ts.map +1 -0
  267. package/dist/hooks/magic-context/recomp-orchestrator.d.ts +1 -0
  268. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  269. package/dist/hooks/magic-context/reference-retrieval.d.ts +1 -1
  270. package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
  271. package/dist/hooks/magic-context/reply-pages.d.ts +3 -0
  272. package/dist/hooks/magic-context/reply-pages.d.ts.map +1 -0
  273. package/dist/hooks/magic-context/rust-lkg-freeze-registry.d.ts +62 -0
  274. package/dist/hooks/magic-context/rust-lkg-freeze-registry.d.ts.map +1 -0
  275. package/dist/hooks/magic-context/rust-mode-transform.d.ts +17 -85
  276. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  277. package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
  278. package/dist/hooks/magic-context/sentinel.d.ts +35 -0
  279. package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
  280. package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts +28 -0
  281. package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts.map +1 -0
  282. package/dist/hooks/magic-context/single-store-refusal.d.ts +14 -0
  283. package/dist/hooks/magic-context/single-store-refusal.d.ts.map +1 -0
  284. package/dist/hooks/magic-context/storage-busy-refusal.d.ts +7 -0
  285. package/dist/hooks/magic-context/storage-busy-refusal.d.ts.map +1 -1
  286. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  287. package/dist/hooks/magic-context/stripped-command.d.ts +1 -1
  288. package/dist/hooks/magic-context/stripped-command.d.ts.map +1 -1
  289. package/dist/hooks/magic-context/system-injection-stripper.d.ts +7 -0
  290. package/dist/hooks/magic-context/system-injection-stripper.d.ts.map +1 -1
  291. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  292. package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -1
  293. package/dist/hooks/magic-context/tag-id-fallback.d.ts.map +1 -1
  294. package/dist/hooks/magic-context/tag-messages.d.ts +18 -1
  295. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  296. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  297. package/dist/hooks/magic-context/tokenizer-calibration.d.ts +1 -1
  298. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  299. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +1 -0
  300. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  301. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +38 -4
  302. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  303. package/dist/hooks/magic-context/transform.d.ts +12 -39
  304. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  305. package/dist/hooks/magic-context/unmanaged-over-window.d.ts +36 -0
  306. package/dist/hooks/magic-context/unmanaged-over-window.d.ts.map +1 -0
  307. package/dist/hooks/magic-context/unresolved-history-boundary.d.ts +15 -0
  308. package/dist/hooks/magic-context/unresolved-history-boundary.d.ts.map +1 -0
  309. package/dist/hooks/magic-context/user-profile-render.d.ts +3 -0
  310. package/dist/hooks/magic-context/user-profile-render.d.ts.map +1 -0
  311. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  312. package/dist/{index-yhm60r53.js → index-16ny736w.js} +13622 -28584
  313. package/dist/{index-q5p1aqvv.js → index-2aq21j41.js} +1208 -429
  314. package/dist/{index-32b096cc.js → index-2ntg5sd4.js} +6 -2
  315. package/dist/index-4krbw8z9.js +6034 -0
  316. package/dist/{index-33q7s9y2.js → index-75zjgwga.js} +61 -85
  317. package/dist/{index-nf9sk8sh.js → index-8fgkmxmy.js} +28 -10
  318. package/dist/index-a4m2b1yv.js +530 -0
  319. package/dist/index-anq4nn6f.js +131 -0
  320. package/dist/index-avwt563y.js +62 -0
  321. package/dist/index-bmzf7zxv.js +445 -0
  322. package/dist/index-e44zzy84.js +10 -0
  323. package/dist/index-en1k8h8m.js +244 -0
  324. package/dist/{index-638hf49n.js → index-f85teqck.js} +15 -6
  325. package/dist/index-fr2z4qy8.js +7810 -0
  326. package/dist/{index-kwe03yde.js → index-fzbvakh0.js} +1 -1
  327. package/dist/{module-asyncify-2EFITU5U-rkqjhjxd.js → index-g20jdh0p.js} +114 -105
  328. package/dist/index-gd5qx1j9.js +398 -0
  329. package/dist/{index-3bygzk2d.js → index-hybnrwq0.js} +169 -4
  330. package/dist/{index-jqcbs2k1.js → index-mc22ayvf.js} +24 -5
  331. package/dist/{index-y5145x8k.js → index-n96ag4rk.js} +15 -1
  332. package/dist/index-q7yesyk9.js +9118 -0
  333. package/dist/index-remp7e2g.js +214 -0
  334. package/dist/{index-7k55qm8a.js → index-sfpzqvdz.js} +8 -8
  335. package/dist/{index-9y5p0d50.js → index-vvtfyw1z.js} +13 -76
  336. package/dist/index-w9jwmntv.js +202 -0
  337. package/dist/{index-kr5qehbd.js → index-x23gah8c.js} +1 -1
  338. package/dist/{index-jdxxq8cz.js → index-x8a7jmkh.js} +6 -1
  339. package/dist/{index-rdsaxnf2.js → index-xgt9k6c6.js} +23 -12
  340. package/dist/index-y8v6yerm.js +77 -0
  341. package/dist/index.d.ts.map +1 -1
  342. package/dist/index.js +7560 -8084
  343. package/dist/message-time-backfill-an311pmk.js +124 -0
  344. package/dist/migration-worker.js +53 -0
  345. package/dist/{model-resolution-dxatzjde.js → model-resolution-xhfmyyvy.js} +5 -1
  346. package/dist/module-ES6BEMUI-3cet1pyp.js +12 -0
  347. package/dist/module-asyncify-2EFITU5U-c2razzd9.js +6 -0
  348. package/dist/plugin/boot-deadline.d.ts.map +1 -1
  349. package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
  350. package/dist/plugin/dream-timer-module-client.d.ts +1 -11
  351. package/dist/plugin/dream-timer-module-client.d.ts.map +1 -1
  352. package/dist/plugin/dream-timer.d.ts.map +1 -1
  353. package/dist/plugin/hooks/create-session-hooks.d.ts +8 -0
  354. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  355. package/dist/plugin/messages-transform.d.ts +20 -13
  356. package/dist/plugin/messages-transform.d.ts.map +1 -1
  357. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  358. package/dist/plugin/stale-build-notice.d.ts +16 -0
  359. package/dist/plugin/stale-build-notice.d.ts.map +1 -0
  360. package/dist/read-session-chunk-8rxs0tc9.js +84 -0
  361. package/dist/recomp-orchestrator-nzamtw29.js +39 -0
  362. package/dist/{rpc-notifications-4amf6mf4.js → rpc-notifications-3hed126v.js} +3 -1
  363. package/dist/{safe-notification-target-50gm9c58.js → safe-notification-target-43r8jsxw.js} +3 -3
  364. package/dist/send-session-notification-nqpv7cne.js +28 -0
  365. package/dist/shared/assistant-message-extractor.d.ts +4 -0
  366. package/dist/shared/assistant-message-extractor.d.ts.map +1 -1
  367. package/dist/shared/background-batch-drain.d.ts +8 -0
  368. package/dist/shared/background-batch-drain.d.ts.map +1 -0
  369. package/dist/{features/builtin-commands/commands.d.ts → shared/builtin-commands.d.ts} +1 -1
  370. package/dist/shared/builtin-commands.d.ts.map +1 -0
  371. package/dist/shared/embedding-activity.d.ts +13 -0
  372. package/dist/shared/embedding-activity.d.ts.map +1 -0
  373. package/dist/shared/historian-tool-expansions.d.ts +5 -0
  374. package/dist/shared/historian-tool-expansions.d.ts.map +1 -0
  375. package/dist/shared/historian-tool-template.d.ts +5 -0
  376. package/dist/shared/historian-tool-template.d.ts.map +1 -0
  377. package/dist/shared/historian-transient-error.d.ts +2 -0
  378. package/dist/shared/historian-transient-error.d.ts.map +1 -0
  379. package/dist/shared/jsonc-edit.d.ts.map +1 -1
  380. package/dist/shared/logger.d.ts +7 -0
  381. package/dist/shared/logger.d.ts.map +1 -1
  382. package/dist/shared/model-suggestion-retry.d.ts +2 -1
  383. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  384. package/dist/shared/models-dev-cache.d.ts.map +1 -1
  385. package/dist/shared/off-thread-migration-clock.d.ts +38 -0
  386. package/dist/shared/off-thread-migration-clock.d.ts.map +1 -0
  387. package/dist/shared/plugin-package-version.d.ts +14 -0
  388. package/dist/shared/plugin-package-version.d.ts.map +1 -0
  389. package/dist/shared/project-directory-key.d.ts +26 -0
  390. package/dist/shared/project-directory-key.d.ts.map +1 -0
  391. package/dist/shared/prompt-async-transport.d.ts +4 -0
  392. package/dist/shared/prompt-async-transport.d.ts.map +1 -1
  393. package/dist/shared/prompt-surface-runtime.d.ts +3 -3
  394. package/dist/shared/provider-response-completion.d.ts +12 -0
  395. package/dist/shared/provider-response-completion.d.ts.map +1 -0
  396. package/dist/shared/redaction.d.ts.map +1 -1
  397. package/dist/shared/rpc-client.d.ts +23 -2
  398. package/dist/shared/rpc-client.d.ts.map +1 -1
  399. package/dist/shared/rpc-types.d.ts +19 -0
  400. package/dist/shared/rpc-types.d.ts.map +1 -1
  401. package/dist/shared/rpc-utils.d.ts +41 -0
  402. package/dist/shared/rpc-utils.d.ts.map +1 -1
  403. package/dist/shared/sqlite.d.ts +13 -2
  404. package/dist/shared/sqlite.d.ts.map +1 -1
  405. package/dist/shared/stale-plugin-build.d.ts +21 -0
  406. package/dist/shared/stale-plugin-build.d.ts.map +1 -0
  407. package/dist/shared/status-summary.d.ts +29 -0
  408. package/dist/shared/status-summary.d.ts.map +1 -1
  409. package/dist/shared/status-view-check.d.ts +124 -0
  410. package/dist/shared/status-view-check.d.ts.map +1 -0
  411. package/dist/shared/status-view.d.ts +38 -2
  412. package/dist/shared/status-view.d.ts.map +1 -1
  413. package/dist/shared/tag-owner-id.d.ts +19 -0
  414. package/dist/shared/tag-owner-id.d.ts.map +1 -0
  415. package/dist/shared/tag-transcript.d.ts +2 -1
  416. package/dist/shared/tag-transcript.d.ts.map +1 -1
  417. package/dist/shared/test-temp-dir.d.ts +8 -2
  418. package/dist/shared/test-temp-dir.d.ts.map +1 -1
  419. package/dist/shared/transcript.d.ts +2 -0
  420. package/dist/shared/transcript.d.ts.map +1 -1
  421. package/dist/shared/user-answer.d.ts +4 -0
  422. package/dist/shared/user-answer.d.ts.map +1 -0
  423. package/dist/shared/user-facing-codes.d.ts +41 -6
  424. package/dist/shared/user-facing-codes.d.ts.map +1 -1
  425. package/dist/shared/xml-unescape.d.ts +9 -0
  426. package/dist/shared/xml-unescape.d.ts.map +1 -0
  427. package/dist/task-config-v81k8jvk.js +17 -0
  428. package/dist/tools/ctx-expand/constants.d.ts +1 -1
  429. package/dist/tools/ctx-expand/constants.d.ts.map +1 -1
  430. package/dist/tools/ctx-expand/mode.d.ts +4 -0
  431. package/dist/tools/ctx-expand/mode.d.ts.map +1 -1
  432. package/dist/tools/ctx-expand/render.d.ts +5 -1
  433. package/dist/tools/ctx-expand/render.d.ts.map +1 -1
  434. package/dist/tools/ctx-expand/tools.d.ts +2 -0
  435. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  436. package/dist/tools/ctx-expand/types.d.ts +1 -0
  437. package/dist/tools/ctx-expand/types.d.ts.map +1 -1
  438. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  439. package/dist/tools/ctx-note/render.d.ts +2 -0
  440. package/dist/tools/ctx-note/render.d.ts.map +1 -1
  441. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  442. package/dist/tools/ctx-reduce/constants.d.ts +1 -1
  443. package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
  444. package/dist/tools/ctx-search/constants.d.ts +1 -1
  445. package/dist/tools/ctx-search/constants.d.ts.map +1 -1
  446. package/dist/tools/light-descriptions.d.ts +3 -3
  447. package/dist/tools/light-descriptions.d.ts.map +1 -1
  448. package/dist/tools/parameter-descriptions.d.ts +14 -14
  449. package/dist/transform-postprocess-phase-414phndq.js +61 -0
  450. package/dist/tui/data/context-db.d.ts +34 -10
  451. package/dist/tui/data/context-db.d.ts.map +1 -1
  452. package/dist/tui/data/notification-socket.d.ts +6 -0
  453. package/dist/tui/data/notification-socket.d.ts.map +1 -1
  454. package/dist/tui/data/session-directory.d.ts +16 -0
  455. package/dist/tui/data/session-directory.d.ts.map +1 -0
  456. package/dist/tui-compiled/data/context-db.d.ts +34 -10
  457. package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
  458. package/dist/tui-compiled/data/notification-socket.d.ts +6 -0
  459. package/dist/tui-compiled/data/notification-socket.d.ts.map +1 -1
  460. package/dist/tui-compiled/data/session-directory.d.ts +16 -0
  461. package/dist/tui-compiled/data/session-directory.d.ts.map +1 -0
  462. package/dist/v2/derive-budgets-v0krf3t7.js +18 -0
  463. package/dist/v2/embedding-worker.js +47 -0
  464. package/dist/v2/emscripten-module-0g8f45e6.js +602 -0
  465. package/dist/v2/emscripten-module-0pekdjxz.js +1532 -0
  466. package/dist/v2/emscripten-module-e67xwsp3.js +503 -0
  467. package/dist/v2/emscripten-module-pj1vyb44.js +4559 -0
  468. package/dist/v2/ffi-3cx1cxpk.js +78 -0
  469. package/dist/v2/ffi-7bqqe4cd.js +91 -0
  470. package/dist/v2/ffi-7e6gryj5.js +91 -0
  471. package/dist/v2/ffi-bpvkebwr.js +78 -0
  472. package/dist/v2/fold/boundary.d.ts.map +1 -1
  473. package/dist/v2/fork-inheritance.d.ts +101 -0
  474. package/dist/v2/fork-inheritance.d.ts.map +1 -0
  475. package/dist/v2/hidden-child-cleanup.d.ts +11 -0
  476. package/dist/v2/hidden-child-cleanup.d.ts.map +1 -0
  477. package/dist/v2/hidden-child-native.d.ts +29 -0
  478. package/dist/v2/hidden-child-native.d.ts.map +1 -0
  479. package/dist/v2/hidden-child-record.d.ts +135 -0
  480. package/dist/v2/hidden-child-record.d.ts.map +1 -0
  481. package/dist/v2/hidden-completion.d.ts +12 -97
  482. package/dist/v2/hidden-completion.d.ts.map +1 -1
  483. package/dist/v2/hooks/context.d.ts +20 -8
  484. package/dist/v2/hooks/context.d.ts.map +1 -1
  485. package/dist/v2/hooks/dream-manual.d.ts.map +1 -1
  486. package/dist/v2/hooks/dream-trigger.d.ts +5 -0
  487. package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
  488. package/dist/v2/hooks/generate.d.ts +10 -0
  489. package/dist/v2/hooks/generate.d.ts.map +1 -0
  490. package/dist/v2/hooks/hidden-child.d.ts +33 -2
  491. package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
  492. package/dist/v2/hooks/payload.d.ts +3 -0
  493. package/dist/v2/hooks/payload.d.ts.map +1 -1
  494. package/dist/v2/hooks/session-api-gate.d.ts +4 -0
  495. package/dist/v2/hooks/session-api-gate.d.ts.map +1 -0
  496. package/dist/v2/hooks/storage-gate.d.ts +3 -1
  497. package/dist/v2/hooks/storage-gate.d.ts.map +1 -1
  498. package/dist/v2/hooks/store.d.ts +1 -1
  499. package/dist/v2/hooks/store.d.ts.map +1 -1
  500. package/dist/v2/hooks/tools.d.ts.map +1 -1
  501. package/dist/v2/hooks/types.d.ts +10 -0
  502. package/dist/v2/hooks/types.d.ts.map +1 -1
  503. package/dist/v2/hooks/update-check.d.ts.map +1 -1
  504. package/dist/v2/hooks/usage-persist.d.ts.map +1 -1
  505. package/dist/v2/hooks/usage-reading.d.ts +4 -0
  506. package/dist/v2/hooks/usage-reading.d.ts.map +1 -1
  507. package/dist/v2/index-6e4mwffh.js +5662 -0
  508. package/dist/v2/index-en1k8h8m.js +244 -0
  509. package/dist/{message-time-backfill-q374fxc5.js → v2/message-time-backfill-0n93vrd7.js} +19 -5
  510. package/dist/v2/migration-worker.js +52 -0
  511. package/dist/v2/model-resolution-xhfmyyvy.js +16 -0
  512. package/dist/v2/module-ES6BEMUI-3cet1pyp.js +12 -0
  513. package/dist/v2/module-asyncify-2EFITU5U-c2razzd9.js +6 -0
  514. package/dist/v2/prompt-context-5y5ms8f9.js +6 -0
  515. package/dist/{read-session-chunk-n072mcq4.js → v2/read-session-chunk-hjza38hr.js} +24 -7
  516. package/dist/v2/recomp-orchestrator-1aq7h44c.js +36 -0
  517. package/dist/v2/retrospective-raw-provider.d.ts +21 -0
  518. package/dist/v2/retrospective-raw-provider.d.ts.map +1 -0
  519. package/dist/v2/rpc-notifications-3hed126v.js +16 -0
  520. package/dist/v2/safe-notification-target-wtj0bbc2.js +9 -0
  521. package/dist/{send-session-notification-04hvd54c.js → v2/send-session-notification-mq9frrtm.js} +10 -5
  522. package/dist/v2/server-0jqw05sa.js +803 -0
  523. package/dist/v2/server-5317ykaf.js +40 -0
  524. package/dist/v2/server-a4m2b1yv.js +530 -0
  525. package/dist/v2/server-avwt563y.js +62 -0
  526. package/dist/v2/server-c4g2y1z8.js +28824 -0
  527. package/dist/v2/server-ckpc8pxy.js +662 -0
  528. package/dist/v2/server-e36nf2p1.js +7702 -0
  529. package/dist/v2/server-e44zzy84.js +10 -0
  530. package/dist/v2/server-fgmxwrgy.js +16 -0
  531. package/dist/v2/server-fmsr7v69.js +75 -0
  532. package/dist/v2/server-g20jdh0p.js +1273 -0
  533. package/dist/{index-dgg5y7er.js → v2/server-hfjfbg59.js} +849 -747
  534. package/dist/v2/server-n96ag4rk.js +633 -0
  535. package/dist/v2/server-qdjnb2z1.js +181 -0
  536. package/dist/v2/server-qpg6wf72.js +187 -0
  537. package/dist/v2/server-r7cmye3k.js +131 -0
  538. package/dist/v2/server-remp7e2g.js +214 -0
  539. package/dist/v2/server-rhdgxp1t.js +398 -0
  540. package/dist/v2/server-sfpzqvdz.js +137 -0
  541. package/dist/v2/server-syahy8j8.js +50 -0
  542. package/dist/v2/server-v5xgft5v.js +9116 -0
  543. package/dist/v2/server-w99cyt6a.js +361 -0
  544. package/dist/v2/server-x8a7jmkh.js +104 -0
  545. package/dist/v2/server-y8v6yerm.js +77 -0
  546. package/dist/v2/server-z19x7eqz.js +423 -0
  547. package/dist/v2/server.d.ts.map +1 -1
  548. package/dist/v2/server.js +8868 -107184
  549. package/dist/v2/store-reader.d.ts +52 -1
  550. package/dist/v2/store-reader.d.ts.map +1 -1
  551. package/dist/v2/task-config-tbndqyny.js +17 -0
  552. package/dist/v2/transformers-node-wasm.js +26768 -0
  553. package/dist/v2/transformers-web.js +25670 -0
  554. package/dist/v2/transformers.node-hj754h7s.js +29997 -0
  555. package/dist/v2/tui/index.d.ts +10 -1
  556. package/dist/v2/tui/index.d.ts.map +1 -1
  557. package/dist/v2/tui/sidebar-mount.d.ts +6 -0
  558. package/dist/v2/tui/sidebar-mount.d.ts.map +1 -1
  559. package/dist/v2/tui/status-dialog-mount.d.ts +7 -4
  560. package/dist/v2/tui/status-dialog-mount.d.ts.map +1 -1
  561. package/dist/v2/tui/types.d.ts +12 -0
  562. package/dist/v2/tui/types.d.ts.map +1 -1
  563. package/dist/v2/wrapup-orchestrator-tbyx78dz.js +425 -0
  564. package/dist/wrapup-orchestrator-h28bqsy6.js +26 -0
  565. package/package.json +8 -8
  566. package/src/agents/hidden-agent-registrations.ts +24 -16
  567. package/src/agents/magic-context-prompt.test.ts +41 -0
  568. package/src/agents/magic-context-prompt.ts +8 -5
  569. package/src/agents/permissions.test.ts +31 -49
  570. package/src/agents/permissions.ts +8 -28
  571. package/src/config/index.test.ts +60 -20
  572. package/src/config/index.ts +53 -1
  573. package/src/config/live-run-config.test.ts +5 -5
  574. package/src/config/live-snapshot.test.ts +4 -4
  575. package/src/config/migrate-config-location.test.ts +3 -10
  576. package/src/config/project-config-trust-boundary.test.ts +207 -0
  577. package/src/config/project-security.hostile-matrix.test.ts +4 -4
  578. package/src/config/project-security.ts +218 -1
  579. package/src/config/protected-tokens.test.ts +14 -9
  580. package/src/config/raw-loader.test.ts +31 -3
  581. package/src/config/raw-loader.ts +8 -3
  582. package/src/config/schema/magic-context.ts +20 -3
  583. package/src/config/variable.test.ts +3 -2
  584. package/src/features/magic-context/dreamer/cron.ts +30 -9
  585. package/src/features/magic-context/dreamer/task-registry.ts +7 -5
  586. package/src/shared/announcement.test.ts +2 -1
  587. package/src/shared/assistant-message-extractor.test.ts +27 -1
  588. package/src/shared/assistant-message-extractor.ts +27 -0
  589. package/src/shared/background-batch-drain.test.ts +38 -0
  590. package/src/shared/background-batch-drain.ts +29 -0
  591. package/src/shared/builtin-commands.ts +50 -0
  592. package/src/shared/console-diagnostics-fence.test.ts +145 -0
  593. package/src/shared/data-path.test.ts +6 -5
  594. package/src/shared/embedding-activity.test.ts +21 -0
  595. package/src/shared/embedding-activity.ts +36 -0
  596. package/src/shared/historian-tool-defaults.json +13 -0
  597. package/src/shared/historian-tool-expansions.ts +18 -0
  598. package/src/shared/historian-tool-template.ts +248 -0
  599. package/src/shared/historian-transient-error.test.ts +36 -0
  600. package/src/shared/historian-transient-error.ts +22 -0
  601. package/src/shared/jsonc-edit.ts +20 -1
  602. package/src/shared/logger.test.ts +3 -2
  603. package/src/shared/logger.ts +40 -1
  604. package/src/shared/model-suggestion-retry.test.ts +46 -0
  605. package/src/shared/model-suggestion-retry.ts +16 -1
  606. package/src/shared/models-dev-cache.test.ts +74 -2
  607. package/src/shared/models-dev-cache.ts +5 -1
  608. package/src/shared/off-thread-migration-clock.test.ts +55 -0
  609. package/src/shared/off-thread-migration-clock.ts +124 -0
  610. package/src/shared/opencode-db-path.test.ts +3 -2
  611. package/src/shared/plugin-package-version.ts +52 -0
  612. package/src/shared/project-directory-key.test.ts +111 -0
  613. package/src/shared/project-directory-key.ts +54 -0
  614. package/src/shared/prompt-async-transport.test.ts +249 -72
  615. package/src/shared/prompt-async-transport.ts +131 -24
  616. package/src/shared/prompt-surface-a1-golden.md +41 -25
  617. package/src/shared/prompt-surface-runtime.test.ts +3 -3
  618. package/src/shared/provider-response-completion.ts +23 -0
  619. package/src/shared/redaction.test.ts +51 -1
  620. package/src/shared/redaction.ts +33 -0
  621. package/src/shared/rpc-async-probes.test.ts +32 -2
  622. package/src/shared/rpc-client.test.ts +3 -2
  623. package/src/shared/rpc-client.ts +76 -18
  624. package/src/shared/rpc-types.ts +15 -0
  625. package/src/shared/rpc-utils.test.ts +191 -12
  626. package/src/shared/rpc-utils.ts +184 -26
  627. package/src/shared/sqlite-acquisition-routing.test.ts +46 -3
  628. package/src/shared/sqlite-pass-scope.test.ts +3 -2
  629. package/src/shared/sqlite-transaction-mode-guard.test.ts +4 -0
  630. package/src/shared/sqlite-writer-diagnostics.test.ts +134 -0
  631. package/src/shared/sqlite.ts +225 -41
  632. package/src/shared/stale-plugin-build.test.ts +129 -0
  633. package/src/shared/stale-plugin-build.ts +151 -0
  634. package/src/shared/status-summary.ts +40 -13
  635. package/src/shared/status-view-check.test.ts +253 -0
  636. package/src/shared/status-view-check.ts +536 -0
  637. package/src/shared/status-view.test.ts +6 -1
  638. package/src/shared/status-view.ts +176 -4
  639. package/src/shared/storage-busy.test.ts +3 -2
  640. package/src/shared/tag-owner-id.test.ts +33 -0
  641. package/src/shared/tag-owner-id.ts +29 -0
  642. package/src/shared/tag-transcript.ts +17 -3
  643. package/src/shared/test-temp-dir-policy.test.ts +33 -0
  644. package/src/shared/test-temp-dir.test.ts +27 -0
  645. package/src/shared/test-temp-dir.ts +36 -12
  646. package/src/shared/transcript.ts +3 -0
  647. package/src/shared/tui-config.test.ts +6 -5
  648. package/src/shared/tui-preferences.test.ts +3 -2
  649. package/src/shared/user-answer.test.ts +40 -0
  650. package/src/shared/user-answer.ts +17 -0
  651. package/src/shared/user-facing-codes.ts +52 -6
  652. package/src/shared/window-geometry.test.ts +3 -2
  653. package/src/shared/write-transaction-attribution.test.ts +11 -7
  654. package/src/shared/write-transaction-hold-clock.test.ts +160 -0
  655. package/src/shared/xml-unescape.ts +19 -0
  656. package/src/tui/data/context-db.test.ts +92 -4
  657. package/src/tui/data/context-db.ts +184 -18
  658. package/src/tui/data/notification-socket.test.ts +49 -2
  659. package/src/tui/data/notification-socket.ts +47 -9
  660. package/src/tui/data/session-directory.ts +19 -0
  661. package/src/tui/dialogs/status-dialog-render.test.ts +284 -0
  662. package/src/tui/dialogs/status-dialog.tsx +41 -38
  663. package/src/tui/index.tsx +30 -18
  664. package/src/tui/slots/sidebar-content.tsx +9 -2
  665. package/src/tui-compiled/data/context-db.ts +184 -18
  666. package/src/tui-compiled/data/notification-socket.ts +47 -9
  667. package/src/tui-compiled/data/session-directory.ts +19 -0
  668. package/src/tui-compiled/dialogs/status-dialog.tsx +38 -29
  669. package/src/tui-compiled/index.tsx +29 -16
  670. package/src/tui-compiled/slots/sidebar-content.tsx +3 -2
  671. package/src/v2/tui/host-contract.test.ts +9 -10
  672. package/src/v2/tui/index.ts +78 -23
  673. package/src/v2/tui/load-compiled-sidebar.d.mts +5 -1
  674. package/src/v2/tui/load-compiled-status-dialog.d.mts +3 -2
  675. package/src/v2/tui/session-directory.test.ts +53 -0
  676. package/src/v2/tui/sidebar-mount.ts +19 -1
  677. package/src/v2/tui/status-dialog-mount.ts +10 -7
  678. package/src/v2/tui/types.ts +10 -0
  679. package/dist/features/builtin-commands/commands.d.ts.map +0 -1
  680. package/dist/features/builtin-commands/types.d.ts +0 -3
  681. package/dist/features/builtin-commands/types.d.ts.map +0 -1
  682. package/dist/features/magic-context/context-authority.d.ts +0 -272
  683. package/dist/features/magic-context/context-authority.d.ts.map +0 -1
  684. package/dist/features/magic-context/memory/mirror-reembed.d.ts +0 -22
  685. package/dist/features/magic-context/memory/mirror-reembed.d.ts.map +0 -1
  686. package/dist/hooks/magic-context/historian-state-file.d.ts +0 -43
  687. package/dist/hooks/magic-context/historian-state-file.d.ts.map +0 -1
  688. package/dist/index-4an2p8qa.js +0 -1056
  689. package/dist/index-rn7gafjr.js +0 -8
  690. package/dist/index-v6t0tg85.js +0 -13
  691. package/dist/plugin/memory-id-translation.d.ts +0 -109
  692. package/dist/plugin/memory-id-translation.d.ts.map +0 -1
  693. package/dist/plugin/rust-note-backend.d.ts +0 -84
  694. package/dist/plugin/rust-note-backend.d.ts.map +0 -1
  695. package/dist/recomp-orchestrator-19tr6zya.js +0 -22
  696. package/dist/task-config-2bm68628.js +0 -9
  697. package/dist/transform-postprocess-phase-z2mfc5w1.js +0 -36
  698. package/dist/v2/host-service.d.ts +0 -66
  699. package/dist/v2/host-service.d.ts.map +0 -1
  700. package/dist/wrapup-orchestrator-sy4m56a7.js +0 -19
  701. /package/dist/{index-s70wtd8k.js → index-q6hef7fh.js} +0 -0
@@ -23,6 +23,10 @@ const READ_ONLY_DEFERRED_TRANSACTIONS: Record<string, string> = {
23
23
  "reads the latest compaction and the rows after it as one consistent snapshot of the OpenCode 2 store; never writes",
24
24
  "packages/pi-plugin/src/inject-compartments-pi.ts#readFrozenM0InputsPi":
25
25
  "reads the m[0] render sources and their watermarks as one consistent snapshot; never writes",
26
+ "packages/plugin/src/features/magic-context/message-fts-session-filter.ts#withMessageFtsSessionFilter":
27
+ "pins one read snapshot so the session's rowid coverage proof and the filtered message search see the same rows; never writes (read-only connections use it too)",
28
+ "packages/plugin/src/hooks/magic-context/lkg-persist.ts#loadPersistedLkgSlot":
29
+ "reads an LKG slot row and its prefix slices as one consistent snapshot; never writes (a failed verification clears the slot afterwards, outside this transaction)",
26
30
  };
27
31
 
28
32
  const REPOSITORY_ROOT = resolve(import.meta.dir, "../../../..");
@@ -0,0 +1,134 @@
1
+ import { afterAll, beforeAll, describe, expect, test } from "bun:test";
2
+ import { existsSync, mkdirSync, readFileSync, rmSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { createTestTempDirFromPath } from "./test-temp-dir";
6
+
7
+ // The scenario runs in a child process with NODE_ENV=production because the
8
+ // shared logger is silent under test. It imports storage-db for its side effect
9
+ // of registering the real log sink, then drives three privileged writes and one
10
+ // background writer through two connections on a throwaway database:
11
+ // wait - another connection holds the lock for 300 ms, the hold is short
12
+ // hold - the lock comes at once, the operation keeps it for 300 ms
13
+ // fast - neither crosses the threshold, so nothing is logged
14
+ // async - beginSqliteWriterAsync acquires at once and holds for 300 ms
15
+ const scenario = `
16
+ await import(${JSON.stringify(new URL("../features/magic-context/storage-db.ts", import.meta.url).href)});
17
+ const sqlite = await import(${JSON.stringify(new URL("./sqlite.ts", import.meta.url).href)});
18
+ const logger = await import(${JSON.stringify(new URL("./logger.ts", import.meta.url).href)});
19
+ const dbPath = process.env.SCENARIO_DB_PATH;
20
+ const holder = new sqlite.Database(dbPath);
21
+ holder.exec("PRAGMA journal_mode=WAL; CREATE TABLE context_privilege_state(id INTEGER PRIMARY KEY, enabled INTEGER)");
22
+ const writer = new sqlite.Database(dbPath);
23
+ const spin = (ms) => { const end = performance.now() + ms; while (performance.now() < end) {} };
24
+
25
+ holder.exec("BEGIN IMMEDIATE");
26
+ setTimeout(() => holder.exec("COMMIT"), 300);
27
+ await sqlite.withAsyncPrivilegedWriter(writer, () => undefined);
28
+
29
+ await sqlite.withAsyncPrivilegedWriter(writer, () => spin(300));
30
+
31
+ await sqlite.withAsyncPrivilegedWriter(writer, () => undefined);
32
+
33
+ await sqlite.beginSqliteWriterAsync(writer, "historian-publish");
34
+ spin(300);
35
+ writer.exec("COMMIT");
36
+
37
+ logger.flushLogger();
38
+ writer.close();
39
+ holder.close();
40
+ `;
41
+
42
+ let root: string | null = null;
43
+ let logLines: string[] = [];
44
+ let consoleOutput = "";
45
+
46
+ function field(line: string, name: string): number {
47
+ const value = new RegExp(`\\b${name}=(\\d+)`).exec(line)?.[1];
48
+ if (value === undefined) throw new Error(`${name} missing from: ${line}`);
49
+ return Number(value);
50
+ }
51
+
52
+ describe("sqlite writer diagnostics", () => {
53
+ beforeAll(async () => {
54
+ root = createTestTempDirFromPath(join(tmpdir(), "mc-sqlite-writer-diagnostics-"));
55
+ const logPath = join(root, "magic-context.log");
56
+ const env: Record<string, string> = {
57
+ ...(process.env as Record<string, string>),
58
+ NODE_ENV: "production",
59
+ MAGIC_CONTEXT_LOG_PATH: logPath,
60
+ MAGIC_CONTEXT_STORAGE_DIR: join(root, "storage"),
61
+ SCENARIO_DB_PATH: join(root, "writer.db"),
62
+ };
63
+ for (const key of [
64
+ "XDG_DATA_HOME",
65
+ "XDG_CONFIG_HOME",
66
+ "XDG_STATE_HOME",
67
+ "XDG_CACHE_HOME",
68
+ ]) {
69
+ env[key] = join(root, key);
70
+ mkdirSync(env[key]);
71
+ }
72
+ const child = Bun.spawn({
73
+ windowsHide: true,
74
+ cmd: ["bun", "--eval", scenario],
75
+ cwd: import.meta.dir,
76
+ env,
77
+ stdout: "pipe",
78
+ stderr: "pipe",
79
+ });
80
+ const [exitCode, stdout, stderr] = await Promise.all([
81
+ child.exited,
82
+ new Response(child.stdout).text(),
83
+ new Response(child.stderr).text(),
84
+ ]);
85
+ expect(exitCode, stderr).toBe(0);
86
+ consoleOutput = stdout + stderr;
87
+ logLines = existsSync(logPath)
88
+ ? readFileSync(logPath, "utf8")
89
+ .split("\n")
90
+ .filter((line) => line.includes("sqlite writer"))
91
+ : [];
92
+ }, 30_000);
93
+
94
+ afterAll(() => {
95
+ if (root) rmSync(root, { recursive: true, force: true });
96
+ root = null;
97
+ });
98
+
99
+ test("nothing reaches the host console", () => {
100
+ expect(consoleOutput).not.toContain("[magic-context]");
101
+ expect(consoleOutput).not.toContain("sqlite writer");
102
+ });
103
+
104
+ test("a writer that waited for the lock reports the wait, not its short hold", () => {
105
+ const waited = logLines.find((line) => line.includes("attempts=2"));
106
+ if (!waited) throw new Error(`no retried acquisition logged:\n${logLines.join("\n")}`);
107
+ expect(waited).toContain("[magic-context] sqlite writer site=privileged_writer");
108
+ expect(waited).toContain("lane=foreground");
109
+ expect(waited).toContain("outcome=committed");
110
+ expect(field(waited, "acquire_ms")).toBeGreaterThanOrEqual(250);
111
+ expect(field(waited, "hold_ms")).toBeLessThan(250);
112
+ });
113
+
114
+ test("a writer that held the lock reports the hold, not its quick acquisition", () => {
115
+ const held = logLines.filter(
116
+ (line) => line.includes("site=privileged_writer") && line.includes("attempts=1"),
117
+ );
118
+ expect(held).toHaveLength(1);
119
+ expect(field(held[0], "acquire_ms")).toBeLessThan(250);
120
+ expect(field(held[0], "hold_ms")).toBeGreaterThanOrEqual(300);
121
+ });
122
+
123
+ test("an async background writer reports its hold under its own site", () => {
124
+ const held = logLines.filter((line) => line.includes("site=historian-publish"));
125
+ expect(held).toHaveLength(1);
126
+ expect(held[0]).toContain("lane=background");
127
+ expect(field(held[0], "acquire_ms")).toBeLessThan(250);
128
+ expect(field(held[0], "hold_ms")).toBeGreaterThanOrEqual(300);
129
+ });
130
+
131
+ test("a fast writer stays out of the log", () => {
132
+ expect(logLines.filter((line) => line.includes("site=privileged_writer"))).toHaveLength(2);
133
+ });
134
+ });
@@ -62,6 +62,28 @@ export function registerSlowWriteReporter(reporter: SlowWriteReporter): void {
62
62
  reportSlowPrivilegedWrite = reporter;
63
63
  }
64
64
 
65
+ /**
66
+ * Writer acquisition and hold diagnostics are injected the same way. They must
67
+ * reach the Magic Context log file and never the console: OpenCode and Pi pass
68
+ * plugin stderr straight through to the operator's terminal. The storage
69
+ * bootstrap registers the shared logger here; until then these lines are
70
+ * dropped.
71
+ */
72
+ type SqliteDiagnosticSink = (message: string) => void;
73
+ let sqliteDiagnosticSink: SqliteDiagnosticSink | undefined;
74
+
75
+ export function registerSqliteDiagnosticSink(sink: SqliteDiagnosticSink): void {
76
+ sqliteDiagnosticSink = sink;
77
+ }
78
+
79
+ function reportSqliteDiagnostic(message: string): void {
80
+ try {
81
+ sqliteDiagnosticSink?.(`[magic-context] ${message}`);
82
+ } catch {
83
+ // Diagnostics must never change the outcome of the write they describe.
84
+ }
85
+ }
86
+
65
87
  export type SqliteRuntime = "Bun" | "Node.js";
66
88
 
67
89
  type SqliteModule = {
@@ -224,14 +246,43 @@ function installTransactionRouting(db: BetterSqlite3.Database, readonly: boolean
224
246
  writable: true,
225
247
  value: (sql: string) => {
226
248
  if (/^\s*BEGIN\s+(?:IMMEDIATE|EXCLUSIVE)(?:\s+TRANSACTION)?\s*;?\s*$/i.test(sql)) {
249
+ // A transaction that ended without passing through exec (for
250
+ // example an automatic rollback) must not be timed as this one.
251
+ openWriterTransactions.delete(db);
227
252
  if (transformPassScope.getStore()?.active || backgroundWriterScope.getStore())
228
253
  acquireShort(db, () => nativeExec(sql), sql.trim());
229
254
  else nativeExec(sql);
230
255
  return db;
231
256
  }
257
+ if (WRITER_TRANSACTION_END.test(sql) && openWriterTransactions.has(db))
258
+ 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));
232
261
  return nativeExec(sql);
233
262
  },
234
263
  });
264
+ const nativePrepare = db.prepare.bind(db);
265
+ Object.defineProperty(db, "prepare", {
266
+ configurable: true,
267
+ writable: true,
268
+ value: (sql: string) => {
269
+ const statement = nativePrepare(sql);
270
+ // SELECT/EXPLAIN cannot acquire a writer. Treat CTEs conservatively:
271
+ // WITH can introduce INSERT/UPDATE/DELETE as well as a read query.
272
+ if (!readonly && !/^\s*(?:SELECT|EXPLAIN|PRAGMA)\b/i.test(sql)) {
273
+ for (const method of ["run", "get", "all"] as const) {
274
+ const execute = statement[method].bind(statement);
275
+ Object.defineProperty(statement, method, {
276
+ configurable: true,
277
+ // biome-ignore lint/suspicious/noExplicitAny: retain SQLite's native binding overloads.
278
+ value: (...args: any[]) =>
279
+ withAutocommitTimeout(db, () => execute(...args)),
280
+ });
281
+ }
282
+ }
283
+ return statement;
284
+ },
285
+ });
235
286
  Object.defineProperty(db, "transaction", {
236
287
  configurable: true,
237
288
  writable: true,
@@ -490,7 +541,9 @@ export type Database = BetterSqlite3.Database;
490
541
  export type Statement = BetterSqlite3.Statement<unknown[], unknown>;
491
542
 
492
543
  const privilegeDepth = new WeakMap<Database, number>();
493
- const transformPassScope = new AsyncLocalStorage<{ active: boolean } | undefined>();
544
+ const transformPassScope = new AsyncLocalStorage<
545
+ { active: boolean; remainingWaitMs: number } | undefined
546
+ >();
494
547
  const admissionScope = new AsyncLocalStorage<boolean>();
495
548
  const backgroundWriterScope = new AsyncLocalStorage<boolean>();
496
549
 
@@ -502,7 +555,9 @@ export function withSqliteBackgroundWriter<T>(operation: () => T): T {
502
555
  /** Only an awaited foreground transform may spend the extra acquisition budget.
503
556
  * The mutable lease also expires for detached descendants when that pass ends. */
504
557
  export function withSqliteTransformPass<T>(operation: () => T): T {
505
- const lease = { active: true };
558
+ const existing = transformPassScope.getStore();
559
+ if (existing?.active) return operation();
560
+ const lease = { active: true, remainingWaitMs: FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS };
506
561
  return transformPassScope.run(lease, () => {
507
562
  try {
508
563
  const result = operation();
@@ -548,60 +603,182 @@ export class SqliteAcquisitionBusyError extends Error {
548
603
  const SHORT_BUSY_TIMEOUT_MS = 25;
549
604
  const FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS = 250;
550
605
  const FOREGROUND_ACQUISITION_BUDGET_MS = 16_500;
606
+ /** Waiting this long for the writer lock, or holding it this long, is logged. */
607
+ const SLOW_WRITER_LOG_MS = 250;
608
+ const WRITER_TRANSACTION_END = /^\s*(?:COMMIT|END|ROLLBACK)(?:\s+TRANSACTION)?\s*;?\s*$/i;
609
+
610
+ type WriterLane = "foreground" | "background";
611
+
612
+ /**
613
+ * One attempt of an outer acquisition loop (`beginSqliteWriterAsync`,
614
+ * `withAsyncPrivilegedWriter`). It names the writer and remembers when the loop
615
+ * started, so the time spent in earlier busy attempts and the sleeps between
616
+ * them counts as waiting for the lock. Only the first BEGIN issued inside the
617
+ * attempt may claim it; a later BEGIN from detached work started inside the
618
+ * same async scope is timed on its own.
619
+ */
620
+ interface WriterAcquisition {
621
+ site: string;
622
+ lane: WriterLane;
623
+ startedAt: number;
624
+ attempts: number;
625
+ claimed: boolean;
626
+ }
627
+
628
+ /** A write transaction whose BEGIN went through `acquireShort` and has not ended yet. */
629
+ interface OpenWriterTransaction {
630
+ site: string;
631
+ lane: WriterLane;
632
+ acquireMs: number;
633
+ attempts: number;
634
+ acquiredAt: number;
635
+ }
636
+
637
+ const writerAcquisitionScope = new AsyncLocalStorage<WriterAcquisition | undefined>();
638
+ const openWriterTransactions = new WeakMap<Database, OpenWriterTransaction>();
639
+
640
+ function foregroundWaitLease() {
641
+ const lease = transformPassScope.getStore();
642
+ return lease?.active && !admissionScope.getStore() && !backgroundWriterScope.getStore()
643
+ ? lease
644
+ : undefined;
645
+ }
646
+
647
+ /** Bound implicit writer admission too, including prepared INSERT OR IGNORE and
648
+ * writes with RETURNING. Charge successful execution time conservatively: the
649
+ * native API cannot separate lock waiting from statement execution. Exhaustion
650
+ * switches to zero-wait acquisition, not a refusal when the writer is free. */
651
+ function withAutocommitTimeout<T>(db: Database, operation: () => T): T {
652
+ const lease = foregroundWaitLease();
653
+ if (isInTransaction(db) || (!lease && !backgroundWriterScope.getStore())) return operation();
654
+ const previous = pragmaNumber(db, "busy_timeout");
655
+ db.exec(
656
+ `PRAGMA busy_timeout=${lease ? Math.floor(lease.remainingWaitMs) : SHORT_BUSY_TIMEOUT_MS}`,
657
+ );
658
+ const started = performance.now();
659
+ try {
660
+ return operation();
661
+ } catch (error) {
662
+ if (lease && isTransientSqliteError(error))
663
+ throw new SqliteAcquisitionBusyError(error, "autocommit");
664
+ throw error;
665
+ } finally {
666
+ if (lease)
667
+ lease.remainingWaitMs = Math.max(
668
+ 0,
669
+ lease.remainingWaitMs - (performance.now() - started),
670
+ );
671
+ if (previous !== null) db.exec(`PRAGMA busy_timeout=${previous}`);
672
+ }
673
+ }
551
674
 
552
675
  /** The connection is never handed back to another caller with a shortened timeout. */
553
676
  function acquireShort(db: Database, acquire: () => unknown, site: string): void {
554
677
  const started = performance.now();
555
678
  const previous = pragmaNumber(db, "busy_timeout");
556
- let acquired = false;
679
+ const outer = writerAcquisitionScope.getStore();
680
+ const owner = outer && !outer.claimed ? outer : undefined;
681
+ if (owner) owner.claimed = true;
682
+ const writerSite = owner?.site ?? site;
683
+ const lane: WriterLane =
684
+ owner?.lane ?? (transformPassScope.getStore()?.active ? "foreground" : "background");
685
+ let acquiredAt: number | undefined;
557
686
  try {
558
687
  // Async admission retries after yielding, so each of its BEGIN attempts
559
688
  // stays short. An ordinary BEGIN inside a transform pass cannot yield;
560
689
  // give that single attempt enough time for a brief writer to finish.
561
- const timeout =
562
- transformPassScope.getStore()?.active &&
563
- !admissionScope.getStore() &&
564
- !backgroundWriterScope.getStore()
565
- ? FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS
566
- : SHORT_BUSY_TIMEOUT_MS;
690
+ const lease = foregroundWaitLease();
691
+ const timeout = lease ? Math.floor(lease.remainingWaitMs) : SHORT_BUSY_TIMEOUT_MS;
567
692
  db.exec(`PRAGMA busy_timeout=${timeout}`);
568
693
  acquire();
569
- acquired = true;
694
+ acquiredAt = performance.now();
570
695
  } catch (error) {
571
696
  if (transformPassScope.getStore()?.active && isTransientSqliteError(error))
572
697
  throw new SqliteAcquisitionBusyError(error, site);
573
698
  throw error;
574
699
  } finally {
700
+ const attemptMs = (acquiredAt ?? performance.now()) - started;
701
+ const lease = foregroundWaitLease();
702
+ if (lease) lease.remainingWaitMs = Math.max(0, lease.remainingWaitMs - attemptMs);
575
703
  if (previous !== null) db.exec(`PRAGMA busy_timeout=${previous}`);
576
- const elapsed = performance.now() - started;
577
- if (elapsed >= 250)
578
- console.warn(
579
- `[${new Date().toISOString()}] [magic-context] sqlite acquisition site=${site} lane=${transformPassScope.getStore()?.active ? "foreground" : "background"} elapsed=${Math.round(elapsed)}ms attempts=1 outcome=${acquired ? "acquired" : "busy"}`,
704
+ if (acquiredAt !== undefined) {
705
+ // Reported when the transaction ends, together with how long it held
706
+ // the lock (see endWriterTransaction).
707
+ openWriterTransactions.set(db, {
708
+ site: writerSite,
709
+ lane,
710
+ acquireMs: acquiredAt - (owner?.startedAt ?? started),
711
+ attempts: owner?.attempts ?? 1,
712
+ acquiredAt,
713
+ });
714
+ } else if (attemptMs >= SLOW_WRITER_LOG_MS) {
715
+ reportSqliteDiagnostic(
716
+ `sqlite writer site=${writerSite} lane=${lane} acquire_ms=${Math.round(attemptMs)} attempts=${owner?.attempts ?? 1} outcome=busy`,
580
717
  );
718
+ }
719
+ }
720
+ }
721
+
722
+ /**
723
+ * Run the COMMIT, END or ROLLBACK that closes a transaction opened through
724
+ * `acquireShort`, then report how long the writer waited for the lock
725
+ * (`acquire_ms`) and how long it then held it (`hold_ms`) when either crosses
726
+ * the threshold. A long hold blocks every other process's writer, so it is
727
+ * worth seeing even when the lock itself came quickly.
728
+ */
729
+ function endWriterTransaction(db: Database, end: () => unknown, sql: string): unknown {
730
+ let ended = false;
731
+ try {
732
+ const result = end();
733
+ ended = true;
734
+ return result;
735
+ } finally {
736
+ const open = openWriterTransactions.get(db);
737
+ // A COMMIT that failed with the transaction still open has not ended it.
738
+ if (open && !isInTransaction(db)) {
739
+ openWriterTransactions.delete(db);
740
+ const holdMs = performance.now() - open.acquiredAt;
741
+ if (open.acquireMs >= SLOW_WRITER_LOG_MS || holdMs >= SLOW_WRITER_LOG_MS) {
742
+ const outcome = /^\s*ROLLBACK/i.test(sql)
743
+ ? "rolled_back"
744
+ : ended
745
+ ? "committed"
746
+ : "failed";
747
+ reportSqliteDiagnostic(
748
+ `sqlite writer site=${open.site} lane=${open.lane} acquire_ms=${Math.round(open.acquireMs)} hold_ms=${Math.round(holdMs)} attempts=${open.attempts} outcome=${outcome}`,
749
+ );
750
+ }
751
+ }
581
752
  }
582
753
  }
583
754
 
584
755
  /** Begin an immediate transaction with bounded asynchronous retries on writer contention.
585
- * Callers must recheck any lease or source snapshot after this function returns. */
586
- export async function beginSqliteWriterAsync(db: Database, site: string): Promise<void> {
756
+ * Callers must recheck any lease or source snapshot after this function returns.
757
+ * Resolves with the `performance.now()` time at which BEGIN IMMEDIATE succeeded,
758
+ * so a caller timing its transaction measures the hold, not the wait for the lock. */
759
+ export async function beginSqliteWriterAsync(db: Database, site: string): Promise<number> {
587
760
  const started = performance.now();
588
761
  let attempts = 0;
589
762
  for (;;) {
590
763
  attempts++;
591
764
  try {
592
- withSqliteBackgroundWriter(() => db.exec("BEGIN IMMEDIATE"));
593
- const elapsed = performance.now() - started;
594
- if (elapsed >= 250)
595
- console.warn(
596
- `[${new Date().toISOString()}] [magic-context] sqlite acquisition site=${site} lane=background elapsed=${Math.round(elapsed)}ms attempts=${attempts} outcome=acquired`,
597
- );
598
- return;
765
+ const acquisition: WriterAcquisition = {
766
+ site,
767
+ lane: "background",
768
+ startedAt: started,
769
+ attempts,
770
+ claimed: false,
771
+ };
772
+ writerAcquisitionScope.run(acquisition, () =>
773
+ withSqliteBackgroundWriter(() => db.exec("BEGIN IMMEDIATE")),
774
+ );
775
+ return performance.now();
599
776
  } catch (error) {
600
777
  if (!isTransientSqliteError(error)) throw error;
601
778
  const elapsed = performance.now() - started;
602
779
  if (elapsed >= FOREGROUND_ACQUISITION_BUDGET_MS) {
603
- console.warn(
604
- `[${new Date().toISOString()}] [magic-context] sqlite acquisition site=${site} lane=background elapsed=${Math.round(elapsed)}ms attempts=${attempts} outcome=busy`,
780
+ reportSqliteDiagnostic(
781
+ `sqlite writer site=${site} lane=background acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`,
605
782
  );
606
783
  throw error;
607
784
  }
@@ -625,27 +802,31 @@ export async function withAsyncPrivilegedWriter<T>(db: Database, operation: () =
625
802
  for (;;) {
626
803
  attempts++;
627
804
  try {
628
- const result = admissionScope.run(true, () =>
629
- withSqliteTransformPass(() => withPrivilegedWriter(db, operation)),
805
+ const acquisition: WriterAcquisition = {
806
+ site: "privileged_writer",
807
+ lane: "foreground",
808
+ startedAt: started,
809
+ attempts,
810
+ claimed: false,
811
+ };
812
+ // The acquisition and hold of this transaction are reported when it
813
+ // commits or rolls back (see endWriterTransaction).
814
+ return admissionScope.run(true, () =>
815
+ withSqliteTransformPass(() =>
816
+ writerAcquisitionScope.run(acquisition, () =>
817
+ withPrivilegedWriter(db, operation),
818
+ ),
819
+ ),
630
820
  );
631
- const elapsed = performance.now() - started;
632
- if (elapsed >= 250)
633
- console.warn(
634
- `[${new Date().toISOString()}] [magic-context] sqlite acquisition site=privileged_writer lane=foreground elapsed=${Math.round(elapsed)}ms attempts=${attempts} outcome=acquired`,
635
- );
636
- return result;
637
821
  } catch (error) {
638
822
  // A callback failure can occur after writes; only retry a failed BEGIN.
639
823
  if (!(error instanceof SqliteAcquisitionBusyError)) throw error;
640
824
  const elapsed = performance.now() - started;
641
825
  if (elapsed >= FOREGROUND_ACQUISITION_BUDGET_MS) {
642
- if (elapsed >= 250)
643
- console.warn(
644
- `[${new Date().toISOString()}] [magic-context] sqlite acquisition site=privileged_writer lane=foreground elapsed=${Math.round(elapsed)}ms attempts=${attempts} outcome=busy`,
645
- );
646
- throw error instanceof SqliteAcquisitionBusyError
647
- ? error
648
- : new SqliteAcquisitionBusyError(error);
826
+ reportSqliteDiagnostic(
827
+ `sqlite writer site=privileged_writer lane=foreground acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`,
828
+ );
829
+ throw error;
649
830
  }
650
831
  await new Promise<void>((resolve) =>
651
832
  setTimeout(
@@ -680,7 +861,9 @@ export function withPrivilegedWriter<T>(db: Database, operation: () => T): T {
680
861
  const previousDepth = privilegeDepth.get(db) ?? 0;
681
862
  const nested = isInTransaction(db);
682
863
  const savepoint = "mc_privilege_scope";
683
- const transactionStartedAt = nested ? undefined : performance.now();
864
+ // Timed from the moment the lock is held, so a slow-write report measures
865
+ // the hold and not the wait for BEGIN IMMEDIATE.
866
+ let transactionStartedAt: number | undefined;
684
867
  if (nested) {
685
868
  db.exec(`SAVEPOINT ${savepoint}`);
686
869
  } else {
@@ -691,6 +874,7 @@ export function withPrivilegedWriter<T>(db: Database, operation: () => T): T {
691
874
  throw new SqliteAcquisitionBusyError(error);
692
875
  throw error;
693
876
  }
877
+ transactionStartedAt = performance.now();
694
878
  }
695
879
  privilegeDepth.set(db, previousDepth + 1);
696
880
  try {
@@ -0,0 +1,129 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from "bun:test";
2
+ import { bindStaleBuildNotice } from "../plugin/stale-build-notice";
3
+ import { __resetNotificationStateForTests, drainNotifications } from "./rpc-notifications";
4
+ import {
5
+ classifyStalePluginBuild,
6
+ importPluginModule,
7
+ registerStalePluginBuildHost,
8
+ StalePluginBuildError,
9
+ stalePluginBuildDiagnostic,
10
+ } from "./stale-plugin-build";
11
+
12
+ function reset(): void {
13
+ delete (globalThis as Record<symbol, unknown>)[Symbol.for("magic-context.stale-plugin-build")];
14
+ __resetNotificationStateForTests();
15
+ }
16
+ beforeEach(reset);
17
+ afterEach(reset);
18
+
19
+ const dist = "/tmp/magic-context/fixture/packages/pi-plugin/dist";
20
+ const missing = (path: string) =>
21
+ new Error(`Cannot find module '${path}' imported from ${dist}/index.js`);
22
+
23
+ describe("stale plugin build classification", () => {
24
+ it("recognizes Node, Bun, file URLs and relative imports only inside the loaded package dist", () => {
25
+ registerStalePluginBuildHost({ moduleUrl: `file://${dist}/index.js`, harness: "pi" });
26
+ for (const error of [
27
+ missing(`${dist}/index-old.js`),
28
+ missing(`file://${dist}/index-old.js`),
29
+ new Error(`Cannot find module './index-old.js' from '${dist}/index.js'`),
30
+ `BuildMessage: ENOENT reading "${dist}/index-old.js"`,
31
+ ]) {
32
+ expect(classifyStalePluginBuild(error)?.chunk).toBe(`${dist}/index-old.js`);
33
+ }
34
+ for (const error of [
35
+ missing("quickjs-emscripten"),
36
+ missing(`${dist}-other/index-old.js`),
37
+ missing(`${dist}/../src/index-old.js`),
38
+ missing("/another/package/dist/index-old.js"),
39
+ new Error(`ENOENT: no such file or directory, open '${dist}/note.txt'`),
40
+ new Error(`network error mentioning ${dist}/index-old.js`),
41
+ new Error(`Cannot find module '../src/missing.js' from '${dist}/index.js'`),
42
+ ])
43
+ expect(classifyStalePluginBuild(error)).toBeNull();
44
+ });
45
+
46
+ it("recognizes Windows paths without confusing an external package for our dist", () => {
47
+ registerStalePluginBuildHost({
48
+ moduleUrl: "file:///C:/dev/pi-plugin/dist/index.js",
49
+ harness: "pi",
50
+ });
51
+ expect(
52
+ classifyStalePluginBuild(missing("C:\\dev\\pi-plugin\\dist\\index-old.js"))?.chunk,
53
+ ).toBe("c:/dev/pi-plugin/dist/index-old.js");
54
+ expect(classifyStalePluginBuild(missing("C:\\other\\dist\\index-old.js"))).toBeNull();
55
+ });
56
+
57
+ it("does not classify source-mode missing modules using the error's dist path", () => {
58
+ registerStalePluginBuildHost({
59
+ moduleUrl: "file:///tmp/plugin/src/index.ts",
60
+ harness: "pi",
61
+ });
62
+ expect(classifyStalePluginBuild(missing(`${dist}/index-old.js`))).toBeNull();
63
+ });
64
+
65
+ it("warns once per process and logs once per missing chunk across registrations and wakes", () => {
66
+ const notices: string[] = [];
67
+ const host = {
68
+ moduleUrl: `file://${dist}/index.js`,
69
+ harness: "pi" as const,
70
+ notify: (message: string) => notices.push(message),
71
+ };
72
+ registerStalePluginBuildHost(host);
73
+ const error = missing(`${dist}/index-first.js`);
74
+ expect(stalePluginBuildDiagnostic(error)).toContain("stale plugin build");
75
+ registerStalePluginBuildHost(host); // Another instance or a reload.
76
+ expect(stalePluginBuildDiagnostic(error)).toBeNull();
77
+ expect(stalePluginBuildDiagnostic(`dry-run failed: ${error.message}`)).toBeNull();
78
+ expect(stalePluginBuildDiagnostic(missing(`${dist}/index-second.js`))).toContain(
79
+ "index-second.js",
80
+ );
81
+ expect(notices).toEqual([
82
+ "Magic Context was rebuilt while this Pi was running; type /reload to load the new build",
83
+ ]);
84
+ expect(stalePluginBuildDiagnostic(new Error(notices[0]))).toBeNull();
85
+ });
86
+
87
+ it("delivers an early failure when the Pi UI becomes available, without logging it again", () => {
88
+ const notices: string[] = [];
89
+ registerStalePluginBuildHost({ moduleUrl: `file://${dist}/index.js`, harness: "pi" });
90
+ expect(stalePluginBuildDiagnostic(missing(`${dist}/index-first.js`))).toContain(
91
+ "stale plugin build",
92
+ );
93
+ registerStalePluginBuildHost({
94
+ moduleUrl: `file://${dist}/index.js`,
95
+ harness: "pi",
96
+ notify: (message) => notices.push(message),
97
+ });
98
+ expect(stalePluginBuildDiagnostic(missing(`${dist}/index-first.js`))).toBeNull();
99
+ expect(notices).toHaveLength(1);
100
+ });
101
+
102
+ it("queues useful OpenCode 2 guidance even without the legacy SDK toast API", () => {
103
+ bindStaleBuildNotice({}, "file:///tmp/plugin/dist/v2/server.js", "opencode2");
104
+ stalePluginBuildDiagnostic(missing("/tmp/plugin/dist/v2/index-old.js"));
105
+ stalePluginBuildDiagnostic(missing("/tmp/plugin/dist/v2/index-old.js"));
106
+ const notifications = drainNotifications();
107
+ expect(notifications).toHaveLength(1);
108
+ expect(notifications[0].payload.message).toBe(
109
+ "Magic Context was rebuilt while this OpenCode host was running; restart the host to load the new build",
110
+ );
111
+ });
112
+
113
+ it("guards arbitrary lazy imports while preserving unrelated errors", async () => {
114
+ registerStalePluginBuildHost({ moduleUrl: `file://${dist}/index.js`, harness: "pi" });
115
+ const error = missing(`${dist}/index-old.js`);
116
+ await expect(
117
+ importPluginModule(async () => {
118
+ throw error;
119
+ }),
120
+ ).rejects.toBeInstanceOf(StalePluginBuildError);
121
+ const unrelated = missing("an-external-dependency");
122
+ await expect(
123
+ importPluginModule(async () => {
124
+ throw unrelated;
125
+ }),
126
+ ).rejects.toBe(unrelated);
127
+ expect(await importPluginModule(async () => 4)).toBe(4);
128
+ });
129
+ });