@cortexkit/opencode-magic-context 0.41.3 → 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 (384) 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 +14 -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-z5sd697e.js → conflict-warning-hook-6p3xqeac.js} +4 -4
  20. package/dist/{derive-budgets-901a0pk0.js → derive-budgets-s2pgnnm4.js} +4 -2
  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/storage-dream-runs.d.ts +13 -0
  37. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  38. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  39. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +7 -0
  40. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  41. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  42. package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
  43. package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts.map +1 -1
  44. package/dist/features/magic-context/index.d.ts +0 -1
  45. package/dist/features/magic-context/index.d.ts.map +1 -1
  46. package/dist/features/magic-context/memory/embedding-local.d.ts +13 -0
  47. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  48. package/dist/features/magic-context/memory/embedding-synapse.d.ts +43 -10
  49. package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
  50. package/dist/features/magic-context/memory/embedding.d.ts +1 -1
  51. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
  52. package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
  53. package/dist/features/magic-context/memory/project-identity.d.ts +1 -0
  54. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  55. package/dist/features/magic-context/memory/promotion.d.ts +7 -1
  56. package/dist/features/magic-context/memory/promotion.d.ts.map +1 -1
  57. package/dist/features/magic-context/merged-reasoning-decisions.d.ts +6 -0
  58. package/dist/features/magic-context/merged-reasoning-decisions.d.ts.map +1 -0
  59. package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -1
  60. package/dist/features/magic-context/message-index-async.d.ts +12 -0
  61. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  62. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  63. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  64. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  65. package/dist/features/magic-context/mural/render-trigger.d.ts +6 -0
  66. package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
  67. package/dist/features/magic-context/no-content-compartment.d.ts +12 -0
  68. package/dist/features/magic-context/no-content-compartment.d.ts.map +1 -0
  69. package/dist/features/magic-context/pi-content-decisions.d.ts +9 -0
  70. package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -0
  71. package/dist/features/magic-context/project-docs-hash.d.ts +4 -0
  72. package/dist/features/magic-context/project-docs-hash.d.ts.map +1 -1
  73. package/dist/features/magic-context/project-embedding-registry.d.ts +13 -4
  74. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  75. package/dist/features/magic-context/protection-window.d.ts +79 -0
  76. package/dist/features/magic-context/protection-window.d.ts.map +1 -0
  77. package/dist/features/magic-context/search.d.ts.map +1 -1
  78. package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
  79. package/dist/features/magic-context/shadow-backfill-state.d.ts +26 -0
  80. package/dist/features/magic-context/shadow-backfill-state.d.ts.map +1 -0
  81. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  82. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +4 -0
  83. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
  84. package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
  85. package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
  86. package/dist/features/magic-context/storage-db.d.ts +1 -1
  87. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  88. package/dist/features/magic-context/storage-embedding-measurements.d.ts +2 -2
  89. package/dist/features/magic-context/storage-embedding-measurements.d.ts.map +1 -1
  90. package/dist/features/magic-context/storage-historian-runs.d.ts +4 -0
  91. package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
  92. package/dist/features/magic-context/storage-memory-mutation-log.d.ts +1 -0
  93. package/dist/features/magic-context/storage-memory-mutation-log.d.ts.map +1 -1
  94. package/dist/features/magic-context/storage-meta-persisted.d.ts +81 -15
  95. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  96. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  97. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  98. package/dist/features/magic-context/storage-native-replay.d.ts +29 -0
  99. package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -0
  100. package/dist/features/magic-context/storage-notes.d.ts +6 -0
  101. package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
  102. package/dist/features/magic-context/storage-replay-document.d.ts +33 -0
  103. package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -0
  104. package/dist/features/magic-context/storage-subagent-invocations.d.ts +1 -1
  105. package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -1
  106. package/dist/features/magic-context/storage-tags.d.ts +19 -11
  107. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  108. package/dist/features/magic-context/storage.d.ts +3 -3
  109. package/dist/features/magic-context/storage.d.ts.map +1 -1
  110. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
  111. package/dist/features/magic-context/tagger.d.ts +13 -0
  112. package/dist/features/magic-context/tagger.d.ts.map +1 -1
  113. package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
  114. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  115. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
  116. package/dist/features/magic-context/workspaces.d.ts.map +1 -1
  117. package/dist/hooks/magic-context/apply-operations.d.ts +11 -5
  118. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  119. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  120. package/dist/hooks/magic-context/cache-busting-signals.d.ts +9 -1
  121. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
  122. package/dist/hooks/magic-context/caveman-cleanup.d.ts +1 -1
  123. package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
  124. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  125. package/dist/hooks/magic-context/child-session-spawn.d.ts +3 -3
  126. package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
  127. package/dist/hooks/magic-context/command-handler.d.ts +5 -10
  128. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  129. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  130. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +10 -21
  131. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
  132. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  133. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  134. package/dist/hooks/magic-context/compartment-runner-types.d.ts +4 -0
  135. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  136. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +26 -2
  137. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
  138. package/dist/hooks/magic-context/decay-render.d.ts.map +1 -1
  139. package/dist/hooks/magic-context/derive-budgets.d.ts +1 -0
  140. package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -1
  141. package/dist/hooks/magic-context/dropped-input-guard.d.ts +9 -0
  142. package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -0
  143. package/dist/hooks/magic-context/emergency-drop.d.ts +9 -2
  144. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  145. package/dist/hooks/magic-context/event-handler.d.ts +0 -1
  146. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  147. package/dist/hooks/magic-context/event-payloads.d.ts +7 -6
  148. package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
  149. package/dist/hooks/magic-context/event-resolvers.d.ts +1 -1
  150. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  151. package/dist/hooks/magic-context/execute-status.d.ts +8 -2
  152. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  153. package/dist/hooks/magic-context/format-embed-status.d.ts.map +1 -1
  154. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +11 -4
  155. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  156. package/dist/hooks/magic-context/hook-handlers.d.ts +5 -1
  157. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  158. package/dist/hooks/magic-context/hook.d.ts +17 -5
  159. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  160. package/dist/hooks/magic-context/inject-compartments.d.ts +14 -1
  161. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  162. package/dist/hooks/magic-context/issue-423-fixture.d.ts +37 -0
  163. package/dist/hooks/magic-context/issue-423-fixture.d.ts.map +1 -0
  164. package/dist/hooks/magic-context/issue-424-fixture.d.ts +11 -0
  165. package/dist/hooks/magic-context/issue-424-fixture.d.ts.map +1 -0
  166. package/dist/hooks/magic-context/live-session-state.d.ts +1 -1
  167. package/dist/hooks/magic-context/lkg-slot.d.ts +34 -0
  168. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  169. package/dist/hooks/magic-context/module-state-sync-timing.d.ts +21 -0
  170. package/dist/hooks/magic-context/module-state-sync-timing.d.ts.map +1 -0
  171. package/dist/hooks/magic-context/module-state-sync.d.ts +21 -7
  172. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  173. package/dist/hooks/magic-context/module-transport.d.ts +12 -0
  174. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  175. package/dist/hooks/magic-context/module-wire.d.ts +8 -0
  176. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  177. package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
  178. package/dist/hooks/magic-context/persist-filtered-noise.d.ts +5 -0
  179. package/dist/hooks/magic-context/persist-filtered-noise.d.ts.map +1 -0
  180. package/dist/hooks/magic-context/producer-window-guard.d.ts +8 -0
  181. package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -0
  182. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +65 -0
  183. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  184. package/dist/hooks/magic-context/read-session-chunk.d.ts +20 -18
  185. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  186. package/dist/hooks/magic-context/read-session-db.d.ts +22 -12
  187. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  188. package/dist/hooks/magic-context/read-session-formatting.d.ts +8 -0
  189. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  190. package/dist/hooks/magic-context/read-session-raw.d.ts +10 -1
  191. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  192. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +4 -1
  193. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  194. package/dist/hooks/magic-context/recomp-orchestrator.d.ts +2 -0
  195. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  196. package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
  197. package/dist/hooks/magic-context/rust-mode-transform.d.ts +79 -11
  198. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  199. package/dist/hooks/magic-context/send-session-notification.d.ts +11 -10
  200. package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
  201. package/dist/hooks/magic-context/sentinel.d.ts +3 -3
  202. package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
  203. package/dist/hooks/magic-context/strip-content.d.ts +7 -0
  204. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  205. package/dist/hooks/magic-context/supersession-reclaim.d.ts +13 -0
  206. package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
  207. package/dist/hooks/magic-context/system-prompt-hash.d.ts +2 -3
  208. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  209. package/dist/hooks/magic-context/tag-messages.d.ts +2 -0
  210. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  211. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +16 -6
  212. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  213. package/dist/hooks/magic-context/tool-drop-target.d.ts +1 -0
  214. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  215. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +2 -0
  216. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  217. package/dist/hooks/magic-context/transform-context-state.d.ts +7 -1
  218. package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
  219. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +11 -4
  220. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  221. package/dist/hooks/magic-context/transform.d.ts +11 -2
  222. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  223. package/dist/hooks/magic-context/upgrade-reminder.d.ts +7 -9
  224. package/dist/hooks/magic-context/upgrade-reminder.d.ts.map +1 -1
  225. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  226. package/dist/index-1974jvn3.js +783 -0
  227. package/dist/{index-npx8vhmy.js → index-36wd1d6k.js} +7 -30
  228. package/dist/{index-kby1sng5.js → index-avwt563y.js} +8 -1
  229. package/dist/{index-vmmjdpc0.js → index-c9hamh36.js} +18357 -16010
  230. package/dist/{index-0bycg0np.js → index-jmtjh2d3.js} +4 -4
  231. package/dist/{index-q264erdp.js → index-nqgjwfzn.js} +70 -38
  232. package/dist/index-sd3egckz.js +1583 -0
  233. package/dist/{index-dn1rwpd8.js → index-xdtge3y2.js} +58 -16
  234. package/dist/index.d.ts.map +1 -1
  235. package/dist/index.js +6826 -6660
  236. package/dist/plugin/conflict-warning-hook.d.ts +5 -6
  237. package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
  238. package/dist/plugin/dream-timer.d.ts +1 -0
  239. package/dist/plugin/dream-timer.d.ts.map +1 -1
  240. package/dist/plugin/embedding-routing.d.ts +4 -1
  241. package/dist/plugin/embedding-routing.d.ts.map +1 -1
  242. package/dist/plugin/hooks/create-session-hooks.d.ts +19 -2
  243. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  244. package/dist/plugin/rpc-handlers.d.ts +31 -1
  245. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  246. package/dist/plugin/rust-tool-backends.d.ts +1 -0
  247. package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
  248. package/dist/plugin/tool-registry.d.ts.map +1 -1
  249. package/dist/{recomp-orchestrator-f5m2wk74.js → recomp-orchestrator-3atsasjy.js} +6 -6
  250. package/dist/{send-session-notification-hdh02wy9.js → send-session-notification-1qeqkswb.js} +6 -4
  251. package/dist/shared/cache-ttl-display.d.ts +23 -0
  252. package/dist/shared/cache-ttl-display.d.ts.map +1 -0
  253. package/dist/shared/cache-ttl-seed.d.ts +10 -0
  254. package/dist/shared/cache-ttl-seed.d.ts.map +1 -0
  255. package/dist/shared/child-session-teardown.d.ts +34 -0
  256. package/dist/shared/child-session-teardown.d.ts.map +1 -0
  257. package/dist/shared/config-diagnostics.d.ts +30 -0
  258. package/dist/shared/config-diagnostics.d.ts.map +1 -0
  259. package/dist/shared/config-warning-surface.d.ts +3 -0
  260. package/dist/shared/config-warning-surface.d.ts.map +1 -0
  261. package/dist/shared/data-path.d.ts +10 -9
  262. package/dist/shared/data-path.d.ts.map +1 -1
  263. package/dist/shared/harness-provider-map.d.ts +7 -0
  264. package/dist/shared/harness-provider-map.d.ts.map +1 -1
  265. package/dist/shared/jsonc-parser.d.ts +12 -0
  266. package/dist/shared/jsonc-parser.d.ts.map +1 -1
  267. package/dist/shared/keep-subagents.d.ts +1 -1
  268. package/dist/shared/keep-subagents.d.ts.map +1 -1
  269. package/dist/shared/model-suggestion-retry.d.ts +15 -11
  270. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  271. package/dist/shared/opencode-db-path.d.ts +24 -0
  272. package/dist/shared/opencode-db-path.d.ts.map +1 -0
  273. package/dist/shared/pi-executable.d.ts +6 -0
  274. package/dist/shared/pi-executable.d.ts.map +1 -0
  275. package/dist/shared/prompt-surface-runtime.d.ts +10 -5
  276. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
  277. package/dist/shared/resolve-fallbacks.d.ts +1 -1
  278. package/dist/shared/rpc-types.d.ts +117 -0
  279. package/dist/shared/rpc-types.d.ts.map +1 -1
  280. package/dist/shared/rpc-utils.d.ts.map +1 -1
  281. package/dist/shared/sqlite.d.ts +42 -0
  282. package/dist/shared/sqlite.d.ts.map +1 -1
  283. package/dist/shared/status-detail-text.d.ts.map +1 -1
  284. package/dist/shared/subagent-runner.d.ts +17 -10
  285. package/dist/shared/subagent-runner.d.ts.map +1 -1
  286. package/dist/shared/tag-transcript.d.ts.map +1 -1
  287. package/dist/shared/transcript.d.ts +6 -0
  288. package/dist/shared/transcript.d.ts.map +1 -1
  289. package/dist/shared/window-geometry.d.ts +23 -0
  290. package/dist/shared/window-geometry.d.ts.map +1 -1
  291. package/dist/shared/write-transaction-timing.d.ts +1 -1
  292. package/dist/shared/write-transaction-timing.d.ts.map +1 -1
  293. package/dist/{storage-meta-session-3rxx9ekm.js → storage-meta-session-e6g0mmec.js} +2 -2
  294. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  295. package/dist/tools/ctx-memory/verification-recording.d.ts.map +1 -1
  296. package/dist/tools/ctx-note/constants.d.ts +1 -1
  297. package/dist/tools/ctx-note/constants.d.ts.map +1 -1
  298. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  299. package/dist/tools/ctx-note/types.d.ts +1 -0
  300. package/dist/tools/ctx-note/types.d.ts.map +1 -1
  301. package/dist/tools/ctx-reduce/tools.d.ts +10 -1
  302. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  303. package/dist/tools/ctx-search/constants.d.ts +1 -1
  304. package/dist/tools/ctx-search/constants.d.ts.map +1 -1
  305. package/dist/tools/light-descriptions.d.ts +2 -2
  306. package/dist/tools/light-descriptions.d.ts.map +1 -1
  307. package/package.json +2 -3
  308. package/src/agents/hidden-agent-registrations.ts +3 -15
  309. package/src/agents/magic-context-prompt.test.ts +7 -5
  310. package/src/agents/magic-context-prompt.ts +22 -30
  311. package/src/agents/permissions.test.ts +1 -42
  312. package/src/agents/permissions.ts +1 -24
  313. package/src/config/agent-disable.ts +5 -22
  314. package/src/config/index.test.ts +169 -14
  315. package/src/config/index.ts +137 -21
  316. package/src/config/latch-permanence-guard.test.ts +4 -0
  317. package/src/config/migrate-config-location.test.ts +39 -6
  318. package/src/config/migrate-config-location.ts +18 -31
  319. package/src/config/profiles.ts +1 -1
  320. package/src/config/project-security.hostile-matrix.test.ts +0 -8
  321. package/src/config/project-security.test.ts +11 -22
  322. package/src/config/project-security.ts +103 -9
  323. package/src/config/protected-tokens.test.ts +235 -0
  324. package/src/config/removed-agent-config.ts +45 -0
  325. package/src/config/removed-agent-source-fence.test.ts +56 -0
  326. package/src/config/schema/magic-context.test.ts +21 -42
  327. package/src/config/schema/magic-context.ts +46 -37
  328. package/src/shared/cache-ttl-display.test.ts +84 -0
  329. package/src/shared/cache-ttl-display.ts +64 -0
  330. package/src/shared/cache-ttl-seed.ts +23 -0
  331. package/src/shared/child-session-teardown.test.ts +218 -0
  332. package/src/shared/child-session-teardown.ts +66 -0
  333. package/src/shared/config-diagnostics.test.ts +29 -0
  334. package/src/shared/config-diagnostics.ts +64 -0
  335. package/src/shared/config-warning-surface.ts +28 -0
  336. package/src/shared/data-path.ts +10 -9
  337. package/src/shared/harness-provider-map.test.ts +16 -0
  338. package/src/shared/harness-provider-map.ts +15 -0
  339. package/src/shared/jsonc-parser.test.ts +14 -1
  340. package/src/shared/jsonc-parser.ts +93 -0
  341. package/src/shared/keep-subagents.ts +9 -14
  342. package/src/shared/model-suggestion-retry.ts +144 -29
  343. package/src/shared/opencode-db-path.test.ts +196 -0
  344. package/src/shared/opencode-db-path.ts +215 -0
  345. package/src/shared/pi-executable.ts +20 -0
  346. package/src/shared/prompt-surface-a1-golden.md +50 -35
  347. package/src/shared/prompt-surface-runtime.test.ts +28 -0
  348. package/src/shared/prompt-surface-runtime.ts +22 -5
  349. package/src/shared/resolve-fallbacks.ts +1 -1
  350. package/src/shared/rpc-types.ts +124 -0
  351. package/src/shared/rpc-utils.ts +2 -3
  352. package/src/shared/session-messages-bounded.test.ts +1 -1
  353. package/src/shared/sqlite-import-fence.test.ts +19 -0
  354. package/src/shared/sqlite.test.ts +27 -1
  355. package/src/shared/sqlite.ts +204 -1
  356. package/src/shared/status-detail-text.test.ts +8 -4
  357. package/src/shared/status-detail-text.ts +20 -1
  358. package/src/shared/subagent-runner.ts +17 -10
  359. package/src/shared/tag-transcript.ts +53 -22
  360. package/src/shared/transcript.ts +7 -0
  361. package/src/shared/window-geometry.test.ts +44 -0
  362. package/src/shared/window-geometry.ts +89 -11
  363. package/src/shared/write-transaction-attribution.test.ts +241 -0
  364. package/src/shared/write-transaction-timing.ts +2 -1
  365. package/src/tui/index.tsx +18 -4
  366. package/src/tui/slots/sidebar-content.tsx +12 -7
  367. package/src/tui-compiled/index.tsx +237 -225
  368. package/src/tui-compiled/slots/sidebar-content.tsx +301 -305
  369. package/dist/agents/sidekick.d.ts +0 -2
  370. package/dist/agents/sidekick.d.ts.map +0 -1
  371. package/dist/features/magic-context/defaults.d.ts +0 -2
  372. package/dist/features/magic-context/defaults.d.ts.map +0 -1
  373. package/dist/features/magic-context/sidekick/agent.d.ts +0 -14
  374. package/dist/features/magic-context/sidekick/agent.d.ts.map +0 -1
  375. package/dist/features/magic-context/sidekick/core.d.ts +0 -38
  376. package/dist/features/magic-context/sidekick/core.d.ts.map +0 -1
  377. package/dist/features/magic-context/sidekick/index.d.ts +0 -3
  378. package/dist/features/magic-context/sidekick/index.d.ts.map +0 -1
  379. package/dist/hooks/magic-context/boundary-execution.d.ts +0 -27
  380. package/dist/hooks/magic-context/boundary-execution.d.ts.map +0 -1
  381. package/dist/index-jfpk81yt.js +0 -146
  382. package/dist/index-raatkvw5.js +0 -360
  383. package/src/agents/sidekick.ts +0 -1
  384. package/src/features/magic-context/defaults.ts +0 -1
@@ -3,7 +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";
7
+ import { buildOpenCodeConfigWarningBanner } from "../shared/config-warning-surface";
6
8
  import { resolveHistorianModel } from "../shared/model-resolution";
9
+ import { Database } from "../shared/sqlite";
7
10
  import { createTestTempDir } from "../shared/test-temp-dir";
8
11
  import {
9
12
  getWindowOverlay,
@@ -12,6 +15,8 @@ import {
12
15
  } from "../shared/window-geometry";
13
16
  import { loadPluginConfig, loadPluginConfigDetailed } from "./index";
14
17
  import { resolveConfigProfile } from "./profiles";
18
+ import { getProtectedTokensTierOverrides } from "./project-security";
19
+ import { REMOVED_AGENT_CONFIG_WARNING } from "./removed-agent-config";
15
20
  import { DEFAULT_LOCAL_EMBEDDING_MODEL } from "./schema/magic-context";
16
21
  import { RUST_COMPACTION_OFF_WARNING } from "./transform-mode";
17
22
 
@@ -192,6 +197,49 @@ describe("loadPluginConfig — preload user-config isolation", () => {
192
197
  });
193
198
  });
194
199
 
200
+ describe("loadPluginConfig — parse failure diagnostics", () => {
201
+ it("recovers the reporter's stray leading character and keeps a loud location warning", () => {
202
+ const result = loadWithUserConfig('\\{\n "cache_ttl": "1h"\n}');
203
+
204
+ expect(result.cache_ttl).toBe("1h");
205
+ expect(result.configParseFailures).toHaveLength(1);
206
+ expect(result.configParseFailures?.[0]).toMatchObject({
207
+ warningClass: "file-parse",
208
+ line: 1,
209
+ column: 1,
210
+ recovered: true,
211
+ message: "invalid symbol",
212
+ });
213
+ expect(result.configWarnings?.[0]).toContain(":1:1: invalid symbol");
214
+ });
215
+
216
+ it("keeps file parse and invalid-leaf warning classes distinct", () => {
217
+ const parseResult = loadWithUserConfig('\\{\n "cache_ttl": "1h"\n}');
218
+ const leafResult = loadWithUserConfig('{"protected_tokens":"bogus"}');
219
+
220
+ expect(parseResult.configWarningDetails?.[0]?.warningClass).toBe("file-parse");
221
+ expect(
222
+ leafResult.configWarningDetails?.some(
223
+ (detail) => detail.warningClass === "invalid-leaf",
224
+ ),
225
+ ).toBe(true);
226
+ });
227
+
228
+ it("puts a recovered parse failure first in the OpenCode warning banner", () => {
229
+ const result = loadWithUserConfig('\\{\n "cache_ttl": "1h"\n}');
230
+ const failures = result.configParseFailures ?? [];
231
+ const banner = buildOpenCodeConfigWarningBanner(
232
+ result.configWarnings ?? [],
233
+ failures,
234
+ failures,
235
+ );
236
+
237
+ expect(banner).toStartWith("## ⚠️ Magic Context Config Warning");
238
+ expect(banner.indexOf("PARSE FAILED")).toBeLessThan(banner.indexOf("Fix the reported"));
239
+ expect(banner).toContain(":1:1");
240
+ });
241
+ });
242
+
195
243
  describe("loadPluginConfig — graduated mural config", () => {
196
244
  it("adopts legacy experimental.mural at the top-level and warns once", () => {
197
245
  const result = loadWithUserConfig(
@@ -703,18 +751,26 @@ describe("loadPluginConfig — legacy agent enabled migration", () => {
703
751
  expect(warnings).not.toContain("dreamer.enabled");
704
752
  });
705
753
 
706
- it("migrates sidekick.enabled=false (loud) and removes sidekick.enabled=true (silent)", () => {
707
- const disabled = loadWithUserConfig(JSON.stringify({ sidekick: { enabled: false } }));
708
- expect(disabled.sidekick?.disable).toBe(true);
709
- expect(disabled.configWarnings?.join("\n")).toContain(
710
- '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
+ }),
711
767
  );
712
768
 
713
- const enabled = loadWithUserConfig(JSON.stringify({ sidekick: { enabled: true } }));
714
- expect(enabled.sidekick?.disable).toBeUndefined();
715
- expect("enabled" in (enabled.sidekick as Record<string, unknown>)).toBe(false);
716
- const enabledWarnings = enabled.configWarnings?.join("\n") ?? "";
717
- 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
+ ]);
718
774
  });
719
775
 
720
776
  it("removes invalid historian.enabled and applies conflict rules", () => {
@@ -722,13 +778,11 @@ describe("loadPluginConfig — legacy agent enabled migration", () => {
722
778
  JSON.stringify({
723
779
  historian: { enabled: false },
724
780
  dreamer: { enabled: false, disable: false },
725
- sidekick: { enabled: true, disable: true },
726
781
  }),
727
782
  );
728
783
 
729
784
  expect(result.historian).toEqual({ two_pass: false, disallowed_tools: [] });
730
785
  expect(result.dreamer?.disable).toBe(true);
731
- expect(result.sidekick?.disable).toBe(true);
732
786
  expect(result.configWarnings?.join("\n")).toContain(
733
787
  'Removed invalid "historian.enabled" in-memory (run doctor to persist).',
734
788
  );
@@ -900,6 +954,109 @@ describe("loadPluginConfig — user-only settings", () => {
900
954
  });
901
955
 
902
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
+
903
1060
  it("ignores a lower project execute_threshold_percentage with a warning", () => {
904
1061
  const result = loadWithUserAndProjectConfig(
905
1062
  JSON.stringify({ execute_threshold_percentage: 60 }),
@@ -1132,7 +1289,6 @@ describe("loadPluginConfig — user-owned model profiles", () => {
1132
1289
  ],
1133
1290
  },
1134
1291
  },
1135
- sidekick: { model: "anthropic/work-sidekick" },
1136
1292
  },
1137
1293
  personal: {
1138
1294
  historian: { opencode: { model: "anthropic/personal-historian" } },
@@ -1156,7 +1312,6 @@ describe("loadPluginConfig — user-owned model profiles", () => {
1156
1312
  expect(result.dreamer?.opencode?.fallback_models).toEqual([
1157
1313
  { model: "openai/work-dreamer-fallback", variant: "medium" },
1158
1314
  ]);
1159
- expect(result.sidekick?.model).toBe("anthropic/work-sidekick");
1160
1315
  });
1161
1316
 
1162
1317
  it("uses project selection over user selection and falls back to the base on an unknown name", () => {
@@ -1,6 +1,15 @@
1
1
  import { existsSync } from "node:fs";
2
2
 
3
- import { detectConfigFile, isPrototypePollutionKey, parseJsonc } from "../shared/jsonc-parser";
3
+ import {
4
+ CONFIG_WARNING_CLASS,
5
+ type ConfigParseFailure,
6
+ type ConfigWarningDetail,
7
+ } from "../shared/config-diagnostics";
8
+ import {
9
+ detectConfigFile,
10
+ isPrototypePollutionKey,
11
+ parseJsoncRecovering,
12
+ } from "../shared/jsonc-parser";
4
13
  import { setOutputReserveConfig } from "../shared/models-dev-cache";
5
14
  import type { PromptSurfaceConfig } from "../shared/prompt-surface";
6
15
  import { setWindowOverlayPath } from "../shared/window-geometry";
@@ -16,18 +25,25 @@ import { migrateDreamerV2 } from "./migrate-dreamer-v2";
16
25
  import { migrateLegacyExperimental } from "./migrate-experimental";
17
26
  import { resolveConfigProfile } from "./profiles";
18
27
  import {
28
+ attachProtectedTokensTierOverrides,
19
29
  constrainProjectThresholdOverrides,
20
30
  dropInheritedEmbeddingKeyOnRedirect,
21
31
  stripUnsafeProjectConfigFields,
22
32
  } from "./project-security";
23
33
  import { pruneNestedConfigLeaf } from "./prune-config-leaf";
24
34
  import { loadRawConfigFile } from "./raw-loader";
35
+ import { stripRemovedAgentConfig } from "./removed-agent-config";
25
36
  import { type MagicContextConfig, MagicContextConfigSchema } from "./schema/magic-context";
26
37
  import { resolveTransformMode } from "./transform-mode";
27
38
  import { substituteConfigVariables } from "./variable";
28
39
 
29
40
  export interface MagicContextPluginConfig extends MagicContextConfig {
30
41
  disabled_hooks?: string[];
42
+ /** Runtime-only diagnostics; never read from user config. */
43
+ configParseFailures?: ConfigParseFailure[];
44
+ configWarningDetails?: ConfigWarningDetail[];
45
+ /** Whether cache_ttl existed in resolved raw config rather than coming from Zod defaults. */
46
+ cacheTtlConfigured?: boolean;
31
47
  command?: Record<
32
48
  string,
33
49
  {
@@ -74,6 +90,8 @@ interface LoadedConfigFile {
74
90
  config: Record<string, unknown>;
75
91
  /** Warnings from {env:} / {file:} substitution, with config-path prefix applied. */
76
92
  warnings: string[];
93
+ parseFailures: ConfigParseFailure[];
94
+ warningDetails: ConfigWarningDetail[];
77
95
  }
78
96
 
79
97
  export type LoadOutcome =
@@ -95,6 +113,9 @@ export interface LoadResultDetailed {
95
113
  };
96
114
  substitutionFailures: Array<{ keyPath: string; source: "user" | "project"; message: string }>;
97
115
  recoveredTopLevelKeys: string[];
116
+ configParseFailures: ConfigParseFailure[];
117
+ warningDetails: ConfigWarningDetail[];
118
+ cacheTtlConfigured: boolean;
98
119
  }
99
120
 
100
121
  interface LoadedConfigFileDetailed extends LoadedConfigFile {
@@ -118,10 +139,13 @@ function loadConfigFileDetailed(
118
139
  rawText = raw.text;
119
140
  rawWarnings = raw.warnings;
120
141
  } catch (error) {
142
+ const message = `failed to read config: ${error instanceof Error ? error.message : String(error)}`;
121
143
  return {
122
144
  config: {},
123
- warnings: [
124
- `${configPath}: failed to read config: ${error instanceof Error ? error.message : String(error)}`,
145
+ warnings: [`${configPath}: ${message}`],
146
+ parseFailures: [],
147
+ warningDetails: [
148
+ { warningClass: CONFIG_WARNING_CLASS.FILE_IO, source, path: configPath, message },
125
149
  ],
126
150
  outcome: "project-file-io-error",
127
151
  source,
@@ -135,32 +159,71 @@ function loadConfigFileDetailed(
135
159
  isProjectConfig: source === "project",
136
160
  });
137
161
  const rejectedKeyPaths: string[] = [];
138
- const config = parseJsonc<Record<string, unknown>>(substituted.text, {
162
+ const parsed = parseJsoncRecovering<Record<string, unknown>>(substituted.text, {
139
163
  onRejectedKey: (path) => rejectedKeyPaths.push(path.join(".")),
140
164
  });
165
+ const config =
166
+ parsed.value && typeof parsed.value === "object" && !Array.isArray(parsed.value)
167
+ ? parsed.value
168
+ : {};
141
169
  const unsafeKeyWarnings = rejectedKeyPaths.map(
142
170
  (path) =>
143
171
  `Ignored unsafe config key "${path}" (security: prototype-pollution keys are not allowed).`,
144
172
  );
173
+ const firstIssue = parsed.issues[0];
174
+ const recovered = firstIssue !== undefined && Object.keys(config).length > 0;
175
+ const parseFailures: ConfigParseFailure[] = firstIssue
176
+ ? [
177
+ {
178
+ warningClass: CONFIG_WARNING_CLASS.FILE_PARSE,
179
+ source,
180
+ path: configPath,
181
+ line: firstIssue.line,
182
+ column: firstIssue.column,
183
+ message: firstIssue.message,
184
+ recovered,
185
+ warning: `${configPath}:${firstIssue.line}:${firstIssue.column}: ${firstIssue.message}; ${recovered ? "recovered values were applied, but the file must be fixed." : "using defaults for this file."}`,
186
+ },
187
+ ]
188
+ : [];
145
189
  return {
146
190
  config,
147
- warnings: [...rawWarnings, ...substituted.warnings, ...unsafeKeyWarnings].map(
148
- (warning) => `${configPath}: ${warning}`,
149
- ),
191
+ warnings: [
192
+ ...parseFailures.map((failure) => failure.warning),
193
+ ...rawWarnings.map((warning) => `${configPath}: ${warning}`),
194
+ ...substituted.warnings.map((warning) => `${configPath}: ${warning}`),
195
+ ...unsafeKeyWarnings.map((warning) => `${configPath}: ${warning}`),
196
+ ],
197
+ parseFailures,
198
+ warningDetails: parseFailures,
150
199
  outcome:
151
- rejectedKeyPaths.length > 0
152
- ? "schema-recovery"
153
- : substituted.warnings.length > 0
154
- ? "substitution-failure"
155
- : "ok",
200
+ parseFailures.length > 0
201
+ ? "project-file-parse-error"
202
+ : rejectedKeyPaths.length > 0
203
+ ? "schema-recovery"
204
+ : substituted.warnings.length > 0
205
+ ? "substitution-failure"
206
+ : "ok",
156
207
  source,
157
208
  };
158
209
  } catch (error) {
210
+ const message = error instanceof Error ? error.message : String(error);
211
+ const warning = `${configPath}:1:1: ${message}; using defaults for this file.`;
212
+ const failure: ConfigParseFailure = {
213
+ warningClass: CONFIG_WARNING_CLASS.FILE_PARSE,
214
+ source,
215
+ path: configPath,
216
+ line: 1,
217
+ column: 1,
218
+ message,
219
+ recovered: false,
220
+ warning,
221
+ };
159
222
  return {
160
223
  config: {},
161
- warnings: [
162
- `${configPath}: failed to load config: ${error instanceof Error ? error.message : String(error)}`,
163
- ],
224
+ warnings: [warning],
225
+ parseFailures: [failure],
226
+ warningDetails: [failure],
164
227
  outcome: "project-file-parse-error",
165
228
  source,
166
229
  };
@@ -258,14 +321,39 @@ function redactConfigValue(value: unknown): string {
258
321
  return typeof value;
259
322
  }
260
323
 
261
- 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(
262
340
  rawConfig: Record<string, unknown>,
263
341
  recoveredTopLevelKeys: string[] = [],
264
342
  ): MagicContextPluginConfig & { configWarnings?: string[] } {
265
343
  // Pre-Zod shim: reshape legacy experimental.* graduated keys so the user's
266
344
  // opt-in/out state survives upgrades even when they never run `doctor`.
267
345
  const preMigrationWarnings: string[] = [];
268
- 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
+ );
269
357
  // Dreamer v2: convert the legacy v1 dreamer shape (window schedule, tasks
270
358
  // array, user_memories/pin_key_files blocks) into the per-task `tasks` record.
271
359
  // Runs AFTER migrate-experimental so experimental.user_memories (already
@@ -336,7 +424,7 @@ function parsePluginConfig(
336
424
  const patched: Record<string, unknown> = { ...rawConfig };
337
425
  for (const key of errorPaths) {
338
426
  recoveredTopLevelKeys.push(key);
339
- const isAgentConfig = key === "historian" || key === "dreamer" || key === "sidekick";
427
+ const isAgentConfig = key === "historian" || key === "dreamer";
340
428
 
341
429
  // For object-valued keys (including agent harness blocks), prune only invalid
342
430
  // nested leaves and keep valid siblings, so one bad field does not remove
@@ -549,6 +637,8 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
549
637
  : null;
550
638
 
551
639
  const allWarnings: string[] = [];
640
+ const removedConfigWarnings: string[] = [];
641
+ const userRaw = stripRemovedAgentConfig(userLoaded?.config ?? {}, removedConfigWarnings);
552
642
 
553
643
  if (userLegacyFallback.source) {
554
644
  allWarnings.push(
@@ -577,18 +667,20 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
577
667
  let projectRaw: Record<string, unknown> = {};
578
668
  if (projectLoaded) {
579
669
  allWarnings.push(...projectLoaded.warnings.map((w) => `[project config] ${w}`));
580
- projectRaw = { ...projectLoaded.config };
670
+ projectRaw = stripRemovedAgentConfig(projectLoaded.config, removedConfigWarnings);
581
671
  for (const warning of stripUnsafeProjectConfigFields(projectRaw)) {
582
672
  allWarnings.push(`[project config] ${warning}`);
583
673
  }
584
674
  }
585
675
 
676
+ allWarnings.push(...removedConfigWarnings.map((warning) => `[config] ${warning}`));
677
+
586
678
  // Resolve profiles at the single user→project merge choke point. The profile
587
679
  // definition is parsed from the trusted user tier, then its validated model
588
680
  // overlay is merged before the untrusted project config. The raw selector is
589
681
  // consumed here; only the resolved name remains as status metadata.
590
682
  const profileResolution = resolveConfigProfile({
591
- userRaw: userLoaded?.config ?? {},
683
+ userRaw,
592
684
  projectRaw,
593
685
  });
594
686
  allWarnings.push(...profileResolution.warnings.map((warning) => `[config] ${warning}`));
@@ -621,10 +713,16 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
621
713
  }
622
714
 
623
715
  const recoveredTopLevelKeys: string[] = [];
716
+ const cacheTtlConfigured = Object.hasOwn(mergedRaw, "cache_ttl");
624
717
  const config = parsePluginConfig(mergedRaw, recoveredTopLevelKeys);
718
+ attachProtectedTokensTierOverrides(config, {
719
+ trustedUser: trustedBaseConfig.protected_tokens,
720
+ project: projectLoaded ? profileResolution.projectBase.protected_tokens : undefined,
721
+ });
625
722
  if (profileResolution.activeProfile) config.profile = profileResolution.activeProfile;
626
723
  setOutputReserveConfig(config.output_reserve);
627
724
  setWindowOverlayPath(config.models?.window_overlay_path);
725
+ const leafValidationWarnings = [...(config.configWarnings ?? [])];
628
726
  if (config.configWarnings?.length) {
629
727
  allWarnings.push(
630
728
  ...config.configWarnings.map((w) => {
@@ -637,7 +735,7 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
637
735
 
638
736
  const resolvedTransformMode = resolveTransformMode({
639
737
  configured: config.transform_mode,
640
- userTierHasSubc: hasUserTierSubcConfig(userLoaded?.config),
738
+ userTierHasSubc: hasUserTierSubcConfig(userRaw),
641
739
  compactionEnabled: isCompactionEnabled(config),
642
740
  });
643
741
  config.transform_mode = resolvedTransformMode.mode;
@@ -653,6 +751,21 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
653
751
  ...bindSubstitutionFailures(userLoaded),
654
752
  ...bindSubstitutionFailures(projectLoaded),
655
753
  ];
754
+ const configParseFailures = [
755
+ ...(userLoaded?.parseFailures ?? []),
756
+ ...(projectLoaded?.parseFailures ?? []),
757
+ ];
758
+ const warningDetails: ConfigWarningDetail[] = [
759
+ ...(userLoaded?.warningDetails ?? []),
760
+ ...(projectLoaded?.warningDetails ?? []),
761
+ ...leafValidationWarnings.map((message) => ({
762
+ warningClass: CONFIG_WARNING_CLASS.INVALID_LEAF,
763
+ message,
764
+ })),
765
+ ];
766
+ config.configParseFailures = configParseFailures;
767
+ config.configWarningDetails = warningDetails;
768
+ config.cacheTtlConfigured = cacheTtlConfigured;
656
769
  const sources = {
657
770
  userConfig:
658
771
  userLoaded?.outcome ??
@@ -669,5 +782,8 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
669
782
  sources,
670
783
  substitutionFailures,
671
784
  recoveredTopLevelKeys,
785
+ configParseFailures,
786
+ warningDetails,
787
+ cacheTtlConfigured,
672
788
  };
673
789
  }
@@ -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.",
@@ -186,10 +186,10 @@ describe("migrateConfigFile (location migration)", () => {
186
186
  try {
187
187
  const target = join(dir, ".cortexkit", "magic-context.jsonc");
188
188
  mkdirSync(join(dir, ".cortexkit"), { recursive: true });
189
- writeFileSync(target, '{ "protected_tags": 5 }');
189
+ writeFileSync(target, '{ "cache_ttl": "5m" }');
190
190
  const legacy = join(dir, ".opencode", "magic-context.jsonc");
191
191
  mkdirSync(join(dir, ".opencode"), { recursive: true });
192
- writeFileSync(legacy, '{ "protected_tags": 9 }');
192
+ writeFileSync(legacy, '{ "cache_ttl": "9m" }');
193
193
 
194
194
  const r = migrateConfigFile({
195
195
  scope: "project",
@@ -201,8 +201,8 @@ describe("migrateConfigFile (location migration)", () => {
201
201
  expect(r.migrated).toBe(false);
202
202
  expect(r.warnings.join("\n")).toContain("already exists with different settings");
203
203
  // BOTH left as-is for manual reconciliation — never auto-clobbered.
204
- expect(readFileSync(target, "utf8")).toContain('"protected_tags": 5');
205
- expect(readFileSync(legacy, "utf8")).toContain('"protected_tags": 9');
204
+ expect(readFileSync(target, "utf8")).toContain('"cache_ttl": "5m"');
205
+ expect(readFileSync(legacy, "utf8")).toContain('"cache_ttl": "9m"');
206
206
  expect(existsSync(`${legacy}.MOVED_READPLEASE`)).toBe(false);
207
207
  } finally {
208
208
  rmSync(dir, { recursive: true, force: true });
@@ -216,8 +216,8 @@ describe("migrateConfigFile (location migration)", () => {
216
216
  const b = join(dir, ".pi", "magic-context.jsonc");
217
217
  mkdirSync(join(dir, ".opencode"), { recursive: true });
218
218
  mkdirSync(join(dir, ".pi"), { recursive: true });
219
- writeFileSync(a, '{ "protected_tags": 5 }');
220
- writeFileSync(b, '{ "protected_tags": 9 }');
219
+ writeFileSync(a, '{ "cache_ttl": "5m" }');
220
+ writeFileSync(b, '{ "cache_ttl": "9m" }');
221
221
  const target = join(dir, ".cortexkit", "magic-context.jsonc");
222
222
 
223
223
  const r = migrateConfigFile({
@@ -256,12 +256,45 @@ describe("migrateConfigFile (location migration)", () => {
256
256
 
257
257
  expect(r.migrated).toBe(true);
258
258
  expect(existsSync(target)).toBe(true);
259
+ expect(readFileSync(target, "utf8")).not.toContain("protected_tags");
259
260
  expect(existsSync(`${a}.MOVED_READPLEASE`)).toBe(true);
260
261
  expect(existsSync(`${b}.MOVED_READPLEASE`)).toBe(true);
261
262
  } finally {
262
263
  rmSync(dir, { recursive: true, force: true });
263
264
  }
264
265
  });
266
+
267
+ it("strips deprecated protected_tags key during migration to target with notice", () => {
268
+ const dir = tmp();
269
+ try {
270
+ const legacy = join(dir, "magic-context.jsonc");
271
+ writeFileSync(legacy, '{\n "protected_tags": 20,\n "cache_ttl": "15m"\n}\n');
272
+ const target = join(dir, ".cortexkit", "magic-context.jsonc");
273
+ const infos: string[] = [];
274
+ const r = migrateConfigFile({
275
+ scope: "project",
276
+ targetPath: target,
277
+ legacySources: [src(legacy)],
278
+ logger: {
279
+ info: (msg) => infos.push(msg),
280
+ warn: () => {},
281
+ },
282
+ });
283
+ expect(r.migrated).toBe(true);
284
+ const targetContent = readFileSync(target, "utf8");
285
+ expect(targetContent).not.toContain("protected_tags");
286
+ expect(targetContent).toContain('"cache_ttl": "15m"');
287
+ expect(
288
+ infos.some((msg) =>
289
+ msg.includes(
290
+ 'Stripped deprecated "protected_tags" key during config location migration',
291
+ ),
292
+ ),
293
+ ).toBe(true);
294
+ } finally {
295
+ rmSync(dir, { recursive: true, force: true });
296
+ }
297
+ });
265
298
  });
266
299
 
267
300
  describe("resolveLegacyConfigSources", () => {