mixdog 1.4.0 → 1.4.2

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 (493) hide show
  1. package/package.json +3 -2
  2. package/scripts/build-shipped-history.mjs +115 -33
  3. package/scripts/check-voice-runtime-inputs.mjs +25 -0
  4. package/scripts/gate-local.mjs +183 -63
  5. package/scripts/latest-guard.mjs +21 -9
  6. package/scripts/lib/gate-scheduler.mjs +138 -32
  7. package/scripts/lib/gate-timing-reporter.mjs +16 -0
  8. package/scripts/lib/isolated-test-env.mjs +10 -5
  9. package/scripts/lib/run-node-tests.mjs +91 -66
  10. package/scripts/lib/scoped-temp.d.mts +16 -0
  11. package/scripts/lib/scoped-temp.mjs +124 -0
  12. package/scripts/lib/stale-temp.mjs +44 -0
  13. package/scripts/lib/test-failure-records.mjs +14 -1
  14. package/scripts/lib/test-failure-summary.mjs +16 -4
  15. package/scripts/lib/test-spawn-ledger.mjs +12 -3
  16. package/scripts/post-release-check.mjs +1 -6
  17. package/scripts/pptx-kit-index.mjs +17 -5
  18. package/scripts/suite-health.mjs +115 -24
  19. package/scripts/test-data-dir.mjs +10 -7
  20. package/scripts/test.mjs +9 -14
  21. package/src/agents/advisor/AGENT.md +4 -4
  22. package/src/agents/advisor/agent.json +1 -1
  23. package/src/agents/explore/AGENT.md +22 -0
  24. package/src/agents/explore/agent.json +6 -0
  25. package/src/app.mjs +4 -0
  26. package/src/cli.mjs +7 -0
  27. package/src/defaults/agents.json +7 -0
  28. package/src/defaults/shipped-history.json +23 -2
  29. package/src/defaults/skills/browser-use/SKILL.md +10 -5
  30. package/src/defaults/skills/code-tidy/SKILL.md +71 -102
  31. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
  32. package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
  33. package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
  34. package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
  35. package/src/defaults/skills/computer-use/SKILL.md +16 -4
  36. package/src/defaults/skills/goal-management/SKILL.md +1 -1
  37. package/src/defaults/skills/setup/references/actions.md +12 -6
  38. package/src/defaults/skills/setup/references/surfaces.md +2 -2
  39. package/src/defaults/skills/setup-guide/SKILL.md +5 -2
  40. package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
  41. package/src/defaults/skills/skill-creator/SKILL.md +85 -190
  42. package/src/defaults/skills/skill-creator/references/design.md +70 -162
  43. package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
  44. package/src/defaults/skills/test-suite/SKILL.md +194 -0
  45. package/src/defaults/skills/test-suite/references/case-management.md +51 -0
  46. package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
  47. package/src/defaults/skills/test-suite/references/reliability.md +49 -0
  48. package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
  49. package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
  50. package/src/defaults/skills/visualize/SKILL.md +6 -2
  51. package/src/lib/rules-builder.cjs +35 -42
  52. package/src/output-styles/common.md +2 -2
  53. package/src/output-styles/simple.md +1 -1
  54. package/src/rules/agent/AGENT.md +5 -4
  55. package/src/rules/lead/LEAD.md +12 -7
  56. package/src/rules/shared/10-tool-workflow.md +3 -1
  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/45-destructive.md +0 -2
  60. package/src/rules/shared/50-execution.md +2 -0
  61. package/src/rules/shared/60-verification.md +10 -9
  62. package/src/rules/shared/70-delivery.md +8 -9
  63. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
  64. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -1
  65. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +156 -24
  66. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -0
  67. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
  69. package/src/runtime/agent/orchestrator/config.mjs +12 -7
  70. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +8 -8
  71. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +5 -26
  72. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +3 -1
  73. package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
  74. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +122 -12
  75. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -3
  76. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +13 -2
  77. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +152 -58
  78. package/src/runtime/agent/orchestrator/mcp/client.mjs +51 -18
  79. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +88 -54
  80. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +42 -26
  81. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +54 -8
  82. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
  83. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +37 -31
  84. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
  85. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
  86. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
  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-oauth-request/initial-status.mjs +3 -1
  90. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +14 -3
  91. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +6 -0
  92. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
  93. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
  94. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
  95. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
  97. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/providers/cursor.mjs +3 -0
  99. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
  100. package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
  101. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
  102. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
  103. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
  104. package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
  105. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
  106. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
  107. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +248 -41
  108. package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
  109. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
  110. package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
  111. package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
  112. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
  113. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
  114. package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
  115. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
  116. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
  117. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
  118. package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
  119. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
  120. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
  121. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
  122. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
  123. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
  124. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
  125. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
  126. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
  127. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
  128. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
  129. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
  130. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
  131. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
  132. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
  133. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +160 -31
  134. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +22 -12
  135. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
  136. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +49 -22
  137. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
  138. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
  139. package/src/runtime/agent/orchestrator/providers/registry.mjs +45 -2
  140. package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
  141. package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
  142. package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
  143. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +567 -0
  144. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +41 -13
  145. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
  146. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -6
  147. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +7 -3
  148. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  149. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +6 -1
  150. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +14 -5
  151. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
  152. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
  153. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
  154. package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
  155. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
  156. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +102 -12
  157. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
  158. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
  159. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
  160. package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
  161. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +160 -36
  162. package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
  163. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +164 -23
  164. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +139 -19
  165. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
  166. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
  167. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +100 -22
  168. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
  169. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -6
  170. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +33 -3
  171. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +9 -2
  172. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
  174. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +14 -0
  175. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +13 -1
  176. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +23 -4
  177. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +2 -0
  178. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
  179. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +39 -21
  180. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
  181. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +50 -28
  182. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
  183. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
  184. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +2 -2
  185. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +1 -0
  186. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +2 -1
  187. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +30 -13
  188. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +63 -6
  189. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +7 -0
  190. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
  191. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +35 -13
  192. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +24 -14
  193. package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
  194. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
  195. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +10 -6
  196. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
  197. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +3 -0
  198. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +56 -29
  199. package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
  200. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +11 -5
  201. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +5 -1
  202. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +30 -7
  203. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
  204. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
  205. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
  206. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
  207. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +37 -8
  208. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +252 -39
  209. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
  210. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +164 -4
  211. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
  212. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +61 -2
  213. package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
  214. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
  215. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
  216. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
  217. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -1
  218. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +46 -20
  219. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
  220. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +67 -31
  221. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +25 -13
  222. package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
  223. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
  224. package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
  225. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
  226. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
  227. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
  228. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
  229. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
  230. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
  231. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +96 -20
  232. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
  233. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
  234. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
  235. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  236. package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
  237. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
  238. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
  239. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +103 -13
  240. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
  241. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
  242. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
  243. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +34 -10
  244. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +28 -4
  245. package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
  246. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -2
  247. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  248. package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
  249. package/src/runtime/channels/lib/whisper-port.mjs +29 -11
  250. package/src/runtime/channels/lib/whisper-server.mjs +10 -1
  251. package/src/runtime/computer-bridge/action-schema.mjs +2 -2
  252. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  253. package/src/runtime/computer-bridge/error-recovery.mjs +5 -4
  254. package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
  255. package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
  256. package/src/runtime/connectors/connector-accounts-mcp.mjs +236 -103
  257. package/src/runtime/connectors/gmail-app-password.mjs +3 -3
  258. package/src/runtime/explore/explorer.mjs +93 -0
  259. package/src/runtime/explore/tool-defs.mjs +35 -0
  260. package/src/runtime/explore/tool.mjs +123 -0
  261. package/src/runtime/local-provider/server-process.mjs +2 -1
  262. package/src/runtime/media/adapters/gemini-video.mjs +4 -1
  263. package/src/runtime/media/adapters/xai-media.mjs +2 -1
  264. package/src/runtime/memory/index.mjs +4 -0
  265. package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
  266. package/src/runtime/memory/lib/embedding-worker.mjs +10 -3
  267. package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
  268. package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
  269. package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
  270. package/src/runtime/office/design/design-art-direction.mjs +29 -27
  271. package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
  272. package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
  273. package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
  274. package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
  275. package/src/runtime/office/quality/assurance-structure-docx.mjs +4 -2
  276. package/src/runtime/office/quality/design-review.mjs +1 -5
  277. package/src/runtime/office/quality/document-brief.mjs +1 -5
  278. package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
  279. package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
  280. package/src/runtime/shared/agent-route-config.mjs +17 -2
  281. package/src/runtime/shared/atomic-file.mjs +103 -2
  282. package/src/runtime/shared/background-tasks.mjs +15 -6
  283. package/src/runtime/shared/bot-owned-work.mjs +56 -0
  284. package/src/runtime/shared/connector-accounts.mjs +5 -5
  285. package/src/runtime/shared/connector-catalog.d.mts +11 -4
  286. package/src/runtime/shared/connector-catalog.mjs +60 -52
  287. package/src/runtime/shared/custom-provider-keys.mjs +20 -0
  288. package/src/runtime/shared/defaults-separation.mjs +1 -4
  289. package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
  290. package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
  291. package/src/runtime/shared/file-has-data.mjs +26 -2
  292. package/src/runtime/shared/file-lock.mjs +13 -15
  293. package/src/runtime/shared/git-launch.d.mts +9 -0
  294. package/src/runtime/shared/git-launch.mjs +213 -0
  295. package/src/runtime/shared/git-runner-worker.mjs +2 -1
  296. package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
  297. package/src/runtime/shared/handoff-artifacts.mjs +18 -8
  298. package/src/runtime/shared/idle-auto-clear-gate.mjs +29 -7
  299. package/src/runtime/shared/llm/cost.mjs +11 -2
  300. package/src/runtime/shared/llm/http-agent.mjs +313 -29
  301. package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
  302. package/src/runtime/shared/llm/model-catalog.mjs +46 -6
  303. package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
  304. package/src/runtime/shared/llm/system-proxy.mjs +452 -0
  305. package/src/runtime/shared/loopback-listener.mjs +25 -2
  306. package/src/runtime/shared/model-route-chain.d.mts +7 -2
  307. package/src/runtime/shared/model-route-chain.mjs +22 -4
  308. package/src/runtime/shared/open-url.mjs +10 -0
  309. package/src/runtime/shared/provider-accounts.mjs +52 -2
  310. package/src/runtime/shared/session-activity-signal.mjs +14 -0
  311. package/src/runtime/shared/session-scratch.mjs +37 -0
  312. package/src/runtime/shared/staged-install-worker.mjs +5 -0
  313. package/src/runtime/shared/staged-update.mjs +47 -2
  314. package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
  315. package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
  316. package/src/runtime/shared/tool-result-summary.mjs +1 -1
  317. package/src/runtime/shared/tool-surface.mjs +113 -36
  318. package/src/runtime/shared/tool-work-units.mjs +6 -0
  319. package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
  320. package/src/runtime/shared/turn-worktree-snapshot.mjs +414 -54
  321. package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
  322. package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
  323. package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
  324. package/src/runtime/shared/worktrees/branch-management.mjs +9 -3
  325. package/src/runtime/shared/worktrees/contract.mjs +4 -1
  326. package/src/runtime/shared/worktrees/git.mjs +72 -0
  327. package/src/runtime/shared/worktrees/manager.mjs +285 -168
  328. package/src/runtime/shared/worktrees/test-support.mjs +6 -10
  329. package/src/runtime/tidy/install.mjs +95 -15
  330. package/src/runtime/tidy/languages.mjs +17 -15
  331. package/src/runtime/tidy/process.mjs +7 -4
  332. package/src/runtime/tidy/resolve.mjs +19 -16
  333. package/src/runtime/tidy/runners/biome.mjs +3 -3
  334. package/src/runtime/tidy/tool.mjs +1 -1
  335. package/src/runtime/tidy/worktree.mjs +10 -6
  336. package/src/runtime/visualize-bridge/client.mjs +6 -1
  337. package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
  338. package/src/runtime/web-search/index.mjs +1 -1
  339. package/src/session-runtime/agent-home-delivery.mjs +41 -0
  340. package/src/session-runtime/agent-task-sessions.mjs +458 -312
  341. package/src/session-runtime/agent-tool-routing.mjs +8 -41
  342. package/src/session-runtime/boot/tools.mjs +7 -1
  343. package/src/session-runtime/bot-status.mjs +107 -101
  344. package/src/session-runtime/bot-target.mjs +38 -0
  345. package/src/session-runtime/channel-config-api.mjs +6 -1
  346. package/src/session-runtime/connector-merge-migration.mjs +18 -15
  347. package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
  348. package/src/session-runtime/conversation-import/discovery.mjs +401 -36
  349. package/src/session-runtime/conversation-import/service.mjs +35 -8
  350. package/src/session-runtime/handoff-attachments.mjs +82 -31
  351. package/src/session-runtime/held-requests.mjs +3 -1
  352. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +12 -13
  353. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +1 -0
  354. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -0
  355. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
  356. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
  357. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +145 -112
  358. package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
  359. package/src/session-runtime/lifecycle/session-catalog.mjs +9 -1
  360. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -1
  361. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  362. package/src/session-runtime/mcp-glue/server-catalog.mjs +16 -10
  363. package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
  364. package/src/session-runtime/mixy-heartbeat.mjs +1 -1
  365. package/src/session-runtime/model-route/set-route.mjs +11 -2
  366. package/src/session-runtime/provider-auth/login.mjs +2 -2
  367. package/src/session-runtime/provider-catalog-cache.mjs +82 -36
  368. package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
  369. package/src/session-runtime/provider-models.mjs +4 -2
  370. package/src/session-runtime/resource-mcp-api.mjs +98 -35
  371. package/src/session-runtime/resource-mcp-connector-accounts.mjs +44 -31
  372. package/src/session-runtime/resource-mcp-secrets.mjs +28 -11
  373. package/src/session-runtime/resource-mcp-servers.mjs +5 -4
  374. package/src/session-runtime/resource-recall-api.mjs +6 -1
  375. package/src/session-runtime/runtime-feature-gates.mjs +5 -1
  376. package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
  377. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
  378. package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
  379. package/src/session-runtime/services/agent-tool/render.mjs +71 -17
  380. package/src/session-runtime/services/agent-tool/send-flow.mjs +10 -2
  381. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
  382. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +4 -1
  383. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +6 -2
  384. package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
  385. package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
  386. package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
  387. package/src/session-runtime/services/daemon-candidate.mjs +4 -1
  388. package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
  389. package/src/session-runtime/services/plugin-admin.mjs +10 -6
  390. package/src/session-runtime/services/provider-admin.mjs +283 -11
  391. package/src/session-runtime/session-turn-api.mjs +2 -0
  392. package/src/session-runtime/settings-builtin-tools-api.mjs +4 -1
  393. package/src/session-runtime/settings-system-api.mjs +1 -1
  394. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
  395. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
  396. package/src/session-runtime/setup-tool/executor.mjs +6 -2
  397. package/src/session-runtime/setup-tool/tool-defs.mjs +2 -1
  398. package/src/session-runtime/tool-policy/policy-stage.mjs +1 -0
  399. package/src/session-runtime/turn/agent-ops.mjs +23 -0
  400. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +49 -11
  401. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
  402. package/src/session-runtime/workflow-agents-api/agent-route.mjs +25 -5
  403. package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
  404. package/src/session-runtime/workspace/activity-guards.mjs +176 -0
  405. package/src/session-runtime/workspace/session-view.mjs +149 -0
  406. package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
  407. package/src/session-runtime/workspace/transition-runner.mjs +188 -0
  408. package/src/session-runtime/workspace/transitions.mjs +108 -1041
  409. package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
  410. package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
  411. package/src/session-runtime/workspace/worktree-maintenance.mjs +80 -0
  412. package/src/session-runtime/workspace/worktree-setup.mjs +85 -0
  413. package/src/session-runtime/workspace/worktree-tool.mjs +73 -56
  414. package/src/standalone/daemon-desktop-runtime.mjs +2 -0
  415. package/src/standalone/daemon-session-control.mjs +169 -138
  416. package/src/standalone/daemon.mjs +7 -0
  417. package/src/standalone/desktop-service-registry.mjs +9 -0
  418. package/src/standalone/local-session-runtime.mjs +5 -1
  419. package/src/standalone/session-client/daemon-unavailable.mjs +3 -0
  420. package/src/standalone/session-client.mjs +5 -1
  421. package/src/standalone/session-frame-stream.mjs +83 -11
  422. package/src/standalone/session-protocol.mjs +4 -0
  423. package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
  424. package/src/standalone/session-service/agent-tree.mjs +45 -9
  425. package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
  426. package/src/standalone/session-service/session-calls/session-action.mjs +10 -3
  427. package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
  428. package/src/standalone/session-service/stored-reader.mjs +127 -40
  429. package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
  430. package/src/tui/App.jsx +154 -164
  431. package/src/tui/app/app-view/floating-panel.jsx +10 -4
  432. package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
  433. package/src/tui/app/clipboard.mjs +21 -10
  434. package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
  435. package/src/tui/app/model-picker/route-selection.mjs +5 -6
  436. package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
  437. package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
  438. package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
  439. package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
  440. package/src/tui/app/provider-setup/oauth-actions.mjs +58 -21
  441. package/src/tui/app/provider-setup/provider-items.mjs +8 -2
  442. package/src/tui/app/provider-setup-picker.mjs +29 -18
  443. package/src/tui/app/shell-layout/row-budgets.mjs +12 -10
  444. package/src/tui/app/slash-commands.mjs +1 -0
  445. package/src/tui/app/slash-dispatch/session-commands.mjs +46 -0
  446. package/src/tui/app/slash-dispatch.mjs +1 -1
  447. package/src/tui/app/use-btw-panel.mjs +29 -0
  448. package/src/tui/app/use-context-panel-refresh.mjs +31 -0
  449. package/src/tui/app/use-model-catalog-cache.mjs +13 -10
  450. package/src/tui/app/use-mouse-input.mjs +11 -0
  451. package/src/tui/app/use-onboarding-start.mjs +8 -3
  452. package/src/tui/app/use-panel-transition.mjs +10 -1
  453. package/src/tui/app/use-pasted-buffers.mjs +28 -20
  454. package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
  455. package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
  456. package/src/tui/app/use-prompt-queue-history.mjs +3 -2
  457. package/src/tui/app/use-selection-focus.mjs +11 -2
  458. package/src/tui/app/use-selection-geometry.mjs +18 -9
  459. package/src/tui/app/use-selection-paint.mjs +4 -4
  460. package/src/tui/app/use-selection-stitch.mjs +3 -3
  461. package/src/tui/app/use-slash-palette.mjs +62 -0
  462. package/src/tui/app/use-terminal-chrome.mjs +2 -2
  463. package/src/tui/app/use-transcript-activity.mjs +47 -32
  464. package/src/tui/app/use-transcript-follow.mjs +12 -4
  465. package/src/tui/app/use-transcript-scroll.mjs +46 -17
  466. package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
  467. package/src/tui/app/use-transcript-window/geometry.mjs +19 -5
  468. package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
  469. package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
  470. package/src/tui/app/use-transcript-window.mjs +21 -11
  471. package/src/tui/app/use-tui-ready.mjs +18 -0
  472. package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
  473. package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
  474. package/src/tui/components/Picker.jsx +27 -3
  475. package/src/tui/components/QuestionPanel.jsx +13 -4
  476. package/src/tui/components/SignInUrl.jsx +68 -0
  477. package/src/tui/components/TextEntryPanel.jsx +76 -46
  478. package/src/tui/components/sign-in-url-layout.mjs +24 -0
  479. package/src/tui/dist/index.mjs +1963 -1361
  480. package/src/tui/session/goal-turn-state.mjs +6 -2
  481. package/src/tui/session/session-api/controls.mjs +4 -0
  482. package/src/tui/session/session-api/extensions.mjs +8 -0
  483. package/src/tui/session/session-api/intake/abort.mjs +2 -1
  484. package/src/tui/session/session-api/intake.mjs +2 -0
  485. package/src/tui/session/session-api/integrations.mjs +2 -2
  486. package/src/tui/session/session-api/routes-agent-definitions.mjs +1 -0
  487. package/src/tui/session/session-api/settings.mjs +2 -2
  488. package/src/tui/session/session-flow/queue/take-entries.mjs +11 -0
  489. package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
  490. package/src/tui/session/transcript-spill.mjs +92 -4
  491. package/src/tui/session/transcript-store.mjs +2 -0
  492. package/src/ui/statusline-agents.mjs +1 -3
  493. package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
@@ -59,15 +59,19 @@ function omitToolsKey(omitTools) {
59
59
  .join(',');
60
60
  }
61
61
 
62
- export function _buildSharedRules({ omitTools = [], allowTools = null } = {}) {
62
+ export function _buildSharedRules({ omitTools = [], allowTools = null, ownerIsAgent = false } = {}) {
63
63
  const PLUGIN_ROOT = mixdogRoot();
64
64
  const RULES_DIR = join(PLUGIN_ROOT, 'rules');
65
65
  return buildCachedRules(
66
66
  'buildSharedToolContent',
67
67
  'shared tool rules',
68
68
  [join(RULES_DIR, 'shared')],
69
- { PLUGIN_ROOT, DATA_DIR: resolvePluginData(), omitTools, allowTools },
70
- JSON.stringify([omitToolsKey(omitTools), Array.isArray(allowTools) ? omitToolsKey(allowTools) : null])
69
+ { PLUGIN_ROOT, DATA_DIR: resolvePluginData(), omitTools, allowTools, ownerIsAgent },
70
+ JSON.stringify([
71
+ omitToolsKey(omitTools),
72
+ Array.isArray(allowTools) ? omitToolsKey(allowTools) : null,
73
+ ownerIsAgent === true,
74
+ ])
71
75
  );
72
76
  }
73
77
 
@@ -98,14 +102,22 @@ export function _buildRouteRules({ provider = null, model = null, omitTools = []
98
102
 
99
103
  // BP1 = shared tool policy followed by this route's rules. Every site that
100
104
  // renders or re-identifies the BP1 block must use this one composition.
101
- export function _buildBaseRules({ provider = null, model = null, omitTools = [], allowTools = null } = {}) {
102
- return [_buildSharedRules({ omitTools, allowTools }), _buildRouteRules({ provider, model, omitTools, allowTools })]
105
+ export function _buildBaseRules({
106
+ provider = null,
107
+ model = null,
108
+ omitTools = [],
109
+ allowTools = null,
110
+ ownerIsAgent = false,
111
+ } = {}) {
112
+ return [
113
+ _buildSharedRules({ omitTools, allowTools, ownerIsAgent }),
114
+ _buildRouteRules({ provider, model, omitTools, allowTools }),
115
+ ]
103
116
  .filter(Boolean)
104
117
  .join('\n\n---\n\n');
105
118
  }
106
119
 
107
- export function _buildAgentRules(profile = 'full') {
108
- const key = String(profile || 'full');
120
+ export function _buildAgentRules() {
109
121
  const PLUGIN_ROOT = mixdogRoot();
110
122
  const DATA_DIR = resolvePluginData();
111
123
  const RULES_DIR = join(PLUGIN_ROOT, 'rules');
@@ -113,8 +125,8 @@ export function _buildAgentRules(profile = 'full') {
113
125
  'buildAgentRoleContent',
114
126
  'agent role rules',
115
127
  [join(RULES_DIR, 'agent'), join(DATA_DIR, 'mixdog-config.json')],
116
- { PLUGIN_ROOT, DATA_DIR, profile: key },
117
- key
128
+ { PLUGIN_ROOT, DATA_DIR },
129
+ 'full'
118
130
  );
119
131
  }
120
132
 
@@ -201,9 +213,14 @@ export function _buildLeadLanguage() {
201
213
  });
202
214
  }
203
215
 
204
- export function _buildLeadLanguageContext() {
216
+ export function _buildLeadLanguageContext({ includeOutputStyle = true } = {}) {
217
+ const PLUGIN_ROOT = mixdogRoot();
205
218
  const DATA_DIR = resolvePluginData();
206
- return buildCachedRules('buildLeadLanguageContent', 'lead language context', [join(DATA_DIR, 'mixdog-config.json')], {
207
- DATA_DIR,
208
- });
219
+ return buildCachedRules(
220
+ 'buildLeadLanguageContent',
221
+ 'lead language context',
222
+ [join(DATA_DIR, 'mixdog-config.json'), join(PLUGIN_ROOT, 'output-styles'), join(DATA_DIR, 'output-styles')],
223
+ { PLUGIN_ROOT, DATA_DIR, includeOutputStyle },
224
+ includeOutputStyle ? 'style' : 'no-style'
225
+ );
209
226
  }
@@ -17,6 +17,10 @@
17
17
  // stage, lastStreamDeltaAt, lastTransportAt, firstSemanticAt,
18
18
  // lastSemanticAt, lastReasoningAt, lastVisibleTextAt, lastToolProtocolAt,
19
19
  // lastToolCall, lastError, updatedAt,
20
+ // modelRequestStartedAt, requestTransportAt, requestFirstSemanticAt,
21
+ // modelResponseAccepted, // the current logical model request (see
22
+ // // _setLogicalModelRequest); the fields above
23
+ // // stay turn-level history
20
24
  // controller?: AbortController, // set while an ask is in flight
21
25
  // generation?: number, // snapshot taken at ask start
22
26
  // closed?: boolean, // flipped by closeSession()
@@ -31,6 +35,7 @@ import { registerSessionPurgeHook } from '../store.mjs';
31
35
  import { finishComputerTurn } from '../../../../computer-bridge/client.mjs';
32
36
  import { configureUsageMetricsRuntime, dropMetricSeenState, bumpUsageMetricsTurnId } from './usage-metrics.mjs';
33
37
  import { runtimeState as _runtimeState, isTurnInFlight } from './runtime-state.mjs';
38
+ import { resetTurnShellReap } from './turn-reap.mjs';
34
39
 
35
40
  export { IN_FLIGHT_STAGES, inFlightSessionActivity } from './runtime-state.mjs';
36
41
 
@@ -131,6 +136,23 @@ function _startToolActivityHeartbeat(id) {
131
136
  _toolActivityHeartbeats.set(id, timer);
132
137
  }
133
138
 
139
+ // One logical model request owns one first-output allowance: its request
140
+ // clock and its own first transport / first semantic marks. It begins with the
141
+ // ask's first request, with the first request after the model's previous
142
+ // response was accepted (its tool calls ran — the request that carries the
143
+ // tool results), and with a request after a settled turn. Every other entry
144
+ // into `requesting` — a provider or loop retry, a route fallback, a no-tool
145
+ // recovery continuation — re-sends the same logical request and keeps all of
146
+ // it, so a retry never earns a fresh allowance. The turn-level marks
147
+ // (firstSemanticAt, lastTransportAt, …) are history and are not touched.
148
+ // `startedAt` null: no request yet (an ask starting).
149
+ function _setLogicalModelRequest(entry, startedAt) {
150
+ entry.modelRequestStartedAt = startedAt;
151
+ entry.requestTransportAt = null;
152
+ entry.requestFirstSemanticAt = null;
153
+ entry.modelResponseAccepted = false;
154
+ }
155
+
134
156
  export function updateSessionStage(id, stage) {
135
157
  if (stage === MODEL_THINKING_STAGE) {
136
158
  markSessionRequestSent(id);
@@ -143,8 +165,11 @@ export function updateSessionStage(id, stage) {
143
165
  entry.stage = stage;
144
166
  // A new stage (a retried attempt included) has not sent its request yet.
145
167
  entry.requestSentAt = null;
146
- if (stage === 'requesting' && priorStage !== 'requesting') {
147
- entry.modelRequestStartedAt = now;
168
+ if (
169
+ stage === 'requesting' &&
170
+ (!entry.modelRequestStartedAt || entry.modelResponseAccepted || TERMINAL_STAGES.has(priorStage))
171
+ ) {
172
+ _setLogicalModelRequest(entry, now);
148
173
  }
149
174
  entry.lastProgressAt = now;
150
175
  entry.updatedAt = now;
@@ -192,7 +217,8 @@ export function markSessionAskStart(id) {
192
217
  // after provider admission (the scheduler emits stage=requesting).
193
218
  const now = Date.now();
194
219
  entry.askStartedAt = now;
195
- entry.modelRequestStartedAt = null;
220
+ resetTurnShellReap(id, entry);
221
+ _setLogicalModelRequest(entry, null);
196
222
  entry.lastProgressAt = now;
197
223
  entry.updatedAt = now;
198
224
  entry.taskWaits = 0;
@@ -229,13 +255,14 @@ export function markSessionTransportActivity(id) {
229
255
  if (!entry || entry.closed || entry.controller?.signal?.aborted || TERMINAL_STAGES.has(entry.stage)) return;
230
256
  const now = Date.now();
231
257
  entry.lastTransportAt = now;
258
+ entry.requestTransportAt = now;
232
259
  entry.updatedAt = now;
233
260
  }
234
261
  function _normalizeModelProgressKind(kind) {
235
262
  let value = 'semantic';
236
263
  if (typeof kind === 'string') value = kind;
237
264
  else if (kind && typeof kind.kind === 'string') value = kind.kind;
238
- if (value === 'transport' || value === 'reasoning' || value === 'text' || value === 'tool') {
265
+ if (value === 'transport' || value === 'keepalive' || value === 'reasoning' || value === 'text' || value === 'tool') {
239
266
  return value;
240
267
  }
241
268
  return 'semantic';
@@ -257,12 +284,22 @@ export async function markSessionStreamDelta(id, kind = 'semantic') {
257
284
  markSessionTransportActivity(id);
258
285
  return;
259
286
  }
287
+ if (progressKind === 'keepalive') {
288
+ markSessionTransportActivity(id);
289
+ // A keepalive before the request's first semantic event is covered by the
290
+ // first-output window and never counts as progress. lastProgressAt stays
291
+ // untouched: the watchdog caps how long keepalives may extend it.
292
+ if (entry.requestFirstSemanticAt) entry.lastKeepaliveAt = Date.now();
293
+ return;
294
+ }
260
295
  _stopToolActivityHeartbeat(id);
261
296
  const now = Date.now();
262
297
  // Every semantic model event also proves transport health. The inverse is
263
298
  // intentionally false: raw chunks/keepalives update only lastTransportAt.
264
299
  entry.lastTransportAt = now;
300
+ entry.requestTransportAt = now;
265
301
  if (!entry.firstSemanticAt) entry.firstSemanticAt = now;
302
+ if (!entry.requestFirstSemanticAt) entry.requestFirstSemanticAt = now;
266
303
  entry.lastSemanticAt = now;
267
304
  entry.lastSemanticKind = progressKind;
268
305
  if (progressKind === 'reasoning') entry.lastReasoningAt = now;
@@ -296,7 +333,12 @@ export function markSessionToolCall(id, toolName) {
296
333
  entry.toolOutputTailAt = null;
297
334
  entry.toolStartedAt = Date.now();
298
335
  entry.lastTransportAt = entry.toolStartedAt;
336
+ entry.requestTransportAt = entry.toolStartedAt;
299
337
  if (!entry.firstSemanticAt) entry.firstSemanticAt = entry.toolStartedAt;
338
+ if (!entry.requestFirstSemanticAt) entry.requestFirstSemanticAt = entry.toolStartedAt;
339
+ // The response whose tool call runs now was accepted: the next model
340
+ // request carries its tool results and is a new logical request.
341
+ entry.modelResponseAccepted = true;
300
342
  entry.lastSemanticAt = entry.toolStartedAt;
301
343
  entry.lastSemanticKind = 'tool';
302
344
  entry.lastToolProtocolAt = entry.toolStartedAt;
@@ -436,6 +478,18 @@ export function markSessionCancelled(id) {
436
478
  entry.emptyFinalAt = null;
437
479
  _unlinkParentAbortListener(entry);
438
480
  }
481
+ /**
482
+ * The session's current logical model request: when it started and whether
483
+ * it has produced semantic output yet. A provider stream opened for it — a
484
+ * retry or a route fallback included — bounds its first-output phase by this
485
+ * request instead of starting a fresh one. Null without a request.
486
+ */
487
+ export function getLogicalModelRequest(sessionId) {
488
+ const entry = sessionId ? _runtimeState.get(sessionId) : null;
489
+ if (!entry?.modelRequestStartedAt) return null;
490
+ return { startedAt: entry.modelRequestStartedAt, outputSeen: Boolean(entry.requestFirstSemanticAt) };
491
+ }
492
+
439
493
  export function getSessionRuntime(id) {
440
494
  return id ? _runtimeState.get(id) || null : null;
441
495
  }
@@ -458,8 +512,10 @@ export function getSessionProgressSnapshot(sessionId) {
458
512
  const firstActivityAt = firstSemanticAt;
459
513
  const stage = entry.stage || 'idle';
460
514
  const activeModelStage = stage === 'connecting' || stage === 'requesting' || stage === 'streaming';
461
- const waitingForTransport = Boolean(modelRequestStartedAt && activeModelStage && !entry.lastTransportAt);
462
- const waitingForFirstSemantic = Boolean(modelRequestStartedAt && activeModelStage && !firstSemanticAt);
515
+ // Judged per logical model request: output an earlier request of this turn
516
+ // produced never ends a later request's first-output phase.
517
+ const waitingForTransport = Boolean(modelRequestStartedAt && activeModelStage && !entry.requestTransportAt);
518
+ const waitingForFirstSemantic = Boolean(modelRequestStartedAt && activeModelStage && !entry.requestFirstSemanticAt);
463
519
  return {
464
520
  stage,
465
521
  askStartedAt,
@@ -481,6 +537,7 @@ export function getSessionProgressSnapshot(sessionId) {
481
537
  toolOutputTail: entry.toolOutputTail || null,
482
538
  toolOutputTailAt: entry.toolOutputTailAt || 0,
483
539
  lastProgressAt: entry.lastProgressAt || 0,
540
+ lastKeepaliveAt: entry.lastKeepaliveAt || 0,
484
541
  updatedAt: entry.updatedAt || 0,
485
542
  hasFirstActivity: Boolean(firstSemanticAt && (!askStartedAt || firstSemanticAt >= askStartedAt)),
486
543
  hasFirstSemantic: Boolean(firstSemanticAt && (!askStartedAt || firstSemanticAt >= askStartedAt)),
@@ -30,6 +30,7 @@ import { releaseReadSnapshotScope } from '../../tools/builtin/snapshot-store.mjs
30
30
  import { cancelOwnedShellTrees } from '../../tools/lib/owned-shell-trees.mjs';
31
31
  import { noteShellOwnerSessionClosed } from '../../tools/builtin/lib/shell-job-records.mjs';
32
32
  import { forgetSideQuestion } from '../side-question-store.mjs';
33
+ import { cancelBackgroundTasks } from '../../../../shared/background-tasks.mjs';
33
34
 
34
35
  /**
35
36
  * Close a session. Plants a `closed=true` tombstone on disk with a bumped
@@ -214,6 +215,12 @@ function cancelOwnedShellProcesses({ id, reason, tombstone }) {
214
215
  } catch {
215
216
  unconfirmed();
216
217
  }
218
+ // What a finished command left running is a tracked task, not an owned tree.
219
+ try {
220
+ cancelBackgroundTasks({ surface: 'shell', executionSessionId: id, reason, notify: false });
221
+ } catch {
222
+ unconfirmed();
223
+ }
217
224
  noteShellOwnerSessionClosed(id);
218
225
  }
219
226
 
@@ -14,6 +14,7 @@ import { runSessionCompaction, resolveSessionCompactionPolicy } from './compacti
14
14
  import {
15
15
  currentContextEstimateTokens,
16
16
  invalidateContextUsageSnapshot,
17
+ invalidateProviderContextBaseline,
17
18
  recordContextUsageSnapshot,
18
19
  resolveGaugeContextTokens,
19
20
  } from '../loop/compact-policy.mjs';
@@ -26,6 +27,8 @@ import {
26
27
  import { getProvider } from '../../providers/registry.mjs';
27
28
  import { isSessionCompactionBlocked, getSessionAbortSignal, _runtimeEntries } from './runtime-liveness.mjs';
28
29
  import { mintSessionId } from './session-id.mjs';
30
+ import { useOwnScratchEnvironment } from './session-scratch-environment.mjs';
31
+ import { rebindToChangedPrefix } from '../thinking-binding.mjs';
29
32
  import { hideCompactionArchive } from '../compaction-archive-capture.mjs';
30
33
  import { writeStderrBestEffort } from '../../../../shared/best-effort-stderr.mjs';
31
34
  import { forgetSideQuestion } from '../side-question-store.mjs';
@@ -234,6 +237,18 @@ function forkOutgoingTranscript(session, messages, now, archiveAs = '') {
234
237
  ...clearedTokenAccounting(now),
235
238
  };
236
239
  delete fork.liveTurnMessages;
240
+ // The spread copied the source's environment: the fork names its own
241
+ // scratch directory (its shell commands use it), not the source's.
242
+ if (useOwnScratchEnvironment(fork)) {
243
+ // The system prefix changed: thinking stored in the copy was bound to the
244
+ // source's prefix (and an open tool round ended), and every measurement
245
+ // taken against it is stale. Resume then finds a matching prefix and
246
+ // would repair nothing.
247
+ fork.messages = rebindToChangedPrefix(fork.messages);
248
+ delete fork._providerPrefixGuardState;
249
+ invalidateContextUsageSnapshot(fork);
250
+ invalidateProviderContextBaseline(fork);
251
+ }
237
252
  // The archive sidecar belongs to the source id; the fork has none.
238
253
  if (fork.compaction?.archive) {
239
254
  fork.compaction = { ...fork.compaction };
@@ -42,11 +42,14 @@ import { ensureCodexWireSessionId, mintSessionId } from './session-id.mjs';
42
42
  import { providerCacheKey } from './provider-cache-key.mjs';
43
43
  import { buildSessionRecord, normalizeDesktopSessionMetadata, sessionOriginFields } from './session-record.mjs';
44
44
  import { normalizeWorkflowRoute } from '../../runtime-core/workflow.mjs';
45
+ import { executionFallbacks } from '../../../../shared/model-route-chain.mjs';
45
46
  import { ownerRouteFallbacks } from './owner-route-fallbacks.mjs';
46
47
  import { applyPendingWorkspaceReroot, refreshSessionBp3Environment } from './prompt-utils.mjs';
47
48
  import { isWorktreeBound } from '../../../../shared/worktrees/contract.mjs';
48
- import { applyAgentToolExposure } from '../loop/tool-exposure-migration.mjs';
49
+ import { applyAgentToolExposure, markToolSurfaceMigrated } from '../loop/tool-exposure-migration.mjs';
50
+ import { useOwnScratchEnvironment } from './session-scratch-environment.mjs';
49
51
  import { prewarmSessionAutoEffort } from './ask-turn-auto-effort.mjs';
52
+ import { cancelCacheWarm } from '../cache-warm.mjs';
50
53
 
51
54
  // Durable turn-checkpoint recovery; re-exported so prior importers of this
52
55
  // module stay unchanged.
@@ -162,9 +165,9 @@ function resolveSessionRoute(opts, presetObj, profile) {
162
165
  const modelName = opts.model || presetObj?.model;
163
166
  // opts.tools (caller-supplied) wins over presetObj.tools — caller
164
167
  // intent ('tools:readonly' from Pool C, etc.) must override the
165
- // preset's default 'full'. Previous priority let HAIKU's tools='full'
166
- // shadow Pool C's explicit readonly request, leaking write tools and
167
- // bash into a read-only agent.
168
+ // preset's default 'full'; otherwise a preset's tools='full' would shadow
169
+ // an explicit readonly request and leak write tools and bash into a
170
+ // read-only agent.
168
171
  const toolPreset = opts.tools || presetObj?.tools || (typeof opts.preset === 'string' ? opts.preset : null) || 'full';
169
172
  const effort = Object.hasOwn(opts, 'effort') ? opts.effort || null : presetObj?.effort || null;
170
173
  const fast = presetObj?.fast === true || opts.fast === true;
@@ -235,15 +238,21 @@ export function createSession(createOpts) {
235
238
  : { ...createOpts, sessionMode };
236
239
  // A Lead-class session (actingAgent set) takes its owner's chain while it
237
240
  // runs on the owner's primary model; an agent keeps its preset's.
238
- const routeFallbacks = actingAgent
239
- ? Object.hasOwn(opts, 'routeFallbacks')
241
+ const explicitRouteFallbacks = Object.hasOwn(opts, 'routeFallbacks');
242
+ let routeFallbacks;
243
+ if (actingAgent) {
244
+ routeFallbacks = explicitRouteFallbacks
240
245
  ? opts.routeFallbacks
241
- : ownerRouteFallbacks({ sessionMode, agentId: actingAgent, provider: providerName, model: modelName })
242
- : normalizeWorkflowRoute({
246
+ : ownerRouteFallbacks({ sessionMode, agentId: actingAgent, provider: providerName, model: modelName });
247
+ } else {
248
+ routeFallbacks = executionFallbacks(
249
+ normalizeWorkflowRoute({
243
250
  provider: providerName,
244
251
  model: modelName,
245
- fallbacks: Object.hasOwn(opts, 'routeFallbacks') ? opts.routeFallbacks : presetObj?.fallbacks,
246
- })?.fallbacks;
252
+ fallbacks: explicitRouteFallbacks ? opts.routeFallbacks : presetObj?.fallbacks,
253
+ })
254
+ );
255
+ }
247
256
  // Provider cache strategy — agentRuntime.resolveSync() above is a
248
257
  // best-effort injection point (setAgentRuntime() has no live caller
249
258
  // today, so that branch never fires); build it directly here so every
@@ -262,7 +271,7 @@ export function createSession(createOpts) {
262
271
  : agentProfileRevision(surface.resolvedAgent, { mixy: sessionMode === AGENT_MODE });
263
272
  // A bot thread lives on across releases: the rules it was built from.
264
273
  const rulesRevision = agentProfile && sessionMode === AGENT_MODE ? promptRulesRevision() : '';
265
- const prompt = composeSessionSystem(opts, { profile, providerName, modelName, surface, sessionMode });
274
+ const prompt = composeSessionSystem(opts, { profile, providerName, modelName, surface, sessionMode, sessionId: id });
266
275
  const messages = seedSessionMessages(prompt, opts.files);
267
276
  logSessionSurface(surface);
268
277
  const contextMeta = resolveSessionContextMeta(provider, modelName, {
@@ -322,24 +331,27 @@ export function contextSeedForRouteUpdate(session, routeChanged, selectedContext
322
331
  // ever replaced; custom-prompt or agent layouts without that block are left
323
332
  // untouched, and a same-variant switch is a no-op.
324
333
  export function _refreshSessionRuleVariantsForModel(session, previousModel, previousProvider = session?.provider) {
334
+ const ownerIsAgent = isAgentOwner(session);
325
335
  const deny = [
326
336
  ...(Array.isArray(session?.disallowedTools) ? session.disallowedTools : []),
327
337
  ...(getHiddenAgent(session?.agent || null) ? ['Skill'] : []),
328
- ...(delegationDisabled(session, isAgentOwner(session)) ? ['agent'] : []),
338
+ ...(delegationDisabled(session, ownerIsAgent) ? ['agent'] : []),
329
339
  ];
330
340
  const allowTools = honoredSchemaAllowlist(session?.schemaAllowedTools, {
331
- ownerIsAgent: isAgentOwner(session),
341
+ ownerIsAgent,
332
342
  agent: session?.agent || null,
333
343
  });
334
344
  const previousRules = _buildBaseRules({
335
345
  omitTools: [...deny, unusedModelEditToolName(previousModel)],
336
346
  allowTools,
347
+ ownerIsAgent,
337
348
  provider: previousProvider,
338
349
  model: previousModel,
339
350
  });
340
351
  const nextRules = _buildBaseRules({
341
352
  omitTools: [...deny, unusedModelEditToolName(session?.model)],
342
353
  allowTools,
354
+ ownerIsAgent,
343
355
  provider: session?.provider,
344
356
  model: session?.model,
345
357
  });
@@ -436,6 +448,10 @@ function resetSessionForRouteChange(id, session, previousModel, previousProvider
436
448
  delete session._providerPrefixGuardState;
437
449
  // The new route resolves its own wire before its first request.
438
450
  session.wireRoute = null;
451
+ // A warm chain replays the previous route's request: stop it. Its recorded
452
+ // warm use names that route, so it never counts as fresh cache for the new
453
+ // one (compact-policy.mjs shouldCompactForExpiredAgentCache).
454
+ cancelCacheWarm(id);
439
455
  const prepared = _prepareResumeTools(session, session.preset || 'full');
440
456
  session.tools = prepared.tools;
441
457
  session.toolSpec = prepared.toolSpec;
@@ -583,6 +599,12 @@ export async function resumeSession(sessionId, preset, options = {}) {
583
599
  _recoverTurnCheckpointDurably(session, sessionId);
584
600
  _refreshResumedTools(session, sessionId, preset);
585
601
  refreshSessionProviderCacheOpts(session);
602
+ // An archive saved before clear learned to rename it still names the
603
+ // session it was copied from: a changed prefix is one cache break.
604
+ if (useOwnScratchEnvironment(session)) {
605
+ invalidateContextUsageSnapshot(session);
606
+ markToolSurfaceMigrated(session, 'prompt_fold');
607
+ }
586
608
  // The live session already owns the refreshed tools and desktop scope.
587
609
  // Defer the structured clone + worker round-trip so opening a conversation
588
610
  // is not blocked on persisting the same in-memory state back to disk.
@@ -21,9 +21,22 @@ import {
21
21
  describeShellToolsStartupState,
22
22
  } from '../../tools/builtin/runtime-capabilities.mjs';
23
23
  import { captureOriginalUserCwd } from '../../../../shared/user-cwd.mjs';
24
+ import { sessionScratchDir } from '../../../../shared/session-scratch.mjs';
24
25
  import { delegationDisabled } from './session-tool-surface.mjs';
25
26
  import { contextAckMessage } from '../compact/user-message-kind.mjs';
26
27
 
28
+ /** What the generated scratch line starts with; the one place that line is recognised. */
29
+ export const SCRATCH_LINE_PREFIX = '- Scratch: ';
30
+
31
+ /** The environment line naming `sessionId`'s scratch directory, '' without one. */
32
+ export function scratchEnvironmentLine(sessionId) {
33
+ // Fixed per session id and data dir, so the line never changes across turns.
34
+ const scratchDir = sessionScratchDir(sessionId);
35
+ return scratchDir
36
+ ? `${SCRATCH_LINE_PREFIX}${scratchDir} — this session's scratch directory; TEMP, TMP and TMPDIR in shell commands point here.`
37
+ : '';
38
+ }
39
+
27
40
  // Preserve the exact pre-layout environment payload: Lead carried the
28
41
  // shell preference in Profile Preferences, while any routing surface with
29
42
  // shell carried the startup capability line in BP1.
@@ -31,7 +44,7 @@ import { contextAckMessage } from '../compact/user-message-kind.mjs';
31
44
  // it still get a location line via captureOriginalUserCwd(), which
32
45
  // resolves explicit session signals first and never leaks the daemon's
33
46
  // install root (user-cwd.mjs safe fallback chain).
34
- function buildShellEnvironmentContext(opts, ownerIsAgent, toolsForRouting) {
47
+ function buildShellEnvironmentContext(opts, ownerIsAgent, toolsForRouting, sessionId = null) {
35
48
  const sessionCwdLine = opts.cwd || captureOriginalUserCwd();
36
49
  const wantsGitStartupLine = toolsForRouting.some((tool) => tool?.name === 'git');
37
50
  let cwdContextLine = '';
@@ -45,6 +58,7 @@ function buildShellEnvironmentContext(opts, ownerIsAgent, toolsForRouting) {
45
58
  return [
46
59
  cwdContextLine,
47
60
  `- Shell: ${shellName}. Use ${shellName} syntax unless the user specifies otherwise.`,
61
+ scratchEnvironmentLine(sessionId),
48
62
  // Which common tools the shell can run, measured where commands run
49
63
  // (login shell on POSIX, this process's PATH on Windows); see
50
64
  // runtime-capabilities.mjs. Recorded runs spent a round per session
@@ -84,7 +98,7 @@ export function buildWorkspacePromptContext(session, cwd) {
84
98
  ...(Array.isArray(session?.deferredToolCatalog) ? session.deferredToolCatalog : []),
85
99
  ];
86
100
  return {
87
- environmentContext: buildShellEnvironmentContext({ cwd }, ownerIsAgent, tools),
101
+ environmentContext: buildShellEnvironmentContext({ cwd }, ownerIsAgent, tools, session?.id),
88
102
  // Agent mode never carries project instruction files.
89
103
  instructionFilesContext:
90
104
  session?.skipInstructionFiles === true || sessionModeOf(session) === AGENT_MODE
@@ -107,15 +121,11 @@ export function sessionRolePromptFields(identity, { ownerIsAgent, toolFreeRole,
107
121
  const mixy = (identity.agent || MIXY_AGENT_ID) === MIXY_AGENT_ID;
108
122
  let roleRules = '';
109
123
  if (!skipRules) {
110
- roleRules = ownerIsAgent
111
- ? _buildAgentRules(identity.agentRulesProfile)
112
- : _buildLeadRules({ includeLeadBrief: !delegationFree });
124
+ roleRules = ownerIsAgent ? _buildAgentRules() : _buildLeadRules({ includeLeadBrief: !delegationFree });
113
125
  }
114
- const identityLine = agentMode
115
- ? agentModeIdentityLine(identity.agent || MIXY_AGENT_ID)
116
- : lead
117
- ? _buildLeadRules({ includeLeadBrief: !delegationFree, part: 'identity' })
118
- : '';
126
+ let identityLine = '';
127
+ if (agentMode) identityLine = agentModeIdentityLine(identity.agent || MIXY_AGENT_ID);
128
+ else if (lead) identityLine = _buildLeadRules({ includeLeadBrief: !delegationFree, part: 'identity' });
119
129
  return {
120
130
  roleRules,
121
131
  ...(lead
@@ -143,7 +153,7 @@ export function sessionRolePromptFields(identity, { ownerIsAgent, toolFreeRole,
143
153
  };
144
154
  }
145
155
 
146
- export function composeSessionSystem(opts, { profile, providerName, modelName, surface, sessionMode }) {
156
+ export function composeSessionSystem(opts, { profile, providerName, modelName, surface, sessionMode, sessionId }) {
147
157
  const agentMode = sessionMode === AGENT_MODE;
148
158
  const { ownerIsAgent, resolvedAgent, skills } = surface;
149
159
  // A tool-free hidden role (a one-shot classifier or title writer) carries
@@ -156,6 +166,7 @@ export function composeSessionSystem(opts, { profile, providerName, modelName, s
156
166
  : _buildBaseRules({
157
167
  omitTools: surface.ruleOmitTools,
158
168
  allowTools: surface.schemaAllowedTools,
169
+ ownerIsAgent,
159
170
  provider: providerName,
160
171
  model: modelName,
161
172
  });
@@ -165,7 +176,6 @@ export function composeSessionSystem(opts, { profile, providerName, modelName, s
165
176
  skipAgentRules: opts.skipAgentRules === true,
166
177
  profileSkip: { ...profile?.skip },
167
178
  agent: resolvedAgent,
168
- agentRulesProfile: surface.agentRulesProfile,
169
179
  };
170
180
  const roleFields = sessionRolePromptFields(promptIdentity, {
171
181
  ownerIsAgent,
@@ -177,12 +187,12 @@ export function composeSessionSystem(opts, { profile, providerName, modelName, s
177
187
  const metaContext = leadOnly ? _buildLeadMetaContext({ includeOutputStyle: !agentMode }) : '';
178
188
  // Lead-only response language; closes the environment block so no English
179
189
  // system text (session/shell/git lines) follows it.
180
- const languageContext = leadOnly ? _buildLeadLanguageContext() : '';
190
+ const languageContext = leadOnly ? _buildLeadLanguageContext({ includeOutputStyle: !agentMode }) : '';
181
191
  // Cwd, shell and repository facts only serve tool calls; a tool-free role
182
192
  // gets none, which also keeps its prompt identical across projects.
183
193
  const shellEnvironmentContext = toolFreeRole
184
194
  ? ''
185
- : buildShellEnvironmentContext(opts, ownerIsAgent, surface.toolsForRouting);
195
+ : buildShellEnvironmentContext(opts, ownerIsAgent, surface.toolsForRouting, sessionId);
186
196
  // Persisted env tail: refreshSessionBp3Environment rebuilds the env block
187
197
  // as [session, bp3EnvironmentContext], so the language block must
188
198
  // already sit at the end of this string to stay last after a refresh.
@@ -0,0 +1,70 @@
1
+ // manager/session-scratch-environment.mjs
2
+ // A session record that was copied from another session (a clear archive)
3
+ // still names the SOURCE's scratch directory in its generated environment,
4
+ // while its shell commands use its own. This rewrites only that line.
5
+ import {
6
+ BP3_PART_SEPARATOR,
7
+ bp3SystemMessage,
8
+ bpEnvSystemMessage,
9
+ replaceSystemMessageContent,
10
+ replaceWorkspaceEnvironment,
11
+ } from './prompt-utils.mjs';
12
+ import { SCRATCH_LINE_PREFIX, scratchEnvironmentLine } from './session-prompt-composition.mjs';
13
+
14
+ // The first line the generator's own prefix starts is the scratch line.
15
+ function withLine(text, line) {
16
+ if (typeof text !== 'string') return text;
17
+ const rows = text.split('\n');
18
+ const at = rows.findIndex((row) => row.startsWith(SCRATCH_LINE_PREFIX));
19
+ if (at < 0) return text;
20
+ rows[at] = line;
21
+ return rows.join('\n');
22
+ }
23
+
24
+ // Only the generated environment facts (the first part of the environment
25
+ // tail) hold the line; memory and instruction files never do.
26
+ function tailWithLine(tail, line) {
27
+ if (typeof tail !== 'string') return tail;
28
+ const facts = tail.split(BP3_PART_SEPARATOR)[0];
29
+ const fixed = withLine(facts, line);
30
+ return fixed === facts ? tail : replaceWorkspaceEnvironment(tail, fixed);
31
+ }
32
+
33
+ /**
34
+ * Make `session`'s generated environment name its own scratch directory:
35
+ * the persisted environment tail, the system block carrying it and the
36
+ * environment facts of a staged workspace change. Instruction files, memory
37
+ * and every conversation message stay as they are; a session that already
38
+ * names its own directory is left byte-identical (message objects included).
39
+ * System messages are replaced in the session's own array, never mutated.
40
+ * @returns {boolean} whether the system prefix changed
41
+ */
42
+ export function useOwnScratchEnvironment(session) {
43
+ const line = scratchEnvironmentLine(session?.id);
44
+ if (!line) return false;
45
+ const oldTail = session.bp3EnvironmentContext;
46
+ const newTail = tailWithLine(oldTail, line);
47
+ session.bp3EnvironmentContext = newTail;
48
+ const pending = session.workspaceReroot;
49
+ const seen = tailWithLine(pending?.seen?.environmentContext, line);
50
+ const target = tailWithLine(pending?.target?.environmentContext, line);
51
+ if (seen !== pending?.seen?.environmentContext || target !== pending?.target?.environmentContext) {
52
+ // The staged state may be shared with the session this one was copied
53
+ // from: replace it, never edit it.
54
+ session.workspaceReroot = {
55
+ ...pending,
56
+ seen: { ...pending.seen, environmentContext: seen },
57
+ target: { ...pending.target, environmentContext: target },
58
+ };
59
+ }
60
+ if (newTail === oldTail || typeof oldTail !== 'string') return false;
61
+ // The generated environment closes its block (split env block, or the
62
+ // combined tier3 block after core + session start): swap that suffix.
63
+ const block = session.bp3EnvSplit === true ? bpEnvSystemMessage(session) : bp3SystemMessage(session);
64
+ const content = block?.content;
65
+ const suffix = oldTail.trim();
66
+ if (typeof content !== 'string' || !suffix || !content.endsWith(suffix)) return false;
67
+ const next = content.slice(0, -suffix.length) + newTail.trim();
68
+ // The prefix changed exactly when the system block's text did.
69
+ return replaceSystemMessageContent(session, block, next) && next !== content;
70
+ }
@@ -74,8 +74,6 @@ function schemaOmittedToolNames(toolsForRouting, tools) {
74
74
  export function resolveSessionToolSurface(opts, { profile, toolPreset, modelName }) {
75
75
  const ownerIsAgent = isAgentOwner(opts.owner);
76
76
  const resolvedAgent = opts.agent || opts.role || profile?.taskType || null;
77
- const hiddenAgent = getHiddenAgent(resolvedAgent);
78
- const isRetrievalAgent = hiddenAgent?.kind === 'retrieval';
79
77
  const hasCallerAllow = Array.isArray(opts.schemaAllowedTools);
80
78
  const schemaAllowedTools = honoredSchemaAllowlist(opts.schemaAllowedTools, { ownerIsAgent, agent: resolvedAgent });
81
79
  // Lead and Agent share the same cwd-scoped Skill inventory. A session that
@@ -112,7 +110,6 @@ export function resolveSessionToolSurface(opts, { profile, toolPreset, modelName
112
110
  return {
113
111
  ownerIsAgent,
114
112
  resolvedAgent,
115
- agentRulesProfile: isRetrievalAgent ? 'retrieval' : 'full',
116
113
  skills,
117
114
  sessionDeny,
118
115
  toolPermission,