@cortexkit/opencode-magic-context 0.41.4 → 0.42.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 (328) hide show
  1. package/README.md +21 -3
  2. package/dist/agents/hidden-agent-registrations.d.ts +1 -3
  3. package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
  4. package/dist/agents/magic-context-prompt.d.ts +1 -1
  5. package/dist/agents/magic-context-prompt.d.ts.map +1 -1
  6. package/dist/agents/permissions.d.ts +1 -22
  7. package/dist/agents/permissions.d.ts.map +1 -1
  8. package/dist/config/agent-disable.d.ts +0 -5
  9. package/dist/config/agent-disable.d.ts.map +1 -1
  10. package/dist/config/index.d.ts +5 -0
  11. package/dist/config/index.d.ts.map +1 -1
  12. package/dist/config/migrate-config-location.d.ts.map +1 -1
  13. package/dist/config/project-security.d.ts +17 -0
  14. package/dist/config/project-security.d.ts.map +1 -1
  15. package/dist/config/removed-agent-config.d.ts +8 -0
  16. package/dist/config/removed-agent-config.d.ts.map +1 -0
  17. package/dist/config/schema/magic-context.d.ts +23 -201
  18. package/dist/config/schema/magic-context.d.ts.map +1 -1
  19. package/dist/{conflict-warning-hook-ejkc9sjn.js → conflict-warning-hook-6p3xqeac.js} +3 -3
  20. package/dist/{derive-budgets-bc366cz8.js → derive-budgets-s2pgnnm4.js} +1 -1
  21. package/dist/features/builtin-commands/commands.d.ts +0 -4
  22. package/dist/features/builtin-commands/commands.d.ts.map +1 -1
  23. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  24. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +7 -0
  25. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  26. package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
  27. package/dist/features/magic-context/context-authority.d.ts +31 -4
  28. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  29. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  30. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  31. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  32. package/dist/features/magic-context/dreamer/open-opencode-db.d.ts.map +1 -1
  33. package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
  34. package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts +19 -9
  35. package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts.map +1 -1
  36. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  37. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +4 -0
  38. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  39. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  40. package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
  41. package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts.map +1 -1
  42. package/dist/features/magic-context/index.d.ts +0 -1
  43. package/dist/features/magic-context/index.d.ts.map +1 -1
  44. package/dist/features/magic-context/memory/embedding-local.d.ts +13 -0
  45. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  46. package/dist/features/magic-context/memory/embedding-synapse.d.ts +43 -10
  47. package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
  48. package/dist/features/magic-context/memory/embedding.d.ts +1 -1
  49. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
  50. package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
  51. package/dist/features/magic-context/memory/project-identity.d.ts +1 -0
  52. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  53. package/dist/features/magic-context/memory/promotion.d.ts +7 -1
  54. package/dist/features/magic-context/memory/promotion.d.ts.map +1 -1
  55. package/dist/features/magic-context/merged-reasoning-decisions.d.ts +6 -0
  56. package/dist/features/magic-context/merged-reasoning-decisions.d.ts.map +1 -0
  57. package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -1
  58. package/dist/features/magic-context/message-index-async.d.ts +12 -0
  59. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  60. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  61. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  62. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  63. package/dist/features/magic-context/mural/render-trigger.d.ts +6 -0
  64. package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
  65. package/dist/features/magic-context/no-content-compartment.d.ts +12 -0
  66. package/dist/features/magic-context/no-content-compartment.d.ts.map +1 -0
  67. package/dist/features/magic-context/pi-content-decisions.d.ts +9 -0
  68. package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -0
  69. package/dist/features/magic-context/project-docs-hash.d.ts +4 -0
  70. package/dist/features/magic-context/project-docs-hash.d.ts.map +1 -1
  71. package/dist/features/magic-context/project-embedding-registry.d.ts +13 -4
  72. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  73. package/dist/features/magic-context/protection-window.d.ts +79 -0
  74. package/dist/features/magic-context/protection-window.d.ts.map +1 -0
  75. package/dist/features/magic-context/search.d.ts.map +1 -1
  76. package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
  77. package/dist/features/magic-context/shadow-backfill-state.d.ts +26 -0
  78. package/dist/features/magic-context/shadow-backfill-state.d.ts.map +1 -0
  79. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  80. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +4 -0
  81. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
  82. package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
  83. package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
  84. package/dist/features/magic-context/storage-db.d.ts +1 -1
  85. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  86. package/dist/features/magic-context/storage-embedding-measurements.d.ts +2 -2
  87. package/dist/features/magic-context/storage-embedding-measurements.d.ts.map +1 -1
  88. package/dist/features/magic-context/storage-historian-runs.d.ts +4 -0
  89. package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
  90. package/dist/features/magic-context/storage-memory-mutation-log.d.ts +1 -0
  91. package/dist/features/magic-context/storage-memory-mutation-log.d.ts.map +1 -1
  92. package/dist/features/magic-context/storage-meta-persisted.d.ts +79 -13
  93. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  94. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  95. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  96. package/dist/features/magic-context/storage-native-replay.d.ts +29 -0
  97. package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -0
  98. package/dist/features/magic-context/storage-notes.d.ts +6 -0
  99. package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
  100. package/dist/features/magic-context/storage-replay-document.d.ts +33 -0
  101. package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -0
  102. package/dist/features/magic-context/storage-subagent-invocations.d.ts +1 -1
  103. package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -1
  104. package/dist/features/magic-context/storage-tags.d.ts +19 -11
  105. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  106. package/dist/features/magic-context/storage.d.ts +3 -3
  107. package/dist/features/magic-context/storage.d.ts.map +1 -1
  108. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
  109. package/dist/features/magic-context/tagger.d.ts +13 -0
  110. package/dist/features/magic-context/tagger.d.ts.map +1 -1
  111. package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
  112. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  113. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
  114. package/dist/features/magic-context/workspaces.d.ts.map +1 -1
  115. package/dist/hooks/magic-context/apply-operations.d.ts +11 -5
  116. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  117. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  118. package/dist/hooks/magic-context/cache-busting-signals.d.ts +9 -1
  119. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
  120. package/dist/hooks/magic-context/caveman-cleanup.d.ts +1 -1
  121. package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
  122. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  123. package/dist/hooks/magic-context/child-session-spawn.d.ts +3 -3
  124. package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
  125. package/dist/hooks/magic-context/command-handler.d.ts +1 -10
  126. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  127. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  128. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +10 -21
  129. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
  130. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  131. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  132. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +26 -2
  133. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
  134. package/dist/hooks/magic-context/decay-render.d.ts.map +1 -1
  135. package/dist/hooks/magic-context/dropped-input-guard.d.ts +9 -0
  136. package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -0
  137. package/dist/hooks/magic-context/emergency-drop.d.ts +6 -1
  138. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  139. package/dist/hooks/magic-context/event-handler.d.ts +0 -1
  140. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  141. package/dist/hooks/magic-context/event-payloads.d.ts +7 -6
  142. package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
  143. package/dist/hooks/magic-context/event-resolvers.d.ts +1 -1
  144. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  145. package/dist/hooks/magic-context/execute-status.d.ts +1 -1
  146. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  147. package/dist/hooks/magic-context/format-embed-status.d.ts.map +1 -1
  148. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +7 -1
  149. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  150. package/dist/hooks/magic-context/hook-handlers.d.ts +3 -1
  151. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  152. package/dist/hooks/magic-context/hook.d.ts +13 -4
  153. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  154. package/dist/hooks/magic-context/inject-compartments.d.ts +14 -1
  155. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  156. package/dist/hooks/magic-context/live-session-state.d.ts +1 -1
  157. package/dist/hooks/magic-context/lkg-slot.d.ts +34 -0
  158. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  159. package/dist/hooks/magic-context/module-state-sync-timing.d.ts +21 -0
  160. package/dist/hooks/magic-context/module-state-sync-timing.d.ts.map +1 -0
  161. package/dist/hooks/magic-context/module-state-sync.d.ts +21 -7
  162. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  163. package/dist/hooks/magic-context/module-transport.d.ts +12 -0
  164. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  165. package/dist/hooks/magic-context/module-wire.d.ts +8 -0
  166. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  167. package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
  168. package/dist/hooks/magic-context/persist-filtered-noise.d.ts +5 -0
  169. package/dist/hooks/magic-context/persist-filtered-noise.d.ts.map +1 -0
  170. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +6 -0
  171. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  172. package/dist/hooks/magic-context/read-session-chunk.d.ts +18 -18
  173. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  174. package/dist/hooks/magic-context/read-session-db.d.ts +22 -12
  175. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  176. package/dist/hooks/magic-context/read-session-formatting.d.ts +8 -0
  177. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  178. package/dist/hooks/magic-context/read-session-raw.d.ts +10 -1
  179. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  180. package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
  181. package/dist/hooks/magic-context/rust-mode-transform.d.ts +74 -9
  182. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  183. package/dist/hooks/magic-context/send-session-notification.d.ts +11 -10
  184. package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
  185. package/dist/hooks/magic-context/strip-content.d.ts +7 -0
  186. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  187. package/dist/hooks/magic-context/supersession-reclaim.d.ts +13 -0
  188. package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
  189. package/dist/hooks/magic-context/system-prompt-hash.d.ts +2 -3
  190. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  191. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +8 -3
  192. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  193. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  194. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  195. package/dist/hooks/magic-context/transform-context-state.d.ts +7 -1
  196. package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
  197. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +11 -4
  198. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  199. package/dist/hooks/magic-context/transform.d.ts +7 -2
  200. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  201. package/dist/hooks/magic-context/upgrade-reminder.d.ts +7 -9
  202. package/dist/hooks/magic-context/upgrade-reminder.d.ts.map +1 -1
  203. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  204. package/dist/index-1974jvn3.js +783 -0
  205. package/dist/{index-4avmwfp5.js → index-36wd1d6k.js} +6 -29
  206. package/dist/{index-0y2mcg5y.js → index-c9hamh36.js} +18332 -16226
  207. package/dist/{index-fz104x1j.js → index-jmtjh2d3.js} +3 -3
  208. package/dist/{index-q264erdp.js → index-nqgjwfzn.js} +70 -38
  209. package/dist/{index-mjv9je4e.js → index-xdtge3y2.js} +45 -7
  210. package/dist/index.d.ts.map +1 -1
  211. package/dist/index.js +6199 -5088
  212. package/dist/plugin/conflict-warning-hook.d.ts +5 -6
  213. package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
  214. package/dist/plugin/dream-timer.d.ts +1 -0
  215. package/dist/plugin/dream-timer.d.ts.map +1 -1
  216. package/dist/plugin/embedding-routing.d.ts +4 -1
  217. package/dist/plugin/embedding-routing.d.ts.map +1 -1
  218. package/dist/plugin/hooks/create-session-hooks.d.ts +16 -2
  219. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  220. package/dist/plugin/rpc-handlers.d.ts +31 -1
  221. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  222. package/dist/plugin/rust-tool-backends.d.ts +1 -0
  223. package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
  224. package/dist/plugin/tool-registry.d.ts.map +1 -1
  225. package/dist/{recomp-orchestrator-q98r6rga.js → recomp-orchestrator-3atsasjy.js} +5 -5
  226. package/dist/{send-session-notification-hdh02wy9.js → send-session-notification-1qeqkswb.js} +6 -4
  227. package/dist/shared/child-session-teardown.d.ts +34 -0
  228. package/dist/shared/child-session-teardown.d.ts.map +1 -0
  229. package/dist/shared/keep-subagents.d.ts +1 -1
  230. package/dist/shared/keep-subagents.d.ts.map +1 -1
  231. package/dist/shared/model-suggestion-retry.d.ts +1 -1
  232. package/dist/shared/opencode-db-path.d.ts +24 -0
  233. package/dist/shared/opencode-db-path.d.ts.map +1 -0
  234. package/dist/shared/prompt-surface-runtime.d.ts +10 -5
  235. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
  236. package/dist/shared/resolve-fallbacks.d.ts +1 -1
  237. package/dist/shared/rpc-types.d.ts +111 -0
  238. package/dist/shared/rpc-types.d.ts.map +1 -1
  239. package/dist/shared/sqlite.d.ts +42 -0
  240. package/dist/shared/sqlite.d.ts.map +1 -1
  241. package/dist/shared/status-detail-text.d.ts.map +1 -1
  242. package/dist/shared/subagent-runner.d.ts +17 -10
  243. package/dist/shared/subagent-runner.d.ts.map +1 -1
  244. package/dist/shared/tag-transcript.d.ts.map +1 -1
  245. package/dist/shared/transcript.d.ts +6 -0
  246. package/dist/shared/transcript.d.ts.map +1 -1
  247. package/dist/shared/window-geometry.d.ts +23 -0
  248. package/dist/shared/window-geometry.d.ts.map +1 -1
  249. package/dist/shared/write-transaction-timing.d.ts +1 -1
  250. package/dist/shared/write-transaction-timing.d.ts.map +1 -1
  251. package/dist/{storage-meta-session-dvwfw778.js → storage-meta-session-e6g0mmec.js} +2 -2
  252. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  253. package/dist/tools/ctx-memory/verification-recording.d.ts.map +1 -1
  254. package/dist/tools/ctx-note/constants.d.ts +1 -1
  255. package/dist/tools/ctx-note/constants.d.ts.map +1 -1
  256. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  257. package/dist/tools/ctx-note/types.d.ts +1 -0
  258. package/dist/tools/ctx-note/types.d.ts.map +1 -1
  259. package/dist/tools/ctx-reduce/tools.d.ts +10 -1
  260. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  261. package/dist/tools/ctx-search/constants.d.ts +1 -1
  262. package/dist/tools/ctx-search/constants.d.ts.map +1 -1
  263. package/dist/tools/light-descriptions.d.ts +2 -2
  264. package/dist/tools/light-descriptions.d.ts.map +1 -1
  265. package/package.json +2 -3
  266. package/src/agents/hidden-agent-registrations.ts +3 -15
  267. package/src/agents/magic-context-prompt.test.ts +7 -5
  268. package/src/agents/magic-context-prompt.ts +22 -30
  269. package/src/agents/permissions.test.ts +1 -42
  270. package/src/agents/permissions.ts +1 -24
  271. package/src/config/agent-disable.ts +5 -22
  272. package/src/config/index.test.ts +126 -15
  273. package/src/config/index.ts +41 -6
  274. package/src/config/latch-permanence-guard.test.ts +4 -0
  275. package/src/config/migrate-config-location.test.ts +39 -6
  276. package/src/config/migrate-config-location.ts +18 -31
  277. package/src/config/profiles.ts +1 -1
  278. package/src/config/project-security.hostile-matrix.test.ts +0 -8
  279. package/src/config/project-security.test.ts +11 -22
  280. package/src/config/project-security.ts +103 -9
  281. package/src/config/protected-tokens.test.ts +235 -0
  282. package/src/config/removed-agent-config.ts +45 -0
  283. package/src/config/removed-agent-source-fence.test.ts +56 -0
  284. package/src/config/schema/magic-context.test.ts +21 -42
  285. package/src/config/schema/magic-context.ts +46 -37
  286. package/src/shared/child-session-teardown.test.ts +218 -0
  287. package/src/shared/child-session-teardown.ts +66 -0
  288. package/src/shared/keep-subagents.ts +9 -14
  289. package/src/shared/model-suggestion-retry.ts +1 -1
  290. package/src/shared/opencode-db-path.test.ts +196 -0
  291. package/src/shared/opencode-db-path.ts +215 -0
  292. package/src/shared/prompt-surface-a1-golden.md +50 -35
  293. package/src/shared/prompt-surface-runtime.test.ts +28 -0
  294. package/src/shared/prompt-surface-runtime.ts +22 -5
  295. package/src/shared/resolve-fallbacks.ts +1 -1
  296. package/src/shared/rpc-types.ts +118 -0
  297. package/src/shared/session-messages-bounded.test.ts +1 -1
  298. package/src/shared/sqlite-import-fence.test.ts +19 -0
  299. package/src/shared/sqlite.test.ts +27 -1
  300. package/src/shared/sqlite.ts +204 -1
  301. package/src/shared/status-detail-text.test.ts +6 -3
  302. package/src/shared/status-detail-text.ts +15 -0
  303. package/src/shared/subagent-runner.ts +17 -10
  304. package/src/shared/tag-transcript.ts +33 -21
  305. package/src/shared/transcript.ts +7 -0
  306. package/src/shared/window-geometry.test.ts +44 -0
  307. package/src/shared/window-geometry.ts +89 -11
  308. package/src/shared/write-transaction-attribution.test.ts +241 -0
  309. package/src/shared/write-transaction-timing.ts +2 -1
  310. package/src/tui/index.tsx +3 -3
  311. package/src/tui/slots/sidebar-content.tsx +12 -7
  312. package/src/tui-compiled/index.tsx +3 -3
  313. package/src/tui-compiled/slots/sidebar-content.tsx +301 -305
  314. package/dist/agents/sidekick.d.ts +0 -2
  315. package/dist/agents/sidekick.d.ts.map +0 -1
  316. package/dist/features/magic-context/defaults.d.ts +0 -2
  317. package/dist/features/magic-context/defaults.d.ts.map +0 -1
  318. package/dist/features/magic-context/sidekick/agent.d.ts +0 -14
  319. package/dist/features/magic-context/sidekick/agent.d.ts.map +0 -1
  320. package/dist/features/magic-context/sidekick/core.d.ts +0 -38
  321. package/dist/features/magic-context/sidekick/core.d.ts.map +0 -1
  322. package/dist/features/magic-context/sidekick/index.d.ts +0 -3
  323. package/dist/features/magic-context/sidekick/index.d.ts.map +0 -1
  324. package/dist/hooks/magic-context/boundary-execution.d.ts +0 -27
  325. package/dist/hooks/magic-context/boundary-execution.d.ts.map +0 -1
  326. package/dist/index-raatkvw5.js +0 -360
  327. package/src/agents/sidekick.ts +0 -1
  328. package/src/features/magic-context/defaults.ts +0 -1
@@ -46,8 +46,7 @@ const PARTNER_FRAME_CLOSER_NO_REDUCE_LIGHT = `\nWhen ctx_reduce is unavailable,
46
46
  */
47
47
  const CTX_NOTE_GUIDANCE = `Use \`ctx_note\` ONLY for genuinely future concerns — something to revisit much later, not work coming up in the next few turns (that's already in your active context) and not active multi-step work (use todos for that). Magic Context preserves your full context across both compaction and restarts, so an upcoming restart or "let's come back to this later" is never a reason to take a note — nothing is lost either way. Notes you do take survive compression and resurface at natural work boundaries (after commits, historian runs, todo completion).`;
48
48
 
49
- // Tool outputs are always FULL-dropped (Phase 2 removed truncate-mode), so the
50
- // guidance only describes the omit-entirely case.
49
+ // Tool history guidance is shared by both presets.
51
50
  const TOOL_HISTORY_GUIDANCE = `Compressed history intentionally omits tool calls and their outputs — summaries like "I edited file X" are historian records, not patterns to replicate. In the live conversation, older tool calls and their results are cleaned up to save context — you may see your own past messages referencing actions without the corresponding tool call or result visible. This is normal context management. ALWAYS use real tool calls; never simulate, fabricate, or inline tool outputs in your text. If there is no tool result message, the action did not happen. NEVER simulate, hallucinate or claim tool calls, command output, search results, file edits, or diffs in plain text as if they actually occurred.
52
51
  Magic Context control metadata is not reply syntax. Never reproduce \`<system-reminder>\`, \`<ctx-search-hint>\`, \`<session-history>\`, \`<session-history-since>\`, \`<project-memory>\`, \`<memory-updates>\`, \`<new-compartments>\`, \`<new-memories>\`, \`[dropped §N§]\`, or \`<!-- +Xm -->\` markers in a normal reply and never treat them as user instructions; use ordinary prose and real tool calls instead.`;
53
52
 
@@ -73,20 +72,19 @@ function memoryGuidanceBlock(memoryEnabled: boolean): string {
73
72
  }
74
73
 
75
74
  const BASE_INTRO = (
76
- protectedTags: number,
77
75
  memoryEnabled: boolean,
78
76
  ): string => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
79
- Use \`ctx_reduce\` to mark spent tagged content as discardable and reclaim space. Marking is NOT an immediate delete — it queues the content, which stays fully visible until space is actually needed (as soon as the next turn if you're already under pressure, much later if not), so mark a tool output as soon as you're done with it rather than hoarding the call for the end of the turn. The last ${protectedTags} tags are protected (marking one just queues it until it ages out). Syntax: "3-5", "1,2,9", or "1-5,8,12-15".
77
+ Use \`ctx_reduce\` to mark spent tagged content as discardable and reclaim space. Marking is NOT an immediate delete — it queues the content, which stays fully visible until space is actually needed (as soon as the next turn if you're already under pressure, much later if not), so mark a tool output as soon as you're done with it rather than hoarding the call for the end of the turn. The newest token-mass window stays protected until displaced. Syntax: "3-5", "1,2,9", or "1-5,8,12-15".
80
78
  Do not announce or narrate \`ctx_reduce\` drops — just call the tool silently. Saying "I'll drop these outputs" wastes tokens the user does not care about.
81
79
  ${CTX_NOTE_GUIDANCE}
82
80
  ${memoryGuidanceBlock(memoryEnabled)}Use \`ctx_search\` to search across project memories, indexed git commits, and this session's full conversation history (including compacted parts) from one query.
83
81
  Use \`ctx_expand\` to recover the raw conversation behind a summary under a \`## start-end · date · title\` heading inside \`<session-history>\` — pass the heading's start/end range when the summary is not enough (exact wording, values, error text).
84
82
  **Search before asking the user**: If you can't remember or don't know something that might have been discussed before or stored in project memory, use \`ctx_search\` before asking the user. Examples:
85
- - Can't remember where a related codebase or dependency lives → \`ctx_search(query="opencode source code path")\`
86
- - Forgot a prior architectural decision or constraint → \`ctx_search(query="why did we choose SQLite over postgres")\`
87
- - Need a config value, API key location, or environment detail → \`ctx_search(query="embedding provider configuration")\`
88
- - Looking for how something was implemented previously → \`ctx_search(query="how does the dreamer lease work")\`
89
- - Want to recall what was decided in an earlier conversation → \`ctx_search(query="dashboard release signing setup")\`
83
+ - Can't remember where a related codebase or dependency lives → \`ctx_search(query="where is the opencode source code path?")\`
84
+ - Forgot a prior architectural decision or constraint → \`ctx_search(query="why did we choose SQLite over postgres?")\`
85
+ - Need a config value, API key location, or environment detail → \`ctx_search(query="how is the embedding provider configured?")\`
86
+ - Looking for how something was implemented previously → \`ctx_search(query="how does the dreamer lease work?")\`
87
+ - Want to recall what was decided in an earlier conversation → \`ctx_search(query="what did we decide about the dashboard release signing setup?")\`
90
88
  \`ctx_search\` returns ranked results from memories, git commits, and raw message history. Use message ordinals from results with \`ctx_expand\` to retrieve surrounding conversation context.
91
89
  ${TOOL_HISTORY_GUIDANCE}
92
90
  NEVER drop large ranges blindly (e.g., "1-50"). Review each tag before deciding.
@@ -104,21 +102,20 @@ const BASE_INTRO_NO_REDUCE = (memoryEnabled: boolean): string => `${CTX_NOTE_GUI
104
102
  ${memoryGuidanceBlock(memoryEnabled)}Use \`ctx_search\` to search across project memories, indexed git commits, and this session's full conversation history (including compacted parts) from one query.
105
103
  Use \`ctx_expand\` to recover the raw conversation behind a summary under a \`## start-end · date · title\` heading inside \`<session-history>\` — pass the heading's start/end range when the summary is not enough (exact wording, values, error text).
106
104
  **Search before asking the user**: If you can't remember or don't know something that might have been discussed before or stored in project memory, use \`ctx_search\` before asking the user. Examples:
107
- - Can't remember where a related codebase or dependency lives → \`ctx_search(query="opencode source code path")\`
108
- - Forgot a prior architectural decision or constraint → \`ctx_search(query="why did we choose SQLite over postgres")\`
109
- - Need a config value, API key location, or environment detail → \`ctx_search(query="embedding provider configuration")\`
110
- - Looking for how something was implemented previously → \`ctx_search(query="how does the dreamer lease work")\`
111
- - Want to recall what was decided in an earlier conversation → \`ctx_search(query="dashboard release signing setup")\`
105
+ - Can't remember where a related codebase or dependency lives → \`ctx_search(query="where is the opencode source code path?")\`
106
+ - Forgot a prior architectural decision or constraint → \`ctx_search(query="why did we choose SQLite over postgres?")\`
107
+ - Need a config value, API key location, or environment detail → \`ctx_search(query="how is the embedding provider configured?")\`
108
+ - Looking for how something was implemented previously → \`ctx_search(query="how does the dreamer lease work?")\`
109
+ - Want to recall what was decided in an earlier conversation → \`ctx_search(query="what did we decide about the dashboard release signing setup?")\`
112
110
  \`ctx_search\` returns ranked results from memories, git commits, and raw message history. Use message ordinals from results with \`ctx_expand\` to retrieve surrounding conversation context.
113
111
  ${TOOL_HISTORY_GUIDANCE}`;
114
112
 
115
113
  const LIGHT_SEARCH_RECOVERY = `Use ctx_search before asking the user about prior project context; it searches memories, commits, and compacted conversation. When a session-history summary lacks exact wording, values, errors, or reasoning, call ctx_expand with its heading range instead of guessing.`;
116
114
 
117
115
  const BASE_INTRO_LIGHT = (
118
- protectedTags: number,
119
116
  memoryEnabled: boolean,
120
117
  ): string => `In primary sessions with ctx_reduce, the system tags messages and tool outputs as §N§ (for example §1§ and §42§); never imitate these prefixes in replies because only injected tag numbers are valid ctx_reduce handles.
121
- In primary sessions, NEVER narrate ctx_reduce; call it silently after extracting a spent output because it marks content discardable and QUEUES release rather than deleting immediately. The last ${protectedTags} tags stay protected until they age out. Use drop grammar "3-5", "1,2,9", or "1-5,8,12-15".
118
+ In primary sessions, NEVER narrate ctx_reduce; call it silently after extracting a spent output because it marks content discardable and QUEUES release rather than deleting immediately. The newest token-mass window stays protected until displaced. Use drop grammar "3-5", "1,2,9", or "1-5,8,12-15".
122
119
  ${CTX_NOTE_GUIDANCE}
123
120
  ${memoryGuidanceBlock(memoryEnabled)}${LIGHT_SEARCH_RECOVERY}
124
121
  ${TOOL_HISTORY_GUIDANCE}
@@ -159,16 +156,14 @@ const TEMPORAL_AWARENESS_GUIDANCE = `\n**Temporal awareness**: User messages may
159
156
  * ctx_reduce mechanics. The `## Magic Context` marker is still present for
160
157
  * injection idempotency (system-prompt-hash.ts gates on it).
161
158
  */
162
- const SUBAGENT_REDUCE_INTRO = (
163
- protectedTags: number,
164
- ): string => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
165
- Use \`ctx_reduce\` to drop tool outputs you have already finished with, keeping your working context lean. Syntax: "3-5", "1,2,9", or "1-5,8,12-15". The last ${protectedTags} tags are protected.
159
+ const SUBAGENT_REDUCE_INTRO =
160
+ (): string => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
161
+ Use \`ctx_reduce\` to drop tool outputs you have already finished with, keeping your working context lean. Syntax: "3-5", "1,2,9", or "1-5,8,12-15". The newest token-mass window stays protected.
166
162
  Drop silently — do not narrate it. NEVER drop large ranges blindly (e.g., "1-50"); review each tag first. Do not drop user or assistant text messages — only large tool outputs are worth dropping.
167
163
  Older tool calls may show \`[dropped §N§]\` sentinels; that is normal context management, not a pattern to copy. ALWAYS make fresh real tool calls when you need data again; never fabricate or inline tool output.`;
168
164
 
169
- const SUBAGENT_REDUCE_INTRO_LIGHT = (
170
- protectedTags: number,
171
- ): string => `In bounded subagent sessions, the system tags messages and tool outputs as §N§; use only those IDs in ctx_reduce drop ranges such as "3-5", "1,2,9", or "1-5,8,12-15". The last ${protectedTags} tags stay protected.
165
+ const SUBAGENT_REDUCE_INTRO_LIGHT =
166
+ (): string => `In bounded subagent sessions, the system tags messages and tool outputs as §N§; use only those IDs in ctx_reduce drop ranges such as "3-5", "1,2,9", or "1-5,8,12-15". Tags in the newest token-mass window stay protected.
172
167
  When dropping, do it silently and NEVER choose a large range before reviewing every tag; drop only finished large tool outputs, never user or assistant messages.
173
168
  If older calls show [dropped §N§], never copy that system sentinel because it is not reply syntax; make a fresh real tool call and never fabricate or inline output.`;
174
169
 
@@ -176,7 +171,7 @@ const CAVEMAN_COMPRESSION_WARNING = `\n**BEWARE**: History compression is on; ol
176
171
 
177
172
  export function buildMagicContextSection(
178
173
  _agent: string | null,
179
- protectedTags: number,
174
+ _legacyProtectionCount: number,
180
175
  ctxReduceCallable = true,
181
176
  dreamerEnabled = false,
182
177
  temporalAwarenessEnabled = false,
@@ -194,10 +189,7 @@ export function buildMagicContextSection(
194
189
  // when ctx_reduce is off the subagent gets no §N§ prefix, so describing the
195
190
  // tag system would be noise.
196
191
  if (subagentMode) {
197
- const intro =
198
- preset === "light"
199
- ? SUBAGENT_REDUCE_INTRO_LIGHT(protectedTags)
200
- : SUBAGENT_REDUCE_INTRO(protectedTags);
192
+ const intro = preset === "light" ? SUBAGENT_REDUCE_INTRO_LIGHT() : SUBAGENT_REDUCE_INTRO();
201
193
  return `## Magic Context\n\n${intro}`;
202
194
  }
203
195
  const smartNoteGuidance = dreamerEnabled
@@ -227,7 +219,7 @@ export function buildMagicContextSection(
227
219
  return `## Magic Context\n\n${LONG_TERM_PARTNER_FRAME}\n${PARTNER_FRAME_CLOSER_NO_REDUCE}\n\n${BASE_INTRO_NO_REDUCE(memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
228
220
  }
229
221
  if (preset === "light") {
230
- return `## Magic Context\n\n${LONG_TERM_PARTNER_FRAME}\n${PARTNER_FRAME_CLOSER_REDUCE_LIGHT}\n\n${BASE_INTRO_LIGHT(protectedTags, memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
222
+ return `## Magic Context\n\n${LONG_TERM_PARTNER_FRAME}\n${PARTNER_FRAME_CLOSER_REDUCE_LIGHT}\n\n${BASE_INTRO_LIGHT(memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
231
223
  }
232
- return `## Magic Context\n\n${LONG_TERM_PARTNER_FRAME}\n${PARTNER_FRAME_CLOSER_REDUCE}\n\n${BASE_INTRO(protectedTags, memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}\n${GENERIC_SECTION}\n\nPrefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance.${languageGuidance}`;
224
+ return `## Magic Context\n\n${LONG_TERM_PARTNER_FRAME}\n${PARTNER_FRAME_CLOSER_REDUCE}\n\n${BASE_INTRO(memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}\n${GENERIC_SECTION}\n\nPrefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance.${languageGuidance}`;
233
225
  }
@@ -4,7 +4,6 @@ import {
4
4
  applyDisallowedTools,
5
5
  buildAllowOnlyPermission,
6
6
  HISTORIAN_ALLOWED_TOOLS,
7
- SIDEKICK_ALLOWED_TOOLS,
8
7
  } from "./permissions";
9
8
 
10
9
  describe("buildAllowOnlyPermission", () => {
@@ -34,7 +33,7 @@ describe("buildAllowOnlyPermission", () => {
34
33
 
35
34
  it("never accidentally allows `task`, `bash`, or `edit` unless explicitly listed", () => {
36
35
  // The whole point of this helper is preventing historian / dreamer /
37
- // sidekick from inheriting the primary-agent surface. Lock that in.
36
+ // hidden agents from inheriting the primary-agent surface. Lock that in.
38
37
  const perm = buildAllowOnlyPermission(["read"]);
39
38
  expect(perm.task).toBeUndefined();
40
39
  expect(perm.bash).toBeUndefined();
@@ -174,36 +173,6 @@ describe("DREAMER_DOCS_ALLOWED_TOOLS (maintain-docs)", () => {
174
173
  });
175
174
  });
176
175
 
177
- describe("SIDEKICK_ALLOWED_TOOLS", () => {
178
- it("includes ctx_search but not ctx_memory for retrieval", () => {
179
- // Sidekick is the /ctx-aug memory retriever. It searches memories without
180
- // receiving the mutation-capable ctx_memory tool.
181
- expect(SIDEKICK_ALLOWED_TOOLS).toContain("ctx_search");
182
- expect(SIDEKICK_ALLOWED_TOOLS).not.toContain("ctx_memory");
183
- });
184
-
185
- it("includes `aft_outline` and `aft_zoom` for lightweight structural context", () => {
186
- // Sidekick can pull file outline / symbol body when the user's
187
- // prompt references a specific file or symbol, without dragging
188
- // in whole files.
189
- expect(SIDEKICK_ALLOWED_TOOLS).toContain("aft_outline");
190
- expect(SIDEKICK_ALLOWED_TOOLS).toContain("aft_zoom");
191
- });
192
-
193
- it("does NOT include `read` (use aft_outline/aft_zoom for navigation instead)", () => {
194
- // Sidekick should pull symbol-scoped views, not arbitrary file
195
- // contents. If it needs full source it can use aft_zoom on a
196
- // specific symbol.
197
- expect(SIDEKICK_ALLOWED_TOOLS).not.toContain("read");
198
- });
199
-
200
- it("does NOT include `task` or any edit / bash / web tool", () => {
201
- for (const denied of ["task", "bash", "edit", "write", "webfetch", "websearch"]) {
202
- expect(SIDEKICK_ALLOWED_TOOLS).not.toContain(denied);
203
- }
204
- });
205
- });
206
-
207
176
  describe("integration: full hidden-agent permission shape", () => {
208
177
  it("historian permission object: `*` denied + read + aft_outline + aft_zoom + aft_search allowed", () => {
209
178
  const perm = buildAllowOnlyPermission(HISTORIAN_ALLOWED_TOOLS);
@@ -239,14 +208,4 @@ describe("integration: full hidden-agent permission shape", () => {
239
208
  aft_search: "allow",
240
209
  });
241
210
  });
242
-
243
- it("sidekick permission object: `*` denied + read-only retrieval/navigation allowed", () => {
244
- const perm = buildAllowOnlyPermission(SIDEKICK_ALLOWED_TOOLS);
245
- expect(perm).toEqual({
246
- "*": "deny",
247
- ctx_search: "allow",
248
- aft_outline: "allow",
249
- aft_zoom: "allow",
250
- });
251
- });
252
211
  });
@@ -5,7 +5,7 @@ import { log } from "../shared/logger";
5
5
  *
6
6
  * # Why this exists
7
7
  *
8
- * Hidden agents (`historian`, `historian-editor`, `dreamer`, `sidekick`) are
8
+ * Hidden agents (`historian`, `historian-editor`, `dreamer`) are
9
9
  * registered with `mode: "primary"` and `hidden: true`: primary mode keeps
10
10
  * them out of OpenCode's general Task candidate list, while hidden keeps them
11
11
  * out of the UI picker. Those flags do NOT restrict which tools the spawned
@@ -63,13 +63,6 @@ import { log } from "../shared/logger";
63
63
  * dreamer task variants. `task` / `edit` / `write` / `webfetch` /
64
64
  * `websearch` remain denied — dreamer must not spawn subagents
65
65
  * or commit changes.
66
- *
67
- * - **sidekick**: `ctx_search`, plus the read-only AFT
68
- * navigation tools `aft_outline` and `aft_zoom`. Sidekick's job
69
- * is augmenting user prompts via memory retrieval — see
70
- * `features/magic-context/sidekick/agent.ts`. AFT navigation lets
71
- * it pull symbol-scoped structural context for prompts that
72
- * reference a specific file or symbol.
73
66
  */
74
67
 
75
68
  /**
@@ -242,20 +235,6 @@ export function applyDisallowedTools(
242
235
  // read/write/bash, no memory) — both in `dreamer.ts` alongside the other
243
236
  // per-task allow-lists (mapper/classifier/etc).
244
237
 
245
- /**
246
- * Tools the sidekick agent needs. Sidekick is a read-only memory
247
- * retriever for `/ctx-aug` — it queries the project's memory store
248
- * through `ctx_search` only. Keep `ctx_memory` out of this list because
249
- * its OpenCode tool definition is mutation-capable for primary agents.
250
- *
251
- * Also allow `aft_outline` and `aft_zoom` so sidekick can pull
252
- * lightweight structural context about a file or symbol when the
253
- * user's prompt references it directly — token-efficient navigation
254
- * without dragging in whole files.
255
- *
256
- * Still denied: spawning subagents, edits, bash, web fetches.
257
- */
258
-
259
238
  export const DREAMER_RETROSPECTIVE_ALLOWED_TOOLS = ["ctx_search"] as const;
260
239
 
261
240
  /**
@@ -280,5 +259,3 @@ export const DREAMER_PRIMER_INVESTIGATOR_ALLOWED_TOOLS = [
280
259
  * performed only when the compiled check runs through the host capability API.
281
260
  */
282
261
  export const SMART_NOTE_COMPILER_ALLOWED_TOOLS = [] as const;
283
-
284
- export const SIDEKICK_ALLOWED_TOOLS = ["ctx_search", "aft_outline", "aft_zoom"] as const;
@@ -12,10 +12,6 @@ export function isDreamerRunnable(config: { dreamer?: { disable?: boolean } | nu
12
12
  return !!config.dreamer && config.dreamer.disable !== true;
13
13
  }
14
14
 
15
- export function isSidekickRunnable(config: { sidekick?: { disable?: boolean } | null }): boolean {
16
- return !!config.sidekick && config.sidekick.disable !== true;
17
- }
18
-
19
15
  export function isHistorianRunnable(config: { historian?: { disable?: boolean } | null }): boolean {
20
16
  return config.historian?.disable !== true;
21
17
  }
@@ -43,7 +39,7 @@ function clonePlainObject(value: unknown): Record<string, unknown> | undefined {
43
39
 
44
40
  function migrateLegacyEnabledForAgent(args: {
45
41
  patched: Record<string, unknown>;
46
- agentName: "dreamer" | "sidekick" | "historian";
42
+ agentName: "dreamer" | "historian";
47
43
  warnings: string[];
48
44
  }): void {
49
45
  const agent = clonePlainObject(args.patched[args.agentName]);
@@ -61,33 +57,21 @@ function migrateLegacyEnabledForAgent(args: {
61
57
  return;
62
58
  }
63
59
 
64
- if (args.agentName === "dreamer") {
65
- if (disable !== true && enabled === false) {
66
- agent.disable = true;
67
- args.warnings.push(
68
- 'Migrated "dreamer.enabled=false" → "dreamer.disable=true" in-memory (run doctor to persist). This now also disables manual /ctx-dream; for manual-only remove disable and set schedule="".',
69
- );
70
- }
71
- // enabled=true is a no-op alias for the new default (disable=false); strip silently.
72
- args.patched.dreamer = agent;
73
- return;
74
- }
75
-
76
60
  if (disable !== true && enabled === false) {
77
61
  agent.disable = true;
78
62
  args.warnings.push(
79
- 'Migrated "sidekick.enabled=false" → "sidekick.disable=true" in-memory (run doctor to persist).',
63
+ 'Migrated "dreamer.enabled=false" → "dreamer.disable=true" in-memory (run doctor to persist). This now also disables manual /ctx-dream; for manual-only remove disable and set schedule="".',
80
64
  );
81
65
  }
82
- // enabled=true is a no-op alias for the new default; strip silently.
83
- args.patched.sidekick = agent;
66
+ // enabled=true is a no-op alias for the new default (disable=false); strip silently.
67
+ args.patched.dreamer = agent;
84
68
  }
85
69
 
86
70
  export function migrateLegacyAgentEnabledInMemory(
87
71
  rawConfig: Record<string, unknown>,
88
72
  warnings: string[],
89
73
  ): Record<string, unknown> {
90
- const shouldPatch = ["dreamer", "sidekick", "historian"].some((key) => {
74
+ const shouldPatch = ["dreamer", "historian"].some((key) => {
91
75
  const agent = rawConfig[key];
92
76
  return (
93
77
  typeof agent === "object" &&
@@ -100,7 +84,6 @@ export function migrateLegacyAgentEnabledInMemory(
100
84
 
101
85
  const patched: Record<string, unknown> = { ...rawConfig };
102
86
  migrateLegacyEnabledForAgent({ patched, agentName: "dreamer", warnings });
103
- migrateLegacyEnabledForAgent({ patched, agentName: "sidekick", warnings });
104
87
  migrateLegacyEnabledForAgent({ patched, agentName: "historian", warnings });
105
88
  return patched;
106
89
  }
@@ -3,8 +3,10 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
5
 
6
+ import { resolveEpochFloorForPass } from "../features/magic-context/storage-meta-persisted";
6
7
  import { buildOpenCodeConfigWarningBanner } from "../shared/config-warning-surface";
7
8
  import { resolveHistorianModel } from "../shared/model-resolution";
9
+ import { Database } from "../shared/sqlite";
8
10
  import { createTestTempDir } from "../shared/test-temp-dir";
9
11
  import {
10
12
  getWindowOverlay,
@@ -13,6 +15,8 @@ import {
13
15
  } from "../shared/window-geometry";
14
16
  import { loadPluginConfig, loadPluginConfigDetailed } from "./index";
15
17
  import { resolveConfigProfile } from "./profiles";
18
+ import { getProtectedTokensTierOverrides } from "./project-security";
19
+ import { REMOVED_AGENT_CONFIG_WARNING } from "./removed-agent-config";
16
20
  import { DEFAULT_LOCAL_EMBEDDING_MODEL } from "./schema/magic-context";
17
21
  import { RUST_COMPACTION_OFF_WARNING } from "./transform-mode";
18
22
 
@@ -211,7 +215,7 @@ describe("loadPluginConfig — parse failure diagnostics", () => {
211
215
 
212
216
  it("keeps file parse and invalid-leaf warning classes distinct", () => {
213
217
  const parseResult = loadWithUserConfig('\\{\n "cache_ttl": "1h"\n}');
214
- const leafResult = loadWithUserConfig('{"protected_tags":"bogus"}');
218
+ const leafResult = loadWithUserConfig('{"protected_tokens":"bogus"}');
215
219
 
216
220
  expect(parseResult.configWarningDetails?.[0]?.warningClass).toBe("file-parse");
217
221
  expect(
@@ -747,18 +751,26 @@ describe("loadPluginConfig — legacy agent enabled migration", () => {
747
751
  expect(warnings).not.toContain("dreamer.enabled");
748
752
  });
749
753
 
750
- it("migrates sidekick.enabled=false (loud) and removes sidekick.enabled=true (silent)", () => {
751
- const disabled = loadWithUserConfig(JSON.stringify({ sidekick: { enabled: false } }));
752
- expect(disabled.sidekick?.disable).toBe(true);
753
- expect(disabled.configWarnings?.join("\n")).toContain(
754
- 'Migrated "sidekick.enabled=false" → "sidekick.disable=true" in-memory (run doctor to persist).',
754
+ it("ignores the removed agent block with one warning", () => {
755
+ const removedKey = ["side", "kick"].join("");
756
+ const result = loadWithUserConfig(
757
+ JSON.stringify({
758
+ profile: "work",
759
+ [removedKey]: { enabled: false, model: "example/model" },
760
+ profiles: {
761
+ work: {
762
+ [removedKey]: { model: "example/profile-model" },
763
+ historian: { opencode: { model: "example/historian" } },
764
+ },
765
+ },
766
+ }),
755
767
  );
756
768
 
757
- const enabled = loadWithUserConfig(JSON.stringify({ sidekick: { enabled: true } }));
758
- expect(enabled.sidekick?.disable).toBeUndefined();
759
- expect("enabled" in (enabled.sidekick as Record<string, unknown>)).toBe(false);
760
- const enabledWarnings = enabled.configWarnings?.join("\n") ?? "";
761
- expect(enabledWarnings).not.toContain("sidekick.enabled");
769
+ expect(removedKey in result).toBe(false);
770
+ expect(result.historian?.opencode?.model).toBe("example/historian");
771
+ expect(result.configWarnings?.filter((warning) => warning.includes(removedKey))).toEqual([
772
+ `[config] ${REMOVED_AGENT_CONFIG_WARNING}`,
773
+ ]);
762
774
  });
763
775
 
764
776
  it("removes invalid historian.enabled and applies conflict rules", () => {
@@ -766,13 +778,11 @@ describe("loadPluginConfig — legacy agent enabled migration", () => {
766
778
  JSON.stringify({
767
779
  historian: { enabled: false },
768
780
  dreamer: { enabled: false, disable: false },
769
- sidekick: { enabled: true, disable: true },
770
781
  }),
771
782
  );
772
783
 
773
784
  expect(result.historian).toEqual({ two_pass: false, disallowed_tools: [] });
774
785
  expect(result.dreamer?.disable).toBe(true);
775
- expect(result.sidekick?.disable).toBe(true);
776
786
  expect(result.configWarnings?.join("\n")).toContain(
777
787
  'Removed invalid "historian.enabled" in-memory (run doctor to persist).',
778
788
  );
@@ -944,6 +954,109 @@ describe("loadPluginConfig — user-only settings", () => {
944
954
  });
945
955
 
946
956
  describe("loadPluginConfig — project compaction trust boundary", () => {
957
+ it("keeps protected_tokens scalar-only at both tiers and preserves the user scalar on an invalid project leaf", () => {
958
+ const vectors = [
959
+ {
960
+ name: "user scalar",
961
+ user: { protected_tokens: 20_000 },
962
+ project: {},
963
+ expected: 20_000,
964
+ warns: false,
965
+ },
966
+ {
967
+ name: "user object",
968
+ user: { protected_tokens: { default: 20_000 } },
969
+ project: {},
970
+ expected: undefined,
971
+ warns: true,
972
+ },
973
+ {
974
+ name: "project scalar",
975
+ user: {},
976
+ project: { protected_tokens: 20_000 },
977
+ expected: 20_000,
978
+ warns: false,
979
+ },
980
+ {
981
+ name: "project object",
982
+ user: {},
983
+ project: { protected_tokens: { default: 20_000 } },
984
+ expected: undefined,
985
+ warns: true,
986
+ },
987
+ {
988
+ name: "invalid project object over user scalar",
989
+ user: { protected_tokens: 25_000 },
990
+ project: { protected_tokens: { default: 30_000 } },
991
+ expected: 25_000,
992
+ warns: true,
993
+ },
994
+ ] as const;
995
+
996
+ for (const vector of vectors) {
997
+ const result = loadWithUserAndProjectConfig(
998
+ JSON.stringify(vector.user),
999
+ JSON.stringify(vector.project),
1000
+ );
1001
+ expect(result.protected_tokens, vector.name).toBe(vector.expected);
1002
+ const warned = (result.configWarnings ?? []).some((warning) =>
1003
+ warning.includes("protected_tokens"),
1004
+ );
1005
+ expect(warned, vector.name).toBe(vector.warns);
1006
+ }
1007
+ });
1008
+
1009
+ it("rejects a project protected_tokens floor below the derived floor once geometry is known", () => {
1010
+ const result = loadWithUserAndProjectConfig(
1011
+ JSON.stringify({}),
1012
+ JSON.stringify({ protected_tokens: 4_000 }),
1013
+ );
1014
+ const db = new Database(":memory:");
1015
+ db.exec(`
1016
+ CREATE TABLE session_meta (
1017
+ session_id TEXT PRIMARY KEY,
1018
+ harness TEXT NOT NULL DEFAULT 'opencode',
1019
+ last_response_time INTEGER NOT NULL DEFAULT 0,
1020
+ cache_ttl TEXT NOT NULL DEFAULT '5m',
1021
+ counter INTEGER NOT NULL DEFAULT 0,
1022
+ last_nudge_tokens INTEGER NOT NULL DEFAULT 0,
1023
+ last_nudge_band TEXT NOT NULL DEFAULT '',
1024
+ last_transform_error TEXT NOT NULL DEFAULT '',
1025
+ is_subagent INTEGER NOT NULL DEFAULT 0,
1026
+ last_context_percentage REAL NOT NULL DEFAULT 0,
1027
+ last_input_tokens INTEGER NOT NULL DEFAULT 0,
1028
+ observed_safe_input_tokens INTEGER NOT NULL DEFAULT 0,
1029
+ cache_alert_sent INTEGER NOT NULL DEFAULT 0,
1030
+ times_execute_threshold_reached INTEGER NOT NULL DEFAULT 0,
1031
+ compartment_in_progress INTEGER NOT NULL DEFAULT 0,
1032
+ system_prompt_hash TEXT NOT NULL DEFAULT '',
1033
+ cleared_reasoning_through_tag INTEGER NOT NULL DEFAULT 0,
1034
+ protected_tokens_effective INTEGER,
1035
+ protected_tokens_pre_snapshot TEXT
1036
+ )
1037
+ `);
1038
+ const warnings: string[] = [];
1039
+ const tierOverrides = getProtectedTokensTierOverrides(result);
1040
+
1041
+ const resolved = resolveEpochFloorForPass(db, "loader-derived-floor", {
1042
+ tierOverrides,
1043
+ usableSoft: 200_000,
1044
+ isCacheBustingPass: true,
1045
+ onRejectedProjectOverride: (warning) => warnings.push(warning),
1046
+ });
1047
+ resolveEpochFloorForPass(db, "loader-derived-floor-next", {
1048
+ tierOverrides,
1049
+ usableSoft: 200_000,
1050
+ isCacheBustingPass: true,
1051
+ onRejectedProjectOverride: (warning) => warnings.push(warning),
1052
+ });
1053
+
1054
+ expect(resolved.floor).toBe(16_000);
1055
+ expect(warnings).toHaveLength(1);
1056
+ expect(warnings[0]).toContain("protected_tokens=4000");
1057
+ db.close();
1058
+ });
1059
+
947
1060
  it("ignores a lower project execute_threshold_percentage with a warning", () => {
948
1061
  const result = loadWithUserAndProjectConfig(
949
1062
  JSON.stringify({ execute_threshold_percentage: 60 }),
@@ -1176,7 +1289,6 @@ describe("loadPluginConfig — user-owned model profiles", () => {
1176
1289
  ],
1177
1290
  },
1178
1291
  },
1179
- sidekick: { model: "anthropic/work-sidekick" },
1180
1292
  },
1181
1293
  personal: {
1182
1294
  historian: { opencode: { model: "anthropic/personal-historian" } },
@@ -1200,7 +1312,6 @@ describe("loadPluginConfig — user-owned model profiles", () => {
1200
1312
  expect(result.dreamer?.opencode?.fallback_models).toEqual([
1201
1313
  { model: "openai/work-dreamer-fallback", variant: "medium" },
1202
1314
  ]);
1203
- expect(result.sidekick?.model).toBe("anthropic/work-sidekick");
1204
1315
  });
1205
1316
 
1206
1317
  it("uses project selection over user selection and falls back to the base on an unknown name", () => {
@@ -25,12 +25,14 @@ import { migrateDreamerV2 } from "./migrate-dreamer-v2";
25
25
  import { migrateLegacyExperimental } from "./migrate-experimental";
26
26
  import { resolveConfigProfile } from "./profiles";
27
27
  import {
28
+ attachProtectedTokensTierOverrides,
28
29
  constrainProjectThresholdOverrides,
29
30
  dropInheritedEmbeddingKeyOnRedirect,
30
31
  stripUnsafeProjectConfigFields,
31
32
  } from "./project-security";
32
33
  import { pruneNestedConfigLeaf } from "./prune-config-leaf";
33
34
  import { loadRawConfigFile } from "./raw-loader";
35
+ import { stripRemovedAgentConfig } from "./removed-agent-config";
34
36
  import { type MagicContextConfig, MagicContextConfigSchema } from "./schema/magic-context";
35
37
  import { resolveTransformMode } from "./transform-mode";
36
38
  import { substituteConfigVariables } from "./variable";
@@ -319,14 +321,39 @@ function redactConfigValue(value: unknown): string {
319
321
  return typeof value;
320
322
  }
321
323
 
322
- function parsePluginConfig(
324
+ let warnedProtectedTagsDeprecation = false;
325
+
326
+ export function resetProtectedTagsDeprecationWarningForTest(): void {
327
+ warnedProtectedTagsDeprecation = false;
328
+ }
329
+
330
+ export function warnProtectedTagsDeprecationOnce(): void {
331
+ if (!warnedProtectedTagsDeprecation) {
332
+ warnedProtectedTagsDeprecation = true;
333
+ console.warn(
334
+ "[magic-context] protected_tags is deprecated and ignored; use protected_tokens instead.",
335
+ );
336
+ }
337
+ }
338
+
339
+ export function parsePluginConfig(
323
340
  rawConfig: Record<string, unknown>,
324
341
  recoveredTopLevelKeys: string[] = [],
325
342
  ): MagicContextPluginConfig & { configWarnings?: string[] } {
326
343
  // Pre-Zod shim: reshape legacy experimental.* graduated keys so the user's
327
344
  // opt-in/out state survives upgrades even when they never run `doctor`.
328
345
  const preMigrationWarnings: string[] = [];
329
- const migratedExperimental = migrateLegacyExperimental(rawConfig, preMigrationWarnings);
346
+ const configWithoutRemovedAgent = stripRemovedAgentConfig(rawConfig, preMigrationWarnings);
347
+ if (Object.hasOwn(rawConfig, "protected_tags")) {
348
+ warnProtectedTagsDeprecationOnce();
349
+ preMigrationWarnings.push(
350
+ "protected_tags is deprecated and ignored; use protected_tokens instead.",
351
+ );
352
+ }
353
+ const migratedExperimental = migrateLegacyExperimental(
354
+ configWithoutRemovedAgent,
355
+ preMigrationWarnings,
356
+ );
330
357
  // Dreamer v2: convert the legacy v1 dreamer shape (window schedule, tasks
331
358
  // array, user_memories/pin_key_files blocks) into the per-task `tasks` record.
332
359
  // Runs AFTER migrate-experimental so experimental.user_memories (already
@@ -397,7 +424,7 @@ function parsePluginConfig(
397
424
  const patched: Record<string, unknown> = { ...rawConfig };
398
425
  for (const key of errorPaths) {
399
426
  recoveredTopLevelKeys.push(key);
400
- const isAgentConfig = key === "historian" || key === "dreamer" || key === "sidekick";
427
+ const isAgentConfig = key === "historian" || key === "dreamer";
401
428
 
402
429
  // For object-valued keys (including agent harness blocks), prune only invalid
403
430
  // nested leaves and keep valid siblings, so one bad field does not remove
@@ -610,6 +637,8 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
610
637
  : null;
611
638
 
612
639
  const allWarnings: string[] = [];
640
+ const removedConfigWarnings: string[] = [];
641
+ const userRaw = stripRemovedAgentConfig(userLoaded?.config ?? {}, removedConfigWarnings);
613
642
 
614
643
  if (userLegacyFallback.source) {
615
644
  allWarnings.push(
@@ -638,18 +667,20 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
638
667
  let projectRaw: Record<string, unknown> = {};
639
668
  if (projectLoaded) {
640
669
  allWarnings.push(...projectLoaded.warnings.map((w) => `[project config] ${w}`));
641
- projectRaw = { ...projectLoaded.config };
670
+ projectRaw = stripRemovedAgentConfig(projectLoaded.config, removedConfigWarnings);
642
671
  for (const warning of stripUnsafeProjectConfigFields(projectRaw)) {
643
672
  allWarnings.push(`[project config] ${warning}`);
644
673
  }
645
674
  }
646
675
 
676
+ allWarnings.push(...removedConfigWarnings.map((warning) => `[config] ${warning}`));
677
+
647
678
  // Resolve profiles at the single user→project merge choke point. The profile
648
679
  // definition is parsed from the trusted user tier, then its validated model
649
680
  // overlay is merged before the untrusted project config. The raw selector is
650
681
  // consumed here; only the resolved name remains as status metadata.
651
682
  const profileResolution = resolveConfigProfile({
652
- userRaw: userLoaded?.config ?? {},
683
+ userRaw,
653
684
  projectRaw,
654
685
  });
655
686
  allWarnings.push(...profileResolution.warnings.map((warning) => `[config] ${warning}`));
@@ -684,6 +715,10 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
684
715
  const recoveredTopLevelKeys: string[] = [];
685
716
  const cacheTtlConfigured = Object.hasOwn(mergedRaw, "cache_ttl");
686
717
  const config = parsePluginConfig(mergedRaw, recoveredTopLevelKeys);
718
+ attachProtectedTokensTierOverrides(config, {
719
+ trustedUser: trustedBaseConfig.protected_tokens,
720
+ project: projectLoaded ? profileResolution.projectBase.protected_tokens : undefined,
721
+ });
687
722
  if (profileResolution.activeProfile) config.profile = profileResolution.activeProfile;
688
723
  setOutputReserveConfig(config.output_reserve);
689
724
  setWindowOverlayPath(config.models?.window_overlay_path);
@@ -700,7 +735,7 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
700
735
 
701
736
  const resolvedTransformMode = resolveTransformMode({
702
737
  configured: config.transform_mode,
703
- userTierHasSubc: hasUserTierSubcConfig(userLoaded?.config),
738
+ userTierHasSubc: hasUserTierSubcConfig(userRaw),
704
739
  compactionEnabled: isCompactionEnabled(config),
705
740
  });
706
741
  config.transform_mode = resolvedTransformMode.mode;
@@ -126,6 +126,10 @@ const KNOWN_SLOTS: Record<string, KnownSlot> = {
126
126
  classification: "VERDICT",
127
127
  reason: "Saved: the promise has a 60-second TTL, including rejections, and discovery is retried after expiry.",
128
128
  },
129
+ "packages/plugin/src/shared/opencode-db-path.ts:lastReadFailure": {
130
+ classification: "DIAGNOSTIC",
131
+ reason: "Most-recent OpenCode DB read diagnostic: a successful open clears it, and path discovery re-probes after disappearance.",
132
+ },
129
133
  "packages/plugin/src/shared/models-dev-cache.ts:authRewarmDone": {
130
134
  classification: "VERDICT",
131
135
  reason: "Saved: refreshModelLimitsAfterAuthOnce resets the latch when its warm fails.",