@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
@@ -2,12 +2,15 @@ import { homedir } from "node:os";
2
2
  import { join } from "node:path";
3
3
  import { readJsoncFile } from "./jsonc-parser";
4
4
  import { log } from "./logger";
5
- import { getOpenCodeConfigPaths } from "./opencode-config-dir";
5
+ import { getOpenCodeConfigDirs, getOpenCodeGlobalConfigDir } from "./opencode-config-dir";
6
+ import type { OpenCodeHostGeneration } from "./opencode-db-path";
6
7
 
7
8
  interface OpenCodeConfig {
8
9
  compaction?: {
9
10
  auto?: boolean;
10
11
  prune?: boolean;
12
+ keep?: { tokens?: number };
13
+ buffer?: number;
11
14
  };
12
15
  // OpenCode allows plugins as plain strings or [name, options] tuples.
13
16
  plugin?: Array<string | [string, unknown]>;
@@ -62,6 +65,8 @@ export interface ConflictResult {
62
65
  export interface ResolvedCompaction {
63
66
  auto: boolean;
64
67
  prune: boolean;
68
+ keepTokens?: number;
69
+ buffer?: number;
65
70
  }
66
71
 
67
72
  /**
@@ -92,6 +97,7 @@ export interface ResolvedCompaction {
92
97
  export interface DetectConflictsOptions {
93
98
  compactionEnabled?: boolean;
94
99
  resolvedCompaction?: ResolvedCompaction;
100
+ hostGeneration?: OpenCodeHostGeneration;
95
101
  }
96
102
 
97
103
  /**
@@ -113,6 +119,7 @@ export function detectConflicts(
113
119
  options?: DetectConflictsOptions,
114
120
  ): ConflictResult {
115
121
  const compactionEnabled = options?.compactionEnabled ?? true;
122
+ const hostGeneration = options?.hostGeneration ?? "v1";
116
123
  const conflicts: ConflictResult["conflicts"] = {
117
124
  compactionAuto: false,
118
125
  compactionPrune: false,
@@ -129,7 +136,8 @@ export function detectConflicts(
129
136
  // wrongly disabling the plugin for users whose auto=false lives in a layer
130
137
  // the file reader cannot see). When the resolved fetch failed, fall back to
131
138
  // the file-based check unchanged.
132
- let compactionResult = options?.resolvedCompaction ?? checkCompaction(directory);
139
+ let compactionResult =
140
+ options?.resolvedCompaction ?? checkCompaction(directory, hostGeneration);
133
141
  // OPENCODE_DISABLE_AUTOCOMPACT short-circuits BOTH arms: it is the first,
134
142
  // cheapest check and is correct regardless of which arm produced the value.
135
143
  // (checkCompaction already applies it internally for the file arm; this
@@ -141,7 +149,7 @@ export function detectConflicts(
141
149
  // compaction-off mode the user has explicitly handed the window to native
142
150
  // compaction (or nothing), so compaction.auto=true / prune=true are the
143
151
  // intended state, not a plugin-disabling conflict.
144
- if (compactionEnabled && compactionResult.auto) {
152
+ if (hostGeneration === "v1" && compactionEnabled && compactionResult.auto) {
145
153
  conflicts.compactionAuto = true;
146
154
  reasons.push(
147
155
  options?.resolvedCompaction
@@ -149,7 +157,7 @@ export function detectConflicts(
149
157
  : "OpenCode auto-compaction is enabled (compaction.auto=true)",
150
158
  );
151
159
  }
152
- if (compactionEnabled && compactionResult.prune) {
160
+ if (hostGeneration === "v1" && compactionEnabled && compactionResult.prune) {
153
161
  conflicts.compactionPrune = true;
154
162
  reasons.push(
155
163
  options?.resolvedCompaction
@@ -192,7 +200,10 @@ export function detectConflicts(
192
200
  hasConflict: reasons.length > 0,
193
201
  reasons,
194
202
  conflicts,
195
- nativeCompaction: { auto: compactionResult.auto, prune: compactionResult.prune },
203
+ nativeCompaction: {
204
+ auto: compactionResult.auto,
205
+ prune: hostGeneration === "v1" ? compactionResult.prune : false,
206
+ },
196
207
  };
197
208
  }
198
209
 
@@ -221,6 +232,8 @@ interface ResolvedCompactionBlock {
221
232
  compaction?: {
222
233
  auto?: boolean;
223
234
  prune?: boolean;
235
+ keep?: { tokens?: number };
236
+ buffer?: number;
224
237
  };
225
238
  }
226
239
 
@@ -239,16 +252,22 @@ interface ResolvedCompactionBlock {
239
252
  * `compaction` key, and reading that absence as `auto=true` disables the
240
253
  * plugin — the one wrong direction, because a false disable leaves NOTHING
241
254
  * managing the window and every long session overflows (issue #309, second
242
- * arm). Only an explicit boolean from the host resolves this arm; anything
243
- * else returns `null` so the caller falls back to the file-based check,
244
- * which reads the layers the user actually wrote.
255
+ * arm). Only an explicit `compaction.auto` boolean from the host resolves
256
+ * this arm; anything else returns `null` so the caller falls back to the
257
+ * file-based check, which reads the layers the user actually wrote.
258
+ *
259
+ * `compaction.prune` is read when present and treated as `false` when absent.
260
+ * OpenCode serves only the keys the user wrote, so requiring it here rejected
261
+ * the ordinary `{"compaction": {"auto": false}}` config and sent an
262
+ * answerable question to the file arm (issue #484).
245
263
  *
246
264
  * Returns `null` when the fetch fails, times out (bounded to `timeoutMs` so
247
- * boot never hangs), or serves no explicit compaction block.
265
+ * boot never hangs), or serves no explicit `compaction.auto`.
248
266
  */
249
267
  export async function resolveCompactionForBoot(
250
268
  client: OpencodeConfigClientLike,
251
269
  timeoutMs = 2_000,
270
+ hostGeneration: OpenCodeHostGeneration = "v1",
252
271
  ): Promise<ResolvedCompaction | null> {
253
272
  const controller = new AbortController();
254
273
  let timer: ReturnType<typeof setTimeout> | undefined;
@@ -276,16 +295,49 @@ export async function resolveCompactionForBoot(
276
295
  // The SDK's generated `Config` type has no `compaction` key, so read it
277
296
  // defensively from the runtime response.
278
297
  const compaction = (result?.data as ResolvedCompactionBlock | undefined)?.compaction;
279
- // Explicit booleans only. An absent block (or non-boolean values) means
280
- // the response shape did not carry the resolved state — fall back to the
281
- // file arm rather than resolving to the plugin-disabling default.
282
- if (typeof compaction?.auto !== "boolean" || typeof compaction?.prune !== "boolean") {
298
+ if (hostGeneration === "v2") {
299
+ if (typeof compaction?.auto !== "boolean") {
300
+ log(
301
+ `[magic-context] conflict-detector: resolved v2 config carried no explicit compaction.auto (${JSON.stringify(compaction) ?? "absent"}); falling back to file-based detection`,
302
+ );
303
+ return null;
304
+ }
305
+ const keepTokens = compaction.keep?.tokens;
306
+ const buffer = compaction.buffer;
307
+ if (
308
+ (keepTokens !== undefined && (!Number.isInteger(keepTokens) || keepTokens < 0)) ||
309
+ (buffer !== undefined && (!Number.isInteger(buffer) || buffer < 0))
310
+ ) {
311
+ return null;
312
+ }
313
+ return {
314
+ auto: compaction.auto,
315
+ prune: false,
316
+ ...(keepTokens === undefined ? {} : { keepTokens }),
317
+ ...(buffer === undefined ? {} : { buffer }),
318
+ };
319
+ }
320
+ // `compaction.auto` is the value the whole conflict decision turns on,
321
+ // so an explicit boolean for it is required: an absent block means the
322
+ // response did not carry the resolved state, and reading that absence
323
+ // as the host default would disable the plugin (issue #309).
324
+ //
325
+ // `compaction.prune` is NOT required. OpenCode merges only the keys a
326
+ // user actually wrote and does not materialise schema defaults into the
327
+ // resolved config, so the ordinary `{"compaction": {"auto": false}}`
328
+ // setup serves a block with no `prune` key at all — verified against
329
+ // opencode 1.18.30 with `opencode debug config`. Demanding both
330
+ // booleans rejected that every-day shape and pushed the decision onto
331
+ // the file arm, which is how issue #484's reporter reached the file
332
+ // arm at all. An absent `prune` takes OpenCode's documented default of
333
+ // `false`, which is also the non-disabling direction.
334
+ if (typeof compaction?.auto !== "boolean") {
283
335
  log(
284
- `[magic-context] conflict-detector: resolved config carried no explicit compaction block (${JSON.stringify(compaction) ?? "absent"}); falling back to file-based detection`,
336
+ `[magic-context] conflict-detector: resolved config carried no explicit compaction.auto (${JSON.stringify(compaction) ?? "absent"}); falling back to file-based detection`,
285
337
  );
286
338
  return null;
287
339
  }
288
- return { auto: compaction.auto, prune: compaction.prune };
340
+ return { auto: compaction.auto, prune: compaction.prune === true };
289
341
  } catch {
290
342
  return null;
291
343
  } finally {
@@ -293,74 +345,154 @@ export async function resolveCompactionForBoot(
293
345
  }
294
346
  }
295
347
 
296
- function checkCompaction(directory: string): { auto: boolean; prune: boolean } {
348
+ function checkCompaction(
349
+ directory: string,
350
+ hostGeneration: OpenCodeHostGeneration,
351
+ ): ResolvedCompaction {
297
352
  if (process.env.OPENCODE_DISABLE_AUTOCOMPACT) {
298
353
  return { auto: false, prune: false };
299
354
  }
300
355
 
301
- // Check project-level config first (higher precedence)
302
- const projectResult = readProjectCompaction(directory);
303
- if (projectResult.resolved) return projectResult;
304
-
305
- // Fall back to user-level config
306
- const userResult = readUserCompaction();
307
- if (userResult.resolved) return userResult;
356
+ const merged = readCompactionFromConfigFiles(directory, hostGeneration);
357
+ if (isRelevantCompactionBlock(merged, hostGeneration)) {
358
+ return resolvedCompactionBlock(merged, hostGeneration);
359
+ }
308
360
 
309
- // Default: OpenCode has compaction enabled by default
310
- return { auto: true, prune: false };
361
+ // Nothing in any file OpenCode reads carried an explicit compaction key.
362
+ // That is INCONCLUSIVE, not "the host default applies", and it must never
363
+ // resolve to the plugin-disabling `auto: true`. We cannot tell "the user
364
+ // wrote nothing" apart from "the user's setting lives somewhere this
365
+ // reader cannot see" — a managed/remote config layer, a directory a
366
+ // launcher pointed us away from, a file we failed to parse. Guessing the
367
+ // disabling direction is the one guess with an unrecoverable cost: the
368
+ // plugin switches off and NOTHING manages the context window, so every
369
+ // long session overflows. Guessing the other way at worst leaves both
370
+ // managers running, which is visible and fixable. Issue #309 established
371
+ // this for the resolved-config arm; issue #484 extends it here after a
372
+ // launcher exporting OPENCODE_CONFIG_DIR to a scaffolding-only directory
373
+ // made this default fire against a user whose global config said
374
+ // auto=false.
375
+ log(
376
+ "[magic-context] conflict-detector: no OpenCode config file carried an explicit compaction block; treating native compaction as inconclusive (not disabling the plugin)",
377
+ );
378
+ return { auto: false, prune: false };
311
379
  }
312
380
 
313
- function readProjectCompaction(directory: string): {
314
- auto: boolean;
315
- prune: boolean;
316
- resolved: boolean;
317
- } {
318
- // .opencode/ config has higher precedence
319
- const dotOcJsonc = join(directory, ".opencode", "opencode.jsonc");
320
- const dotOcJson = join(directory, ".opencode", "opencode.json");
321
- const dotOcConfig =
322
- readJsoncFile<OpenCodeConfig>(dotOcJsonc) ?? readJsoncFile<OpenCodeConfig>(dotOcJson);
323
-
324
- if (dotOcConfig?.compaction) {
325
- const c = dotOcConfig.compaction;
326
- if (c.auto !== undefined || c.prune !== undefined) {
327
- return { auto: c.auto === true, prune: c.prune === true, resolved: true };
328
- }
329
- }
381
+ /**
382
+ * Every readable config file OpenCode merges for this project, ordered from
383
+ * LOWEST to HIGHEST precedence.
384
+ *
385
+ * OpenCode 1.18.30 (`Config.loadInstanceState`) uses:
386
+ *
387
+ * 1. `$XDG_CONFIG_HOME/opencode/` — `config.json`, `opencode.json`, `opencode.jsonc`
388
+ * 2. `$OPENCODE_CONFIG` — the explicit single-file override
389
+ * 3. the project's own `opencode.json` / `opencode.jsonc`
390
+ * 4. the project's `.opencode/` directory
391
+ * 5. `~/.opencode/` and `$OPENCODE_CONFIG_DIR` (see getOpenCodeConfigDirs)
392
+ *
393
+ * OpenCode 2.x orders the corresponding groups as well-known, global
394
+ * supplementary, explicit, direct, then project supplementary. See
395
+ * `packages/core/src/config.ts:220-236` at 7e70f7e1ab. Consequently project
396
+ * `.opencode` files outrank global supplementary directories only on v2.
397
+ *
398
+ * Remote, org, managed-enterprise, and content layers are NOT readable from
399
+ * here. That is why an empty result is inconclusive rather than the host
400
+ * default.
401
+ */
402
+ function openCodeConfigFileChain(
403
+ directory: string,
404
+ hostGeneration: OpenCodeHostGeneration,
405
+ ): string[] {
406
+ const globalDir = getOpenCodeGlobalConfigDir();
407
+ const wellKnown = [
408
+ join(globalDir, "config.json"),
409
+ join(globalDir, "opencode.json"),
410
+ join(globalDir, "opencode.jsonc"),
411
+ ];
412
+ const globalSupplementary = getOpenCodeConfigDirs()
413
+ .filter((dir) => dir !== globalDir)
414
+ .flatMap((dir) => [join(dir, "opencode.json"), join(dir, "opencode.jsonc")]);
415
+ const explicitConfig = process.env.OPENCODE_CONFIG?.trim();
416
+ const explicit = explicitConfig ? [explicitConfig] : [];
417
+ const direct = [join(directory, "opencode.json"), join(directory, "opencode.jsonc")];
418
+ const projectSupplementary = [
419
+ join(directory, ".opencode", "opencode.json"),
420
+ join(directory, ".opencode", "opencode.jsonc"),
421
+ ];
422
+
423
+ const files =
424
+ hostGeneration === "v2"
425
+ ? [
426
+ ...wellKnown,
427
+ ...globalSupplementary,
428
+ ...explicit,
429
+ ...direct,
430
+ ...projectSupplementary,
431
+ ]
432
+ : [
433
+ ...wellKnown,
434
+ ...explicit,
435
+ ...direct,
436
+ ...projectSupplementary,
437
+ ...globalSupplementary,
438
+ ];
439
+ return [...new Set(files)];
440
+ }
330
441
 
331
- // Root-level project config
332
- const rootJsonc = join(directory, "opencode.jsonc");
333
- const rootJson = join(directory, "opencode.json");
334
- const rootConfig =
335
- readJsoncFile<OpenCodeConfig>(rootJsonc) ?? readJsoncFile<OpenCodeConfig>(rootJson);
442
+ type CompactionBlock = NonNullable<OpenCodeConfig["compaction"]>;
336
443
 
337
- if (rootConfig?.compaction) {
338
- const c = rootConfig.compaction;
339
- if (c.auto !== undefined || c.prune !== undefined) {
340
- return { auto: c.auto === true, prune: c.prune === true, resolved: true };
444
+ /**
445
+ * Merge the `compaction` blocks of every readable config file, in OpenCode's
446
+ * own precedence order. Merging (rather than taking the first file that has a
447
+ * block) is what OpenCode does, so a global `auto: false` and a project-level
448
+ * `prune: true` both survive instead of one silently erasing the other.
449
+ */
450
+ function readCompactionFromConfigFiles(
451
+ directory: string,
452
+ hostGeneration: OpenCodeHostGeneration,
453
+ ): CompactionBlock {
454
+ const merged: CompactionBlock = {};
455
+ for (const filePath of openCodeConfigFileChain(directory, hostGeneration)) {
456
+ let block: CompactionBlock | undefined;
457
+ try {
458
+ block = readJsoncFile<OpenCodeConfig>(filePath)?.compaction;
459
+ } catch {
460
+ // Intentional: each config read is best-effort. An unreadable file
461
+ // leaves the chain inconclusive rather than failing detection.
341
462
  }
463
+ if (!block || typeof block !== "object") continue;
464
+ if (block.auto !== undefined) merged.auto = block.auto;
465
+ if (block.prune !== undefined) merged.prune = block.prune;
466
+ if (block.buffer !== undefined) merged.buffer = block.buffer;
467
+ if (block.keep !== undefined) merged.keep = { ...merged.keep, ...block.keep };
342
468
  }
469
+ return merged;
470
+ }
343
471
 
344
- return { auto: false, prune: false, resolved: false };
472
+ /** Whether a merged block carries any key this host generation acts on. */
473
+ function isRelevantCompactionBlock(
474
+ block: CompactionBlock,
475
+ hostGeneration: OpenCodeHostGeneration,
476
+ ): boolean {
477
+ if (block.auto !== undefined) return true;
478
+ if (hostGeneration === "v1") return block.prune !== undefined;
479
+ return block.keep?.tokens !== undefined || block.buffer !== undefined;
345
480
  }
346
481
 
347
- function readUserCompaction(): { auto: boolean; prune: boolean; resolved: boolean } {
348
- try {
349
- const paths = getOpenCodeConfigPaths({ binary: "opencode" });
350
- const config =
351
- readJsoncFile<OpenCodeConfig>(paths.configJsonc) ??
352
- readJsoncFile<OpenCodeConfig>(paths.configJson);
353
-
354
- if (config?.compaction) {
355
- const c = config.compaction;
356
- if (c.auto !== undefined || c.prune !== undefined) {
357
- return { auto: c.auto === true, prune: c.prune === true, resolved: true };
358
- }
359
- }
360
- } catch {
361
- // Intentional: config read is best-effort
482
+ function resolvedCompactionBlock(
483
+ block: NonNullable<OpenCodeConfig["compaction"]>,
484
+ hostGeneration: OpenCodeHostGeneration,
485
+ ): ResolvedCompaction & { resolved: true } {
486
+ if (hostGeneration === "v2") {
487
+ return {
488
+ auto: block.auto !== false,
489
+ prune: false,
490
+ resolved: true,
491
+ ...(typeof block.keep?.tokens === "number" ? { keepTokens: block.keep.tokens } : {}),
492
+ ...(typeof block.buffer === "number" ? { buffer: block.buffer } : {}),
493
+ };
362
494
  }
363
- return { auto: false, prune: false, resolved: false };
495
+ return { auto: block.auto === true, prune: block.prune === true, resolved: true };
364
496
  }
365
497
 
366
498
  // --- DCP detection ---
@@ -454,12 +586,21 @@ function collectPluginEntries(directory: string): string[] {
454
586
  pushFrom(config?.plugin);
455
587
  }
456
588
 
457
- // User-level config
589
+ // User-level config. Every directory OpenCode reads is searched, not just
590
+ // the one we would write to: a launcher that exports OPENCODE_CONFIG_DIR
591
+ // does not stop OpenCode from loading the plugin list in the user's global
592
+ // config, so a conflicting plugin declared there is still installed.
458
593
  try {
459
- const paths = getOpenCodeConfigPaths({ binary: "opencode" });
460
- for (const configPath of [paths.configJsonc, paths.configJson]) {
461
- const config = readJsoncFile<OpenCodeConfig>(configPath);
462
- pushFrom(config?.plugin);
594
+ const globalDir = getOpenCodeGlobalConfigDir();
595
+ for (const dir of getOpenCodeConfigDirs()) {
596
+ const names =
597
+ dir === globalDir
598
+ ? ["config.json", "opencode.json", "opencode.jsonc"]
599
+ : ["opencode.json", "opencode.jsonc"];
600
+ for (const name of names) {
601
+ const config = readJsoncFile<OpenCodeConfig>(join(dir, name));
602
+ pushFrom(config?.plugin);
603
+ }
463
604
  }
464
605
  } catch {
465
606
  // best-effort
@@ -524,13 +665,13 @@ function readOmoDisabledHooks(directory: string): Set<string> {
524
665
  ];
525
666
 
526
667
  try {
527
- const paths = getOpenCodeConfigPaths({ binary: "opencode" });
528
- for (const name of configNames) {
529
- const configPath = join(paths.configDir, name);
530
- const config = readJsoncFile<OmoConfig>(configPath);
531
- if (config?.disabled_hooks) {
532
- for (const hook of config.disabled_hooks) {
533
- disabled.add(hook);
668
+ for (const dir of getOpenCodeConfigDirs()) {
669
+ for (const name of configNames) {
670
+ const config = readJsoncFile<OmoConfig>(join(dir, name));
671
+ if (config?.disabled_hooks) {
672
+ for (const hook of config.disabled_hooks) {
673
+ disabled.add(hook);
674
+ }
534
675
  }
535
676
  }
536
677
  }
@@ -0,0 +1,21 @@
1
+ const warnings = new Map<string, string>();
2
+
3
+ /** Remember a host catalog mismatch until the process exits so status can show it once. */
4
+ export function recordHiddenVariantWarning(
5
+ providerID: string,
6
+ modelID: string,
7
+ variant: string,
8
+ ): string {
9
+ const key = `${providerID}/${modelID}:${variant}`;
10
+ const message = `variant '${variant}' not offered by ${providerID}/${modelID} on this host; running without it`;
11
+ warnings.set(key, message);
12
+ return message;
13
+ }
14
+
15
+ export function listHiddenVariantWarnings(): string[] {
16
+ return [...warnings.values()];
17
+ }
18
+
19
+ export function clearHiddenVariantWarningsForTest(): void {
20
+ warnings.clear();
21
+ }
@@ -0,0 +1,43 @@
1
+ import { USER_FACING_FAILURES, type UserFacingFailureKey } from "./user-facing-codes";
2
+
3
+ /**
4
+ * Named things the host Magic Context is running in cannot do.
5
+ *
6
+ * A limitation is not a failed operation: it is a capability the current host
7
+ * lacks for as long as this process lives, so every status surface keeps
8
+ * printing it instead of showing it once and forgetting. Each one is an
9
+ * existing MC-* user-facing code, so the status dialog, the plain-text status
10
+ * summary and the sidebar all print the same sentence for it.
11
+ *
12
+ * Process-global on purpose. The surfaces that show these (the RPC status and
13
+ * sidebar handlers) are built without a reference to the adapter that
14
+ * discovered the limitation, and a limitation of the host is true for every
15
+ * session in the process rather than for one of them.
16
+ */
17
+ const declared = new Set<UserFacingFailureKey>();
18
+
19
+ /**
20
+ * Record a limitation of this host. Returns true only the first time a given
21
+ * limitation is declared, which is what callers use to log their explanation
22
+ * once instead of on every pass.
23
+ */
24
+ export function declareHostLimitation(key: UserFacingFailureKey): boolean {
25
+ if (declared.has(key)) return false;
26
+ declared.add(key);
27
+ return true;
28
+ }
29
+
30
+ /** Limitations declared so far, in the order they were first declared. */
31
+ export function activeHostLimitations(): UserFacingFailureKey[] {
32
+ return [...declared];
33
+ }
34
+
35
+ /** The MC-* codes for the declared limitations, for logs and reports. */
36
+ export function activeHostLimitationCodes(): string[] {
37
+ return activeHostLimitations().map((key) => USER_FACING_FAILURES[key].code);
38
+ }
39
+
40
+ /** Test helper: forget every declared limitation so suites do not leak them. */
41
+ export function __resetHostLimitations(): void {
42
+ declared.clear();
43
+ }
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Debug / data-collection switch for settled ordinary child sessions
3
- * (historian and memory migration). Privacy-sensitive Dreamer and
4
- * smart-note children are still deleted after their prompts settle.
2
+ * Debug / data-collection switch for every settled Magic Context child session,
3
+ * including historian, Dreamer, smart-note, user-memory, and migration work.
5
4
  *
6
5
  * Unsettled children are never deleted inline because OpenCode's server loop may
7
- * still be writing after a client timeout or abort. They remain for the
8
- * age-gated sweep; privacy-sensitive rows are swept even when this switch is on.
6
+ * still be writing after a client timeout or abort. They remain archived for the
7
+ * age-gated sweep; archived privacy-sensitive rows are swept even when this
8
+ * switch is on.
9
9
  *
10
10
  * Process-global, set once at boot from config (mirrors `harness.ts`). A config
11
11
  * change requires a restart to take effect.
@@ -17,7 +17,7 @@ export function setKeepSubagents(value: boolean): void {
17
17
  keepSubagents = value === true;
18
18
  }
19
19
 
20
- /** True when settled ordinary child sessions should be retained. */
20
+ /** True when every settled Magic Context child session should be retained. */
21
21
  export function shouldKeepSubagents(): boolean {
22
22
  return keepSubagents;
23
23
  }
@@ -225,6 +225,49 @@ describe("promptSyncWithModelSuggestionRetry", () => {
225
225
  expect((abort.mock.calls[0]?.[0] as { path: { id: string } }).path.id).toBe("ses-test");
226
226
  });
227
227
 
228
+ test("timeout with a resolving transport still aborts the child", async () => {
229
+ const abort = mock(async () => ({}));
230
+ const client = createClient(
231
+ mock(async () => ({})),
232
+ abort,
233
+ );
234
+ const transport = Object.assign(
235
+ ({ signal }: { signal?: AbortSignal }) =>
236
+ new Promise<void>((resolve) => signal?.addEventListener("abort", () => resolve())),
237
+ { childSessionId: "child-test" },
238
+ );
239
+ await expect(
240
+ promptSyncWithModelSuggestionRetry(client, createArgs(), {
241
+ timeoutMs: 10,
242
+ transport,
243
+ }),
244
+ ).rejects.toThrow("prompt timed out after 10ms");
245
+ expect(abort).toHaveBeenCalledTimes(1);
246
+ expect((abort.mock.calls[0]?.[0] as { path: { id: string } }).path.id).toBe("child-test");
247
+ });
248
+
249
+ test("external abort with a resolving transport still aborts the child", async () => {
250
+ const controller = new AbortController();
251
+ const abort = mock(async () => ({}));
252
+ const client = createClient(
253
+ mock(async () => ({})),
254
+ abort,
255
+ );
256
+ const transport = Object.assign(
257
+ ({ signal }: { signal?: AbortSignal }) =>
258
+ new Promise<void>((resolve) => signal?.addEventListener("abort", () => resolve())),
259
+ { childSessionId: "child-test" },
260
+ );
261
+ setTimeout(() => controller.abort(), 10);
262
+ await expect(
263
+ promptSyncWithModelSuggestionRetry(client, createArgs(), {
264
+ signal: controller.signal,
265
+ transport,
266
+ }),
267
+ ).rejects.toThrow("prompt aborted by external signal");
268
+ expect(abort).toHaveBeenCalledTimes(1);
269
+ });
270
+
228
271
  // External abort (e.g. dreamer lease loss) mid-flight must also stop the
229
272
  // server-side loop, not just our fetch.
230
273
  test("external abort fires session.abort on the child session", async () => {
@@ -254,6 +254,18 @@ async function promptWithTimeout(
254
254
  clearTimeout(timeout);
255
255
  signal?.removeEventListener("abort", onExternalAbort);
256
256
  }
257
+ // Some transports resolve with an error result when their fetch is aborted.
258
+ // A resolved fetch does not mean the server-side child run has stopped.
259
+ if (signal?.aborted || controller.signal.aborted) {
260
+ if (!transport || transport.childSessionId) {
261
+ await abortChildRun(client, transport?.childSessionId ?? args.path.id);
262
+ }
263
+ throw new Error(
264
+ signal?.aborted
265
+ ? "prompt aborted by external signal"
266
+ : `prompt timed out after ${timeoutMs}ms`,
267
+ );
268
+ }
257
269
  }
258
270
 
259
271
  /**
@@ -2,6 +2,7 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
2
2
  import { mkdtempSync, rmSync } from "node:fs";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
+ import { resolveKnownHistorianContextLimit } from "../hooks/magic-context/derive-budgets";
5
6
  import {
6
7
  clearModelsDevCache,
7
8
  getModelsDevCacheState,
@@ -230,6 +231,30 @@ describe("models-dev-cache (SDK-only)", () => {
230
231
  expect(getSdkContextLimit("openai", "gpt-5.4-mini")).toBe(922000);
231
232
  });
232
233
 
234
+ test("explicit SDK-resolved config limit wins over a larger catalog or detected value", async () => {
235
+ // OpenCode's config.providers() has already applied opencode.json over its
236
+ // catalog. The cache must preserve that 120K effective value, and a later
237
+ // API-detected 262K value may narrow but never enlarge it.
238
+ await refreshModelLimitsFromApi(
239
+ makeClient([
240
+ {
241
+ id: "regolo",
242
+ models: {
243
+ "qwen3.5-122b": { limit: { context: 120_000, output: 32_000 } },
244
+ },
245
+ },
246
+ ]),
247
+ );
248
+
249
+ expect(
250
+ getSdkContextLimit("regolo", "qwen3.5-122b", 262_144, {
251
+ reservation: "none",
252
+ detectedLimitProvenance: "combined",
253
+ }),
254
+ ).toBe(120_000);
255
+ expect(resolveKnownHistorianContextLimit("regolo/qwen3.5-122b")).toBe(120_000);
256
+ });
257
+
233
258
  test("narrows raw context with detected wire truth before reserving output", async () => {
234
259
  await refreshModelLimitsFromApi(
235
260
  makeClient([
@@ -601,6 +601,11 @@ export function modelSupportsVision(providerID: string, modelID: string): boolea
601
601
  : false;
602
602
  }
603
603
 
604
+ export function getSdkOutputLimit(providerID: string, modelID: string): number | undefined {
605
+ loadPersistedApiCacheOnce();
606
+ return lookupMetadataWithTagFallback(apiCache, providerID, modelID)?.outputLimit;
607
+ }
608
+
604
609
  export function getSdkInputLimit(providerID: string, modelID: string): number | undefined {
605
610
  loadPersistedApiCacheOnce();
606
611
  if (!apiCache) return undefined;