mixdog 1.1.2 → 1.2.1

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 (424) hide show
  1. package/README.md +8 -5
  2. package/package.json +2 -1
  3. package/scripts/lib/run-node-tests.mjs +9 -0
  4. package/scripts/prune-desktop-runtime.mjs +3 -0
  5. package/scripts/test-direct.mjs +4 -2
  6. package/src/defaults/shipped-history.json +10 -0
  7. package/src/defaults/skills/pptx/SKILL.md +6 -6
  8. package/src/defaults/skills/pptx/references/review.md +6 -4
  9. package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
  10. package/src/defaults/skills/setup/references/actions.md +18 -5
  11. package/src/defaults/skills/visualize/SKILL.md +160 -0
  12. package/src/defaults/skills/visualize/references/craft.md +88 -0
  13. package/src/headless-command.mjs +56 -3
  14. package/src/headless-exec.mjs +17 -1
  15. package/src/help.mjs +2 -0
  16. package/src/rules/shared/60-verification.md +3 -1
  17. package/src/rules/shared/70-delivery.md +4 -2
  18. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  19. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +1 -0
  20. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +2 -0
  21. package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
  22. package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
  23. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +17 -11
  24. package/src/runtime/agent/orchestrator/config-storage.mjs +1 -0
  25. package/src/runtime/agent/orchestrator/config.mjs +19 -5
  26. package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
  27. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
  28. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
  29. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +133 -15
  30. package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +55 -8
  31. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +86 -8
  32. package/src/runtime/agent/orchestrator/mcp/client.mjs +474 -164
  33. package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
  34. package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
  35. package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
  36. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +108 -17
  37. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  38. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
  39. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -1
  40. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -12
  41. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
  42. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
  43. package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
  44. package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
  45. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +444 -0
  46. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
  47. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  48. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
  49. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
  50. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +21 -6
  51. package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
  52. package/src/runtime/agent/orchestrator/providers/gemini.mjs +41 -28
  53. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  54. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
  55. package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
  56. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +8 -40
  57. package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +2 -0
  58. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +51 -12
  59. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +37 -2
  60. package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
  61. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +82 -0
  62. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +556 -0
  63. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +251 -0
  64. package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +2 -0
  65. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +69 -102
  66. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +15 -0
  67. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
  68. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -1
  69. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +6 -2
  70. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
  71. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +2 -1
  72. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +15 -4
  73. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +1 -1
  74. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +5 -2
  75. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +3 -0
  76. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +4 -4
  77. package/src/runtime/agent/orchestrator/providers/registry.mjs +47 -7
  78. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +10 -0
  79. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +36 -3
  80. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -11
  81. package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
  82. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
  83. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +16 -1
  84. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +278 -84
  85. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
  86. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
  87. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
  88. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -3
  89. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -0
  90. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +9 -5
  91. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +18 -8
  92. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
  93. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +268 -0
  94. package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
  95. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
  96. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +10 -3
  97. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +24 -13
  98. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +13 -5
  99. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +362 -0
  100. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +253 -0
  101. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
  102. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
  103. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
  104. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
  105. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
  106. package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
  107. package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
  108. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
  109. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
  110. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +1 -1
  111. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/diagnostic.mjs +1 -7
  112. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/refusal.mjs +1 -1
  113. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +3 -2
  114. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +5 -3
  115. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +7 -4
  116. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +21 -10
  117. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
  118. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
  119. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -3
  120. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +15 -3
  121. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +22 -12
  122. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +9 -2
  123. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +9 -3
  124. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +5 -2
  125. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +37 -16
  126. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +4 -0
  127. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +17 -4
  128. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +90 -0
  129. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +22 -12
  130. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +32 -3
  131. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +27 -0
  132. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -1
  133. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
  134. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +2 -0
  135. package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
  136. package/src/runtime/agent/orchestrator/session/message-ids.mjs +123 -0
  137. package/src/runtime/agent/orchestrator/session/message-ids.test-support.mjs +29 -0
  138. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +33 -22
  139. package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
  140. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -0
  141. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
  142. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +10 -3
  143. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +11 -0
  144. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +817 -0
  145. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +36 -0
  146. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +23 -12
  147. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
  148. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +202 -374
  149. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
  150. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
  151. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
  152. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +48 -9
  153. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +161 -0
  154. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
  155. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
  156. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +52 -2
  157. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +32 -22
  158. package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +10 -3
  159. package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
  160. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
  161. package/src/runtime/agent/orchestrator/tools/builtin/read-cache-policy.mjs +8 -0
  162. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +203 -33
  163. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
  164. package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
  165. package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +11 -12
  166. package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +9 -6
  167. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +83 -68
  168. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
  169. package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +20 -3
  170. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +16 -7
  171. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +2 -1
  172. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +137 -0
  173. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +11 -10
  174. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +21 -11
  175. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +12 -1
  176. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
  177. package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
  178. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
  179. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +56 -13
  180. package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +58 -0
  181. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
  182. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
  183. package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +25 -1
  184. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
  185. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
  186. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
  187. package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
  188. package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
  189. package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
  190. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +78 -5
  191. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
  192. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
  193. package/src/runtime/attachments/store.d.mts +3 -0
  194. package/src/runtime/attachments/store.mjs +38 -0
  195. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
  196. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
  197. package/src/runtime/channels/lib/worker-main.mjs +17 -14
  198. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
  199. package/src/runtime/effort-judge/judge-client.mjs +56 -18
  200. package/src/runtime/memory/lib/memory.mjs +1 -1
  201. package/src/runtime/memory/lib/session-ingest.mjs +2 -2
  202. package/src/runtime/shared/atomic-file.mjs +33 -6
  203. package/src/runtime/shared/best-effort-stderr.mjs +8 -0
  204. package/src/runtime/shared/code-graph-state.mjs +12 -0
  205. package/src/runtime/shared/defaults-separation.mjs +2 -0
  206. package/src/runtime/shared/extension-scopes.mjs +5 -3
  207. package/src/runtime/shared/file-lock.mjs +37 -11
  208. package/src/runtime/shared/git-runner-worker.mjs +3 -2
  209. package/src/runtime/shared/git-runner.mjs +4 -3
  210. package/src/runtime/shared/llm/anthropic-effort.mjs +14 -0
  211. package/src/runtime/shared/llm/default-context-window.mjs +6 -0
  212. package/src/runtime/shared/llm/model-catalog-projection.mjs +5 -4
  213. package/src/runtime/shared/llm/model-catalog.mjs +240 -130
  214. package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
  215. package/src/runtime/shared/llm/provider-catalog-registry.mjs +162 -0
  216. package/src/runtime/shared/llm/provider-seed-rosters.mjs +130 -0
  217. package/src/runtime/shared/model-proxy-mode.d.mts +3 -0
  218. package/src/runtime/shared/model-proxy-mode.mjs +19 -0
  219. package/src/runtime/shared/plugin-manifest.mjs +18 -9
  220. package/src/runtime/shared/pristine-execution-contract.json +9 -2
  221. package/src/runtime/shared/pristine-execution.mjs +28 -4
  222. package/src/runtime/shared/provider-accounts.mjs +125 -21
  223. package/src/runtime/shared/provider-api-key.mjs +33 -1
  224. package/src/runtime/shared/schedule-model-ref.mjs +11 -2
  225. package/src/runtime/shared/session-usage-totals.mjs +19 -0
  226. package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
  227. package/src/runtime/shared/shell-display.mjs +9 -3
  228. package/src/runtime/shared/singleton-owner.mjs +36 -6
  229. package/src/runtime/shared/skill-mentions.d.mts +10 -0
  230. package/src/runtime/shared/skill-mentions.mjs +133 -0
  231. package/src/runtime/shared/skill-script-runtime.mjs +264 -0
  232. package/src/runtime/shared/statusline/statusline-segments.mjs +68 -14
  233. package/src/runtime/shared/tool-primitives.mjs +35 -2
  234. package/src/runtime/shared/tool-surface.mjs +7 -0
  235. package/src/runtime/shared/tool-work-units.mjs +14 -0
  236. package/src/runtime/shared/transcript-metadata.mjs +17 -1
  237. package/src/runtime/shared/turn-changes.mjs +791 -0
  238. package/src/runtime/shared/turn-snapshot-store.mjs +346 -12
  239. package/src/runtime/shared/turn-snapshot.mjs +690 -81
  240. package/src/runtime/shared/turn-worktree-snapshot.mjs +185 -15
  241. package/src/runtime/shared/worker-requests.mjs +15 -2
  242. package/src/runtime/shared/worktrees/cache-cleanups.mjs +52 -0
  243. package/src/runtime/shared/worktrees/contract.mjs +551 -0
  244. package/src/runtime/shared/worktrees/disk.mjs +57 -0
  245. package/src/runtime/shared/worktrees/git.mjs +247 -0
  246. package/src/runtime/shared/worktrees/include.mjs +480 -0
  247. package/src/runtime/shared/worktrees/lock.mjs +46 -0
  248. package/src/runtime/shared/worktrees/maintenance.mjs +96 -0
  249. package/src/runtime/shared/worktrees/manager.mjs +1215 -0
  250. package/src/runtime/shared/worktrees/merge.mjs +182 -0
  251. package/src/runtime/shared/worktrees/owner.mjs +46 -0
  252. package/src/runtime/shared/worktrees/paths.mjs +62 -0
  253. package/src/runtime/shared/worktrees/registry.mjs +110 -0
  254. package/src/runtime/shared/worktrees/settings.mjs +84 -0
  255. package/src/runtime/shared/worktrees/slug.mjs +62 -0
  256. package/src/runtime/shared/worktrees/test-support.mjs +96 -0
  257. package/src/runtime/visualize-bridge/client.mjs +181 -0
  258. package/src/runtime/visualize-bridge/tool-defs.mjs +97 -0
  259. package/src/session-runtime/automation-agents.mjs +8 -2
  260. package/src/session-runtime/boot/apis.mjs +90 -0
  261. package/src/session-runtime/boot/config.mjs +7 -2
  262. package/src/session-runtime/boot/facade.mjs +21 -0
  263. package/src/session-runtime/boot/infrastructure.mjs +30 -18
  264. package/src/session-runtime/boot/session.mjs +1 -0
  265. package/src/session-runtime/boot/tools.mjs +4 -0
  266. package/src/session-runtime/config-lifecycle.mjs +10 -1
  267. package/src/session-runtime/conversation-import/discovery.mjs +698 -0
  268. package/src/session-runtime/conversation-import/service.mjs +369 -0
  269. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +21 -6
  270. package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
  271. package/src/session-runtime/global-extensions.mjs +2 -2
  272. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +27 -2
  273. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +32 -1
  274. package/src/session-runtime/internal-tool-executor.mjs +9 -1
  275. package/src/session-runtime/lifecycle/session-catalog.mjs +8 -1
  276. package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +5 -0
  277. package/src/session-runtime/lifecycle/session-switch/resume.mjs +21 -3
  278. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +16 -0
  279. package/src/session-runtime/mcp-glue/connect.mjs +68 -16
  280. package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
  281. package/src/session-runtime/mcp-glue/server-catalog.mjs +122 -33
  282. package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
  283. package/src/session-runtime/mcp-glue.mjs +22 -2
  284. package/src/session-runtime/model-route/route-persist.mjs +3 -0
  285. package/src/session-runtime/model-route/set-route.mjs +15 -2
  286. package/src/session-runtime/new-session-config.mjs +3 -2
  287. package/src/session-runtime/notification-bus.mjs +18 -3
  288. package/src/session-runtime/provider-auth/accounts.mjs +33 -15
  289. package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
  290. package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
  291. package/src/session-runtime/provider-readiness.mjs +16 -10
  292. package/src/session-runtime/resource-extension-sync.mjs +45 -7
  293. package/src/session-runtime/resource-mcp-api.mjs +121 -84
  294. package/src/session-runtime/resource-plugins-api.mjs +29 -41
  295. package/src/session-runtime/resource-scope-decorate.mjs +6 -8
  296. package/src/session-runtime/resource-skills-api.mjs +23 -2
  297. package/src/session-runtime/route-resolution.mjs +10 -1
  298. package/src/session-runtime/route-state.mjs +16 -2
  299. package/src/session-runtime/runtime-core.mjs +5 -0
  300. package/src/session-runtime/runtime-facade.mjs +8 -0
  301. package/src/session-runtime/runtime-review-api.mjs +9 -0
  302. package/src/session-runtime/schedule-session-run.mjs +1 -1
  303. package/src/session-runtime/services/agent-tool/helpers.mjs +5 -0
  304. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +3 -0
  305. package/src/session-runtime/services/agent-tool/job-views/job-lookup.mjs +1 -0
  306. package/src/session-runtime/services/agent-tool/job-views/spawn-meta.mjs +1 -0
  307. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +15 -0
  308. package/src/session-runtime/services/agent-tool/send-flow.mjs +1 -0
  309. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +10 -2
  310. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -7
  311. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  312. package/src/session-runtime/services/agent-tool/tag-registry.mjs +2 -1
  313. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -0
  314. package/src/session-runtime/services/agent-tool/worker-rows.mjs +1 -0
  315. package/src/session-runtime/services/agent-tool.mjs +1 -0
  316. package/src/session-runtime/services/channel-session-router.mjs +4 -1
  317. package/src/session-runtime/services/daemon-candidate.mjs +3 -2
  318. package/src/session-runtime/services/daemon-crash-capture/spawn-capture.mjs +55 -0
  319. package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
  320. package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
  321. package/src/session-runtime/services/provider-admin.mjs +64 -18
  322. package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
  323. package/src/session-runtime/session-create/session-options.mjs +10 -1
  324. package/src/session-runtime/session-turn-api.mjs +1 -0
  325. package/src/session-runtime/settings-api.mjs +4 -2
  326. package/src/session-runtime/settings-builtin-tools-api.mjs +9 -2
  327. package/src/session-runtime/settings-worktree-api.mjs +17 -0
  328. package/src/session-runtime/setup-tool/executor.mjs +23 -5
  329. package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
  330. package/src/session-runtime/setup-tool/settings-contract.mjs +4 -1
  331. package/src/session-runtime/setup-tool/tool-defs.mjs +38 -4
  332. package/src/session-runtime/skills-api.mjs +7 -3
  333. package/src/session-runtime/turn/agent-ops.mjs +12 -1
  334. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +14 -3
  335. package/src/session-runtime/turn/turn-run/snapshot-tracker.mjs +20 -15
  336. package/src/session-runtime/turn/turn-run/turn-open.mjs +4 -5
  337. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +29 -1
  338. package/src/session-runtime/turn/turn-run/turn-settle.mjs +6 -1
  339. package/src/session-runtime/turn/turn-run.mjs +6 -7
  340. package/src/session-runtime/webhook-session-run.mjs +16 -4
  341. package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -3
  342. package/src/session-runtime/workspace/admission-gate.mjs +197 -0
  343. package/src/session-runtime/workspace/project-branches.mjs +136 -0
  344. package/src/session-runtime/workspace/transition-steps.mjs +364 -0
  345. package/src/session-runtime/workspace/transitions.mjs +651 -0
  346. package/src/session-runtime/workspace/workspace-state.mjs +112 -0
  347. package/src/skill-script-entry.mjs +36 -0
  348. package/src/standalone/channel-transport/http-routes.mjs +17 -0
  349. package/src/standalone/channel-transport.mjs +13 -1
  350. package/src/standalone/daemon-desktop-runtime.mjs +1 -0
  351. package/src/standalone/daemon-owner.mjs +372 -0
  352. package/src/standalone/daemon-stored-session-views.mjs +15 -4
  353. package/src/standalone/daemon.mjs +179 -8
  354. package/src/standalone/desktop-service-registry.mjs +20 -0
  355. package/src/standalone/local-session-runtime.mjs +11 -0
  356. package/src/standalone/session-client/attachment-calls.mjs +3 -1
  357. package/src/standalone/session-client/daemon-unavailable.mjs +62 -0
  358. package/src/standalone/session-client/lease-heartbeat.mjs +47 -0
  359. package/src/standalone/session-client.mjs +104 -13
  360. package/src/standalone/session-protocol.mjs +21 -0
  361. package/src/standalone/session-proxy.mjs +3 -0
  362. package/src/standalone/session-service/agent-tree/agent-child.mjs +4 -0
  363. package/src/standalone/session-service/agent-tree/agent-rehydrate.mjs +1 -0
  364. package/src/standalone/session-service/entries/lifecycle.mjs +6 -0
  365. package/src/standalone/session-service/projection/revisions.mjs +2 -0
  366. package/src/standalone/session-service/projection/transcript-window.mjs +149 -19
  367. package/src/standalone/session-service/projection/workspace.mjs +14 -0
  368. package/src/standalone/session-service/session-calls/session-action.mjs +17 -4
  369. package/src/standalone/session-transport/call-route.mjs +13 -0
  370. package/src/standalone/session-transport/client-registry/client-grace.mjs +45 -3
  371. package/src/standalone/session-transport/client-registry/registration-replays.mjs +1 -0
  372. package/src/standalone/session-transport/client-registry.mjs +20 -3
  373. package/src/standalone/session-transport/routes.mjs +79 -2
  374. package/src/standalone/session-transport/stack.mjs +2 -0
  375. package/src/standalone/session-transport.mjs +24 -1
  376. package/src/tui/App.jsx +9 -1
  377. package/src/tui/app/app-view/floating-panel.jsx +9 -1
  378. package/src/tui/app/app-view.jsx +6 -0
  379. package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
  380. package/src/tui/app/message-selector.mjs +2 -1
  381. package/src/tui/app/model-options.mjs +37 -5
  382. package/src/tui/app/model-picker/provider-models-list.mjs +2 -2
  383. package/src/tui/app/model-picker.mjs +4 -2
  384. package/src/tui/app/skill-mention-palette.mjs +88 -0
  385. package/src/tui/app/slash-palette.mjs +23 -7
  386. package/src/tui/app/transcript-row-estimate.mjs +11 -3
  387. package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
  388. package/src/tui/app/use-prompt-state.mjs +5 -0
  389. package/src/tui/components/Message.jsx +22 -1
  390. package/src/tui/components/PromptInput.jsx +21 -3
  391. package/src/tui/components/SlashCommandPalette.jsx +12 -3
  392. package/src/tui/components/TranscriptItem.jsx +9 -1
  393. package/src/tui/components/prompt-input/key-handler.mjs +21 -8
  394. package/src/tui/components/user-message-skills.mjs +38 -0
  395. package/src/tui/dist/index.mjs +839 -207
  396. package/src/tui/index.jsx +10 -2
  397. package/src/tui/session/compaction-view.mjs +147 -0
  398. package/src/tui/session/context-state.mjs +6 -0
  399. package/src/tui/session/initial-state.mjs +3 -0
  400. package/src/tui/session/queue-helpers.mjs +7 -2
  401. package/src/tui/session/quota-resume.mjs +2 -1
  402. package/src/tui/session/session-api/commands.mjs +10 -2
  403. package/src/tui/session/session-api/controls.mjs +4 -0
  404. package/src/tui/session/session-api/extensions.mjs +4 -2
  405. package/src/tui/session/session-api/intake/rewind.mjs +2 -1
  406. package/src/tui/session/session-api/integrations.mjs +17 -0
  407. package/src/tui/session/session-api/lifecycle/dispose.mjs +6 -1
  408. package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -0
  409. package/src/tui/session/session-api/lifecycle/resume.mjs +3 -0
  410. package/src/tui/session/session-api/routes.mjs +10 -1
  411. package/src/tui/session/session-api/settings.mjs +9 -0
  412. package/src/tui/session/session-api/worktree.mjs +60 -0
  413. package/src/tui/session/session-api.mjs +2 -0
  414. package/src/tui/session/session-flow/auto-clear.mjs +31 -12
  415. package/src/tui/session/session-flow/drain.mjs +27 -3
  416. package/src/tui/session/session-flow/session-reset.mjs +4 -3
  417. package/src/tui/session/session-flow.mjs +2 -0
  418. package/src/tui/session/transcript-intake.mjs +14 -5
  419. package/src/tui/session/tui-steering-persist.mjs +25 -9
  420. package/src/tui/session/turn-stream.mjs +32 -4
  421. package/src/tui/session/turn-tool-cards.mjs +10 -2
  422. package/src/tui/session/turn.mjs +56 -10
  423. package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
  424. package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
@@ -6,6 +6,7 @@ import { hasOwn } from '../../runtime/agent/orchestrator/runtime-core/session-te
6
6
  import { toolSpecForMode } from '../../runtime/agent/orchestrator/runtime-core/effort.mjs';
7
7
  import { pluginDataDir } from '../runtime-paths.mjs';
8
8
  import { LEAD_DISALLOWED_TOOLS } from '../../runtime/agent/orchestrator/runtime-core/tool-defs.mjs';
9
+ import { HEADLESS_TOOL_PROFILE } from '../../runtime/agent/orchestrator/runtime-core/tool-profile.mjs';
9
10
 
10
11
  // Ownership and permission fields an agent-owned session inherits from its profile.
11
12
  function agentOwnedSessionFields(sessionProfile) {
@@ -47,7 +48,13 @@ export function sessionOptions(deps, coreMemoryContext) {
47
48
  owner: agentOwned ? 'agent' : 'cli',
48
49
  agent: agentOwned ? sessionProfile?.agent || 'worker' : 'lead',
49
50
  lane: agentOwned ? 'agent' : 'cli',
50
- sourceType: agentOwned ? sessionProfile?.sourceType || 'agent' : 'lead',
51
+ // One-shot `mixdog exec` runs carry their own source so session catalogs
52
+ // can keep them out of the user's resumable list.
53
+ sourceType: agentOwned
54
+ ? sessionProfile?.sourceType || 'agent'
55
+ : rt.toolProfile === HEADLESS_TOOL_PROFILE
56
+ ? 'exec'
57
+ : 'lead',
51
58
  sourceName: agentOwned ? sessionProfile?.sourceName || sessionProfile?.agent || 'agent' : 'main',
52
59
  ...(rt.approvalMode ? { approvalMode: rt.approvalMode } : {}),
53
60
  clientHostPid: sessionProfile?.clientHostPid || process.pid,
@@ -64,8 +71,10 @@ export function sessionOptions(deps, coreMemoryContext) {
64
71
  workflowContext,
65
72
  orchestrationMode,
66
73
  fast: rt.route.fast === true,
74
+ autoEffort: rt.route.autoEffort !== false,
67
75
  modelParameters: rt.route.modelParameters || {},
68
76
  contextPercent: rt.route.contextPercent,
77
+ contextTokens: rt.route.contextTokens || null,
69
78
  selectedContextWindow: rt.route.selectedContextWindow || null,
70
79
  compaction:
71
80
  rt.config.compaction && typeof rt.config.compaction === 'object'
@@ -34,6 +34,7 @@ export function createSessionTurnApi(deps) {
34
34
  sessionOwnerGone: share.sessionOwnerGone,
35
35
  agentControl: agent.agentControl,
36
36
  taskControl: agent.taskControl,
37
+ stopShellJob: agent.stopShellJob,
37
38
  onNotification: agent.onNotification,
38
39
  toolsStatus: agent.toolsStatus,
39
40
  selectTools: agent.selectTools,
@@ -5,9 +5,9 @@
5
5
  // `this.*` resolve against the spread target, so cross-member calls (e.g.
6
6
  // setProfile -> this.getProfile) keep working when spread into the facade.
7
7
  //
8
- // The members live in five topic modules: profile/onboarding/skills,
8
+ // The members live in six topic modules: profile/onboarding/skills,
9
9
  // compaction/auto-clear, built-in tool modules, system (channels, shell,
10
- // updates) and developer options; the local provider's own methods come from
10
+ // updates), developer options and worktree defaults; the local provider's own methods come from
11
11
  // local-provider-settings.mjs.
12
12
  import { createLocalProviderSettings } from './local-provider-settings.mjs';
13
13
  import { createProfileSettings } from './settings-profile-api.mjs';
@@ -15,6 +15,7 @@ import { createCompactionSettings } from './settings-compaction-api.mjs';
15
15
  import { createBuiltinToolSettings } from './settings-builtin-tools-api.mjs';
16
16
  import { createSystemSettings } from './settings-system-api.mjs';
17
17
  import { createDeveloperSettings } from './settings-developer-api.mjs';
18
+ import { createWorktreeSettings } from './settings-worktree-api.mjs';
18
19
 
19
20
  export function createSettingsApi(deps) {
20
21
  // Optional: callers without a live local provider / gate fall back to the
@@ -38,5 +39,6 @@ export function createSettingsApi(deps) {
38
39
  ...createBuiltinToolSettings(shared, localSettings),
39
40
  ...createSystemSettings(shared),
40
41
  ...createDeveloperSettings(shared),
42
+ ...createWorktreeSettings(shared),
41
43
  };
42
44
  }
@@ -7,6 +7,7 @@ import {
7
7
  builtinInstalled,
8
8
  setBuiltinInstalledInConfig,
9
9
  } from '../runtime/agent/orchestrator/runtime-core/builtin-features.mjs';
10
+ import { featureEnvOverride, moduleEnabled } from '../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
10
11
  import { LOCAL_PROVIDER_ID } from '../runtime/local-provider/managed-runtime.mjs';
11
12
  import {
12
13
  INSTRUCTION_FILES_MODES,
@@ -23,7 +24,7 @@ import {
23
24
  shutdownEffortJudge,
24
25
  } from '../runtime/effort-judge/judge-client.mjs';
25
26
 
26
- const TOGGLEABLE_BUILTINS = ['git', 'office', 'tidy', 'localProvider', 'autoEffort'];
27
+ const TOGGLEABLE_BUILTINS = ['git', 'office', 'tidy', 'localProvider', 'autoEffort', 'visualize'];
27
28
 
28
29
  function setLocalProviderEnabledInConfig(configLike, enabled) {
29
30
  const next = { ...(configLike || {}) };
@@ -97,6 +98,12 @@ export function createBuiltinToolSettings(
97
98
  enabled: tidyToolEnabledFn ? tidyToolEnabledFn() : builtinFeatureActive(config, 'tidy'),
98
99
  installed: builtinInstalled(config, 'tidy'),
99
100
  },
101
+ // Ships with the runtime and needs no install; the toggle reflects the
102
+ // module flag, not live bridge presence.
103
+ visualize: {
104
+ enabled: featureEnvOverride('MIXDOG_FEATURE_VISUALIZE') ?? moduleEnabled(config, 'visualize', true),
105
+ installed: true,
106
+ },
100
107
  localProvider: {
101
108
  ...localProvider,
102
109
  ...localSettings.status(),
@@ -152,7 +159,7 @@ export function createBuiltinToolSettings(
152
159
  },
153
160
  async setBuiltinToolEnabled(name, enabled) {
154
161
  if (!TOGGLEABLE_BUILTINS.includes(name)) {
155
- throw new TypeError('Built-in tool must be git, office, tidy, localProvider, or autoEffort.');
162
+ throw new TypeError('Built-in tool must be git, office, tidy, localProvider, autoEffort, or visualize.');
156
163
  }
157
164
  if (name === 'autoEffort' && enabled !== false && !onnxRuntimeSupported()) {
158
165
  throw new Error(EFFORT_JUDGE_UNSUPPORTED);
@@ -0,0 +1,17 @@
1
+ // Settings → Worktrees: defaults for Lead-session git worktrees
2
+ // (runtime/shared/worktrees/settings.mjs). Values persist at agent config
3
+ // `worktree.<key>`; defaults are not stored.
4
+ import { applyWorktreeSettingsPatch, normalizeWorktreeSettings } from '../runtime/shared/worktrees/settings.mjs';
5
+
6
+ export function createWorktreeSettings({ getConfig, saveConfigAndAdopt }) {
7
+ return {
8
+ getWorktreeSettings() {
9
+ return normalizeWorktreeSettings(getConfig()?.worktree);
10
+ },
11
+ setWorktreeSettings(patch) {
12
+ const config = getConfig() || {};
13
+ saveConfigAndAdopt({ ...config, worktree: applyWorktreeSettingsPatch(config.worktree, patch) });
14
+ return this.getWorktreeSettings();
15
+ },
16
+ };
17
+ }
@@ -30,6 +30,7 @@ const PROFILE_VALUE_IDS = Object.freeze({
30
30
  const ACTION_APPLIES_TO = {
31
31
  set_recap_enabled: 'background Memory cycles; no restart required',
32
32
  set_auto_update: 'subsequent automatic update checks',
33
+ set_worktree_settings: 'new tasks and worktrees created afterwards; existing worktrees are unchanged',
33
34
  set_system_shell: 'subsequent shell calls',
34
35
  save_automation: 'the automation worker; scheduled runs follow the saved timing',
35
36
  delete_automation: 'future automation runs',
@@ -93,6 +94,7 @@ function routeInput(source) {
93
94
  if (typeof source.fast === 'boolean') next.fast = source.fast;
94
95
  if (Object.hasOwn(source, 'modelParameters')) next.modelParameters = { ...source.modelParameters };
95
96
  if (Object.hasOwn(source, 'contextPercent')) next.contextPercent = source.contextPercent;
97
+ if (Object.hasOwn(source, 'contextTokens')) next.contextTokens = source.contextTokens;
96
98
  if (Object.hasOwn(source, 'disabled')) next.disabled = source.disabled;
97
99
  return next;
98
100
  }
@@ -144,6 +146,7 @@ function publicAccounts(pool) {
144
146
  return {
145
147
  selectedId: pool.selectedId,
146
148
  auto: pool.auto,
149
+ ...(pool.policy ? { policy: pool.policy } : {}),
147
150
  useCredits: pool.useCredits === true,
148
151
  accounts: pool.accounts.map(({ id, label, authenticated, reauthRequired }) => ({
149
152
  id,
@@ -164,9 +167,15 @@ function mcpRows(status) {
164
167
  transport: server.transport || server.type || '',
165
168
  toolCount: Number(server.toolCount || 0),
166
169
  source: server.source || '',
170
+ ...(server.owner?.kind === 'plugin'
171
+ ? { plugin: server.owner.id, pluginServer: server.owner.key, disabledReason: server.disabledReason || null }
172
+ : {}),
167
173
  error: server.error || null,
174
+ ...(server.warnings?.length ? { warnings: server.warnings } : {}),
168
175
  scope: Array.isArray(server.scope) ? server.scope : null,
169
176
  })),
177
+ ...(status?.warnings?.length ? { warnings: status.warnings } : {}),
178
+ ...(status?.declarationErrors?.length ? { declarationErrors: status.declarationErrors } : {}),
170
179
  };
171
180
  }
172
181
 
@@ -178,6 +187,7 @@ const mainRoute = (rt) => ({
178
187
  fastCapable: rt.fastCapable === true,
179
188
  modelParameters: rt.modelParameters || {},
180
189
  contextPercent: rt.contextPercent ?? null,
190
+ contextTokens: rt.contextTokens ?? null,
181
191
  });
182
192
 
183
193
  async function automationStatus(rt, { domain }) {
@@ -303,6 +313,7 @@ const SETUP_STATUS_READERS = {
303
313
  plugins: (rt) => rt.pluginsStatus?.() || {},
304
314
  update: (rt) => rt.getUpdateSettings?.() || {},
305
315
  onboarding: (rt) => rt.getOnboardingStatus?.() || {},
316
+ worktree: (rt) => rt.getWorktreeSettings(),
306
317
  schedules: automationStatus,
307
318
  webhooks: automationStatus,
308
319
  hooks: hookStatus,
@@ -328,11 +339,13 @@ function validateSetupInput(args) {
328
339
  if (action !== 'set_agent_route' && Object.hasOwn(args.route, 'disabled')) {
329
340
  throw new Error('route.disabled is only accepted by set_agent_route');
330
341
  }
331
- if (action !== 'set_route' && action !== 'set_agent_route' && Object.hasOwn(args.route, 'contextPercent')) {
332
- throw new Error('route.contextPercent is only accepted by set_route and set_agent_route');
342
+ for (const field of ['contextPercent', 'contextTokens']) {
343
+ if (action !== 'set_route' && action !== 'set_agent_route' && Object.hasOwn(args.route, field)) {
344
+ throw new Error(`route.${field} is only accepted by set_route and set_agent_route`);
345
+ }
333
346
  }
334
347
  }
335
- for (const field of ['desktop', 'appearance', 'webhook', 'compaction', 'providerAccount']) {
348
+ for (const field of ['desktop', 'appearance', 'webhook', 'compaction', 'providerAccount', 'worktree']) {
336
349
  if (args[field] && !Object.keys(args[field]).length) throw new Error(`${field} requires at least one setting`);
337
350
  }
338
351
  return action;
@@ -507,6 +520,7 @@ const SETUP_ACTION_HANDLERS = {
507
520
  rt.deleteLocalProviderModel(requireText(args.confirmationToken, 'confirmationToken')),
508
521
  set_system_shell: (rt, args) => rt.setSystemShell({ command: clean(args.command) }),
509
522
  set_auto_update: (rt, args) => rt.setAutoUpdate(requireBoolean(args.enabled)),
523
+ set_worktree_settings: (rt, args) => rt.setWorktreeSettings(args.worktree),
510
524
  forget_provider_auth: async (rt, args) => {
511
525
  const name = requireText(args.name, 'name');
512
526
  const setup = await rt.getProviderSetup({});
@@ -541,7 +555,7 @@ const SETUP_ACTION_HANDLERS = {
541
555
  set_mcp_enabled: async (rt, args) => ({
542
556
  mcp: mcpRows(await rt.setMcpServerEnabled(requireText(args.name, 'name'), requireBoolean(args.enabled))),
543
557
  }),
544
- reconnect_mcp: async (rt) => ({ mcp: mcpRows(await rt.reconnectMcp()) }),
558
+ reconnect_mcp: async (rt, args) => ({ mcp: mcpRows(await rt.reconnectMcp(clean(args.name) || undefined)) }),
545
559
  set_disabled_skills: (rt, args) => {
546
560
  if (!Array.isArray(args.skills)) throw new Error('skills (array of names) is required');
547
561
  return rt.setDisabledSkills(args.skills.map(clean).filter(Boolean));
@@ -570,7 +584,11 @@ const SETUP_ACTION_HANDLERS = {
570
584
  const plugin = ((await rt.pluginsStatus())?.plugins || []).find((row) => row.name === name || row.id === name);
571
585
  if (!plugin) throw new Error(`plugin "${name}" not found`);
572
586
  const result = await rt.enablePluginMcp(plugin);
573
- return { serverName: result.serverName, mcp: mcpRows(result.status) };
587
+ return {
588
+ serverName: result.serverName,
589
+ ...(result.serverNames ? { serverNames: result.serverNames } : {}),
590
+ mcp: mcpRows(result.status),
591
+ };
574
592
  },
575
593
  };
576
594
 
@@ -34,6 +34,7 @@ function publicMcpConfig(row) {
34
34
  return {
35
35
  name: row.name,
36
36
  source: row.source,
37
+ ...(row.owner?.kind === 'plugin' ? { plugin: row.owner.id, pluginServer: row.owner.key, readOnly: true } : {}),
37
38
  enabled: row.enabled !== false,
38
39
  type: config.type || 'stdio',
39
40
  cwd: config.cwd || '',
@@ -108,6 +108,8 @@ export const SETUP_MCP_SCHEMA = object({
108
108
  additionalProperties: removableText,
109
109
  description: 'HTTP header names mapped to existing environment variable names.',
110
110
  },
111
+ startupTimeoutSec: { type: 'number', description: 'Connect/handshake timeout in seconds (>0, default 30).' },
112
+ toolTimeoutSec: { type: 'number', description: 'Per tool-call timeout in seconds (>0, default 120).' },
111
113
  });
112
114
 
113
115
  export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
@@ -158,7 +160,7 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
158
160
  model: {
159
161
  ...text,
160
162
  description:
161
- 'Required for new schedules; no default-model fallback. Use provider/model[@effort][+fast][?parameter=value] or an existing preset name. On overwrite, omission preserves the saved model, which must be non-empty.',
163
+ 'Required for new schedules; no default-model fallback. Use provider/model[@effort][+fast][+noauto][?parameter=value] (+noauto: Auto reasoning off; absent = on) or an existing preset name. On overwrite, omission preserves the saved model, which must be non-empty.',
162
164
  },
163
165
  cwd: text,
164
166
  workflow: text,
@@ -194,6 +196,7 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
194
196
  runInBackground: boolean,
195
197
  turnNotifications: boolean,
196
198
  usagePinned: boolean,
199
+ usageRailShortLong: boolean,
197
200
  computerObserveOnly: boolean,
198
201
  notificationVolume: {
199
202
  type: 'integer',
@@ -6,6 +6,7 @@ import {
6
6
  } from './settings-contract.mjs';
7
7
  import { MEDIA_KINDS } from '../../runtime/media/tool-defs.mjs';
8
8
  import { INSTRUCTION_FILES_MODES } from '../../runtime/shared/instruction-files-mode.mjs';
9
+ import { WORKTREE_NEW_TASK_DEFAULTS } from '../../runtime/shared/worktrees/settings.mjs';
9
10
 
10
11
  /** Built-in `setup` tool: the model's handle on a Mixdog user's persisted
11
12
  * configuration. The description is a contract only; how to use each action
@@ -31,6 +32,7 @@ export const SETUP_STATUS_DOMAINS = Object.freeze([
31
32
  'plugins',
32
33
  'update',
33
34
  'onboarding',
35
+ 'worktree',
34
36
  ...SETUP_EXTENDED_DOMAINS,
35
37
  ]);
36
38
 
@@ -100,7 +102,7 @@ export const SETUP_ACTION_FIELDS = Object.freeze({
100
102
  save_mcp_server: 'server',
101
103
  remove_mcp_server: 'name',
102
104
  set_mcp_enabled: 'name enabled',
103
- reconnect_mcp: '',
105
+ reconnect_mcp: 'name?',
104
106
  set_disabled_skills: 'skills',
105
107
  set_extension_scope: 'kind name projects',
106
108
  add_plugin: 'source',
@@ -108,6 +110,7 @@ export const SETUP_ACTION_FIELDS = Object.freeze({
108
110
  set_plugin_enabled: 'name enabled',
109
111
  remove_plugin: 'name',
110
112
  enable_plugin_mcp: 'name',
113
+ set_worktree_settings: 'worktree',
111
114
  ...SETUP_EXTENDED_ACTION_FIELDS,
112
115
  });
113
116
 
@@ -122,6 +125,7 @@ export const SETUP_BUILTIN_TOGGLE_FEATURES = Object.freeze([
122
125
  'browser',
123
126
  'computer',
124
127
  'voice',
128
+ 'visualize',
125
129
  ]);
126
130
 
127
131
  const ROUTE_SCHEMA = {
@@ -136,6 +140,11 @@ const ROUTE_SCHEMA = {
136
140
  // A typed enum is unrepresentable on Gemini; the bounds project everywhere
137
141
  // and the executor rejects values that are not a multiple of 10.
138
142
  contextPercent: { type: 'integer', minimum: 10, maximum: 100, description: 'A multiple of 10.' },
143
+ contextTokens: {
144
+ type: 'integer',
145
+ minimum: 1,
146
+ description: 'Exact context window in tokens; overrides contextPercent, clamped to 10%-100% of the model window.',
147
+ },
139
148
  disabled: {
140
149
  type: 'boolean',
141
150
  description: 'Agent routes only: true disables without losing the route; false re-enables.',
@@ -176,7 +185,7 @@ export const SETUP_TOOL_DEFS = Object.freeze([
176
185
  route: {
177
186
  ...ROUTE_SCHEMA,
178
187
  description:
179
- 'Partial route update; omitted fields are preserved. Agent or Web Search provider "" restores Main inheritance. contextPercent applies to Main and agent routes only.',
188
+ 'Partial route update; omitted fields are preserved. Agent or Web Search provider "" restores Main inheritance. contextPercent and contextTokens apply to Main and agent routes only.',
180
189
  },
181
190
  agent: { type: 'string', description: 'set_agent_route: agent id.' },
182
191
  workflow: { type: 'string', description: 'set_workflow: pack id.' },
@@ -218,11 +227,11 @@ export const SETUP_TOOL_DEFS = Object.freeze([
218
227
  type: 'string',
219
228
  enum: [...INSTRUCTION_FILES_MODES],
220
229
  description:
221
- 'set_instruction_files: which user instruction files new sessions load (global ~/.codex/AGENTS.md, ~/.claude/CLAUDE.md, then the Project root\'s AGENTS.md/CLAUDE.md).',
230
+ "set_instruction_files: which user instruction files new sessions load (global ~/.codex/AGENTS.md, ~/.claude/CLAUDE.md, then the Project root's AGENTS.md/CLAUDE.md).",
222
231
  },
223
232
  name: {
224
233
  type: 'string',
225
- description: `set_builtin_enabled: ${SETUP_BUILTIN_TOGGLE_FEATURES.join('|')}; install_builtin also accepts memory. Memory toggles use set_memory_enabled. revoke_linked_device: client id from status connection, not its display name; set_developer_option: option id from status developer; read_definition/delete_definition: the definition id; else MCP/plugin/provider id.`,
234
+ description: `set_builtin_enabled: ${SETUP_BUILTIN_TOGGLE_FEATURES.join('|')}; install_builtin also accepts memory. Memory toggles use set_memory_enabled. revoke_linked_device: client id from status connection, not its display name; set_developer_option: option id from status developer; read_definition/delete_definition: the definition id; reconnect_mcp: optional MCP server name (omit for all); else MCP/plugin/provider id.`,
226
235
  },
227
236
  accountId: {
228
237
  type: 'string',
@@ -235,6 +244,12 @@ export const SETUP_TOOL_DEFS = Object.freeze([
235
244
  properties: {
236
245
  selectedId: { type: 'string', description: 'Account to use now.' },
237
246
  auto: { type: 'boolean', description: 'Automatic switching to another account when one is exhausted.' },
247
+ policy: {
248
+ type: 'string',
249
+ enum: ['manual', 'limit', 'headroom'],
250
+ description:
251
+ 'Account switching: manual = selected account only; limit = switch when it reaches a limit; headroom = each new session starts on the account with the most headroom.',
252
+ },
238
253
  useCredits: { type: 'boolean', description: 'Allow paid credits once plan limits are reached.' },
239
254
  order: {
240
255
  type: 'array',
@@ -320,6 +335,25 @@ export const SETUP_TOOL_DEFS = Object.freeze([
320
335
  items: { type: 'string', minLength: 1, pattern: '\\S' },
321
336
  description: 'set_extension_scope: required project roots; [] = every project.',
322
337
  },
338
+ worktree: {
339
+ type: 'object',
340
+ additionalProperties: false,
341
+ properties: {
342
+ newTaskDefault: {
343
+ type: 'string',
344
+ enum: [...WORKTREE_NEW_TASK_DEFAULTS],
345
+ description: 'branch = new tasks use the current branch (default); worktree = a new worktree.',
346
+ },
347
+ branchPrefix: { type: 'string', description: 'Ref prefix ending with "/"; default "mixdog/".' },
348
+ sizeWarnBytes: {
349
+ type: 'integer',
350
+ minimum: 0,
351
+ description: 'Repository size that asks for confirmation first; 0 never asks.',
352
+ },
353
+ autoCleanup: { type: 'boolean', description: 'Remove clean, merged worktrees when their task ends.' },
354
+ },
355
+ description: 'set_worktree_settings: only the given fields change.',
356
+ },
323
357
  ...SETUP_EXTENDED_PROPERTIES,
324
358
  },
325
359
  },
@@ -24,8 +24,8 @@ const DEFAULT_SKILL_BODY = '# Instructions\n\nDescribe how to use this skill.';
24
24
  export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
25
25
  const globalSkillsRoot = () => resolve(resolvePluginData(), 'skills');
26
26
 
27
- function skillsStatus() {
28
- const cwd = getCwd();
27
+ /** `cwd` overrides the session's folder (already validated by the caller). */
28
+ function skillsStatus({ cwd = getCwd() } = {}) {
29
29
  const skills = typeof contextMod.collectSkillsCached === 'function' ? contextMod.collectSkillsCached(cwd) : [];
30
30
  const norm = (value) =>
31
31
  String(value || '')
@@ -54,7 +54,10 @@ export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
54
54
  const source = sourceForSkill(skill);
55
55
  return {
56
56
  name: skill.name,
57
- enabled: !(contextMod.isSkillDisabled?.(skill.name) || contextMod.skillMissingFeature?.(skill.name)),
57
+ enabled: !(
58
+ contextMod.isSkillDisabled?.(skill.name, null, skills) ||
59
+ contextMod.skillMissingFeature?.(skill.name, null, skills)
60
+ ),
58
61
  description: skill.description || '',
59
62
  whenToUse: skill.whenToUse || '',
60
63
  filePath: skill.filePath || null,
@@ -90,6 +93,7 @@ export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
90
93
  if (typeof contextMod.isSkillDisabled === 'function' && contextMod.isSkillDisabled(skillName)) {
91
94
  return `Error: skill "${skillName}" is disabled`;
92
95
  }
96
+ if (contextMod.skillOutsideScope?.(skillName, getCwd())) return contextMod.skillOutsideScopeError(skillName);
93
97
  const skill = skillContent(skillName);
94
98
  // The general tool envelope keeps the main/Lead session identical to agent
95
99
  // loops: the model-visible tool_result is the short stub and the SKILL.md
@@ -56,6 +56,17 @@ export function createAgentOps(deps) {
56
56
  });
57
57
  }
58
58
 
59
+ // Stop one background shell job of THIS session through the task tool's
60
+ // cancel path; the answer is structured so a surface never parses text.
61
+ async function stopShellJob(taskId) {
62
+ const session = getSession();
63
+ const { stopBackgroundShellJob } = await import('../../runtime/agent/orchestrator/tools/builtin/task-tool.mjs');
64
+ return stopBackgroundShellJob(taskId, {
65
+ callerSessionId: session?.id || null,
66
+ clientHostPid: session?.clientHostPid || process.pid,
67
+ });
68
+ }
69
+
59
70
  function onNotification(listener) {
60
71
  if (typeof listener !== 'function') return () => {};
61
72
  const sessionId = getSession()?.id || getReservedSessionId?.() || '';
@@ -94,5 +105,5 @@ export function createAgentOps(deps) {
94
105
  return { ...result, status: toolsStatus() };
95
106
  }
96
107
 
97
- return { agentControl, taskControl, onNotification, toolsStatus, selectTools };
108
+ return { agentControl, taskControl, stopShellJob, onNotification, toolsStatus, selectTools };
98
109
  }
@@ -55,18 +55,28 @@ export function createAskCallbacks({ transcript, notifyFnForSession, scheduleSea
55
55
  };
56
56
  }
57
57
 
58
+ // The turn's change-record key rides the caller's transcript metadata (in
59
+ // place: the stream stamps assistantAt on this same object), so the
60
+ // persisted user row and completion carry it across restore.
61
+ function stampCheckpoint(options) {
62
+ const meta = options.transcriptMeta;
63
+ const checkpointId = String(options.id || '').trim();
64
+ if (checkpointId && meta && typeof meta === 'object') meta.checkpointId = checkpointId;
65
+ return meta;
66
+ }
67
+
58
68
  function askCallbacks(turn, session0, options) {
59
69
  return {
60
70
  beforeToolExecution: () => turn.snapshot.promise || Promise.resolve(),
61
- transcriptMeta: options.transcriptMeta,
71
+ transcriptMeta: stampCheckpoint(options),
62
72
  promptSource: options.promptSource,
63
73
  retryFailedTurn: options.retryFailedTurn === true,
64
74
  onTextDelta: options.onTextDelta,
65
75
  onTextReset: options.onTextReset,
66
76
  onReasoningDelta: options.onReasoningDelta,
67
- onAssistantText: (text) => {
77
+ onAssistantText: (text, detail) => {
68
78
  transcript.appendAssistantText(text);
69
- return options.onAssistantText?.(text);
79
+ return options.onAssistantText?.(text, detail);
70
80
  },
71
81
  onUsageDelta: options.onUsageDelta,
72
82
  onAssistantToolCallObserved: options.onAssistantToolCallObserved,
@@ -81,6 +91,7 @@ export function createAskCallbacks({ transcript, notifyFnForSession, scheduleSea
81
91
  onStreamDelta: streamDelta(turn, options),
82
92
  drainSteering: options.drainSteering,
83
93
  onSteerMessage: options.onSteerMessage,
94
+ onSkillsApplied: options.onSkillsApplied,
84
95
  notifyFn: notifyFnForSession(session0.id),
85
96
  signal: turn.signal,
86
97
  };
@@ -1,25 +1,21 @@
1
1
  import { settleWithin } from '../../../runtime/shared/abort-race.mjs';
2
2
 
3
- // Worktree snapshot for the turn review. Captured immediately, but never on
4
- // the first-token critical path: every actual tool execution joins the same
5
- // promise, so shell/apply_patch cannot mutate the worktree before the baseline.
3
+ // Worktree snapshot for the turn review. Captured as soon as the turn's
4
+ // workspace is final (after any lazy worktree provisioning, so the baseline is
5
+ // taken in the root the turn runs in), but never on the first-token critical
6
+ // path: every actual tool execution joins the same promise, so
7
+ // shell/apply_patch cannot mutate the worktree before the baseline.
6
8
  export function createSnapshotTrackerFactory({
7
9
  getCurrentCwd,
8
10
  beginTurnSnapshotForTurn,
9
- cancelTurnSnapshotForTurn,
10
11
  completeTurnSnapshotForTurn,
11
12
  turnCleanupSettleMs,
12
13
  }) {
13
14
  return function createSnapshotTracker(options) {
15
+ // `promise` resolves to the turn token beginTurnSnapshot returns
16
+ // (`{ generation, checkpointId }`), or undefined when nothing began.
14
17
  const tracker = { sessionId: null, promise: null };
15
- // A completion wake continues the user turn whose review already exists;
16
- // aborting the wake seals that review instead of discarding it.
17
18
  const continueTurn = options.continueTurn === true;
18
- const cancel = () => {
19
- try {
20
- cancelTurnSnapshotForTurn(tracker.sessionId);
21
- } catch {}
22
- };
23
19
  tracker.start = (sessionId) => {
24
20
  const id = typeof sessionId === 'string' ? sessionId.trim() : '';
25
21
  if (!id || (tracker.promise && tracker.sessionId === id)) return;
@@ -36,19 +32,28 @@ export function createSnapshotTrackerFactory({
36
32
  .catch(() => undefined);
37
33
  };
38
34
  tracker.finish = async (signal, awaitTurn) => {
35
+ // A turn refused before its workspace was final never began a review.
36
+ if (!tracker.promise) return;
37
+ // Captured now: a later start (or the next turn) cannot redirect this seal.
38
+ const sessionId = tracker.sessionId;
39
+ const started = Promise.resolve(tracker.promise);
39
40
  if (signal.aborted && !continueTurn) {
40
- cancel();
41
- void Promise.resolve(tracker.promise).catch(() => {});
41
+ // A cancelled turn keeps its edits as a change record. Sealing waits
42
+ // for the snapshot start, never for the abort's settlement, and only
43
+ // seals the generation this turn began: delayed cleanup cannot seal
44
+ // a newer turn.
45
+ void started
46
+ .then((token) => (token ? completeTurnSnapshotForTurn(sessionId, token) : undefined))
47
+ .catch(() => {});
42
48
  return;
43
49
  }
44
- const cleanup = Promise.resolve(tracker.promise).then(() => completeTurnSnapshotForTurn(tracker.sessionId));
50
+ const cleanup = started.then((token) => completeTurnSnapshotForTurn(sessionId, token));
45
51
  cleanup.catch(() => {});
46
52
  try {
47
53
  await awaitTurn(() => settleWithin(cleanup, turnCleanupSettleMs));
48
54
  } catch {
49
55
  /* optional review cleanup never overrides turn settlement */
50
56
  }
51
- if (signal.aborted && !continueTurn) cancel();
52
57
  };
53
58
  return tracker;
54
59
  };
@@ -1,13 +1,11 @@
1
1
  import { runAbortable } from '../../../runtime/shared/abort-race.mjs';
2
2
 
3
3
  // Opens one turn: abort controller registration, timing, the worktree
4
- // snapshot tracker, the active-turn count and the one-shot heavy-runtime
5
- // warmup arm.
4
+ // snapshot tracker (started by session preparation once the turn's workspace
5
+ // is final), the active-turn count and the one-shot heavy-runtime warmup arm.
6
6
  export function createTurnOpener({
7
7
  createTiming,
8
8
  createSnapshot,
9
- getSession,
10
- getReservedSessionId,
11
9
  registerActiveTurnController,
12
10
  getActiveTurnCount,
13
11
  setActiveTurnCount,
@@ -41,7 +39,6 @@ export function createTurnOpener({
41
39
  const signal = controller.signal;
42
40
  const snapshot = createSnapshot(options);
43
41
  const routeStartedAt = performance.now();
44
- snapshot.start(getSession()?.id || getReservedSessionId?.());
45
42
  setActiveTurnCount(getActiveTurnCount() + 1);
46
43
  return {
47
44
  signal,
@@ -54,6 +51,8 @@ export function createTurnOpener({
54
51
  armHeavyRuntimeWarmup: heavyRuntimeWarmupArm(),
55
52
  session0: null,
56
53
  releaseFirstTitle: null,
54
+ /** Set by turn admission (admitTurnWorkspace); released by settleTurn. */
55
+ releaseWorkspace: null,
57
56
  startedAt: Date.now(),
58
57
  };
59
58
  };
@@ -21,6 +21,8 @@ export function createTurnPreparation({
21
21
  agentTool,
22
22
  getConfig,
23
23
  assertSessionAdmission,
24
+ prepareTurnWorkspace,
25
+ admitTurnWorkspace,
24
26
  }) {
25
27
  const scopedMcpTools = (session) => scopedMcpToolsFor(session, getConfig());
26
28
 
@@ -84,7 +86,7 @@ export function createTurnPreparation({
84
86
  // Historical-session resume publishes its transcript immediately while
85
87
  // provider/model metadata initializes in the background. Only the next
86
88
  // actual turn waits, guaranteeing that it cannot run on a stale route.
87
- async function prepareSession(turn, prompt) {
89
+ async function prepareSession(turn, prompt, options = {}) {
88
90
  // A closing/closed addressed runtime admits no turn (checked again after
89
91
  // every await that could have outlived a close).
90
92
  assertSessionAdmission?.();
@@ -96,6 +98,32 @@ export function createTurnPreparation({
96
98
  }
97
99
  throwIfAborted(turn.signal);
98
100
  assertSessionAdmission?.();
101
+ // Turn admission: waits while this session's workspace transitions or
102
+ // another session changes the checkout this session works in, then holds
103
+ // the turn registered (released by settleTurn) so no checkout changes
104
+ // under it.
105
+ if (typeof admitTurnWorkspace === 'function') {
106
+ turn.releaseWorkspace = await admitTurnWorkspace({ signal: turn.signal });
107
+ throwIfAborted(turn.signal);
108
+ assertSessionAdmission?.();
109
+ }
110
+ // Workspace gate: a session in recovery refuses the turn, and a pending
111
+ // worktree intent is provisioned and applied (cwd, record, prompt context)
112
+ // BEFORE the user row, the review snapshot, hooks, the provider and any
113
+ // worker spawn. The submission id is the provisioning transaction id, so a
114
+ // retried or duplicate send reuses the same worktree.
115
+ if (typeof prepareTurnWorkspace === 'function') {
116
+ await turn.awaitTurn(() =>
117
+ prepareTurnWorkspace({
118
+ submissionId: String(options.id || '').trim(),
119
+ prompt,
120
+ signal: turn.signal,
121
+ confirmLarge: options.confirmLarge === true,
122
+ })
123
+ );
124
+ throwIfAborted(turn.signal);
125
+ assertSessionAdmission?.();
126
+ }
99
127
  ensureSessionTranscriptWriter?.();
100
128
  transcript.appendUser(prompt);
101
129
  const session0 = getSession();
@@ -84,7 +84,12 @@ export function createTurnSettlement({
84
84
  turn.releaseFirstTitle?.();
85
85
  turn.emitTiming(turn.timing.status);
86
86
  turn.armHeavyRuntimeWarmup('turn-settled');
87
- await turn.snapshot.finish(turn.signal, turn.awaitTurn);
87
+ try {
88
+ await turn.snapshot.finish(turn.signal, turn.awaitTurn);
89
+ } finally {
90
+ // The turn no longer works in its checkout: transitions may proceed.
91
+ turn.releaseWorkspace?.();
92
+ }
88
93
  try {
89
94
  turn.unregister?.();
90
95
  } catch {}