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
@@ -130,7 +130,7 @@ function saveCredentials(tokens) {
130
130
 
131
131
  export function hasCursorOAuthCredentials() {
132
132
  const tokens = loadStoredCredentials();
133
- if (!tokens?.access_token) return false;
133
+ if (!tokens?.access_token || tokens.reauth_required === true) return false;
134
134
  const expiresAt = Number(tokens.expires_at) || 0;
135
135
  return expiresAt === 0 || expiresAt > Date.now() || Boolean(tokens.refresh_token);
136
136
  }
@@ -147,6 +147,18 @@ export function describeCursorOAuthCredentials() {
147
147
  detail: 'Mixdog token store or CURSOR_ACCESS_TOKEN',
148
148
  };
149
149
  }
150
+ if (tokens.reauth_required === true) {
151
+ return {
152
+ authenticated: false,
153
+ usable: false,
154
+ refreshable: false,
155
+ reauthRequired: true,
156
+ status: 'Reauth Required',
157
+ detail: tokens.source || 'Cursor OAuth',
158
+ expiresAt: Number(tokens.expires_at) || null,
159
+ ...accountIdentityFields(tokens.identity),
160
+ };
161
+ }
150
162
  const expiresAt = Number(tokens.expires_at) || 0;
151
163
  const expired = expiresAt > 0 && expiresAt <= Date.now();
152
164
  const expiring = expiresAt > 0 && expiresAt <= Date.now() + REFRESH_SKEW_MS;
@@ -336,10 +348,32 @@ export async function resolveCursorOAuthAccessToken({ forceRefresh = false, fetc
336
348
  // (turn cancel / session close) kill it would fail the refresh for
337
349
  // all of them and leave the process without a usable token. Its own
338
350
  // timeout bounds the request instead.
339
- const next = await exchangeCursorToken(latest.refresh_token, {
340
- fetchFn,
341
- signal: AbortSignal.timeout(REFRESH_TIMEOUT_MS),
342
- });
351
+ let next;
352
+ try {
353
+ next = await exchangeCursorToken(latest.refresh_token, {
354
+ fetchFn,
355
+ signal: AbortSignal.timeout(REFRESH_TIMEOUT_MS),
356
+ });
357
+ } catch (error) {
358
+ if (error?.reauthRequired !== true) throw error;
359
+ // Mark the account dead only if no other process replaced the
360
+ // refresh token meanwhile. Non-destructive: tokens stay intact and
361
+ // a new sign-in rewrites the file without this marker.
362
+ if (!process.env.CURSOR_ACCESS_TOKEN || boundProviderAuthPath('cursor-oauth')) {
363
+ const current = loadStoredCredentials();
364
+ if (current?.refresh_token && current.refresh_token === latest.refresh_token) {
365
+ const { source: _source, ...persisted } = current;
366
+ try {
367
+ saveCredentials({ ...persisted, reauth_required: true });
368
+ } catch (saveError) {
369
+ process.stderr.write(
370
+ `[cursor-oauth] dead-account mark failed: ${String(saveError?.message || saveError).slice(0, 200)}\n`
371
+ );
372
+ }
373
+ }
374
+ }
375
+ throw error;
376
+ }
343
377
  if (!process.env.CURSOR_ACCESS_TOKEN || boundProviderAuthPath('cursor-oauth')) {
344
378
  saveCredentials(next);
345
379
  }
@@ -4,7 +4,7 @@ import { createRemoteVersionSource } from './npm-cli-version.mjs';
4
4
  // documented version endpoint; the official installer script embeds the
5
5
  // current build (…/lab/<build>/…), parsed best-effort. Any format change or
6
6
  // failure falls back to the floor.
7
- export const CURSOR_CLIENT_VERSION_FLOOR = 'cli-2026.10.14-0f9edde';
7
+ export const CURSOR_CLIENT_VERSION_FLOOR = 'cli-2026.10.16-e3cb207';
8
8
  const BUILD_PATTERN = /downloads\.cursor\.com\/lab\/(\d{4}\.\d{2}\.\d{2}-[0-9a-f]{6,40})\//;
9
9
  export const CURSOR_INSTALL_URL = 'https://cursor.com/install';
10
10
 
@@ -0,0 +1,48 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { isDeepStrictEqual } from 'node:util';
3
+
4
+ const PREFIX = 'cursor_native_';
5
+ const pendingCalls = new Map();
6
+ const AUTHORIZATION_MS = 10 * 60 * 1000;
7
+
8
+ export function isCursorNativeCallId(id) {
9
+ return typeof id === 'string' && id.startsWith(PREFIX);
10
+ }
11
+
12
+ // Registered before streaming the call, including when a later frame is partial.
13
+ // Model arguments never grant this capability.
14
+ export function registerCursorNativeCall(ownerSessionId, pending, executions) {
15
+ if (!ownerSessionId || !pending.native) return;
16
+ if (pending.toolName !== 'read' && pending.toolName !== 'edit') return;
17
+ if (!['readResult', 'writeResult'].includes(pending.native.resultType)) return;
18
+ const now = Date.now();
19
+ for (const [id, entry] of pendingCalls) {
20
+ if (entry.expiresAt <= now) pendingCalls.delete(id);
21
+ }
22
+ if (pendingCalls.size >= 4096) throw new Error('Cursor native execution authorization capacity exceeded');
23
+ pending.toolCallId = `${PREFIX}${randomUUID()}`;
24
+ const entry = {
25
+ ownerSessionId,
26
+ pending,
27
+ executions,
28
+ expiresAt: now + AUTHORIZATION_MS,
29
+ arguments: JSON.parse(pending.decodedArgs),
30
+ };
31
+ pendingCalls.set(pending.toolCallId, entry);
32
+ }
33
+
34
+ export function cursorNativeCall(ownerSessionId, id, name, args) {
35
+ if (!isCursorNativeCallId(id)) return null;
36
+ const entry = pendingCalls.get(id);
37
+ if (!entry) throw new Error('Cursor native execution authorization is missing');
38
+ if (entry.expiresAt <= Date.now()) throw new Error('Cursor native execution authorization expired');
39
+ if (entry.ownerSessionId !== ownerSessionId) throw new Error('Cursor native execution authorization owner mismatch');
40
+ if (entry.pending.toolName !== name) throw new Error('Cursor native execution authorization tool mismatch');
41
+ if (!isDeepStrictEqual(entry.arguments, args))
42
+ throw new Error('Cursor native execution authorization argument mismatch');
43
+ return entry;
44
+ }
45
+
46
+ export function releaseCursorNativeCall(pending) {
47
+ pendingCalls.delete(pending.toolCallId);
48
+ }
@@ -1,11 +1,28 @@
1
1
  // Cursor exec/kv message handling: routing native exec requests to local
2
2
  // tools and sending results back on the bridge.
3
3
  import crypto from 'node:crypto';
4
+ import { BRIDGE_NAME_MAX_CHARS, isBridgeMetaTool } from '../runtime-core/tool-bridge-contract.mjs';
5
+ import { releaseCursorNativeCall } from './cursor-native-context.mjs';
4
6
  import { decodeJsonValue, encodeMessage } from './cursor-wire-protobuf.mjs';
5
7
  import { capCursorToolResult, storeCursorBlob } from './cursor-wire-guards.mjs';
6
8
  import { buildCursorExecThrow } from './cursor-wire-interactions.mjs';
7
9
  import { connectFrame, textDecoder, textEncoder } from './cursor-wire-transport.mjs';
8
10
  import { buildRequestContext } from './cursor-wire-request.mjs';
11
+ import { readSourceWindow } from '../../../shared/read-row-numbers.mjs';
12
+ import { splitGrepLineNumberOnlyPrefix, splitGrepCountPrefix } from '../tools/builtin/grep-formatting.mjs';
13
+
14
+ const nativeWriteDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
15
+
16
+ function nativeWriteText(args) {
17
+ if (!args.fileBytes?.length) return args.fileText || '';
18
+ try {
19
+ return nativeWriteDecoder.decode(args.fileBytes);
20
+ } catch {
21
+ throw Object.assign(new Error('Native Write fileBytes must be valid UTF-8; no file was written'), {
22
+ code: 'CURSOR_WRITE_ENCODING',
23
+ });
24
+ }
25
+ }
9
26
 
10
27
  export function heartbeatFrame() {
11
28
  return connectFrame(encodeMessage('AgentClientMessage', { clientHeartbeat: {} }));
@@ -70,12 +87,15 @@ const NATIVE_EXEC_CASES = [
70
87
  ],
71
88
  [
72
89
  'writeArgs',
73
- ['write'],
90
+ // Only the guarded edit tool: it creates missing files and fills empty
91
+ // ones, while its executor rejects overwrites of non-empty files. An
92
+ // explicit write tool would overwrite without any native capability
93
+ // (remote/proxied calls), so it never serves a native Write.
94
+ ['edit'],
74
95
  (tool, args) => ({
75
96
  [argumentName(tool, ['file_path', 'filePath', 'path'], 'file_path')]: args.path || '',
76
- [argumentName(tool, ['content', 'file_text', 'text'], 'content')]: args.fileBytes?.length
77
- ? textDecoder.decode(args.fileBytes)
78
- : args.fileText || '',
97
+ old_string: '',
98
+ new_string: nativeWriteText(args),
79
99
  }),
80
100
  'writeResult',
81
101
  ],
@@ -90,7 +110,9 @@ const NATIVE_EXEC_CASES = [
90
110
  pattern: args.pattern || '.',
91
111
  ...(args.path ? { path: args.path } : {}),
92
112
  ...(args.glob ? { glob: args.glob } : {}),
93
- mode: args.outputMode || 'content',
113
+ mode: args.outputMode === 'files_with_matches' ? 'files' : args.outputMode || 'content',
114
+ context: 0,
115
+ ...(args.headLimit > 0 ? { limit: args.headLimit } : {}),
94
116
  }),
95
117
  'grepResult',
96
118
  ],
@@ -130,6 +152,16 @@ const rejectedPath = (args) => ({ rejected: { path: args.path || '', reason: UNA
130
152
  const rejectedShell = (args) => ({
131
153
  rejected: { command: args.command || '', workingDirectory: args.workingDirectory || '', reason: UNAVAILABLE },
132
154
  });
155
+ const rejectedBackgroundShell = (args) => ({
156
+ rejected: {
157
+ command: args.command || '',
158
+ workingDirectory: args.workingDirectory || '',
159
+ reason:
160
+ 'Cursor background shell is not supported. Use the mixdog MCP shell tool with {"command":"..."}; ' +
161
+ 'if it returns task_id, use the mixdog task tool with {"action":"wait","task_id":"<returned id>"}. ' +
162
+ 'Use load_tool {"names":"task"} if task is not loaded.',
163
+ },
164
+ });
133
165
  const unavailableError = () => ({ error: { error: UNAVAILABLE } });
134
166
 
135
167
  // Native exec cases with no Mixdog tool behind them: [exec key, exec result
@@ -143,7 +175,7 @@ const UNAVAILABLE_EXEC_RESULTS = [
143
175
  ['fetchArgs', 'fetchResult', (args) => ({ error: { url: args.url || '', error: UNAVAILABLE } })],
144
176
  ['shellArgs', 'shellResult', rejectedShell],
145
177
  ['shellStreamArgs', 'shellResult', rejectedShell],
146
- ['backgroundShellSpawnArgs', 'backgroundShellSpawnResult', rejectedShell],
178
+ ['backgroundShellSpawnArgs', 'backgroundShellSpawnResult', rejectedBackgroundShell],
147
179
  ['writeShellStdinArgs', 'writeShellStdinResult', unavailableError],
148
180
  ['diagnosticsArgs', 'diagnosticsResult', () => ({})],
149
181
  ];
@@ -163,18 +195,44 @@ function rejectUnavailableExec(bridge, exec) {
163
195
  function handleMcpExec(bridge, exec, tools, onToolCall) {
164
196
  const args = exec.mcpArgs;
165
197
  const requestedName = args.toolName || args.name;
166
- const tool = toolByNames(tools, [requestedName]);
198
+ const directTool = toolByNames(tools, [requestedName]);
199
+ // Only the bridge granted in this request can resolve a deferred name.
200
+ // The ordinary runtime still projects the target and enforces its policy.
201
+ let tool =
202
+ directTool ||
203
+ (typeof requestedName === 'string' && requestedName.length > 0 ? toolByNames(tools, ['call_tool']) : null);
167
204
  if (!tool) {
168
205
  sendExecResult(bridge, exec, 'mcpResult', {
169
206
  error: { error: `Tool not available: ${requestedName || 'unknown'}` },
170
207
  });
171
208
  return;
172
209
  }
210
+ let decodedArgs = decodeMcpArgs(args.args);
211
+ if (
212
+ requestedName === 'call_tool' &&
213
+ directTool &&
214
+ Object.keys(decodedArgs).length === 2 &&
215
+ Object.hasOwn(decodedArgs, 'name') &&
216
+ Object.hasOwn(decodedArgs, 'arguments') &&
217
+ typeof decodedArgs.name === 'string' &&
218
+ decodedArgs.name.length > 0 &&
219
+ decodedArgs.name.length <= BRIDGE_NAME_MAX_CHARS &&
220
+ !isBridgeMetaTool(decodedArgs.name) &&
221
+ decodedArgs.arguments !== null &&
222
+ typeof decodedArgs.arguments === 'object' &&
223
+ !Array.isArray(decodedArgs.arguments)
224
+ ) {
225
+ const target = toolByNames(tools, [decodedArgs.name]);
226
+ if (target) {
227
+ tool = target;
228
+ decodedArgs = decodedArgs.arguments;
229
+ }
230
+ }
173
231
  onToolCall({
174
232
  exec,
175
233
  toolCallId: args.toolCallId || crypto.randomUUID(),
176
234
  toolName: tool.name,
177
- decodedArgs: JSON.stringify(decodeMcpArgs(args.args)),
235
+ decodedArgs: JSON.stringify(directTool ? decodedArgs : { name: requestedName, arguments: decodedArgs }),
178
236
  });
179
237
  }
180
238
 
@@ -191,7 +249,14 @@ export function handleExecMessage(bridge, exec, tools, cloudRule, onToolCall) {
191
249
  handleMcpExec(bridge, exec, tools, onToolCall);
192
250
  return;
193
251
  }
194
- const redirect = redirectNativeExec(exec, tools);
252
+ let redirect;
253
+ try {
254
+ redirect = redirectNativeExec(exec, tools);
255
+ } catch (error) {
256
+ if (error.code !== 'CURSOR_WRITE_ENCODING') throw error;
257
+ sendExecResult(bridge, exec, 'writeResult', { error: { path: exec.writeArgs.path || '', error: error.message } });
258
+ return;
259
+ }
195
260
  if (redirect) {
196
261
  onToolCall(redirect);
197
262
  return;
@@ -227,31 +292,41 @@ function parseListedPaths(text, rootPath) {
227
292
 
228
293
  function parseGrepResult(text, args) {
229
294
  const mode = args.outputMode || 'content';
295
+ const lines = text.split(/\r?\n/).filter((line) => line && !line.startsWith('[total ') && !line.startsWith('... ['));
230
296
  if (mode === 'files_with_matches') {
231
- const files = text
232
- .split(/\r?\n/)
233
- .map((line) => line.trim())
234
- .filter(Boolean);
297
+ const files = lines.map((line) => line.trim()).filter((line) => !line.startsWith('(no matches)'));
235
298
  return { files: { files, totalFiles: files.length } };
236
299
  }
237
300
  if (mode === 'count') {
238
301
  const counts = [];
239
302
  let totalMatches = 0;
240
- for (const line of text.split(/\r?\n/)) {
241
- const match = line.match(/^(.*):(\d+)$/);
242
- if (!match) continue;
243
- const count = Number(match[2]);
244
- counts.push({ file: match[1], count });
303
+ for (const line of lines) {
304
+ const parsed = splitGrepCountPrefix(line);
305
+ if (!parsed && !/^\d+$/.test(line)) continue;
306
+ const count = parsed ? parsed.count : Number(line);
307
+ counts.push({ file: parsed?.path || args.path, count });
245
308
  totalMatches += count;
246
309
  }
247
310
  return { count: { counts, totalFiles: counts.length, totalMatches } };
248
311
  }
249
312
  const byFile = new Map();
250
- for (const line of text.split(/\r?\n/)) {
251
- const match = line.match(/^(.+?):(\d+):(.*)$/);
252
- if (!match) continue;
253
- if (!byFile.has(match[1])) byFile.set(match[1], []);
254
- byFile.get(match[1]).push({ lineNumber: Number(match[2]), content: match[3] });
313
+ let currentFile = args.path;
314
+ for (const line of lines) {
315
+ const grouped = /^ {2}(\d+): (.*)$/.exec(line);
316
+ // Native searches request no context: only :N: is a line delimiter.
317
+ // A -N- segment may be part of the filename, not a context-line prefix.
318
+ const match = grouped ? null : /^(.+?):(\d+):/.exec(line);
319
+ const prefix = match ? { path: match[1], lineNo: Number(match[2]), markerEnd: match[0].length } : null;
320
+ const single = grouped || prefix ? null : splitGrepLineNumberOnlyPrefix(line);
321
+ if (!grouped && !prefix && !single) {
322
+ currentFile = line.replace(/ \(\d+ hits\)$/, '');
323
+ continue;
324
+ }
325
+ const file = prefix?.path || currentFile;
326
+ const lineNumber = grouped ? Number(grouped[1]) : (prefix || single).lineNo;
327
+ const content = grouped ? grouped[2] : line.slice((prefix || single).markerEnd);
328
+ if (!byFile.has(file)) byFile.set(file, []);
329
+ byFile.get(file).push({ lineNumber, content });
255
330
  }
256
331
  const matches = [...byFile].map(([file, fileMatches]) => ({ file, matches: fileMatches }));
257
332
  const matchedLines = matches.reduce((sum, entry) => sum + entry.matches.length, 0);
@@ -290,7 +365,7 @@ function sendShellStream(bridge, exec, text, code) {
290
365
  // rejected shell command.
291
366
  const NATIVE_FAILURE_PAYLOADS = {
292
367
  readResult: (args, text) => ({ rejected: { path: args.path || '', reason: text || 'Read failed' } }),
293
- writeResult: (args, text) => ({ rejected: { path: args.path || '', reason: text || 'Write failed' } }),
368
+ writeResult: (args, text) => ({ error: { path: args.path || '', error: text || 'Write failed' } }),
294
369
  fetchResult: (args, text) => ({ error: { url: args.url || '', error: text || 'Fetch failed' } }),
295
370
  lsResult: (args, text) => ({ rejected: { path: args.path || '', reason: text || 'List failed' } }),
296
371
  grepResult: (_args, text) => ({ error: { error: text || 'Grep failed' } }),
@@ -304,16 +379,30 @@ const NATIVE_FAILURE_PAYLOADS = {
304
379
  };
305
380
 
306
381
  const NATIVE_SUCCESS_PAYLOADS = {
307
- readResult: (args, text) => ({
308
- success: {
309
- path: args.path || '',
310
- content: text,
311
- totalLines: text ? text.split(/\r?\n/).length : 0,
312
- fileSize: textEncoder.encode(text).length,
313
- },
314
- }),
382
+ readResult: (args, text, pending, result) => {
383
+ const source = readSourceWindow(text);
384
+ // The read executor reports per-line clipping out of band: on the
385
+ // pending call (local) or on the result (remote/proxied).
386
+ if (!source || pending.nativeReadWindow?.lineClipped || result?.readWindow?.lineClipped)
387
+ return {
388
+ rejected: {
389
+ path: args.path || '',
390
+ reason:
391
+ 'This read result is not a complete contiguous source window. Use the mixdog MCP read tool with file_path, offset and limit; do not treat display markers as file content.',
392
+ },
393
+ };
394
+ return {
395
+ success: {
396
+ path: args.path || '',
397
+ content: source.content,
398
+ ...(source.totalLines === undefined ? {} : { totalLines: source.totalLines }),
399
+ truncated: source.truncated,
400
+ rangeApplied: Boolean(args.offset || args.limit || (source.startLine != null && source.startLine > 1)),
401
+ },
402
+ };
403
+ },
315
404
  writeResult: (args) => {
316
- const content = args.fileBytes?.length ? textDecoder.decode(args.fileBytes) : args.fileText || '';
405
+ const content = nativeWriteText(args);
317
406
  return {
318
407
  success: {
319
408
  path: args.path || '',
@@ -345,7 +434,9 @@ const NATIVE_SUCCESS_PAYLOADS = {
345
434
  };
346
435
 
347
436
  export function sendToolResult(bridge, pending, result, ok) {
437
+ releaseCursorNativeCall(pending);
348
438
  result = capCursorToolResult(result);
439
+ pending.completedResult = { result, ok };
349
440
  const { exec, native } = pending;
350
441
  const text = String(result?.content ?? '');
351
442
  const media = Array.isArray(result?.media) ? result.media : [];
@@ -354,6 +445,21 @@ export function sendToolResult(bridge, pending, result, ok) {
354
445
  return;
355
446
  }
356
447
  const { args, resultType } = native;
448
+ if (ok && resultType === 'readResult' && pending.nativeReadReply) {
449
+ let reply = pending.nativeReadReply;
450
+ if (pending.nativeUserMessage) {
451
+ reply = {
452
+ rejected: {
453
+ path: args.path || '',
454
+ reason: `Read interrupted by a new user instruction: ${pending.nativeUserMessage}`,
455
+ },
456
+ };
457
+ } else if (pending.nativeSnapshot) {
458
+ pending.nativeSnapshot.delivered = true;
459
+ }
460
+ sendExecResult(bridge, exec, resultType, reply);
461
+ return;
462
+ }
357
463
  if (resultType === 'shellStreamResult') {
358
464
  sendShellStream(bridge, exec, text, ok ? 0 : 1);
359
465
  return;
@@ -364,6 +470,10 @@ export function sendToolResult(bridge, pending, result, ok) {
364
470
  return;
365
471
  }
366
472
  if (Object.hasOwn(NATIVE_SUCCESS_PAYLOADS, resultType)) {
367
- sendExecResult(bridge, exec, resultType, NATIVE_SUCCESS_PAYLOADS[resultType](args, text));
473
+ const value = NATIVE_SUCCESS_PAYLOADS[resultType](args, text, pending, result);
474
+ if (resultType === 'writeResult' && Number.isInteger(pending.nativeWrittenBytes)) {
475
+ value.success.fileSize = pending.nativeWrittenBytes;
476
+ }
477
+ sendExecResult(bridge, exec, resultType, value);
368
478
  }
369
479
  }
@@ -87,7 +87,19 @@ const SCHEMAS = {
87
87
  ['clientHeartbeat', 7, 'ClientHeartbeat'],
88
88
  ]),
89
89
  TextDeltaUpdate: fields([['text', 1, 'string']]),
90
- ToolCall: fields([['mcpToolCall', 15, 'McpToolCall']]),
90
+ ToolCall: fields([
91
+ ['editToolCall', 12, 'NativeEditToolCall'],
92
+ ['mcpToolCall', 15, 'McpToolCall'],
93
+ ]),
94
+ NativeEditToolCall: fields([['result', 2, 'NativeEditResult']]),
95
+ NativeEditResult: fields([
96
+ ['success', 1, 'raw'],
97
+ ['fileNotFound', 2, 'raw'],
98
+ ['readPermissionDenied', 3, 'raw'],
99
+ ['writePermissionDenied', 4, 'raw'],
100
+ ['rejected', 6, 'raw'],
101
+ ['error', 7, 'raw'],
102
+ ]),
91
103
  McpToolCall: fields([
92
104
  ['args', 1, 'McpArgs'],
93
105
  ['result', 2, 'McpResult'],
@@ -422,6 +434,7 @@ const SCHEMAS = {
422
434
  ['totalLines', 3, 'int'],
423
435
  ['fileSize', 4, 'int'],
424
436
  ['truncated', 6, 'bool'],
437
+ ['rangeApplied', 8, 'bool'],
425
438
  ]),
426
439
  ReadRejected: fields([
427
440
  ['path', 1, 'string'],
@@ -430,7 +443,9 @@ const SCHEMAS = {
430
443
  ReadResult: fields([
431
444
  ['success', 1, 'ReadSuccess'],
432
445
  ['rejected', 3, 'ReadRejected'],
446
+ ['fileNotFound', 4, 'ReadFileNotFound'],
433
447
  ]),
448
+ ReadFileNotFound: fields([['path', 1, 'string']]),
434
449
  WriteSuccess: fields([
435
450
  ['path', 1, 'string'],
436
451
  ['linesCreated', 2, 'int'],
@@ -440,8 +455,13 @@ const SCHEMAS = {
440
455
  ['path', 1, 'string'],
441
456
  ['reason', 2, 'string'],
442
457
  ]),
458
+ WriteError: fields([
459
+ ['path', 1, 'string'],
460
+ ['error', 2, 'string'],
461
+ ]),
443
462
  WriteResult: fields([
444
463
  ['success', 1, 'WriteSuccess'],
464
+ ['error', 5, 'WriteError'],
445
465
  ['rejected', 6, 'WriteRejected'],
446
466
  ]),
447
467
  DeleteRejected: fields([
@@ -610,7 +630,7 @@ const SCHEMAS = {
610
630
  JsonValue: fields([
611
631
  ['nullValue', 1, 'int'],
612
632
  ['numberValue', 2, 'double'],
613
- ['stringValue', 3, 'string'],
633
+ ['stringValue', 3, 'string', { presence: true }],
614
634
  ['boolValue', 4, 'bool'],
615
635
  ['structValue', 5, 'JsonStruct'],
616
636
  ['listValue', 6, 'JsonList'],
@@ -620,7 +640,8 @@ const SCHEMAS = {
620
640
  };
621
641
 
622
642
  const textEncoder = new TextEncoder();
623
- const textDecoder = new TextDecoder();
643
+ // A protobuf string is data, not a text document with a disposable BOM.
644
+ const textDecoder = new TextDecoder('utf-8', { ignoreBOM: true });
624
645
 
625
646
  function concatBytes(parts) {
626
647
  const length = parts.reduce((sum, part) => sum + part.length, 0);
@@ -709,7 +730,10 @@ export function encodeMessage(type, value = {}) {
709
730
  let values = [fieldValue];
710
731
  if (descriptor.repeated) values = Array.isArray(fieldValue) ? fieldValue : [];
711
732
  for (const item of values) {
712
- if (shouldWrite(descriptor.type, item)) parts.push(encodeField(descriptor.no, descriptor.type, item));
733
+ // A oneof's explicit empty string is a value, not an absent field.
734
+ if ((descriptor.presence && item != null) || shouldWrite(descriptor.type, item)) {
735
+ parts.push(encodeField(descriptor.no, descriptor.type, item));
736
+ }
713
737
  }
714
738
  }
715
739
  return concatBytes(parts);
@@ -61,7 +61,13 @@ function toolResultEntry(message, text, toolNames) {
61
61
  const isError = message.mixdog_tool_error === true;
62
62
  const toolName = toolNames.get(toolCallId) || '';
63
63
  return {
64
- toolResult: { toolCallId, content: text, media, isError },
64
+ toolResult: {
65
+ toolCallId,
66
+ content: text,
67
+ media,
68
+ isError,
69
+ ...(message.mixdog_read_window?.lineClipped === true ? { readWindow: { lineClipped: true } } : {}),
70
+ },
65
71
  entry: {
66
72
  role: 'tool',
67
73
  id: toolCallId,
@@ -170,9 +176,7 @@ export function buildRequestContext(tools, cloudRule) {
170
176
  {
171
177
  serverName: 'mixdog',
172
178
  instructions:
173
- 'Use the tools provided by the mixdog MCP server for this task. ' +
174
- 'Follow their descriptions and input schemas. Prefer them over Cursor native tools; ' +
175
- 'native tools do not directly access the Mixdog environment. ' +
179
+ 'Do not use Cursor native tools; use only the tools provided by the mixdog MCP server, following their descriptions and declared input schemas. ' +
176
180
  'If a needed tool is not available, use the provided tool discovery mechanism rather than inventing a tool.',
177
181
  },
178
182
  ]
@@ -4,6 +4,7 @@
4
4
  * close verdict and the bounded in-place restart.
5
5
  */
6
6
  import {
7
+ MAX_CONNECT_FRAME_BYTES,
7
8
  isCursorAuthError,
8
9
  isCursorThrottleError,
9
10
  isRetryableCursorStreamError,
@@ -13,6 +14,10 @@ import { emitProviderRetryStage, markProviderRecoveryExhausted, retryAfterMsFrom
13
14
  import { createFrameParser, cursorError, parseEndStream } from './cursor-wire-transport.mjs';
14
15
  import { processServerMessage } from './cursor-wire-stream-messages.mjs';
15
16
 
17
+ // A parked HTTP/2 run can still receive parallel execs. Keep their raw chunks
18
+ // with the transport until the next SSE consumer attaches.
19
+ const parkedInputs = new WeakMap();
20
+
16
21
  // Resolves after `ms`, or early when the stream is cancelled.
17
22
  function abortableSleep(ms, signal) {
18
23
  return new Promise((resolve) => {
@@ -51,7 +56,9 @@ export function createBridgeController(ctx) {
51
56
  modelParameters: run.modelParameters,
52
57
  maxMode: run.maxMode,
53
58
  sessionId: run.sessionId,
59
+ ownerSessionId: run.ownerSessionId,
54
60
  pending: state.pending,
61
+ executions: state.executions,
55
62
  sawTurnEnded: state.sawTurnEnded,
56
63
  });
57
64
  sink.finish('tool_calls');
@@ -80,13 +87,11 @@ export function createBridgeController(ctx) {
80
87
  const serverDelay = retryAfterMsFromError(error);
81
88
  // Server advice is honored in full for every retryable kind; local
82
89
  // backoff applies only when the server gave none.
83
- const delayMs = Number.isFinite(serverDelay)
84
- ? serverDelay
85
- : backoffMs(throttled ? throttleCount + 1 : retryCount + 1);
90
+ const backoffAttempt = (throttled ? throttleCount : retryCount) + 1;
91
+ const delayMs = Number.isFinite(serverDelay) ? serverDelay : backoffMs(backoffAttempt);
86
92
  const throttleOk = throttled && throttleCount < tuning.maxThrottleRetries;
87
93
  const authOk = authFailure && authCount < tuning.maxAuthRetries;
88
- const canRetry =
89
- retryCount < tuning.maxRetries && recoveryEligible && (retryable || throttleOk || authOk);
94
+ const canRetry = retryCount < tuning.maxRetries && recoveryEligible && (retryable || throttleOk || authOk);
90
95
  if (!canRetry) {
91
96
  // A fresh Cursor run owns its bounded in-place retries. Mark
92
97
  // exhaustion so the outer loop does not multiply that budget.
@@ -96,8 +101,7 @@ export function createBridgeController(ctx) {
96
101
  // A throttle that spent its bounded retries is final for the turn too.
97
102
  if (
98
103
  recoveryEligible &&
99
- ((retryable && retryCount >= tuning.maxRetries) ||
100
- (throttled && throttleCount >= tuning.maxThrottleRetries))
104
+ ((retryable && retryCount >= tuning.maxRetries) || (throttled && throttleCount >= tuning.maxThrottleRetries))
101
105
  ) {
102
106
  markProviderRecoveryExhausted(error, { owner: 'cursor-wire', attempts: retryCount + 1 });
103
107
  }
@@ -118,6 +122,9 @@ export function createBridgeController(ctx) {
118
122
  lastErr: error,
119
123
  delayMs,
120
124
  });
125
+ let restartReason = 'transient';
126
+ if (throttled) restartReason = 'throttle';
127
+ else if (authFailure) restartReason = 'auth';
121
128
  void sleep(delayMs, cancelSignal).then(async () => {
122
129
  if (isCancelled() || state.closed) return;
123
130
  try {
@@ -126,7 +133,7 @@ export function createBridgeController(ctx) {
126
133
  attempt: retryCount,
127
134
  fromCheckpoint: !throttled && Boolean(run.conversation.checkpoint),
128
135
  visibleOutput: state.visibleOutput,
129
- reason: throttled ? 'throttle' : authFailure ? 'auth' : 'transient',
136
+ reason: restartReason,
130
137
  error,
131
138
  });
132
139
  if (isCancelled() || state.closed) {
@@ -200,6 +207,11 @@ export function createBridgeController(ctx) {
200
207
  const attach = (ownedBridge, nextHeartbeat) => {
201
208
  live.bridge = ownedBridge;
202
209
  live.heartbeat = nextHeartbeat;
210
+ let inbox = parkedInputs.get(ownedBridge);
211
+ if (!inbox) {
212
+ inbox = { chunks: [], bytes: 0 };
213
+ parkedInputs.set(ownedBridge, inbox);
214
+ }
203
215
  const messageCtx = {
204
216
  state,
205
217
  filter,
@@ -207,14 +219,27 @@ export function createBridgeController(ctx) {
207
219
  conversation: run.conversation,
208
220
  tools: run.tools,
209
221
  cloudRule: run.cloudRule,
222
+ sessionId: run.sessionId,
223
+ ownerSessionId: run.ownerSessionId,
210
224
  };
211
225
  const frameParser = createFrameParser(
212
226
  // Server requests answer on whichever bridge is live when they arrive.
213
227
  (bytes) => watchdog.progress(processServerMessage(bytes, { ...messageCtx, bridge: live.bridge })),
214
228
  (bytes) => onEndStream(ownedBridge, bytes)
215
229
  );
216
- ownedBridge.onData((chunk) => {
217
- if (live.bridge !== ownedBridge || state.closed) return;
230
+ const receive = (chunk) => {
231
+ if (live.bridge !== ownedBridge || isCancelled()) return;
232
+ if (state.closed) {
233
+ if (inbox.bytes + chunk.byteLength > MAX_CONNECT_FRAME_BYTES) {
234
+ ownedBridge.close(
235
+ cursorError('Cursor parked input exceeds the buffer limit', { code: 'stream_buffer_limit' })
236
+ );
237
+ return;
238
+ }
239
+ inbox.chunks.push(chunk);
240
+ inbox.bytes += chunk.byteLength;
241
+ return;
242
+ }
218
243
  state.chunkSeq += 1;
219
244
  try {
220
245
  frameParser(chunk);
@@ -226,9 +251,15 @@ export function createBridgeController(ctx) {
226
251
  } catch (error) {
227
252
  ownedBridge.close(error);
228
253
  }
229
- });
254
+ };
255
+ ownedBridge.onData(receive);
230
256
  ownedBridge.onClose((error) => onBridgeClose(ownedBridge, nextHeartbeat, frameParser, error));
231
257
  watchdog.start();
258
+ while (!state.closed && !isCancelled() && inbox.chunks.length) {
259
+ const chunk = inbox.chunks.shift();
260
+ inbox.bytes -= chunk.byteLength;
261
+ receive(chunk);
262
+ }
232
263
  };
233
264
 
234
265
  return { attach };