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
@@ -1,5 +1,12 @@
1
+ import { worktreeNameError } from './runtime/shared/worktrees/contract.mjs';
2
+
1
3
  const VALUE_OPTIONS = new Set(['--provider', '--model', '--effort', '--workflow']);
4
+ // `--worktree [name]` takes an optional value; `--worktree=<name>` is the
5
+ // unambiguous spelling.
6
+ const WORKTREE_OPTION = '--worktree';
7
+ const NO_WORKTREE_OPTION = '--no-worktree';
2
8
  const FLAG_OPTIONS = new Set([
9
+ NO_WORKTREE_OPTION,
3
10
  '--readonly',
4
11
  '--help',
5
12
  '-h',
@@ -12,7 +19,7 @@ const FLAG_OPTIONS = new Set([
12
19
  '--memory',
13
20
  '--json',
14
21
  ]);
15
- const EXEC_UNSUPPORTED_FLAGS = new Set(['--readonly', '--remote', '--onboarding', '--memory']);
22
+ const EXEC_UNSUPPORTED_FLAGS = new Set(['--readonly', '--remote', '--onboarding', '--memory', NO_WORKTREE_OPTION]);
16
23
  const HEADLESS_WORKFLOW_ERROR = 'option --workflow is not supported for mixdog exec';
17
24
 
18
25
  function roleKey(value) {
@@ -22,6 +29,16 @@ function roleKey(value) {
22
29
  .replace(/[\s_]+/g, '-');
23
30
  }
24
31
 
32
+ const isWorktreeOption = (arg) => arg === WORKTREE_OPTION || arg.startsWith(`${WORKTREE_OPTION}=`);
33
+
34
+ /** The token after a bare `--worktree` is its name unless it is an option or the exec verb. */
35
+ function worktreeNameToken(value) {
36
+ if (value === undefined || value === null) return null;
37
+ const text = String(value);
38
+ if (!text || text.startsWith('-') || roleKey(text) === 'exec') return null;
39
+ return text;
40
+ }
41
+
25
42
  function argvIndicatesExec(argv) {
26
43
  for (let index = 0; index < argv.length; index += 1) {
27
44
  const arg = String(argv[index] ?? '');
@@ -29,6 +46,11 @@ function argvIndicatesExec(argv) {
29
46
  index += 1;
30
47
  continue;
31
48
  }
49
+ if (arg === WORKTREE_OPTION) {
50
+ if (worktreeNameToken(argv[index + 1]) !== null) index += 1;
51
+ continue;
52
+ }
53
+ if (isWorktreeOption(arg)) continue;
32
54
  if (arg === '--') continue;
33
55
  if (FLAG_OPTIONS.has(arg) || arg.startsWith('-')) continue;
34
56
  return roleKey(arg) === 'exec';
@@ -39,9 +61,23 @@ function argvIndicatesExec(argv) {
39
61
  function parseTokens(argv, { strictValues = true } = {}) {
40
62
  const positional = [];
41
63
  const values = {};
64
+ let worktree;
42
65
  const allowHeadlessIntent = strictValues && !argv.includes('--react');
43
66
  for (let index = 0; index < argv.length; index += 1) {
44
67
  const arg = String(argv[index] ?? '');
68
+ if (isWorktreeOption(arg)) {
69
+ let name = arg === WORKTREE_OPTION ? null : arg.slice(WORKTREE_OPTION.length + 1);
70
+ if (name === null) {
71
+ name = worktreeNameToken(argv[index + 1]);
72
+ if (name !== null) index += 1;
73
+ }
74
+ const nameError = name === null ? null : worktreeNameError(name);
75
+ if (nameError && strictValues) {
76
+ return { error: `option --worktree name ${JSON.stringify(name)} is invalid: ${nameError}` };
77
+ }
78
+ worktree = { mode: 'worktree', name: nameError ? null : name };
79
+ continue;
80
+ }
45
81
  if (VALUE_OPTIONS.has(arg)) {
46
82
  const value = argv[index + 1];
47
83
  if (value === undefined || value === '' || String(value).startsWith('-')) {
@@ -87,7 +123,19 @@ function parseTokens(argv, { strictValues = true } = {}) {
87
123
  }
88
124
  positional.push(arg);
89
125
  }
90
- return { positional, values };
126
+ return { positional, values, worktree };
127
+ }
128
+
129
+ /**
130
+ * Session creation intent from `--worktree [name]` / `--no-worktree`:
131
+ * undefined follows the worktree settings default.
132
+ * @returns {{ worktree?: { mode: 'worktree', name: string|null } | { mode: 'branch' } } | { error: string }}
133
+ */
134
+ function worktreeIntent(argv, parsed) {
135
+ const disabled = argv.includes(NO_WORKTREE_OPTION);
136
+ if (disabled && parsed.worktree) return { error: 'options --worktree and --no-worktree are mutually exclusive' };
137
+ if (disabled) return { worktree: { mode: 'branch' } };
138
+ return parsed.worktree ? { worktree: parsed.worktree } : {};
91
139
  }
92
140
 
93
141
  function execFromPositional(positional) {
@@ -103,7 +151,10 @@ export function classifyCliInvocation(argv = []) {
103
151
  const hasPlain = argv.includes('--plain');
104
152
  const parsed = parseTokens(argv, { strictValues: !hasHelp && !hasPlain });
105
153
  if (parsed.error) return { kind: 'error', ...parsed };
154
+ const intent = worktreeIntent(argv, parsed);
155
+ if (intent.error && !hasHelp && !hasPlain) return { kind: 'error', error: intent.error };
106
156
  const options = {
157
+ ...(intent.worktree ? { worktree: intent.worktree } : {}),
107
158
  provider: parsed.values['--provider'],
108
159
  model: parsed.values['--model'],
109
160
  effort: parsed.values['--effort'],
@@ -129,7 +180,9 @@ export function classifyCliInvocation(argv = []) {
129
180
  skipHostPrelude: true,
130
181
  };
131
182
  }
132
- const unsupported = [...EXEC_UNSUPPORTED_FLAGS].find((flag) => argv.includes(flag));
183
+ const unsupported =
184
+ [...EXEC_UNSUPPORTED_FLAGS].find((flag) => argv.includes(flag)) ||
185
+ (parsed.worktree ? WORKTREE_OPTION : undefined);
133
186
  if (unsupported) {
134
187
  return {
135
188
  kind: 'error',
@@ -75,6 +75,7 @@ export async function runHeadlessExec({
75
75
  memoryRuntimeCleanup = stopStandaloneMemoryRuntimesForProcess,
76
76
  daemonRuntimeCleanup = shutdownDaemonForRuntimeRoot,
77
77
  usageLedgerCleanup = closeUsageLedgers,
78
+ sessionStoreDrain = drainHeadlessSessionStore,
78
79
  hasActiveTasks = hasActiveBackgroundTasks,
79
80
  installSignalCleanupFn = installProcessSignalCleanup,
80
81
  } = {}) {
@@ -122,6 +123,7 @@ export async function runHeadlessExec({
122
123
  memoryRuntimeCleanup,
123
124
  daemonRuntimeCleanup,
124
125
  usageLedgerCleanup,
126
+ sessionStoreDrain,
125
127
  hasActiveTasks,
126
128
  installSignalCleanupFn,
127
129
  });
@@ -155,6 +157,7 @@ async function executeHeadlessPrompt(
155
157
  memoryRuntimeCleanup,
156
158
  daemonRuntimeCleanup,
157
159
  usageLedgerCleanup,
160
+ sessionStoreDrain,
158
161
  hasActiveTasks,
159
162
  installSignalCleanupFn,
160
163
  }
@@ -172,6 +175,7 @@ async function executeHeadlessPrompt(
172
175
  writeErr,
173
176
  hasActiveTasks,
174
177
  usageLedgerCleanup,
178
+ sessionStoreDrain,
175
179
  daemonRuntimeCleanup,
176
180
  memoryRuntimeCleanup,
177
181
  });
@@ -266,7 +270,7 @@ function taskScopeFor(session) {
266
270
  // pristine root.
267
271
  function headlessCleanup(
268
272
  run,
269
- { writeErr, hasActiveTasks, usageLedgerCleanup, daemonRuntimeCleanup, memoryRuntimeCleanup }
273
+ { writeErr, hasActiveTasks, usageLedgerCleanup, sessionStoreDrain, daemonRuntimeCleanup, memoryRuntimeCleanup }
270
274
  ) {
271
275
  let cleanupPromise = null;
272
276
  const shutdown = async (reason) => {
@@ -289,6 +293,13 @@ function headlessCleanup(
289
293
  await drainAgentTrace();
290
294
  }
291
295
  });
296
+ // The session store's process-exit hook flushes any save still pending
297
+ // at exit to the data dir resolved AT THAT MOMENT — by then the boundary
298
+ // has restored the host environment, so a late write would land in the
299
+ // host's session catalog. Flush while the pristine data dir is current.
300
+ await attemptShutdownStep(errors, async () => {
301
+ if (boundary) await sessionStoreDrain();
302
+ });
292
303
  // The usage ledger lives inside the pristine root. Its open SQLite
293
304
  // handle blocks the root removal below on Windows (EBUSY) for the whole
294
305
  // rmSync retry budget, so release it once the last usage row is in.
@@ -316,6 +327,11 @@ function headlessCleanup(
316
327
  };
317
328
  }
318
329
 
330
+ async function drainHeadlessSessionStore() {
331
+ const { drainSessionStore } = await import('./runtime/agent/orchestrator/session/store.mjs');
332
+ drainSessionStore();
333
+ }
334
+
319
335
  // Runs one shutdown step, collecting its failure so the remaining steps still
320
336
  // run; true when the step succeeded.
321
337
  async function attemptShutdownStep(errors, step) {
package/src/help.mjs CHANGED
@@ -17,6 +17,8 @@ const HELP_LINES = [
17
17
  ' --web-search enable web search and page retrieval for headless exec',
18
18
  ' --json emit headless exec events as JSONL',
19
19
  ' --workflow <name> start with the given workflow active',
20
+ ' --worktree [name] run this session in a new git worktree (optionally named)',
21
+ ' --no-worktree run this session on the current branch in the project folder',
20
22
  ' --readonly read-only tool surface',
21
23
  ' --remote enable remote/channel mode for this session',
22
24
  ' --onboarding re-run the first-run setup wizard',
@@ -5,7 +5,9 @@
5
5
  independent invariants, never from the output itself or from recall.
6
6
  - After all edits, cover each required check once: one runner per runtime,
7
7
  independent checks in parallel; no read/list/diff to confirm your own
8
- writes; rerun only failed or invalidated checks.
8
+ writes; rerun only failed or invalidated checks. If repeated fixes leave
9
+ the same failure unchanged, test the underlying assumptions before
10
+ another fix.
9
11
  - Use supplied commands unchanged except inputs, else documented defaults; no
10
12
  stricter flags or unrequested suites.
11
13
  - Warnings or blocked checks never justify editing passing code. Fix obsolete
@@ -8,8 +8,10 @@
8
8
  `src/app.ts:42`); files outside the Project always by absolute path; never a
9
9
  bare name, a path relative to another folder, or a `file://` URI.
10
10
  - Deliver requested visual artifacts (SVG, diagrams, HTML pages) as saved files
11
- and give their path; never paste their source as the answer unless the user
12
- asks for the code.
11
+ and give their path; never open them in the system browser or paste their
12
+ source unless the user asks.
13
+ <!-- tools: visualize -->
14
+ - Open each finished artifact beside the chat with `visualize open` when available.
13
15
 
14
16
  <!-- tools: git -->
15
17
  - A commit request includes selecting and staging its changes; a stage-only
@@ -35,6 +35,7 @@ function maintenanceRouteToPreset(routeOrName, agent) {
35
35
  const effort = String(routeOrName.effort || '').trim();
36
36
  if (effort) out.effort = effort;
37
37
  if (routeOrName.fast === true) out.fast = true;
38
+ if (routeOrName.autoEffort === false) out.autoEffort = false;
38
39
  if (routeOrName.modelParameters && typeof routeOrName.modelParameters === 'object') {
39
40
  out.modelParameters = { ...routeOrName.modelParameters };
40
41
  }
@@ -12,6 +12,7 @@ function normalizeMaintenanceCandidate(candidate) {
12
12
  model,
13
13
  effort: String(candidate.effort || '').trim() || undefined,
14
14
  fast: candidate.fast === true,
15
+ ...(candidate.autoEffort === false ? { autoEffort: false } : {}),
15
16
  };
16
17
  }
17
18
 
@@ -77,6 +77,7 @@ export function prepareAgentSession({
77
77
  sessionId,
78
78
  mcpScopeId,
79
79
  contextPercent,
80
+ contextTokens,
80
81
  selectedContextWindow,
81
82
  }) {
82
83
  const effectivePermission = resolveAgentSessionPermission(agent, permission);
@@ -115,6 +116,7 @@ export function prepareAgentSession({
115
116
  mcpScopeId: mcpScopeId || null,
116
117
  };
117
118
  if (contextPercent) sessionOpts.contextPercent = contextPercent;
119
+ if (contextTokens) sessionOpts.contextTokens = contextTokens;
118
120
  if (selectedContextWindow) sessionOpts.selectedContextWindow = selectedContextWindow;
119
121
  if (agentTag) sessionOpts.agentTag = agentTag;
120
122
  if (effectivePermission) sessionOpts.permission = effectivePermission;
@@ -1,3 +1,4 @@
1
+ import { createHash } from 'node:crypto';
1
2
  import { statSync, readdirSync } from 'node:fs';
2
3
 
3
4
  /**
@@ -14,6 +15,28 @@ import { statSync, readdirSync } from 'node:fs';
14
15
  */
15
16
  export function maxMtimeRecursive(paths, depth = 3) {
16
17
  let max = 0;
18
+ walkMtimes(paths, depth, (_p, m) => {
19
+ if (m > max) max = m;
20
+ });
21
+ return max;
22
+ }
23
+
24
+ /**
25
+ * Exact change signature over the same walk as maxMtimeRecursive: every
26
+ * stat'ed path with its own mtime, so any single path changing (even to an
27
+ * older time) changes the result. Compare for equality only.
28
+ *
29
+ * @param {string[]} paths
30
+ * @param {number} [depth=3]
31
+ * @returns {string}
32
+ */
33
+ export function mtimeSignatureRecursive(paths, depth = 3) {
34
+ const parts = [];
35
+ walkMtimes(paths, depth, (p, m) => parts.push(`${p}:${m}`));
36
+ return createHash('sha1').update(parts.join('\n')).digest('hex');
37
+ }
38
+
39
+ function walkMtimes(paths, depth, visit) {
17
40
  function walk(p, d) {
18
41
  let st;
19
42
  try {
@@ -22,7 +45,7 @@ export function maxMtimeRecursive(paths, depth = 3) {
22
45
  return;
23
46
  }
24
47
  if (st.isDirectory()) {
25
- if (st.mtimeMs > max) max = st.mtimeMs;
48
+ visit(p, st.mtimeMs);
26
49
  if (d <= 0) return;
27
50
  let entries;
28
51
  try {
@@ -36,17 +59,15 @@ export function maxMtimeRecursive(paths, depth = 3) {
36
59
  walk(child, d - 1);
37
60
  } else if (e.isFile() && (e.name.endsWith('.md') || e.name.endsWith('.json'))) {
38
61
  try {
39
- const m = statSync(child).mtimeMs;
40
- if (m > max) max = m;
62
+ visit(child, statSync(child).mtimeMs);
41
63
  } catch {
42
64
  /* unreadable entry: skipped like a missing path */
43
65
  }
44
66
  }
45
67
  }
46
68
  } else {
47
- if (st.mtimeMs > max) max = st.mtimeMs;
69
+ visit(p, st.mtimeMs);
48
70
  }
49
71
  }
50
72
  for (const p of paths) walk(p, depth);
51
- return max;
52
73
  }
@@ -141,6 +141,8 @@ export function normalizePreset(preset) {
141
141
  const out = { id, name, type: 'agent', provider, model };
142
142
  if (preset.effort) out.effort = String(preset.effort).trim();
143
143
  if (preset.fast === true && FAST_CAPABLE_PRESET_PROVIDERS.has(provider)) out.fast = true;
144
+ // Auto effort is on unless the preset opts out; only the off state is kept.
145
+ if (preset.autoEffort === false) out.autoEffort = false;
144
146
  out.tools = ['full', 'readonly', 'mcp'].includes(preset.tools) ? preset.tools : 'full';
145
147
  return out;
146
148
  }
@@ -6,9 +6,21 @@
6
6
  * is dropped.
7
7
  */
8
8
  import { AGENT_PROVIDER_ENV, getAgentApiKey } from '../../shared/config.mjs';
9
+ import { hasAgentApiKey } from '../../shared/provider-api-key.mjs';
9
10
  import { OPENAI_COMPAT_PRESETS } from './providers/openai-compat-presets.mjs';
10
11
 
11
- export function mergeStoredProviders({ raw, defaults, includeSecrets }) {
12
+ /** `presenceOnly`: a stored key only marks its provider enabled; its value is
13
+ * neither read nor attached. */
14
+ export function mergeStoredProviders({ raw, defaults, includeSecrets, presenceOnly = false }) {
15
+ const storedKey = (name) => {
16
+ if (!presenceOnly) return getAgentApiKey(name);
17
+ return hasAgentApiKey(name) ? true : null;
18
+ };
19
+ const withKey = (entry, name, key) => ({
20
+ ...(entry || {}),
21
+ ...(presenceOnly ? {} : { apiKey: key }),
22
+ enabled: raw.providers?.[name]?.enabled !== false,
23
+ });
12
24
  // Deep-merge provider subkeys: unknown per-provider values are
13
25
  // preserved through save/load so future fields round-trip
14
26
  // without schema updates here.
@@ -39,14 +51,8 @@ export function mergeStoredProviders({ raw, defaults, includeSecrets }) {
39
51
  // stored key still ships 'no-key' → 401.
40
52
  if (includeSecrets) {
41
53
  for (const name of new Set([...Object.keys(AGENT_PROVIDER_ENV), ...Object.keys(OPENAI_COMPAT_PRESETS)])) {
42
- const kc = getAgentApiKey(name);
43
- if (kc) {
44
- mergedProviders[name] = {
45
- ...(mergedProviders[name] || {}),
46
- apiKey: kc,
47
- enabled: raw.providers?.[name]?.enabled !== false,
48
- };
49
- }
54
+ const kc = storedKey(name);
55
+ if (kc) mergedProviders[name] = withKey(mergedProviders[name], name, kc);
50
56
  }
51
57
  }
52
58
  // Custom providers: the keychain account is the generated custom-<uuid> id.
@@ -61,8 +67,8 @@ export function mergeStoredProviders({ raw, defaults, includeSecrets }) {
61
67
  if (includeSecrets) {
62
68
  for (const [name, val] of Object.entries(mergedProviders)) {
63
69
  if (val?.type !== 'custom' || !name.startsWith('custom-') || val.auth === 'none') continue;
64
- const kc = getAgentApiKey(name);
65
- if (kc) mergedProviders[name] = { ...val, apiKey: kc, enabled: raw.providers?.[name]?.enabled !== false };
70
+ const kc = storedKey(name);
71
+ if (kc) mergedProviders[name] = withKey(val, name, kc);
66
72
  }
67
73
  }
68
74
  // Cursor account access is OAuth-only. The dashboard's "API"
@@ -103,6 +103,7 @@ export function normalizeMaintenanceRoutes(rawMaint) {
103
103
  const effort = String(value.effort || '').trim();
104
104
  if (effort) route.effort = effort;
105
105
  if (value.fast === true) route.fast = true;
106
+ if (value.autoEffort === false) route.autoEffort = false;
106
107
  out[slot] = route;
107
108
  }
108
109
  return out;
@@ -4,10 +4,7 @@ import { mergeStoredProviders } from './config-providers-merge.mjs';
4
4
  import { normalizeExtensionScopes } from '../../shared/extension-scopes.mjs';
5
5
  import { applyConfigPatch, diffConfig } from '../../shared/config-patch.mjs';
6
6
  import { normalizeWorkflowSelection } from '../../shared/orchestration.mjs';
7
- import {
8
- DEFAULT_INSTRUCTION_FILES_MODE,
9
- normalizeInstructionFilesMode,
10
- } from '../../shared/instruction-files-mode.mjs';
7
+ import { DEFAULT_INSTRUCTION_FILES_MODE, normalizeInstructionFilesMode } from '../../shared/instruction-files-mode.mjs';
11
8
  import {
12
9
  DEFAULT_DISABLED_AGENT_ROSTER,
13
10
  canonicalizeAgentRouteStorage,
@@ -44,6 +41,8 @@ import {
44
41
  } from './config-storage.mjs';
45
42
  import { oauthCredentialProbeState, isOAuthProviderAvailable } from './providers/oauth-credential-probes.mjs';
46
43
  import { normalizeDeveloperConfig } from '../../shared/developer-options.mjs';
44
+ import { normalizeWorktreeSettings } from '../../shared/worktrees/settings.mjs';
45
+ import { normalizePluginMcpIntents } from './runtime-core/plugin-mcp.mjs';
47
46
 
48
47
  export const {
49
48
  PROFILE_LANGUAGES,
@@ -113,6 +112,8 @@ export function buildDefaultConfig(options = {}) {
113
112
  providers['grok-oauth'] = oauthEntry('grok-oauth');
114
113
  // Muse Code subscription (Meta Muse Spark), enabled from its stored key.
115
114
  providers['muse-code-oauth'] = oauthEntry('muse-code-oauth');
115
+ // Command Code Provider API, enabled from its stored Studio API key.
116
+ providers['command-code-oauth'] = oauthEntry('command-code-oauth');
116
117
  // Dev-only providers (Settings → Developer → Providers, one option each):
117
118
  // omitted entirely from the default config while their option is off so
118
119
  // they never surface in settings.
@@ -204,6 +205,10 @@ function storedInstructionFiles(agent) {
204
205
 
205
206
  export function loadConfig(options = {}) {
206
207
  const includeSecrets = options.secrets !== false;
208
+ // `secrets: 'presence'`: credentials are detected (env, OAuth files, which
209
+ // keychain entries exist) but no keychain value is read or attached — the
210
+ // availability view the model proxy answers a server with.
211
+ const presenceOnly = options.secrets === 'presence';
207
212
  try {
208
213
  ensureDefaultsSeparated({ stripRouteDefaults: separateStoredAgent });
209
214
  } catch (err) {
@@ -219,7 +224,7 @@ export function loadConfig(options = {}) {
219
224
  const storageNeedsMigration = agentConfigStorageNeedsMigration(raw);
220
225
  raw = canonicalizeAgentStorage(raw);
221
226
  const defaults = buildDefaultConfig({ detectCredentials: includeSecrets });
222
- const mergedProviders = mergeStoredProviders({ raw, defaults, includeSecrets });
227
+ const mergedProviders = mergeStoredProviders({ raw, defaults, includeSecrets, presenceOnly });
223
228
  // Drop unknown maintenance keys (e.g. truly legacy slot names from
224
229
  // pre-removal installs). Every valid fallback slot lives in
225
230
  // DEFAULT_MAINTENANCE, so the allow-list below is the single
@@ -248,6 +253,7 @@ export function loadConfig(options = {}) {
248
253
  const loaded = canonicalizeAgentRouteStorage({
249
254
  providers: mergedProviders,
250
255
  mcpServers,
256
+ pluginMcp: normalizePluginMcpIntents(raw.pluginMcp),
251
257
  presets: withDefaultPresets(normalizedPresets),
252
258
  default: raw.default || null,
253
259
  maintenance: { ...DEFAULT_MAINTENANCE, ...normalizedMaint },
@@ -274,6 +280,7 @@ export function loadConfig(options = {}) {
274
280
  shell: raw.shell && typeof raw.shell === 'object' ? raw.shell : {},
275
281
  update: raw.update && typeof raw.update === 'object' ? { ...raw.update } : {},
276
282
  recap: recapConfig,
283
+ worktree: normalizeWorktreeSettings(raw.worktree),
277
284
  developer: normalizeDeveloperConfig(raw.developer),
278
285
  modules: canonicalizeModulesStorage(raw.modules) || {},
279
286
  ...(raw.builtins && typeof raw.builtins === 'object'
@@ -299,6 +306,7 @@ export function loadConfig(options = {}) {
299
306
  return {
300
307
  ...defaults,
301
308
  mcpServers: {},
309
+ pluginMcp: {},
302
310
  presets: DEFAULT_PRESETS.map((p) => ({ ...p })),
303
311
  default: null,
304
312
  maintenance: { ...DEFAULT_MAINTENANCE },
@@ -316,6 +324,7 @@ export function loadConfig(options = {}) {
316
324
  shell: {},
317
325
  update: {},
318
326
  recap: { enabled: true },
327
+ worktree: normalizeWorktreeSettings(null),
319
328
  developer: {},
320
329
  modules: {},
321
330
  // No stored section at all is a brand-new profile: its built-ins start
@@ -421,9 +430,14 @@ function buildAgentSaveBuilder(config) {
421
430
  shell,
422
431
  update: config.update || {},
423
432
  recap: config.recap || {},
433
+ ...(config.worktree ? { worktree: config.worktree } : {}),
424
434
  modules,
425
435
  builtins,
426
436
  };
437
+ // Per-server intent for plugin-declared MCP servers; empty stays absent.
438
+ const pluginMcp = normalizePluginMcpIntents(config.pluginMcp);
439
+ if (Object.keys(pluginMcp).length) next.pluginMcp = pluginMcp;
440
+ else delete next.pluginMcp;
427
441
  // Developer options (developer-options.mjs); an empty set stays absent.
428
442
  if (Object.keys(developer).length) next.developer = developer;
429
443
  else if (Object.hasOwn(config, 'developer')) delete next.developer;
@@ -13,11 +13,12 @@ export {
13
13
  collectSkillsCached,
14
14
  filterSkillsExcludingDisabled,
15
15
  invalidateSkillsCache,
16
- invalidateSkillsMtimeGate,
17
16
  isSkillDisabled,
18
17
  loadSkillResource,
19
18
  skillBodyPresentInSession,
20
19
  skillMissingFeature,
20
+ skillOutsideScope,
21
+ skillOutsideScopeError,
21
22
  } from './skill-catalog.mjs';
22
23
  export {
23
24
  composeSystemPrompt,
@@ -1,4 +1,5 @@
1
1
  // Deferred-pool and MCP-instruction manifests injected into BP2.
2
+ import { parseMcpToolName } from '../../../shared/tool-primitives.mjs';
2
3
 
3
4
  export function compactPromptManifestText(value, max = 250) {
4
5
  const text = String(value || '')
@@ -100,16 +101,21 @@ function sanitizeMcpInstructionText(text, max = MCP_INSTRUCTION_MAX_CHARS) {
100
101
  * names per server doubled the MCP share of the BP2 prefix (2026-08-05 audit).
101
102
  * Server membership stays evident from the mcp__<server>__ name prefix.
102
103
  */
103
- function buildMcpInstructionsManifest(mcpServerInstructions, poolNames) {
104
+ function buildMcpInstructionsManifest(mcpServerInstructions, poolNames, catalog = []) {
104
105
  const map = mcpServerInstructions && typeof mcpServerInstructions === 'object' ? mcpServerInstructions : {};
105
106
  const pool = [
106
107
  ...new Set((Array.isArray(poolNames) ? poolNames : []).map((name) => sanitizeManifestName(name)).filter(Boolean)),
107
108
  ];
109
+ // Tool definitions carry their server (shortened names cannot be parsed).
110
+ const byName = new Map();
111
+ for (const tool of Array.isArray(catalog) ? catalog : []) {
112
+ const name = String(tool?.name || '').trim();
113
+ if (name && !byName.has(name)) byName.set(name, tool);
114
+ }
108
115
  const deferredServers = new Set();
109
116
  for (const name of pool) {
110
- const match = name.match(/^mcp__(.+?)__(.+)$/);
111
- if (!match) continue;
112
- deferredServers.add(match[1]);
117
+ const server = parseMcpToolName(byName.get(name) || name)?.server;
118
+ if (server) deferredServers.add(server);
113
119
  }
114
120
  const servers = [...deferredServers]
115
121
  .filter((server) => sanitizeManifestName(server) && sanitizeMcpInstructionText(map[server]))
@@ -170,7 +176,7 @@ function composeDeferredBp2Manifest(session, pool) {
170
176
  const parts = [];
171
177
  const deferredManifest = buildDeferredToolManifest(deferredManifestEntries(session, pool));
172
178
  if (deferredManifest) parts.push(deferredManifest);
173
- const mcpManifest = buildMcpInstructionsManifest(session.mcpServerInstructions, pool);
179
+ const mcpManifest = buildMcpInstructionsManifest(session.mcpServerInstructions, pool, session.deferredToolCatalog);
174
180
  if (mcpManifest) parts.push(mcpManifest);
175
181
  return parts.join('\n\n');
176
182
  }