mixdog 1.2.2 → 1.2.4

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 (692) hide show
  1. package/README.md +18 -0
  2. package/package.json +2 -1
  3. package/scripts/gate-local.mjs +6 -4
  4. package/scripts/lib/gate-scheduler.mjs +29 -11
  5. package/scripts/probe-provider-catalog.mjs +31 -0
  6. package/scripts/provider-pingpong-live.mjs +599 -0
  7. package/scripts/session-sweep.mjs +5 -25
  8. package/src/agents/advisor/AGENT.md +1 -1
  9. package/src/agents/advisor/agent.json +1 -1
  10. package/src/agents/maintainer/AGENT.md +1 -1
  11. package/src/agents/maintainer/agent.json +1 -1
  12. package/src/agents/reviewer/AGENT.md +2 -4
  13. package/src/agents/security/AGENT.md +1 -2
  14. package/src/agents/writer/AGENT.md +2 -3
  15. package/src/defaults/shipped-history.json +11 -1
  16. package/src/defaults/skills/image/SKILL.md +21 -23
  17. package/src/defaults/skills/setup/SKILL.md +6 -1
  18. package/src/defaults/skills/setup/references/actions.md +44 -22
  19. package/src/defaults/skills/setup/references/surfaces.md +10 -8
  20. package/src/headless-exec.mjs +15 -8
  21. package/src/lib/keychain-cjs.cjs +20 -15
  22. package/src/output-styles/common.md +11 -10
  23. package/src/rules/agent/AGENT.md +6 -4
  24. package/src/rules/lead/LEAD.md +7 -9
  25. package/src/rules/shared/45-destructive.md +4 -0
  26. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
  28. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
  29. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
  30. package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
  31. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
  32. package/src/runtime/agent/orchestrator/config.mjs +5 -0
  33. package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
  34. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
  35. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
  36. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
  37. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
  38. package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
  39. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
  40. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +3 -1
  41. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
  42. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +9 -9
  43. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
  45. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +31 -15
  46. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
  47. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
  48. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
  49. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
  50. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
  51. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
  52. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
  53. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -0
  54. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
  55. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +10 -0
  56. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
  57. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
  58. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +131 -9
  59. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
  60. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +125 -8
  61. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +12 -62
  62. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +117 -41
  63. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  64. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
  65. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
  66. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +39 -5
  67. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  68. package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
  69. package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
  70. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
  71. package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +42 -11
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +109 -6
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +17 -4
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -2
  76. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +73 -7
  77. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +75 -6
  78. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
  79. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
  80. package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
  81. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +29 -5
  82. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
  83. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +36 -13
  84. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +101 -11
  85. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
  86. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
  87. package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
  88. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +19 -14
  89. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +371 -41
  90. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
  91. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +97 -49
  92. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +81 -10
  93. package/src/runtime/agent/orchestrator/providers/gemini.mjs +35 -8
  94. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
  96. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
  97. package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
  98. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +253 -42
  99. package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
  100. package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
  101. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +392 -0
  102. package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
  103. package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
  104. package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
  105. package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
  106. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
  107. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +50 -22
  108. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +133 -21
  109. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
  110. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
  111. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
  112. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  113. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +92 -16
  114. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -13
  115. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
  116. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +133 -62
  117. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
  118. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +5 -2
  119. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +39 -7
  120. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
  121. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
  122. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +1 -1
  123. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +84 -2
  124. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
  125. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
  126. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +155 -0
  127. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +40 -24
  128. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
  129. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
  130. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +183 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +87 -6
  132. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
  133. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
  134. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
  135. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
  136. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
  137. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
  138. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +17 -2
  139. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
  140. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
  141. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
  142. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +28 -5
  143. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
  144. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
  145. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +4 -0
  146. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
  147. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
  148. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
  149. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
  150. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
  151. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
  152. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +72 -24
  153. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
  154. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +50 -16
  155. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -19
  156. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
  157. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -36
  158. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
  159. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
  160. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
  161. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -9
  162. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +181 -0
  163. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +78 -70
  164. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +74 -0
  165. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +150 -10
  166. package/src/runtime/agent/orchestrator/providers/registry.mjs +13 -2
  167. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +7 -1
  168. package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
  169. package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
  170. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +164 -0
  171. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +522 -0
  172. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
  173. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +195 -0
  174. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +104 -0
  175. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
  176. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +24 -0
  177. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
  178. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
  179. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
  180. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
  181. package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
  182. package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
  183. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +16 -3
  184. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
  185. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
  186. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  187. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
  188. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +178 -71
  189. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +102 -12
  190. package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
  191. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
  192. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
  193. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
  194. package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
  195. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
  196. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -11
  197. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
  198. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
  199. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +16 -93
  200. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
  201. package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
  202. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +148 -0
  203. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  204. package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
  205. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
  206. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
  207. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
  208. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +3 -2
  209. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
  210. package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
  211. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
  212. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +89 -1
  213. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
  214. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
  215. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
  216. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -27
  217. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
  218. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
  219. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
  220. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +24 -10
  221. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +135 -0
  222. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +31 -4
  223. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
  224. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
  225. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +10 -10
  226. package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
  227. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
  228. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
  229. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +29 -5
  230. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
  231. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +147 -0
  232. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -5
  233. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
  234. package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
  235. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +23 -2
  236. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
  237. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +54 -13
  238. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
  239. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
  240. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +11 -0
  241. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +22 -0
  242. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
  243. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
  244. package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
  245. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
  246. package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
  247. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +231 -16
  248. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
  249. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
  250. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +47 -17
  251. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +26 -4
  252. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
  253. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +36 -35
  254. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
  255. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +6 -3
  256. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
  257. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
  258. package/src/runtime/agent/orchestrator/session/manager.mjs +4 -10
  259. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
  260. package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
  261. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +17 -1
  262. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
  263. package/src/runtime/agent/orchestrator/session/side-question.mjs +197 -0
  264. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +22 -15
  265. package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
  266. package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
  267. package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
  269. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
  270. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
  271. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
  272. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +44 -37
  273. package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
  274. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
  275. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
  276. package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
  277. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -21
  278. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
  279. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
  280. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
  281. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +4 -2
  282. package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
  283. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
  284. package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
  285. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +53 -115
  286. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
  287. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -1
  288. package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
  289. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
  290. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +17 -10
  291. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
  292. package/src/runtime/agent/orchestrator/session/store.mjs +22 -19
  293. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +12 -12
  294. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +38 -14
  295. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
  296. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
  297. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
  298. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
  299. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +79 -0
  300. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
  301. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
  302. package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
  303. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
  304. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
  305. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
  306. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
  307. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
  308. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +218 -20
  309. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
  310. package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
  311. package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
  312. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
  313. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
  314. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
  315. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
  316. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +247 -49
  317. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
  318. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
  319. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
  320. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
  321. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
  322. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
  323. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
  324. package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
  325. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
  326. package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
  327. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
  328. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
  329. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
  330. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
  331. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
  332. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
  333. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
  334. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
  335. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
  336. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
  337. package/src/runtime/attachments/store.d.mts +9 -0
  338. package/src/runtime/attachments/store.mjs +80 -9
  339. package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
  340. package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
  341. package/src/runtime/computer-bridge/action-schema.mjs +219 -196
  342. package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
  343. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
  344. package/src/runtime/effort-judge/judge-client.mjs +21 -4
  345. package/src/runtime/effort-judge/judge-worker.mjs +4 -1
  346. package/src/runtime/github/tool.mjs +208 -17
  347. package/src/runtime/media/adapters/codex-image.mjs +140 -21
  348. package/src/runtime/media/catalog.mjs +4 -4
  349. package/src/runtime/media/chatgpt-usage.mjs +55 -0
  350. package/src/runtime/media/defaults.mjs +37 -0
  351. package/src/runtime/media/jobs.mjs +12 -2
  352. package/src/runtime/media/lanes.mjs +12 -0
  353. package/src/runtime/media/tool-defs.mjs +15 -4
  354. package/src/runtime/media/tool.mjs +41 -12
  355. package/src/runtime/media/upstream-error.mjs +72 -6
  356. package/src/runtime/memory/index.mjs +1 -0
  357. package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
  358. package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
  359. package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
  360. package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
  361. package/src/runtime/memory/lib/pg/process.mjs +36 -33
  362. package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
  363. package/src/runtime/memory/lib/pg/supervisor.mjs +112 -4
  364. package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
  365. package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
  366. package/src/runtime/office/README.md +1 -1
  367. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  368. package/src/runtime/office/authoring/html-browser.mjs +18 -8
  369. package/src/runtime/office/authoring/html-document-author.mjs +2 -0
  370. package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
  371. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
  372. package/src/runtime/office/authoring/pptx-html-measure.mjs +3 -1
  373. package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
  374. package/src/runtime/office/authoring/xlsx-html-runner.mjs +3 -1
  375. package/src/runtime/office/core/office-actions-read.mjs +3 -0
  376. package/src/runtime/office/core/office-render-preview.mjs +2 -0
  377. package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
  378. package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
  379. package/src/runtime/office/core/office-sessions.mjs +5 -0
  380. package/src/runtime/office/core/office-transactions.mjs +3 -0
  381. package/src/runtime/office/core/office-write-ledger.mjs +94 -0
  382. package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
  383. package/src/runtime/office/index.mjs +29 -0
  384. package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
  385. package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
  386. package/src/runtime/office/pdf/pdf-render.mjs +23 -7
  387. package/src/runtime/office/pdf/pdf-security.mjs +2 -0
  388. package/src/runtime/office/portable/portable-opc.mjs +4 -1
  389. package/src/runtime/office/quality/visual-diff.mjs +2 -0
  390. package/src/runtime/session-search/session-search-ingest.mjs +1 -1
  391. package/src/runtime/shared/agent-reap-state.mjs +13 -0
  392. package/src/runtime/shared/atomic-file.d.mts +1 -1
  393. package/src/runtime/shared/background-tasks.mjs +6 -1
  394. package/src/runtime/shared/bounded-file-read.mjs +13 -0
  395. package/src/runtime/shared/bounded-line-diff.mjs +191 -0
  396. package/src/runtime/shared/browser-launch.mjs +15 -0
  397. package/src/runtime/shared/buffered-appender.mjs +18 -0
  398. package/src/runtime/shared/config.mjs +78 -18
  399. package/src/runtime/shared/err-text.mjs +48 -4
  400. package/src/runtime/shared/file-lock.mjs +6 -5
  401. package/src/runtime/shared/file-permissions.d.mts +6 -1
  402. package/src/runtime/shared/file-permissions.mjs +54 -6
  403. package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
  404. package/src/runtime/shared/llm/anthropic-effort.mjs +6 -0
  405. package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
  406. package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
  407. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
  408. package/src/runtime/shared/loopback-listener.mjs +9 -0
  409. package/src/runtime/shared/model-route-chain.d.mts +8 -0
  410. package/src/runtime/shared/model-route-chain.mjs +48 -0
  411. package/src/runtime/shared/model-route-fallback.mjs +22 -0
  412. package/src/runtime/shared/pid-liveness.mjs +12 -0
  413. package/src/runtime/shared/provider-api-key.mjs +8 -0
  414. package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
  415. package/src/runtime/shared/quiet-progress.d.mts +35 -0
  416. package/src/runtime/shared/quiet-progress.mjs +101 -0
  417. package/src/runtime/shared/quota-resume-store.mjs +32 -1
  418. package/src/runtime/shared/read-row-numbers.mjs +44 -0
  419. package/src/runtime/shared/remote-intent.mjs +2 -42
  420. package/src/runtime/shared/review-diff.mjs +52 -0
  421. package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
  422. package/src/runtime/shared/session-sidebar-host.mjs +38 -0
  423. package/src/runtime/shared/slow-span.mjs +121 -0
  424. package/src/runtime/shared/statusline/statusline-segments.mjs +52 -6
  425. package/src/runtime/shared/tool-card-model/card-header.mjs +7 -1
  426. package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
  427. package/src/runtime/shared/tool-card-model.mjs +5 -2
  428. package/src/runtime/shared/tool-output-budget.mjs +2 -0
  429. package/src/runtime/shared/tool-output-limit.mjs +4 -0
  430. package/src/runtime/shared/tool-primitives.mjs +13 -0
  431. package/src/runtime/shared/tool-result-summary.mjs +22 -1
  432. package/src/runtime/shared/tool-status.mjs +3 -2
  433. package/src/runtime/shared/tool-surface.mjs +20 -6
  434. package/src/runtime/shared/tool-work-units.mjs +54 -11
  435. package/src/runtime/shared/transcript-metadata.mjs +49 -1
  436. package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
  437. package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
  438. package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
  439. package/src/runtime/shared/transcript-writer.mjs +24 -6
  440. package/src/runtime/shared/turn-changes.mjs +269 -100
  441. package/src/runtime/shared/turn-review-reply.mjs +8 -39
  442. package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
  443. package/src/runtime/shared/turn-snapshot.mjs +865 -683
  444. package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
  445. package/src/runtime/shared/user-data-guard.mjs +262 -49
  446. package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
  447. package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
  448. package/src/runtime/shared/worktrees/carry.mjs +533 -0
  449. package/src/runtime/shared/worktrees/contract.mjs +60 -0
  450. package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
  451. package/src/runtime/shared/worktrees/file-recovery.mjs +84 -0
  452. package/src/runtime/shared/worktrees/git-head.mjs +214 -0
  453. package/src/runtime/shared/worktrees/git.mjs +8 -3
  454. package/src/runtime/shared/worktrees/include.mjs +125 -7
  455. package/src/runtime/shared/worktrees/lock.mjs +1 -1
  456. package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
  457. package/src/runtime/shared/worktrees/manager.mjs +525 -31
  458. package/src/runtime/shared/worktrees/merge.mjs +31 -21
  459. package/src/runtime/shared/worktrees/owner.mjs +2 -1
  460. package/src/runtime/shared/worktrees/paths.d.mts +6 -0
  461. package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
  462. package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
  463. package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
  464. package/src/runtime/terminal-bridge/client.mjs +57 -20
  465. package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
  466. package/src/runtime/tidy/apply.mjs +47 -2
  467. package/src/runtime/tidy/run-engines.mjs +11 -5
  468. package/src/session-runtime/agent-tool-routing.mjs +19 -13
  469. package/src/session-runtime/boot/apis.mjs +20 -6
  470. package/src/session-runtime/boot/config.mjs +2 -0
  471. package/src/session-runtime/boot/facade.mjs +4 -0
  472. package/src/session-runtime/boot/infrastructure.mjs +6 -1
  473. package/src/session-runtime/boot/session.mjs +3 -3
  474. package/src/session-runtime/boot/tools.mjs +7 -1
  475. package/src/session-runtime/conversation-import/service.mjs +1 -1
  476. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
  477. package/src/session-runtime/goal-facade-api.mjs +2 -2
  478. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +91 -0
  479. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
  480. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +15 -5
  481. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +137 -26
  482. package/src/session-runtime/internal-tool-executor.mjs +8 -2
  483. package/src/session-runtime/lifecycle/cold-heir.mjs +187 -0
  484. package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
  485. package/src/session-runtime/lifecycle/session-catalog.mjs +25 -18
  486. package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
  487. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +36 -48
  488. package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
  489. package/src/session-runtime/lifecycle/shared.mjs +5 -6
  490. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
  491. package/src/session-runtime/lifecycle/teardown.mjs +70 -14
  492. package/src/session-runtime/lifecycle-api.mjs +1 -0
  493. package/src/session-runtime/mcp-glue/connect.mjs +17 -5
  494. package/src/session-runtime/media-api.mjs +8 -0
  495. package/src/session-runtime/model-route/route-ownership.mjs +60 -0
  496. package/src/session-runtime/model-route/route-persist.mjs +3 -2
  497. package/src/session-runtime/model-route/set-route.mjs +116 -36
  498. package/src/session-runtime/model-route/web-search-route.mjs +7 -2
  499. package/src/session-runtime/model-route-api.mjs +4 -2
  500. package/src/session-runtime/native-web-search/routes.mjs +37 -24
  501. package/src/session-runtime/native-web-search-usage.mjs +51 -0
  502. package/src/session-runtime/native-web-search.mjs +19 -9
  503. package/src/session-runtime/new-session-config.mjs +4 -2
  504. package/src/session-runtime/provider-auth/login.mjs +4 -0
  505. package/src/session-runtime/provider-auth/setup.mjs +4 -0
  506. package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
  507. package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
  508. package/src/session-runtime/provider-models.mjs +1 -0
  509. package/src/session-runtime/provider-usage.mjs +4 -0
  510. package/src/session-runtime/resource-scope-decorate.mjs +10 -3
  511. package/src/session-runtime/route-resolution.mjs +3 -1
  512. package/src/session-runtime/runtime-core.mjs +4 -0
  513. package/src/session-runtime/runtime-facade.mjs +6 -0
  514. package/src/session-runtime/runtime-review-api.mjs +8 -2
  515. package/src/session-runtime/services/agent-task-status.mjs +2 -0
  516. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
  517. package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
  518. package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
  519. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
  520. package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
  521. package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
  522. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
  523. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
  524. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
  525. package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
  526. package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
  527. package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
  528. package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
  529. package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
  530. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +82 -13
  531. package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
  532. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
  533. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
  534. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
  535. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
  536. package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
  537. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  538. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
  539. package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
  540. package/src/session-runtime/services/agent-tool/tag-registry.mjs +18 -10
  541. package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
  542. package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
  543. package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
  544. package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
  545. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  546. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
  547. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
  548. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
  549. package/src/session-runtime/services/agent-tool/worker-index.mjs +74 -15
  550. package/src/session-runtime/services/agent-tool.mjs +7 -0
  551. package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
  552. package/src/session-runtime/services/channel-admin.mjs +19 -3
  553. package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
  554. package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
  555. package/src/session-runtime/services/provider-admin.mjs +158 -15
  556. package/src/session-runtime/session-create/session-options.mjs +7 -5
  557. package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
  558. package/src/session-runtime/session-transcript-purge.mjs +32 -0
  559. package/src/session-runtime/session-transcript.mjs +4 -5
  560. package/src/session-runtime/session-turn-api.mjs +17 -14
  561. package/src/session-runtime/settings-builtin-tools-api.mjs +18 -6
  562. package/src/session-runtime/setup-tool/executor.mjs +57 -9
  563. package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
  564. package/src/session-runtime/setup-tool/settings-contract.mjs +18 -3
  565. package/src/session-runtime/setup-tool/tool-defs.mjs +25 -4
  566. package/src/session-runtime/skills-api.mjs +3 -5
  567. package/src/session-runtime/tool-policy-refresh.mjs +83 -32
  568. package/src/session-runtime/tool-surface.mjs +5 -1
  569. package/src/session-runtime/turn/agent-ops.mjs +49 -2
  570. package/src/session-runtime/turn/compaction-gate.mjs +25 -0
  571. package/src/session-runtime/turn/session-ops.mjs +7 -5
  572. package/src/session-runtime/turn/side-question-ops.mjs +19 -0
  573. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +7 -1
  574. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +12 -3
  575. package/src/session-runtime/turn/turn-run/turn-settle.mjs +18 -2
  576. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  577. package/src/session-runtime/turn/turn-run.mjs +26 -45
  578. package/src/session-runtime/usage-stats-api.mjs +46 -11
  579. package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
  580. package/src/session-runtime/workspace/admission-gate.mjs +44 -15
  581. package/src/session-runtime/workspace/project-branches.mjs +35 -41
  582. package/src/session-runtime/workspace/transition-steps.mjs +215 -116
  583. package/src/session-runtime/workspace/transitions.mjs +428 -73
  584. package/src/standalone/channel-transport.mjs +3 -4
  585. package/src/standalone/daemon-agent-control.mjs +9 -1
  586. package/src/standalone/daemon-desktop-runtime.mjs +32 -1
  587. package/src/standalone/daemon-local-session-bridge.mjs +14 -1
  588. package/src/standalone/daemon-owner.mjs +17 -4
  589. package/src/standalone/daemon-pg-stop.mjs +49 -0
  590. package/src/standalone/daemon-session-control.mjs +88 -0
  591. package/src/standalone/daemon-stop-budget.d.mts +2 -0
  592. package/src/standalone/daemon-stop-budget.mjs +18 -0
  593. package/src/standalone/daemon-stored-session-views.mjs +25 -3
  594. package/src/standalone/daemon-telemetry.mjs +19 -0
  595. package/src/standalone/daemon.mjs +63 -1
  596. package/src/standalone/desktop-service-registry.mjs +5 -0
  597. package/src/standalone/local-session-runtime.mjs +80 -30
  598. package/src/standalone/session-client.mjs +42 -0
  599. package/src/standalone/session-protocol.mjs +14 -0
  600. package/src/standalone/session-proxy/projection.mjs +41 -4
  601. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
  602. package/src/standalone/session-runtime-inline-host.mjs +3 -0
  603. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
  604. package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
  605. package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
  606. package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
  607. package/src/standalone/session-service/agent-tree.mjs +28 -2
  608. package/src/standalone/session-service/entries/session-loads.mjs +16 -5
  609. package/src/standalone/session-service/entries.mjs +1 -0
  610. package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
  611. package/src/standalone/session-service/quota-resume.mjs +28 -13
  612. package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
  613. package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
  614. package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
  615. package/src/standalone/session-service-api.mjs +6 -1
  616. package/src/standalone/session-state-patch.d.mts +2 -1
  617. package/src/standalone/session-state-patch.mjs +41 -1
  618. package/src/standalone/session-tool-output.mjs +82 -0
  619. package/src/tui/App.jsx +25 -0
  620. package/src/tui/app/app-view/floating-panel.jsx +26 -1
  621. package/src/tui/app/app-view.jsx +2 -1
  622. package/src/tui/app/btw-controller.mjs +118 -0
  623. package/src/tui/app/create-app-pickers.mjs +2 -0
  624. package/src/tui/app/provider-setup/provider-items.mjs +8 -0
  625. package/src/tui/app/provider-setup-picker.mjs +15 -3
  626. package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
  627. package/src/tui/app/shell-layout/surfaces.mjs +3 -1
  628. package/src/tui/app/slash-commands.mjs +19 -3
  629. package/src/tui/app/slash-dispatch/session-commands.mjs +68 -6
  630. package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
  631. package/src/tui/app/use-global-key-input.mjs +5 -12
  632. package/src/tui/app/use-prompt-handlers.mjs +11 -0
  633. package/src/tui/components/BtwPanel.jsx +53 -0
  634. package/src/tui/components/QuestionPanel.jsx +275 -0
  635. package/src/tui/components/Spinner.jsx +4 -0
  636. package/src/tui/components/SpinnerByline.jsx +21 -2
  637. package/src/tui/components/question-panel-model.mjs +156 -0
  638. package/src/tui/components/status-line/local-line.mjs +10 -2
  639. package/src/tui/dist/index.mjs +2897 -1722
  640. package/src/tui/session/active-tool-summary.mjs +1 -1
  641. package/src/tui/session/context-state.mjs +4 -5
  642. package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
  643. package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
  644. package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
  645. package/src/tui/session/quota-resume.mjs +140 -61
  646. package/src/tui/session/session-api/commands.mjs +14 -10
  647. package/src/tui/session/session-api/controls.mjs +14 -2
  648. package/src/tui/session/session-api/integrations.mjs +9 -2
  649. package/src/tui/session/session-api/lifecycle/dispose.mjs +3 -9
  650. package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
  651. package/src/tui/session/session-api/lifecycle.mjs +14 -11
  652. package/src/tui/session/session-api/media.mjs +2 -0
  653. package/src/tui/session/session-api/routes.mjs +81 -57
  654. package/src/tui/session/session-api/settings.mjs +9 -3
  655. package/src/tui/session/session-api/worktree.mjs +3 -2
  656. package/src/tui/session/session-api.mjs +1 -0
  657. package/src/tui/session/session-flow/auto-clear.mjs +1 -3
  658. package/src/tui/session/session-flow/drain.mjs +6 -4
  659. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
  660. package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
  661. package/src/tui/session/session-flow/queue.mjs +1 -1
  662. package/src/tui/session/tool-approval.mjs +20 -8
  663. package/src/tui/session/transcript-spill.mjs +14 -7
  664. package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
  665. package/src/tui/session/tui-steering-persist.mjs +3 -5
  666. package/src/tui/session/turn-quiet.mjs +53 -0
  667. package/src/tui/session/turn-stream.mjs +179 -32
  668. package/src/tui/session/turn.mjs +50 -36
  669. package/src/tui/session/worktree-setup-notice.mjs +38 -0
  670. package/src/tui/spinner-meta.mjs +10 -0
  671. package/src/tui/spinner-verbs.mjs +3 -0
  672. package/src/ui/statusline.mjs +13 -3
  673. package/src/workflows/default/WORKFLOW.md +3 -1
  674. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
  675. package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
  676. package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
  677. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -246
  678. package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
  679. package/src/session-runtime/turn/share-ops.mjs +0 -77
  680. package/src/tui/session/cross-surface-share.mjs +0 -406
  681. package/src/tui/session/live-share/delta.mjs +0 -153
  682. package/src/tui/session/live-share/mirror.mjs +0 -106
  683. package/src/tui/session/live-share/owner.mjs +0 -254
  684. package/src/tui/session/live-share/retry.mjs +0 -54
  685. package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
  686. package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
  687. package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
  688. package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
  689. package/src/tui/session/live-share/viewer.mjs +0 -99
  690. package/src/tui/session/live-share/wire.mjs +0 -44
  691. package/src/tui/session/live-share.mjs +0 -154
  692. package/src/tui/session/shared-dir-watch.mjs +0 -69
@@ -3,6 +3,10 @@
3
3
  - Commit, push, release, deployment and any irreversible action only on the
4
4
  user's explicit request. Validate exact targets first: never roots, `~` or
5
5
  unresolved variables/globs.
6
+ - Never stash, reset, checkout, restore or clean the working tree, or delete
7
+ files you did not create: it may hold other agents' or the user's
8
+ uncommitted work. Use a separate worktree or copy for before/after
9
+ comparisons.
6
10
  - Back up only when changes risk irreversible loss, not for routine code edits;
7
11
  keep backups unless the user requests removal. Report what is recoverable.
8
12
  - Temp workspaces come from a unique-directory allocator, never by clearing
@@ -30,6 +30,7 @@ function maintenanceRouteToPreset(routeOrName, agent) {
30
30
  type: 'agent',
31
31
  provider,
32
32
  model,
33
+ ...(routeOrName.fallbacks?.length ? { fallbacks: routeOrName.fallbacks } : {}),
33
34
  tools: 'full',
34
35
  };
35
36
  const effort = String(routeOrName.effort || '').trim();
@@ -11,6 +11,7 @@ import { appendAgentTrace } from '../agent-trace-io.mjs';
11
11
  import { getHiddenAgent } from '../internal-agents.mjs';
12
12
  import { envNonNegativeInt, envPresent } from '../../../shared/env.mjs';
13
13
  import {
14
+ PROVIDER_FIRST_BYTE_TIMEOUT_MS,
14
15
  PROVIDER_SEMANTIC_IDLE_TIMEOUT_MS,
15
16
  PROVIDER_WS_SEMANTIC_IDLE_TIMEOUT_MS,
16
17
  STALL_TICK_MS,
@@ -45,7 +46,7 @@ export class AgentStallAbortError extends Error {
45
46
  }
46
47
  }
47
48
 
48
- function isAgentProgressWatchdogAbortError(err) {
49
+ export function isAgentProgressWatchdogAbortError(err) {
49
50
  const msg = err?.message;
50
51
  return typeof msg === 'string' && WATCHDOG_ABORT_RE.test(msg);
51
52
  }
@@ -203,14 +204,34 @@ function resolveExplicitMs(value, fallback) {
203
204
  return fallback;
204
205
  }
205
206
 
207
+ // One deadline floored one watchdog tick above the provider's own budget for
208
+ // that phase (none when the provider names none); 0 stays disabled.
209
+ function aboveProviderBudget(requestedMs, providerBudgetMs) {
210
+ if (!(requestedMs > 0) || !(providerBudgetMs > 0)) return requestedMs;
211
+ return Math.max(requestedMs, providerBudgetMs + STALL_TICK_MS);
212
+ }
213
+
214
+ // `providerFirstByteTimeoutMs` is how long the session's provider itself may
215
+ // wait for response headers, and `providerFirstOutputTimeoutMs` for its first
216
+ // output (headers plus first chunk), its own retries included
217
+ // (providerFirstResponseBudget). Provider retries keep the request clock
218
+ // running, so each first-response deadline sits one watchdog tick above that
219
+ // budget: the provider's timeout and retry decide first, and a provider that
220
+ // gives up is reported as the provider's failure.
206
221
  export function resolveAgentWatchdogPolicy(agent, overrides = {}) {
207
- const firstTransportMs = resolveExplicitMs(
208
- overrides.firstTransportTimeoutMs ?? overrides.firstResponseTimeoutMs,
209
- DEFAULT_FIRST_RESPONSE_TIMEOUT_MS
222
+ const firstTransportMs = aboveProviderBudget(
223
+ resolveExplicitMs(
224
+ overrides.firstTransportTimeoutMs ?? overrides.firstResponseTimeoutMs,
225
+ DEFAULT_FIRST_RESPONSE_TIMEOUT_MS
226
+ ),
227
+ resolveExplicitMs(overrides.providerFirstByteTimeoutMs, PROVIDER_FIRST_BYTE_TIMEOUT_MS)
210
228
  );
211
- const firstSemanticMs = resolveExplicitMs(
212
- overrides.firstSemanticTimeoutMs ?? overrides.firstVisibleTimeoutMs,
213
- DEFAULT_FIRST_VISIBLE_CEILING_MS
229
+ const firstSemanticMs = aboveProviderBudget(
230
+ resolveExplicitMs(
231
+ overrides.firstSemanticTimeoutMs ?? overrides.firstVisibleTimeoutMs,
232
+ DEFAULT_FIRST_VISIBLE_CEILING_MS
233
+ ),
234
+ resolveExplicitMs(overrides.providerFirstOutputTimeoutMs, 0)
214
235
  );
215
236
 
216
237
  let idleStaleMs;
@@ -493,19 +493,10 @@ export function buildProviderCacheOpts(provider, _sessionId, agent, options = {}
493
493
  const ttls = resolveCacheStrategy(agent, options);
494
494
  const capability = cacheCapabilityForProvider(provider);
495
495
  if (capability === 'explicit-breakpoint') {
496
- // 2026-03-06 Anthropic dropped default TTL 1h→5m. We send
497
- // extended-cache-ttl-2025-04-11 header to retain 1h.
496
+ // 2026-03-06 Anthropic dropped default TTL 1h→5m. We request 1h via
497
+ // cache_control ttl:"1h"; no beta header is required.
498
498
  // Verified 2026-04-17 (ephemeral_1h_input_tokens=4722).
499
499
  return { cacheStrategy: ttls, ...oneShotPromptCacheOpts(agent) };
500
500
  }
501
- // NOTE: createSession's direct-call site (manager.mjs) only invokes this
502
- // for explicit-breakpoint (Anthropic-family) providers, so this branch
503
- // stays reachable only from other callers (none in-tree today) — keeping
504
- // it here preserves the documented public API/behavior of this function.
505
- if (provider === 'openai') {
506
- // Public OpenAI API: prompt_cache_retention extends prefix retention.
507
- // openai-oauth rejects the header — falls through to default.
508
- return { cacheRetention: '24h' };
509
- }
510
501
  return {};
511
502
  }
@@ -21,7 +21,8 @@ let _serviceUrl = null;
21
21
  // came from legacy active-instance.json). Lets a flush connect-failure distrust
22
22
  // a recycled-pid corpse advert so the next resolve falls back to legacy/buffer.
23
23
  let _serviceAdvertPort = null;
24
- let _flushInFlight = false;
24
+ let _flushPromise = null;
25
+ let _flushImmediate = null;
25
26
  let _localTracePath = null;
26
27
  let _localTraceIsExplicit = false;
27
28
  let _localTraceBuffer = [];
@@ -180,6 +181,8 @@ function _flushLocalTrace() {
180
181
  _localTraceFlushInFlight = false;
181
182
  _localTraceFlushPromise = null;
182
183
  if (_localTraceBuffer.length > 0) {
184
+ // An append during the write may already have armed a timer.
185
+ if (_localTraceTimer) clearTimeout(_localTraceTimer);
183
186
  _localTraceTimer = setTimeout(_flushLocalTrace, 0);
184
187
  _localTraceTimer.unref?.();
185
188
  }
@@ -220,11 +223,13 @@ try {
220
223
  // Ignore lifecycle hook failures in embedded runtimes.
221
224
  }
222
225
 
226
+ const _deps = { readServicePort };
227
+
223
228
  function _resolveServiceUrl() {
224
229
  if (_serviceUrl) return _serviceUrl;
225
230
  try {
226
231
  // Standalone memory HTTP uses its pid-validated discovery advert.
227
- const advertPort = readServicePort('memory', { requirePid: false });
232
+ const advertPort = _deps.readServicePort('memory', { requirePid: false });
228
233
  if (advertPort) {
229
234
  _serviceAdvertPort = advertPort;
230
235
  _serviceUrl = `http://127.0.0.1:${advertPort}`;
@@ -237,71 +242,78 @@ function _resolveServiceUrl() {
237
242
  }
238
243
  }
239
244
 
240
- async function _flush() {
241
- _flushTimer = null;
242
- if (_buffer.length === 0) return;
243
- if (_flushInFlight) {
244
- _scheduleFlush();
245
- return;
245
+ // Single entry point for every flush trigger (timer, immediate, drain). While a
246
+ // flush is in flight, callers share its promise; its completion schedules the
247
+ // continuation for whatever remains.
248
+ function _flush() {
249
+ if (_flushTimer) {
250
+ clearTimeout(_flushTimer);
251
+ _flushTimer = null;
252
+ }
253
+ // This flush takes over any queued immediate; its completion reschedules.
254
+ if (_flushImmediate) {
255
+ clearImmediate(_flushImmediate);
256
+ _flushImmediate = null;
246
257
  }
247
- _flushInFlight = true;
258
+ if (_flushPromise) return _flushPromise;
259
+ if (_buffer.length === 0) return Promise.resolve();
260
+ _flushPromise = _flushOnce().finally(() => {
261
+ _flushPromise = null;
262
+ _scheduleContinuation();
263
+ });
264
+ return _flushPromise;
265
+ }
266
+
267
+ async function _flushOnce() {
268
+ // Discovery runs here only (timer / drain / full-batch continuation), never per append.
269
+ const url = _resolveServiceUrl();
270
+ if (!url) return;
271
+ const batch = _buffer.splice(0, _FLUSH_BATCH_SIZE);
248
272
  try {
249
- const url = _resolveServiceUrl();
250
- if (!url) {
251
- // Service not up yet — keep buffer, retry next timer tick
252
- _scheduleFlush();
253
- return;
254
- }
255
- const batch = _buffer.splice(0, _FLUSH_BATCH_SIZE);
273
+ const resp = await fetch(`${url}/admin/trace-record`, {
274
+ method: 'POST',
275
+ headers: { 'Content-Type': 'application/json' },
276
+ body: JSON.stringify({ events: batch }),
277
+ signal: AbortSignal.timeout(5000),
278
+ });
279
+ // Always drain the body. An undrained response body keeps the
280
+ // underlying keep-alive socket referenced, which can hold the event
281
+ // loop open and make a short-lived process (smoke scripts / one-shot
282
+ // agent tasks) appear to hang for seconds after its work is done.
256
283
  try {
257
- const resp = await fetch(`${url}/admin/trace-record`, {
258
- method: 'POST',
259
- headers: { 'Content-Type': 'application/json' },
260
- body: JSON.stringify({ events: batch }),
261
- signal: AbortSignal.timeout(5000),
262
- });
263
- // Always drain the body. An undrained response body keeps the
264
- // underlying keep-alive socket referenced, which can hold the event
265
- // loop open and make a short-lived process (smoke scripts / one-shot
266
- // agent tasks) appear to hang for seconds after its work is done.
267
- try {
268
- await resp.arrayBuffer();
269
- } catch {
270
- /* body already gone */
271
- }
272
- if (!resp.ok) {
273
- warnAgentOnce(
274
- 'agent-trace:flush-error',
275
- `[agent-trace] /admin/trace-record returned ${resp.status} — dropping batch`
276
- );
277
- }
278
- } catch (err) {
279
- _serviceUrl = null;
280
- // Discovery-first consumer with no health probe: a connect failure
281
- // means the pid-validated advert points at a dead (recycled-pid)
282
- // port. Distrust it (connection-level errors ONLY — a timeout is a
283
- // slow-but-alive daemon, not a corpse) so the next resolve falls back
284
- // to legacy/buffer instead of re-trusting the same advert.
285
- if (_serviceAdvertPort && isConnRefuseError(err)) markServiceUnreachable('memory', _serviceAdvertPort);
286
- _serviceAdvertPort = null;
287
- warnAgentOnce('agent-trace:flush-fetch', `[agent-trace] flush fetch failed (${err?.message}) — dropping batch`);
284
+ await resp.arrayBuffer();
285
+ } catch {
286
+ /* body already gone */
288
287
  }
289
- if (_buffer.length >= _FLUSH_BATCH_SIZE) {
290
- // More pending — schedule another flush immediately
291
- setImmediate(_flush);
288
+ if (!resp.ok) {
289
+ warnAgentOnce(
290
+ 'agent-trace:flush-error',
291
+ `[agent-trace] /admin/trace-record returned ${resp.status} — dropping batch`
292
+ );
292
293
  }
293
- } finally {
294
- _flushInFlight = false;
294
+ } catch (err) {
295
+ _serviceUrl = null;
296
+ // Discovery-first consumer with no health probe: a connect failure
297
+ // means the pid-validated advert points at a dead (recycled-pid)
298
+ // port. Distrust it (connection-level errors ONLY — a timeout is a
299
+ // slow-but-alive daemon, not a corpse) so the next resolve falls back
300
+ // to legacy/buffer instead of re-trusting the same advert.
301
+ if (_serviceAdvertPort && isConnRefuseError(err)) markServiceUnreachable('memory', _serviceAdvertPort);
302
+ _serviceAdvertPort = null;
303
+ warnAgentOnce('agent-trace:flush-fetch', `[agent-trace] flush fetch failed (${err?.message}) — dropping batch`);
295
304
  }
296
305
  }
297
306
 
298
- function _scheduleFlush(immediate = false) {
299
- if (immediate) {
307
+ // Full batch pending and the service is usable → one immediate; everything else
308
+ // → the single non-resetting retry timer.
309
+ function _scheduleContinuation() {
310
+ if (_buffer.length === 0) return;
311
+ if (_serviceUrl && _buffer.length >= _FLUSH_BATCH_SIZE) {
300
312
  if (_flushTimer) {
301
313
  clearTimeout(_flushTimer);
302
314
  _flushTimer = null;
303
315
  }
304
- setImmediate(_flush);
316
+ if (!_flushImmediate) _flushImmediate = setImmediate(_flush);
305
317
  } else if (!_flushTimer) {
306
318
  _flushTimer = setTimeout(_flush, _FLUSH_INTERVAL_MS);
307
319
  // Never let the periodic trace flush keep the event loop alive: a
@@ -328,11 +340,10 @@ async function _drainLocalTrace() {
328
340
  async function drainAgentTrace() {
329
341
  await _drainLocalTrace();
330
342
  if (!_resolveServiceUrl()) return;
331
- if (_flushTimer) {
332
- clearTimeout(_flushTimer);
333
- _flushTimer = null;
334
- }
335
- for (let i = 0; i < 10 && _buffer.length > 0; i++) {
343
+ // Each iteration either awaits the in-flight flush or delivers a batch, so
344
+ // this terminates; it stops early only when the service is unresolvable.
345
+ while (_buffer.length > 0 || _flushPromise) {
346
+ if (!_flushPromise && !_resolveServiceUrl()) break;
336
347
  await _flush();
337
348
  }
338
349
  }
@@ -363,7 +374,8 @@ function appendAgentTrace(record = {}) {
363
374
  }
364
375
  _appendLocalTrace(row);
365
376
  _buffer.push(row);
366
- _scheduleFlush(_buffer.length >= _FLUSH_BATCH_SIZE);
377
+ // An in-flight flush schedules its own continuation on completion.
378
+ if (!_flushPromise) _scheduleContinuation();
367
379
  } catch {
368
380
  // Never break agent execution for telemetry
369
381
  }
@@ -464,7 +476,26 @@ function _flushToolFailuresSync() {
464
476
  }
465
477
  }
466
478
 
479
+ // Test-only seams: inject discovery and reset module state between cases.
480
+ const _traceIoTest = {
481
+ setReadServicePort(fn) {
482
+ _deps.readServicePort = fn;
483
+ },
484
+ // Resolves once the in-flight local spool write and its completion handler have run.
485
+ localWrite: () => _localTraceFlushPromise,
486
+ reset() {
487
+ _deps.readServicePort = readServicePort;
488
+ _buffer.length = 0;
489
+ _flushTimer = null;
490
+ _flushImmediate = null;
491
+ _flushPromise = null;
492
+ _serviceUrl = null;
493
+ _serviceAdvertPort = null;
494
+ },
495
+ };
496
+
467
497
  export {
498
+ _traceIoTest,
468
499
  appendAgentTrace,
469
500
  drainAgentTrace,
470
501
  normalizeSessionId,
@@ -31,9 +31,18 @@ export function maxMtimeRecursive(paths, depth = 3) {
31
31
  * @returns {string}
32
32
  */
33
33
  export function mtimeSignatureRecursive(paths, depth = 3) {
34
+ return createHash('sha1').update(mtimeSignatureText(paths, depth)).digest('hex');
35
+ }
36
+
37
+ /**
38
+ * The raw text mtimeSignatureRecursive hashes (`path:mtime` lines). Texts of
39
+ * consecutive path groups joined with '\n' hash to the same signature as one
40
+ * call over all of them, so a caller can reuse an unchanged group's text.
41
+ */
42
+ export function mtimeSignatureText(paths, depth = 3) {
34
43
  const parts = [];
35
44
  walkMtimes(paths, depth, (p, m) => parts.push(`${p}:${m}`));
36
- return createHash('sha1').update(parts.join('\n')).digest('hex');
45
+ return parts.join('\n');
37
46
  }
38
47
 
39
48
  function walkMtimes(paths, depth, visit) {
@@ -67,6 +67,13 @@ export function mergeStoredProviders({ raw, defaults, includeSecrets, presenceOn
67
67
  if (includeSecrets) {
68
68
  for (const [name, val] of Object.entries(mergedProviders)) {
69
69
  if (val?.type !== 'custom' || !name.startsWith('custom-') || val.auth === 'none') continue;
70
+ if (val.apiKeyEnv) {
71
+ // Env mode: the named variable is the only key source (no keychain).
72
+ const { apiKey: _dropped, ...rest } = val;
73
+ const envKey = process.env[val.apiKeyEnv];
74
+ mergedProviders[name] = envKey && !presenceOnly ? { ...rest, apiKey: envKey } : rest;
75
+ continue;
76
+ }
70
77
  const kc = storedKey(name);
71
78
  if (kc) mergedProviders[name] = withKey(val, name, kc);
72
79
  }
@@ -280,6 +280,8 @@ export function loadConfig(options = {}) {
280
280
  shell: raw.shell && typeof raw.shell === 'object' ? raw.shell : {},
281
281
  update: raw.update && typeof raw.update === 'object' ? { ...raw.update } : {},
282
282
  recap: recapConfig,
283
+ // The model may title the session (session tool, action=rename); default on.
284
+ aiSessionTitles: raw.aiSessionTitles !== false,
283
285
  worktree: normalizeWorktreeSettings(raw.worktree),
284
286
  developer: normalizeDeveloperConfig(raw.developer),
285
287
  modules: canonicalizeModulesStorage(raw.modules) || {},
@@ -450,6 +452,9 @@ function buildAgentSaveBuilder(config) {
450
452
  } else Object.assign(next, disabledAgentDelta(canonicalRoutes.disabledAgents));
451
453
  if (config.memoryTools && typeof config.memoryTools === 'object') next.memoryTools = { ...config.memoryTools };
452
454
  else delete next.memoryTools;
455
+ // Default true lives in code: only the opt-out is stored.
456
+ if (config.aiSessionTitles === false) next.aiSessionTitles = false;
457
+ else delete next.aiSessionTitles;
453
458
  delete next.instructionFiles;
454
459
  Object.assign(next, storedInstructionFiles(config));
455
460
  delete next.workflowRoutes;
@@ -18,6 +18,7 @@ export {
18
18
  skillBodyPresentInSession,
19
19
  skillMissingFeature,
20
20
  skillOutsideScope,
21
+ skillEnabledFlags,
21
22
  skillOutsideScopeError,
22
23
  } from './skill-catalog.mjs';
23
24
  export {
@@ -1,5 +1,6 @@
1
1
  // Deferred-pool and MCP-instruction manifests injected into BP2.
2
2
  import { parseMcpToolName } from '../../../shared/tool-primitives.mjs';
3
+ import { isToolBridgeEnabled, TOOL_BRIDGE_GUIDANCE } from '../runtime-core/tool-exposure.mjs';
3
4
 
4
5
  export function compactPromptManifestText(value, max = 250) {
5
6
  const text = String(value || '')
@@ -13,7 +14,10 @@ export function compactPromptManifestText(value, max = 250) {
13
14
  return `${cut.replace(/[\s,.;:!?/-]+$/, '')}...`;
14
15
  }
15
16
 
16
- const DEFERRED_TOOLS_BLOCK_RE = /(\n\n---\n*)?<available-deferred-tools>[\s\S]*?<\/available-deferred-tools>\s*/gi;
17
+ // The native deferred-pool manifest and the static bridge guidance occupy the
18
+ // same BP2 slot: one replaces the other when the exposure changes.
19
+ const DEFERRED_TOOLS_BLOCK_RE =
20
+ /(\n\n---\n*)?<(available-deferred-tools|tool-bridge)>[\s\S]*?<\/(?:available-deferred-tools|tool-bridge)>\s*/gi;
17
21
  const MCP_INSTRUCTIONS_BLOCK_RE = /(\n\n---\n*)?<mcp-instructions>[\s\S]*?<\/mcp-instructions>\s*/gi;
18
22
  // Tool and MCP server names enter the manifests only as plain identifiers
19
23
  // (no markup can be smuggled into the prompt through a name).
@@ -47,6 +51,7 @@ function hasDeferredToolManifestBlock(text) {
47
51
  const raw = String(text || '');
48
52
  return (
49
53
  /<available-deferred-tools>[\s\S]*?<\/available-deferred-tools>/i.test(raw) ||
54
+ /<tool-bridge>[\s\S]*?<\/tool-bridge>/i.test(raw) ||
50
55
  /<mcp-instructions>[\s\S]*?<\/mcp-instructions>/i.test(raw)
51
56
  );
52
57
  }
@@ -173,11 +178,17 @@ function deferredManifestEntries(session, pool) {
173
178
  }
174
179
 
175
180
  function composeDeferredBp2Manifest(session, pool) {
181
+ // Bridge exposure gets the native roster and MCP instructions (the pool is
182
+ // already limited to what the session's policy lets it run), followed by
183
+ // the static bridge guidance. A tool-free bridge session gets nothing.
184
+ const bridge = isToolBridgeEnabled(session);
185
+ if (bridge && !(session.tools || []).some((tool) => tool?.name === 'call_tool')) return '';
176
186
  const parts = [];
177
187
  const deferredManifest = buildDeferredToolManifest(deferredManifestEntries(session, pool));
178
188
  if (deferredManifest) parts.push(deferredManifest);
179
189
  const mcpManifest = buildMcpInstructionsManifest(session.mcpServerInstructions, pool, session.deferredToolCatalog);
180
190
  if (mcpManifest) parts.push(mcpManifest);
191
+ if (bridge) parts.push(TOOL_BRIDGE_GUIDANCE);
181
192
  return parts.join('\n\n');
182
193
  }
183
194
 
@@ -186,12 +197,20 @@ function markDeferredBp2Applied(session) {
186
197
  delete session.deferredToolBp1Applied;
187
198
  }
188
199
 
200
+ // Replace, never mutate: session-store delta saves treat stable message
201
+ // references as an unchanged prefix, so a rewritten prompt block must be a
202
+ // fresh object for the next save to persist it.
203
+ function setSystemContent(session, index, content) {
204
+ const message = session.messages[index];
205
+ if (message.content !== content) session.messages[index] = { ...message, content };
206
+ }
207
+
189
208
  function clearDeferredManifestBlocks(session) {
190
- for (const message of session.messages) {
209
+ session.messages.forEach((message, index) => {
191
210
  if (message?.role === 'system' && typeof message.content === 'string') {
192
- message.content = stripDeferredToolManifestBlock(message.content);
211
+ setSystemContent(session, index, stripDeferredToolManifestBlock(message.content));
193
212
  }
194
- }
213
+ });
195
214
  session.messages = session.messages.filter(
196
215
  (message) => message?.role !== 'system' || String(message.content || '').trim()
197
216
  );
@@ -214,15 +233,15 @@ function writeDeferredManifestAt(session, idx, manifest, rebuild) {
214
233
  for (let i = 0; i < session.messages.length; i++) {
215
234
  if (i === idx || session.messages[i]?.role !== 'system' || typeof session.messages[i].content !== 'string')
216
235
  continue;
217
- session.messages[i].content = stripDeferredToolManifestBlock(session.messages[i].content);
236
+ setSystemContent(session, i, stripDeferredToolManifestBlock(session.messages[i].content));
218
237
  }
219
238
  const raw = typeof session.messages[idx].content === 'string' ? session.messages[idx].content : '';
220
239
  if (rebuild && hasDeferredToolManifestBlock(raw)) {
221
- session.messages[idx].content = rebuildDeferredToolManifestBlock(raw, manifest);
240
+ setSystemContent(session, idx, rebuildDeferredToolManifestBlock(raw, manifest));
222
241
  return;
223
242
  }
224
243
  const base = stripDeferredToolManifestBlock(raw);
225
- session.messages[idx].content = base ? `${base}\n\n---\n\n${manifest}` : manifest;
244
+ setSystemContent(session, idx, base ? `${base}\n\n---\n\n${manifest}` : manifest);
226
245
  }
227
246
 
228
247
  /**
@@ -1,9 +1,10 @@
1
1
  // Skill discovery, cache, resource loading, envelopes, manifests, and the
2
2
  // Skill meta-tool.
3
3
 
4
- import { readFileSync, existsSync, readdirSync } from 'node:fs';
4
+ import { createHash } from 'node:crypto';
5
+ import { readFileSync, existsSync, readdirSync, statSync, watch as watch_ } from 'node:fs';
5
6
  import { basename, dirname, join } from 'node:path';
6
- import { maxMtimeRecursive, mtimeSignatureRecursive } from '../cache-mtime.mjs';
7
+ import { maxMtimeRecursive, mtimeSignatureRecursive, mtimeSignatureText } from '../cache-mtime.mjs';
7
8
  import { mixdogHome, resolvePluginData, mixdogRoot } from '../../../shared/plugin-paths.mjs';
8
9
  import { PLUGIN_MANIFEST_FILES, pluginSkillsRoots } from '../../../shared/plugin-manifest.mjs';
9
10
  import {
@@ -257,6 +258,31 @@ export function isSkillDisabled(name, config = null, skills = null) {
257
258
  return Boolean(skill && missingFeature(skill, featureConfig(config)));
258
259
  }
259
260
 
261
+ /**
262
+ * `enabled` for every skill of one collectSkillsCached() snapshot, exactly as
263
+ * `!(isSkillDisabled(name, config, skills) || skillMissingFeature(name, config,
264
+ * skills))` per skill — but with ONE config read, one disabled-name set and one
265
+ * name index for the whole list instead of three config reads and a linear
266
+ * lookup per skill (the status listing blocked the event loop on them).
267
+ */
268
+ export function skillEnabledFlags(skills, config = null) {
269
+ const list = Array.isArray(skills) ? skills : [];
270
+ const cfg = config || loadConfig({ secrets: false });
271
+ const disabled = getDisabledSkillNameSet(cfg);
272
+ const features = featureConfig(cfg);
273
+ const byKey = new Map();
274
+ for (const entry of list) {
275
+ const key = normalizeSkillNameKey(entry.name);
276
+ if (!byKey.has(key)) byKey.set(key, entry);
277
+ }
278
+ return list.map((entry) => {
279
+ const key = normalizeSkillNameKey(entry.name);
280
+ const skill = byKey.get(key);
281
+ if (key && !followsBuiltinFeature(skill) && disabled.has(key)) return false;
282
+ return !(skill && missingFeature(skill, features));
283
+ });
284
+ }
285
+
260
286
  /** The built-in feature a skill needs that is not active, or null. */
261
287
  export function skillMissingFeature(name, config = null, skills = null) {
262
288
  const skill = findCachedSkillByKey(normalizeSkillNameKey(name), skills);
@@ -303,6 +329,81 @@ export function collectPromptSkillsCached(cwd, config = null) {
303
329
  // --- Global skill cache (mtime-based) ---
304
330
  const _skillsCache = new Map();
305
331
 
332
+ // Change watchers over the recursive skill roots. Re-walking every skill
333
+ // folder (one stat per entry) on every status/prompt read blocked the event
334
+ // loop for tens to hundreds of ms with a large skill set. A root whose
335
+ // recursive watcher has reported nothing since its last walk reuses that
336
+ // walk's signature text instead; any event, watcher error or explicit
337
+ // invalidation re-walks it. A watched root is trusted only once an event-loop
338
+ // turn has passed since its walk.
339
+ // Freshness contract: every write made through the app (addSkill, saveSkill,
340
+ // setDisabledSkills, reloadSkills, settings/plugin mutations, peer-runtime
341
+ // announcements) calls invalidateSkillsCache synchronously, which drops every
342
+ // watch, so the very next read re-walks and is exact. A passive edit made
343
+ // outside the app is eventually consistent: it is seen once the watcher
344
+ // delivers its event (watcher latency), or at the next explicit invalidation.
345
+ // Roots that cannot be watched (missing, or unsupported by the platform) and
346
+ // every plain-file gate path are stat'ed on every call as before.
347
+ const _ROOT_WATCH_LIMIT = 64;
348
+ const _rootWatches = new Map(); // root -> { watcher, dirty, text, settled }
349
+
350
+ function _closeRootWatch(root) {
351
+ const watch = _rootWatches.get(root);
352
+ if (!watch) return;
353
+ _rootWatches.delete(root);
354
+ try {
355
+ watch.watcher.close();
356
+ } catch {
357
+ /* already closed */
358
+ }
359
+ }
360
+
361
+ function _closeAllRootWatches() {
362
+ for (const root of [..._rootWatches.keys()]) _closeRootWatch(root);
363
+ }
364
+
365
+ function _openRootWatch(root) {
366
+ let isDir = false;
367
+ try {
368
+ isDir = statSync(root).isDirectory();
369
+ } catch {
370
+ return null;
371
+ }
372
+ if (!isDir) return null;
373
+ if (_rootWatches.size >= _ROOT_WATCH_LIMIT) _closeAllRootWatches();
374
+ const watch = { watcher: null, dirty: true, text: null, settled: false };
375
+ try {
376
+ // A change anywhere below drops the root's reused walk; the watcher is
377
+ // closed with it (a re-walk re-opens one), so a churning folder never
378
+ // keeps a handle on directories being deleted.
379
+ watch.watcher = watch_(root, { recursive: true, persistent: false }, () => _closeRootWatch(root));
380
+ watch.watcher.on('error', () => _closeRootWatch(root));
381
+ } catch {
382
+ return null;
383
+ }
384
+ _rootWatches.set(root, watch);
385
+ return watch;
386
+ }
387
+
388
+ /** Signature text of one recursive gate root (see mtimeSignatureText). */
389
+ function _rootSignatureText(root) {
390
+ const current = _rootWatches.get(root);
391
+ if (current && !current.dirty && current.settled) return current.text;
392
+ // Open the watcher BEFORE the walk: a change racing the walk then either
393
+ // shows in it or arrives as an event that drops the reused text.
394
+ const watch = current || _openRootWatch(root);
395
+ const text = mtimeSignatureText([root]);
396
+ if (watch && _rootWatches.get(root) === watch) {
397
+ watch.text = text;
398
+ watch.dirty = false;
399
+ watch.settled = false;
400
+ setImmediate(() => {
401
+ if (_rootWatches.get(root) === watch && watch.text === text) watch.settled = true;
402
+ }).unref?.();
403
+ }
404
+ return text;
405
+ }
406
+
306
407
  export function collectSkillsCached(cwd) {
307
408
  if (skillsDisabled()) return [];
308
409
  void cwd;
@@ -313,12 +414,15 @@ export function collectSkillsCached(cwd) {
313
414
  skillsDirs.push(...pluginSkillDirs().map(({ dir }) => dir), ...builtinSkillDirs());
314
415
  // registry.json itself gates plugin add/remove: removal deletes the
315
416
  // plugin's skills dir (so no dir mtime advances), but saveRegistry()
316
- // always rewrites this file. mtimeSignatureRecursive stats plain files directly.
417
+ // always rewrites this file. It is a plain file: stat'ed directly.
317
418
  const registryPath = pluginRegistryPath();
318
- if (registryPath) skillsDirs.push(registryPath);
319
- // Exact, un-timed gate: stat every call. The shallow watch list covers
320
- // manifest edits and skill roots that do not exist yet.
321
- const signature = `${mtimeSignatureRecursive(skillsDirs)}|${mtimeSignatureRecursive(pluginShallowWatchPaths(), 0)}`;
419
+ // Exact gate: unwatched roots and plain files are stat'ed every call; a
420
+ // watched root reuses its last walk only while its watcher stayed quiet.
421
+ // The shallow watch list covers manifest edits and skill roots that do not
422
+ // exist yet.
423
+ const rootTexts = skillsDirs.map((dir) => _rootSignatureText(dir));
424
+ if (registryPath) rootTexts.push(mtimeSignatureText([registryPath]));
425
+ const signature = `${createHash('sha1').update(rootTexts.join('\n')).digest('hex')}|${mtimeSignatureRecursive(pluginShallowWatchPaths(), 0)}`;
322
426
  const entry = _skillsCache.get(key);
323
427
  if (entry && entry.signature === signature) {
324
428
  return entry.value;
@@ -331,6 +435,7 @@ export function collectSkillsCached(cwd) {
331
435
  export function invalidateSkillsCache(cwd) {
332
436
  void cwd;
333
437
  _skillsCache.clear();
438
+ _closeAllRootWatches();
334
439
  }
335
440
 
336
441
  /**