mixdog 1.4.1 → 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 (630) hide show
  1. package/package.json +4 -3
  2. package/scripts/build-shipped-history.mjs +125 -33
  3. package/scripts/gate-local.mjs +220 -63
  4. package/scripts/graph-parity.mjs +8 -3
  5. package/scripts/lib/gate-scheduler.mjs +139 -32
  6. package/scripts/lib/gate-timing-reporter.mjs +16 -0
  7. package/scripts/lib/run-node-tests.mjs +71 -34
  8. package/scripts/lib/scoped-temp.mjs +1 -0
  9. package/scripts/lib/test-failure-records.mjs +14 -1
  10. package/scripts/lib/test-failure-summary.mjs +9 -4
  11. package/scripts/lib/test-spawn-ledger.mjs +43 -3
  12. package/scripts/post-release-check.mjs +26 -16
  13. package/scripts/pptx-kit-index.mjs +5 -6
  14. package/scripts/provider-pingpong-live.mjs +1 -1
  15. package/scripts/prune-embedding-runtime.mjs +3 -1
  16. package/scripts/release-paths.mjs +7 -1
  17. package/scripts/suite-health.mjs +110 -28
  18. package/scripts/test.mjs +9 -14
  19. package/src/agents/advisor/AGENT.md +4 -4
  20. package/src/agents/advisor/agent.json +1 -1
  21. package/src/agents/explore/AGENT.md +22 -0
  22. package/src/agents/explore/agent.json +6 -0
  23. package/src/cli.mjs +7 -0
  24. package/src/defaults/agents.json +7 -0
  25. package/src/defaults/shipped-history.json +38 -2
  26. package/src/defaults/skills/browser-use/SKILL.md +4 -1
  27. package/src/defaults/skills/code-tidy/SKILL.md +71 -102
  28. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
  29. package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
  30. package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
  31. package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
  32. package/src/defaults/skills/computer-use/SKILL.md +12 -2
  33. package/src/defaults/skills/setup/SKILL.md +2 -2
  34. package/src/defaults/skills/setup/references/actions.md +28 -9
  35. package/src/defaults/skills/setup/references/surfaces.md +5 -2
  36. package/src/defaults/skills/setup-guide/SKILL.md +11 -3
  37. package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
  38. package/src/defaults/skills/skill-creator/SKILL.md +85 -190
  39. package/src/defaults/skills/skill-creator/references/design.md +70 -162
  40. package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
  41. package/src/defaults/skills/test-suite/SKILL.md +194 -0
  42. package/src/defaults/skills/test-suite/references/case-management.md +51 -0
  43. package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
  44. package/src/defaults/skills/test-suite/references/reliability.md +49 -0
  45. package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
  46. package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
  47. package/src/defaults/skills/visualize/SKILL.md +6 -2
  48. package/src/lib/instruction-text.cjs +36 -0
  49. package/src/lib/rules-builder.cjs +40 -50
  50. package/src/orchestration/balanced.md +23 -0
  51. package/src/orchestration/focused.md +22 -0
  52. package/src/orchestration/none.md +5 -0
  53. package/src/orchestration/swarm.md +24 -0
  54. package/src/rules/agent-mode/AGENT_MODE.md +3 -1
  55. package/src/rules/agent-mode/MIXY.md +2 -2
  56. package/src/rules/lead/LEAD.md +3 -3
  57. package/src/rules/shared/20-research.md +3 -6
  58. package/src/rules/shared/40-editing.md +1 -0
  59. package/src/rules/shared/60-verification.md +10 -9
  60. package/src/rules/shared/70-delivery.md +4 -3
  61. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
  62. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
  63. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
  64. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
  65. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
  66. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
  67. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
  69. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  70. package/src/runtime/agent/orchestrator/config.mjs +12 -7
  71. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
  72. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
  73. package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
  74. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
  75. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
  76. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
  77. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
  78. package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
  79. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
  80. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
  81. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
  82. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
  83. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
  84. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
  85. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
  86. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
  87. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
  89. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
  90. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
  91. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
  92. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  93. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
  94. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
  95. package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
  96. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
  97. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
  98. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
  99. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
  100. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
  101. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
  102. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
  103. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
  104. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
  105. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
  106. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
  107. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
  108. package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
  109. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
  110. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
  111. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
  112. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
  113. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
  114. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
  115. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
  116. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
  117. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
  118. package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
  119. package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
  120. package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
  121. package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
  122. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +576 -0
  123. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
  124. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
  125. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
  126. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
  127. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
  128. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
  129. package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
  130. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
  131. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
  132. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
  133. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
  134. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
  135. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
  136. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
  137. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
  138. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
  139. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
  140. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
  141. package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
  142. package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
  143. package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
  144. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
  145. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
  146. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
  147. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
  148. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
  149. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
  150. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
  151. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
  152. package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
  153. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
  154. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
  155. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
  156. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
  157. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
  158. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
  159. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
  160. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
  161. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
  162. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
  163. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
  164. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
  165. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
  166. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
  167. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
  168. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
  169. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
  170. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
  171. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
  172. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
  174. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  175. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
  176. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
  177. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
  178. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
  179. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
  180. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
  181. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
  182. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
  183. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
  184. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
  185. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
  186. package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
  187. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
  188. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
  189. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
  190. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
  191. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
  192. package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
  193. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
  194. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
  195. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
  196. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
  197. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
  198. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  199. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
  200. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
  201. package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
  202. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
  203. package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
  204. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
  205. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
  206. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
  207. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
  208. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
  209. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
  210. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
  211. package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
  212. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
  213. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
  214. package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
  215. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
  216. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -4
  217. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
  218. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
  219. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
  220. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
  221. package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
  222. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
  223. package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
  224. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
  225. package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
  226. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
  227. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
  228. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
  229. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
  230. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
  231. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
  232. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
  233. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
  234. package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
  235. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
  236. package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
  237. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
  238. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
  239. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
  240. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
  241. package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
  242. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
  243. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
  244. package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
  245. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
  246. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
  247. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
  248. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
  249. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
  250. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
  251. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  252. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
  253. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
  254. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
  255. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
  256. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
  257. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
  258. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  259. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
  260. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
  261. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
  262. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
  263. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
  264. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
  265. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
  266. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  267. package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
  269. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
  270. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
  271. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
  272. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  273. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
  274. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
  275. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +105 -15
  276. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
  277. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
  278. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
  279. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +35 -11
  280. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
  281. package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
  282. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
  283. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
  284. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  285. package/src/runtime/attachments/attachment-reference.mjs +1 -1
  286. package/src/runtime/attachments/pdf-extract.mjs +1 -1
  287. package/src/runtime/attachments/store.d.mts +1 -0
  288. package/src/runtime/attachments/store.mjs +2 -2
  289. package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
  290. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
  291. package/src/runtime/channels/lib/scheduler.mjs +33 -0
  292. package/src/runtime/channels/lib/schedules-db.mjs +11 -4
  293. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
  294. package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
  295. package/src/runtime/channels/lib/whisper-port.mjs +19 -10
  296. package/src/runtime/channels/lib/whisper-server.mjs +22 -13
  297. package/src/runtime/channels/lib/worker-main.mjs +9 -31
  298. package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
  299. package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
  300. package/src/runtime/connectors/gmail-app-password.mjs +4 -4
  301. package/src/runtime/connectors/google-mcp.mjs +1 -1
  302. package/src/runtime/effort-judge/judge-client.mjs +2 -2
  303. package/src/runtime/effort-judge/judge-input.mjs +4 -4
  304. package/src/runtime/explore/explorer.mjs +88 -0
  305. package/src/runtime/explore/tool-defs.mjs +35 -0
  306. package/src/runtime/explore/tool.mjs +123 -0
  307. package/src/runtime/local-provider/hardware.mjs +1 -1
  308. package/src/runtime/media/adapters/codex-image.mjs +3 -3
  309. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  310. package/src/runtime/media/media-usage.mjs +1 -1
  311. package/src/runtime/media/store.mjs +1 -1
  312. package/src/runtime/memory/index.mjs +15 -1
  313. package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
  314. package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
  315. package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
  316. package/src/runtime/memory/lib/memory-embed.mjs +83 -14
  317. package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
  318. package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
  319. package/src/runtime/memory/lib/memory.mjs +17 -0
  320. package/src/runtime/memory/lib/pg/process.mjs +1 -1
  321. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
  322. package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
  323. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  324. package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
  325. package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
  326. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  327. package/src/runtime/office/capabilities.mjs +1 -1
  328. package/src/runtime/office/core/office-core.mjs +1 -1
  329. package/src/runtime/office/design/content-model.mjs +3 -3
  330. package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
  331. package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
  332. package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
  333. package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
  334. package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
  335. package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
  336. package/src/runtime/office/portable/portable-soffice.mjs +8 -6
  337. package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
  338. package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
  339. package/src/runtime/shared/agent-route-config.mjs +17 -2
  340. package/src/runtime/shared/atomic-file.d.mts +8 -0
  341. package/src/runtime/shared/atomic-file.mjs +103 -2
  342. package/src/runtime/shared/background-tasks.mjs +37 -10
  343. package/src/runtime/shared/background-wait.mjs +66 -0
  344. package/src/runtime/shared/child-guardian.mjs +17 -7
  345. package/src/runtime/shared/config.mjs +313 -16
  346. package/src/runtime/shared/connector-accounts.mjs +5 -5
  347. package/src/runtime/shared/connector-catalog.d.mts +14 -8
  348. package/src/runtime/shared/connector-catalog.mjs +70 -52
  349. package/src/runtime/shared/custom-provider-keys.mjs +20 -0
  350. package/src/runtime/shared/file-has-data.mjs +26 -2
  351. package/src/runtime/shared/file-lock.mjs +21 -18
  352. package/src/runtime/shared/git-launch.d.mts +9 -0
  353. package/src/runtime/shared/git-launch.mjs +213 -0
  354. package/src/runtime/shared/git-runner-worker.mjs +2 -1
  355. package/src/runtime/shared/git-runner.mjs +7 -2
  356. package/src/runtime/shared/idle-gc.mjs +30 -7
  357. package/src/runtime/shared/llm/cost.mjs +6 -1
  358. package/src/runtime/shared/llm/http-agent.mjs +316 -29
  359. package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
  360. package/src/runtime/shared/llm/model-catalog.mjs +46 -6
  361. package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
  362. package/src/runtime/shared/llm/system-proxy.mjs +453 -0
  363. package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
  364. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
  365. package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
  366. package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
  367. package/src/runtime/shared/maintenance-schedule.mjs +109 -0
  368. package/src/runtime/shared/process-runner.mjs +8 -4
  369. package/src/runtime/shared/provider-accounts.mjs +52 -2
  370. package/src/runtime/shared/routine-trigger.d.mts +13 -0
  371. package/src/runtime/shared/routine-trigger.mjs +34 -0
  372. package/src/runtime/shared/run-child.d.mts +2 -1
  373. package/src/runtime/shared/run-child.mjs +70 -18
  374. package/src/runtime/shared/session-scratch.mjs +14 -2
  375. package/src/runtime/shared/shipped-definitions.mjs +7 -1
  376. package/src/runtime/shared/staged-install-worker.mjs +5 -0
  377. package/src/runtime/shared/staged-update.mjs +47 -2
  378. package/src/runtime/shared/tool-card-model.golden.json +3 -12
  379. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  380. package/src/runtime/shared/tool-surface.mjs +110 -36
  381. package/src/runtime/shared/tool-work-units.mjs +35 -6
  382. package/src/runtime/shared/turn-snapshot.mjs +26 -4
  383. package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
  384. package/src/runtime/shared/worker-requests.mjs +17 -3
  385. package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
  386. package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
  387. package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
  388. package/src/runtime/shared/worktrees/branch-management.mjs +5 -3
  389. package/src/runtime/shared/worktrees/contract.mjs +16 -6
  390. package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
  391. package/src/runtime/shared/worktrees/disk.mjs +79 -2
  392. package/src/runtime/shared/worktrees/git.mjs +97 -7
  393. package/src/runtime/shared/worktrees/include.mjs +6 -4
  394. package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
  395. package/src/runtime/shared/worktrees/manager.mjs +962 -197
  396. package/src/runtime/shared/worktrees/settings.mjs +33 -7
  397. package/src/runtime/shared/worktrees/test-support.mjs +5 -1
  398. package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
  399. package/src/runtime/tidy/install.mjs +95 -15
  400. package/src/runtime/tidy/languages.mjs +17 -15
  401. package/src/runtime/tidy/process.mjs +9 -5
  402. package/src/runtime/tidy/resolve.mjs +19 -16
  403. package/src/runtime/tidy/runners/biome.mjs +3 -3
  404. package/src/runtime/tidy/tool.mjs +1 -1
  405. package/src/runtime/tidy/worktree.mjs +10 -6
  406. package/src/runtime/visualize-bridge/client.mjs +4 -1
  407. package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
  408. package/src/runtime/web-search/index.mjs +4 -23
  409. package/src/runtime/web-search/lib/web-tools.mjs +2 -2
  410. package/src/runtime/web-search/tool-defs.mjs +17 -26
  411. package/src/session-runtime/agent-profile-changes.mjs +55 -4
  412. package/src/session-runtime/agent-task-sessions.mjs +410 -353
  413. package/src/session-runtime/boot/apis.mjs +27 -4
  414. package/src/session-runtime/boot/begin.mjs +2 -0
  415. package/src/session-runtime/boot/config.mjs +10 -1
  416. package/src/session-runtime/boot/facade.mjs +1 -0
  417. package/src/session-runtime/boot/providers.mjs +70 -3
  418. package/src/session-runtime/boot/session.mjs +2 -0
  419. package/src/session-runtime/boot/tools.mjs +71 -25
  420. package/src/session-runtime/bot-status.mjs +103 -103
  421. package/src/session-runtime/channel-config-api.mjs +1 -0
  422. package/src/session-runtime/config-change-effects.mjs +179 -0
  423. package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
  424. package/src/session-runtime/config-lifecycle.mjs +160 -24
  425. package/src/session-runtime/connector-merge-migration.mjs +18 -15
  426. package/src/session-runtime/conversation-import/discovery.mjs +245 -47
  427. package/src/session-runtime/conversation-import/service.mjs +12 -5
  428. package/src/session-runtime/goal-facade-api.mjs +49 -3
  429. package/src/session-runtime/handoff-attachments.mjs +1 -1
  430. package/src/session-runtime/held-requests.mjs +3 -1
  431. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
  432. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
  433. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
  434. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
  435. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
  436. package/src/session-runtime/internal-tool-executor.mjs +12 -19
  437. package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
  438. package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
  439. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
  440. package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
  441. package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
  442. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  443. package/src/session-runtime/lifecycle-api.mjs +1 -0
  444. package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
  445. package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
  446. package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
  447. package/src/session-runtime/mixy-heartbeat.mjs +1 -1
  448. package/src/session-runtime/model-route/set-route.mjs +40 -7
  449. package/src/session-runtime/native-web-search/routes.mjs +3 -3
  450. package/src/session-runtime/provider-auth/login.mjs +2 -2
  451. package/src/session-runtime/provider-auth/refresh.mjs +6 -3
  452. package/src/session-runtime/provider-auth/setup.mjs +1 -1
  453. package/src/session-runtime/provider-readiness.mjs +53 -4
  454. package/src/session-runtime/resource-api.mjs +1 -1
  455. package/src/session-runtime/resource-extension-sync.mjs +4 -8
  456. package/src/session-runtime/resource-mcp-api.mjs +98 -35
  457. package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
  458. package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
  459. package/src/session-runtime/resource-mcp-servers.mjs +5 -4
  460. package/src/session-runtime/resource-plugins-api.mjs +4 -0
  461. package/src/session-runtime/routine-executor.mjs +152 -0
  462. package/src/session-runtime/routine-home-turn.mjs +46 -5
  463. package/src/session-runtime/runtime-facade.mjs +5 -0
  464. package/src/session-runtime/runtime-feature-gates.mjs +2 -11
  465. package/src/session-runtime/schedule-session-run.mjs +1 -0
  466. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
  467. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
  468. package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
  469. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
  470. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
  471. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
  472. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +28 -7
  473. package/src/session-runtime/services/agent-tool.mjs +51 -1
  474. package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
  475. package/src/session-runtime/services/channel-admin.mjs +18 -0
  476. package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
  477. package/src/session-runtime/services/daemon-candidate.mjs +4 -1
  478. package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
  479. package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
  480. package/src/session-runtime/services/plugin-admin.mjs +14 -6
  481. package/src/session-runtime/services/provider-admin.mjs +281 -10
  482. package/src/session-runtime/services/seeds.mjs +7 -0
  483. package/src/session-runtime/services/usage-stats-model.mjs +32 -11
  484. package/src/session-runtime/session-create/materialize.mjs +4 -2
  485. package/src/session-runtime/session-create/session-options.mjs +2 -0
  486. package/src/session-runtime/session-turn-api.mjs +2 -0
  487. package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
  488. package/src/session-runtime/settings-system-api.mjs +1 -1
  489. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
  490. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
  491. package/src/session-runtime/setup-tool/executor.mjs +14 -3
  492. package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
  493. package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
  494. package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
  495. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
  496. package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
  497. package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
  498. package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
  499. package/src/session-runtime/tool-policy-refresh.mjs +182 -5
  500. package/src/session-runtime/tool-surface.mjs +38 -1
  501. package/src/session-runtime/turn/agent-ops.mjs +33 -2
  502. package/src/session-runtime/turn/session-ops.mjs +2 -0
  503. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
  504. package/src/session-runtime/turn/turn-run.mjs +1 -1
  505. package/src/session-runtime/webhook-session-run.mjs +2 -0
  506. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
  507. package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
  508. package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
  509. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
  510. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
  511. package/src/session-runtime/workflow-agents-api.mjs +2 -0
  512. package/src/session-runtime/workspace/activity-guards.mjs +176 -0
  513. package/src/session-runtime/workspace/project-branches.mjs +1 -1
  514. package/src/session-runtime/workspace/session-view.mjs +149 -0
  515. package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
  516. package/src/session-runtime/workspace/transition-runner.mjs +188 -0
  517. package/src/session-runtime/workspace/transitions.mjs +128 -1070
  518. package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
  519. package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
  520. package/src/session-runtime/workspace/worktree-maintenance.mjs +200 -0
  521. package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
  522. package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
  523. package/src/standalone/daemon-agent-control.mjs +25 -8
  524. package/src/standalone/daemon-desktop-runtime.mjs +8 -2
  525. package/src/standalone/daemon-lag-profiler.mjs +7 -7
  526. package/src/standalone/daemon-session-control.mjs +151 -136
  527. package/src/standalone/daemon.mjs +61 -2
  528. package/src/standalone/desktop-service-registry.mjs +9 -0
  529. package/src/standalone/local-session-runtime.mjs +21 -1
  530. package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
  531. package/src/standalone/session-client.mjs +5 -1
  532. package/src/standalone/session-frame-stream.mjs +83 -11
  533. package/src/standalone/session-protocol.mjs +15 -0
  534. package/src/standalone/session-service/agent-route-follow.mjs +23 -20
  535. package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
  536. package/src/standalone/session-service/agent-tree.mjs +45 -9
  537. package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
  538. package/src/standalone/session-service/quota-resume.mjs +9 -0
  539. package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
  540. package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
  541. package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
  542. package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
  543. package/src/standalone/session-service/session-calls.mjs +2 -1
  544. package/src/standalone/session-service/stored-reader.mjs +127 -40
  545. package/src/tui/App.jsx +162 -164
  546. package/src/tui/app/app-view/floating-panel.jsx +3 -0
  547. package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
  548. package/src/tui/app/clipboard.mjs +22 -11
  549. package/src/tui/app/create-app-pickers.mjs +2 -0
  550. package/src/tui/app/doctor.mjs +2 -2
  551. package/src/tui/app/panel-signature.mjs +1 -1
  552. package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
  553. package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
  554. package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
  555. package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
  556. package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
  557. package/src/tui/app/provider-setup-picker.mjs +20 -13
  558. package/src/tui/app/settings-picker.mjs +53 -8
  559. package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
  560. package/src/tui/app/slash-commands.mjs +2 -1
  561. package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
  562. package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
  563. package/src/tui/app/slash-dispatch.mjs +1 -1
  564. package/src/tui/app/use-btw-panel.mjs +29 -0
  565. package/src/tui/app/use-context-panel-refresh.mjs +31 -0
  566. package/src/tui/app/use-model-catalog-cache.mjs +13 -10
  567. package/src/tui/app/use-mouse-input.mjs +11 -0
  568. package/src/tui/app/use-onboarding-start.mjs +8 -3
  569. package/src/tui/app/use-panel-transition.mjs +10 -1
  570. package/src/tui/app/use-pasted-buffers.mjs +28 -20
  571. package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
  572. package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
  573. package/src/tui/app/use-prompt-queue-history.mjs +5 -4
  574. package/src/tui/app/use-selection-focus.mjs +11 -2
  575. package/src/tui/app/use-selection-geometry.mjs +18 -9
  576. package/src/tui/app/use-selection-paint.mjs +4 -4
  577. package/src/tui/app/use-selection-stitch.mjs +3 -3
  578. package/src/tui/app/use-slash-palette.mjs +62 -0
  579. package/src/tui/app/use-terminal-chrome.mjs +2 -2
  580. package/src/tui/app/use-transcript-activity.mjs +48 -33
  581. package/src/tui/app/use-transcript-follow.mjs +12 -4
  582. package/src/tui/app/use-transcript-scroll.mjs +46 -17
  583. package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
  584. package/src/tui/app/use-transcript-window/geometry.mjs +20 -6
  585. package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
  586. package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
  587. package/src/tui/app/use-transcript-window.mjs +21 -11
  588. package/src/tui/app/use-tui-ready.mjs +18 -0
  589. package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
  590. package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
  591. package/src/tui/components/Picker.jsx +27 -3
  592. package/src/tui/components/SignInUrl.jsx +68 -0
  593. package/src/tui/components/TextEntryPanel.jsx +76 -46
  594. package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
  595. package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
  596. package/src/tui/components/question-panel-model.mjs +4 -4
  597. package/src/tui/components/sign-in-url-layout.mjs +24 -0
  598. package/src/tui/components/tool-execution/standard-card.jsx +3 -4
  599. package/src/tui/components/user-message-skills.mjs +1 -1
  600. package/src/tui/dist/index.mjs +2205 -1371
  601. package/src/tui/markdown/render-ansi.mjs +1 -1
  602. package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
  603. package/src/tui/session/agent-job-feed.mjs +2 -0
  604. package/src/tui/session/context-state.mjs +3 -0
  605. package/src/tui/session/goal-turn-state.mjs +6 -2
  606. package/src/tui/session/quota-resume.mjs +1 -1
  607. package/src/tui/session/session-api/controls.mjs +4 -0
  608. package/src/tui/session/session-api/extensions.mjs +8 -0
  609. package/src/tui/session/session-api/intake/abort.mjs +2 -1
  610. package/src/tui/session/session-api/intake.mjs +2 -0
  611. package/src/tui/session/session-api/integrations.mjs +2 -2
  612. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  613. package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
  614. package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
  615. package/src/tui/session/session-api/settings.mjs +2 -2
  616. package/src/tui/session/session-api/worktree.mjs +13 -1
  617. package/src/tui/session/session-flow/drain.mjs +11 -14
  618. package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
  619. package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
  620. package/src/tui/session/transcript-spill.mjs +92 -4
  621. package/src/tui/session/transcript-store.mjs +2 -0
  622. package/src/tui/session/turn-quiet.mjs +1 -1
  623. package/src/tui/session/turn.mjs +3 -0
  624. package/src/tui/session/worktree-setup-notice.mjs +1 -1
  625. package/src/tui/spinner-meta.mjs +3 -3
  626. package/src/tui/spinner-verbs.mjs +2 -2
  627. package/src/defaults/skills/goal-management/SKILL.md +0 -169
  628. package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
  629. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
  630. package/src/session-runtime/goal-tasks.mjs +0 -1
@@ -0,0 +1,598 @@
1
+ // Prompt-shaping settings — output style, profile (title, experience,
2
+ // response language), the workflow pack, the skill listing, instruction
3
+ // files and core memory — as the sections a prompt renders from them. A
4
+ // prompt records what it presents (`session.promptSettings`); a conversation
5
+ // that meets other settings keeps its cached prefix, is told once by a
6
+ // <system-reminder> (acknowledged when the provider accepts the turn) and
7
+ // folds them in at the next cold point (session-runtime/tool-policy-refresh.mjs,
8
+ // tool-policy/agent-profile-fold.mjs).
9
+ //
10
+ // Injection policy: a notice says what changed, never what the prompt or an
11
+ // earlier notice already carries — one `#` section per changed item, names
12
+ // and line diffs instead of bodies, each section and the whole block capped.
13
+ // promptSettingsNoticeContent is the one builder of that text.
14
+ import { createHash } from 'node:crypto';
15
+ import { isAgentOwner } from '../../agent-owner.mjs';
16
+ import { orchestrationModeName } from './orchestration-mode-switch-notice.mjs';
17
+
18
+ /** The rendered sections a prompt carries, in prompt order, with their labels. */
19
+ const PROMPT_SETTING_SECTIONS = Object.freeze([
20
+ ['meta', 'Profile Preferences and Output Style'],
21
+ ['workflow', 'Workflow'],
22
+ ['orchestration', 'Orchestration Mode'],
23
+ ['skills', 'Skills'],
24
+ ['instructionFiles', 'Instruction Files'],
25
+ ['coreMemory', 'Core Memory'],
26
+ ['language', 'Language'],
27
+ ]);
28
+
29
+ export const NOTICE_MAX_BYTES = 4096;
30
+ export const DIFF_MAX_BYTES = 2048;
31
+ const STYLE_BODY_MAX_BYTES = 1536;
32
+
33
+ const record = (value) => (value && typeof value === 'object' && !Array.isArray(value) ? value : null);
34
+
35
+ /** The prompt inputs of the runtime's in-memory config, for the rule builders. */
36
+ export function promptConfigSlice(config) {
37
+ const root = record(config);
38
+ if (!root) return null;
39
+ const agent = record(root.agent) || {};
40
+ return {
41
+ outputStyle: root.outputStyle ?? null,
42
+ profile: root.profile ?? agent.profile ?? null,
43
+ instructionFiles: root.instructionFiles ?? agent.instructionFiles ?? null,
44
+ };
45
+ }
46
+
47
+ const hashOf = (text) =>
48
+ createHash('sha256')
49
+ .update(String(text || '').trim())
50
+ .digest('hex')
51
+ .slice(0, 16);
52
+
53
+ const bytes = (text) => Buffer.byteLength(String(text || ''));
54
+
55
+ // --- section parsing ---------------------------------------------------------
56
+
57
+ /** `# Heading` blocks of a rendered section: heading → body. */
58
+ function headedBlocks(text) {
59
+ const blocks = new Map();
60
+ let heading = null;
61
+ let lines = [];
62
+ const flush = () => {
63
+ if (heading !== null) blocks.set(heading, lines.join('\n').trim());
64
+ };
65
+ for (const line of String(text || '').split('\n')) {
66
+ const match = /^# (.+)$/.exec(line);
67
+ if (match) {
68
+ flush();
69
+ heading = match[1].trim();
70
+ lines = [];
71
+ } else if (heading !== null) lines.push(line);
72
+ }
73
+ flush();
74
+ return blocks;
75
+ }
76
+
77
+ function outputStyleOf(meta) {
78
+ for (const [heading, body] of headedBlocks(meta)) {
79
+ const match = /^Output Style: (.+)$/.exec(heading);
80
+ if (match) return { name: match[1].trim(), body };
81
+ }
82
+ return null;
83
+ }
84
+
85
+ const bulletLines = (text) =>
86
+ String(text || '')
87
+ .split('\n')
88
+ .map((line) => line.trim())
89
+ .filter((line) => line.startsWith('- '));
90
+
91
+ const profileLines = (meta) => bulletLines(headedBlocks(meta).get('Profile Preferences'));
92
+
93
+ function skillNames(manifest) {
94
+ return bulletLines(manifest)
95
+ .map((line) => /^- ([^:[]+?)(?::|\s\[|$)/.exec(line)?.[1]?.trim())
96
+ .filter((name) => name && !name.startsWith('...'));
97
+ }
98
+
99
+ // A file's own `## ` headings are content: only an absolute path opens a file.
100
+ const FILE_HEADING_RE = /^## ((?:[A-Za-z]:[\\/]|\/).*)$/;
101
+
102
+ /** `## <path>` → content of a rendered `# Instruction Files` block. */
103
+ function instructionFiles(text) {
104
+ const files = new Map();
105
+ let path = null;
106
+ let lines = [];
107
+ const flush = () => {
108
+ if (path) files.set(path, lines.join('\n').trim());
109
+ };
110
+ for (const line of String(text || '').split('\n')) {
111
+ const match = FILE_HEADING_RE.exec(line);
112
+ if (match) {
113
+ flush();
114
+ path = match[1].trim();
115
+ lines = [];
116
+ } else if (path) lines.push(line);
117
+ }
118
+ flush();
119
+ return files;
120
+ }
121
+
122
+ const contentLines = (text) =>
123
+ String(text || '')
124
+ .split('\n')
125
+ .map((line) => line.trimEnd())
126
+ .filter((line) => line.trim());
127
+
128
+ /** Whether the items both lists share run in a different order or count. */
129
+ function orderChanged(was, now) {
130
+ const wasSet = new Set(was);
131
+ const nowSet = new Set(now);
132
+ return was.filter((item) => nowSet.has(item)).join('\n') !== now.filter((item) => wasSet.has(item)).join('\n');
133
+ }
134
+
135
+ // `lines` kept while they fit `max` bytes, then a `(N more <what>)` tail.
136
+ function capped(lines, max, what) {
137
+ const kept = [];
138
+ let used = 0;
139
+ for (const line of lines) {
140
+ if (used + bytes(line) + 1 > max) {
141
+ kept.push(`(${lines.length - kept.length} more ${what})`);
142
+ break;
143
+ }
144
+ kept.push(line);
145
+ used += bytes(line) + 1;
146
+ }
147
+ return kept;
148
+ }
149
+
150
+ /** Added (+) and removed (-) lines, capped at `max` bytes; '' when equal.
151
+ * Order is meaning in instructions: when the shared lines were moved or
152
+ * repeated, the lines are listed again in their new order. */
153
+ function lineDiff(before, after, max = DIFF_MAX_BYTES) {
154
+ const was = contentLines(before);
155
+ const now = contentLines(after);
156
+ const wasSet = new Set(was);
157
+ const nowSet = new Set(now);
158
+ const changes = [
159
+ ...was.filter((line) => !nowSet.has(line)).map((line) => `- ${line}`),
160
+ ...now.filter((line) => !wasSet.has(line)).map((line) => `+ ${line}`),
161
+ ];
162
+ const out = capped(changes, max, 'changed lines');
163
+ if (orderChanged(was, now)) {
164
+ out.push(
165
+ 'The line order changed; the lines now run in this order:',
166
+ ...capped(
167
+ now.map((line, index) => `${index + 1}. ${line}`),
168
+ max,
169
+ 'lines'
170
+ )
171
+ );
172
+ }
173
+ return out.join('\n');
174
+ }
175
+
176
+ // --- records -----------------------------------------------------------------
177
+
178
+ /** `sections`: { meta, workflow, skills, instructionFiles, coreMemory,
179
+ * language } texts ('' when absent), plus `responseLanguage` ({ id, name })
180
+ * and `instructionFilesMode`. The record keeps what a later notice diffs. */
181
+ export function promptSettingsRecord(sections = {}) {
182
+ const hashes = Object.fromEntries(PROMPT_SETTING_SECTIONS.map(([key]) => [key, hashOf(sections[key])]));
183
+ const revision = hashOf(PROMPT_SETTING_SECTIONS.map(([key]) => hashes[key]).join('|'));
184
+ return {
185
+ revision,
186
+ hashes,
187
+ texts: {
188
+ meta: String(sections.meta || ''),
189
+ orchestration: String(sections.orchestration || ''),
190
+ orchestrationMode: String(sections.orchestrationMode || ''),
191
+ instructionFiles: String(sections.instructionFiles || ''),
192
+ coreMemory: String(sections.coreMemory || ''),
193
+ skills: skillNames(sections.skills),
194
+ ...(sections.instructionFilesMode ? { instructionFilesMode: sections.instructionFilesMode } : {}),
195
+ },
196
+ };
197
+ }
198
+
199
+ // A section a record predates (added to the list later) counts as unchanged.
200
+ function changedKeys(from, to) {
201
+ return PROMPT_SETTING_SECTIONS.map(([key]) => key).filter(
202
+ (key) => from?.hashes?.[key] !== undefined && from.hashes[key] !== to.hashes[key]
203
+ );
204
+ }
205
+
206
+ // --- the notice builder ------------------------------------------------------
207
+
208
+ function languageSection(sections) {
209
+ const name = sections.responseLanguage?.name;
210
+ return name
211
+ ? `# Language\nRespond in ${name} from now on.`
212
+ : '# Language\nNo response language is set any more: reply in the language of the conversation.';
213
+ }
214
+
215
+ function metaSections(before, sections) {
216
+ const out = [];
217
+ const style = outputStyleOf(sections.meta);
218
+ const was = outputStyleOf(before);
219
+ if (style?.name !== was?.name || style?.body !== was?.body) {
220
+ if (!style) out.push('# Output Style\nNo output style applies any more.');
221
+ else {
222
+ const body =
223
+ bytes(style.body) < STYLE_BODY_MAX_BYTES ? `\n\n${style.body}` : '\nIt applies from the next prompt rebuild.';
224
+ out.push(`# Output Style\nThe output style is now "${style.name}".${body}`);
225
+ }
226
+ }
227
+ const profileDiff = lineDiff(profileLines(before).join('\n'), profileLines(sections.meta).join('\n'));
228
+ if (profileDiff) out.push(`# Profile\n${profileDiff}`);
229
+ return out;
230
+ }
231
+
232
+ // Files earlier in the block take precedence: their order is meaning too.
233
+ const fileOrderChanged = (was, now) => orderChanged([...was.keys()], [...now.keys()]);
234
+
235
+ function instructionFilesSection(told, sections) {
236
+ const mode = sections.instructionFilesMode;
237
+ if (mode && told.instructionFilesMode && mode !== told.instructionFilesMode) {
238
+ return `# Instruction Files\nThe instruction files mode is now "${mode}"; the files apply from the next prompt rebuild.`;
239
+ }
240
+ const was = instructionFiles(told.instructionFiles);
241
+ const now = instructionFiles(sections.instructionFiles);
242
+ const parts = [];
243
+ for (const path of new Set([...was.keys(), ...now.keys()])) {
244
+ if (!now.has(path)) parts.push(`## ${path}\nNo longer applies.`);
245
+ else {
246
+ const diff = lineDiff(was.get(path), now.get(path));
247
+ if (diff) parts.push(`## ${path}\n${diff}\nRead ${path} for the full file.`);
248
+ }
249
+ }
250
+ if (fileOrderChanged(was, now)) parts.push(`The files now apply in this order:\n${[...now.keys()].join('\n')}`);
251
+ return parts.length ? `# Instruction Files\n${parts.join('\n\n')}` : '';
252
+ }
253
+
254
+ function skillsSection(told, sections) {
255
+ const was = new Set(told.skills || []);
256
+ const now = skillNames(sections.skills);
257
+ const added = now.filter((name) => !was.has(name));
258
+ const removed = [...was].filter((name) => !now.includes(name));
259
+ const lines = [
260
+ ...(added.length ? [`Added: ${added.join(', ')}`] : []),
261
+ ...(removed.length ? [`Removed: ${removed.join(', ')}`] : []),
262
+ ...(orderChanged(told.skills || [], now) ? [`Order now: ${now.join(', ')}`] : []),
263
+ ];
264
+ return lines.length ? `# Skills\n${lines.join('\n')}` : '';
265
+ }
266
+
267
+ const LATER = 'it applies from the next prompt rebuild.';
268
+
269
+ // The paths of changed instruction files, with how each changed.
270
+ function changedInstructionFiles(told, sections) {
271
+ const was = instructionFiles(told.instructionFiles);
272
+ const now = instructionFiles(sections.instructionFiles);
273
+ const out = [];
274
+ for (const path of new Set([...was.keys(), ...now.keys()])) {
275
+ if (!now.has(path)) out.push({ path, line: `- no longer applies: ${path}` });
276
+ else if (!was.has(path)) out.push({ path, line: `- added: ${path} (read it)` });
277
+ else if (was.get(path) !== now.get(path)) out.push({ path, line: `- changed: ${path} (read it)` });
278
+ }
279
+ // No path of its own: acknowledged only with the whole item.
280
+ // Listed first, so even the minimal form carries it.
281
+ if (fileOrderChanged(was, now)) out.unshift({ line: `- file order changed: ${[...now.keys()].join(', ')}` });
282
+ return out;
283
+ }
284
+
285
+ // The rendered block of `files` (path → text), as instructionFiles() parses it.
286
+ function renderInstructionFiles(files) {
287
+ if (!files.size) return '';
288
+ return ['# Instruction Files', ...[...files].map(([path, text]) => `## ${path}\n\n${text}`)].join('\n\n');
289
+ }
290
+
291
+ /** What the model knows of instruction files once `paths` were told. */
292
+ function instructionFilesAfter(toldText, nowText, paths) {
293
+ const files = instructionFiles(toldText);
294
+ const now = instructionFiles(nowText);
295
+ for (const path of paths) {
296
+ if (now.has(path)) files.set(path, now.get(path));
297
+ else files.delete(path);
298
+ }
299
+ return renderInstructionFiles(files);
300
+ }
301
+
302
+ const INSTRUCTION_LIST_MAX_BYTES = 1024;
303
+
304
+ // Instruction files: the diffs (full), every path by name (compact), or as
305
+ // many paths as fit a short list (minimal). A form lists `paths`: only those
306
+ // are acknowledged; the rest stay pending for the next turn.
307
+ function instructionFilesItem(full, told, sections) {
308
+ const changed = changedInstructionFiles(told, sections);
309
+ const heading = '# Instruction Files';
310
+ const all = changed.map((entry) => entry.path).filter(Boolean);
311
+ const compact = [heading, ...changed.map((entry) => entry.line)].join('\n');
312
+ const listed = [];
313
+ let size = bytes(heading);
314
+ for (const entry of changed) {
315
+ if (listed.length && size + bytes(entry.line) + 1 > INSTRUCTION_LIST_MAX_BYTES) break;
316
+ listed.push(entry);
317
+ size += bytes(entry.line) + 1;
318
+ }
319
+ const rest = changed.length - listed.length;
320
+ const minimal = [
321
+ heading,
322
+ ...listed.map((entry) => entry.line),
323
+ ...(rest ? [`(${rest} more changed files follow in the next notice)`] : []),
324
+ ].join('\n');
325
+ return {
326
+ key: 'instructionFiles',
327
+ full,
328
+ compact,
329
+ minimal,
330
+ paths: { full: all, compact: all, minimal: listed.map((entry) => entry.path).filter(Boolean) },
331
+ };
332
+ }
333
+
334
+ // One changed item: its full text and the compact form it degrades to when
335
+ // the block has no room (a name and a pointer, never dropped).
336
+ function noticeItems(keys, sections, told) {
337
+ const items = [];
338
+ const add = (key, full, compact = full, minimal = compact) => full && items.push({ key, full, compact, minimal });
339
+ for (const [key] of PROMPT_SETTING_SECTIONS) {
340
+ if (!keys.includes(key)) continue;
341
+ if (key === 'meta') {
342
+ const style = outputStyleOf(sections.meta);
343
+ for (const part of metaSections(told.meta, sections)) {
344
+ if (part.startsWith('# Output Style')) {
345
+ add(key, part, style ? `# Output Style\nThe output style is now "${style.name}"; ${LATER}` : part);
346
+ } else {
347
+ const lines = part.split('\n').length - 1;
348
+ add(key, part, `# Profile\n${lines} profile preference lines changed; ${LATER}`);
349
+ }
350
+ }
351
+ } else if (key === 'workflow') {
352
+ const name = sections.workflowName ? `"${sections.workflowName}"` : 'active';
353
+ add(key, `# Workflow\nThe ${name} workflow pack changed; ${LATER}`);
354
+ } else if (key === 'orchestration') {
355
+ // The text of the active mode was edited. A switch to another mode is
356
+ // the mode-switch notice's, and a record that predates the text has
357
+ // nothing to diff.
358
+ const mode = sections.orchestrationMode;
359
+ if (told.orchestration === undefined || !mode || told.orchestrationMode !== mode) continue;
360
+ const diff = lineDiff(told.orchestration, sections.orchestration);
361
+ if (!diff) continue;
362
+ const name = orchestrationModeName(mode);
363
+ const head = `# Orchestration Mode\nThe ${name} orchestration mode instructions were edited`;
364
+ add(key, `${head}:\n${diff}`, `${head}; ${LATER}`);
365
+ } else if (key === 'skills') {
366
+ const full = skillsSection(told, sections);
367
+ const added = skillNames(sections.skills).filter((name) => !(told.skills || []).includes(name)).length;
368
+ const removed = (told.skills || []).filter((name) => !skillNames(sections.skills).includes(name)).length;
369
+ const moved = orderChanged(told.skills || [], skillNames(sections.skills)) ? ', order changed' : '';
370
+ add(key, full, `# Skills\n${added} skills added, ${removed} removed${moved}; ${LATER}`);
371
+ } else if (key === 'instructionFiles') {
372
+ const full = instructionFilesSection(told, sections);
373
+ if (!full) continue;
374
+ if (full.includes('instruction files mode is now')) add(key, full);
375
+ else items.push(instructionFilesItem(full, told, sections));
376
+ } else if (key === 'coreMemory') {
377
+ const later = `# Core Memory\nCore memory was updated; ${LATER}`;
378
+ const diff = told.coreMemory === undefined ? '' : lineDiff(told.coreMemory, sections.coreMemory);
379
+ add(key, diff ? `# Core Memory\nCore memory was updated:\n${diff}` : later, later);
380
+ } else if (key === 'language') add(key, languageSection(sections));
381
+ }
382
+ return items;
383
+ }
384
+
385
+ const NOTICE_OPEN =
386
+ '<system-reminder>\nSettings changed during this conversation; each section replaces the matching part of your system prompt.';
387
+ const NOTICE_CLOSE = '</system-reminder>';
388
+
389
+ /**
390
+ * The one builder of model-visible prompt-settings text: one `#` section per
391
+ * changed item of `keys`, diffed against `told` (the texts the model last
392
+ * had: promptSettingsRecord().texts). Every item first takes its minimal
393
+ * form (one line), smallest first; the budget left then upgrades items to
394
+ * their compact form and then their full text, smallest first. An item that
395
+ * does not fit even minimal is left out, named by the overflow line and not
396
+ * acknowledged. `compact: true` stops at the compact forms.
397
+ * Returns `{ content, emitted }` (`emitted`: the keys whose every item was
398
+ * sent); content '' when nothing is worth telling.
399
+ */
400
+ function buildPromptSettingsNotice(keys, sections, told = {}, { compact = false } = {}) {
401
+ const items = noticeItems(keys, sections, told);
402
+ if (!items.length) return { content: '', emitted: [] };
403
+ let used = bytes(NOTICE_OPEN) + bytes(NOTICE_CLOSE);
404
+ const cost = (text) => bytes(text) + 2;
405
+ const overflowReserve = cost('99 more changes; see the setup tool.');
406
+ const chosen = new Map(); // item → tier
407
+ for (const item of [...items].sort((a, b) => bytes(a.minimal) - bytes(b.minimal))) {
408
+ if (used + cost(item.minimal) + overflowReserve > NOTICE_MAX_BYTES) continue;
409
+ chosen.set(item, 'minimal');
410
+ used += cost(item.minimal);
411
+ }
412
+ // Upgrade, smallest first: to the compact form, then (unless compact only) the full text.
413
+ for (const tier of compact ? ['compact'] : ['compact', 'full']) {
414
+ for (const item of [...chosen.keys()].sort((a, b) => bytes(a[tier]) - bytes(b[tier]))) {
415
+ const extra = cost(item[tier]) - cost(item[chosen.get(item)]);
416
+ if (extra > 0 && used + extra + overflowReserve > NOTICE_MAX_BYTES) continue;
417
+ chosen.set(item, tier);
418
+ used += extra;
419
+ }
420
+ }
421
+ const left = items.filter((item) => !chosen.has(item));
422
+ const parts = items.filter((item) => chosen.has(item)).map((item) => item[chosen.get(item)]);
423
+ if (left.length) parts.push(`${left.length} more changes; see the setup tool.`);
424
+ // An item whose form names only some of its paths tells those alone.
425
+ const partial = {};
426
+ for (const [item, tier] of chosen) {
427
+ const paths = item.paths?.[tier];
428
+ if (paths && paths.length < item.paths.full.length) partial[item.key] = paths;
429
+ }
430
+ const emitted = keys.filter(
431
+ (key) =>
432
+ items.some((item) => item.key === key) && !left.some((item) => item.key === key) && !Object.hasOwn(partial, key)
433
+ );
434
+ return { content: parts.length ? [NOTICE_OPEN, ...parts, NOTICE_CLOSE].join('\n\n') : '', emitted, partial };
435
+ }
436
+
437
+ /** The notice text alone (see buildPromptSettingsNotice). */
438
+ export function promptSettingsNoticeContent(keys, sections, told = {}) {
439
+ return buildPromptSettingsNotice(keys, sections, told).content;
440
+ }
441
+
442
+ // --- staging -----------------------------------------------------------------
443
+
444
+ // What the model was last told: an acknowledged notice, else its prompt; a
445
+ // staged working-folder change tells its own instruction files and core
446
+ // memory (workspace notice), so they count as told.
447
+ function toldRecord(session, presented) {
448
+ const told = session.promptSettingsTold || presented;
449
+ const target = session.workspaceReroot?.target;
450
+ if (!target) return told;
451
+ const hashes = { ...told.hashes };
452
+ const texts = { ...(told.texts || {}) };
453
+ if (target.instructionFilesContext !== undefined) {
454
+ hashes.instructionFiles = hashOf(target.instructionFilesContext);
455
+ texts.instructionFiles = String(target.instructionFilesContext || '');
456
+ }
457
+ if (target.coreMemoryContext !== undefined) {
458
+ hashes.coreMemory = hashOf(target.coreMemoryContext);
459
+ texts.coreMemory = String(target.coreMemoryContext || '');
460
+ }
461
+ return { ...told, hashes, texts };
462
+ }
463
+
464
+ /**
465
+ * Compare a conversation's settings with `sections` (as they stand now).
466
+ * Returns the keys that differ from the prompt (a later fold presents them),
467
+ * staging one notice for what differs from what the model was last told —
468
+ * a setting moved back to the prompt's value is told too.
469
+ */
470
+ export function stagePromptSettingsNotice(session, sections) {
471
+ if (sections.responseLanguage !== undefined) session.responseLanguage = sections.responseLanguage;
472
+ // After a compaction stripped what a worker was told: names and pointers only.
473
+ const compact = session.promptSettingsRecheck === 'compact';
474
+ delete session.promptSettingsRecheck;
475
+ const presented = session?.promptSettings;
476
+ // A prompt from before settings were recorded: what it presents is unknown.
477
+ if (!presented?.hashes) {
478
+ session.promptSettings = promptSettingsRecord(sections);
479
+ return [];
480
+ }
481
+ const next = promptSettingsRecord(sections);
482
+ // `sections.only`: the caller computes these sections alone; the others
483
+ // stay as the prompt presents them.
484
+ if (Array.isArray(sections.only)) {
485
+ for (const [key] of PROMPT_SETTING_SECTIONS) {
486
+ if (sections.only.includes(key) || presented.hashes[key] === undefined) continue;
487
+ next.hashes[key] = presented.hashes[key];
488
+ }
489
+ next.revision = hashOf(PROMPT_SETTING_SECTIONS.map(([key]) => next.hashes[key]).join('|'));
490
+ }
491
+ // Sections a record predates are adopted as presented.
492
+ for (const [key] of PROMPT_SETTING_SECTIONS) {
493
+ if (presented.hashes[key] === undefined) presented.hashes[key] = next.hashes[key];
494
+ }
495
+ const changed = changedKeys(presented, next);
496
+ const told = toldRecord(session, presented);
497
+ const fresh = changedKeys(told, next);
498
+ const { content, emitted, partial } = fresh.length
499
+ ? buildPromptSettingsNotice(fresh, sections, told.texts || {}, { compact })
500
+ : { content: '', emitted: [], partial: {} };
501
+ if (!content) {
502
+ delete session.promptSettingsNotice;
503
+ // Nothing to tell: the model's view is the prompt's, or what it was told.
504
+ if (!changed.length) delete session.promptSettingsTold;
505
+ else if (fresh.length) session.promptSettingsTold = next;
506
+ return changed;
507
+ }
508
+ const pending = session.promptSettingsNotice;
509
+ if (pending?.record?.revision === next.revision && pending.content === content) return changed;
510
+ // One notice per change: an unsent one is replaced by what is current.
511
+ const revision = (Number(session.promptSettingsNoticeRevision) || 0) + 1;
512
+ session.promptSettingsNoticeRevision = revision;
513
+ session.promptSettingsNotice = { revision, record: next, content, emitted, partial, fresh };
514
+ session.updatedAt = Date.now();
515
+ return changed;
516
+ }
517
+
518
+ // What the model knows after `notice` reached it: the record's sections it
519
+ // carried, the earlier told state for the rest.
520
+ const TEXTS_OF = {
521
+ meta: ['meta'],
522
+ orchestration: ['orchestration', 'orchestrationMode'],
523
+ instructionFiles: ['instructionFiles', 'instructionFilesMode'],
524
+ coreMemory: ['coreMemory'],
525
+ skills: ['skills'],
526
+ };
527
+ function toldAfter(session, notice) {
528
+ const emitted = Array.isArray(notice.emitted) ? notice.emitted : null;
529
+ if (!emitted) return notice.record;
530
+ const base = session.promptSettingsTold || session.promptSettings || notice.record;
531
+ const hashes = { ...base.hashes };
532
+ const texts = { ...(base.texts || {}) };
533
+ for (const key of emitted) {
534
+ hashes[key] = notice.record.hashes[key];
535
+ for (const field of TEXTS_OF[key] || []) {
536
+ if (notice.record.texts?.[field] === undefined) delete texts[field];
537
+ else texts[field] = notice.record.texts[field];
538
+ }
539
+ }
540
+ // Instruction files the notice named one by one: those paths alone.
541
+ const paths = notice.partial?.instructionFiles;
542
+ if (Array.isArray(paths)) {
543
+ texts.instructionFiles = instructionFilesAfter(
544
+ texts.instructionFiles,
545
+ notice.record.texts?.instructionFiles,
546
+ paths
547
+ );
548
+ hashes.instructionFiles = hashOf(texts.instructionFiles);
549
+ }
550
+ const revision = hashOf(PROMPT_SETTING_SECTIONS.map(([key]) => hashes[key]).join('|'));
551
+ return { revision, hashes, texts };
552
+ }
553
+
554
+ /** The notice the next user turn carries, or null. */
555
+ export function snapshotPendingPromptSettingsNotice(session) {
556
+ const pending = session?.promptSettingsNotice;
557
+ return pending?.content ? { revision: pending.revision, content: pending.content } : null;
558
+ }
559
+
560
+ /** The notice of `revision` reached the model. */
561
+ export function acknowledgePendingPromptSettingsNotice(session, revision) {
562
+ const pending = session?.promptSettingsNotice;
563
+ if (!pending || pending.revision !== Number(revision)) return false;
564
+ // Only what the notice carried is told; an item the cap left out stays
565
+ // pending and is told by the next turn's reconcile.
566
+ session.promptSettingsTold = toldAfter(session, pending);
567
+ if (Array.isArray(pending.fresh) && pending.fresh.some((key) => !pending.emitted.includes(key))) {
568
+ session.promptSettingsRecheck = true;
569
+ }
570
+ delete session.promptSettingsNotice;
571
+ return true;
572
+ }
573
+
574
+ /** The prompt now presents `sections`: nothing is pending any more. */
575
+ export function notePromptSettingsPresented(session, sections) {
576
+ if (sections.responseLanguage !== undefined) session.responseLanguage = sections.responseLanguage;
577
+ session.promptSettings = promptSettingsRecord(sections);
578
+ delete session.promptSettingsNotice;
579
+ delete session.promptSettingsTold;
580
+ delete session.promptSettingsRecheck;
581
+ }
582
+
583
+ /**
584
+ * A compaction dropped the notices the model was told — acknowledged ones and
585
+ * a pending one the running turn may already carry (its acknowledgement at
586
+ * settlement then finds nothing). A Lead or bot thread folds its settings
587
+ * into the rebuilt prompt instead; a session whose prompt is never rebuilt (a
588
+ * delegated worker) is told the difference from its prompt again at the next
589
+ * reconcile, in compact form (names and pointers).
590
+ */
591
+ export function rearmPromptSettingsNotice(session) {
592
+ if (session?.promptIdentity && !isAgentOwner(session)) return false;
593
+ if (!session?.promptSettingsTold && !session?.promptSettingsNotice) return false;
594
+ delete session.promptSettingsTold;
595
+ delete session.promptSettingsNotice;
596
+ session.promptSettingsRecheck = 'compact';
597
+ return true;
598
+ }
@@ -263,6 +263,25 @@ export function replaceWorkspaceEnvironment(environmentTail, environmentContext)
263
263
  return parts.filter((part) => part?.trim()).join(BP3_PART_SEPARATOR);
264
264
  }
265
265
 
266
+ const LANGUAGE_HEADING = '# Language';
267
+
268
+ /**
269
+ * Replace the response language block that closes the persisted environment
270
+ * tail (rules-builder buildLanguageSection, `# Language`); '' drops it. It
271
+ * stays the last part.
272
+ */
273
+ export function replaceLanguageBlock(environmentTail, languageContext) {
274
+ const parts = (
275
+ typeof environmentTail === 'string' && environmentTail ? environmentTail.split(BP3_PART_SEPARATOR) : []
276
+ ).filter((part) => {
277
+ const text = part.trim();
278
+ return text && text !== LANGUAGE_HEADING && !text.startsWith(`${LANGUAGE_HEADING}\n`);
279
+ });
280
+ const language = trimmedSlice(languageContext);
281
+ if (language) parts.push(language);
282
+ return parts.join(BP3_PART_SEPARATOR);
283
+ }
284
+
266
285
  /**
267
286
  * Re-root a session's prompt at a workspace in place: environment facts,
268
287
  * project memory and instruction files are replaced (never appended), then
@@ -578,6 +597,7 @@ function isReferenceFilesMessage(message) {
578
597
  }
579
598
 
580
599
  export { isProtectedContextUserMessage };
600
+ export { BP3_PART_SEPARATOR, bp3SystemMessage, bpEnvSystemMessage, replaceSystemMessageContent };
581
601
 
582
602
  // Compact summary messages (role:'user', content startsWith SUMMARY_PREFIX)
583
603
  // are synthetic anchors, not a real human turn — they must not count as