mixdog 0.9.152 → 0.9.154

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 (300) hide show
  1. package/LICENSES/browser-import-NOTICE.txt +11 -0
  2. package/NOTICE.md +11 -0
  3. package/README.md +8 -10
  4. package/package.json +19 -3
  5. package/scripts/computer-task-cost-report.mjs +144 -0
  6. package/scripts/run-office-live-tests.mjs +32 -0
  7. package/src/agents/front-worker/AGENT.md +13 -0
  8. package/src/agents/front-worker/agent.json +6 -0
  9. package/src/agents/heavy-worker/AGENT.md +10 -11
  10. package/src/agents/heavy-worker/agent.json +1 -1
  11. package/src/agents/maintainer/AGENT.md +0 -2
  12. package/src/agents/reviewer/AGENT.md +9 -13
  13. package/src/agents/reviewer/agent.json +1 -1
  14. package/src/agents/security/AGENT.md +14 -0
  15. package/src/agents/security/agent.json +6 -0
  16. package/src/agents/worker/AGENT.md +8 -8
  17. package/src/agents/worker/agent.json +1 -1
  18. package/src/agents/writer/AGENT.md +14 -0
  19. package/src/agents/writer/agent.json +6 -0
  20. package/src/rules/agent/00-common.md +4 -7
  21. package/src/rules/lead/01-general.md +0 -3
  22. package/src/rules/shared/10-tool-workflow.md +10 -2
  23. package/src/rules/shared/60-verification.md +2 -0
  24. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +183 -26
  25. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +4 -0
  26. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +109 -0
  27. package/src/runtime/agent/orchestrator/config.mjs +7 -2
  28. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +16 -3
  29. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +9 -1
  30. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +30 -9
  31. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +18 -26
  32. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +25 -2
  33. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +103 -10
  34. package/src/runtime/agent/orchestrator/providers/openai-turn-state.mjs +68 -0
  35. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +36 -11
  36. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +140 -86
  37. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +9 -13
  38. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +72 -4
  39. package/src/runtime/agent/orchestrator/session/browser-snapshot-supersession.mjs +61 -0
  40. package/src/runtime/agent/orchestrator/session/compact/handoff.mjs +0 -22
  41. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -2
  42. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +11 -23
  43. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +28 -269
  44. package/src/runtime/agent/orchestrator/session/compact.mjs +0 -6
  45. package/src/runtime/agent/orchestrator/session/context-utils.mjs +86 -11
  46. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +17 -1
  47. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +12 -8
  48. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +110 -2
  49. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +3 -16
  50. package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +80 -18
  51. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +6 -0
  52. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +3 -0
  53. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +6 -0
  54. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +80 -21
  55. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +33 -72
  56. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +21 -2
  57. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +25 -51
  58. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +3 -0
  59. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -110
  60. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +39 -15
  61. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +14 -4
  62. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +41 -8
  63. package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +129 -12
  64. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +2 -2
  65. package/src/runtime/agent/orchestrator/session/store/listing.mjs +8 -1
  66. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +15 -1
  67. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +36 -2
  68. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +157 -30
  69. package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +57 -0
  70. package/src/runtime/agent/orchestrator/session/store.mjs +3 -1
  71. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +22 -0
  72. package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +6 -6
  73. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +4 -0
  74. package/src/runtime/attachments/pdf-extract.mjs +3 -0
  75. package/src/runtime/attachments/pdfjs-runtime.mjs +13 -0
  76. package/src/runtime/browser-bridge/action-schema.mjs +251 -0
  77. package/src/runtime/browser-bridge/client.mjs +75 -26
  78. package/src/runtime/browser-bridge/tool-defs.mjs +132 -15
  79. package/src/runtime/computer-bridge/action-schema.mjs +653 -0
  80. package/src/runtime/computer-bridge/client.mjs +211 -28
  81. package/src/runtime/computer-bridge/tool-defs.mjs +25 -45
  82. package/src/runtime/office/assurance-benchmark.mjs +358 -0
  83. package/src/runtime/office/assurance.mjs +833 -0
  84. package/src/runtime/office/benchmark.mjs +496 -0
  85. package/src/runtime/office/capabilities.mjs +551 -0
  86. package/src/runtime/office/com-adapter.mjs +283 -0
  87. package/src/runtime/office/content-model.mjs +183 -0
  88. package/src/runtime/office/contract-benchmark.mjs +105 -0
  89. package/src/runtime/office/design-library.mjs +1562 -0
  90. package/src/runtime/office/design-system.mjs +1966 -0
  91. package/src/runtime/office/index.mjs +2413 -0
  92. package/src/runtime/office/journal.mjs +82 -0
  93. package/src/runtime/office/office-com-host.ps1 +3781 -0
  94. package/src/runtime/office/office-com-session-host.ps1 +855 -0
  95. package/src/runtime/office/ooxml-validator.mjs +271 -0
  96. package/src/runtime/office/pagination.mjs +132 -0
  97. package/src/runtime/office/pdf-adapter.mjs +591 -0
  98. package/src/runtime/office/pdf-analysis.mjs +372 -0
  99. package/src/runtime/office/pdf-render.mjs +167 -0
  100. package/src/runtime/office/pdf-security.mjs +63 -0
  101. package/src/runtime/office/polish-benchmark.mjs +190 -0
  102. package/src/runtime/office/portable-ooxml.mjs +1867 -0
  103. package/src/runtime/office/quality-live-benchmark.mjs +486 -0
  104. package/src/runtime/office/quality-pipeline.mjs +136 -0
  105. package/src/runtime/office/tabular.mjs +302 -0
  106. package/src/runtime/office/templates/mixdog-executive.pptx +0 -0
  107. package/src/runtime/office/templates/mixdog-executive.pptx.mixdog.json +190 -0
  108. package/src/runtime/office/tool-defs.mjs +113 -0
  109. package/src/runtime/office/visual-diff.mjs +89 -0
  110. package/src/runtime/office/xlsx-assertions.mjs +172 -0
  111. package/src/runtime/office/xlsx-contract.mjs +147 -0
  112. package/src/runtime/shared/agent-route-config.mjs +9 -0
  113. package/src/runtime/shared/tool-execution-contract.mjs +16 -0
  114. package/src/runtime/shared/tool-surface.mjs +9 -0
  115. package/src/session-runtime/context-status.mjs +9 -3
  116. package/src/session-runtime/deferred-tool-delta.mjs +104 -0
  117. package/src/session-runtime/goal-runtime.mjs +617 -197
  118. package/src/session-runtime/lifecycle-api.mjs +50 -8
  119. package/src/session-runtime/provider-request-snapshot.mjs +33 -9
  120. package/src/session-runtime/resource-api.mjs +31 -94
  121. package/src/session-runtime/runtime-core.mjs +78 -26
  122. package/src/session-runtime/session-lifecycle.mjs +34 -12
  123. package/src/session-runtime/session-title.mjs +2 -2
  124. package/src/session-runtime/session-turn-api.mjs +15 -14
  125. package/src/session-runtime/tool-catalog-data.mjs +1 -1
  126. package/src/session-runtime/tool-catalog.mjs +38 -99
  127. package/src/session-runtime/tool-defs.mjs +6 -1
  128. package/src/session-runtime/tool-surface.mjs +18 -8
  129. package/src/session-runtime/workflow-agents-api.mjs +8 -25
  130. package/src/session-runtime/workflow.mjs +8 -6
  131. package/src/standalone/agent-tool/helpers.mjs +2 -2
  132. package/src/standalone/agent-tool/job-views.mjs +3 -1
  133. package/src/standalone/agent-tool/notify.mjs +5 -1
  134. package/src/standalone/agent-tool/render.mjs +3 -0
  135. package/src/standalone/agent-tool/spawn-flow.mjs +61 -16
  136. package/src/standalone/agent-tool/tool-def.mjs +1 -1
  137. package/src/standalone/agent-tool/worker-index.mjs +123 -0
  138. package/src/standalone/agent-tool/worker-rows.mjs +2 -1
  139. package/src/standalone/agent-tool.mjs +57 -10
  140. package/src/standalone/daemon.mjs +105 -6
  141. package/src/standalone/session-runtime-host.mjs +61 -48
  142. package/src/standalone/session-runtime-inline-host.mjs +34 -127
  143. package/src/standalone/session-runtime-worker.mjs +20 -198
  144. package/src/standalone/session-service.mjs +632 -7
  145. package/src/tui/dist/index.mjs +24 -1
  146. package/src/tui/lib/voice-setup.mjs +4 -1
  147. package/src/tui/session/context-state.mjs +2 -13
  148. package/src/tui/session/goal-continuation.mjs +38 -7
  149. package/src/tui/session/session-api-ext.mjs +9 -0
  150. package/src/tui/session/session-api.mjs +15 -1
  151. package/src/tui/session/session-flow.mjs +25 -1
  152. package/src/tui/session/turn.mjs +88 -16
  153. package/src/tui/session-local.mjs +25 -3
  154. package/src/vendor/statusline/src/gateway/route-meta.mjs +31 -0
  155. package/scripts/generate-voice-runtime-manifest.test.mjs +0 -135
  156. package/scripts/native-binary-arch.test.mjs +0 -111
  157. package/scripts/patch-replay.test.mjs +0 -94
  158. package/src/headless-exec.test.mjs +0 -539
  159. package/src/runtime/agent/orchestrator/agent-trace-timing.test.mjs +0 -57
  160. package/src/runtime/agent/orchestrator/context/collect-skills.test.mjs +0 -153
  161. package/src/runtime/agent/orchestrator/mcp/cancellation.test.mjs +0 -139
  162. package/src/runtime/agent/orchestrator/mcp/features.test.mjs +0 -66
  163. package/src/runtime/agent/orchestrator/mcp/security.test.mjs +0 -80
  164. package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.test.mjs +0 -90
  165. package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.test.mjs +0 -215
  166. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.test.mjs +0 -165
  167. package/src/runtime/agent/orchestrator/providers/media-parity.test.mjs +0 -142
  168. package/src/runtime/agent/orchestrator/providers/openai-codex-identity.test.mjs +0 -153
  169. package/src/runtime/agent/orchestrator/providers/openai-codex-model.test.mjs +0 -24
  170. package/src/runtime/agent/orchestrator/providers/openai-ws-delta-parity.test.mjs +0 -190
  171. package/src/runtime/agent/orchestrator/providers/provider-replay.test.mjs +0 -235
  172. package/src/runtime/agent/orchestrator/providers/sse-framing.test.mjs +0 -719
  173. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.test.mjs +0 -40
  174. package/src/runtime/agent/orchestrator/session/compact-policy.test.mjs +0 -176
  175. package/src/runtime/agent/orchestrator/session/compaction-read-reset.test.mjs +0 -161
  176. package/src/runtime/agent/orchestrator/session/eager-dispatch.test.mjs +0 -115
  177. package/src/runtime/agent/orchestrator/session/evidence-union.test.mjs +0 -228
  178. package/src/runtime/agent/orchestrator/session/image-strip-recovery.test.mjs +0 -245
  179. package/src/runtime/agent/orchestrator/session/lossless-tool-output.test.mjs +0 -125
  180. package/src/runtime/agent/orchestrator/session/manager/pending-messages-persistence.test.mjs +0 -325
  181. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.test.mjs +0 -70
  182. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.test.mjs +0 -457
  183. package/src/runtime/agent/orchestrator/session/provider-prefix-guard.test.mjs +0 -117
  184. package/src/runtime/agent/orchestrator/session/reduction-metrics.test.mjs +0 -87
  185. package/src/runtime/agent/orchestrator/session/store/serialize.test.mjs +0 -60
  186. package/src/runtime/agent/orchestrator/session/store-summary-reader.test.mjs +0 -583
  187. package/src/runtime/agent/orchestrator/session/task-wait-control.test.mjs +0 -78
  188. package/src/runtime/agent/orchestrator/tools/builtin/absence-absorption.test.mjs +0 -43
  189. package/src/runtime/agent/orchestrator/tools/builtin/absolute-glob-expand.test.mjs +0 -63
  190. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool-cwd-env.test.mjs +0 -14
  191. package/src/runtime/agent/orchestrator/tools/builtin/edit-encoding-eol.test.mjs +0 -224
  192. package/src/runtime/agent/orchestrator/tools/builtin/edit-sequential-occupation.test.mjs +0 -224
  193. package/src/runtime/agent/orchestrator/tools/builtin/enoent-outside-project.test.mjs +0 -56
  194. package/src/runtime/agent/orchestrator/tools/builtin/find-search-budget.test.mjs +0 -103
  195. package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.test.mjs +0 -30
  196. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.test.mjs +0 -390
  197. package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.test.mjs +0 -83
  198. package/src/runtime/agent/orchestrator/tools/builtin/grep-output-budget.test.mjs +0 -31
  199. package/src/runtime/agent/orchestrator/tools/builtin/grep-single-file-rescue.test.mjs +0 -106
  200. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.test.mjs +0 -102
  201. package/src/runtime/agent/orchestrator/tools/builtin/list-tool-integrity.test.mjs +0 -152
  202. package/src/runtime/agent/orchestrator/tools/builtin/native-search-health.test.mjs +0 -24
  203. package/src/runtime/agent/orchestrator/tools/builtin/native-search-transport.test.mjs +0 -24
  204. package/src/runtime/agent/orchestrator/tools/builtin/noise-dir-visibility.test.mjs +0 -69
  205. package/src/runtime/agent/orchestrator/tools/builtin/read-glob-survey.test.mjs +0 -71
  206. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.test.mjs +0 -56
  207. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.test.mjs +0 -16
  208. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-top-k.test.mjs +0 -39
  209. package/src/runtime/agent/orchestrator/tools/builtin/write-symlink.test.mjs +0 -153
  210. package/src/runtime/agent/orchestrator/tools/code-graph/aggregate-anchor-relocation.test.mjs +0 -55
  211. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.test.mjs +0 -88
  212. package/src/runtime/agent/orchestrator/tools/code-graph/loose-file-target.test.mjs +0 -72
  213. package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.test.mjs +0 -54
  214. package/src/runtime/agent/orchestrator/tools/code-graph/search-references.test.mjs +0 -20
  215. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-search-scope.test.mjs +0 -55
  216. package/src/runtime/agent/orchestrator/tools/code-graph/text-span-mask.test.mjs +0 -268
  217. package/src/runtime/agent/orchestrator/tools/env-scrub.test.mjs +0 -57
  218. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.test.mjs +0 -19
  219. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.test.mjs +0 -104
  220. package/src/runtime/agent/orchestrator/tools/patch/engine-contract-gate.test.mjs +0 -661
  221. package/src/runtime/agent/orchestrator/tools/patch/patch-codec-eol.test.mjs +0 -552
  222. package/src/runtime/agent/orchestrator/tools/patch/patch-symlink.test.mjs +0 -141
  223. package/src/runtime/agent/orchestrator/tools/patch/v4a-pure-move.test.mjs +0 -57
  224. package/src/runtime/agent/orchestrator/tools/patch/v4a-section-coalesce.test.mjs +0 -81
  225. package/src/runtime/agent/orchestrator/tools/spawn-binary-fetcher.test.mjs +0 -52
  226. package/src/runtime/attachments/store.test.mjs +0 -209
  227. package/src/runtime/channels/lib/voice-runtime-fetcher.test.mjs +0 -17
  228. package/src/runtime/channels/lib/webhook/deliveries.test.mjs +0 -18
  229. package/src/runtime/channels/lib/webhook/relay-tunnel.test.mjs +0 -68
  230. package/src/runtime/media/adapters/codex-image.test.mjs +0 -22
  231. package/src/runtime/media/download.test.mjs +0 -52
  232. package/src/runtime/media/renditions.test.mjs +0 -99
  233. package/src/runtime/media/store.test.mjs +0 -159
  234. package/src/runtime/memory/lib/archive-security.test.mjs +0 -128
  235. package/src/runtime/memory/lib/embedding-model-config.test.mjs +0 -33
  236. package/src/runtime/memory/lib/http-wire.test.mjs +0 -15
  237. package/src/runtime/memory/lib/memory-cycle-packets.test.mjs +0 -49
  238. package/src/runtime/memory/lib/memory-cycle2-shared.test.mjs +0 -78
  239. package/src/runtime/memory/lib/memory-embedding-migration.test.mjs +0 -50
  240. package/src/runtime/memory/lib/pg/process.test.mjs +0 -36
  241. package/src/runtime/memory/lib/trace-store.test.mjs +0 -57
  242. package/src/runtime/memory/lib/transcript-ingest.test.mjs +0 -52
  243. package/src/runtime/shared/background-tasks.test.mjs +0 -78
  244. package/src/runtime/shared/bounded-download.test.mjs +0 -41
  245. package/src/runtime/shared/channel-notification-routing.test.mjs +0 -25
  246. package/src/runtime/shared/child-spawn-remote.test.mjs +0 -124
  247. package/src/runtime/shared/remote-intent.test.mjs +0 -40
  248. package/src/runtime/shared/resource-admission.test.mjs +0 -43
  249. package/src/runtime/shared/runtime-root.test.mjs +0 -34
  250. package/src/runtime/shared/schedule-time.test.mjs +0 -29
  251. package/src/runtime/shared/session-runtime-health.test.mjs +0 -83
  252. package/src/runtime/shared/skill-document.test.mjs +0 -81
  253. package/src/runtime/shared/tool-surface.test.mjs +0 -87
  254. package/src/runtime/shared/update-checker.test.mjs +0 -33
  255. package/src/runtime/shared/user-cwd.test.mjs +0 -43
  256. package/src/runtime/shared/webhook-session-run.test.mjs +0 -14
  257. package/src/session-runtime/agent-disable.test.mjs +0 -123
  258. package/src/session-runtime/cwd-plugins.test.mjs +0 -75
  259. package/src/session-runtime/cwd-tool-routing.test.mjs +0 -61
  260. package/src/session-runtime/global-extensions.test.mjs +0 -28
  261. package/src/session-runtime/goal-runtime.test.mjs +0 -108
  262. package/src/session-runtime/lifecycle-api.test.mjs +0 -21
  263. package/src/session-runtime/model-settings-persist.test.mjs +0 -105
  264. package/src/session-runtime/notification-bus.test.mjs +0 -148
  265. package/src/session-runtime/plugin-mcp-standard.test.mjs +0 -177
  266. package/src/session-runtime/prewarm.test.mjs +0 -52
  267. package/src/session-runtime/provider-request-snapshot.test.mjs +0 -37
  268. package/src/session-runtime/resource-api-global.test.mjs +0 -69
  269. package/src/session-runtime/session-lifecycle.test.mjs +0 -125
  270. package/src/session-runtime/session-title.test.mjs +0 -36
  271. package/src/session-runtime/skills-api.test.mjs +0 -99
  272. package/src/session-runtime/tool-policy-surface.test.mjs +0 -331
  273. package/src/standalone/agent-tool/helpers.test.mjs +0 -62
  274. package/src/standalone/agent-tool/notify.test.mjs +0 -37
  275. package/src/standalone/agent-tool/spawn-flow.test.mjs +0 -63
  276. package/src/standalone/channel-restart.test.mjs +0 -145
  277. package/src/standalone/channel-session-router.test.mjs +0 -37
  278. package/src/standalone/channel-worker-heartbeat.test.mjs +0 -30
  279. package/src/standalone/hook-bus/handlers.test.mjs +0 -88
  280. package/src/standalone/plugin-admin.test.mjs +0 -173
  281. package/src/standalone/session-runtime-agent-control-client.test.mjs +0 -71
  282. package/src/standalone/session-runtime-dispatch-cancel.test.mjs +0 -139
  283. package/src/standalone/session-runtime-host-factory.test.mjs +0 -31
  284. package/src/standalone/session-runtime-host-health.test.mjs +0 -160
  285. package/src/standalone/session-runtime-inline-host.test.mjs +0 -83
  286. package/src/standalone/session-runtime-provider-cooldown.test.mjs +0 -80
  287. package/src/standalone/session-runtime-shard-host.test.mjs +0 -569
  288. package/src/standalone/session-runtime-shard-router.test.mjs +0 -101
  289. package/src/tui/app/live-spinner-visibility.test.mjs +0 -44
  290. package/src/tui/app/panel-epoch.test.mjs +0 -1009
  291. package/src/tui/app/panel-handoff.test.mjs +0 -311
  292. package/src/tui/app/prompt-submit.test.mjs +0 -206
  293. package/src/tui/session/completion-card-restore.test.mjs +0 -111
  294. package/src/tui/session/goal-continuation.test.mjs +0 -84
  295. package/src/tui/session/oauth-flows.test.mjs +0 -134
  296. package/src/tui/session/queue-helpers.test.mjs +0 -46
  297. package/src/tui/session/session-action-surface.test.mjs +0 -108
  298. package/src/tui/session/task-wait-submit.test.mjs +0 -80
  299. package/src/tui/session/tool-result-status.test.mjs +0 -131
  300. package/src/tui/session/tui-steering-persist.test.mjs +0 -104
@@ -1,6 +1,10 @@
1
1
  import { cancelBackgroundTasks } from '../runtime/shared/background-tasks.mjs';
2
2
  import { hasUserConversationMessage } from '../runtime/agent/orchestrator/session/manager/prompt-utils.mjs';
3
3
  import { isAgentOwner } from '../runtime/agent/orchestrator/agent-owner.mjs';
4
+ import {
5
+ isAgentOnlySession,
6
+ isRootLeadSession,
7
+ } from '../runtime/agent/orchestrator/session/store-summary-visibility.mjs';
4
8
  import { writeStatuslineRoute } from './statusline-route.mjs';
5
9
  import {
6
10
  sessionMessageText,
@@ -16,6 +20,7 @@ import {
16
20
  listSessionHeartbeatMtimes,
17
21
  } from '../runtime/agent/orchestrator/session/store/paths-heartbeat.mjs';
18
22
  import { SessionClosedError } from '../runtime/agent/orchestrator/session/manager/session-errors.mjs';
23
+ import { releaseComputerSession } from '../runtime/computer-bridge/client.mjs';
19
24
  import { saveSession } from '../runtime/agent/orchestrator/session/store.mjs';
20
25
 
21
26
  export function resolveResumeCwd(session, currentCwd) {
@@ -100,8 +105,14 @@ export function createLifecycleApi(deps) {
100
105
  return mgr.listSessions({
101
106
  refreshFromStorage: options?.refreshFromStorage === true,
102
107
  }).map(s => {
108
+ // Durable visibility is the catalog boundary. Apply it before the legacy
109
+ // lead-shape heuristics so an explicitly agent-only child cannot leak just
110
+ // because its owner field looks ordinary.
111
+ if (isAgentOnlySession(s)) return null;
103
112
  const owner = clean(s.owner || 'user').toLowerCase();
104
- if (owner && !['cli', 'user', 'mixdog'].includes(owner)) return null;
113
+ // A root Lead can carry Agent ownership plus a self-link after recovery;
114
+ // it remains an ordinary resumable session, not a child dispatch.
115
+ if (!isRootLeadSession(s) && owner && !['cli', 'user', 'mixdog'].includes(owner)) return null;
105
116
  const sourceType = clean(s.sourceType || '').toLowerCase();
106
117
  const sourceName = clean(s.sourceName || '').toLowerCase();
107
118
  const agent = clean(s.agent || '').toLowerCase();
@@ -192,6 +203,17 @@ export function createLifecycleApi(deps) {
192
203
  } catch { /* best-effort: memory ingest must never break lifecycle paths */ }
193
204
  }
194
205
  return {
206
+ /** Plant the ordinary manager/store tombstone barrier for a canonical
207
+ * child session without running whole-process teardown. */
208
+ closeCanonicalSession(reason = 'canonical-session-close') {
209
+ const session = getSession?.();
210
+ if (!session?.id || session.remoteAttached === true) return false;
211
+ const closed = mgr.closeSession(session.id, reason, { tombstone: true }) === true;
212
+ if (!closed) return false;
213
+ setSession?.(null);
214
+ invalidateContextStatusCache?.();
215
+ return true;
216
+ },
195
217
  async close(reason = 'cli-exit', options = {}) {
196
218
  const detach = options?.detach === true || options?.wait === false || options?.waitForExit === false;
197
219
  // Desktop multi-engine hosts dispose idle engines while other sessions
@@ -365,11 +387,18 @@ export function createLifecycleApi(deps) {
365
387
  .then(() => closeNativeToolTransports?.(reason))
366
388
  .catch(() => {})
367
389
  : null;
390
+ // Computer Use pins a host-side worker plus window claims for the closing
391
+ // session, and the runtime's deferred release timer is unref'd. A real
392
+ // teardown releases them here; a keepBackgroundWork eviction leaves the
393
+ // lease to that timer so a re-materialized session keeps its refs.
394
+ const computerStop = teardownReapsWork && closingSessionId
395
+ ? Promise.resolve(releaseComputerSession(closingSessionId)).catch(() => false)
396
+ : null;
368
397
  if (detach) {
369
398
  try { await withTeardownDeadline(channelStop, 300, false); } catch {}
370
399
  try { await withTeardownDeadline(shellJobsStop, 300, false); } catch {}
371
400
  try { await withTeardownDeadline(memoryStop, 1500, false); } catch {}
372
- for (const stop of [mcpStop, openaiWsStop, patchStop, nativeToolStop]) {
401
+ for (const stop of [mcpStop, openaiWsStop, patchStop, nativeToolStop, computerStop]) {
373
402
  Promise.resolve(stop).catch(() => {});
374
403
  }
375
404
  onProcessExit();
@@ -383,6 +412,7 @@ export function createLifecycleApi(deps) {
383
412
  withTeardownDeadline(memoryStop, 5500, false),
384
413
  withTeardownDeadline(shellJobsStop, 1500, false),
385
414
  withTeardownDeadline(nativeToolStop, 1500, false),
415
+ withTeardownDeadline(computerStop, 1500, false),
386
416
  ]);
387
417
  onProcessExit();
388
418
  return ok;
@@ -573,6 +603,23 @@ export function createLifecycleApi(deps) {
573
603
  },
574
604
  );
575
605
  setRoute(resumedRoute);
606
+ // resumeSession refreshes only the bootstrap/base bundle. Reapply the
607
+ // persisted deferred selection synchronously with current definitions
608
+ // before this resume becomes observable; waiting for asynchronous route
609
+ // preparation temporarily dropped loaded tools and invalidated the
610
+ // provider-aligned context baseline.
611
+ const restoreResumedToolSurface = (target, targetRoute) => {
612
+ applyDeferredToolSurface(
613
+ target,
614
+ deferredSurfaceModeForLead(getMode()),
615
+ getStandaloneTools(),
616
+ {
617
+ provider: targetRoute.provider,
618
+ model: targetRoute.model,
619
+ },
620
+ );
621
+ };
622
+ restoreResumedToolSurface(resumed, resumedRoute);
576
623
  const finishRoutePreparation = async () => {
577
624
  const preparedRoute = await refreshRouteEffort(null, resumedRoute);
578
625
  // Session or route changed while provider metadata was loading.
@@ -581,12 +628,7 @@ export function createLifecycleApi(deps) {
581
628
  activeSession.effort = getRoute().effectiveEffort || null;
582
629
  activeSession.fast = getRoute().fast === true;
583
630
  activeSession.cwd = getCurrentCwd();
584
- applyDeferredToolSurface(
585
- activeSession,
586
- deferredSurfaceModeForLead(getMode()),
587
- getStandaloneTools(),
588
- { provider: getRoute().provider },
589
- );
631
+ restoreResumedToolSurface(activeSession, getRoute());
590
632
  writeStatuslineRoute(statusRoutes, activeSession, getRoute());
591
633
  return true;
592
634
  };
@@ -1,5 +1,5 @@
1
1
  // Provider request-tool resolution + JSON-safe snapshot machinery, extracted from tool-catalog.mjs.
2
- import { clean, LATE_TOOL_ANNOUNCEMENT_SENTINEL } from './session-text.mjs';
2
+ import { clean } from './session-text.mjs';
3
3
  import { estimateToolSchemaTokens, toolSchemaSignature } from '../runtime/agent/orchestrator/session/context-utils.mjs';
4
4
  import {
5
5
  applyInitialDeferredToolManifestToBp2,
@@ -50,7 +50,15 @@ export function resolveProviderRequestTools({
50
50
  }
51
51
  if (discovered.size === 0) return activeTools;
52
52
  const activeNames = new Set(activeTools.map((tool) => clean(tool?.name)).filter(Boolean));
53
- const catalog = Array.isArray(session?.deferredToolCatalog) ? session.deferredToolCatalog : [];
53
+ const catalogByName = new Map();
54
+ for (const tool of [
55
+ ...(Array.isArray(session?.deferredToolCatalog) ? session.deferredToolCatalog : []),
56
+ ...(Array.isArray(session?.deferredLateToolCatalog) ? session.deferredLateToolCatalog : []),
57
+ ]) {
58
+ const name = clean(tool?.name);
59
+ if (name) catalogByName.set(name, tool);
60
+ }
61
+ const catalog = [...catalogByName.values()];
54
62
  const deferredTools = catalog
55
63
  .filter((tool) => {
56
64
  const name = clean(tool?.name);
@@ -306,15 +314,31 @@ export function snapshotProviderRequestTools(options = {}) {
306
314
  || names.size === 0) {
307
315
  return finish();
308
316
  }
309
- // Anthropic tools precede every cache_control breakpoint. Adding a schema
310
- // after tool_search therefore invalidates the whole provider cache prefix.
311
- // Send the complete defer_loading catalog from the first request instead;
312
- // tool_search controls callability, not provider-visible schema membership.
317
+ const discovered = new Set(
318
+ parseToolSelection(session?.deferredDiscoveredTools),
319
+ );
320
+ for (const message of Array.isArray(messages) ? messages : []) {
321
+ const native = message?.nativeToolSearch;
322
+ const source = clean(native?.provider).toLowerCase();
323
+ if (source && source !== normalizedProvider
324
+ && !(ANTHROPIC_NATIVE_PROVIDERS.has(source)
325
+ && ANTHROPIC_NATIVE_PROVIDERS.has(normalizedProvider))) continue;
326
+ for (const name of parseToolSelection(native?.toolReferences)) discovered.add(name);
327
+ }
328
+ if (discovered.size === 0) return finish();
329
+ // Claude-compatible deferred loading: the catalog stays metadata-only until
330
+ // tool_search/load_tool selects a name. Only selected schemas join the next
331
+ // request, marked defer_loading; active schemas continue to win by name.
313
332
  const seenCatalogRefs = new WeakSet();
314
- const catalog = [
333
+ const catalogByName = new Map();
334
+ for (const tool of [
315
335
  ...(Array.isArray(session?.deferredToolCatalog) ? session.deferredToolCatalog : []),
316
336
  ...(Array.isArray(session?.deferredLateToolCatalog) ? session.deferredLateToolCatalog : []),
317
- ];
337
+ ]) {
338
+ const name = clean(tool?.name);
339
+ if (name) catalogByName.set(name, tool);
340
+ }
341
+ const catalog = [...catalogByName.values()];
318
342
  for (const tool of catalog) {
319
343
  if (tool && typeof tool === 'object') {
320
344
  if (activeCandidateRefs.has(tool) || seenCatalogRefs.has(tool)) continue;
@@ -322,7 +346,7 @@ export function snapshotProviderRequestTools(options = {}) {
322
346
  }
323
347
  const capturedName = tool?.name;
324
348
  const selectionName = typeof capturedName === 'string' ? clean(capturedName) : '';
325
- if (!selectionName || names.has(selectionName)) continue;
349
+ if (!selectionName || !discovered.has(selectionName) || names.has(selectionName)) continue;
326
350
  appendSnapshot(tool, capturedName, true);
327
351
  }
328
352
  return finish();
@@ -5,7 +5,6 @@ import {
5
5
  toolResponseText,
6
6
  isEmptyRecallText,
7
7
  currentSessionRecallRows,
8
- tombstoneOnClose,
9
8
  } from './session-text.mjs';
10
9
  import {
11
10
  publishGlobalExtensionChange,
@@ -31,41 +30,30 @@ import {
31
30
  // and the runtime injects live state getters plus the closure callbacks.
32
31
  export function createResourceApi(deps) {
33
32
  const {
34
- getConfig, getSession, getCurrentCwd,
35
- cfgMod, mgr, hooks, STANDALONE_DATA_DIR,
33
+ getConfig, getCurrentCwd,
34
+ cfgMod, hooks, STANDALONE_DATA_DIR,
36
35
  saveConfigAndAdopt, connectConfiguredMcp, invalidatePreSessionToolSurface,
37
- recreateCurrentSessionIfReady, normalizeMcpServerInput, mcpStatus, getMcpServerConfig,
36
+ refreshEmptySessionToolPolicy, normalizeMcpServerInput, mcpStatus, getMcpServerConfig,
38
37
  skillsStatus, skillContent, addGlobalSkill, saveSkillDocument, invalidateSkills,
39
38
  getDisabledSkills, setDisabledSkills, pluginsStatus, getMemoryModule,
40
- reloadFullConfig, flushSkillsSave, awaitKeychainPrewarm, getActiveTurnCount,
39
+ reloadFullConfig, flushSkillsSave, awaitKeychainPrewarm,
41
40
  } = deps;
42
41
  // Per-server MCP toggle serialization. The synchronous config adopt in
43
42
  // setMcpServerEnabled has already made the intent durable; the heavy
44
- // connectConfiguredMcp (process spawn/handshake) + session close/recreate
45
- // run here off the toggle's critical path. Rapid re-toggles on one server
43
+ // connectConfiguredMcp process spawn/handshake runs here off the toggle's
44
+ // critical path. Rapid re-toggles on one server
46
45
  // update `desired` and ride the in-flight chain so it converges to the last
47
- // requested state, closing/recreating the session only once at the end.
46
+ // requested state without replacing any addressed session.
48
47
  const mcpToggleChains = new Map(); // name -> { desired, running }
49
- let globalRefreshTimer = null;
50
- function applyGlobalExtensionRecreate(kind) {
51
- if (typeof getActiveTurnCount === 'function' && getActiveTurnCount() > 0) {
52
- if (!globalRefreshTimer) {
53
- globalRefreshTimer = setTimeout(() => {
54
- globalRefreshTimer = null;
55
- applyGlobalExtensionRecreate(kind);
56
- }, 250);
57
- globalRefreshTimer.unref?.();
58
- }
59
- return;
60
- }
48
+ async function refreshGlobalExtensionSurface(kind) {
61
49
  invalidatePreSessionToolSurface();
62
- const session = getSession();
63
- if (session?.id) {
64
- mgr.closeSession(session.id, `global-${kind}-refresh`, { tombstone: tombstoneOnClose(session) });
50
+ // Existing conversations retain their stable prompt/session identity.
51
+ // Empty sessions can safely rebuild their policy in place; MCP has its own
52
+ // first-turn/late-tool reconciliation against the live connection registry.
53
+ if ((kind === 'skills' || kind === 'plugins')
54
+ && typeof refreshEmptySessionToolPolicy === 'function') {
55
+ await refreshEmptySessionToolPolicy();
65
56
  }
66
- void recreateCurrentSessionIfReady().catch((err) => {
67
- process.stderr.write(`[extensions] session recreate failed: ${err?.message || err}\n`);
68
- });
69
57
  }
70
58
  async function refreshGlobalExtensionState(kind) {
71
59
  reloadFullConfig?.();
@@ -73,30 +61,12 @@ export function createResourceApi(deps) {
73
61
  if (kind === 'mcp' || kind === 'plugins') {
74
62
  await connectConfiguredMcp({ reset: true });
75
63
  }
76
- applyGlobalExtensionRecreate(kind);
64
+ await refreshGlobalExtensionSurface(kind);
77
65
  }
78
66
  const globalExtensionSubscription = subscribeGlobalExtensionChanges(refreshGlobalExtensionState);
79
67
  const publishGlobalChange = (kind) => (
80
68
  publishGlobalExtensionChange(kind, globalExtensionSubscription.id)
81
69
  );
82
- // Close/recreate the live session only at a turn boundary: a background
83
- // toggle must never abort an in-flight turn. If a turn is active, poll until
84
- // it ends, then swap the session so it picks up the new tool surface.
85
- function applyMcpToggleRecreate(serverName) {
86
- if (typeof getActiveTurnCount === 'function' && getActiveTurnCount() > 0) {
87
- const timer = setTimeout(() => applyMcpToggleRecreate(serverName), 250);
88
- timer.unref?.();
89
- return;
90
- }
91
- invalidatePreSessionToolSurface();
92
- const session = getSession();
93
- if (session?.id) mgr.closeSession(session.id, 'cli-mcp-toggle', { tombstone: tombstoneOnClose(session) });
94
- // Recreate off the critical path (see removeMcpServer notes): the next
95
- // on-demand createCurrentSession dedupes onto this in-flight create.
96
- void recreateCurrentSessionIfReady().catch((err) => {
97
- process.stderr.write(`[mcp] session recreate after toggle failed: ${err?.message || err}\n`);
98
- });
99
- }
100
70
  function scheduleMcpToggle(serverName, enabled) {
101
71
  const chain = mcpToggleChains.get(serverName) || { desired: enabled, running: null };
102
72
  chain.desired = enabled;
@@ -110,8 +80,7 @@ export function createResourceApi(deps) {
110
80
  want = chain.desired;
111
81
  status = await connectConfiguredMcp({ only: serverName, enabled: want });
112
82
  } while (chain.desired !== want);
113
- // Turn-safe: defers until any active turn ends (never aborts it).
114
- applyMcpToggleRecreate(serverName);
83
+ await refreshGlobalExtensionSurface('mcp');
115
84
  } finally {
116
85
  chain.running = null;
117
86
  }
@@ -149,10 +118,7 @@ export function createResourceApi(deps) {
149
118
  await awaitKeychainPrewarm();
150
119
  reloadFullConfig();
151
120
  const status = await connectConfiguredMcp({ reset: true });
152
- invalidatePreSessionToolSurface();
153
- const session = getSession();
154
- if (session?.id) mgr.closeSession(session.id, 'cli-mcp-reconnect', { tombstone: tombstoneOnClose(session) });
155
- await recreateCurrentSessionIfReady();
121
+ await refreshGlobalExtensionSurface('mcp');
156
122
  await publishGlobalChange('mcp');
157
123
  return status;
158
124
  },
@@ -166,10 +132,7 @@ export function createResourceApi(deps) {
166
132
  };
167
133
  saveConfigAndAdopt(nextConfig);
168
134
  const status = await connectConfiguredMcp({ reset: true });
169
- invalidatePreSessionToolSurface();
170
- const session = getSession();
171
- if (session?.id) mgr.closeSession(session.id, 'cli-mcp-add', { tombstone: tombstoneOnClose(session) });
172
- await recreateCurrentSessionIfReady();
135
+ await refreshGlobalExtensionSurface('mcp');
173
136
  await publishGlobalChange('mcp');
174
137
  return { name, status };
175
138
  },
@@ -197,10 +160,7 @@ export function createResourceApi(deps) {
197
160
  nextConfig.mcpServers = servers;
198
161
  saveConfigAndAdopt(nextConfig);
199
162
  const status = await connectConfiguredMcp({ reset: true });
200
- invalidatePreSessionToolSurface();
201
- const session = getSession();
202
- if (session?.id) mgr.closeSession(session.id, 'cli-mcp-save', { tombstone: tombstoneOnClose(session) });
203
- await recreateCurrentSessionIfReady();
163
+ await refreshGlobalExtensionSurface('mcp');
204
164
  await publishGlobalChange('mcp');
205
165
  return { name, source: 'config', status };
206
166
  },
@@ -218,10 +178,7 @@ export function createResourceApi(deps) {
218
178
  delete nextConfig.mcpProjectOverrides;
219
179
  saveConfigAndAdopt({ ...nextConfig, mcpServers: current });
220
180
  const status = await connectConfiguredMcp({ reset: true });
221
- invalidatePreSessionToolSurface();
222
- const session = getSession();
223
- if (session?.id) mgr.closeSession(session.id, 'cli-mcp-remove', { tombstone: tombstoneOnClose(session) });
224
- await recreateCurrentSessionIfReady();
181
+ await refreshGlobalExtensionSurface('mcp');
225
182
  await publishGlobalChange('mcp');
226
183
  return status;
227
184
  },
@@ -255,9 +212,7 @@ export function createResourceApi(deps) {
255
212
  async addSkill(input = {}) {
256
213
  const skill = addGlobalSkill(input);
257
214
  invalidateSkills?.();
258
- const session = getSession();
259
- if (session?.id) mgr.closeSession(session.id, 'cli-skill-add', { tombstone: tombstoneOnClose(session) });
260
- await recreateCurrentSessionIfReady();
215
+ await refreshGlobalExtensionSurface('skills');
261
216
  await publishGlobalChange('skills');
262
217
  return { skill, status: skillsStatus() };
263
218
  },
@@ -271,9 +226,7 @@ export function createResourceApi(deps) {
271
226
  flushSkillsSave?.();
272
227
  }
273
228
  }
274
- const session = getSession();
275
- if (session?.id) mgr.closeSession(session.id, 'cli-skill-save', { tombstone: tombstoneOnClose(session) });
276
- await recreateCurrentSessionIfReady();
229
+ await refreshGlobalExtensionSurface('skills');
277
230
  await publishGlobalChange('skills');
278
231
  return { skill, status: skillsStatus() };
279
232
  },
@@ -281,15 +234,13 @@ export function createResourceApi(deps) {
281
234
  const result = setDisabledSkills?.(names);
282
235
  flushSkillsSave?.();
283
236
  invalidateSkills?.();
284
- applyGlobalExtensionRecreate('skills');
237
+ await refreshGlobalExtensionSurface('skills');
285
238
  await publishGlobalChange('skills');
286
239
  return result;
287
240
  },
288
241
  async reloadSkills() {
289
242
  invalidateSkills?.();
290
- const session = getSession();
291
- if (session?.id) mgr.closeSession(session.id, 'cli-skills-reload', { tombstone: tombstoneOnClose(session) });
292
- await recreateCurrentSessionIfReady();
243
+ await refreshGlobalExtensionSurface('skills');
293
244
  await publishGlobalChange('skills');
294
245
  return skillsStatus();
295
246
  },
@@ -297,9 +248,8 @@ export function createResourceApi(deps) {
297
248
  return pluginsStatus();
298
249
  },
299
250
  async reloadPlugins() {
300
- const session = getSession();
301
- if (session?.id) mgr.closeSession(session.id, 'cli-plugins-reload', { tombstone: tombstoneOnClose(session) });
302
- await recreateCurrentSessionIfReady();
251
+ invalidateSkills?.();
252
+ await refreshGlobalExtensionSurface('plugins');
303
253
  await publishGlobalChange('plugins');
304
254
  return pluginsStatus();
305
255
  },
@@ -307,9 +257,7 @@ export function createResourceApi(deps) {
307
257
  const dataDir = cfgMod.getPluginData?.();
308
258
  const plugin = registryAddPlugin(source, { dataDir });
309
259
  invalidateSkills?.();
310
- const session = getSession();
311
- if (session?.id) mgr.closeSession(session.id, 'cli-plugin-add', { tombstone: tombstoneOnClose(session) });
312
- await recreateCurrentSessionIfReady();
260
+ await refreshGlobalExtensionSurface('plugins');
313
261
  await publishGlobalChange('plugins');
314
262
  return { plugin, status: pluginsStatus() };
315
263
  },
@@ -318,9 +266,7 @@ export function createResourceApi(deps) {
318
266
  const dataDir = cfgMod.getPluginData?.();
319
267
  const updated = registryUpdatePlugin(key, { dataDir });
320
268
  invalidateSkills?.();
321
- const session = getSession();
322
- if (session?.id) mgr.closeSession(session.id, 'cli-plugin-update', { tombstone: tombstoneOnClose(session) });
323
- await recreateCurrentSessionIfReady();
269
+ await refreshGlobalExtensionSurface('plugins');
324
270
  await publishGlobalChange('plugins');
325
271
  return { plugin: updated, status: pluginsStatus() };
326
272
  },
@@ -353,9 +299,7 @@ export function createResourceApi(deps) {
353
299
  invalidatePreSessionToolSurface();
354
300
  }
355
301
  invalidateSkills?.();
356
- const session = getSession();
357
- if (session?.id) mgr.closeSession(session.id, 'cli-plugin-toggle', { tombstone: tombstoneOnClose(session) });
358
- await recreateCurrentSessionIfReady();
302
+ await refreshGlobalExtensionSurface('plugins');
359
303
  await publishGlobalChange('plugins');
360
304
  return { plugin: updated, status: pluginsStatus() };
361
305
  },
@@ -379,9 +323,7 @@ export function createResourceApi(deps) {
379
323
  invalidatePreSessionToolSurface();
380
324
  }
381
325
  invalidateSkills?.();
382
- const session = getSession();
383
- if (session?.id) mgr.closeSession(session.id, 'cli-plugin-remove', { tombstone: tombstoneOnClose(session) });
384
- await recreateCurrentSessionIfReady();
326
+ await refreshGlobalExtensionSurface('plugins');
385
327
  await publishGlobalChange('plugins');
386
328
  return { plugin: removed, status: pluginsStatus() };
387
329
  },
@@ -435,16 +377,11 @@ export function createResourceApi(deps) {
435
377
  }
436
378
  saveConfigAndAdopt(nextConfig);
437
379
  const status = await connectConfiguredMcp({ reset: true });
438
- invalidatePreSessionToolSurface();
439
- const session = getSession();
440
- if (session?.id) mgr.closeSession(session.id, 'cli-plugin-mcp-enable', { tombstone: tombstoneOnClose(session) });
441
- await recreateCurrentSessionIfReady();
380
+ await refreshGlobalExtensionSurface('mcp');
442
381
  await publishGlobalChange('mcp');
443
382
  return { serverName, status };
444
383
  },
445
384
  disposeGlobalExtensionSubscription() {
446
- if (globalRefreshTimer) clearTimeout(globalRefreshTimer);
447
- globalRefreshTimer = null;
448
385
  globalExtensionSubscription.unsubscribe();
449
386
  },
450
387
  hooksStatus() {