@cortexkit/opencode-magic-context 0.41.4 → 0.42.1

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 (358) hide show
  1. package/README.md +21 -3
  2. package/dist/agents/hidden-agent-registrations.d.ts +1 -3
  3. package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
  4. package/dist/agents/magic-context-prompt.d.ts +1 -1
  5. package/dist/agents/magic-context-prompt.d.ts.map +1 -1
  6. package/dist/agents/permissions.d.ts +1 -22
  7. package/dist/agents/permissions.d.ts.map +1 -1
  8. package/dist/config/agent-disable.d.ts +0 -5
  9. package/dist/config/agent-disable.d.ts.map +1 -1
  10. package/dist/config/index.d.ts +5 -0
  11. package/dist/config/index.d.ts.map +1 -1
  12. package/dist/config/migrate-config-location.d.ts.map +1 -1
  13. package/dist/config/project-security.d.ts +20 -2
  14. package/dist/config/project-security.d.ts.map +1 -1
  15. package/dist/config/removed-agent-config.d.ts +8 -0
  16. package/dist/config/removed-agent-config.d.ts.map +1 -0
  17. package/dist/config/schema/magic-context.d.ts +43 -201
  18. package/dist/config/schema/magic-context.d.ts.map +1 -1
  19. package/dist/{conflict-warning-hook-ejkc9sjn.js → conflict-warning-hook-6p3xqeac.js} +3 -3
  20. package/dist/{derive-budgets-bc366cz8.js → derive-budgets-s2pgnnm4.js} +1 -1
  21. package/dist/features/builtin-commands/commands.d.ts +0 -4
  22. package/dist/features/builtin-commands/commands.d.ts.map +1 -1
  23. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  24. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +15 -4
  25. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  26. package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
  27. package/dist/features/magic-context/context-authority.d.ts +31 -4
  28. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  29. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  30. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  31. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  32. package/dist/features/magic-context/dreamer/open-opencode-db.d.ts.map +1 -1
  33. package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
  34. package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts +19 -9
  35. package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts.map +1 -1
  36. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  37. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  38. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +4 -0
  39. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  40. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  41. package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
  42. package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts.map +1 -1
  43. package/dist/features/magic-context/index.d.ts +0 -1
  44. package/dist/features/magic-context/index.d.ts.map +1 -1
  45. package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
  46. package/dist/features/magic-context/memory/embedding-local.d.ts +13 -0
  47. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  48. package/dist/features/magic-context/memory/embedding-model-match.d.ts +41 -0
  49. package/dist/features/magic-context/memory/embedding-model-match.d.ts.map +1 -0
  50. package/dist/features/magic-context/memory/embedding-openai.d.ts +7 -20
  51. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  52. package/dist/features/magic-context/memory/embedding-provider.d.ts +2 -2
  53. package/dist/features/magic-context/memory/embedding-provider.d.ts.map +1 -1
  54. package/dist/features/magic-context/memory/embedding-synapse.d.ts +48 -14
  55. package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
  56. package/dist/features/magic-context/memory/embedding.d.ts +1 -1
  57. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
  58. package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
  59. package/dist/features/magic-context/memory/project-identity.d.ts +1 -0
  60. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  61. package/dist/features/magic-context/memory/promotion.d.ts +7 -1
  62. package/dist/features/magic-context/memory/promotion.d.ts.map +1 -1
  63. package/dist/features/magic-context/merged-reasoning-decisions.d.ts +6 -0
  64. package/dist/features/magic-context/merged-reasoning-decisions.d.ts.map +1 -0
  65. package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -1
  66. package/dist/features/magic-context/message-index-async.d.ts +12 -0
  67. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  68. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  69. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  70. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  71. package/dist/features/magic-context/mural/render-trigger.d.ts +6 -0
  72. package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
  73. package/dist/features/magic-context/no-content-compartment.d.ts +12 -0
  74. package/dist/features/magic-context/no-content-compartment.d.ts.map +1 -0
  75. package/dist/features/magic-context/pi-content-decisions.d.ts +9 -0
  76. package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -0
  77. package/dist/features/magic-context/project-docs-hash.d.ts +4 -0
  78. package/dist/features/magic-context/project-docs-hash.d.ts.map +1 -1
  79. package/dist/features/magic-context/project-embedding-registry.d.ts +13 -4
  80. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  81. package/dist/features/magic-context/protection-window.d.ts +79 -0
  82. package/dist/features/magic-context/protection-window.d.ts.map +1 -0
  83. package/dist/features/magic-context/search.d.ts.map +1 -1
  84. package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
  85. package/dist/features/magic-context/shadow-backfill-state.d.ts +26 -0
  86. package/dist/features/magic-context/shadow-backfill-state.d.ts.map +1 -0
  87. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  88. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +4 -0
  89. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
  90. package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
  91. package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
  92. package/dist/features/magic-context/storage-db.d.ts +1 -1
  93. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  94. package/dist/features/magic-context/storage-embedding-measurements.d.ts +2 -2
  95. package/dist/features/magic-context/storage-embedding-measurements.d.ts.map +1 -1
  96. package/dist/features/magic-context/storage-historian-runs.d.ts +4 -0
  97. package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
  98. package/dist/features/magic-context/storage-memory-mutation-log.d.ts +1 -0
  99. package/dist/features/magic-context/storage-memory-mutation-log.d.ts.map +1 -1
  100. package/dist/features/magic-context/storage-meta-persisted.d.ts +79 -13
  101. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  102. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  103. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  104. package/dist/features/magic-context/storage-native-replay.d.ts +29 -0
  105. package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -0
  106. package/dist/features/magic-context/storage-notes.d.ts +6 -0
  107. package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
  108. package/dist/features/magic-context/storage-replay-document.d.ts +33 -0
  109. package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -0
  110. package/dist/features/magic-context/storage-subagent-invocations.d.ts +1 -1
  111. package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -1
  112. package/dist/features/magic-context/storage-tags.d.ts +19 -11
  113. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  114. package/dist/features/magic-context/storage.d.ts +3 -3
  115. package/dist/features/magic-context/storage.d.ts.map +1 -1
  116. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
  117. package/dist/features/magic-context/tagger.d.ts +13 -0
  118. package/dist/features/magic-context/tagger.d.ts.map +1 -1
  119. package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
  120. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  121. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
  122. package/dist/features/magic-context/workspaces.d.ts.map +1 -1
  123. package/dist/hooks/magic-context/apply-operations.d.ts +11 -5
  124. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  125. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  126. package/dist/hooks/magic-context/cache-busting-signals.d.ts +9 -1
  127. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
  128. package/dist/hooks/magic-context/caveman-cleanup.d.ts +1 -1
  129. package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
  130. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  131. package/dist/hooks/magic-context/child-session-spawn.d.ts +3 -3
  132. package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
  133. package/dist/hooks/magic-context/command-handler.d.ts +1 -10
  134. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  135. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  136. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +10 -21
  137. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
  138. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  139. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
  140. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  141. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +1 -1
  142. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  143. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +26 -2
  144. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
  145. package/dist/hooks/magic-context/decay-render.d.ts.map +1 -1
  146. package/dist/hooks/magic-context/dropped-input-guard.d.ts +9 -0
  147. package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -0
  148. package/dist/hooks/magic-context/embed-session-state.d.ts +1 -1
  149. package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
  150. package/dist/hooks/magic-context/emergency-drop.d.ts +6 -1
  151. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  152. package/dist/hooks/magic-context/event-handler.d.ts +0 -1
  153. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  154. package/dist/hooks/magic-context/event-payloads.d.ts +7 -6
  155. package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
  156. package/dist/hooks/magic-context/event-resolvers.d.ts +1 -1
  157. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  158. package/dist/hooks/magic-context/execute-status.d.ts +3 -1
  159. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  160. package/dist/hooks/magic-context/format-embed-failure.d.ts +2 -1
  161. package/dist/hooks/magic-context/format-embed-failure.d.ts.map +1 -1
  162. package/dist/hooks/magic-context/format-embed-status.d.ts.map +1 -1
  163. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +7 -1
  164. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  165. package/dist/hooks/magic-context/hook-handlers.d.ts +3 -1
  166. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  167. package/dist/hooks/magic-context/hook.d.ts +13 -4
  168. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  169. package/dist/hooks/magic-context/inject-compartments.d.ts +14 -1
  170. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  171. package/dist/hooks/magic-context/live-session-state.d.ts +1 -1
  172. package/dist/hooks/magic-context/lkg-slot.d.ts +34 -0
  173. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  174. package/dist/hooks/magic-context/maintenance-authority.d.ts +2 -2
  175. package/dist/hooks/magic-context/maintenance-authority.d.ts.map +1 -1
  176. package/dist/hooks/magic-context/module-state-sync-timing.d.ts +21 -0
  177. package/dist/hooks/magic-context/module-state-sync-timing.d.ts.map +1 -0
  178. package/dist/hooks/magic-context/module-state-sync.d.ts +21 -7
  179. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  180. package/dist/hooks/magic-context/module-transport.d.ts +12 -0
  181. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  182. package/dist/hooks/magic-context/module-wire.d.ts +8 -0
  183. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  184. package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
  185. package/dist/hooks/magic-context/persist-filtered-noise.d.ts +5 -0
  186. package/dist/hooks/magic-context/persist-filtered-noise.d.ts.map +1 -0
  187. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +6 -0
  188. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  189. package/dist/hooks/magic-context/read-session-chunk.d.ts +18 -18
  190. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  191. package/dist/hooks/magic-context/read-session-db.d.ts +22 -12
  192. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  193. package/dist/hooks/magic-context/read-session-formatting.d.ts +8 -0
  194. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  195. package/dist/hooks/magic-context/read-session-raw.d.ts +10 -1
  196. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  197. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  198. package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
  199. package/dist/hooks/magic-context/rust-mode-transform.d.ts +74 -9
  200. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  201. package/dist/hooks/magic-context/send-session-notification.d.ts +11 -10
  202. package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
  203. package/dist/hooks/magic-context/strip-content.d.ts +7 -0
  204. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  205. package/dist/hooks/magic-context/supersession-reclaim.d.ts +13 -0
  206. package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
  207. package/dist/hooks/magic-context/system-prompt-hash.d.ts +2 -3
  208. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  209. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +8 -3
  210. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  211. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  212. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  213. package/dist/hooks/magic-context/transform-context-state.d.ts +7 -1
  214. package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
  215. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +11 -4
  216. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  217. package/dist/hooks/magic-context/transform.d.ts +7 -2
  218. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  219. package/dist/hooks/magic-context/upgrade-reminder.d.ts +7 -9
  220. package/dist/hooks/magic-context/upgrade-reminder.d.ts.map +1 -1
  221. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  222. package/dist/index-1974jvn3.js +783 -0
  223. package/dist/{index-0y2mcg5y.js → index-1q9kay7n.js} +18717 -16197
  224. package/dist/{index-4avmwfp5.js → index-36wd1d6k.js} +6 -29
  225. package/dist/{index-fz104x1j.js → index-jmtjh2d3.js} +3 -3
  226. package/dist/{index-q264erdp.js → index-nqgjwfzn.js} +70 -38
  227. package/dist/{index-mjv9je4e.js → index-xdtge3y2.js} +45 -7
  228. package/dist/index.d.ts.map +1 -1
  229. package/dist/index.js +6457 -5190
  230. package/dist/plugin/conflict-warning-hook.d.ts +5 -6
  231. package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
  232. package/dist/plugin/dream-timer.d.ts +1 -0
  233. package/dist/plugin/dream-timer.d.ts.map +1 -1
  234. package/dist/plugin/embedding-bootstrap-helpers.d.ts.map +1 -1
  235. package/dist/plugin/embedding-routing.d.ts +4 -1
  236. package/dist/plugin/embedding-routing.d.ts.map +1 -1
  237. package/dist/plugin/hooks/create-session-hooks.d.ts +16 -2
  238. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  239. package/dist/plugin/rpc-handlers.d.ts +31 -1
  240. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  241. package/dist/plugin/rust-tool-backends.d.ts +1 -0
  242. package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
  243. package/dist/plugin/tool-registry.d.ts.map +1 -1
  244. package/dist/{recomp-orchestrator-q98r6rga.js → recomp-orchestrator-m33b3rk9.js} +5 -5
  245. package/dist/{send-session-notification-hdh02wy9.js → send-session-notification-1qeqkswb.js} +6 -4
  246. package/dist/shared/child-session-teardown.d.ts +34 -0
  247. package/dist/shared/child-session-teardown.d.ts.map +1 -0
  248. package/dist/shared/keep-subagents.d.ts +1 -1
  249. package/dist/shared/keep-subagents.d.ts.map +1 -1
  250. package/dist/shared/model-suggestion-retry.d.ts +1 -1
  251. package/dist/shared/opencode-db-path.d.ts +24 -0
  252. package/dist/shared/opencode-db-path.d.ts.map +1 -0
  253. package/dist/shared/prompt-surface-runtime.d.ts +10 -5
  254. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
  255. package/dist/shared/resolve-fallbacks.d.ts +1 -1
  256. package/dist/shared/rpc-types.d.ts +121 -0
  257. package/dist/shared/rpc-types.d.ts.map +1 -1
  258. package/dist/shared/sqlite.d.ts +42 -0
  259. package/dist/shared/sqlite.d.ts.map +1 -1
  260. package/dist/shared/status-detail-text.d.ts +3 -1
  261. package/dist/shared/status-detail-text.d.ts.map +1 -1
  262. package/dist/shared/status-summary.d.ts +30 -0
  263. package/dist/shared/status-summary.d.ts.map +1 -0
  264. package/dist/shared/subagent-runner.d.ts +17 -10
  265. package/dist/shared/subagent-runner.d.ts.map +1 -1
  266. package/dist/shared/tag-transcript.d.ts.map +1 -1
  267. package/dist/shared/tail-hygiene-status.d.ts +1 -0
  268. package/dist/shared/tail-hygiene-status.d.ts.map +1 -1
  269. package/dist/shared/transcript.d.ts +6 -0
  270. package/dist/shared/transcript.d.ts.map +1 -1
  271. package/dist/shared/user-facing-codes.d.ts +191 -0
  272. package/dist/shared/user-facing-codes.d.ts.map +1 -0
  273. package/dist/shared/window-geometry.d.ts +23 -0
  274. package/dist/shared/window-geometry.d.ts.map +1 -1
  275. package/dist/shared/write-transaction-timing.d.ts +1 -1
  276. package/dist/shared/write-transaction-timing.d.ts.map +1 -1
  277. package/dist/{storage-meta-session-dvwfw778.js → storage-meta-session-e6g0mmec.js} +2 -2
  278. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  279. package/dist/tools/ctx-memory/verification-recording.d.ts.map +1 -1
  280. package/dist/tools/ctx-note/constants.d.ts +1 -1
  281. package/dist/tools/ctx-note/constants.d.ts.map +1 -1
  282. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  283. package/dist/tools/ctx-note/types.d.ts +1 -0
  284. package/dist/tools/ctx-note/types.d.ts.map +1 -1
  285. package/dist/tools/ctx-reduce/tools.d.ts +10 -1
  286. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  287. package/dist/tools/ctx-search/constants.d.ts +1 -1
  288. package/dist/tools/ctx-search/constants.d.ts.map +1 -1
  289. package/dist/tools/light-descriptions.d.ts +2 -2
  290. package/dist/tools/light-descriptions.d.ts.map +1 -1
  291. package/package.json +2 -3
  292. package/src/agents/hidden-agent-registrations.ts +3 -15
  293. package/src/agents/magic-context-prompt.test.ts +7 -5
  294. package/src/agents/magic-context-prompt.ts +22 -30
  295. package/src/agents/permissions.test.ts +1 -42
  296. package/src/agents/permissions.ts +1 -24
  297. package/src/config/agent-disable.ts +5 -22
  298. package/src/config/index.test.ts +126 -15
  299. package/src/config/index.ts +41 -6
  300. package/src/config/latch-permanence-guard.test.ts +4 -0
  301. package/src/config/migrate-config-location.test.ts +39 -6
  302. package/src/config/migrate-config-location.ts +18 -31
  303. package/src/config/profiles.ts +1 -1
  304. package/src/config/project-security.hostile-matrix.test.ts +0 -8
  305. package/src/config/project-security.test.ts +21 -24
  306. package/src/config/project-security.ts +115 -14
  307. package/src/config/protected-tokens.test.ts +235 -0
  308. package/src/config/removed-agent-config.ts +45 -0
  309. package/src/config/removed-agent-source-fence.test.ts +56 -0
  310. package/src/config/schema/magic-context.test.ts +50 -42
  311. package/src/config/schema/magic-context.ts +70 -37
  312. package/src/shared/child-session-teardown.test.ts +218 -0
  313. package/src/shared/child-session-teardown.ts +66 -0
  314. package/src/shared/keep-subagents.ts +9 -14
  315. package/src/shared/model-suggestion-retry.ts +1 -1
  316. package/src/shared/opencode-db-path.test.ts +196 -0
  317. package/src/shared/opencode-db-path.ts +215 -0
  318. package/src/shared/prompt-surface-a1-golden.md +50 -35
  319. package/src/shared/prompt-surface-runtime.test.ts +28 -0
  320. package/src/shared/prompt-surface-runtime.ts +22 -5
  321. package/src/shared/resolve-fallbacks.ts +1 -1
  322. package/src/shared/rpc-types.ts +128 -0
  323. package/src/shared/session-messages-bounded.test.ts +1 -1
  324. package/src/shared/sqlite-import-fence.test.ts +19 -0
  325. package/src/shared/sqlite.test.ts +27 -1
  326. package/src/shared/sqlite.ts +204 -1
  327. package/src/shared/status-detail-text.test.ts +92 -20
  328. package/src/shared/status-detail-text.ts +24 -2
  329. package/src/shared/status-summary.ts +167 -0
  330. package/src/shared/subagent-runner.ts +17 -10
  331. package/src/shared/tag-transcript.ts +33 -21
  332. package/src/shared/tail-hygiene-status.ts +8 -0
  333. package/src/shared/transcript.ts +7 -0
  334. package/src/shared/user-facing-codes.test.ts +140 -0
  335. package/src/shared/user-facing-codes.ts +276 -0
  336. package/src/shared/window-geometry.test.ts +44 -0
  337. package/src/shared/window-geometry.ts +89 -11
  338. package/src/shared/write-transaction-attribution.test.ts +241 -0
  339. package/src/shared/write-transaction-timing.ts +2 -1
  340. package/src/tui/index.tsx +44 -11
  341. package/src/tui/slots/sidebar-content.tsx +12 -7
  342. package/src/tui-compiled/index.tsx +662 -649
  343. package/src/tui-compiled/slots/sidebar-content.tsx +301 -305
  344. package/dist/agents/sidekick.d.ts +0 -2
  345. package/dist/agents/sidekick.d.ts.map +0 -1
  346. package/dist/features/magic-context/defaults.d.ts +0 -2
  347. package/dist/features/magic-context/defaults.d.ts.map +0 -1
  348. package/dist/features/magic-context/sidekick/agent.d.ts +0 -14
  349. package/dist/features/magic-context/sidekick/agent.d.ts.map +0 -1
  350. package/dist/features/magic-context/sidekick/core.d.ts +0 -38
  351. package/dist/features/magic-context/sidekick/core.d.ts.map +0 -1
  352. package/dist/features/magic-context/sidekick/index.d.ts +0 -3
  353. package/dist/features/magic-context/sidekick/index.d.ts.map +0 -1
  354. package/dist/hooks/magic-context/boundary-execution.d.ts +0 -27
  355. package/dist/hooks/magic-context/boundary-execution.d.ts.map +0 -1
  356. package/dist/index-raatkvw5.js +0 -360
  357. package/src/agents/sidekick.ts +0 -1
  358. package/src/features/magic-context/defaults.ts +0 -1
@@ -0,0 +1,783 @@
1
+ import {
2
+ log
3
+ } from "./index-dkv2dn46.js";
4
+
5
+ // src/shared/opencode-db-path.ts
6
+ import { existsSync, readdirSync, statSync } from "node:fs";
7
+ import { homedir } from "node:os";
8
+ import { isAbsolute, join } from "node:path";
9
+ var cachedResolution = null;
10
+ var lastReadFailure = null;
11
+ var claimedDiagnostics = new Set;
12
+ function openCodeDataDir() {
13
+ return join(process.env.XDG_DATA_HOME ?? join(homedir(), ".local", "share"), "opencode");
14
+ }
15
+ function environmentKey(dataDir) {
16
+ return [
17
+ dataDir,
18
+ process.env.OPENCODE_DB ?? "",
19
+ process.env.OPENCODE_DISABLE_CHANNEL_DB ?? "",
20
+ process.env.OPENCODE_CHANNEL ?? ""
21
+ ].join("\x00");
22
+ }
23
+ function channelPath(dataDir, channel) {
24
+ return ["latest", "beta", "prod"].includes(channel) ? join(dataDir, "opencode.db") : join(dataDir, `opencode-${channel}.db`);
25
+ }
26
+ function discoveredCandidateNames(dataDir) {
27
+ const names = ["opencode.db", "opencode-local.db", "opencode-dev.db"];
28
+ try {
29
+ const discovered = readdirSync(dataDir, { withFileTypes: true }).filter((entry) => /^opencode-.+\.db$/.test(entry.name) && !names.includes(entry.name)).map((entry) => entry.name).sort();
30
+ names.push(...discovered);
31
+ } catch {}
32
+ return names;
33
+ }
34
+ function discoverOpenCodeDb(dataDir) {
35
+ const candidates = discoveredCandidateNames(dataDir).map((name, order) => {
36
+ const path = join(dataDir, name);
37
+ try {
38
+ const metadata = statSync(path);
39
+ return metadata.isFile() ? { path, order, mtimeMs: metadata.mtimeMs } : null;
40
+ } catch {
41
+ return null;
42
+ }
43
+ });
44
+ const existing = candidates.filter((candidate) => candidate !== null).sort((left, right) => right.mtimeMs - left.mtimeMs || left.order - right.order)[0];
45
+ if (!existing) {
46
+ return { path: join(dataDir, "opencode.db"), source: "default", channel: null };
47
+ }
48
+ const name = existing.path.slice(dataDir.length + 1);
49
+ const channel = name === "opencode.db" ? null : name.slice("opencode-".length, -".db".length) || null;
50
+ return { path: existing.path, source: "discovered", channel };
51
+ }
52
+ function resolveFresh(dataDir) {
53
+ const explicit = process.env.OPENCODE_DB;
54
+ if (explicit !== undefined && explicit.length > 0) {
55
+ if (explicit === ":memory:") {
56
+ return { path: explicit, source: "OPENCODE_DB", channel: null };
57
+ }
58
+ return {
59
+ path: isAbsolute(explicit) ? explicit : join(dataDir, explicit),
60
+ source: "OPENCODE_DB",
61
+ channel: null
62
+ };
63
+ }
64
+ const disableChannelDb = process.env.OPENCODE_DISABLE_CHANNEL_DB;
65
+ if (disableChannelDb === "1" || disableChannelDb === "true") {
66
+ return { path: join(dataDir, "opencode.db"), source: "default", channel: null };
67
+ }
68
+ const channel = process.env.OPENCODE_CHANNEL;
69
+ if (channel !== undefined && channel.length > 0) {
70
+ return { path: channelPath(dataDir, channel), source: "channel", channel };
71
+ }
72
+ return discoverOpenCodeDb(dataDir);
73
+ }
74
+ function resolveOpenCodeDbPath() {
75
+ const dataDir = openCodeDataDir();
76
+ const key = environmentKey(dataDir);
77
+ if (cachedResolution?.key === key && (!cachedResolution.existed || existsSync(cachedResolution.resolution.path))) {
78
+ if (cachedResolution.existed)
79
+ return cachedResolution.resolution;
80
+ }
81
+ const resolution = resolveFresh(dataDir);
82
+ cachedResolution = {
83
+ key,
84
+ resolution,
85
+ existed: resolution.path !== ":memory:" && existsSync(resolution.path)
86
+ };
87
+ return resolution;
88
+ }
89
+ function openCodeDbPathExists(resolution = resolveOpenCodeDbPath()) {
90
+ return resolution.path !== ":memory:" && existsSync(resolution.path);
91
+ }
92
+ function getOpenCodeDbProbeDescriptions(resolution = resolveOpenCodeDbPath()) {
93
+ if (resolution.source === "OPENCODE_DB")
94
+ return [resolution.path];
95
+ if (resolution.source === "channel" || process.env.OPENCODE_DISABLE_CHANNEL_DB === "1" || process.env.OPENCODE_DISABLE_CHANNEL_DB === "true") {
96
+ return [resolution.path];
97
+ }
98
+ const dataDir = openCodeDataDir();
99
+ return [
100
+ join(dataDir, "opencode.db"),
101
+ join(dataDir, "opencode-local.db"),
102
+ join(dataDir, "opencode-dev.db"),
103
+ join(dataDir, "opencode-<channel>.db")
104
+ ];
105
+ }
106
+ function lookedForText(resolution) {
107
+ return getOpenCodeDbProbeDescriptions(resolution).join(", ");
108
+ }
109
+ function formatOpenCodeDbMissingBanner(resolution = resolveOpenCodeDbPath()) {
110
+ return `Magic Context cannot find OpenCode's session database (looked for ${lookedForText(resolution)}). History compaction (historian) and the mid-turn valve are disabled until it is found; set OPENCODE_DB if OpenCode stores it elsewhere.`;
111
+ }
112
+ function formatOpenCodeDbMissingStatusLine(resolution = resolveOpenCodeDbPath()) {
113
+ return `OpenCode DB: MISSING (looked for ${lookedForText(resolution)}). History compaction (historian) and the mid-turn valve are disabled; set OPENCODE_DB if OpenCode stores it elsewhere.`;
114
+ }
115
+ function formatOpenCodeDbReadFailureStatusLine(failure) {
116
+ return `OpenCode DB: READ FAILED (path=${failure.path}, source=${failure.source}) — ${failure.message}`;
117
+ }
118
+ function recordOpenCodeDbReadFailure(resolution, error) {
119
+ const message = error instanceof Error ? error.message : String(error);
120
+ lastReadFailure = { ...resolution, message };
121
+ return lastReadFailure;
122
+ }
123
+ function clearOpenCodeDbReadFailure(path) {
124
+ if (path === undefined || lastReadFailure?.path === path)
125
+ lastReadFailure = null;
126
+ }
127
+ function getOpenCodeDbReadFailure() {
128
+ return lastReadFailure;
129
+ }
130
+ function claimOpenCodeDbDiagnosticOnce(surface, resolution) {
131
+ const key = `${surface}\x00${resolution.path}\x00${resolution.source}`;
132
+ if (claimedDiagnostics.has(key))
133
+ return false;
134
+ claimedDiagnostics.add(key);
135
+ return true;
136
+ }
137
+
138
+ // src/shared/sqlite-helpers.ts
139
+ function closeQuietly(db) {
140
+ if (!db)
141
+ return;
142
+ try {
143
+ db.close();
144
+ } catch {}
145
+ }
146
+
147
+ // src/shared/sqlite.ts
148
+ import { statSync as statSync2 } from "node:fs";
149
+ var reportSlowPrivilegedWrite;
150
+ function registerSlowWriteReporter(reporter) {
151
+ reportSlowPrivilegedWrite = reporter;
152
+ }
153
+ function detectSqliteRuntime() {
154
+ const hasBunVersion = typeof process !== "undefined" && typeof process.versions?.bun === "string";
155
+ const hasBunGlobal = typeof globalThis !== "undefined" && typeof globalThis.Bun !== "undefined";
156
+ return hasBunVersion || hasBunGlobal ? "Bun" : "Node.js";
157
+ }
158
+ var bunSpec = "bun:" + "sqlite";
159
+ var nodeSpec = "node:" + "sqlite";
160
+ async function importSqliteModule(specifier) {
161
+ return await import(specifier);
162
+ }
163
+ function isModuleNotFoundError(error, specifier) {
164
+ const candidate = error;
165
+ const code = typeof candidate?.code === "string" ? candidate.code : "";
166
+ const name = typeof candidate?.name === "string" ? candidate.name : "";
167
+ const message = error instanceof Error ? error.message : String(error ?? "");
168
+ const details = `${code} ${name} ${message}`.toLowerCase();
169
+ const mentionsSpecifier = details.includes(specifier.toLowerCase());
170
+ if (!mentionsSpecifier)
171
+ return false;
172
+ return code === "ERR_MODULE_NOT_FOUND" || code === "ERR_UNKNOWN_BUILTIN_MODULE" || code === "MODULE_NOT_FOUND" || name === "ResolveMessage" || details.includes("module not found") || details.includes("cannot find module") || details.includes("cannot find package") || details.includes("no such built-in module");
173
+ }
174
+
175
+ class SqliteRuntimeUnavailableError extends Error {
176
+ runtime;
177
+ specifier;
178
+ constructor(runtime, specifier, cause) {
179
+ const requirement = specifier === nodeSpec ? "Requires Node.js >= 24, or Bun with bun:sqlite — this Bun build lacks node:sqlite." : "Requires Bun with bun:sqlite, or Node.js >= 24 — this Bun build lacks bun:sqlite.";
180
+ super(`Magic Context detected ${runtime}, but could not load ${specifier}. ${requirement}`, { cause });
181
+ this.name = "SqliteRuntimeUnavailableError";
182
+ this.runtime = runtime;
183
+ this.specifier = specifier;
184
+ }
185
+ }
186
+ async function loadSqliteModule(runtime = detectSqliteRuntime(), importer = importSqliteModule) {
187
+ const specifier = runtime === "Bun" ? bunSpec : nodeSpec;
188
+ try {
189
+ return await importer(specifier);
190
+ } catch (error) {
191
+ if (isModuleNotFoundError(error, specifier)) {
192
+ throw new SqliteRuntimeUnavailableError(runtime, specifier, error);
193
+ }
194
+ throw error;
195
+ }
196
+ }
197
+ var detectedRuntime = detectSqliteRuntime();
198
+ var isBun = detectedRuntime === "Bun";
199
+ var sqliteModule = await loadSqliteModule(detectedRuntime);
200
+ var DatabaseImpl = isBun ? sqliteModule.Database : buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
201
+ var trackedSqliteConnections = new Map;
202
+ var nextSqliteConnectionSequence = 1;
203
+ function trackSqliteConnection(db, filename, options) {
204
+ const originalClose = db.close.bind(db);
205
+ const sequence = nextSqliteConnectionSequence++;
206
+ const metadata = {
207
+ sequence,
208
+ filename: typeof filename === "string" ? filename : Buffer.isBuffer(filename) ? "<buffer>" : ":memory:",
209
+ readonly: Boolean(options) && typeof options === "object" && (options.readonly === true || options.readOnly === true)
210
+ };
211
+ Object.defineProperty(db, "close", {
212
+ configurable: true,
213
+ value: (...args) => {
214
+ try {
215
+ return originalClose(...args);
216
+ } finally {
217
+ trackedSqliteConnections.delete(sequence);
218
+ }
219
+ }
220
+ });
221
+ trackedSqliteConnections.set(sequence, {
222
+ ...metadata,
223
+ reference: new WeakRef(db)
224
+ });
225
+ return db;
226
+ }
227
+ var TrackedDatabase = new Proxy(DatabaseImpl, {
228
+ construct(target, args) {
229
+ const db = Reflect.construct(target, args, target);
230
+ return trackSqliteConnection(db, args[0], args[1]);
231
+ }
232
+ });
233
+ function buildNodeSqliteDatabaseClass(DatabaseSync) {
234
+ const SAVEPOINT = "mc_tx_sp";
235
+
236
+ class NodeSqliteDatabase extends DatabaseSync {
237
+ constructor(filename, options) {
238
+ const translated = { ...options };
239
+ if (options && "readonly" in options) {
240
+ translated.readOnly = options.readonly;
241
+ delete translated.readonly;
242
+ }
243
+ super(typeof filename === "string" ? filename : ":memory:", translated);
244
+ }
245
+ prepare(sql) {
246
+ const stmt = super.prepare(sql);
247
+ for (const method of ["run", "get", "all"]) {
248
+ const original = stmt[method].bind(stmt);
249
+ stmt[method] = (...args) => args.length === 1 && Array.isArray(args[0]) ? original(...args[0]) : original(...args);
250
+ }
251
+ return stmt;
252
+ }
253
+ transaction(fn) {
254
+ const self = this;
255
+ const execute = (mode, receiver, args) => {
256
+ const nested = self.isTransaction === true;
257
+ self.exec(nested ? `SAVEPOINT ${SAVEPOINT}` : `BEGIN${mode ? ` ${mode}` : ""}`);
258
+ try {
259
+ const result = fn.apply(receiver, args);
260
+ self.exec(nested ? `RELEASE ${SAVEPOINT}` : "COMMIT");
261
+ return result;
262
+ } catch (error) {
263
+ if (nested) {
264
+ self.exec(`ROLLBACK TO ${SAVEPOINT}`);
265
+ self.exec(`RELEASE ${SAVEPOINT}`);
266
+ } else {
267
+ self.exec("ROLLBACK");
268
+ }
269
+ throw error;
270
+ }
271
+ };
272
+ const wrapped = function(...args) {
273
+ return execute("", this, args);
274
+ };
275
+ wrapped.default = function(...args) {
276
+ return execute("", this, args);
277
+ };
278
+ wrapped.deferred = function(...args) {
279
+ return execute("DEFERRED", this, args);
280
+ };
281
+ wrapped.immediate = function(...args) {
282
+ return execute("IMMEDIATE", this, args);
283
+ };
284
+ wrapped.exclusive = function(...args) {
285
+ return execute("EXCLUSIVE", this, args);
286
+ };
287
+ return wrapped;
288
+ }
289
+ }
290
+ return NodeSqliteDatabase;
291
+ }
292
+ var Database = TrackedDatabase;
293
+ function pragmaValue(db, name) {
294
+ const row = db.prepare(`PRAGMA ${name}`).get();
295
+ if (!row)
296
+ return;
297
+ return row[name] ?? Object.values(row)[0];
298
+ }
299
+ function pragmaNumber(db, name) {
300
+ try {
301
+ const value = pragmaValue(db, name);
302
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
303
+ } catch {
304
+ return null;
305
+ }
306
+ }
307
+ function pragmaString(db, name) {
308
+ try {
309
+ const value = pragmaValue(db, name);
310
+ return typeof value === "string" ? value : null;
311
+ } catch {
312
+ return null;
313
+ }
314
+ }
315
+ function sqliteSidecarBytes(filename, suffix) {
316
+ if (filename === ":memory:" || filename === "<buffer>")
317
+ return 0;
318
+ try {
319
+ return statSync2(`${filename}${suffix}`).size;
320
+ } catch (error) {
321
+ return error.code === "ENOENT" ? 0 : null;
322
+ }
323
+ }
324
+ function fts5TableCount(db) {
325
+ try {
326
+ const row = db.prepare("SELECT COUNT(*) AS count FROM sqlite_master WHERE type = 'table' AND sql LIKE '%USING fts5%'").get();
327
+ return typeof row?.count === "number" ? row.count : null;
328
+ } catch {
329
+ return null;
330
+ }
331
+ }
332
+ function getSqliteMemoryStats() {
333
+ const connections = [];
334
+ for (const [sequence, tracked] of trackedSqliteConnections) {
335
+ const db = tracked.reference.deref();
336
+ if (!db) {
337
+ trackedSqliteConnections.delete(sequence);
338
+ continue;
339
+ }
340
+ const pageSize = pragmaNumber(db, "page_size");
341
+ const cacheSize = pragmaNumber(db, "cache_size");
342
+ const cacheSizeUnit = cacheSize === null ? null : cacheSize < 0 ? "kib" : "pages";
343
+ const cacheUpperBoundBytes = cacheSize === null ? null : cacheSize < 0 ? Math.abs(cacheSize) * 1024 : pageSize === null ? null : cacheSize * pageSize;
344
+ connections.push({
345
+ sequence: tracked.sequence,
346
+ filename: tracked.filename,
347
+ readonly: tracked.readonly,
348
+ pageSize,
349
+ pageCount: pragmaNumber(db, "page_count"),
350
+ freelistCount: pragmaNumber(db, "freelist_count"),
351
+ cacheSize,
352
+ cacheSizeUnit,
353
+ cacheUpperBoundBytes,
354
+ mmapSizeBytes: pragmaNumber(db, "mmap_size"),
355
+ walFileBytes: sqliteSidecarBytes(tracked.filename, "-wal"),
356
+ shmFileBytes: sqliteSidecarBytes(tracked.filename, "-shm"),
357
+ fts5TableCount: fts5TableCount(db),
358
+ journalMode: pragmaString(db, "journal_mode")
359
+ });
360
+ }
361
+ const sumKnown = (select) => connections.reduce((sum, connection) => sum + (select(connection) ?? 0), 0);
362
+ return {
363
+ connectionCount: connections.length,
364
+ cacheUpperBoundBytes: sumKnown((connection) => connection.cacheUpperBoundBytes),
365
+ mmapUpperBoundBytes: sumKnown((connection) => connection.mmapSizeBytes),
366
+ walFileBytes: sumKnown((connection) => connection.walFileBytes),
367
+ shmFileBytes: sumKnown((connection) => connection.shmFileBytes),
368
+ sqliteStatusApi: "unavailable",
369
+ connections
370
+ };
371
+ }
372
+ var privilegeDepth = new WeakMap;
373
+ function isInTransaction(db) {
374
+ const candidate = db;
375
+ return candidate.inTransaction === true || candidate.isTransaction === true;
376
+ }
377
+ function withPrivilegedWriter(db, operation) {
378
+ const previousDepth = privilegeDepth.get(db) ?? 0;
379
+ const nested = isInTransaction(db);
380
+ const savepoint = "mc_privilege_scope";
381
+ const transactionStartedAt = nested ? undefined : performance.now();
382
+ if (nested) {
383
+ db.exec(`SAVEPOINT ${savepoint}`);
384
+ } else {
385
+ db.exec("BEGIN IMMEDIATE");
386
+ }
387
+ privilegeDepth.set(db, previousDepth + 1);
388
+ try {
389
+ db.prepare("INSERT INTO context_privilege_state(id, enabled) VALUES (1, 1) ON CONFLICT(id) DO UPDATE SET enabled = 1").run();
390
+ const result = operation();
391
+ if (previousDepth === 0) {
392
+ db.prepare("UPDATE context_privilege_state SET enabled = 0 WHERE id = 1").run();
393
+ }
394
+ if (nested) {
395
+ db.exec(`RELEASE ${savepoint}`);
396
+ } else {
397
+ db.exec("COMMIT");
398
+ if (transactionStartedAt !== undefined) {
399
+ reportSlowPrivilegedWrite?.("privileged_writer", transactionStartedAt);
400
+ }
401
+ }
402
+ if (previousDepth > 0)
403
+ privilegeDepth.set(db, previousDepth);
404
+ else
405
+ privilegeDepth.delete(db);
406
+ return result;
407
+ } catch (error) {
408
+ try {
409
+ if (nested) {
410
+ db.exec(`ROLLBACK TO ${savepoint}`);
411
+ db.exec(`RELEASE ${savepoint}`);
412
+ } else {
413
+ db.exec("ROLLBACK");
414
+ }
415
+ } finally {
416
+ if (previousDepth > 0)
417
+ privilegeDepth.set(db, previousDepth);
418
+ else
419
+ privilegeDepth.delete(db);
420
+ }
421
+ throw error;
422
+ }
423
+ }
424
+
425
+ // src/hooks/magic-context/read-session-db.ts
426
+ function openCodeDbExists() {
427
+ return openCodeDbPathExists(resolveOpenCodeDbPath());
428
+ }
429
+ var cachedReadOnlyDb = null;
430
+ function closeCachedReadOnlyDb() {
431
+ if (!cachedReadOnlyDb) {
432
+ return;
433
+ }
434
+ try {
435
+ closeQuietly(cachedReadOnlyDb.db);
436
+ } catch (error) {
437
+ log("[magic-context] failed to close cached OpenCode read-only DB:", error);
438
+ } finally {
439
+ cachedReadOnlyDb = null;
440
+ }
441
+ }
442
+ function getReadOnlySessionDb() {
443
+ const resolution = resolveOpenCodeDbPath();
444
+ const dbPath = resolution.path;
445
+ if (!openCodeDbPathExists(resolution)) {
446
+ throw new Error(`OpenCode session database is unavailable at ${dbPath} (source=${resolution.source})`);
447
+ }
448
+ if (cachedReadOnlyDb?.path === dbPath) {
449
+ return cachedReadOnlyDb.db;
450
+ }
451
+ closeCachedReadOnlyDb();
452
+ const db = new Database(dbPath, { readonly: true });
453
+ cachedReadOnlyDb = { path: dbPath, db };
454
+ clearOpenCodeDbReadFailure();
455
+ return db;
456
+ }
457
+ function withReadOnlySessionDb(fn) {
458
+ return fn(getReadOnlySessionDb());
459
+ }
460
+ function getRawSessionMessageCountFromDb(db, sessionId) {
461
+ const row = db.prepare(`SELECT COUNT(*) as count FROM message WHERE session_id = ?
462
+ AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
463
+ AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')`).get(sessionId);
464
+ return typeof row?.count === "number" ? row.count : 0;
465
+ }
466
+ var trackedSessions = new Map;
467
+ var pendingParts = new Map;
468
+ var probeLogObserverForTests;
469
+ function asRecord(value) {
470
+ return value !== null && typeof value === "object" ? value : null;
471
+ }
472
+ function truthyStoredFlag(value) {
473
+ return value === true || value === 1 || value === "true";
474
+ }
475
+ function isMachineGeneratedPart(value) {
476
+ const part = asRecord(value);
477
+ if (!part)
478
+ return false;
479
+ const metadata = asRecord(part.metadata);
480
+ const marker = asRecord(metadata?.marker);
481
+ return truthyStoredFlag(part.synthetic) || truthyStoredFlag(part.ignored) || marker !== null && marker.kind !== null && marker.kind !== undefined;
482
+ }
483
+ function messageTimeCreated(message, fallback) {
484
+ const time = asRecord(message.info.time);
485
+ return typeof time?.created === "number" ? time.created : fallback;
486
+ }
487
+ function latestMessageByRole(messages, role, realUserOnly = false) {
488
+ let latest = null;
489
+ for (const [index, message] of messages.entries()) {
490
+ if (message.info.role !== role)
491
+ continue;
492
+ if (realUserOnly && message.parts.length > 0 && message.parts.every(isMachineGeneratedPart)) {
493
+ continue;
494
+ }
495
+ const timeCreated = messageTimeCreated(message, index);
496
+ if (latest === null || timeCreated > latest.timeCreated || timeCreated === latest.timeCreated && index > latest.index) {
497
+ latest = { message, timeCreated, index };
498
+ }
499
+ }
500
+ return latest;
501
+ }
502
+ function assistantAwaitingToolsFromMessages(messages) {
503
+ const latestAssistant = latestMessageByRole(messages, "assistant");
504
+ if (!latestAssistant)
505
+ return false;
506
+ const assistantTime = asRecord(latestAssistant.message.info.time);
507
+ if (typeof assistantTime?.created !== "number")
508
+ return false;
509
+ const latestRealUser = latestMessageByRole(messages, "user", true);
510
+ if (latestRealUser && latestRealUser.timeCreated > latestAssistant.timeCreated)
511
+ return false;
512
+ if (latestAssistant.message.info.finish === "tool-calls")
513
+ return true;
514
+ return latestAssistant.message.parts.some((value) => {
515
+ const part = asRecord(value);
516
+ return part?.type === "tool" && part.providerExecuted !== true;
517
+ });
518
+ }
519
+ function shouldHoldIgnoredNotificationFromMessages(messages) {
520
+ if (assistantAwaitingToolsFromMessages(messages))
521
+ return true;
522
+ const latestAssistant = latestMessageByRole(messages, "assistant");
523
+ if (latestAssistant) {
524
+ const finish = latestAssistant.message.info.finish;
525
+ if (typeof finish !== "string" || finish.length === 0)
526
+ return true;
527
+ if (finish === "tool-calls" || finish === "unknown")
528
+ return true;
529
+ }
530
+ const latestRealUser = latestMessageByRole(messages, "user", true);
531
+ return latestRealUser !== null && latestRealUser.timeCreated > (latestAssistant?.timeCreated ?? -1);
532
+ }
533
+ function trackedMessages(session) {
534
+ return [...session.messages.values()].sort((left, right) => left.timeCreated - right.timeCreated).map((message) => ({
535
+ info: {
536
+ id: message.id,
537
+ role: message.role,
538
+ time: { created: message.timeCreated },
539
+ ...message.finish === undefined ? {} : { finish: message.finish }
540
+ },
541
+ parts: [...message.parts.values()]
542
+ }));
543
+ }
544
+ function pendingMessageParts(sessionId, messageId) {
545
+ return pendingParts.get(sessionId)?.get(messageId) ?? new Map;
546
+ }
547
+ function observeOpenCodeTurnEvent(type, properties) {
548
+ const props = asRecord(properties);
549
+ if (!props)
550
+ return;
551
+ if (type === "message.part.updated") {
552
+ const part = asRecord(props.part);
553
+ if (!part || typeof part.sessionID !== "string" || typeof part.messageID !== "string" || typeof part.id !== "string") {
554
+ return;
555
+ }
556
+ const tracked = trackedSessions.get(part.sessionID)?.messages.get(part.messageID);
557
+ if (tracked) {
558
+ tracked.parts.set(part.id, part);
559
+ return;
560
+ }
561
+ let byMessage = pendingParts.get(part.sessionID);
562
+ if (!byMessage) {
563
+ byMessage = new Map;
564
+ pendingParts.set(part.sessionID, byMessage);
565
+ }
566
+ let parts = byMessage.get(part.messageID);
567
+ if (!parts) {
568
+ parts = new Map;
569
+ byMessage.set(part.messageID, parts);
570
+ }
571
+ parts.set(part.id, part);
572
+ return;
573
+ }
574
+ if (type === "message.updated") {
575
+ const info = asRecord(props.info);
576
+ const time = asRecord(info?.time);
577
+ if (!info || info.role !== "assistant" && info.role !== "user" || typeof info.sessionID !== "string" || typeof info.id !== "string") {
578
+ return;
579
+ }
580
+ let session = trackedSessions.get(info.sessionID);
581
+ if (!session) {
582
+ session = { messages: new Map, sequence: 0 };
583
+ trackedSessions.set(info.sessionID, session);
584
+ }
585
+ session.sequence += 1;
586
+ const existing = session.messages.get(info.id);
587
+ session.messages.set(info.id, {
588
+ id: info.id,
589
+ role: info.role,
590
+ timeCreated: typeof time?.created === "number" ? time.created : existing?.timeCreated ?? session.sequence,
591
+ ...typeof info.finish === "string" ? { finish: info.finish } : {},
592
+ parts: existing?.parts ?? pendingMessageParts(info.sessionID, info.id)
593
+ });
594
+ pendingParts.get(info.sessionID)?.delete(info.id);
595
+ return;
596
+ }
597
+ if (type === "message.removed") {
598
+ if (typeof props.sessionID === "string" && typeof props.messageID === "string") {
599
+ trackedSessions.get(props.sessionID)?.messages.delete(props.messageID);
600
+ pendingParts.get(props.sessionID)?.delete(props.messageID);
601
+ }
602
+ return;
603
+ }
604
+ if (type === "session.deleted" && typeof props.sessionID === "string") {
605
+ clearTrackedOpenCodeSession(props.sessionID);
606
+ }
607
+ }
608
+ function clearTrackedOpenCodeSession(sessionId) {
609
+ trackedSessions.delete(sessionId);
610
+ pendingParts.delete(sessionId);
611
+ }
612
+ function logProbeFailureOnce(resolution, error) {
613
+ const failure = recordOpenCodeDbReadFailure(resolution, error);
614
+ if (!claimOpenCodeDbDiagnosticOnce("session-state-probe", resolution))
615
+ return;
616
+ const message = `[magic-context] OpenCode DB probe failed: path=${resolution.path} source=${resolution.source} cause=${failure.message}`;
617
+ probeLogObserverForTests?.(message);
618
+ log(message);
619
+ }
620
+ function resolvedDbIsAvailable() {
621
+ const resolution = resolveOpenCodeDbPath();
622
+ const available = openCodeDbPathExists(resolution);
623
+ if (available)
624
+ clearOpenCodeDbReadFailure(resolution.path);
625
+ else
626
+ logProbeFailureOnce(resolution, "opencode_db_missing");
627
+ return { resolution, available };
628
+ }
629
+ function assistantAwaitingTools(_deps, sessionId) {
630
+ const availability = resolvedDbIsAvailable();
631
+ const tracked = trackedSessions.get(sessionId);
632
+ if (tracked)
633
+ return assistantAwaitingToolsFromMessages(trackedMessages(tracked));
634
+ if (!availability.available)
635
+ return false;
636
+ try {
637
+ return withReadOnlySessionDb((db) => assistantAwaitingToolsFromOpenCodeDb(db, sessionId));
638
+ } catch (error) {
639
+ logProbeFailureOnce(availability.resolution, error);
640
+ return false;
641
+ }
642
+ }
643
+ function shouldHoldIgnoredNotificationFromOpenCodeDb(db, sessionId) {
644
+ if (assistantAwaitingToolsFromOpenCodeDb(db, sessionId))
645
+ return true;
646
+ if (hasUnfinishedAssistant(db, sessionId))
647
+ return true;
648
+ if (hasUnansweredRealUser(db, sessionId))
649
+ return true;
650
+ return false;
651
+ }
652
+ function shouldHoldIgnoredNotification(sessionId) {
653
+ if (process.env.MAGIC_CONTEXT_NOTICE_GATE === "bypass")
654
+ return false;
655
+ if (process.env.MAGIC_CONTEXT_NOTICE_GATE === "hold")
656
+ return true;
657
+ const availability = resolvedDbIsAvailable();
658
+ const tracked = trackedSessions.get(sessionId);
659
+ if (tracked)
660
+ return shouldHoldIgnoredNotificationFromMessages(trackedMessages(tracked));
661
+ if (!availability.available)
662
+ return false;
663
+ try {
664
+ return withReadOnlySessionDb((db) => shouldHoldIgnoredNotificationFromOpenCodeDb(db, sessionId));
665
+ } catch (error) {
666
+ logProbeFailureOnce(availability.resolution, error);
667
+ return false;
668
+ }
669
+ }
670
+ function assistantAwaitingToolsFromOpenCodeDb(db, sessionId) {
671
+ const latestAssistant = latestAssistantRow(db, sessionId);
672
+ if (typeof latestAssistant?.id !== "string")
673
+ return false;
674
+ if (hasNewerRealUserMessage(db, sessionId, latestAssistant.timeCreated))
675
+ return false;
676
+ if (latestAssistant.finish === "tool-calls")
677
+ return true;
678
+ const partRows = db.prepare("SELECT data FROM part WHERE session_id = ? AND likelihood(message_id = ?, 0.000001)").all(sessionId, latestAssistant.id);
679
+ return partRows.some((row) => {
680
+ if (typeof row.data !== "string" || row.data.length === 0)
681
+ return false;
682
+ try {
683
+ const part = JSON.parse(row.data);
684
+ return part.type === "tool" && part.providerExecuted !== true;
685
+ } catch {
686
+ return false;
687
+ }
688
+ });
689
+ }
690
+ function hasNewerRealUserMessage(db, sessionId, latestAssistantTimeCreated) {
691
+ if (typeof latestAssistantTimeCreated !== "number")
692
+ return false;
693
+ const row = db.prepare(`SELECT 1 as one
694
+ FROM message m
695
+ WHERE m.session_id = ?
696
+ AND m.time_created > ?
697
+ AND json_extract(m.data, '$.role') = 'user'
698
+ AND NOT (
699
+ EXISTS (SELECT 1 FROM part p WHERE p.message_id = m.id)
700
+ AND NOT EXISTS (
701
+ SELECT 1 FROM part p
702
+ WHERE p.message_id = m.id
703
+ AND COALESCE(json_extract(p.data, '$.synthetic'), 0) NOT IN (1, 'true')
704
+ AND json_extract(p.data, '$.metadata.marker.kind') IS NULL
705
+ AND COALESCE(json_extract(p.data, '$.ignored'), 0) NOT IN (1, 'true')
706
+ )
707
+ )
708
+ LIMIT 1`).get(sessionId, latestAssistantTimeCreated);
709
+ return row?.one === 1;
710
+ }
711
+ function latestAssistantRow(db, sessionId) {
712
+ return db.prepare(`SELECT id,
713
+ json_extract(data, '$.finish') as finish,
714
+ time_created as timeCreated
715
+ FROM message
716
+ WHERE session_id = ?
717
+ AND json_extract(data, '$.role') = 'assistant'
718
+ ORDER BY time_created DESC
719
+ LIMIT 1`).get(sessionId);
720
+ }
721
+ function hasUnfinishedAssistant(db, sessionId) {
722
+ const latestAssistant = latestAssistantRow(db, sessionId);
723
+ if (typeof latestAssistant?.id !== "string")
724
+ return false;
725
+ const finish = latestAssistant.finish;
726
+ if (typeof finish !== "string" || finish.length === 0)
727
+ return true;
728
+ return finish === "tool-calls" || finish === "unknown";
729
+ }
730
+ function hasUnansweredRealUser(db, sessionId) {
731
+ const latestAssistant = latestAssistantRow(db, sessionId);
732
+ const latestAssistantTime = typeof latestAssistant?.timeCreated === "number" ? latestAssistant.timeCreated : -1;
733
+ return hasNewerRealUserMessage(db, sessionId, latestAssistantTime);
734
+ }
735
+ function getMessageTimesFromOpenCodeDb(sessionId, messageIds) {
736
+ const result = new Map;
737
+ if (messageIds.length === 0)
738
+ return result;
739
+ try {
740
+ withReadOnlySessionDb((db) => {
741
+ const placeholders = messageIds.map(() => "?").join(",");
742
+ const rows = db.prepare(`SELECT id, time_created FROM message WHERE session_id = ? AND id IN (${placeholders})`).all(sessionId, ...messageIds);
743
+ for (const row of rows) {
744
+ if (typeof row.id === "string" && typeof row.time_created === "number") {
745
+ result.set(row.id, row.time_created);
746
+ }
747
+ }
748
+ });
749
+ } catch (error) {
750
+ logProbeFailureOnce(resolveOpenCodeDbPath(), error);
751
+ }
752
+ return result;
753
+ }
754
+ function findLastAssistantModelFromOpenCodeDb(sessionId) {
755
+ try {
756
+ return withReadOnlySessionDb((db) => {
757
+ const row = db.prepare(`SELECT json_extract(data, '$.providerID') as providerID,
758
+ json_extract(data, '$.modelID') as modelID,
759
+ json_extract(data, '$.agent') as agent
760
+ FROM message
761
+ WHERE session_id = ?
762
+ AND json_extract(data, '$.role') = 'assistant'
763
+ AND json_extract(data, '$.providerID') IS NOT NULL
764
+ AND json_extract(data, '$.modelID') IS NOT NULL
765
+ ORDER BY time_created DESC
766
+ LIMIT 1`).get(sessionId);
767
+ if (!row || typeof row.providerID !== "string" || typeof row.modelID !== "string") {
768
+ return null;
769
+ }
770
+ const agent = typeof row.agent === "string" && row.agent.length > 0 ? row.agent : undefined;
771
+ return {
772
+ providerID: row.providerID,
773
+ modelID: row.modelID,
774
+ ...agent ? { agent } : {}
775
+ };
776
+ });
777
+ } catch (error) {
778
+ logProbeFailureOnce(resolveOpenCodeDbPath(), error);
779
+ return null;
780
+ }
781
+ }
782
+
783
+ export { resolveOpenCodeDbPath, openCodeDbPathExists, formatOpenCodeDbMissingBanner, formatOpenCodeDbMissingStatusLine, formatOpenCodeDbReadFailureStatusLine, recordOpenCodeDbReadFailure, clearOpenCodeDbReadFailure, getOpenCodeDbReadFailure, claimOpenCodeDbDiagnosticOnce, registerSlowWriteReporter, detectSqliteRuntime, Database, getSqliteMemoryStats, withPrivilegedWriter, closeQuietly, openCodeDbExists, withReadOnlySessionDb, getRawSessionMessageCountFromDb, observeOpenCodeTurnEvent, clearTrackedOpenCodeSession, assistantAwaitingTools, shouldHoldIgnoredNotification, getMessageTimesFromOpenCodeDb, findLastAssistantModelFromOpenCodeDb };