@cortexkit/opencode-magic-context 0.42.5 → 0.43.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 (511) hide show
  1. package/README.md +6 -7
  2. package/dist/agents/dreamer.d.ts +7 -9
  3. package/dist/agents/dreamer.d.ts.map +1 -1
  4. package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
  5. package/dist/agents/magic-context-prompt.d.ts.map +1 -1
  6. package/dist/config/index.d.ts +10 -1
  7. package/dist/config/index.d.ts.map +1 -1
  8. package/dist/config/live-run-config.d.ts +12 -0
  9. package/dist/config/live-run-config.d.ts.map +1 -0
  10. package/dist/config/live-snapshot.d.ts +32 -0
  11. package/dist/config/live-snapshot.d.ts.map +1 -0
  12. package/dist/config/schema/magic-context.d.ts +13 -2
  13. package/dist/config/schema/magic-context.d.ts.map +1 -1
  14. package/dist/{conflict-warning-hook-jyj54gbe.js → conflict-warning-hook-t2vb0wnx.js} +3 -3
  15. package/dist/{derive-budgets-v1fkhjjr.js → derive-budgets-0sg5vp61.js} +5 -2
  16. package/dist/features/builtin-commands/commands.d.ts +0 -4
  17. package/dist/features/builtin-commands/commands.d.ts.map +1 -1
  18. package/dist/features/magic-context/compaction-marker.d.ts +6 -0
  19. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  20. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +4 -1
  21. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  22. package/dist/features/magic-context/compartment-lease.d.ts +8 -0
  23. package/dist/features/magic-context/compartment-lease.d.ts.map +1 -1
  24. package/dist/features/magic-context/compartment-storage.d.ts +21 -0
  25. package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
  26. package/dist/features/magic-context/context-authority.d.ts +37 -3
  27. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  28. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  29. package/dist/features/magic-context/dreamer/docs-proposals.d.ts +23 -0
  30. package/dist/features/magic-context/dreamer/docs-proposals.d.ts.map +1 -0
  31. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +5 -1
  32. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  33. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts +48 -0
  34. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -0
  35. package/dist/features/magic-context/dreamer/manual-summary.d.ts +7 -0
  36. package/dist/features/magic-context/dreamer/manual-summary.d.ts.map +1 -0
  37. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  38. package/dist/features/magic-context/dreamer/open-opencode-db.d.ts.map +1 -1
  39. package/dist/features/magic-context/dreamer/promote-primers.d.ts +8 -1
  40. package/dist/features/magic-context/dreamer/promote-primers.d.ts.map +1 -1
  41. package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
  42. package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts +5 -2
  43. package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts.map +1 -1
  44. package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts +22 -13
  45. package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts.map +1 -1
  46. package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts +9 -0
  47. package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts.map +1 -1
  48. package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
  49. package/dist/features/magic-context/dreamer/task-executor.d.ts +3 -0
  50. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  51. package/dist/features/magic-context/dreamer/task-prompts.d.ts +7 -4
  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 +53 -2
  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 +3 -0
  56. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  57. package/dist/features/magic-context/dreamer/tick-failure.d.ts +38 -0
  58. package/dist/features/magic-context/dreamer/tick-failure.d.ts.map +1 -0
  59. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  60. package/dist/features/magic-context/git-commits/search-git-commits.d.ts +2 -0
  61. package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
  62. package/dist/features/magic-context/memory/embedding-identity.d.ts +1 -0
  63. package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
  64. package/dist/features/magic-context/memory/embedding-local.d.ts +1 -0
  65. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  66. package/dist/features/magic-context/memory/embedding.d.ts +1 -1
  67. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
  68. package/dist/features/magic-context/memory/memory-diagnostics.d.ts +6 -0
  69. package/dist/features/magic-context/memory/memory-diagnostics.d.ts.map +1 -0
  70. package/dist/features/magic-context/memory/memory-selection.d.ts +12 -0
  71. package/dist/features/magic-context/memory/memory-selection.d.ts.map +1 -0
  72. package/dist/features/magic-context/memory/memory-visibility.d.ts +46 -0
  73. package/dist/features/magic-context/memory/memory-visibility.d.ts.map +1 -0
  74. package/dist/features/magic-context/memory/mirror-reembed.d.ts +22 -0
  75. package/dist/features/magic-context/memory/mirror-reembed.d.ts.map +1 -0
  76. package/dist/features/magic-context/memory/project-identity.d.ts +9 -0
  77. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  78. package/dist/features/magic-context/memory/storage-memory-fts.d.ts +6 -2
  79. package/dist/features/magic-context/memory/storage-memory-fts.d.ts.map +1 -1
  80. package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
  81. package/dist/features/magic-context/memory/transformers-remote-host.d.ts +6 -0
  82. package/dist/features/magic-context/memory/transformers-remote-host.d.ts.map +1 -0
  83. package/dist/features/magic-context/memory/transformers-web-entry.d.ts.map +1 -1
  84. package/dist/features/magic-context/message-fts-rowid-map.d.ts +3 -1
  85. package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -1
  86. package/dist/features/magic-context/message-index-async.d.ts +8 -3
  87. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  88. package/dist/features/magic-context/message-index.d.ts +7 -1
  89. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  90. package/dist/features/magic-context/message-time-backfill.d.ts +19 -0
  91. package/dist/features/magic-context/message-time-backfill.d.ts.map +1 -0
  92. package/dist/features/magic-context/migrations.d.ts +16 -0
  93. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  94. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  95. package/dist/features/magic-context/mural/storage-mural.d.ts +5 -0
  96. package/dist/features/magic-context/mural/storage-mural.d.ts.map +1 -1
  97. package/dist/features/magic-context/opencode2-relabel.d.ts +132 -0
  98. package/dist/features/magic-context/opencode2-relabel.d.ts.map +1 -0
  99. package/dist/features/magic-context/overflow-detection.d.ts +3 -0
  100. package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
  101. package/dist/features/magic-context/project-embedding-registry.d.ts +1 -0
  102. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  103. package/dist/features/magic-context/protection-window.d.ts +1 -1
  104. package/dist/features/magic-context/protection-window.d.ts.map +1 -1
  105. package/dist/features/magic-context/search.d.ts +6 -0
  106. package/dist/features/magic-context/search.d.ts.map +1 -1
  107. package/dist/features/magic-context/session-decision-calibration.d.ts +31 -0
  108. package/dist/features/magic-context/session-decision-calibration.d.ts.map +1 -0
  109. package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
  110. package/dist/features/magic-context/shadow-backfill-state.d.ts +1 -1
  111. package/dist/features/magic-context/shadow-backfill-state.d.ts.map +1 -1
  112. package/dist/features/magic-context/smart-notes/compiler.d.ts +5 -1
  113. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  114. package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
  115. package/dist/features/magic-context/storage-db.d.ts +1 -1
  116. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  117. package/dist/features/magic-context/storage-historian-runs.d.ts +4 -2
  118. package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
  119. package/dist/features/magic-context/storage-meta-persisted.d.ts +16 -2
  120. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  121. package/dist/features/magic-context/storage-meta-shared.d.ts +1 -1
  122. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  123. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  124. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  125. package/dist/features/magic-context/storage-notes.d.ts +1 -0
  126. package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
  127. package/dist/features/magic-context/storage-replay-document.d.ts +2 -0
  128. package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -1
  129. package/dist/features/magic-context/storage-subagent-invocations.d.ts +1 -1
  130. package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -1
  131. package/dist/features/magic-context/storage-tags.d.ts +42 -4
  132. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  133. package/dist/features/magic-context/storage.d.ts +2 -2
  134. package/dist/features/magic-context/storage.d.ts.map +1 -1
  135. package/dist/features/magic-context/store-generation-rebase.d.ts +95 -0
  136. package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -0
  137. package/dist/features/magic-context/subagent-token-capture.d.ts +1 -0
  138. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
  139. package/dist/features/magic-context/tagger.d.ts +2 -0
  140. package/dist/features/magic-context/tagger.d.ts.map +1 -1
  141. package/dist/features/magic-context/tool-definition-tokens.d.ts +1 -0
  142. package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
  143. package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
  144. package/dist/features/magic-context/user-memory/review-user-memories.d.ts +5 -1
  145. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  146. package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
  147. package/dist/hooks/magic-context/apply-operations.d.ts +10 -1
  148. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  149. package/dist/hooks/magic-context/cache-busting-signals.d.ts +19 -4
  150. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
  151. package/dist/hooks/magic-context/channel2-delivery.d.ts +8 -0
  152. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  153. package/dist/hooks/magic-context/command-handler.d.ts +5 -4
  154. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  155. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  156. package/dist/hooks/magic-context/compaction-off-transition.d.ts +1 -0
  157. package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -1
  158. package/dist/hooks/magic-context/compartment-prompt.d.ts +1 -1
  159. package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
  160. package/dist/hooks/magic-context/compartment-render-epoch.d.ts +3 -1
  161. package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
  162. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +1 -1
  163. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
  164. package/dist/hooks/magic-context/compartment-runner-historian.d.ts +1 -0
  165. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  166. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +19 -0
  167. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  168. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  169. package/dist/hooks/magic-context/compartment-runner-types.d.ts +19 -11
  170. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  171. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +4 -1
  172. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  173. package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
  174. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  175. package/dist/hooks/magic-context/decay-render.d.ts +1 -0
  176. package/dist/hooks/magic-context/decay-render.d.ts.map +1 -1
  177. package/dist/hooks/magic-context/decision-calibration.d.ts +24 -0
  178. package/dist/hooks/magic-context/decision-calibration.d.ts.map +1 -0
  179. package/dist/hooks/magic-context/derive-budgets.d.ts +2 -0
  180. package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -1
  181. package/dist/hooks/magic-context/dropped-input-guard.d.ts +50 -4
  182. package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -1
  183. package/dist/hooks/magic-context/embed-history-runner.d.ts +30 -0
  184. package/dist/hooks/magic-context/embed-history-runner.d.ts.map +1 -0
  185. package/dist/hooks/magic-context/emergency-drop.d.ts +13 -8
  186. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  187. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  188. package/dist/hooks/magic-context/event-payloads.d.ts +2 -1
  189. package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
  190. package/dist/hooks/magic-context/execute-status.d.ts +2 -1
  191. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  192. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +12 -4
  193. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
  194. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  195. package/dist/hooks/magic-context/historian-no-fire-cause.d.ts +5 -0
  196. package/dist/hooks/magic-context/historian-no-fire-cause.d.ts.map +1 -0
  197. package/dist/hooks/magic-context/historian-publish-stage-logger.d.ts +3 -0
  198. package/dist/hooks/magic-context/historian-publish-stage-logger.d.ts.map +1 -0
  199. package/dist/hooks/magic-context/hook-handlers.d.ts +0 -3
  200. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  201. package/dist/hooks/magic-context/hook.d.ts +4 -4
  202. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  203. package/dist/hooks/magic-context/host-served-rows.d.ts +58 -0
  204. package/dist/hooks/magic-context/host-served-rows.d.ts.map +1 -0
  205. package/dist/hooks/magic-context/inject-compartments.d.ts +38 -0
  206. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  207. package/dist/hooks/magic-context/legacy-compartments.d.ts +20 -0
  208. package/dist/hooks/magic-context/legacy-compartments.d.ts.map +1 -0
  209. package/dist/hooks/magic-context/live-session-state.d.ts +7 -7
  210. package/dist/hooks/magic-context/m0-token-breakdown.d.ts +6 -0
  211. package/dist/hooks/magic-context/m0-token-breakdown.d.ts.map +1 -1
  212. package/dist/hooks/magic-context/maintenance-authority.d.ts +0 -1
  213. package/dist/hooks/magic-context/maintenance-authority.d.ts.map +1 -1
  214. package/dist/hooks/magic-context/module-state-sync.d.ts +4 -1
  215. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  216. package/dist/hooks/magic-context/module-transport.d.ts +24 -2
  217. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  218. package/dist/hooks/magic-context/module-wire.d.ts +43 -1
  219. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  220. package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
  221. package/dist/hooks/magic-context/postprocess-read-cache.d.ts +8 -0
  222. package/dist/hooks/magic-context/postprocess-read-cache.d.ts.map +1 -0
  223. package/dist/hooks/magic-context/producer-window-guard.d.ts +47 -1
  224. package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -1
  225. package/dist/hooks/magic-context/producer-window-test-support.d.ts +14 -0
  226. package/dist/hooks/magic-context/producer-window-test-support.d.ts.map +1 -0
  227. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +2 -0
  228. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  229. package/dist/hooks/magic-context/read-session-chunk.d.ts +51 -10
  230. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  231. package/dist/hooks/magic-context/read-session-db.d.ts +8 -0
  232. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  233. package/dist/hooks/magic-context/read-session-formatting.d.ts +6 -0
  234. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  235. package/dist/hooks/magic-context/read-session-raw.d.ts +4 -0
  236. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  237. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +6 -0
  238. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  239. package/dist/hooks/magic-context/recomp-orchestrator.d.ts +17 -39
  240. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  241. package/dist/hooks/magic-context/rust-mode-transform.d.ts +51 -0
  242. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  243. package/dist/hooks/magic-context/rust-refusal-recovery.d.ts +28 -0
  244. package/dist/hooks/magic-context/rust-refusal-recovery.d.ts.map +1 -0
  245. package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
  246. package/dist/hooks/magic-context/system-prompt-hash.d.ts +6 -7
  247. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  248. package/dist/hooks/magic-context/tag-messages.d.ts +21 -1
  249. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  250. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +63 -0
  251. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  252. package/dist/hooks/magic-context/tokenizer-calibration.d.ts +19 -12
  253. package/dist/hooks/magic-context/tokenizer-calibration.d.ts.map +1 -1
  254. package/dist/hooks/magic-context/tool-drop-target.d.ts +52 -1
  255. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  256. package/dist/hooks/magic-context/tool-sweep-policy.d.ts +50 -0
  257. package/dist/hooks/magic-context/tool-sweep-policy.d.ts.map +1 -0
  258. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +20 -1
  259. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  260. package/dist/hooks/magic-context/transform-context-state.d.ts +9 -0
  261. package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
  262. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +5 -3
  263. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  264. package/dist/hooks/magic-context/transform.d.ts +44 -4
  265. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  266. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  267. package/dist/{index-f9gem5cr.js → index-8w1skpnm.js} +85 -5
  268. package/dist/index-99sfbrrf.js +170 -0
  269. package/dist/index-9skq8m9y.js +16 -0
  270. package/dist/{index-3wbd8sdq.js → index-d0dh7v0f.js} +28107 -29850
  271. package/dist/{index-d8mgqezq.js → index-rpz2me0v.js} +133 -78
  272. package/dist/{index-p474rw9p.js → index-rvwvdq59.js} +1 -1
  273. package/dist/index-w2ety11c.js +393 -0
  274. package/dist/index-y5145x8k.js +619 -0
  275. package/dist/index-ygwdyntq.js +5407 -0
  276. package/dist/{index-jkrqhc7y.js → index-ykg9sdzz.js} +147 -28
  277. package/dist/index.d.ts.map +1 -1
  278. package/dist/index.js +7065 -3197
  279. package/dist/message-time-backfill-gzjer78y.js +108 -0
  280. package/dist/plugin/dream-timer.d.ts +13 -0
  281. package/dist/plugin/dream-timer.d.ts.map +1 -1
  282. package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
  283. package/dist/plugin/hooks/create-session-hooks.d.ts +5 -2
  284. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  285. package/dist/plugin/memory-id-translation.d.ts +109 -0
  286. package/dist/plugin/memory-id-translation.d.ts.map +1 -0
  287. package/dist/plugin/messages-transform.d.ts.map +1 -1
  288. package/dist/plugin/rpc-handlers.d.ts +10 -0
  289. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  290. package/dist/plugin/rust-note-backend.d.ts +84 -0
  291. package/dist/plugin/rust-note-backend.d.ts.map +1 -0
  292. package/dist/plugin/rust-tool-backends.d.ts +1 -1
  293. package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
  294. package/dist/plugin/tool-registry.d.ts +1 -0
  295. package/dist/plugin/tool-registry.d.ts.map +1 -1
  296. package/dist/read-session-chunk-ec3jkvhg.js +61 -0
  297. package/dist/{recomp-orchestrator-k20sfpm2.js → recomp-orchestrator-6akjp11f.js} +8 -8
  298. package/dist/{send-session-notification-xnypkxpx.js → send-session-notification-f6gwkesy.js} +2 -2
  299. package/dist/shared/assistant-message-extractor.d.ts +6 -0
  300. package/dist/shared/assistant-message-extractor.d.ts.map +1 -1
  301. package/dist/shared/auto-update-provenance.d.ts +9 -0
  302. package/dist/shared/auto-update-provenance.d.ts.map +1 -0
  303. package/dist/shared/conflict-detector.d.ts +14 -5
  304. package/dist/shared/conflict-detector.d.ts.map +1 -1
  305. package/dist/shared/hidden-variant-warnings.d.ts +5 -0
  306. package/dist/shared/hidden-variant-warnings.d.ts.map +1 -0
  307. package/dist/shared/host-limitations.d.ts +14 -0
  308. package/dist/shared/host-limitations.d.ts.map +1 -0
  309. package/dist/shared/keep-subagents.d.ts +1 -1
  310. package/dist/shared/keep-subagents.d.ts.map +1 -1
  311. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  312. package/dist/shared/models-dev-cache.d.ts +1 -0
  313. package/dist/shared/models-dev-cache.d.ts.map +1 -1
  314. package/dist/shared/opencode-config-dir.d.ts +52 -0
  315. package/dist/shared/opencode-config-dir.d.ts.map +1 -1
  316. package/dist/shared/opencode-db-path.d.ts +46 -2
  317. package/dist/shared/opencode-db-path.d.ts.map +1 -1
  318. package/dist/shared/prompt-surface-runtime.d.ts +6 -6
  319. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
  320. package/dist/shared/rpc-server.d.ts +10 -0
  321. package/dist/shared/rpc-server.d.ts.map +1 -1
  322. package/dist/shared/rpc-types.d.ts +64 -5
  323. package/dist/shared/rpc-types.d.ts.map +1 -1
  324. package/dist/shared/status-detail-text.d.ts +1 -3
  325. package/dist/shared/status-detail-text.d.ts.map +1 -1
  326. package/dist/shared/status-summary.d.ts +7 -0
  327. package/dist/shared/status-summary.d.ts.map +1 -1
  328. package/dist/shared/status-view.d.ts +229 -0
  329. package/dist/shared/status-view.d.ts.map +1 -0
  330. package/dist/shared/tag-transcript.d.ts.map +1 -1
  331. package/dist/shared/tail-hygiene-status.d.ts +8 -0
  332. package/dist/shared/tail-hygiene-status.d.ts.map +1 -1
  333. package/dist/shared/user-facing-codes.d.ts +32 -7
  334. package/dist/shared/user-facing-codes.d.ts.map +1 -1
  335. package/dist/shared/window-geometry.d.ts +3 -0
  336. package/dist/shared/window-geometry.d.ts.map +1 -1
  337. package/dist/{task-config-cv8k9y8r.js → task-config-ex4nt0q0.js} +1 -1
  338. package/dist/tools/ctx-expand/constants.d.ts +1 -1
  339. package/dist/tools/ctx-expand/constants.d.ts.map +1 -1
  340. package/dist/tools/ctx-expand/mode.d.ts +31 -0
  341. package/dist/tools/ctx-expand/mode.d.ts.map +1 -0
  342. package/dist/tools/ctx-expand/render.d.ts.map +1 -1
  343. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  344. package/dist/tools/ctx-memory/constants.d.ts +3 -1
  345. package/dist/tools/ctx-memory/constants.d.ts.map +1 -1
  346. package/dist/tools/ctx-memory/tools.d.ts +1 -0
  347. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  348. package/dist/tools/ctx-memory/types.d.ts +2 -2
  349. package/dist/tools/ctx-note/constants.d.ts +1 -1
  350. package/dist/tools/ctx-note/constants.d.ts.map +1 -1
  351. package/dist/tools/ctx-note/render.d.ts +88 -0
  352. package/dist/tools/ctx-note/render.d.ts.map +1 -0
  353. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  354. package/dist/tools/ctx-note/types.d.ts +1 -1
  355. package/dist/tools/ctx-note/types.d.ts.map +1 -1
  356. package/dist/tools/ctx-reduce/constants.d.ts +1 -1
  357. package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
  358. package/dist/tools/ctx-search/constants.d.ts +1 -1
  359. package/dist/tools/ctx-search/constants.d.ts.map +1 -1
  360. package/dist/tools/ctx-search/date-range.d.ts +9 -0
  361. package/dist/tools/ctx-search/date-range.d.ts.map +1 -0
  362. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  363. package/dist/tools/ctx-search/types.d.ts +3 -1
  364. package/dist/tools/ctx-search/types.d.ts.map +1 -1
  365. package/dist/tools/light-descriptions.d.ts +5 -5
  366. package/dist/tools/light-descriptions.d.ts.map +1 -1
  367. package/dist/tools/parameter-descriptions.d.ts +75 -0
  368. package/dist/tools/parameter-descriptions.d.ts.map +1 -0
  369. package/dist/transformers-node-wasm.js +1918 -826
  370. package/dist/transformers-web.js +1736 -636
  371. package/dist/{transformers.node-dpmf3wpx.js → transformers.node-3zqr6k1w.js} +4087 -2898
  372. package/dist/tui/data/context-db.d.ts +19 -7
  373. package/dist/tui/data/context-db.d.ts.map +1 -1
  374. package/dist/tui-compiled/data/context-db.d.ts +19 -7
  375. package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
  376. package/dist/v2/fold/host-media.d.ts +36 -0
  377. package/dist/v2/fold/host-media.d.ts.map +1 -0
  378. package/dist/v2/fold/restore.d.ts +21 -1
  379. package/dist/v2/fold/restore.d.ts.map +1 -1
  380. package/dist/v2/hidden-completion.d.ts +114 -14
  381. package/dist/v2/hidden-completion.d.ts.map +1 -1
  382. package/dist/v2/hooks/commands.d.ts +29 -0
  383. package/dist/v2/hooks/commands.d.ts.map +1 -0
  384. package/dist/v2/hooks/context.d.ts +58 -2
  385. package/dist/v2/hooks/context.d.ts.map +1 -1
  386. package/dist/v2/hooks/deleted-session-tombstones.d.ts +10 -0
  387. package/dist/v2/hooks/deleted-session-tombstones.d.ts.map +1 -0
  388. package/dist/v2/hooks/dream-manual.d.ts +43 -0
  389. package/dist/v2/hooks/dream-manual.d.ts.map +1 -0
  390. package/dist/v2/hooks/dream-trigger.d.ts +7 -0
  391. package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
  392. package/dist/v2/hooks/hidden-child.d.ts +32 -0
  393. package/dist/v2/hooks/hidden-child.d.ts.map +1 -0
  394. package/dist/v2/hooks/model-limit-cache.d.ts +19 -0
  395. package/dist/v2/hooks/model-limit-cache.d.ts.map +1 -0
  396. package/dist/v2/hooks/payload.d.ts.map +1 -1
  397. package/dist/v2/hooks/provider-admission.d.ts +22 -0
  398. package/dist/v2/hooks/provider-admission.d.ts.map +1 -0
  399. package/dist/v2/hooks/rpc-live-state.d.ts +9 -0
  400. package/dist/v2/hooks/rpc-live-state.d.ts.map +1 -0
  401. package/dist/v2/hooks/store.d.ts +38 -2
  402. package/dist/v2/hooks/store.d.ts.map +1 -1
  403. package/dist/v2/hooks/tools.d.ts +8 -0
  404. package/dist/v2/hooks/tools.d.ts.map +1 -0
  405. package/dist/v2/hooks/types.d.ts +157 -19
  406. package/dist/v2/hooks/types.d.ts.map +1 -1
  407. package/dist/v2/hooks/usage-reading.d.ts +42 -0
  408. package/dist/v2/hooks/usage-reading.d.ts.map +1 -0
  409. package/dist/v2/host-service.d.ts +65 -0
  410. package/dist/v2/host-service.d.ts.map +1 -0
  411. package/dist/v2/server.d.ts +19 -0
  412. package/dist/v2/server.d.ts.map +1 -1
  413. package/dist/v2/server.js +141849 -110533
  414. package/dist/v2/store-reader.d.ts +78 -6
  415. package/dist/v2/store-reader.d.ts.map +1 -1
  416. package/dist/v2/tui/events.d.ts +7 -0
  417. package/dist/v2/tui/events.d.ts.map +1 -0
  418. package/dist/v2/tui/index.d.ts +33 -0
  419. package/dist/v2/tui/index.d.ts.map +1 -0
  420. package/dist/v2/tui/sidebar-mount.d.ts +40 -0
  421. package/dist/v2/tui/sidebar-mount.d.ts.map +1 -0
  422. package/dist/v2/tui/status-dialog-mount.d.ts +29 -0
  423. package/dist/v2/tui/status-dialog-mount.d.ts.map +1 -0
  424. package/dist/v2/tui/types.d.ts +148 -0
  425. package/dist/v2/tui/types.d.ts.map +1 -0
  426. package/dist/wrapup-orchestrator-5akc87gr.js +16 -0
  427. package/package.json +9 -7
  428. package/src/agents/dreamer.ts +7 -16
  429. package/src/agents/hidden-agent-registrations.ts +10 -22
  430. package/src/agents/magic-context-prompt.test.ts +29 -39
  431. package/src/agents/magic-context-prompt.ts +99 -122
  432. package/src/agents/permissions.test.ts +17 -21
  433. package/src/config/index.ts +39 -4
  434. package/src/config/live-run-config.test.ts +237 -0
  435. package/src/config/live-run-config.ts +80 -0
  436. package/src/config/live-schema-drift.test.ts +67 -0
  437. package/src/config/live-snapshot.test.ts +85 -0
  438. package/src/config/live-snapshot.ts +191 -0
  439. package/src/config/protected-tokens.test.ts +40 -0
  440. package/src/config/raw-loader.test.ts +1 -0
  441. package/src/config/schema/magic-context.test.ts +13 -5
  442. package/src/config/schema/magic-context.ts +109 -13
  443. package/src/features/magic-context/dreamer/task-registry.ts +137 -13
  444. package/src/shared/assistant-message-extractor.test.ts +21 -0
  445. package/src/shared/assistant-message-extractor.ts +43 -8
  446. package/src/shared/auto-update-provenance.ts +42 -0
  447. package/src/shared/child-session-teardown.test.ts +38 -3
  448. package/src/shared/child-session-teardown.ts +3 -3
  449. package/src/shared/conflict-detector.test.ts +277 -7
  450. package/src/shared/conflict-detector.ts +221 -80
  451. package/src/shared/hidden-variant-warnings.ts +21 -0
  452. package/src/shared/host-limitations.ts +43 -0
  453. package/src/shared/keep-subagents.ts +6 -6
  454. package/src/shared/model-suggestion-retry.test.ts +43 -0
  455. package/src/shared/model-suggestion-retry.ts +12 -0
  456. package/src/shared/models-dev-cache.test.ts +25 -0
  457. package/src/shared/models-dev-cache.ts +5 -0
  458. package/src/shared/opencode-config-dir.ts +80 -7
  459. package/src/shared/opencode-db-path.test.ts +174 -0
  460. package/src/shared/opencode-db-path.ts +193 -15
  461. package/src/shared/opencode-host-generation.test.ts +29 -0
  462. package/src/shared/prompt-surface-a1-golden.md +142 -215
  463. package/src/shared/prompt-surface-runtime.test.ts +20 -0
  464. package/src/shared/prompt-surface-runtime.ts +7 -5
  465. package/src/shared/rpc-server.ts +18 -0
  466. package/src/shared/rpc-types.ts +63 -4
  467. package/src/shared/status-detail-text.test.ts +52 -18
  468. package/src/shared/status-detail-text.ts +1 -90
  469. package/src/shared/status-summary.ts +37 -2
  470. package/src/shared/status-view.test.ts +441 -0
  471. package/src/shared/status-view.ts +707 -0
  472. package/src/shared/tag-transcript.ts +115 -16
  473. package/src/shared/tail-hygiene-status.ts +9 -1
  474. package/src/shared/user-facing-codes.test.ts +3 -4
  475. package/src/shared/user-facing-codes.ts +33 -8
  476. package/src/shared/window-geometry.test.ts +23 -5
  477. package/src/shared/window-geometry.ts +13 -3
  478. package/src/tui/data/context-db.ts +50 -15
  479. package/src/tui/dialogs/status-dialog-colors.test.ts +58 -0
  480. package/src/tui/dialogs/status-dialog.tsx +288 -0
  481. package/src/tui/entry.mjs +11 -1
  482. package/src/tui/index.tsx +7 -464
  483. package/src/tui/slots/sidebar-content.tsx +21 -5
  484. package/src/tui-compiled/data/context-db.ts +50 -15
  485. package/src/tui-compiled/dialogs/status-dialog.tsx +552 -0
  486. package/src/tui-compiled/index.tsx +43 -1025
  487. package/src/tui-compiled/slots/sidebar-content.tsx +173 -152
  488. package/src/v2/tui/__fixtures__/ga-host-theme.json +160 -0
  489. package/src/v2/tui/events.ts +23 -0
  490. package/src/v2/tui/host-contract.test.ts +251 -0
  491. package/src/v2/tui/index.ts +526 -0
  492. package/src/v2/tui/load-compiled-sidebar.d.mts +59 -0
  493. package/src/v2/tui/load-compiled-sidebar.mjs +24 -0
  494. package/src/v2/tui/load-compiled-status-dialog.d.mts +17 -0
  495. package/src/v2/tui/load-compiled-status-dialog.mjs +16 -0
  496. package/src/v2/tui/sidebar-fallback.test.ts +100 -0
  497. package/src/v2/tui/sidebar-mount.ts +164 -0
  498. package/src/v2/tui/sidebar-text.test.ts +70 -0
  499. package/src/v2/tui/status-dialog-fallback.test.ts +97 -0
  500. package/src/v2/tui/status-dialog-mount.ts +76 -0
  501. package/src/v2/tui/theme-mapping.test.ts +57 -0
  502. package/src/v2/tui/types.ts +132 -0
  503. package/tui.js +1 -0
  504. package/dist/features/magic-context/memory/memory-migration.d.ts +0 -129
  505. package/dist/features/magic-context/memory/memory-migration.d.ts.map +0 -1
  506. package/dist/hooks/magic-context/upgrade-reminder.d.ts +0 -76
  507. package/dist/hooks/magic-context/upgrade-reminder.d.ts.map +0 -1
  508. package/dist/index-1ar7b3e9.js +0 -637
  509. package/dist/index-4wwr6cz0.js +0 -112
  510. package/dist/index-avwt563y.js +0 -62
  511. package/dist/storage-meta-session-x3j0q9qy.js +0 -20
@@ -9,19 +9,64 @@ export type {
9
9
  OpenCodeConfigPaths,
10
10
  } from "./opencode-config-dir-types";
11
11
 
12
- function getCliConfigDir(): string {
13
- const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
14
- if (envConfigDir) {
15
- return resolve(envConfigDir);
16
- }
12
+ /**
13
+ * The user's home directory, preferring `$HOME` over the cached value.
14
+ *
15
+ * `os.homedir()` reads `$HOME` once when the process starts and never again,
16
+ * so a test (or a wrapper) that sets `HOME` afterwards would otherwise be
17
+ * silently ignored and we would read the developer's real config. `$HOME` is
18
+ * normally unset on Windows, where the cached value is the right answer.
19
+ */
20
+ function resolveHomeDir(): string {
21
+ return process.env.HOME?.trim() || homedir();
22
+ }
17
23
 
24
+ /**
25
+ * OpenCode's GLOBAL config directory: `$XDG_CONFIG_HOME/opencode`, falling
26
+ * back to `~/.config/opencode` (on every platform, Windows included — OpenCode
27
+ * does not use %APPDATA%).
28
+ *
29
+ * This helper names the loader's XDG layer, not every OpenCode surface called
30
+ * "config". In 1.18.30, `Global.Path.config` is the pure-XDG path
31
+ * (`packages/core/src/global.ts:13`) and the loader merges it once at
32
+ * `packages/opencode/src/config/config.ts:412-413`. Its later directories loop
33
+ * accepts only `.opencode` paths or the exact `OPENCODE_CONFIG_DIR` value
34
+ * (`config.ts:437-441`), so the XDG layer is skipped there and the env path is
35
+ * merged last. The detector mirrors that loader order via
36
+ * {@link getOpenCodeConfigDirs}.
37
+ *
38
+ * Service consumers see a different value: `Global.make()` injects
39
+ * `Flag.OPENCODE_CONFIG_DIR ?? Path.config` as `config`
40
+ * (`packages/core/src/global.ts:64`), so setting the env var replaces the
41
+ * service's value even though the loader still merges the XDG layer.
42
+ */
43
+ export function getOpenCodeGlobalConfigDir(): string {
18
44
  if (process.platform === "win32") {
19
- return join(homedir(), ".config", "opencode");
45
+ return join(resolveHomeDir(), ".config", "opencode");
20
46
  }
21
47
 
22
- return join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "opencode");
48
+ return join(process.env.XDG_CONFIG_HOME || join(resolveHomeDir(), ".config"), "opencode");
49
+ }
50
+
51
+ function getEnvConfigDir(): string | undefined {
52
+ const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
53
+ return envConfigDir ? resolve(envConfigDir) : undefined;
54
+ }
55
+
56
+ function getCliConfigDir(): string {
57
+ return getEnvConfigDir() ?? getOpenCodeGlobalConfigDir();
23
58
  }
24
59
 
60
+ /**
61
+ * The single directory Magic Context WRITES its OpenCode-side config into.
62
+ *
63
+ * `OPENCODE_CONFIG_DIR` wins here on purpose: among the directories OpenCode
64
+ * reads it has the highest precedence, so a setting written there is the one
65
+ * that takes effect. Do NOT use this to decide what OpenCode RESOLVED — for
66
+ * that you must read every directory in {@link getOpenCodeConfigDirs}, because
67
+ * a value the user set in the global directory is still live when
68
+ * `OPENCODE_CONFIG_DIR` points somewhere that does not override it.
69
+ */
25
70
  export function getOpenCodeConfigDir(_options: OpenCodeConfigDirOptions): string {
26
71
  return getCliConfigDir();
27
72
  }
@@ -36,3 +81,31 @@ export function getOpenCodeConfigPaths(options: OpenCodeConfigDirOptions): OpenC
36
81
  omoConfig: join(configDir, "magic-context.jsonc"),
37
82
  };
38
83
  }
84
+
85
+ /**
86
+ * Every user-tier directory OpenCode reads config from, ordered from LOWEST to
87
+ * HIGHEST precedence — later entries override earlier ones, which is the order
88
+ * OpenCode merges them in.
89
+ *
90
+ * Verified against the opencode 1.18.30 binary (`ConfigPaths.directories` plus
91
+ * the global loader in `Config.loadInstanceState`) and confirmed on a live host
92
+ * with `opencode debug config`:
93
+ *
94
+ * 1. `$XDG_CONFIG_HOME/opencode` — always read, whatever the environment says
95
+ * 2. `~/.opencode` — always scanned, even outside a project
96
+ * 3. `$OPENCODE_CONFIG_DIR` — appended last, so it wins ties
97
+ *
98
+ * The important part is that entry 3 is an ADDITION, not a replacement. A
99
+ * launcher that exports `OPENCODE_CONFIG_DIR` to a directory holding only
100
+ * plugin scaffolding does not stop OpenCode from reading the user's real
101
+ * config in entry 1 — so neither may we.
102
+ *
103
+ * Project-level directories are deliberately not included: they depend on the
104
+ * working directory and are resolved by the caller that knows it.
105
+ */
106
+ export function getOpenCodeConfigDirs(): string[] {
107
+ const dirs = [getOpenCodeGlobalConfigDir(), join(resolveHomeDir(), ".opencode")];
108
+ const envDir = getEnvConfigDir();
109
+ if (envDir) dirs.push(envDir);
110
+ return [...new Set(dirs)];
111
+ }
@@ -5,13 +5,18 @@ import { mkdirSync, mkdtempSync, rmSync, unlinkSync, utimesSync, writeFileSync }
5
5
  import { tmpdir } from "node:os";
6
6
  import { join } from "node:path";
7
7
  import {
8
+ assertOpenCodeStoreGeneration,
9
+ detectOpenCodeStoreGeneration,
8
10
  formatOpenCodeDbDoctorLine,
9
11
  formatOpenCodeDbMissingBanner,
10
12
  formatOpenCodeDbMissingStatusLine,
13
+ hasV1MessageTables,
11
14
  openCodeDbPathExists,
12
15
  resetOpenCodeDbPathStateForTesting,
13
16
  resolveOpenCodeDbPath,
17
+ sourceOpenCodeDatabaseFilename,
14
18
  } from "./opencode-db-path";
19
+ import { Database } from "./sqlite";
15
20
 
16
21
  const ORIGINAL_ENV = {
17
22
  XDG_DATA_HOME: process.env.XDG_DATA_HOME,
@@ -173,6 +178,175 @@ describe("resolveOpenCodeDbPath", () => {
173
178
  });
174
179
  });
175
180
 
181
+ it("uses the verbatim v2 channel filename table without changing v1 defaults", () => {
182
+ const { dataHome, openCodeDir } = useDataHome();
183
+ for (const channel of ["latest", "dev", "beta", "next", "prod"]) {
184
+ expect(sourceOpenCodeDatabaseFilename("v2", channel, {})).toBe("opencode.db");
185
+ }
186
+ expect(sourceOpenCodeDatabaseFilename("v2", "a/b c!._-", {})).toBe("opencode-abc._-.db");
187
+ expect(
188
+ resolveOpenCodeDbPath("v2", {
189
+ dataHome,
190
+ channel: "local",
191
+ env: { OPENCODE_DB: "opencode2.db" },
192
+ }),
193
+ ).toEqual({
194
+ path: join(openCodeDir, "opencode2.db"),
195
+ source: "OPENCODE_DB",
196
+ channel: null,
197
+ });
198
+ });
199
+
200
+ it("detects store generations and refuses a mismatched schema before reading", () => {
201
+ const { openCodeDir } = useDataHome();
202
+ const v1Path = join(openCodeDir, "v1.db");
203
+ const v2Path = join(openCodeDir, "v2.db");
204
+ const v1 = new Database(v1Path);
205
+ const v2 = new Database(v2Path);
206
+ try {
207
+ v1.exec("CREATE TABLE message(id TEXT); CREATE TABLE part(id TEXT)");
208
+ v2.exec("CREATE TABLE session_message(id TEXT)");
209
+ expect(detectOpenCodeStoreGeneration(v1)).toBe("v1");
210
+ expect(detectOpenCodeStoreGeneration(v2)).toBe("v2");
211
+ expect(() => assertOpenCodeStoreGeneration(v2, "v1", v2Path)).toThrow(
212
+ "expected v1, found v2",
213
+ );
214
+ expect(() => assertOpenCodeStoreGeneration(v1, "v2", v1Path)).toThrow(
215
+ "expected v2, found v1",
216
+ );
217
+ } finally {
218
+ v1.close();
219
+ v2.close();
220
+ }
221
+ });
222
+
223
+ it("reads a live OpenCode 1.18.x store as v1 even though it ships session_message", () => {
224
+ const { openCodeDir } = useDataHome();
225
+ const livePath = join(openCodeDir, "live-v1.db");
226
+ const live = new Database(livePath);
227
+ try {
228
+ // Captured from a running OpenCode 1.18.30 store. session_message exists in v1,
229
+ // so a detector keyed on its presence calls a v1 host v2 and every v1 reader
230
+ // (historian chunk, marker discovery, message index, tool-owner backfill) then
231
+ // refuses. Keep this table list as observed, not as remembered.
232
+ for (const table of [
233
+ "account",
234
+ "event",
235
+ "message",
236
+ "part",
237
+ "permission",
238
+ "project",
239
+ "session",
240
+ "session_message",
241
+ "session_run_lease",
242
+ "todo",
243
+ "workspace",
244
+ ]) {
245
+ live.exec(`CREATE TABLE ${table}(id TEXT)`);
246
+ }
247
+ expect(detectOpenCodeStoreGeneration(live)).toBe("v1");
248
+ expect(() => assertOpenCodeStoreGeneration(live, "v1", livePath)).not.toThrow();
249
+ expect(() => assertOpenCodeStoreGeneration(live, "v2", livePath)).toThrow(
250
+ "expected v2, found v1",
251
+ );
252
+ } finally {
253
+ live.close();
254
+ }
255
+ });
256
+
257
+ it("reports v1 message capability on a migrated store accepted by both readers", () => {
258
+ const { openCodeDir } = useDataHome();
259
+ const migratedPath = join(openCodeDir, "migrated-v2.db");
260
+ const migrated = new Database(migratedPath);
261
+ try {
262
+ // Captured from an OpenCode 2.0.7 store that the v2 host migrated from a 1.18.x
263
+ // store: it keeps the v1 `message`/`part` tables beside its own schema, so it
264
+ // carries BOTH generations. `session_v2` is written only by an OpenCode 2 host
265
+ // (the 1.18.31 binary never references it). Keep this table list as observed.
266
+ for (const table of [
267
+ "account",
268
+ "account_state",
269
+ "control_account",
270
+ "credential",
271
+ "event",
272
+ "event_sequence",
273
+ "instruction_blob",
274
+ "instruction_entry",
275
+ "instruction_state",
276
+ "kv",
277
+ "message",
278
+ "migration",
279
+ "part",
280
+ "permission",
281
+ "project",
282
+ "project_directory",
283
+ "session",
284
+ "session_inbox",
285
+ "session_message",
286
+ "session_pending",
287
+ "session_share",
288
+ "session_v2",
289
+ "todo",
290
+ "workspace",
291
+ "worktree",
292
+ ]) {
293
+ migrated.exec(`CREATE TABLE ${table}(id TEXT)`);
294
+ }
295
+ expect(hasV1MessageTables(migrated)).toBe(true);
296
+ expect(() => assertOpenCodeStoreGeneration(migrated, "v2", migratedPath)).not.toThrow();
297
+ expect(() => assertOpenCodeStoreGeneration(migrated, "v1", migratedPath)).not.toThrow();
298
+ } finally {
299
+ migrated.close();
300
+ }
301
+ });
302
+
303
+ it("reads a fresh OpenCode 2 store as v2 only", () => {
304
+ const { openCodeDir } = useDataHome();
305
+ const freshV2Path = join(openCodeDir, "fresh-v2.db");
306
+ const freshV2 = new Database(freshV2Path);
307
+ try {
308
+ // Captured from a new OpenCode 2.0.7 data directory: no v1 message tables.
309
+ for (const table of [
310
+ "account",
311
+ "event",
312
+ "migration",
313
+ "permission",
314
+ "project",
315
+ "session_inbox",
316
+ "session_message",
317
+ "session_pending",
318
+ "session_v2",
319
+ "workspace",
320
+ ]) {
321
+ freshV2.exec(`CREATE TABLE ${table}(id TEXT)`);
322
+ }
323
+ expect(hasV1MessageTables(freshV2)).toBe(false);
324
+ expect(detectOpenCodeStoreGeneration(freshV2)).toBe("v2");
325
+ expect(() => assertOpenCodeStoreGeneration(freshV2, "v2", freshV2Path)).not.toThrow();
326
+ expect(() => assertOpenCodeStoreGeneration(freshV2, "v1", freshV2Path)).toThrow(
327
+ "expected v1, found v2",
328
+ );
329
+ } finally {
330
+ freshV2.close();
331
+ }
332
+ });
333
+
334
+ it("treats a store with no schema yet as empty rather than as a conflicting host", () => {
335
+ const { openCodeDir } = useDataHome();
336
+ const freshPath = join(openCodeDir, "fresh.db");
337
+ const fresh = new Database(freshPath);
338
+ try {
339
+ // A host that has not written its first row looks like this. Readers have always
340
+ // seen it as empty; refusing here throws inside the historian, marker and index
341
+ // readers on every fresh data directory.
342
+ expect(detectOpenCodeStoreGeneration(fresh)).toBe("unknown");
343
+ expect(() => assertOpenCodeStoreGeneration(fresh, "v1", freshPath)).not.toThrow();
344
+ expect(() => assertOpenCodeStoreGeneration(fresh, "v2", freshPath)).not.toThrow();
345
+ } finally {
346
+ fresh.close();
347
+ }
348
+ });
349
+
176
350
  it("formats the missing banner, status, and doctor lines by value", () => {
177
351
  const { openCodeDir } = useDataHome();
178
352
  const lookedFor = [
@@ -3,6 +3,40 @@ import { homedir } from "node:os";
3
3
  import { isAbsolute, join } from "node:path";
4
4
 
5
5
  export type OpenCodeDbPathSource = "OPENCODE_DB" | "channel" | "default" | "discovered";
6
+ export type OpenCodeHostGeneration = "v1" | "v2";
7
+ export type OpenCodeStoreGeneration = OpenCodeHostGeneration | "unknown";
8
+
9
+ export interface ResolveOpenCodeDbPathOptions {
10
+ dataHome?: string;
11
+ channel?: string;
12
+ env?: NodeJS.ProcessEnv;
13
+ }
14
+
15
+ /**
16
+ * Decide the host generation from the version the executable reports, never
17
+ * from its name (the public installer places OpenCode 2 at
18
+ * `~/.opencode/bin/opencode` with a tiny `opencode2` shim beside it). The raw
19
+ * `--version` stdout carries a program-name prefix ("opencode v2.0.12"), so the
20
+ * major is the first digit run, not `parseInt` of the whole string.
21
+ *
22
+ * OpenCode 2's pre-GA betas were published under the old scope as
23
+ * `@opencode-ai/*@0.0.0-beta-<n>` (verified: `0.0.0-beta-19234` ships the V2
24
+ * `host`/`promise`/`effect` contract and the `compaction` hook); at GA the line
25
+ * moved to `@opencode/*@2.0.x`. A major of 0 therefore does not mean 1.x: the
26
+ * beta and dev pre-release shapes are OpenCode 2.
27
+ */
28
+ export function openCodeHostGenerationFromVersion(
29
+ version: string | null | undefined,
30
+ ): OpenCodeHostGeneration {
31
+ const text = version ?? "";
32
+ if (/(?:^|\s|v)0\.0\.0-(?:beta|dev)-/.test(text)) return "v2";
33
+ const major = Number.parseInt(text.match(/\d+/)?.[0] ?? "", 10);
34
+ return Number.isFinite(major) && major >= 2 ? "v2" : "v1";
35
+ }
36
+
37
+ export interface OpenCodeStoreSchemaDatabase {
38
+ prepare(sql: string): { all(...params: unknown[]): unknown[] };
39
+ }
6
40
 
7
41
  export interface OpenCodeDbPathResolution {
8
42
  path: string;
@@ -24,16 +58,22 @@ let cachedResolution: CachedResolution | null = null;
24
58
  let lastReadFailure: OpenCodeDbReadFailure | null = null;
25
59
  const claimedDiagnostics = new Set<string>();
26
60
 
27
- function openCodeDataDir(): string {
28
- return join(process.env.XDG_DATA_HOME ?? join(homedir(), ".local", "share"), "opencode");
61
+ function openCodeDataDir(env: NodeJS.ProcessEnv = process.env, dataHome?: string): string {
62
+ return join(dataHome ?? env.XDG_DATA_HOME ?? join(homedir(), ".local", "share"), "opencode");
29
63
  }
30
64
 
31
- function environmentKey(dataDir: string): string {
65
+ function environmentKey(
66
+ dataDir: string,
67
+ hostGeneration: OpenCodeHostGeneration,
68
+ channel: string | undefined,
69
+ env: NodeJS.ProcessEnv,
70
+ ): string {
32
71
  return [
72
+ hostGeneration,
33
73
  dataDir,
34
- process.env.OPENCODE_DB ?? "",
35
- process.env.OPENCODE_DISABLE_CHANNEL_DB ?? "",
36
- process.env.OPENCODE_CHANNEL ?? "",
74
+ env.OPENCODE_DB ?? "",
75
+ env.OPENCODE_DISABLE_CHANNEL_DB ?? "",
76
+ channel ?? env.OPENCODE_CHANNEL ?? "",
37
77
  ].join("\0");
38
78
  }
39
79
 
@@ -81,8 +121,11 @@ function discoverOpenCodeDb(dataDir: string): OpenCodeDbPathResolution {
81
121
  return { path: existing.path, source: "discovered", channel };
82
122
  }
83
123
 
84
- function resolveFresh(dataDir: string): OpenCodeDbPathResolution {
85
- const explicit = process.env.OPENCODE_DB;
124
+ function resolveV1Fresh(
125
+ dataDir: string,
126
+ env: NodeJS.ProcessEnv = process.env,
127
+ ): OpenCodeDbPathResolution {
128
+ const explicit = env.OPENCODE_DB;
86
129
  if (explicit !== undefined && explicit.length > 0) {
87
130
  if (explicit === ":memory:") {
88
131
  return { path: explicit, source: "OPENCODE_DB", channel: null };
@@ -94,12 +137,12 @@ function resolveFresh(dataDir: string): OpenCodeDbPathResolution {
94
137
  };
95
138
  }
96
139
 
97
- const disableChannelDb = process.env.OPENCODE_DISABLE_CHANNEL_DB;
140
+ const disableChannelDb = env.OPENCODE_DISABLE_CHANNEL_DB;
98
141
  if (disableChannelDb === "1" || disableChannelDb === "true") {
99
142
  return { path: join(dataDir, "opencode.db"), source: "default", channel: null };
100
143
  }
101
144
 
102
- const channel = process.env.OPENCODE_CHANNEL;
145
+ const channel = env.OPENCODE_CHANNEL;
103
146
  if (channel !== undefined && channel.length > 0) {
104
147
  return { path: channelPath(dataDir, channel), source: "channel", channel };
105
148
  }
@@ -107,10 +150,59 @@ function resolveFresh(dataDir: string): OpenCodeDbPathResolution {
107
150
  return discoverOpenCodeDb(dataDir);
108
151
  }
109
152
 
110
- /** Resolve an explicit DB override first, then channel paths; discover candidates when the compiled channel is unknown. */
111
- export function resolveOpenCodeDbPath(): OpenCodeDbPathResolution {
112
- const dataDir = openCodeDataDir();
113
- const key = environmentKey(dataDir);
153
+ /** Match OpenCode 2's filename table and strip path separators from custom channels. */
154
+ export function sourceOpenCodeDatabaseFilename(
155
+ hostGeneration: OpenCodeHostGeneration,
156
+ channel: string,
157
+ env: NodeJS.ProcessEnv = process.env,
158
+ ): string {
159
+ if (hostGeneration === "v1") {
160
+ const explicit = env.OPENCODE_DB;
161
+ if (explicit !== undefined && explicit.length > 0) return explicit;
162
+ if (env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true") {
163
+ return "opencode.db";
164
+ }
165
+ return ["latest", "beta", "prod"].includes(channel)
166
+ ? "opencode.db"
167
+ : `opencode-${channel}.db`;
168
+ }
169
+
170
+ return (
171
+ env.OPENCODE_DB ??
172
+ (["latest", "dev", "beta", "next", "prod"].includes(channel) ||
173
+ env.OPENCODE_DISABLE_CHANNEL_DB === "1" ||
174
+ env.OPENCODE_DISABLE_CHANNEL_DB === "true"
175
+ ? "opencode.db"
176
+ : `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "")}.db`)
177
+ );
178
+ }
179
+
180
+ function resolveV2Fresh(
181
+ dataDir: string,
182
+ channel: string,
183
+ env: NodeJS.ProcessEnv,
184
+ ): OpenCodeDbPathResolution {
185
+ const filename = sourceOpenCodeDatabaseFilename("v2", channel, env);
186
+ const explicit = env.OPENCODE_DB !== undefined;
187
+ return {
188
+ path: filename === ":memory:" ? filename : join(dataDir, filename),
189
+ source: explicit ? "OPENCODE_DB" : env.OPENCODE_CHANNEL ? "channel" : "default",
190
+ channel: explicit ? null : channel,
191
+ };
192
+ }
193
+
194
+ /**
195
+ * Resolve the store for one host generation. The default is the historical v1
196
+ * resolver, including candidate discovery and all existing diagnostic text.
197
+ */
198
+ export function resolveOpenCodeDbPath(
199
+ hostGeneration: OpenCodeHostGeneration = "v1",
200
+ options: ResolveOpenCodeDbPathOptions = {},
201
+ ): OpenCodeDbPathResolution {
202
+ const env = options.env ?? process.env;
203
+ const dataDir = openCodeDataDir(env, options.dataHome);
204
+ const channel = options.channel ?? env.OPENCODE_CHANNEL;
205
+ const key = environmentKey(dataDir, hostGeneration, channel, env);
114
206
  if (
115
207
  cachedResolution?.key === key &&
116
208
  (!cachedResolution.existed || existsSync(cachedResolution.resolution.path))
@@ -119,7 +211,10 @@ export function resolveOpenCodeDbPath(): OpenCodeDbPathResolution {
119
211
  // An absent result is re-probed so a DB created after plugin boot is detected.
120
212
  }
121
213
 
122
- const resolution = resolveFresh(dataDir);
214
+ const resolution =
215
+ hostGeneration === "v2"
216
+ ? resolveV2Fresh(dataDir, channel ?? "latest", env)
217
+ : resolveV1Fresh(dataDir, env);
123
218
  cachedResolution = {
124
219
  key,
125
220
  resolution,
@@ -128,6 +223,89 @@ export function resolveOpenCodeDbPath(): OpenCodeDbPathResolution {
128
223
  return resolution;
129
224
  }
130
225
 
226
+ function schemaTableNames(
227
+ db: OpenCodeStoreSchemaDatabase,
228
+ schema: "main" | "oc_backfill" = "main",
229
+ ): Set<string> {
230
+ const rows = db
231
+ .prepare(
232
+ `SELECT name FROM ${schema}.sqlite_master WHERE type = 'table' AND name IN ('message', 'part', 'session', 'project', 'session_message', 'session_v2')`,
233
+ )
234
+ .all() as Array<{ name?: unknown }>;
235
+ return new Set(rows.flatMap((row) => (typeof row.name === "string" ? [row.name] : [])));
236
+ }
237
+
238
+ /** Whether the schema has the legacy message tables required by v1-only readers. */
239
+ export function hasV1MessageTables(
240
+ db: OpenCodeStoreSchemaDatabase,
241
+ schema: "main" | "oc_backfill" = "main",
242
+ ): boolean {
243
+ const tables = schemaTableNames(db, schema);
244
+ return tables.has("message") && tables.has("part");
245
+ }
246
+
247
+ /**
248
+ * Detect the persisted host schema.
249
+ *
250
+ * `session_message` does NOT identify v2: OpenCode 1.18.x ships that table beside `message`
251
+ * and `part` (verified against a live 1.18.30 store, pinned in this module's tests). Only the
252
+ * ABSENCE of the v1 message tables identifies a v2 store, so a v1 host is never mistaken for
253
+ * a v2 one. A store carrying neither is a host that has not written its schema yet.
254
+ */
255
+ export function detectOpenCodeStoreGeneration(
256
+ db: OpenCodeStoreSchemaDatabase,
257
+ schema: "main" | "oc_backfill" = "main",
258
+ ): OpenCodeStoreGeneration {
259
+ const tables = schemaTableNames(db, schema);
260
+ const hasV1Messages = tables.has("message") && tables.has("part");
261
+ if (hasV1Messages) return "v1";
262
+ if (tables.has("session_message")) return "v2";
263
+ if (tables.has("session") || tables.has("project")) return "v1";
264
+ return "unknown";
265
+ }
266
+
267
+ /**
268
+ * A store the OpenCode 2 host migrated from a v1 store keeps the v1 `message`/`part` tables
269
+ * beside its own schema, so it carries BOTH generations and `detectOpenCodeStoreGeneration`
270
+ * (which must keep calling a 1.18.x store v1) reports v1. `session_v2` is written only by an
271
+ * OpenCode 2 host (1.18.x never creates it), so a store with it and `session_message` is
272
+ * readable by v2 readers regardless of any v1 tables it also kept.
273
+ */
274
+ function hasMigratedV2Schema(tables: Set<string>): boolean {
275
+ return tables.has("session_message") && tables.has("session_v2");
276
+ }
277
+
278
+ /** A native OpenCode 2 store, or a v1 store an OpenCode 2 host has migrated. */
279
+ function isOpenCodeV2Store(
280
+ db: OpenCodeStoreSchemaDatabase,
281
+ schema: "main" | "oc_backfill" = "main",
282
+ ): boolean {
283
+ return (
284
+ detectOpenCodeStoreGeneration(db, schema) === "v2" ||
285
+ hasMigratedV2Schema(schemaTableNames(db, schema))
286
+ );
287
+ }
288
+
289
+ /** Refuse before a generation-specific query can read the other host's schema. */
290
+ export function assertOpenCodeStoreGeneration(
291
+ db: OpenCodeStoreSchemaDatabase,
292
+ expected: OpenCodeHostGeneration,
293
+ path: string,
294
+ schema: "main" | "oc_backfill" = "main",
295
+ ): void {
296
+ const actual = detectOpenCodeStoreGeneration(db, schema);
297
+ if (actual === expected) return;
298
+ if (expected === "v2" && isOpenCodeV2Store(db, schema)) return;
299
+ // A store with none of these tables has no schema YET — a host that has not written its
300
+ // first row, or a fresh data directory. That is "nothing to read", not a conflicting host,
301
+ // and readers have always treated it as empty. Refusing here made every reader throw before
302
+ // OpenCode created its tables, which is how this guard took down 15 host e2e tests.
303
+ if (actual === "unknown") return;
304
+ throw new Error(
305
+ `OpenCode store generation mismatch at ${path}: expected ${expected}, found ${actual}; refusing generation-specific database access`,
306
+ );
307
+ }
308
+
131
309
  export function openCodeDbPathExists(
132
310
  resolution: OpenCodeDbPathResolution = resolveOpenCodeDbPath(),
133
311
  ): boolean {
@@ -0,0 +1,29 @@
1
+ import { describe, expect, it } from "bun:test";
2
+ import { openCodeHostGenerationFromVersion } from "./opencode-db-path";
3
+
4
+ // The generation is decided from the version the executable reports, never
5
+ // from its name: the public installer puts OpenCode 2 at ~/.opencode/bin/opencode
6
+ // with a tiny `opencode2` shim beside it, so the name says nothing. The raw
7
+ // `--version` stdout carries a program-name prefix ("opencode v2.0.12"); a
8
+ // parser that feeds that to Number.parseInt reads NaN and demotes every
9
+ // standalone 2.x install to 1.x (AFT hit this on a clean VM, 2026-09-21).
10
+ // OpenCode 2's pre-GA betas were `@opencode-ai/*@0.0.0-beta-<n>` — the V2 line
11
+ // wearing the old scope's version string — so a major of 0 is v2, not v1.
12
+ describe("OpenCode host generation from --version output", () => {
13
+ it.each([
14
+ ["opencode v2.0.12", "v2"],
15
+ ["v2.0.12", "v2"],
16
+ ["2.0.12", "v2"],
17
+ ["opencode v2.0.12\n", "v2"],
18
+ ["opencode 1.18.31", "v1"],
19
+ ["1.18.31", "v1"],
20
+ ["0.0.0-beta-19234", "v2"],
21
+ ["opencode v0.0.0-beta-19234", "v2"],
22
+ ["0.0.0-dev-42", "v2"],
23
+ ["0.9.3", "v1"],
24
+ [null, "v1"],
25
+ ["", "v1"],
26
+ ])("%p → %s", (raw, expected) => {
27
+ expect(openCodeHostGenerationFromVersion(raw)).toBe(expected);
28
+ });
29
+ });