mixdog 1.3.1 → 1.3.3

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 (468) hide show
  1. package/README.md +8 -4
  2. package/package.json +8 -8
  3. package/scripts/native-release-status.mjs +238 -0
  4. package/scripts/verify-runtime-dependency-versions.mjs +158 -0
  5. package/src/agents/reviewer/AGENT.md +5 -7
  6. package/src/agents/reviewer/agent.json +1 -1
  7. package/src/defaults/shipped-history.json +9 -1
  8. package/src/defaults/skills/browser-use/SKILL.md +6 -3
  9. package/src/defaults/skills/local-provider/SKILL.md +33 -6
  10. package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
  11. package/src/defaults/skills/setup/SKILL.md +23 -1
  12. package/src/defaults/skills/setup/references/actions.md +50 -3
  13. package/src/defaults/skills/setup/references/surfaces.md +23 -3
  14. package/src/defaults/skills/setup-guide/SKILL.md +7 -3
  15. package/src/defaults/skills/visualize/SKILL.md +9 -6
  16. package/src/defaults/skills/visualize/references/craft.md +8 -1
  17. package/src/help.mjs +1 -1
  18. package/src/lib/keychain-cjs.cjs +4 -1
  19. package/src/lib/rules-builder.cjs +14 -7
  20. package/src/rules/agent-mode/AGENT_MODE.md +8 -5
  21. package/src/rules/agent-mode/MIXY.md +6 -8
  22. package/src/rules/lead/LEAD.md +7 -10
  23. package/src/rules/shared/10-tool-workflow.md +4 -0
  24. package/src/rules/shared/20-research.md +2 -0
  25. package/src/rules/shared/45-destructive.md +5 -1
  26. package/src/rules/shared/60-verification.md +6 -4
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
  28. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
  29. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
  30. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
  31. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
  32. package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
  33. package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
  34. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
  35. package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
  36. package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
  37. package/src/runtime/agent/orchestrator/config.mjs +11 -0
  38. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -2
  39. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -5
  40. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
  41. package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
  42. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +84 -32
  43. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +38 -11
  44. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +15 -3
  45. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
  46. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  47. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +84 -42
  48. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
  49. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +14 -1
  50. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
  51. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +27 -8
  52. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  53. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
  54. package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
  55. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +14 -1
  56. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
  57. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  58. package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
  59. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +16 -0
  60. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
  61. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
  62. package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
  63. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
  64. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
  65. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
  66. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
  67. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +2 -1
  68. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
  69. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
  70. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
  71. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
  72. package/src/runtime/agent/orchestrator/providers/registry.mjs +19 -0
  73. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +13 -1
  74. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
  75. package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
  76. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
  77. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +5 -0
  78. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
  79. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
  80. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +10 -1
  81. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +4 -6
  82. package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
  83. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
  84. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +52 -6
  85. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +35 -13
  86. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +7 -6
  87. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
  89. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +8 -3
  90. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -1
  91. package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
  92. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
  93. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
  94. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -2
  95. package/src/runtime/agent/orchestrator/session/agent-room.mjs +196 -45
  96. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
  97. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
  98. package/src/runtime/agent/orchestrator/session/compact/continuation.mjs +15 -6
  99. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +45 -19
  100. package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
  101. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +44 -0
  102. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +185 -37
  103. package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
  104. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
  105. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
  106. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +6 -2
  107. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +4 -1
  108. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  109. package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
  110. package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +240 -0
  111. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +102 -35
  112. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
  113. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +19 -9
  114. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
  115. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
  116. package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
  117. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
  118. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +199 -109
  119. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +5 -0
  120. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +2 -0
  121. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/empty-nudge.mjs +1 -1
  122. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +62 -13
  123. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +22 -6
  124. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
  125. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +5 -5
  126. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -0
  127. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
  128. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +33 -8
  129. package/src/runtime/agent/orchestrator/session/loop/tool-exec/call-prep.mjs +5 -0
  130. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +27 -0
  131. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
  132. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
  133. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
  134. package/src/runtime/agent/orchestrator/session/manager/agent-listing-notice.mjs +102 -0
  135. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +2 -0
  136. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +13 -1
  137. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
  138. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +27 -14
  139. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +14 -0
  140. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
  141. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +1 -0
  142. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
  143. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +32 -1
  144. package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +115 -0
  145. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
  146. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +6 -0
  147. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
  148. package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
  149. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
  150. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +36 -0
  151. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
  152. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
  153. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
  154. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +28 -9
  155. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +55 -27
  156. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +4 -9
  157. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +14 -1
  158. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +7 -3
  159. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
  160. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
  161. package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
  162. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +52 -11
  163. package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
  164. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +18 -3
  165. package/src/runtime/agent/orchestrator/session/routine-result.mjs +126 -12
  166. package/src/runtime/agent/orchestrator/session/runtime-user-context.mjs +3 -1
  167. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +16 -3
  168. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
  169. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
  170. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
  171. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
  172. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
  173. package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +5 -4
  174. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +140 -0
  175. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +5 -0
  176. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +15 -5
  177. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +49 -1
  178. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +80 -1
  179. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
  180. package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
  181. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +33 -1
  182. package/src/runtime/agent/orchestrator/session/store-summary-visibility.d.mts +5 -0
  183. package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +37 -0
  184. package/src/runtime/agent/orchestrator/session/store.mjs +1 -0
  185. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
  186. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
  187. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
  188. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +35 -5
  189. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +42 -2
  190. package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +47 -14
  191. package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
  192. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +6 -3
  193. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
  194. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
  195. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
  196. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
  197. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +127 -20
  198. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +557 -0
  199. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +10 -12
  200. package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
  201. package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
  202. package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
  203. package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
  204. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
  205. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +42 -23
  206. package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
  207. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
  208. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
  209. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
  210. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
  211. package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
  212. package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
  213. package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
  214. package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
  215. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
  216. package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
  217. package/src/runtime/attachments/attachment-reference.mjs +155 -0
  218. package/src/runtime/attachments/legacy-office.mjs +110 -0
  219. package/src/runtime/attachments/limits.mjs +5 -1
  220. package/src/runtime/attachments/office-extract.mjs +3 -6
  221. package/src/runtime/attachments/pdf-extract.mjs +84 -10
  222. package/src/runtime/attachments/prompt-restore.mjs +70 -0
  223. package/src/runtime/attachments/store.mjs +109 -33
  224. package/src/runtime/browser-bridge/client.mjs +73 -20
  225. package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
  226. package/src/runtime/channels/lib/scheduler.mjs +14 -7
  227. package/src/runtime/channels/lib/state-file.mjs +15 -15
  228. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
  229. package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
  230. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
  231. package/src/runtime/channels/lib/worker-main.mjs +3 -2
  232. package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
  233. package/src/runtime/effort-judge/judge-client.mjs +66 -16
  234. package/src/runtime/effort-judge/model-install.mjs +47 -7
  235. package/src/runtime/local-provider/asset-installer.mjs +10 -4
  236. package/src/runtime/local-provider/catalog.mjs +5 -2
  237. package/src/runtime/local-provider/registered-models.mjs +64 -27
  238. package/src/runtime/local-provider/server.mjs +2 -3
  239. package/src/runtime/media/adapters/image-api.mjs +89 -0
  240. package/src/runtime/media/auth.mjs +64 -1
  241. package/src/runtime/media/catalog.mjs +66 -4
  242. package/src/runtime/media/jobs.mjs +4 -0
  243. package/src/runtime/media/lanes.mjs +46 -5
  244. package/src/runtime/media/media-usage.mjs +17 -0
  245. package/src/runtime/media/renditions.mjs +15 -15
  246. package/src/runtime/media/store.mjs +36 -35
  247. package/src/runtime/media/tool.mjs +8 -1
  248. package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
  249. package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
  250. package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
  251. package/src/runtime/memory/lib/memory-chunk-quality.mjs +14 -2
  252. package/src/runtime/memory/lib/pg/process.mjs +8 -4
  253. package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
  254. package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
  255. package/src/runtime/office/core/journal.mjs +7 -14
  256. package/src/runtime/office/design/library/design-library-core.mjs +4 -16
  257. package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
  258. package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
  259. package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
  260. package/src/runtime/office/pdf/pdf-render.mjs +30 -18
  261. package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
  262. package/src/runtime/office/portable/portable-soffice.mjs +135 -29
  263. package/src/runtime/shared/agent-avatar-sprites.mjs +23 -8
  264. package/src/runtime/shared/agent-avatar.mjs +3 -2
  265. package/src/runtime/shared/agent-kind-migration.mjs +200 -0
  266. package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
  267. package/src/runtime/shared/agent-message-envelope.mjs +44 -0
  268. package/src/runtime/shared/agent-reap-state.d.mts +4 -0
  269. package/src/runtime/shared/agent-room-host.d.mts +31 -0
  270. package/src/runtime/shared/agent-room-host.mjs +58 -0
  271. package/src/runtime/shared/agent-store.mjs +24 -7
  272. package/src/runtime/shared/agent-task-starts.mjs +27 -0
  273. package/src/runtime/shared/atomic-file.d.mts +50 -0
  274. package/src/runtime/shared/atomic-file.mjs +394 -132
  275. package/src/runtime/shared/background-tasks.mjs +7 -4
  276. package/src/runtime/shared/bot-hops.mjs +35 -0
  277. package/src/runtime/shared/bot-split-migration.mjs +1 -1
  278. package/src/runtime/shared/bounded-download.mjs +4 -2
  279. package/src/runtime/shared/config.mjs +39 -9
  280. package/src/runtime/shared/defaults-separation.mjs +6 -2
  281. package/src/runtime/shared/delegated-approval-host.mjs +74 -0
  282. package/src/runtime/shared/err-text.mjs +4 -0
  283. package/src/runtime/shared/error-presentation.mjs +22 -4
  284. package/src/runtime/shared/file-has-data.mjs +28 -0
  285. package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
  286. package/src/runtime/shared/pending-agent-work.mjs +54 -0
  287. package/src/runtime/shared/process-lifecycle.mjs +8 -12
  288. package/src/runtime/shared/projects.mjs +50 -41
  289. package/src/runtime/shared/provider-accounts.mjs +17 -12
  290. package/src/runtime/shared/redact-directories.mjs +18 -0
  291. package/src/runtime/shared/remove-directory.mjs +28 -0
  292. package/src/runtime/shared/routine-trigger.d.mts +6 -1
  293. package/src/runtime/shared/routine-trigger.mjs +14 -6
  294. package/src/runtime/shared/run-child.d.mts +3 -0
  295. package/src/runtime/shared/run-child.mjs +24 -3
  296. package/src/runtime/shared/session-baseline-store.mjs +8 -2
  297. package/src/runtime/shared/session-sidebar-host.d.mts +11 -2
  298. package/src/runtime/shared/session-sidebar-host.mjs +16 -3
  299. package/src/runtime/shared/singleton-owner.mjs +7 -6
  300. package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
  301. package/src/runtime/shared/staged-update.mjs +4 -2
  302. package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
  303. package/src/runtime/shared/tool-execution-contract.mjs +10 -0
  304. package/src/runtime/shared/tool-work-units.mjs +12 -9
  305. package/src/runtime/shared/transcript-metadata.mjs +28 -3
  306. package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
  307. package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
  308. package/src/runtime/shared/turn-snapshot.mjs +277 -124
  309. package/src/runtime/shared/user-cwd.mjs +9 -4
  310. package/src/runtime/shared/user-data-guard.mjs +92 -61
  311. package/src/runtime/shared/utf8-cut.mjs +10 -0
  312. package/src/runtime/shared/worktrees/activity-gate.mjs +251 -61
  313. package/src/runtime/shared/worktrees/contract.mjs +11 -3
  314. package/src/runtime/shared/worktrees/maintenance.mjs +11 -2
  315. package/src/runtime/shared/worktrees/manager.mjs +419 -52
  316. package/src/runtime/shared/worktrees/registry.mjs +29 -27
  317. package/src/runtime/shared/worktrees/tool-host.mjs +39 -0
  318. package/src/runtime/tidy/core-install.mjs +26 -4
  319. package/src/runtime/tidy/install.mjs +91 -23
  320. package/src/runtime/tidy/process.mjs +41 -8
  321. package/src/runtime/tidy/resolve.mjs +10 -7
  322. package/src/runtime/web-search/lib/config.mjs +4 -16
  323. package/src/session-runtime/agent-home-delivery.mjs +542 -204
  324. package/src/session-runtime/agent-profile-changes.mjs +16 -0
  325. package/src/session-runtime/agent-room-delivery.mjs +81 -35
  326. package/src/session-runtime/agent-task-sessions.mjs +811 -179
  327. package/src/session-runtime/agent-tool-routing.mjs +1 -0
  328. package/src/session-runtime/boot/apis.mjs +48 -24
  329. package/src/session-runtime/boot/config.mjs +1 -0
  330. package/src/session-runtime/boot/facade.mjs +16 -7
  331. package/src/session-runtime/boot/infrastructure.mjs +14 -2
  332. package/src/session-runtime/boot/providers.mjs +2 -2
  333. package/src/session-runtime/boot/shared.mjs +12 -6
  334. package/src/session-runtime/boot/tools.mjs +23 -3
  335. package/src/session-runtime/bot-status.mjs +432 -0
  336. package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
  337. package/src/session-runtime/config-lifecycle.mjs +60 -55
  338. package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
  339. package/src/session-runtime/held-requests.mjs +31 -33
  340. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
  341. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
  342. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +24 -26
  343. package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
  344. package/src/session-runtime/lifecycle/teardown.mjs +11 -3
  345. package/src/session-runtime/mcp-glue/connect.mjs +100 -186
  346. package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
  347. package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
  348. package/src/session-runtime/media-api.mjs +5 -2
  349. package/src/session-runtime/model-recency.mjs +1 -0
  350. package/src/session-runtime/model-route/route-tuning.mjs +4 -1
  351. package/src/session-runtime/model-route/set-route.mjs +61 -1
  352. package/src/session-runtime/owned-automation-run.mjs +8 -1
  353. package/src/session-runtime/provider-models/row-hydration.mjs +8 -1
  354. package/src/session-runtime/quick-model-rows/model-meta.mjs +2 -0
  355. package/src/session-runtime/quick-model-rows/provider-rows.mjs +7 -1
  356. package/src/session-runtime/route-resolution.mjs +16 -8
  357. package/src/session-runtime/route-state.mjs +1 -59
  358. package/src/session-runtime/routine-home-turn.mjs +5 -3
  359. package/src/session-runtime/runtime-bootstrap.mjs +5 -3
  360. package/src/session-runtime/runtime-paths.mjs +11 -5
  361. package/src/session-runtime/runtime-review-api.mjs +4 -1
  362. package/src/session-runtime/runtime-tunables.mjs +6 -0
  363. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
  364. package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
  365. package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
  366. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
  367. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +34 -19
  368. package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
  369. package/src/session-runtime/services/agent-tool/send-flow.mjs +25 -21
  370. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +7 -0
  371. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
  372. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +8 -5
  373. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
  374. package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
  375. package/src/session-runtime/services/agent-tool.mjs +6 -0
  376. package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
  377. package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
  378. package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
  379. package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
  380. package/src/session-runtime/services/plugin-admin.mjs +26 -26
  381. package/src/session-runtime/services/provider-admin.mjs +26 -6
  382. package/src/session-runtime/services/schedule-access.mjs +33 -4
  383. package/src/session-runtime/services/seeds.mjs +4 -3
  384. package/src/session-runtime/services/usage-dashboard.mjs +1 -1
  385. package/src/session-runtime/services/usage-stats-model.mjs +2 -1
  386. package/src/session-runtime/services/worktree-access.mjs +27 -0
  387. package/src/session-runtime/session-create/materialize.mjs +2 -3
  388. package/src/session-runtime/session-create/session-options.mjs +15 -2
  389. package/src/session-runtime/session-hooks.mjs +9 -17
  390. package/src/session-runtime/settings-builtin-tools-api.mjs +65 -1
  391. package/src/session-runtime/settings-compaction-api.mjs +86 -39
  392. package/src/session-runtime/setup-tool/executor.mjs +12 -2
  393. package/src/session-runtime/setup-tool/settings-contract.mjs +34 -1
  394. package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
  395. package/src/session-runtime/skills-api.mjs +12 -5
  396. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +349 -0
  397. package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
  398. package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
  399. package/src/session-runtime/tool-policy/policy-stage.mjs +183 -0
  400. package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
  401. package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
  402. package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
  403. package/src/session-runtime/tool-policy-refresh.mjs +48 -369
  404. package/src/session-runtime/tool-surface.mjs +10 -4
  405. package/src/session-runtime/turn/session-ops.mjs +8 -0
  406. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +95 -88
  407. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  408. package/src/session-runtime/turn/turn-run.mjs +7 -2
  409. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
  410. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +527 -333
  411. package/src/session-runtime/workflow-agents-api/agent-route.mjs +85 -63
  412. package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
  413. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
  414. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
  415. package/src/session-runtime/workspace/transition-steps.mjs +1 -18
  416. package/src/session-runtime/workspace/transitions.mjs +279 -67
  417. package/src/session-runtime/workspace/workspace-state.mjs +7 -6
  418. package/src/session-runtime/workspace/worktree-tool.mjs +194 -0
  419. package/src/standalone/daemon-agent-control.mjs +4 -1
  420. package/src/standalone/daemon-lag-profiler.mjs +3 -1
  421. package/src/standalone/daemon-session-control.mjs +173 -15
  422. package/src/standalone/daemon-telemetry.mjs +9 -0
  423. package/src/standalone/daemon.mjs +33 -10
  424. package/src/standalone/local-session-runtime.mjs +33 -16
  425. package/src/standalone/session-client.mjs +7 -2
  426. package/src/standalone/session-protocol.mjs +8 -0
  427. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +2 -0
  428. package/src/standalone/session-service/agent-route-follow.mjs +69 -0
  429. package/src/standalone/session-service/session-calls/session-turns.mjs +33 -4
  430. package/src/standalone/session-service.mjs +21 -0
  431. package/src/standalone/session-state-projection.mjs +19 -9
  432. package/src/standalone/session-tool-output.mjs +36 -9
  433. package/src/standalone/staged-import.mjs +47 -0
  434. package/src/tui/App.jsx +2 -0
  435. package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
  436. package/src/tui/app/message-selector.mjs +15 -2
  437. package/src/tui/app/model-options.mjs +16 -2
  438. package/src/tui/app/model-picker.mjs +2 -1
  439. package/src/tui/app/route-pickers.mjs +3 -1
  440. package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
  441. package/src/tui/app/slash-commands.mjs +1 -1
  442. package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
  443. package/src/tui/dist/index.mjs +617 -369
  444. package/src/tui/paste-attachments.mjs +0 -1
  445. package/src/tui/paste-text-policy.mjs +4 -5
  446. package/src/tui/prompt-history-store.mjs +16 -21
  447. package/src/tui/session/agent-job-feed/execution-delivery.mjs +4 -1
  448. package/src/tui/session/context-state.mjs +4 -0
  449. package/src/tui/session/notice-surface.mjs +3 -0
  450. package/src/tui/session/session-api/intake/abort.mjs +52 -18
  451. package/src/tui/session/session-api/intake/rewind.mjs +39 -4
  452. package/src/tui/session/session-api/media.mjs +2 -1
  453. package/src/tui/session/session-api/routes-agent-definitions.mjs +76 -0
  454. package/src/tui/session/session-api/routes-write.mjs +203 -0
  455. package/src/tui/session/session-api/routes.mjs +23 -247
  456. package/src/tui/session/session-api/settings.mjs +14 -1
  457. package/src/tui/session/session-flow/drain.mjs +28 -3
  458. package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
  459. package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
  460. package/src/tui/session/session-flow/steering.mjs +8 -3
  461. package/src/tui/session/tool-approval.mjs +142 -14
  462. package/src/tui/session/transcript-intake.mjs +2 -0
  463. package/src/tui/session/turn.mjs +23 -14
  464. package/src/tui/transcript-tool-failures.mjs +8 -2
  465. package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
  466. package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
  467. package/src/rules/agent-mode/ROUTINE.md +0 -6
  468. package/src/session-runtime/room-member-gate.mjs +0 -48
@@ -5,6 +5,68 @@ import {
5
5
  } from '../../../runtime/agent/orchestrator/runtime-core/tool-catalog.mjs';
6
6
  import { throwIfAborted } from '../../../runtime/shared/abort-race.mjs';
7
7
 
8
+ function scheduleFirstTitle(sessionTitles, session0, prompt) {
9
+ let resolve = null;
10
+ const after = new Promise((done) => {
11
+ resolve = done;
12
+ });
13
+ const release = () => {
14
+ if (!resolve) return;
15
+ const done = resolve;
16
+ resolve = null;
17
+ done();
18
+ };
19
+ try {
20
+ sessionTitles?.scheduleFirst(session0, prompt, { after });
21
+ } catch {
22
+ /* title fallback stays the preview */
23
+ }
24
+ return release;
25
+ }
26
+
27
+ async function foldMcpSurface(turn, session0, scopedMcpTools) {
28
+ // Slower servers remain available through the late-tool path; a reconnect
29
+ // in flight gets the same short TTFT grace BEFORE folding the catalog so it
30
+ // cannot hold the provider request. No reconnect in flight → no-op.
31
+ const awaitGrace = async (options) => {
32
+ try {
33
+ await turn.awaitTurn(() => turn.timing.awaitMcpGrace(options));
34
+ } catch {
35
+ /* gate must never break the turn */
36
+ }
37
+ };
38
+ if (session0.deferredInitialRefreshPending) {
39
+ // FIRST TURN of a FRESH session (session-local gate, NOT the process-wide
40
+ // firstTurnCompleted): an MCP server may have finished its handshake
41
+ // BETWEEN session-create and this first send. Re-fold the LIVE registry
42
+ // into the INITIAL provider-visible surface (sync, in-place, idempotent).
43
+ // One-shot: cleared before the fold so a throw still never re-runs it,
44
+ // and a resumed session (flag unset) skips straight to the late path.
45
+ session0.deferredInitialRefreshPending = false;
46
+ // A spawned agent runtime owns a fresh MCP scope whose connect starts at
47
+ // its boot, so the 0 ms default grace would hide every MCP tool from the
48
+ // agent's first (often only) turn. Agents are not on the user's TTFT
49
+ // path: wait for the initial connect within the server startup budget.
50
+ const agentOwned = session0.owner === 'agent' || session0.visibility === 'agent-only';
51
+ await awaitGrace({ untilConnected: agentOwned });
52
+ try {
53
+ refreshInitialDeferredMcpSurface(session0, scopedMcpTools(session0));
54
+ } catch {
55
+ /* first-turn MCP fold must never break the turn */
56
+ }
57
+ return;
58
+ }
59
+ await awaitGrace();
60
+ try {
61
+ // Persist a typed world-state delta on the session. askSession attaches
62
+ // it to THIS real prompt; reconciliation itself never enqueues a
63
+ // follow-up turn.
64
+ reconcileDeferredMcpToolCatalog(session0, scopedMcpTools(session0));
65
+ } catch {
66
+ /* MCP delta must never break the turn */
67
+ }
68
+ }
69
+
8
70
  // Session preparation before askSession: route readiness, session creation,
9
71
  // transcript user row, first title, the MCP surface fold, and the
10
72
  // UserPromptSubmit hook.
@@ -27,68 +89,34 @@ export function createTurnPreparation({
27
89
  admitTurnWorkspace,
28
90
  applyPendingRoute,
29
91
  applyPendingAgentProfile,
92
+ applyPendingSessionSwitches,
30
93
  }) {
31
- const scopedMcpTools = (session) => scopedMcpToolsFor(session, getConfig());
32
-
33
- function scheduleFirstTitle(session0, prompt) {
34
- let resolve = null;
35
- const after = new Promise((done) => {
36
- resolve = done;
37
- });
38
- const release = () => {
39
- if (!resolve) return;
40
- const done = resolve;
41
- resolve = null;
42
- done();
43
- };
44
- try {
45
- sessionTitles?.scheduleFirst(session0, prompt, { after });
46
- } catch {
47
- /* title fallback stays the preview */
48
- }
49
- return release;
50
- }
51
-
52
- async function foldMcpSurface(turn, session0) {
53
- // Slower servers remain available through the late-tool path; a reconnect
54
- // in flight gets the same short TTFT grace BEFORE folding the catalog so it
55
- // cannot hold the provider request. No reconnect in flight → no-op.
56
- const awaitGrace = async (options) => {
57
- try {
58
- await turn.awaitTurn(() => turn.timing.awaitMcpGrace(options));
59
- } catch {
60
- /* gate must never break the turn */
61
- }
62
- };
63
- if (session0.deferredInitialRefreshPending) {
64
- // FIRST TURN of a FRESH session (session-local gate, NOT the process-wide
65
- // firstTurnCompleted): an MCP server may have finished its handshake
66
- // BETWEEN session-create and this first send. Re-fold the LIVE registry
67
- // into the INITIAL provider-visible surface (sync, in-place, idempotent).
68
- // One-shot: cleared before the fold so a throw still never re-runs it,
69
- // and a resumed session (flag unset) skips straight to the late path.
70
- session0.deferredInitialRefreshPending = false;
71
- // A spawned agent runtime owns a fresh MCP scope whose connect starts at
72
- // its boot, so the 0 ms default grace would hide every MCP tool from the
73
- // agent's first (often only) turn. Agents are not on the user's TTFT
74
- // path: wait for the initial connect within the server startup budget.
75
- const agentOwned = session0.owner === 'agent' || session0.visibility === 'agent-only';
76
- await awaitGrace({ untilConnected: agentOwned });
77
- try {
78
- refreshInitialDeferredMcpSurface(session0, scopedMcpTools(session0));
79
- } catch {
80
- /* first-turn MCP fold must never break the turn */
81
- }
82
- return;
94
+ async function admitWorkspace(turn, prompt, options) {
95
+ // Turn admission: waits while this session's workspace transitions or
96
+ // another session changes the checkout this session works in, then holds
97
+ // the turn registered (released by settleTurn) so no checkout changes
98
+ // under it.
99
+ if (typeof admitTurnWorkspace === 'function') {
100
+ turn.releaseWorkspace = await admitTurnWorkspace({ signal: turn.signal });
101
+ throwIfAborted(turn.signal);
102
+ assertSessionAdmission?.();
83
103
  }
84
- await awaitGrace();
85
- try {
86
- // Persist a typed world-state delta on the session. askSession attaches
87
- // it to THIS real prompt; reconciliation itself never enqueues a
88
- // follow-up turn.
89
- reconcileDeferredMcpToolCatalog(session0, scopedMcpTools(session0));
90
- } catch {
91
- /* MCP delta must never break the turn */
104
+ // Workspace gate: a session in recovery refuses the turn, and a pending
105
+ // worktree intent is provisioned and applied (cwd, record, prompt context)
106
+ // BEFORE the user row, the review snapshot, hooks, the provider and any
107
+ // worker spawn. The submission id is the provisioning transaction id, so a
108
+ // retried or duplicate send reuses the same worktree.
109
+ if (typeof prepareTurnWorkspace === 'function') {
110
+ await turn.awaitTurn(() =>
111
+ prepareTurnWorkspace({
112
+ submissionId: String(options.id || '').trim(),
113
+ prompt,
114
+ signal: turn.signal,
115
+ confirmLarge: options.confirmLarge === true,
116
+ })
117
+ );
118
+ throwIfAborted(turn.signal);
119
+ assertSessionAdmission?.();
92
120
  }
93
121
  }
94
122
 
@@ -116,37 +144,16 @@ export function createTurnPreparation({
116
144
  // on the session it runs on (as completeTurn adopts it afterwards).
117
145
  const stored = mgr.getSession(getSession().id);
118
146
  if (stored && stored !== getSession()) setSession(stored);
119
- // Turn admission: waits while this session's workspace transitions or
120
- // another session changes the checkout this session works in, then holds
121
- // the turn registered (released by settleTurn) so no checkout changes
122
- // under it.
123
- if (typeof admitTurnWorkspace === 'function') {
124
- turn.releaseWorkspace = await admitTurnWorkspace({ signal: turn.signal });
125
- throwIfAborted(turn.signal);
126
- assertSessionAdmission?.();
127
- }
128
- // Workspace gate: a session in recovery refuses the turn, and a pending
129
- // worktree intent is provisioned and applied (cwd, record, prompt context)
130
- // BEFORE the user row, the review snapshot, hooks, the provider and any
131
- // worker spawn. The submission id is the provisioning transaction id, so a
132
- // retried or duplicate send reuses the same worktree.
133
- if (typeof prepareTurnWorkspace === 'function') {
134
- await turn.awaitTurn(() =>
135
- prepareTurnWorkspace({
136
- submissionId: String(options.id || '').trim(),
137
- prompt,
138
- signal: turn.signal,
139
- confirmLarge: options.confirmLarge === true,
140
- })
141
- );
142
- throwIfAborted(turn.signal);
143
- assertSessionAdmission?.();
144
- }
147
+ await admitWorkspace(turn, prompt, options);
145
148
  const modelSwitch = applyPendingRoute?.();
149
+ // An orchestration mode or workflow chosen while the previous turn ran
150
+ // applies from this one (before a cold-cache fold can take it in).
151
+ const sessionSwitches = applyPendingSessionSwitches?.();
146
152
  // An agent profile saved while the previous turn ran applies from this one.
147
153
  await applyPendingAgentProfile?.();
148
154
  options.onRouteApplied?.(getSession());
149
155
  if (modelSwitch) options.onModelSwitch?.(modelSwitch);
156
+ if (sessionSwitches) options.onSessionSwitches?.(sessionSwitches);
150
157
  ensureSessionTranscriptWriter?.();
151
158
  transcript.appendUser(prompt);
152
159
  const session0 = getSession();
@@ -155,8 +162,8 @@ export function createTurnPreparation({
155
162
  // preparation. Worker apply_patch diffs bind to this generation and cannot
156
163
  // leak into the next turn/session.
157
164
  turn.snapshot.start(session0?.id);
158
- turn.releaseFirstTitle = scheduleFirstTitle(session0, prompt);
159
- await foldMcpSurface(turn, session0);
165
+ turn.releaseFirstTitle = scheduleFirstTitle(sessionTitles, session0, prompt);
166
+ await foldMcpSurface(turn, session0, (session) => scopedMcpToolsFor(session, getConfig()));
160
167
  hooks.emit('turn:start', { sessionId: session0.id, prompt, cwd: getCurrentCwd() });
161
168
  try {
162
169
  agentTool?.upsertLeadSession?.(session0, {
@@ -2,7 +2,7 @@ import { traceTurnTiming } from '../../../runtime/agent/orchestrator/agent-trace
2
2
 
3
3
  // TTFT telemetry for one turn: emitted once (first visible progress or
4
4
  // settlement), to the in-process event and the durable trace row.
5
- export function createTurnTimingFactory({ getSession, awaitInitialMcpConnect, mcpTurnGraceMs }) {
5
+ export function createTurnTimingFactory({ getSession, awaitInitialMcpConnect, mcpTurnGraceMs, mcpAgentGraceMs }) {
6
6
  return function createTurnTiming(options) {
7
7
  const startedAt = performance.now();
8
8
  const startedAtEpoch = Date.now();
@@ -39,11 +39,12 @@ export function createTurnTimingFactory({ getSession, awaitInitialMcpConnect, mc
39
39
  }
40
40
  };
41
41
  // Give an in-flight MCP connect only a short TTFT grace. untilConnected
42
- // waits for the initial connect bounded only by the server startup budget.
42
+ // (a spawned agent's first turn) gets the longer, still bounded, agent
43
+ // grace; the gate additionally never exceeds the server startup budget.
43
44
  timing.awaitMcpGrace = async ({ untilConnected = false } = {}) => {
44
45
  const graceStartedAt = performance.now();
45
46
  try {
46
- await awaitInitialMcpConnect?.(untilConnected ? undefined : mcpTurnGraceMs);
47
+ await awaitInitialMcpConnect?.(untilConnected ? mcpAgentGraceMs : mcpTurnGraceMs);
47
48
  } finally {
48
49
  timing.mcpWaitMs += performance.now() - graceStartedAt;
49
50
  }
@@ -21,17 +21,19 @@ export function createTurnRunner(deps) {
21
21
  getCurrentCwd,
22
22
  mgr,
23
23
  mcpTurnGraceMs = 0,
24
+ mcpAgentGraceMs = 3_000,
24
25
  endComputerExecution = async () => false,
25
26
  deferComputerSessionRelease = () => false,
26
27
  beginTurnSnapshotForTurn = beginTurnSnapshot,
27
28
  completeTurnSnapshotForTurn = completeTurnSnapshot,
28
29
  turnCleanupSettleMs = 2_000,
29
30
  getConfig = () => null,
31
+ currentAgents,
30
32
  } = deps;
31
33
  const transcript = createTurnTranscript(deps);
32
34
  const openTurn = createTurnOpener({
33
35
  ...deps,
34
- createTiming: createTurnTimingFactory({ ...deps, mcpTurnGraceMs }),
36
+ createTiming: createTurnTimingFactory({ ...deps, mcpTurnGraceMs, mcpAgentGraceMs }),
35
37
  createSnapshot: createSnapshotTrackerFactory({
36
38
  getCurrentCwd,
37
39
  beginTurnSnapshotForTurn,
@@ -80,7 +82,10 @@ export function createTurnRunner(deps) {
80
82
  plannedToolCalls(session0, options),
81
83
  getCurrentCwd(),
82
84
  options.prefetch || null,
83
- callbacks
85
+ // The agents enabled now (coding Leads), asked for each user turn
86
+ // the ask prepares, for its agent list reminder
87
+ // (manager/agent-listing-notice.mjs).
88
+ { ...callbacks, agentsNow: currentAgents }
84
89
  );
85
90
  } finally {
86
91
  releaseWebSearchUsage?.();
@@ -1,13 +1,16 @@
1
1
  import { readdirSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import {
4
+ assertConnectorPolicyNotWidened,
4
5
  CONNECTOR_PERMISSIONS,
5
6
  connectorEnabled,
6
7
  DENY_ALL_CONNECTORS,
7
8
  migrateLegacyConnectorPolicy,
9
+ NO_WIDEN_MESSAGE,
8
10
  PROJECT_CONNECTORS_FILE,
9
11
  parseConnectorPolicy,
10
12
  readProjectConnectorsFile,
13
+ setConnectorToolPermissionWriter,
11
14
  storedConnectorPolicy,
12
15
  } from '../../runtime/agent/orchestrator/mcp/agent-connectors.mjs';
13
16
  import {
@@ -88,19 +91,26 @@ export function createAgentConnectorsApi(deps, editor) {
88
91
  return switches(editor.getAgentConnectorPolicy(agentId));
89
92
  }
90
93
 
91
- /** Switch one connector on or off for the agent; returns its switches. */
92
- async function setAgentConnectorEnabled(agentId, connectorId, enabled) {
94
+ /** Switch one connector on or off for the agent; returns its switches.
95
+ * `options.noWiden` (set by the host for a remote client, never by a caller's
96
+ * payload) refuses a change that gives the agent more authority; it is judged
97
+ * against the stored policy in the same synchronous stretch as the write, so
98
+ * a restriction landing meanwhile is never overwritten. */
99
+ async function setAgentConnectorEnabled(agentId, connectorId, enabled, options) {
93
100
  const id = requireId(connectorId, 'connector id');
94
101
  if (typeof enabled !== 'boolean') throw new TypeError('enabled must be a boolean');
95
102
  const policy = editablePolicy(agentId);
96
103
  const off = enabled ? policy.off.filter((entry) => entry !== id) : [...policy.off, id];
104
+ if (options?.noWiden) {
105
+ assertConnectorPolicyNotWidened(editor.getAgentConnectorPolicy(agentId), { off, tools: policy.tools });
106
+ }
97
107
  await editor.setAgentConnectorPolicy(agentId, storedConnectorPolicy({ off, tools: policy.tools }));
98
108
  return getAgentConnectors(agentId);
99
109
  }
100
110
 
101
111
  // Older per-tool overrides keep working (the profile no longer shows them):
102
112
  // `permission` null drops the tool's entry, so the tool is auto again.
103
- async function setAgentConnectorToolPermission(agentId, connectorId, toolName, permission) {
113
+ async function setAgentConnectorToolPermission(agentId, connectorId, toolName, permission, options) {
104
114
  if (permission != null && !CONNECTOR_PERMISSIONS.includes(permission)) {
105
115
  throw new Error(`permission must be one of ${CONNECTOR_PERMISSIONS.join(', ')}`);
106
116
  }
@@ -110,12 +120,45 @@ export function createAgentConnectorsApi(deps, editor) {
110
120
  const own = { ...policy.tools[server] };
111
121
  if (permission == null) delete own[tool];
112
122
  else own[tool] = permission;
123
+ if (options?.noWiden) {
124
+ assertConnectorPolicyNotWidened(editor.getAgentConnectorPolicy(agentId), {
125
+ off: policy.off,
126
+ tools: { ...policy.tools, [server]: own },
127
+ });
128
+ }
113
129
  return editor.setAgentConnectorPolicy(
114
130
  agentId,
115
131
  storedConnectorPolicy({ off: policy.off, tools: { ...policy.tools, [server]: own } })
116
132
  );
117
133
  }
118
134
 
135
+ // A card's "항상 허용" for a connector tool saves through this same writer.
136
+ setConnectorToolPermissionWriter(setAgentConnectorToolPermission);
137
+
138
+ /** `[{ connector, tool }]`: the connector tools this agent may run without
139
+ * asking (an explicit `auto` entry in its own policy). The profile lists
140
+ * them so each can be turned back to asking. */
141
+ function getAgentAlwaysAllowedTools(agentId) {
142
+ const tools = editor.getAgentConnectorPolicy(agentId)?.tools || {};
143
+ return Object.entries(tools)
144
+ .flatMap(([connector, own]) =>
145
+ Object.entries(own)
146
+ .filter(([, permission]) => permission === 'auto')
147
+ .map(([tool]) => ({ connector, tool }))
148
+ )
149
+ .sort((a, b) => a.connector.localeCompare(b.connector) || a.tool.localeCompare(b.tool));
150
+ }
151
+
152
+ /** Replace the agent's connector policy (null removes it). With `options.noWiden`
153
+ * the replacement may not give any tool more authority than the stored policy. */
154
+ async function setAgentConnectors(agentId, connectors, options) {
155
+ if (options?.noWiden) {
156
+ const next = connectors == null ? null : parseConnectorPolicy(connectors);
157
+ assertConnectorPolicyNotWidened(editor.getAgentConnectorPolicy(agentId), next);
158
+ }
159
+ return editor.setAgentConnectorPolicy(agentId, connectors);
160
+ }
161
+
119
162
  /** The registered Project at `projectPath` (its path is the policy key). */
120
163
  function registeredProject(projectPath) {
121
164
  const path = requireId(projectPath, 'project path');
@@ -157,13 +200,16 @@ export function createAgentConnectorsApi(deps, editor) {
157
200
  }
158
201
 
159
202
  /** Switch one connector on or off for the project; returns its switches. */
160
- function setProjectConnectorEnabled(projectPath, connectorId, enabled) {
203
+ function setProjectConnectorEnabled(projectPath, connectorId, enabled, options) {
161
204
  const id = requireId(connectorId, 'connector id');
162
205
  if (typeof enabled !== 'boolean') throw new TypeError('enabled must be a boolean');
163
206
  const root = registeredProject(projectPath);
164
207
  updateProjectPolicies((byRoot) => {
165
208
  const key = [...byRoot.keys()].find((entry) => samePath(entry, root)) ?? root;
166
- const off = (byRoot.get(key) || []).filter((entry) => entry !== id);
209
+ const current = byRoot.get(key) || [];
210
+ // Under the policy file lock, against the file as it is now.
211
+ if (options?.noWiden && enabled && current.includes(id)) throw new Error(NO_WIDEN_MESSAGE);
212
+ const off = current.filter((entry) => entry !== id);
167
213
  byRoot.set(key, enabled ? off : [...off, id]);
168
214
  });
169
215
  return getProjectConnectors(root);
@@ -202,7 +248,7 @@ export function createAgentConnectorsApi(deps, editor) {
202
248
  );
203
249
  if (next) manifest.connectors = next;
204
250
  else delete manifest.connectors;
205
- writeJsonAtomicSync(file, manifest);
251
+ writeJsonAtomicSync(file, manifest, { backup: true });
206
252
  agents.push(entry.name);
207
253
  }
208
254
  const config = getConfig?.();
@@ -229,9 +275,10 @@ export function createAgentConnectorsApi(deps, editor) {
229
275
  listConnectors,
230
276
  listConnectorTools,
231
277
  getAgentConnectors,
232
- setAgentConnectors: editor.setAgentConnectorPolicy,
278
+ setAgentConnectors,
233
279
  setAgentConnectorEnabled,
234
280
  setAgentConnectorToolPermission,
281
+ getAgentAlwaysAllowedTools,
235
282
  getProjectConnectors,
236
283
  setProjectConnectorEnabled,
237
284
  migrateConnectorPolicies,