mixdog 1.4.2 → 1.4.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 (417) hide show
  1. package/package.json +2 -2
  2. package/scripts/build-shipped-history.mjs +15 -5
  3. package/scripts/gate-local.mjs +65 -19
  4. package/scripts/graph-parity.mjs +8 -3
  5. package/scripts/lib/gate-scheduler.mjs +2 -1
  6. package/scripts/lib/run-node-tests.mjs +17 -5
  7. package/scripts/lib/test-failure-summary.mjs +1 -8
  8. package/scripts/lib/test-spawn-ledger.mjs +33 -2
  9. package/scripts/post-release-check.mjs +26 -16
  10. package/scripts/provider-pingpong-live.mjs +1 -1
  11. package/scripts/prune-embedding-runtime.mjs +3 -1
  12. package/scripts/release-paths.mjs +7 -1
  13. package/src/defaults/shipped-history.json +20 -0
  14. package/src/defaults/skills/setup/SKILL.md +2 -2
  15. package/src/defaults/skills/setup/references/actions.md +16 -3
  16. package/src/defaults/skills/setup/references/surfaces.md +3 -0
  17. package/src/defaults/skills/setup-guide/SKILL.md +6 -1
  18. package/src/lib/instruction-text.cjs +36 -0
  19. package/src/lib/rules-builder.cjs +34 -20
  20. package/src/orchestration/balanced.md +23 -0
  21. package/src/orchestration/focused.md +22 -0
  22. package/src/orchestration/none.md +5 -0
  23. package/src/orchestration/swarm.md +24 -0
  24. package/src/rules/agent-mode/AGENT_MODE.md +3 -1
  25. package/src/rules/agent-mode/MIXY.md +2 -2
  26. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +0 -1
  28. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +4 -2
  29. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +0 -9
  30. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
  31. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
  32. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  33. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +4 -4
  34. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -1
  35. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +199 -46
  36. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +3 -5
  37. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +9 -3
  38. package/src/runtime/agent/orchestrator/mcp/client.mjs +3 -5
  39. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
  40. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
  41. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
  42. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
  43. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  45. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
  46. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  47. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
  48. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
  49. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
  50. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
  51. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
  52. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +10 -1
  53. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
  54. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +30 -0
  55. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
  56. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
  57. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
  58. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
  59. package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
  60. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
  61. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
  62. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
  63. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
  64. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
  65. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
  66. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
  67. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
  68. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
  69. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
  70. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -48
  71. package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
  72. package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
  73. package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
  74. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +9 -0
  75. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
  76. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +1 -1
  77. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
  78. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
  79. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
  80. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
  81. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +2 -2
  82. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
  83. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
  84. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
  85. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
  86. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
  87. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
  88. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +1 -1
  89. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +1 -1
  90. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +1 -1
  91. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
  92. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
  93. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +1 -2
  94. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
  97. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  99. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
  100. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
  101. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
  102. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
  103. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
  104. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
  105. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
  106. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +6 -1
  107. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  108. package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
  109. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
  110. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +57 -26
  111. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
  112. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
  113. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
  114. package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
  115. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
  116. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
  117. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
  118. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
  119. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
  120. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  121. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
  122. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
  123. package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
  124. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
  125. package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
  126. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +19 -0
  127. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +19 -10
  128. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +5 -0
  129. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
  130. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +31 -0
  131. package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
  132. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +42 -6
  133. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
  134. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +11 -1
  135. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
  136. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
  137. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
  138. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
  139. package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
  140. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +1 -1
  141. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
  142. package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
  143. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +1 -1
  144. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
  145. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
  146. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
  147. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
  148. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
  149. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
  150. package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
  151. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
  152. package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
  153. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +14 -5
  154. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +2 -2
  155. package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
  156. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
  157. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
  158. package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
  159. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
  160. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
  161. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
  162. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
  163. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
  164. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  165. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
  166. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
  167. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +7 -3
  168. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +27 -9
  169. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
  170. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  171. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
  172. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
  173. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +1 -2
  174. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
  175. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
  176. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  177. package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
  178. package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
  179. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
  180. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
  181. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
  182. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +2 -2
  183. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +1 -1
  184. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +0 -4
  185. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
  186. package/src/runtime/attachments/attachment-reference.mjs +1 -1
  187. package/src/runtime/attachments/pdf-extract.mjs +1 -1
  188. package/src/runtime/attachments/store.d.mts +1 -0
  189. package/src/runtime/attachments/store.mjs +2 -2
  190. package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
  191. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
  192. package/src/runtime/channels/lib/scheduler.mjs +33 -0
  193. package/src/runtime/channels/lib/schedules-db.mjs +11 -4
  194. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
  195. package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
  196. package/src/runtime/channels/lib/whisper-server.mjs +12 -12
  197. package/src/runtime/channels/lib/worker-main.mjs +9 -31
  198. package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
  199. package/src/runtime/connectors/connector-accounts-mcp.mjs +169 -33
  200. package/src/runtime/connectors/gmail-app-password.mjs +2 -2
  201. package/src/runtime/connectors/google-mcp.mjs +1 -1
  202. package/src/runtime/effort-judge/judge-client.mjs +2 -2
  203. package/src/runtime/effort-judge/judge-input.mjs +4 -4
  204. package/src/runtime/explore/explorer.mjs +0 -5
  205. package/src/runtime/explore/tool.mjs +3 -3
  206. package/src/runtime/local-provider/hardware.mjs +1 -1
  207. package/src/runtime/media/adapters/codex-image.mjs +3 -3
  208. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  209. package/src/runtime/media/media-usage.mjs +1 -1
  210. package/src/runtime/media/store.mjs +1 -1
  211. package/src/runtime/memory/index.mjs +11 -1
  212. package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
  213. package/src/runtime/memory/lib/memory-embed.mjs +83 -14
  214. package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
  215. package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
  216. package/src/runtime/memory/lib/memory.mjs +17 -0
  217. package/src/runtime/memory/lib/pg/process.mjs +1 -1
  218. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
  219. package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
  220. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  221. package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
  222. package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
  223. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  224. package/src/runtime/office/capabilities.mjs +1 -1
  225. package/src/runtime/office/core/office-core.mjs +1 -1
  226. package/src/runtime/office/design/content-model.mjs +3 -3
  227. package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
  228. package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
  229. package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
  230. package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
  231. package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
  232. package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
  233. package/src/runtime/office/portable/portable-soffice.mjs +8 -6
  234. package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
  235. package/src/runtime/shared/atomic-file.d.mts +8 -0
  236. package/src/runtime/shared/background-tasks.mjs +22 -4
  237. package/src/runtime/shared/background-wait.mjs +66 -0
  238. package/src/runtime/shared/child-guardian.mjs +17 -7
  239. package/src/runtime/shared/config.mjs +313 -16
  240. package/src/runtime/shared/connector-catalog.d.mts +4 -5
  241. package/src/runtime/shared/connector-catalog.mjs +11 -1
  242. package/src/runtime/shared/file-lock.mjs +8 -3
  243. package/src/runtime/shared/git-runner.mjs +7 -2
  244. package/src/runtime/shared/idle-gc.mjs +30 -7
  245. package/src/runtime/shared/llm/http-agent.mjs +8 -5
  246. package/src/runtime/shared/llm/system-proxy.mjs +2 -1
  247. package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
  248. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
  249. package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
  250. package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
  251. package/src/runtime/shared/maintenance-schedule.mjs +109 -0
  252. package/src/runtime/shared/process-runner.mjs +8 -4
  253. package/src/runtime/shared/routine-trigger.d.mts +13 -0
  254. package/src/runtime/shared/routine-trigger.mjs +34 -0
  255. package/src/runtime/shared/run-child.d.mts +2 -1
  256. package/src/runtime/shared/run-child.mjs +70 -18
  257. package/src/runtime/shared/session-scratch.mjs +14 -2
  258. package/src/runtime/shared/shipped-definitions.mjs +7 -1
  259. package/src/runtime/shared/tool-card-model.golden.json +3 -12
  260. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  261. package/src/runtime/shared/tool-work-units.mjs +31 -6
  262. package/src/runtime/shared/turn-snapshot.mjs +26 -4
  263. package/src/runtime/shared/turn-worktree-snapshot.mjs +6 -11
  264. package/src/runtime/shared/worker-requests.mjs +17 -3
  265. package/src/runtime/shared/worktrees/branch-management.mjs +1 -5
  266. package/src/runtime/shared/worktrees/contract.mjs +16 -6
  267. package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
  268. package/src/runtime/shared/worktrees/disk.mjs +79 -2
  269. package/src/runtime/shared/worktrees/git.mjs +44 -11
  270. package/src/runtime/shared/worktrees/include.mjs +6 -4
  271. package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
  272. package/src/runtime/shared/worktrees/manager.mjs +772 -75
  273. package/src/runtime/shared/worktrees/settings.mjs +33 -7
  274. package/src/runtime/shared/worktrees/test-support.mjs +5 -1
  275. package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
  276. package/src/runtime/tidy/process.mjs +2 -1
  277. package/src/runtime/web-search/index.mjs +3 -22
  278. package/src/runtime/web-search/lib/web-tools.mjs +2 -2
  279. package/src/runtime/web-search/tool-defs.mjs +17 -26
  280. package/src/session-runtime/agent-profile-changes.mjs +55 -4
  281. package/src/session-runtime/boot/apis.mjs +27 -4
  282. package/src/session-runtime/boot/begin.mjs +2 -0
  283. package/src/session-runtime/boot/config.mjs +10 -1
  284. package/src/session-runtime/boot/facade.mjs +1 -0
  285. package/src/session-runtime/boot/providers.mjs +70 -3
  286. package/src/session-runtime/boot/session.mjs +2 -0
  287. package/src/session-runtime/boot/tools.mjs +69 -25
  288. package/src/session-runtime/channel-config-api.mjs +1 -0
  289. package/src/session-runtime/config-change-effects.mjs +179 -0
  290. package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
  291. package/src/session-runtime/config-lifecycle.mjs +160 -24
  292. package/src/session-runtime/conversation-import/discovery.mjs +86 -7
  293. package/src/session-runtime/conversation-import/service.mjs +3 -2
  294. package/src/session-runtime/goal-facade-api.mjs +49 -3
  295. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
  296. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
  297. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +3 -11
  298. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +18 -4
  299. package/src/session-runtime/internal-tool-executor.mjs +12 -19
  300. package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
  301. package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
  302. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
  303. package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
  304. package/src/session-runtime/lifecycle/teardown/session-close.mjs +4 -4
  305. package/src/session-runtime/lifecycle-api.mjs +1 -0
  306. package/src/session-runtime/mcp-glue/server-catalog.mjs +14 -3
  307. package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
  308. package/src/session-runtime/model-route/set-route.mjs +40 -7
  309. package/src/session-runtime/native-web-search/routes.mjs +3 -3
  310. package/src/session-runtime/provider-auth/refresh.mjs +6 -3
  311. package/src/session-runtime/provider-auth/setup.mjs +1 -1
  312. package/src/session-runtime/provider-readiness.mjs +53 -4
  313. package/src/session-runtime/resource-api.mjs +1 -1
  314. package/src/session-runtime/resource-extension-sync.mjs +4 -8
  315. package/src/session-runtime/resource-mcp-connector-accounts.mjs +5 -1
  316. package/src/session-runtime/resource-mcp-secrets.mjs +3 -3
  317. package/src/session-runtime/resource-plugins-api.mjs +4 -0
  318. package/src/session-runtime/routine-executor.mjs +152 -0
  319. package/src/session-runtime/routine-home-turn.mjs +46 -5
  320. package/src/session-runtime/runtime-facade.mjs +5 -0
  321. package/src/session-runtime/runtime-feature-gates.mjs +2 -11
  322. package/src/session-runtime/schedule-session-run.mjs +1 -0
  323. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
  324. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
  325. package/src/session-runtime/services/agent-tool/send-flow.mjs +110 -6
  326. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
  327. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
  328. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +24 -6
  329. package/src/session-runtime/services/agent-tool.mjs +51 -1
  330. package/src/session-runtime/services/channel-admin.mjs +18 -0
  331. package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
  332. package/src/session-runtime/services/plugin-admin.mjs +4 -0
  333. package/src/session-runtime/services/seeds.mjs +7 -0
  334. package/src/session-runtime/services/usage-stats-model.mjs +32 -11
  335. package/src/session-runtime/session-create/materialize.mjs +4 -2
  336. package/src/session-runtime/session-create/session-options.mjs +2 -0
  337. package/src/session-runtime/settings-builtin-tools-api.mjs +1 -9
  338. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +1 -1
  339. package/src/session-runtime/setup-tool/executor.mjs +8 -1
  340. package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
  341. package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
  342. package/src/session-runtime/setup-tool/tool-defs.mjs +26 -1
  343. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
  344. package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
  345. package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
  346. package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
  347. package/src/session-runtime/tool-policy-refresh.mjs +182 -5
  348. package/src/session-runtime/tool-surface.mjs +38 -1
  349. package/src/session-runtime/turn/agent-ops.mjs +10 -2
  350. package/src/session-runtime/turn/session-ops.mjs +2 -0
  351. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
  352. package/src/session-runtime/turn/turn-run.mjs +1 -1
  353. package/src/session-runtime/webhook-session-run.mjs +2 -0
  354. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +1 -4
  355. package/src/session-runtime/workflow-agents-api/agent-route.mjs +3 -10
  356. package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
  357. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
  358. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
  359. package/src/session-runtime/workflow-agents-api.mjs +2 -0
  360. package/src/session-runtime/workspace/project-branches.mjs +1 -1
  361. package/src/session-runtime/workspace/session-view.mjs +1 -1
  362. package/src/session-runtime/workspace/transitions.mjs +20 -4
  363. package/src/session-runtime/workspace/worktree-maintenance.mjs +126 -6
  364. package/src/session-runtime/workspace/worktree-setup.mjs +13 -1
  365. package/src/session-runtime/workspace/worktree-tool.mjs +16 -0
  366. package/src/standalone/daemon-agent-control.mjs +25 -8
  367. package/src/standalone/daemon-desktop-runtime.mjs +6 -2
  368. package/src/standalone/daemon-lag-profiler.mjs +7 -7
  369. package/src/standalone/daemon.mjs +54 -2
  370. package/src/standalone/local-session-runtime.mjs +16 -0
  371. package/src/standalone/session-client/daemon-unavailable.mjs +1 -1
  372. package/src/standalone/session-protocol.mjs +11 -0
  373. package/src/standalone/session-service/agent-route-follow.mjs +23 -20
  374. package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
  375. package/src/standalone/session-service/quota-resume.mjs +9 -0
  376. package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
  377. package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
  378. package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
  379. package/src/standalone/session-service/session-calls.mjs +2 -1
  380. package/src/tui/App.jsx +8 -0
  381. package/src/tui/app/clipboard.mjs +1 -1
  382. package/src/tui/app/create-app-pickers.mjs +2 -0
  383. package/src/tui/app/doctor.mjs +2 -2
  384. package/src/tui/app/panel-signature.mjs +1 -1
  385. package/src/tui/app/settings-picker.mjs +53 -8
  386. package/src/tui/app/shell-layout/row-budgets.mjs +2 -2
  387. package/src/tui/app/slash-commands.mjs +1 -1
  388. package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
  389. package/src/tui/app/slash-dispatch/session-commands.mjs +1 -1
  390. package/src/tui/app/use-prompt-queue-history.mjs +2 -2
  391. package/src/tui/app/use-transcript-activity.mjs +1 -1
  392. package/src/tui/app/use-transcript-window/geometry.mjs +1 -1
  393. package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
  394. package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
  395. package/src/tui/components/question-panel-model.mjs +4 -4
  396. package/src/tui/components/tool-execution/standard-card.jsx +3 -4
  397. package/src/tui/components/user-message-skills.mjs +1 -1
  398. package/src/tui/dist/index.mjs +309 -30
  399. package/src/tui/markdown/render-ansi.mjs +1 -1
  400. package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
  401. package/src/tui/session/agent-job-feed.mjs +2 -0
  402. package/src/tui/session/context-state.mjs +3 -0
  403. package/src/tui/session/quota-resume.mjs +1 -1
  404. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  405. package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
  406. package/src/tui/session/session-api/routes-agent-definitions.mjs +5 -0
  407. package/src/tui/session/session-api/worktree.mjs +13 -1
  408. package/src/tui/session/session-flow/drain.mjs +11 -14
  409. package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
  410. package/src/tui/session/turn-quiet.mjs +1 -1
  411. package/src/tui/session/turn.mjs +3 -0
  412. package/src/tui/session/worktree-setup-notice.mjs +1 -1
  413. package/src/tui/spinner-meta.mjs +3 -3
  414. package/src/tui/spinner-verbs.mjs +2 -2
  415. package/src/defaults/skills/goal-management/SKILL.md +0 -169
  416. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
  417. package/src/session-runtime/goal-tasks.mjs +0 -1
@@ -13,10 +13,7 @@ import {
13
13
  } from '../../runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs';
14
14
  import { sessionTailCacheExpired } from '../../runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs';
15
15
  import { mergePendingDeferredToolDelta } from '../../runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs';
16
- import {
17
- agentMcpToolPermission,
18
- connectorPolicyAgentOf,
19
- } from '../../runtime/agent/orchestrator/mcp/agent-connectors.mjs';
16
+ import { foldLateDeferredTools } from '../../runtime/agent/orchestrator/runtime-core/tool-catalog.mjs';
20
17
  import { agentListEntries } from '../../runtime/agent/orchestrator/session/manager/prompt-utils.mjs';
21
18
  import { markToolSurfaceMigrated } from '../../runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs';
22
19
  import { resetBp2StableContext } from '../../runtime/agent/orchestrator/context/collect.mjs';
@@ -92,24 +89,14 @@ function cacheCold(session) {
92
89
  );
93
90
  }
94
91
 
95
- // The connector tools among `names` the session's agent may run now.
96
- function connectorTools(session, names) {
97
- const agent = connectorPolicyAgentOf(session);
98
- return [...names]
99
- .filter((name) => name.startsWith('mcp__') && agentMcpToolPermission(agent, name) !== 'disabled')
100
- .sort();
101
- }
102
-
103
- // A bot thread's tools that changed without its prompt: feature gates that
104
- // opened (or closed) and connectors added or removed. Nothing in the request
105
- // prefix moves. An opened tool joins the deferred catalog — reachable by
92
+ // A bot thread's tools that changed without its prompt: workflow and
93
+ // reaction gates that opened (or closed). Nothing in the request prefix
94
+ // moves. An opened tool joins the late deferred catalog — reachable by
106
95
  // deferred loading, which brings its schema into the conversation — and a
107
96
  // gone one is refused at call time; the next turn's deferred_tools_delta
108
97
  // notice names both. Gate changes are folded into the prompt at the next
109
- // cold point (promptFoldPending). Connectors live in the bot's agent.json,
110
- // so they are compared only when its profile stamp moved (`edited`).
111
- // Returns true when anything changed.
112
- function stageLiveToolChanges({ liveDeniedTools, modelStandaloneTools }, session, workflow, { edited = false } = {}) {
98
+ // cold point (promptFoldPending). Returns true when anything changed.
99
+ function stageLiveToolChanges({ liveDeniedTools, modelStandaloneTools }, session, workflow) {
113
100
  const added = [];
114
101
  const removed = [];
115
102
  const known = new Map(schemaTools(session).map((tool) => [toolName(tool), tool]));
@@ -121,24 +108,17 @@ function stageLiveToolChanges({ liveDeniedTools, modelStandaloneTools }, session
121
108
  const fresh = modelStandaloneTools().filter(
122
109
  (tool) => opened.includes(toolName(tool)) && !known.has(toolName(tool))
123
110
  );
124
- if (fresh.length) session.deferredToolCatalog = [...(session.deferredToolCatalog || []), ...fresh];
111
+ // The late pool, never the boot catalog a native request keeps byte-stable.
112
+ if (fresh.length) session.deferredLateToolCatalog = [...(session.deferredLateToolCatalog || []), ...fresh];
125
113
  for (const tool of fresh) known.set(toolName(tool), tool);
126
114
  session.disallowedTools = [...live];
127
115
  added.push(...opened.filter((name) => known.has(name)));
128
116
  removed.push(...closed);
129
117
  session.promptFoldPending = true;
130
118
  }
131
- // Connectors gate MCP tools at call time only (pre-dispatch-deny.mjs).
132
- const previous = session.agentConnectorTools;
133
- const permitted = edited || !Array.isArray(previous) ? connectorTools(session, known.keys()) : previous;
134
- session.agentConnectorTools = permitted;
135
- if (edited && Array.isArray(previous)) {
136
- added.push(...permitted.filter((name) => !previous.includes(name)));
137
- removed.push(...previous.filter((name) => !permitted.includes(name)));
138
- }
139
- if (!added.length && !removed.length) {
140
- return opened.length + closed.length > 0 || !Array.isArray(previous);
141
- }
119
+ // Connector moves are staged at every turn start, for every session kind
120
+ // (tool-availability.mjs stageConnectorAvailability).
121
+ if (!added.length && !removed.length) return opened.length + closed.length > 0;
142
122
  mergePendingDeferredToolDelta(session, {
143
123
  added: added.map((name) => ({ name, description: known.get(name)?.description || '' })),
144
124
  removed,
@@ -162,7 +142,8 @@ function liftAgentDenial({ liveDeniedTools, modelStandaloneTools }, session) {
162
142
  if (!known.has('agent')) {
163
143
  const fresh = modelStandaloneTools().filter((tool) => toolName(tool) === 'agent');
164
144
  if (!fresh.length) return false;
165
- session.deferredToolCatalog = [...(session.deferredToolCatalog || []), ...fresh];
145
+ // The late pool, never the boot catalog a native request keeps byte-stable.
146
+ session.deferredLateToolCatalog = [...(session.deferredLateToolCatalog || []), ...fresh];
166
147
  known.set('agent', fresh[0]);
167
148
  }
168
149
  session.disallowedTools = disallowed.filter((name) => name !== 'agent');
@@ -185,6 +166,7 @@ export function createAgentProfileFold({
185
166
  liveDeniedTools,
186
167
  stagePolicy,
187
168
  applyPolicy,
169
+ presentPromptSettings = () => {},
188
170
  turnInFlight,
189
171
  }) {
190
172
  // An agent profile edit that met a running turn: the next turn applies it.
@@ -206,7 +188,13 @@ export function createAgentProfileFold({
206
188
  // re-appends its deferred manifest.
207
189
  if (typeof staged.stableContext === 'string') resetBp2StableContext(session, staged.stableContext);
208
190
  applyPolicy(session, staged);
191
+ // Late tools join the rebuilt manifest (MCP instructions return with the
192
+ // server's next tool load): no notice.
193
+ foldLateDeferredTools(session);
209
194
  rewriteConversationBp3Core(session, staged.core);
195
+ // Every prompt setting as it stands — style, profile, language, core
196
+ // memory, instruction files — so no part of the prompt contradicts another.
197
+ presentPromptSettings(session, staged);
210
198
  if (session.agentProfileRevision !== undefined) {
211
199
  session.agentProfileRevision = agentProfileRevision(identity.agent, { mixy: agentMode });
212
200
  const { leadPromptParts } = activeWorkflowContext(config, getDataDir());
@@ -231,7 +219,9 @@ export function createAgentProfileFold({
231
219
  // prompt they were created with; they are task-scoped, and their skill
232
220
  // bodies are still restored from current sources at Compact.
233
221
  if (!session?.id || !session.promptIdentity || isAgentOwner(session)) return false;
234
- const compacted = COLD_INTENTS.has(session.pendingCacheBreakIntent);
222
+ // A compaction is a cold point: the prompt is rebuilt instead of the
223
+ // dropped notices being sent again (pre-send compaction marks it).
224
+ const compacted = COLD_INTENTS.has(session.pendingCacheBreakIntent) || session.compactionFoldPending === true;
235
225
  if (!compacted && !(foldPending(session) && cacheCold(session))) return false;
236
226
  return foldPrompt(session, PROMPT_FOLD_INTENT);
237
227
  }
@@ -256,7 +246,7 @@ export function createAgentProfileFold({
256
246
  * release changed wait silently; both are folded in at the next cold point
257
247
  * (foldPromptIfCold). Returns true when the session changed (save it).
258
248
  */
259
- async function refreshAgentProfile({ trigger = 'save' } = {}) {
249
+ async function refreshAgentProfile({ trigger = 'save', onlyIfEdited = false } = {}) {
260
250
  const session = getSession?.();
261
251
  const identity = session?.promptIdentity;
262
252
  const agent = identity?.agent;
@@ -276,15 +266,14 @@ export function createAgentProfileFold({
276
266
  const edited =
277
267
  recoverMode || session.agentProfileRevision !== revision || (agentMode && session.agentRosterRevision !== roster);
278
268
  // At a turn's start its own turn is the one counted; nothing runs yet.
269
+ if (onlyIfEdited && !edited) return false;
279
270
  const busy = () => getSession?.() !== session || (trigger !== 'turn' && turnInFlight(session));
280
271
  if (busy()) {
281
272
  agentProfilePending = true;
282
273
  return false;
283
274
  }
284
275
  const toolsChanged = agentMode
285
- ? stageLiveToolChanges({ liveDeniedTools, modelStandaloneTools }, session, workflow, {
286
- edited: session.agentProfileRevision !== revision,
287
- })
276
+ ? stageLiveToolChanges({ liveDeniedTools, modelStandaloneTools }, session, workflow)
288
277
  : trigger === 'resume' && syncAgentListing(session);
289
278
  if (!edited) return (trigger === 'resume' && (await foldPromptIfCold())) || toolsChanged;
290
279
  // A coding session from before profile stamps keeps its prompt when it
@@ -315,14 +304,22 @@ export function createAgentProfileFold({
315
304
  * fold pending prompt changes if the cache is cold anyway. */
316
305
  async function applyPendingAgentProfile() {
317
306
  let changed = false;
318
- // A bot thread's connector baseline, before any edit can be compared to it.
319
307
  const session = getSession?.();
320
- if (session?.id && sessionModeOf(session) === AGENT_MODE && !Array.isArray(session.agentConnectorTools)) {
321
- session.agentConnectorTools = connectorTools(session, schemaTools(session).map(toolName));
322
- }
323
- if (agentProfilePending || orchestrationRecoveryNeeded(session)) {
308
+ // A bot thread compares its profile and roster stamps every turn, so hand
309
+ // edits and other processes' saves of AGENT.md, PERSONA.md and the roster
310
+ // reach it too.
311
+ // A thread from before profile stamps keeps its prompt until a save.
312
+ const botThread = Boolean(
313
+ session?.id &&
314
+ session.promptIdentity?.agent &&
315
+ sessionModeOf(session) === AGENT_MODE &&
316
+ session.agentProfileRevision !== undefined
317
+ );
318
+ const pending = agentProfilePending || orchestrationRecoveryNeeded(session);
319
+ if (pending || botThread) {
324
320
  agentProfilePending = false;
325
- changed = await refreshAgentProfile({ trigger: 'turn' });
321
+ // A turn with nothing pending acts only on moved stamps.
322
+ changed = await refreshAgentProfile({ trigger: 'turn', onlyIfEdited: !pending });
326
323
  }
327
324
  changed = (await foldPromptIfCold()) || changed;
328
325
  return syncAgentListing(session) || changed;
@@ -17,7 +17,7 @@ function modeLoadableTools(session, mode) {
17
17
  ...toolNames(session.deferredCallableTools),
18
18
  ...toolNames(session.deferredDiscoveredTools),
19
19
  ]);
20
- const deferred = new Set(toolNames(session.deferredToolCatalog));
20
+ const deferred = new Set([...toolNames(session.deferredToolCatalog), ...toolNames(session.deferredLateToolCatalog)]);
21
21
  const denied = new Set(
22
22
  [...(session.disallowedTools || []), ...(session.workflowOverlay?.deniedTools || [])].map(String)
23
23
  );
@@ -17,9 +17,19 @@ import {
17
17
  } from '../../runtime/agent/orchestrator/context/collect.mjs';
18
18
  import {
19
19
  _buildBaseRules,
20
+ _buildLeadLanguage,
21
+ _buildLeadLanguageContext,
20
22
  _buildLeadMetaContext,
21
23
  } from '../../runtime/agent/orchestrator/session/manager/rules-cache.mjs';
22
- import { sessionRolePromptFields } from '../../runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs';
24
+ import {
25
+ notePromptSettingsPresented,
26
+ promptConfigSlice,
27
+ } from '../../runtime/agent/orchestrator/session/manager/prompt-settings.mjs';
28
+ import { normalizeInstructionFilesMode } from '../../runtime/shared/instruction-files-mode.mjs';
29
+ import {
30
+ buildWorkspacePromptContext,
31
+ sessionRolePromptFields,
32
+ } from '../../runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs';
23
33
  import {
24
34
  delegationDisabled,
25
35
  honoredSchemaAllowlist,
@@ -32,14 +42,19 @@ import { AGENT_MODE, sessionModeOf } from '../../runtime/agent/orchestrator/sess
32
42
  import { unusedModelEditToolName } from '../../runtime/shared/edit-tool-dialect.mjs';
33
43
  import {
34
44
  presentedAgentCatalogSlice,
45
+ refreshSessionBp3Environment,
46
+ replaceLanguageBlock,
47
+ replaceWorkspaceCoreSlices,
48
+ replaceWorkspaceEnvironment,
35
49
  withPresentedWorkspaceSlices,
36
50
  } from '../../runtime/agent/orchestrator/session/manager/prompt-utils.mjs';
37
- import { leadPartsFor, rewriteSystemHeading, toolNames } from './surface-helpers.mjs';
51
+ import { leadPartsFor, rewriteConversationBp3Core, rewriteSystemHeading, toolNames } from './surface-helpers.mjs';
38
52
 
39
53
  export function createPolicyStage({
40
54
  getRoute,
41
55
  getMode,
42
56
  getDataDir,
57
+ getConfig,
43
58
  modelStandaloneTools,
44
59
  featureDisallowedTools,
45
60
  loadCoreMemoryContext,
@@ -96,17 +111,58 @@ export function createPolicyStage({
96
111
  }
97
112
  }
98
113
 
114
+ // The prompt-shaping settings sections `session` renders from `config` (the
115
+ // runtime's in-memory config) and `coreMemoryContext`, as session creation
116
+ // composes them (session-prompt-composition.mjs composeSessionSystem).
117
+ // `language` is the response language block closing the environment.
118
+ function promptSettingsSections(session, identity, config, coreMemoryContext) {
119
+ const ownerIsAgent = isAgentOwner(session);
120
+ const schemaAllowedTools = honoredSchemaAllowlist(session.schemaAllowedTools, {
121
+ ownerIsAgent,
122
+ agent: identity.agent,
123
+ });
124
+ const toolFreeRole = ownerIsAgent && schemaAllowedTools?.length === 0;
125
+ const agentMode = sessionModeOf(session) === AGENT_MODE;
126
+ const lead = !identity.skipAgentRules && !toolFreeRole && !ownerIsAgent;
127
+ const slice = promptConfigSlice(config);
128
+ const skip = identity.profileSkip || {};
129
+ const skills = schemaAllowedTools?.length === 0 ? [] : collectPromptSkillsCached(session.cwd, config);
130
+ const { packContext, summary, leadPromptParts, orchestrationMode } = activeWorkflowContext(config, getDataDir());
131
+ // A coding Lead's mode text, as session creation records it.
132
+ const codingLead = !ownerIsAgent && !agentMode;
133
+ return {
134
+ meta: lead ? _buildLeadMetaContext({ includeOutputStyle: !agentMode, config: slice }) : '',
135
+ // The workflow pack and the skill listing BP2 carries.
136
+ workflow: String(packContext || ''),
137
+ workflowName: summary?.name || summary?.id || null,
138
+ orchestration: codingLead ? String(leadPartsFor(session, leadPromptParts).orchestrationContext || '') : '',
139
+ orchestrationMode: codingLead ? orchestrationMode || '' : '',
140
+ skills: buildSkillManifest(skills),
141
+ instructionFilesMode: normalizeInstructionFilesMode(slice?.instructionFiles),
142
+ language: lead ? _buildLeadLanguageContext({ includeOutputStyle: !agentMode, config: slice }) : '',
143
+ instructionFiles:
144
+ toolFreeRole || agentMode || skip.claudemd ? '' : String(loadInstructionFilesContext?.(session) || ''),
145
+ coreMemory: skip.memory ? '' : String(coreMemoryContext || ''),
146
+ // Not a section: the language per-request rules match (tail-reminder-rules.mjs).
147
+ responseLanguage: lead ? _buildLeadLanguage({ config: slice }) || null : null,
148
+ };
149
+ }
150
+
99
151
  // The policy `config` gives `session`, computed without touching the
100
152
  // session, so a turn that starts during the async rebuild cannot lose tools
101
153
  // to it. `conversation`: the rebuilt BP3 core keeps the instruction files
102
154
  // and core memory the prompt presents now (withPresentedWorkspaceSlices).
103
- async function stagePolicy(session, identity, config, { conversation = false } = {}) {
155
+ // `settings`: the prompt settings sections as they stand (a fold or an
156
+ // empty rebuild presents them); `coreMemoryContext` a snapshot already read.
157
+ async function stagePolicy(session, identity, config, { conversation = false, coreMemoryContext: memory } = {}) {
104
158
  const ownerIsAgent = isAgentOwner(session);
105
159
  const schemaAllowedTools = honoredSchemaAllowlist(session.schemaAllowedTools, {
106
160
  ownerIsAgent,
107
161
  agent: identity.agent,
108
162
  });
109
163
  const toolFreeRole = ownerIsAgent && schemaAllowedTools?.length === 0;
164
+ const freshMemory = memory ?? (await leadCoreMemoryContext());
165
+ const settings = promptSettingsSections(session, identity, config, freshMemory);
110
166
 
111
167
  const {
112
168
  summary: workflow,
@@ -139,12 +195,11 @@ export function createPolicyStage({
139
195
  provider: getRoute()?.provider,
140
196
  model: getRoute()?.model,
141
197
  });
142
- const coreMemoryContext = conversation ? '' : await leadCoreMemoryContext();
198
+ const coreMemoryContext = conversation ? '' : freshMemory;
143
199
  // BP2's stable part as session creation composes it
144
200
  // (session-prompt-composition.mjs): the Lead meta context and the skill
145
201
  // manifest of the skills in scope now.
146
202
  const skipRules = identity.skipAgentRules || toolFreeRole;
147
- const skills = schemaAllowedTools?.length === 0 ? [] : collectPromptSkillsCached(session.cwd);
148
203
  const { sessionMarkerCore, stableSystemContext } = composeSystemPrompt({
149
204
  ...sessionRolePromptFields(identity, {
150
205
  ownerIsAgent,
@@ -160,8 +215,8 @@ export function createPolicyStage({
160
215
  // setting; agent mode carries none.
161
216
  instructionFilesContext:
162
217
  conversation || toolFreeRole || agentMode ? null : loadInstructionFilesContext?.(session) || null,
163
- metaContext: skipRules || ownerIsAgent ? undefined : _buildLeadMetaContext({ includeOutputStyle: !agentMode }),
164
- skillManifest: buildSkillManifest(skills),
218
+ metaContext: settings.meta || undefined,
219
+ skillManifest: settings.skills,
165
220
  });
166
221
  return {
167
222
  workflow,
@@ -174,9 +229,44 @@ export function createPolicyStage({
174
229
  core: conversation ? withPresentedWorkspaceSlices(session, sessionMarkerCore) : sessionMarkerCore,
175
230
  // Without BP1 the BP2 block cannot be located: null leaves it as it is.
176
231
  stableContext: skipRules ? null : stableSystemContext,
232
+ settings,
177
233
  };
178
234
  }
179
235
 
236
+ /**
237
+ * Make the prompt present `staged.settings` (an empty session's rebuild, a
238
+ * fold): the BP3 core's instruction files and core memory and the language
239
+ * block closing the environment; the caller has written BP2 and the core.
240
+ * A staged workspace re-root keeps the slices it will replace itself.
241
+ */
242
+ function presentPromptSettings(session, staged) {
243
+ const { settings } = staged;
244
+ if (!session.workspaceReroot) {
245
+ rewriteConversationBp3Core(
246
+ session,
247
+ replaceWorkspaceCoreSlices(staged.core, {
248
+ coreMemoryContext: settings.coreMemory,
249
+ instructionFilesContext: settings.instructionFiles,
250
+ })
251
+ );
252
+ }
253
+ if (typeof session.bp3EnvironmentContext === 'string') {
254
+ session.bp3EnvironmentContext = replaceLanguageBlock(session.bp3EnvironmentContext, settings.language);
255
+ refreshSessionBp3Environment(session, session.cwd);
256
+ }
257
+ notePromptSettingsPresented(session, settings);
258
+ }
259
+
260
+ /** An empty session's rebuild: the shell, git and listing facts as they stand. */
261
+ function refreshEnvironmentFacts(session) {
262
+ if (typeof session.bp3EnvironmentContext !== 'string' || !session.cwd || session.workspaceReroot) return;
263
+ const { environmentContext } = buildWorkspacePromptContext(session, session.cwd, {
264
+ instructionFilesMode: promptConfigSlice(getConfig?.())?.instructionFiles,
265
+ });
266
+ session.bp3EnvironmentContext = replaceWorkspaceEnvironment(session.bp3EnvironmentContext, environmentContext);
267
+ refreshSessionBp3Environment(session, session.cwd);
268
+ }
269
+
180
270
  // Apply a staged policy synchronously; the BP3 core is the caller's. The
181
271
  // prompt then carries the session's workflow and tools as they stand.
182
272
  function applyPolicy(session, staged) {
@@ -184,6 +274,7 @@ export function createPolicyStage({
184
274
  delete session.orchestrationModeOverlay;
185
275
  delete session.workflowOpenedTools;
186
276
  delete session.promptFoldPending;
277
+ delete session.compactionFoldPending;
187
278
  session.workflow = toSessionWorkflowMeta(staged.workflow);
188
279
  session.orchestrationMode = staged.orchestrationMode;
189
280
  session.sessionMode = staged.sessionMode;
@@ -197,5 +288,12 @@ export function createPolicyStage({
197
288
  session.updatedAt = Date.now();
198
289
  }
199
290
 
200
- return { liveDeniedTools, stagePolicy, applyPolicy };
291
+ return {
292
+ liveDeniedTools,
293
+ stagePolicy,
294
+ applyPolicy,
295
+ promptSettingsSections,
296
+ presentPromptSettings,
297
+ refreshEnvironmentFacts,
298
+ };
201
299
  }
@@ -78,7 +78,8 @@ export function createWorkflowOverlay({ liveDeniedTools, modelStandaloneTools })
78
78
  if (!loadableTools.length) return;
79
79
  const opened = session.workflowOpenedTools || [];
80
80
  session.workflowOpenedTools = [...new Set([...opened, ...loadableTools])];
81
- if (fresh.length) session.deferredToolCatalog = [...(session.deferredToolCatalog || []), ...fresh];
81
+ // The late pool, never the boot catalog a native request keeps byte-stable.
82
+ if (fresh.length) session.deferredLateToolCatalog = [...(session.deferredLateToolCatalog || []), ...fresh];
82
83
  session.disallowedTools = (session.disallowedTools || []).filter((name) => !loadableTools.includes(String(name)));
83
84
  const byName = new Map(schemaTools(session).map((tool) => [toolName(tool), tool]));
84
85
  // Announced on every switch that opens them: a pending removal (a switch
@@ -1,7 +1,7 @@
1
- // Refresh the empty Lead session's model-facing tool surface and BP1/BP3
2
- // layers after workflow or search/memory settings change. Conversation
3
- // sessions keep their frozen schema; the next new session picks up the
4
- // updated policy. The exceptions are a workflow or orchestration mode switch
1
+ // Bring a session to the settings as they stand at each turn start
2
+ // (reconcileTurnSettings): an empty session's tool surface and BP1/BP3 are
3
+ // rebuilt; a conversation keeps its prefix and takes moved tool gates live.
4
+ // Setters only save config. The exceptions are a workflow or orchestration mode switch
5
5
  // made in the session itself (switchSessionWorkflow,
6
6
  // switchSessionOrchestrationMode), which that conversation takes as an overlay.
7
7
  import { sessionHasConversationMessages } from '../runtime/agent/orchestrator/runtime-core/session-text.mjs';
@@ -9,6 +9,17 @@ import { createAgentProfileFold } from './tool-policy/agent-profile-fold.mjs';
9
9
  import { createPolicyStage } from './tool-policy/policy-stage.mjs';
10
10
  import { createSessionSwitches } from './tool-policy/session-switches.mjs';
11
11
  import { rewriteBp3Core } from './tool-policy/surface-helpers.mjs';
12
+ import {
13
+ stageConnectorAvailability,
14
+ stageToolAvailability,
15
+ } from '../runtime/agent/orchestrator/runtime-core/tool-availability.mjs';
16
+ import { resetBp2StableContext } from '../runtime/agent/orchestrator/context/collect.mjs';
17
+ import {
18
+ promptSettingsRecord,
19
+ stagePromptSettingsNotice,
20
+ } from '../runtime/agent/orchestrator/session/manager/prompt-settings.mjs';
21
+ import { isAgentOwner } from '../runtime/agent/orchestrator/agent-owner.mjs';
22
+ import { configForSession, currentMode } from './tool-policy/surface-helpers.mjs';
12
23
 
13
24
  export function createToolPolicyRefresh({
14
25
  getSession,
@@ -24,11 +35,21 @@ export function createToolPolicyRefresh({
24
35
  activeWorkflowContext,
25
36
  invalidatePreSessionToolSurface,
26
37
  persistSession,
38
+ toolDefinitionsFor = () => [],
39
+ getSurfaceGeneration,
27
40
  }) {
28
- const { liveDeniedTools, stagePolicy, applyPolicy } = createPolicyStage({
41
+ const {
42
+ liveDeniedTools,
43
+ stagePolicy,
44
+ applyPolicy,
45
+ promptSettingsSections,
46
+ presentPromptSettings,
47
+ refreshEnvironmentFacts,
48
+ } = createPolicyStage({
29
49
  getRoute,
30
50
  getMode,
31
51
  getDataDir,
52
+ getConfig,
32
53
  modelStandaloneTools,
33
54
  featureDisallowedTools,
34
55
  loadCoreMemoryContext,
@@ -55,6 +76,153 @@ export function createToolPolicyRefresh({
55
76
  );
56
77
  }
57
78
 
79
+ // What the gates a surface is built from read: the config object (replaced,
80
+ // never mutated, on every adopt and every reload of a change made
81
+ // elsewhere), the surface generation (skills/plugins invalidate it) and the
82
+ // live gate list (which carries bridge presence).
83
+ const configGenerations = new WeakMap();
84
+ let configCount = 0;
85
+ function availabilityKey() {
86
+ const config = getConfig?.() || {};
87
+ let generation = configGenerations.get(config);
88
+ if (generation === undefined) {
89
+ generation = ++configCount;
90
+ configGenerations.set(config, generation);
91
+ }
92
+ return `${generation}|${getSurfaceGeneration?.() || 0}|${featureDisallowedTools().join(',')}`;
93
+ }
94
+ // Session → the key it was last brought to (process-local, so a session
95
+ // first seen here, e.g. resumed, is checked once).
96
+ const appliedKeys = new WeakMap();
97
+
98
+ const conversationEmpty = (session) =>
99
+ !sessionHasConversationMessages(session) && !sessionHasConversationMessages({ messages: session.liveTurnMessages });
100
+
101
+ // The revision of the prompt settings `session` would be built from now.
102
+ function settingsRevision(session, coreMemory) {
103
+ const identity = session.promptIdentity;
104
+ if (!identity) return undefined;
105
+ const config = configForSession(getConfig(), session.workflow?.id, currentMode(session));
106
+ return promptSettingsRecord(promptSettingsSections(session, identity, config, coreMemory)).revision;
107
+ }
108
+
109
+ /** A session just built from the current settings (`coreMemory`: the
110
+ * snapshot its prompt was composed with). */
111
+ function noteToolAvailability(session, coreMemory = '') {
112
+ if (session) {
113
+ appliedKeys.set(session, {
114
+ gates: availabilityKey(),
115
+ settings: settingsRevision(session, String(coreMemory || '')),
116
+ });
117
+ }
118
+ }
119
+
120
+ /** Whether a settings change reaches the current session's whole prompt
121
+ * (no session yet, or one without a conversation, rebuilt at its turn). */
122
+ function settingsReachCurrentSession() {
123
+ const session = getSession?.();
124
+ return !session?.id || (Boolean(session.promptIdentity) && conversationEmpty(session));
125
+ }
126
+
127
+ async function readCoreMemory() {
128
+ try {
129
+ return String((await loadCoreMemoryContext?.()) || '');
130
+ } catch {
131
+ return '';
132
+ }
133
+ }
134
+
135
+ async function reconcileSession(session) {
136
+ // Connector switches are read from their (stat-cached) files every turn.
137
+ const connectors = stageConnectorAvailability(session);
138
+ const coreMemory = await readCoreMemory();
139
+ const gates = availabilityKey();
140
+ const identity = session.promptIdentity;
141
+ // The prompt settings as they stand, file-based ones included (core
142
+ // memory, instruction files, output-style files, the workflow pack, the
143
+ // skill listing): their revision is part of the key.
144
+ const sections = identity
145
+ ? promptSettingsSections(
146
+ session,
147
+ identity,
148
+ configForSession(getConfig(), session.workflow?.id, currentMode(session)),
149
+ coreMemory
150
+ )
151
+ : null;
152
+ const settings = sections ? promptSettingsRecord(sections).revision : undefined;
153
+ const applied = appliedKeys.get(session);
154
+ if (applied?.gates === gates && applied.settings === settings && !session.promptSettingsRecheck) {
155
+ return connectors ? { rebuilt: false, ...connectors } : null;
156
+ }
157
+ let rebuilt = false;
158
+ let settingsChanged = [];
159
+ if (identity && conversationEmpty(session)) {
160
+ // Nothing was sent: the whole prompt is rebuilt in place.
161
+ const staged = await stagePolicy(session, identity, getConfig(), { coreMemoryContext: coreMemory });
162
+ if (getSession?.() === session && conversationEmpty(session)) {
163
+ if (typeof staged.stableContext === 'string') resetBp2StableContext(session, staged.stableContext);
164
+ applyPolicy(session, staged);
165
+ rewriteBp3Core(session, staged.core);
166
+ presentPromptSettings(session, staged);
167
+ refreshEnvironmentFacts(session);
168
+ // The first-turn MCP fold may rebuild it in place too (an empty
169
+ // session reopened from disk was never marked).
170
+ session.deferredInitialRefreshPending = true;
171
+ rebuilt = true;
172
+ }
173
+ } else if (identity) {
174
+ // A conversation keeps its prefix: told once, folded at the next cold point.
175
+ settingsChanged = stagePromptSettingsNotice(session, sections);
176
+ // A delegated worker is never folded: after a compaction it is told
177
+ // again instead (rearmPromptSettingsNotice).
178
+ if (settingsChanged.length && !isAgentOwner(session)) session.promptFoldPending = true;
179
+ }
180
+ const staged = stageToolAvailability(session, featureDisallowedTools(), toolDefinitionsFor);
181
+ appliedKeys.set(session, { gates, settings: rebuilt ? session.promptSettings?.revision : settings });
182
+ const tools = staged || connectors;
183
+ const merged =
184
+ staged && connectors
185
+ ? { added: [...staged.added, ...connectors.added], removed: [...staged.removed, ...connectors.removed] }
186
+ : tools;
187
+ return rebuilt || tools || settingsChanged.length
188
+ ? { rebuilt, ...(merged || {}), ...(settingsChanged.length ? { settingsChanged } : {}) }
189
+ : null;
190
+ }
191
+
192
+ // One reconcile per session at a time: a turn start and a surface read of
193
+ // the same empty session share it.
194
+ const inflight = new WeakMap();
195
+
196
+ /** Turn start, any session kind: an empty session is rebuilt from current
197
+ * settings; a conversation keeps its prefix, takes moved tool gates live
198
+ * (stageToolAvailability) and prompt settings as a one-time notice. */
199
+ function reconcileTurnSettings() {
200
+ const session = getSession?.();
201
+ if (!session?.id) return Promise.resolve(null);
202
+ let running = inflight.get(session);
203
+ if (!running) {
204
+ running = reconcileSession(session).finally(() => inflight.delete(session));
205
+ inflight.set(session, running);
206
+ }
207
+ return running;
208
+ }
209
+
210
+ /** A read of an empty session's surface or status: the same reconcile, so
211
+ * what is shown is what its first turn will send. A conversation (or a
212
+ * running turn) is left to its turn start. */
213
+ function reconcileEmptySession() {
214
+ const session = getSession?.();
215
+ if (!session?.id || turnInFlight(session) || !conversationEmpty(session)) return Promise.resolve(null);
216
+ return reconcileTurnSettings();
217
+ }
218
+
219
+ /** Sync: whether an empty session's surface lags the settings gates. */
220
+ function emptySessionStale() {
221
+ const session = getSession?.();
222
+ if (!session?.id || turnInFlight(session) || !conversationEmpty(session)) return false;
223
+ return appliedKeys.get(session)?.gates !== availabilityKey();
224
+ }
225
+
58
226
  async function refreshEmptySessionToolPolicy() {
59
227
  invalidatePreSessionToolSurface?.();
60
228
  const session = getSession?.();
@@ -67,8 +235,11 @@ export function createToolPolicyRefresh({
67
235
  const staged = await stagePolicy(session, identity, getConfig());
68
236
  // Apply: re-check admission after the await, then mutate synchronously.
69
237
  if (!admitsRefresh(session)) return { appliedToCurrentSession: false };
238
+ if (typeof staged.stableContext === 'string') resetBp2StableContext(session, staged.stableContext);
70
239
  applyPolicy(session, staged);
71
240
  rewriteBp3Core(session, staged.core);
241
+ presentPromptSettings(session, staged);
242
+ refreshEnvironmentFacts(session);
72
243
  return { appliedToCurrentSession: true };
73
244
  }
74
245
 
@@ -91,10 +262,16 @@ export function createToolPolicyRefresh({
91
262
  liveDeniedTools,
92
263
  stagePolicy,
93
264
  applyPolicy,
265
+ presentPromptSettings,
94
266
  turnInFlight,
95
267
  });
96
268
 
97
269
  return {
270
+ reconcileTurnSettings,
271
+ reconcileEmptySession,
272
+ emptySessionStale,
273
+ noteToolAvailability,
274
+ settingsReachCurrentSession,
98
275
  refreshEmptySessionToolPolicy,
99
276
  switchSessionWorkflow: switches.switchSessionWorkflow,
100
277
  switchSessionOrchestrationMode: switches.switchSessionOrchestrationMode,